From b7280455886e4879a80a05a56ca14af5ba92ca58 Mon Sep 17 00:00:00 2001
From: Orgad Shaneh <orgad.shaneh@audiocodes.com>
Date: Thu, 23 Jan 2014 07:53:24 +0200
Subject: [PATCH] CppEditor: Move InsertVirtualMethods to its own file

It contains many components, doesn't make sense to have it with all
other quickfixes.

Change-Id: Idede14c90ba9b612ae9e9048f5795d674811acfe
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
---
 src/plugins/cppeditor/cppeditor.pro           |    9 +-
 .../cppeditor/cppinsertvirtualmethods.cpp     | 1417 +++++++++++++++++
 ...test_utils.h => cppinsertvirtualmethods.h} |   32 +-
 src/plugins/cppeditor/cppquickfix_test.cpp    |  940 +++--------
 src/plugins/cppeditor/cppquickfix_test.h      |  101 ++
 .../cppeditor/cppquickfix_test_utils.cpp      |   58 -
 src/plugins/cppeditor/cppquickfixes.cpp       |  745 +--------
 src/plugins/cppeditor/cppquickfixes.h         |   83 -
 .../cppeditor/fileandtokenactions_test.cpp    |    7 +-
 9 files changed, 1733 insertions(+), 1659 deletions(-)
 create mode 100644 src/plugins/cppeditor/cppinsertvirtualmethods.cpp
 rename src/plugins/cppeditor/{cppquickfix_test_utils.h => cppinsertvirtualmethods.h} (69%)
 create mode 100644 src/plugins/cppeditor/cppquickfix_test.h
 delete mode 100644 src/plugins/cppeditor/cppquickfix_test_utils.cpp

diff --git a/src/plugins/cppeditor/cppeditor.pro b/src/plugins/cppeditor/cppeditor.pro
index 3ab35cdf4cd..6958bb920a9 100644
--- a/src/plugins/cppeditor/cppeditor.pro
+++ b/src/plugins/cppeditor/cppeditor.pro
@@ -29,7 +29,8 @@ HEADERS += \
     cppsnippetprovider.h \
     cpptypehierarchy.h \
     cppvirtualfunctionassistprovider.h \
-    cppvirtualfunctionproposalitem.h
+    cppvirtualfunctionproposalitem.h \
+    cppinsertvirtualmethods.h
 
 SOURCES += \
     cppautocompleter.cpp \
@@ -56,7 +57,8 @@ SOURCES += \
     cppsnippetprovider.cpp \
     cpptypehierarchy.cpp \
     cppvirtualfunctionassistprovider.cpp \
-    cppvirtualfunctionproposalitem.cpp
+    cppvirtualfunctionproposalitem.cpp \
+    cppinsertvirtualmethods.cpp
 
 FORMS += \
     cpppreprocessordialog.ui \
@@ -68,13 +70,12 @@ RESOURCES += \
 equals(TEST, 1) {
     HEADERS += \
         cppeditortestcase.h \
-        cppquickfix_test_utils.h
+        cppquickfix_test.h
     SOURCES += \
         cppdoxygen_test.cpp \
         cppeditortestcase.cpp \
         cppincludehierarchy_test.cpp \
         cppquickfix_test.cpp \
-        cppquickfix_test_utils.cpp \
         fileandtokenactions_test.cpp \
         followsymbol_switchmethoddecldef_test.cpp
     DEFINES += SRCDIR=\\\"$$PWD\\\"
diff --git a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp
new file mode 100644
index 00000000000..61cdeef960b
--- /dev/null
+++ b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp
@@ -0,0 +1,1417 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "cppinsertvirtualmethods.h"
+#include "cppquickfixassistant.h"
+
+#include <coreplugin/icore.h>
+#include <cpptools/cppcodestylesettings.h>
+#include <cpptools/cpptoolsreuse.h>
+#include <cpptools/functionutils.h>
+#include <cpptools/insertionpointlocator.h>
+#include <texteditor/fontsettings.h>
+#include <texteditor/texteditorsettings.h>
+
+#include <cplusplus/CppRewriter.h>
+#include <cplusplus/Overview.h>
+
+#include <QCheckBox>
+#include <QComboBox>
+#include <QCoreApplication>
+#include <QDialog>
+#include <QDialogButtonBox>
+#include <QGroupBox>
+#include <QPointer>
+#include <QQueue>
+#include <QSortFilterProxyModel>
+#include <QStandardItemModel>
+#include <QTextDocument>
+#include <QTreeView>
+
+using namespace CPlusPlus;
+using namespace CppEditor;
+using namespace CppEditor::Internal;
+using namespace CppTools;
+using namespace TextEditor;
+
+namespace CppEditor {
+namespace Internal {
+
+class InsertVirtualMethodsDialog : public QDialog
+{
+    Q_OBJECT
+public:
+    enum CustomItemRoles {
+        ClassOrFunction = Qt::UserRole + 1,
+        Reimplemented = Qt::UserRole + 2,
+        PureVirtual = Qt::UserRole + 3,
+        AccessSpec = Qt::UserRole + 4
+    };
+
+    enum ImplementationMode {
+        ModeOnlyDeclarations = 0x00000001,
+        ModeInsideClass = 0x00000002,
+        ModeOutsideClass = 0x00000004,
+        ModeImplementationFile = 0x00000008
+    };
+
+    InsertVirtualMethodsDialog(QWidget *parent = 0);
+    void initGui();
+    void initData();
+    virtual ImplementationMode implementationMode() const;
+    void setImplementationsMode(ImplementationMode mode);
+    virtual bool insertKeywordVirtual() const;
+    void setInsertKeywordVirtual(bool insert);
+    void setHasImplementationFile(bool file);
+    void setHasReimplementedFunctions(bool functions);
+    bool hideReimplementedFunctions() const;
+    virtual bool gather();
+
+public slots:
+    void updateCheckBoxes(QStandardItem *item);
+
+private slots:
+    void setHideReimplementedFunctions(bool hide);
+
+private:
+    QTreeView *m_view;
+    QCheckBox *m_hideReimplementedFunctions;
+    QComboBox *m_insertMode;
+    QCheckBox *m_virtualKeyword;
+    QDialogButtonBox *m_buttons;
+    QList<bool> m_expansionStateNormal;
+    QList<bool> m_expansionStateReimp;
+    bool m_hasImplementationFile;
+    bool m_hasReimplementedFunctions;
+
+    void saveExpansionState();
+    void restoreExpansionState();
+
+protected:
+    ImplementationMode m_implementationMode;
+    bool m_insertKeywordVirtual;
+
+public:
+    QStandardItemModel *classFunctionModel;
+    QSortFilterProxyModel *classFunctionFilterModel;
+};
+
+} // namespace Internal
+} // namespace CppEditor
+
+namespace {
+
+class InsertVirtualMethodsOp : public CppQuickFixOperation
+{
+public:
+    InsertVirtualMethodsOp(const QSharedPointer<const CppQuickFixAssistInterface> &interface,
+                           InsertVirtualMethodsDialog *factory)
+        : CppQuickFixOperation(interface, 0)
+        , m_factory(factory)
+        , m_classAST(0)
+        , m_valid(false)
+        , m_cppFileName(QString::null)
+        , m_insertPosDecl(0)
+        , m_insertPosOutside(0)
+        , m_functionCount(0)
+    {
+        setDescription(QCoreApplication::translate(
+                           "CppEditor::QuickFix", "Insert Virtual Functions of Base Classes"));
+
+        const QList<AST *> &path = interface->path();
+        const int pathSize = path.size();
+        if (pathSize < 2)
+            return;
+
+        // Determine if cursor is on a class or a base class
+        if (SimpleNameAST *nameAST = path.at(pathSize - 1)->asSimpleName()) {
+            if (!interface->isCursorOn(nameAST))
+                return;
+
+            if (!(m_classAST = path.at(pathSize - 2)->asClassSpecifier())) { // normal class
+                int index = pathSize - 2;
+                const BaseSpecifierAST *baseAST = path.at(index)->asBaseSpecifier();// simple bclass
+                if (!baseAST) {
+                    if (index > 0 && path.at(index)->asQualifiedName()) // namespaced base class
+                        baseAST = path.at(--index)->asBaseSpecifier();
+                }
+                --index;
+                if (baseAST && index >= 0)
+                    m_classAST = path.at(index)->asClassSpecifier();
+            }
+        }
+        if (!m_classAST || !m_classAST->base_clause_list)
+            return;
+
+        // Determine insert positions
+        const int endOfClassAST = interface->currentFile()->endOf(m_classAST);
+        m_insertPosDecl = endOfClassAST - 1; // Skip last "}"
+        m_insertPosOutside = endOfClassAST + 1; // Step over ";"
+
+        // Determine base classes
+        QList<const Class *> baseClasses;
+        QQueue<ClassOrNamespace *> baseClassQueue;
+        QSet<ClassOrNamespace *> visitedBaseClasses;
+        if (ClassOrNamespace *clazz = interface->context().lookupType(m_classAST->symbol))
+            baseClassQueue.enqueue(clazz);
+        while (!baseClassQueue.isEmpty()) {
+            ClassOrNamespace *clazz = baseClassQueue.dequeue();
+            visitedBaseClasses.insert(clazz);
+            const QList<ClassOrNamespace *> bases = clazz->usings();
+            foreach (ClassOrNamespace *baseClass, bases) {
+                foreach (Symbol *symbol, baseClass->symbols()) {
+                    Class *base = symbol->asClass();
+                    if (base
+                            && (clazz = interface->context().lookupType(symbol))
+                            && !visitedBaseClasses.contains(clazz)
+                            && !baseClasses.contains(base)) {
+                        baseClasses.prepend(base);
+                        baseClassQueue.enqueue(clazz);
+                    }
+                }
+            }
+        }
+
+        // Determine virtual functions
+        m_factory->classFunctionModel->clear();
+        Overview printer = CppCodeStyleSettings::currentProjectCodeStyleOverview();
+        printer.showFunctionSignatures = true;
+        const FontSettings &fs = TextEditorSettings::fontSettings();
+        const Format formatReimpFunc = fs.formatFor(C_DISABLED_CODE);
+        QHash<const Function *, QStandardItem *> virtualFunctions;
+        foreach (const Class *clazz, baseClasses) {
+            QStandardItem *itemBase = new QStandardItem(printer.prettyName(clazz->name()));
+            itemBase->setData(false, InsertVirtualMethodsDialog::Reimplemented);
+            itemBase->setData(qVariantFromValue((void *) clazz),
+                              InsertVirtualMethodsDialog::ClassOrFunction);
+            for (Scope::iterator it = clazz->firstMember(); it != clazz->lastMember(); ++it) {
+                if (const Function *func = (*it)->type()->asFunctionType()) {
+                    // Filter virtual destructors
+                    if (func->name()->asDestructorNameId())
+                        continue;
+
+                    const Function *firstVirtual = 0;
+                    const bool isVirtual = FunctionUtils::isVirtualFunction(
+                                func, interface->context(), &firstVirtual);
+                    if (!isVirtual)
+                        continue;
+
+                    // Filter OQbject's
+                    //   - virtual const QMetaObject *metaObject() const;
+                    //   - virtual void *qt_metacast(const char *);
+                    //   - virtual int qt_metacall(QMetaObject::Call, int, void **);
+                    if (printer.prettyName(firstVirtual->enclosingClass()->name())
+                            == QLatin1String("QObject")) {
+                        const QString funcName = printer.prettyName(func->name());
+                        if (funcName == QLatin1String("metaObject")
+                                || funcName == QLatin1String("qt_metacast")
+                                || funcName == QLatin1String("qt_metacall")) {
+                            continue;
+                        }
+                    }
+
+                    // Do not implement existing functions inside target class
+                    bool funcExistsInClass = false;
+                    const Name *funcName = func->name();
+                    for (Symbol *symbol = m_classAST->symbol->find(funcName->identifier());
+                         symbol; symbol = symbol->next()) {
+                        if (!symbol->name()
+                                || !funcName->identifier()->isEqualTo(symbol->identifier())) {
+                            continue;
+                        }
+                        if (symbol->type().isEqualTo(func->type())) {
+                            funcExistsInClass = true;
+                            break;
+                        }
+                    }
+
+                    // Construct function item
+                    const bool isReimplemented = (func != firstVirtual);
+                    const bool isPureVirtual = func->isPureVirtual();
+                    QString itemName = printer.prettyType(func->type(), func->name());
+                    if (isPureVirtual)
+                        itemName += QLatin1String(" = 0");
+                    const QString itemReturnTypeString = printer.prettyType(func->returnType());
+                    itemName += QLatin1String(" : ") + itemReturnTypeString;
+                    if (isReimplemented)
+                        itemName += QLatin1String(" (redeclared)");
+                    QStandardItem *funcItem = new QStandardItem(itemName);
+                    funcItem->setCheckable(true);
+                    if (isReimplemented) {
+                        factory->setHasReimplementedFunctions(true);
+                        funcItem->setEnabled(false);
+                        funcItem->setCheckState(Qt::Unchecked);
+                        if (QStandardItem *first = virtualFunctions[firstVirtual]) {
+                            if (!first->data(InsertVirtualMethodsDialog::Reimplemented).toBool()) {
+                                first->setCheckState(isPureVirtual ? Qt::Checked : Qt::Unchecked);
+                                factory->updateCheckBoxes(first);
+                            }
+                        }
+                    } else {
+                        if (!funcExistsInClass) {
+                            funcItem->setCheckState(isPureVirtual ? Qt::Checked : Qt::Unchecked);
+                        } else {
+                            funcItem->setEnabled(false);
+                            funcItem->setCheckState(Qt::Checked);
+                            funcItem->setData(formatReimpFunc.foreground(), Qt::ForegroundRole);
+                            factory->setHasReimplementedFunctions(true);
+                            if (formatReimpFunc.background().isValid())
+                                funcItem->setData(formatReimpFunc.background(), Qt::BackgroundRole);
+                        }
+                    }
+
+                    funcItem->setData(qVariantFromValue((void *) func),
+                                      InsertVirtualMethodsDialog::ClassOrFunction);
+                    funcItem->setData(isPureVirtual, InsertVirtualMethodsDialog::PureVirtual);
+                    funcItem->setData(acessSpec(*it), InsertVirtualMethodsDialog::AccessSpec);
+                    funcItem->setData(funcExistsInClass || isReimplemented,
+                                      InsertVirtualMethodsDialog::Reimplemented);
+
+                    itemBase->appendRow(funcItem);
+                    virtualFunctions[func] = funcItem;
+
+                    // update internal counters
+                    if (!funcExistsInClass)
+                        ++m_functionCount;
+                }
+            }
+            if (itemBase->hasChildren()) {
+                itemBase->setData(false, InsertVirtualMethodsDialog::Reimplemented);
+                bool enabledFound = false;
+                Qt::CheckState state = Qt::Unchecked;
+                for (int i = 0; i < itemBase->rowCount(); ++i) {
+                    QStandardItem *childItem = itemBase->child(i, 0);
+                    if (!childItem->isEnabled())
+                        continue;
+                    if (!enabledFound) {
+                        state = childItem->checkState();
+                        enabledFound = true;
+                    }
+                    if (childItem->isCheckable()) {
+                        if (!itemBase->isCheckable()) {
+                            itemBase->setCheckable(true);
+                            itemBase->setTristate(true);
+                            itemBase->setCheckState(state);
+                        }
+                        if (state != childItem->checkState()) {
+                            itemBase->setCheckState(Qt::PartiallyChecked);
+                            break;
+                        }
+                    }
+                }
+                if (!enabledFound) {
+                    itemBase->setCheckable(true);
+                    itemBase->setEnabled(false);
+                }
+                m_factory->classFunctionModel->invisibleRootItem()->appendRow(itemBase);
+            }
+        }
+        if (!m_factory->classFunctionModel->invisibleRootItem()->hasChildren()
+                || m_functionCount == 0) {
+            return;
+        }
+
+        bool isHeaderFile = false;
+        m_cppFileName = correspondingHeaderOrSource(interface->fileName(), &isHeaderFile);
+        m_factory->setHasImplementationFile(isHeaderFile && !m_cppFileName.isEmpty());
+
+        m_valid = true;
+    }
+
+    bool isValid() const
+    {
+        return m_valid;
+    }
+
+    InsertionPointLocator::AccessSpec acessSpec(const Symbol *symbol)
+    {
+        const Function *func = symbol->type()->asFunctionType();
+        if (!func)
+            return InsertionPointLocator::Invalid;
+        if (func->isSignal())
+            return InsertionPointLocator::Signals;
+
+        InsertionPointLocator::AccessSpec spec = InsertionPointLocator::Invalid;
+        if (symbol->isPrivate())
+            spec = InsertionPointLocator::Private;
+        else if (symbol->isProtected())
+            spec = InsertionPointLocator::Protected;
+        else if (symbol->isPublic())
+            spec = InsertionPointLocator::Public;
+        else
+            return InsertionPointLocator::Invalid;
+
+        if (func->isSlot()) {
+            switch (spec) {
+            case InsertionPointLocator::Private:
+                return InsertionPointLocator::PrivateSlot;
+            case InsertionPointLocator::Protected:
+                return InsertionPointLocator::ProtectedSlot;
+            case InsertionPointLocator::Public:
+                return InsertionPointLocator::PublicSlot;
+            default:
+                return spec;
+            }
+        }
+        return spec;
+    }
+
+    void perform()
+    {
+        if (!m_factory->gather())
+            return;
+
+        Core::ICore::settings()->setValue(
+                    QLatin1String("QuickFix/InsertVirtualMethods/insertKeywordVirtual"),
+                    m_factory->insertKeywordVirtual());
+        Core::ICore::settings()->setValue(
+                    QLatin1String("QuickFix/InsertVirtualMethods/implementationMode"),
+                    m_factory->implementationMode());
+        Core::ICore::settings()->setValue(
+                    QLatin1String("QuickFix/InsertVirtualMethods/hideReimplementedFunctions"),
+                    m_factory->hideReimplementedFunctions());
+
+        // Insert declarations (and definition if Inside-/OutsideClass)
+        Overview printer = CppCodeStyleSettings::currentProjectCodeStyleOverview();
+        printer.showFunctionSignatures = true;
+        printer.showReturnTypes = true;
+        printer.showArgumentNames = true;
+        Utils::ChangeSet headerChangeSet;
+        const CppRefactoringChanges refactoring(assistInterface()->snapshot());
+        const QString filename = assistInterface()->currentFile()->fileName();
+        const CppRefactoringFilePtr headerFile = refactoring.file(filename);
+        const LookupContext targetContext(headerFile->cppDocument(), assistInterface()->snapshot());
+
+        const Class *targetClass = m_classAST->symbol;
+        ClassOrNamespace *targetCoN = targetContext.lookupType(targetClass->enclosingScope());
+        if (!targetCoN)
+            targetCoN = targetContext.globalNamespace();
+        UseMinimalNames useMinimalNames(targetCoN);
+        Control *control = assistInterface()->context().bindings()->control().data();
+        for (int i = 0; i < m_factory->classFunctionModel->rowCount(); ++i) {
+            const QStandardItem *parent =
+                    m_factory->classFunctionModel->invisibleRootItem()->child(i, 0);
+            if (!parent->isCheckable() || parent->checkState() == Qt::Unchecked)
+                continue;
+            const Class *clazz = (const Class *)
+                    parent->data(InsertVirtualMethodsDialog::ClassOrFunction).value<void *>();
+
+            // Add comment
+            const QString comment = QLatin1String("\n// ") + printer.prettyName(clazz->name()) +
+                    QLatin1String(" interface\n");
+            headerChangeSet.insert(m_insertPosDecl, comment);
+
+            // Insert Declarations (+ definitions)
+            QString lastAccessSpecString;
+            for (int j = 0; j < parent->rowCount(); ++j) {
+                const QStandardItem *item = parent->child(j, 0);
+                if (!item->isEnabled() || !item->isCheckable() || item->checkState() == Qt::Unchecked)
+                    continue;
+                const Function *func = (const Function *)
+                        item->data(InsertVirtualMethodsDialog::ClassOrFunction).value<void *>();
+
+                // Construct declaration
+                // setup rewriting to get minimally qualified names
+                SubstitutionEnvironment env;
+                env.setContext(assistInterface()->context());
+                env.switchScope(clazz->enclosingScope());
+                env.enter(&useMinimalNames);
+
+                QString declaration;
+                const FullySpecifiedType tn = rewriteType(func->type(), &env, control);
+                declaration += printer.prettyType(tn, func->unqualifiedName());
+
+                if (m_factory->insertKeywordVirtual())
+                    declaration = QLatin1String("virtual ") + declaration;
+                if (m_factory->implementationMode() & InsertVirtualMethodsDialog::ModeInsideClass)
+                    declaration += QLatin1String("\n{\n}\n");
+                else
+                    declaration += QLatin1String(";\n");
+
+                const InsertionPointLocator::AccessSpec spec =
+                        static_cast<InsertionPointLocator::AccessSpec>(
+                            item->data(InsertVirtualMethodsDialog::AccessSpec).toInt());
+                const QString accessSpecString = InsertionPointLocator::accessSpecToString(spec);
+                if (accessSpecString != lastAccessSpecString) {
+                    declaration = accessSpecString + declaration;
+                    if (!lastAccessSpecString.isEmpty()) // separate if not direct after the comment
+                        declaration = QLatin1String("\n") + declaration;
+                    lastAccessSpecString = accessSpecString;
+                }
+                headerChangeSet.insert(m_insertPosDecl, declaration);
+
+                // Insert definition outside class
+                if (m_factory->implementationMode() & InsertVirtualMethodsDialog::ModeOutsideClass) {
+                    const QString name = printer.prettyName(targetClass->name()) +
+                            QLatin1String("::") + printer.prettyName(func->name());
+                    const QString defText = printer.prettyType(tn, name) + QLatin1String("\n{\n}");
+                    headerChangeSet.insert(m_insertPosOutside,  QLatin1String("\n\n") + defText);
+                }
+            }
+        }
+
+        // Write header file
+        headerFile->setChangeSet(headerChangeSet);
+        headerFile->appendIndentRange(Utils::ChangeSet::Range(m_insertPosDecl, m_insertPosDecl + 1));
+        headerFile->setOpenEditor(true, m_insertPosDecl);
+        headerFile->apply();
+
+        // Insert in implementation file
+        if (m_factory->implementationMode() & InsertVirtualMethodsDialog::ModeImplementationFile) {
+            const Symbol *symbol = headerFile->cppDocument()->lastVisibleSymbolAt(
+                        targetClass->line(), targetClass->column());
+            if (!symbol)
+                return;
+            const Class *clazz = symbol->asClass();
+            if (!clazz)
+                return;
+
+            CppRefactoringFilePtr implementationFile = refactoring.file(m_cppFileName);
+            Utils::ChangeSet implementationChangeSet;
+            const int insertPos = qMax(0, implementationFile->document()->characterCount() - 1);
+
+            // make target lookup context
+            Document::Ptr implementationDoc = implementationFile->cppDocument();
+            unsigned line, column;
+            implementationDoc->translationUnit()->getPosition(insertPos, &line, &column);
+            Scope *targetScope = implementationDoc->scopeAt(line, column);
+            const LookupContext targetContext(implementationDoc, assistInterface()->snapshot());
+            ClassOrNamespace *targetCoN = targetContext.lookupType(targetScope);
+            if (!targetCoN)
+                targetCoN = targetContext.globalNamespace();
+
+            // Loop through inserted declarations
+            for (unsigned i = targetClass->memberCount(); i < clazz->memberCount(); ++i) {
+                Declaration *decl = clazz->memberAt(i)->asDeclaration();
+                if (!decl)
+                    continue;
+
+                // setup rewriting to get minimally qualified names
+                SubstitutionEnvironment env;
+                env.setContext(assistInterface()->context());
+                env.switchScope(decl->enclosingScope());
+                UseMinimalNames q(targetCoN);
+                env.enter(&q);
+                Control *control = assistInterface()->context().bindings()->control().data();
+
+                // rewrite the function type and name + create definition
+                const FullySpecifiedType type = rewriteType(decl->type(), &env, control);
+                const QString name = printer.prettyName(
+                            LookupContext::minimalName(decl, targetCoN, control));
+                const QString defText = printer.prettyType(type, name) + QLatin1String("\n{\n}");
+
+                implementationChangeSet.insert(insertPos,  QLatin1String("\n\n") + defText);
+            }
+
+            implementationFile->setChangeSet(implementationChangeSet);
+            implementationFile->appendIndentRange(Utils::ChangeSet::Range(insertPos, insertPos + 1));
+            implementationFile->apply();
+        }
+    }
+
+private:
+    InsertVirtualMethodsDialog *m_factory;
+    const ClassSpecifierAST *m_classAST;
+    bool m_valid;
+    QString m_cppFileName;
+    int m_insertPosDecl;
+    int m_insertPosOutside;
+    unsigned m_functionCount;
+};
+
+class InsertVirtualMethodsFilterModel : public QSortFilterProxyModel
+{
+    Q_OBJECT
+public:
+    InsertVirtualMethodsFilterModel(QObject *parent = 0)
+        : QSortFilterProxyModel(parent)
+        , m_hideReimplemented(false)
+    {}
+
+    bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
+    {
+        QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
+
+        // Handle base class
+        if (!sourceParent.isValid()) {
+            // check if any child is valid
+            if (!sourceModel()->hasChildren(index))
+                return false;
+            if (!m_hideReimplemented)
+                return true;
+
+            for (int i = 0; i < sourceModel()->rowCount(index); ++i) {
+                const QModelIndex child = sourceModel()->index(i, 0, index);
+                if (!child.data(InsertVirtualMethodsDialog::Reimplemented).toBool())
+                    return true;
+            }
+            return false;
+        }
+
+        if (m_hideReimplemented)
+            return !index.data(InsertVirtualMethodsDialog::Reimplemented).toBool();
+        return true;
+    }
+
+    bool hideReimplemented() const
+    {
+        return m_hideReimplemented;
+    }
+
+    void setHideReimplementedFunctions(bool show)
+    {
+        m_hideReimplemented = show;
+        invalidateFilter();
+    }
+
+private:
+    bool m_hideReimplemented;
+};
+
+} // anonymous namespace
+
+InsertVirtualMethodsDialog::InsertVirtualMethodsDialog(QWidget *parent)
+    : QDialog(parent)
+    , m_view(0)
+    , m_hideReimplementedFunctions(0)
+    , m_insertMode(0)
+    , m_virtualKeyword(0)
+    , m_buttons(0)
+    , m_hasImplementationFile(false)
+    , m_hasReimplementedFunctions(false)
+    , m_implementationMode(ModeOnlyDeclarations)
+    , m_insertKeywordVirtual(false)
+    , classFunctionModel(new QStandardItemModel(this))
+    , classFunctionFilterModel(new InsertVirtualMethodsFilterModel(this))
+{
+    classFunctionFilterModel->setSourceModel(classFunctionModel);
+}
+
+void InsertVirtualMethodsDialog::initGui()
+{
+    if (m_view)
+        return;
+
+    setWindowTitle(tr("Insert Virtual Functions"));
+    QVBoxLayout *globalVerticalLayout = new QVBoxLayout;
+
+    // View
+    QGroupBox *groupBoxView = new QGroupBox(tr("&Functions to insert:"), this);
+    QVBoxLayout *groupBoxViewLayout = new QVBoxLayout(groupBoxView);
+    m_view = new QTreeView(this);
+    m_view->setEditTriggers(QAbstractItemView::NoEditTriggers);
+    m_view->setHeaderHidden(true);
+    groupBoxViewLayout->addWidget(m_view);
+    m_hideReimplementedFunctions =
+            new QCheckBox(tr("&Hide reimplemented functions"), this);
+    groupBoxViewLayout->addWidget(m_hideReimplementedFunctions);
+
+    // Insertion options
+    QGroupBox *groupBoxImplementation = new QGroupBox(tr("&Insertion options:"), this);
+    QVBoxLayout *groupBoxImplementationLayout = new QVBoxLayout(groupBoxImplementation);
+    m_insertMode = new QComboBox(this);
+    m_insertMode->addItem(tr("Insert only declarations"), ModeOnlyDeclarations);
+    m_insertMode->addItem(tr("Insert definitions inside class"), ModeInsideClass);
+    m_insertMode->addItem(tr("Insert definitions outside class"), ModeOutsideClass);
+    m_insertMode->addItem(tr("Insert definitions in implementation file"), ModeImplementationFile);
+    m_virtualKeyword = new QCheckBox(tr("&Add keyword 'virtual' to function declaration"), this);
+    groupBoxImplementationLayout->addWidget(m_insertMode);
+    groupBoxImplementationLayout->addWidget(m_virtualKeyword);
+    groupBoxImplementationLayout->addStretch(99);
+
+    // Bottom button box
+    m_buttons = new QDialogButtonBox(this);
+    m_buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+    connect(m_buttons, SIGNAL(accepted()), this, SLOT(accept()));
+    connect(m_buttons, SIGNAL(rejected()), this, SLOT(reject()));
+
+    globalVerticalLayout->addWidget(groupBoxView, 9);
+    globalVerticalLayout->addWidget(groupBoxImplementation, 0);
+    globalVerticalLayout->addWidget(m_buttons, 0);
+    setLayout(globalVerticalLayout);
+
+    connect(classFunctionModel, SIGNAL(itemChanged(QStandardItem*)),
+            this, SLOT(updateCheckBoxes(QStandardItem*)));
+    connect(m_hideReimplementedFunctions, SIGNAL(toggled(bool)),
+            this, SLOT(setHideReimplementedFunctions(bool)));
+}
+
+void InsertVirtualMethodsDialog::initData()
+{
+    m_insertKeywordVirtual = Core::ICore::settings()->value(
+                QLatin1String("QuickFix/InsertVirtualMethods/insertKeywordVirtual"),
+                false).toBool();
+    m_implementationMode = static_cast<InsertVirtualMethodsDialog::ImplementationMode>(
+                Core::ICore::settings()->value(
+                    QLatin1String("QuickFix/InsertVirtualMethods/implementationMode"), 1).toInt());
+    m_hideReimplementedFunctions->setChecked(
+                Core::ICore::settings()->value(
+                    QLatin1String("QuickFix/InsertVirtualMethods/hideReimplementedFunctions"),
+                    false).toBool());
+
+    m_view->setModel(classFunctionFilterModel);
+    m_expansionStateNormal.clear();
+    m_expansionStateReimp.clear();
+    m_hideReimplementedFunctions->setEnabled(m_hasReimplementedFunctions);
+    m_virtualKeyword->setChecked(m_insertKeywordVirtual);
+    m_insertMode->setCurrentIndex(m_insertMode->findData(m_implementationMode));
+
+    setHideReimplementedFunctions(m_hideReimplementedFunctions->isChecked());
+
+    if (m_hasImplementationFile) {
+        if (m_insertMode->count() == 3) {
+            m_insertMode->addItem(tr("Insert definitions in implementation file"),
+                                  ModeImplementationFile);
+        }
+    } else {
+        if (m_insertMode->count() == 4)
+            m_insertMode->removeItem(3);
+    }
+}
+
+bool InsertVirtualMethodsDialog::gather()
+{
+    initGui();
+    initData();
+
+    // Expand the dialog a little bit
+    adjustSize();
+    resize(size() * 1.5);
+
+    QPointer<InsertVirtualMethodsDialog> that(this);
+    const int ret = exec();
+    if (!that)
+        return false;
+
+    m_implementationMode = implementationMode();
+    m_insertKeywordVirtual = insertKeywordVirtual();
+    return (ret == QDialog::Accepted);
+}
+
+InsertVirtualMethodsDialog::ImplementationMode
+InsertVirtualMethodsDialog::implementationMode() const
+{
+    return static_cast<InsertVirtualMethodsDialog::ImplementationMode>(
+                m_insertMode->itemData(m_insertMode->currentIndex()).toInt());
+}
+
+void InsertVirtualMethodsDialog::setImplementationsMode(InsertVirtualMethodsDialog::ImplementationMode mode)
+{
+    m_implementationMode = mode;
+}
+
+bool InsertVirtualMethodsDialog::insertKeywordVirtual() const
+{
+    return m_virtualKeyword->isChecked();
+}
+
+void InsertVirtualMethodsDialog::setInsertKeywordVirtual(bool insert)
+{
+    m_insertKeywordVirtual = insert;
+}
+
+void InsertVirtualMethodsDialog::setHasImplementationFile(bool file)
+{
+    m_hasImplementationFile = file;
+}
+
+void InsertVirtualMethodsDialog::setHasReimplementedFunctions(bool functions)
+{
+    m_hasReimplementedFunctions = functions;
+}
+
+bool InsertVirtualMethodsDialog::hideReimplementedFunctions() const
+{
+    // Safty check necessary because of testing class
+    return (m_hideReimplementedFunctions && m_hideReimplementedFunctions->isChecked());
+}
+
+void InsertVirtualMethodsDialog::updateCheckBoxes(QStandardItem *item)
+{
+    if (item->hasChildren()) {
+        const Qt::CheckState state = item->checkState();
+        if (!item->isCheckable() || state == Qt::PartiallyChecked)
+            return;
+        for (int i = 0; i < item->rowCount(); ++i) {
+            QStandardItem *childItem = item->child(i, 0);
+            if (childItem->isCheckable() && childItem->isEnabled())
+                childItem->setCheckState(state);
+        }
+    } else {
+        QStandardItem *parent = item->parent();
+        if (!parent->isCheckable())
+            return;
+        const Qt::CheckState state = item->checkState();
+        for (int i = 0; i < parent->rowCount(); ++i) {
+            QStandardItem *childItem = parent->child(i, 0);
+            if (childItem->isEnabled() && state != childItem->checkState()) {
+                parent->setCheckState(Qt::PartiallyChecked);
+                return;
+            }
+        }
+        parent->setCheckState(state);
+    }
+}
+
+void InsertVirtualMethodsDialog::setHideReimplementedFunctions(bool hide)
+{
+    InsertVirtualMethodsFilterModel *model =
+            qobject_cast<InsertVirtualMethodsFilterModel *>(classFunctionFilterModel);
+
+    if (m_expansionStateNormal.isEmpty() && m_expansionStateReimp.isEmpty()) {
+        model->setHideReimplementedFunctions(hide);
+        m_view->expandAll();
+        saveExpansionState();
+        return;
+    }
+
+    if (model->hideReimplemented() == hide)
+        return;
+
+    saveExpansionState();
+    model->setHideReimplementedFunctions(hide);
+    restoreExpansionState();
+}
+
+void InsertVirtualMethodsDialog::saveExpansionState()
+{
+    InsertVirtualMethodsFilterModel *model =
+            qobject_cast<InsertVirtualMethodsFilterModel *>(classFunctionFilterModel);
+
+    QList<bool> &state = model->hideReimplemented() ? m_expansionStateReimp
+                                                    : m_expansionStateNormal;
+    state.clear();
+    for (int i = 0; i < model->rowCount(); ++i)
+        state << m_view->isExpanded(model->index(i, 0));
+}
+
+void InsertVirtualMethodsDialog::restoreExpansionState()
+{
+    InsertVirtualMethodsFilterModel *model =
+            qobject_cast<InsertVirtualMethodsFilterModel *>(classFunctionFilterModel);
+
+    const QList<bool> &state = model->hideReimplemented() ? m_expansionStateReimp
+                                                          : m_expansionStateNormal;
+    const int stateCount = state.count();
+    for (int i = 0; i < model->rowCount(); ++i) {
+        if (i < stateCount && !state.at(i)) {
+            m_view->collapse(model->index(i, 0));
+            continue;
+        }
+        m_view->expand(model->index(i, 0));
+    }
+}
+
+InsertVirtualMethods::InsertVirtualMethods(InsertVirtualMethodsDialog *dialog)
+    : m_dialog(dialog)
+{
+    if (!dialog)
+        m_dialog = new InsertVirtualMethodsDialog;
+}
+
+InsertVirtualMethods::~InsertVirtualMethods()
+{
+    m_dialog->deleteLater();
+}
+
+void InsertVirtualMethods::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
+{
+    InsertVirtualMethodsOp *op = new InsertVirtualMethodsOp(interface, m_dialog);
+    if (op->isValid())
+        result.append(QuickFixOperation::Ptr(op));
+    else
+        delete op;
+}
+
+#ifdef WITH_TESTS
+
+#include "cppeditorplugin.h"
+#include "cppquickfix_test.h"
+
+using namespace CppEditor::Internal::Tests;
+
+#include <QtTest>
+
+typedef QByteArray _;
+
+/// Fake dialog of InsertVirtualMethodsDialog that does not pop up anything.
+class InsertVirtualMethodsDialogTest : public InsertVirtualMethodsDialog
+{
+public:
+    InsertVirtualMethodsDialogTest(ImplementationMode mode, bool insertVirtualKeyword,
+                                   QWidget *parent = 0)
+        : InsertVirtualMethodsDialog(parent)
+    {
+        setImplementationsMode(mode);
+        setInsertKeywordVirtual(insertVirtualKeyword);
+    }
+
+    bool gather() { return true; }
+    ImplementationMode implementationMode() const { return m_implementationMode; }
+    bool insertKeywordVirtual() const { return m_insertKeywordVirtual; }
+};
+
+InsertVirtualMethods *InsertVirtualMethods::createTestFactory()
+{
+    return new InsertVirtualMethods(new InsertVirtualMethodsDialogTest(
+                                        InsertVirtualMethodsDialog::ModeOutsideClass, true));
+}
+
+Q_DECLARE_METATYPE(InsertVirtualMethodsDialog::ImplementationMode)
+
+void CppEditorPlugin::test_quickfix_InsertVirtualMethods_data()
+{
+    QTest::addColumn<InsertVirtualMethodsDialog::ImplementationMode>("implementationMode");
+    QTest::addColumn<bool>("insertVirtualKeyword");
+    QTest::addColumn<QByteArray>("original");
+    QTest::addColumn<QByteArray>("expected");
+
+    // Check: Insert only declarations
+    QTest::newRow("onlyDecl")
+        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int virtualFuncA() = 0;\n"
+        "};\n\n"
+        "class Derived : public Bas@eA {\n"
+        "};"
+        ) << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int virtualFuncA() = 0;\n"
+        "};\n\n"
+        "class Derived : public BaseA {\n"
+        "\n"
+        "    // BaseA interface\n"
+        "public:\n"
+        "    virtual int virtualFuncA();\n"
+        "};\n"
+    );
+
+    // Check: Insert only declarations vithout virtual keyword
+    QTest::newRow("onlyDeclWithoutVirtual")
+        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << false << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int virtualFuncA() = 0;\n"
+        "};\n\n"
+        "class Derived : public Bas@eA {\n"
+        "};"
+        ) << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int virtualFuncA() = 0;\n"
+        "};\n\n"
+        "class Derived : public BaseA {\n"
+        "\n"
+        "    // BaseA interface\n"
+        "public:\n"
+        "    int virtualFuncA();\n"
+        "};\n"
+    );
+
+    // Check: Are access specifiers considered
+    QTest::newRow("Access")
+        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int a() = 0;\n"
+        "protected:\n"
+        "    virtual int b() = 0;\n"
+        "private:\n"
+        "    virtual int c() = 0;\n"
+        "public slots:\n"
+        "    virtual int d() = 0;\n"
+        "protected slots:\n"
+        "    virtual int e() = 0;\n"
+        "private slots:\n"
+        "    virtual int f() = 0;\n"
+        "signals:\n"
+        "    virtual int g() = 0;\n"
+        "};\n\n"
+        "class Der@ived : public BaseA {\n"
+        "};"
+        ) << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int a() = 0;\n"
+        "protected:\n"
+        "    virtual int b() = 0;\n"
+        "private:\n"
+        "    virtual int c() = 0;\n"
+        "public slots:\n"
+        "    virtual int d() = 0;\n"
+        "protected slots:\n"
+        "    virtual int e() = 0;\n"
+        "private slots:\n"
+        "    virtual int f() = 0;\n"
+        "signals:\n"
+        "    virtual int g() = 0;\n"
+        "};\n\n"
+        "class Derived : public BaseA {\n"
+        "\n"
+        "    // BaseA interface\n"
+        "public:\n"
+        "    virtual int a();\n\n"
+        "protected:\n"
+        "    virtual int b();\n\n"
+        "private:\n"
+        "    virtual int c();\n\n"
+        "public slots:\n"
+        "    virtual int d();\n\n"
+        "protected slots:\n"
+        "    virtual int e();\n\n"
+        "private slots:\n"
+        "    virtual int f();\n\n"
+        "signals:\n"
+        "    virtual int g();\n"
+        "};\n"
+    );
+
+    // Check: Is a base class of a base class considered.
+    QTest::newRow("Superclass")
+        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int a() = 0;\n"
+        "};\n\n"
+        "class BaseB : public BaseA {\n"
+        "public:\n"
+        "    virtual int b() = 0;\n"
+        "};\n\n"
+        "class Der@ived : public BaseB {\n"
+        "};"
+        ) << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int a() = 0;\n"
+        "};\n\n"
+        "class BaseB : public BaseA {\n"
+        "public:\n"
+        "    virtual int b() = 0;\n"
+        "};\n\n"
+        "class Der@ived : public BaseB {\n"
+        "\n"
+        "    // BaseA interface\n"
+        "public:\n"
+        "    virtual int a();\n"
+        "\n"
+        "    // BaseB interface\n"
+        "public:\n"
+        "    virtual int b();\n"
+        "};\n"
+    );
+
+
+    // Check: Do not insert reimplemented functions twice.
+    QTest::newRow("SuperclassOverride")
+        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int a() = 0;\n"
+        "};\n\n"
+        "class BaseB : public BaseA {\n"
+        "public:\n"
+        "    virtual int a() = 0;\n"
+        "};\n\n"
+        "class Der@ived : public BaseB {\n"
+        "};"
+        ) << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int a() = 0;\n"
+        "};\n\n"
+        "class BaseB : public BaseA {\n"
+        "public:\n"
+        "    virtual int a() = 0;\n"
+        "};\n\n"
+        "class Der@ived : public BaseB {\n"
+        "\n"
+        "    // BaseA interface\n"
+        "public:\n"
+        "    virtual int a();\n"
+        "};\n"
+    );
+
+    // Check: Insert only declarations for pure virtual function
+    QTest::newRow("PureVirtualOnlyDecl")
+        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int virtualFuncA() = 0;\n"
+        "};\n\n"
+        "class Derived : public Bas@eA {\n"
+        "};"
+        ) << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int virtualFuncA() = 0;\n"
+        "};\n\n"
+        "class Derived : public BaseA {\n"
+        "\n"
+        "    // BaseA interface\n"
+        "public:\n"
+        "    virtual int virtualFuncA();\n"
+        "};\n"
+    );
+
+    // Check: Insert pure virtual functions inside class
+    QTest::newRow("PureVirtualInside")
+        << InsertVirtualMethodsDialog::ModeInsideClass << true << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int virtualFuncA() = 0;\n"
+        "};\n\n"
+        "class Derived : public Bas@eA {\n"
+        "};"
+        ) << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int virtualFuncA() = 0;\n"
+        "};\n\n"
+        "class Derived : public BaseA {\n"
+        "\n"
+        "    // BaseA interface\n"
+        "public:\n"
+        "    virtual int virtualFuncA()\n"
+        "    {\n"
+        "    }\n"
+        "};\n"
+    );
+
+    // Check: Insert inside class
+    QTest::newRow("inside")
+        << InsertVirtualMethodsDialog::ModeInsideClass << true << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int virtualFuncA() = 0;\n"
+        "};\n\n"
+        "class Derived : public Bas@eA {\n"
+        "};"
+        ) << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int virtualFuncA() = 0;\n"
+        "};\n\n"
+        "class Derived : public BaseA {\n"
+        "\n"
+        "    // BaseA interface\n"
+        "public:\n"
+        "    virtual int virtualFuncA()\n"
+        "    {\n"
+        "    }\n"
+        "};\n"
+    );
+
+    // Check: Insert outside class
+    QTest::newRow("outside")
+        << InsertVirtualMethodsDialog::ModeOutsideClass << true << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int virtualFuncA() = 0;\n"
+        "};\n\n"
+        "class Derived : public Bas@eA {\n"
+        "};"
+        ) << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int virtualFuncA() = 0;\n"
+        "};\n\n"
+        "class Derived : public BaseA {\n"
+        "\n"
+        "    // BaseA interface\n"
+        "public:\n"
+        "    virtual int virtualFuncA();\n"
+        "};\n\n"
+        "int Derived::virtualFuncA()\n"
+        "{\n"
+        "}\n"
+    );
+
+    // Check: No trigger: all implemented
+    QTest::newRow("notrigger_allImplemented")
+        << InsertVirtualMethodsDialog::ModeOutsideClass << true << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int virtualFuncA();\n"
+        "};\n\n"
+        "class Derived : public Bas@eA {\n"
+        "public:\n"
+        "    virtual int virtualFuncA() = 0;\n"
+        "};"
+        ) << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int virtualFuncA();\n"
+        "};\n\n"
+        "class Derived : public Bas@eA {\n"
+        "public:\n"
+        "    virtual int virtualFuncA() = 0;\n"
+        "};\n"
+    );
+
+    // Check: One pure, one not
+    QTest::newRow("Some_Pure")
+        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int virtualFuncA() = 0;\n"
+        "    virtual int virtualFuncB();\n"
+        "};\n\n"
+        "class Derived : public Bas@eA {\n"
+        "};"
+        ) << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int virtualFuncA() = 0;\n"
+        "    virtual int virtualFuncB();\n"
+        "};\n\n"
+        "class Derived : public BaseA {\n"
+        "\n"
+        "    // BaseA interface\n"
+        "public:\n"
+        "    virtual int virtualFuncA();\n"
+        "};\n"
+    );
+
+    // Check: Pure function in derived class
+    QTest::newRow("Pure_in_Derived")
+        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int a();\n"
+        "};\n\n"
+        "class BaseB : public BaseA {\n"
+        "public:\n"
+        "    virtual int a() = 0;\n"
+        "};\n\n"
+        "class Der@ived : public BaseB {\n"
+        "};"
+        ) << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int a();\n"
+        "};\n\n"
+        "class BaseB : public BaseA {\n"
+        "public:\n"
+        "    virtual int a() = 0;\n"
+        "};\n\n"
+        "class Der@ived : public BaseB {\n"
+        "\n"
+        "    // BaseA interface\n"
+        "public:\n"
+        "    virtual int a();\n"
+        "};\n"
+    );
+
+    // Check: One pure function in base class, one in derived
+    QTest::newRow("Pure_in_Base_And_Derived")
+        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int a() = 0;\n"
+        "    virtual int b();\n"
+        "};\n\n"
+        "class BaseB : public BaseA {\n"
+        "public:\n"
+        "    virtual int b() = 0;\n"
+        "};\n\n"
+        "class Der@ived : public BaseB {\n"
+        "};"
+        ) << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int a() = 0;\n"
+        "    virtual int b();\n"
+        "};\n\n"
+        "class BaseB : public BaseA {\n"
+        "public:\n"
+        "    virtual int b() = 0;\n"
+        "};\n\n"
+        "class Der@ived : public BaseB {\n"
+        "\n"
+        "    // BaseA interface\n"
+        "public:\n"
+        "    virtual int a();\n"
+        "    virtual int b();\n"
+        "};\n"
+    );
+
+    // Check: One pure function in base class, two in derived
+    QTest::newRow("Pure_in_Base_And_Derived_2")
+        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int a() = 0;\n"
+        "    virtual int b();\n"
+        "};\n\n"
+        "class BaseB : public BaseA {\n"
+        "public:\n"
+        "    virtual int b() = 0;\n"
+        "    virtual int c() = 0;\n"
+        "};\n\n"
+        "class Der@ived : public BaseB {\n"
+        "};"
+        ) << _(
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int a() = 0;\n"
+        "    virtual int b();\n"
+        "};\n\n"
+        "class BaseB : public BaseA {\n"
+        "public:\n"
+        "    virtual int b() = 0;\n"
+        "    virtual int c() = 0;\n"
+        "};\n\n"
+        "class Der@ived : public BaseB {\n"
+        "\n"
+        "    // BaseA interface\n"
+        "public:\n"
+        "    virtual int a();\n"
+        "    virtual int b();\n"
+        "\n"
+        "    // BaseB interface\n"
+        "public:\n"
+        "    virtual int c();\n"
+        "};\n"
+    );
+}
+
+void CppEditorPlugin::test_quickfix_InsertVirtualMethods()
+{
+    QFETCH(InsertVirtualMethodsDialog::ImplementationMode, implementationMode);
+    QFETCH(bool, insertVirtualKeyword);
+    QFETCH(QByteArray, original);
+    QFETCH(QByteArray, expected);
+
+    InsertVirtualMethods factory(
+                new InsertVirtualMethodsDialogTest(implementationMode, insertVirtualKeyword));
+    QuickFixTestCase(singleDocument(original, expected), &factory);
+}
+
+/// Check: Insert in implementation file
+void CppEditorPlugin::test_quickfix_InsertVirtualMethods_implementationFile()
+{
+    QList<QuickFixTestDocument::Ptr> testFiles;
+    QByteArray original;
+    QByteArray expected;
+
+    // Header File
+    original =
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int a() = 0;\n"
+        "};\n\n"
+        "class Derived : public Bas@eA {\n"
+        "public:\n"
+        "    Derived();\n"
+        "};";
+    expected =
+        "class BaseA {\n"
+        "public:\n"
+        "    virtual int a() = 0;\n"
+        "};\n\n"
+        "class Derived : public BaseA {\n"
+        "public:\n"
+        "    Derived();\n"
+        "\n"
+        "    // BaseA interface\n"
+        "public:\n"
+        "    virtual int a();\n"
+        "};\n";
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
+
+    // Source File
+    original = "#include \"file.h\"\n";
+    expected =
+        "#include \"file.h\"\n"
+        "\n\n"
+        "int Derived::a()\n"
+        "{\n}\n";
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
+
+    InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest(
+                                     InsertVirtualMethodsDialog::ModeImplementationFile, true));
+    QuickFixTestCase(testFiles, &factory);
+}
+
+/// Check: Qualified names.
+void CppEditorPlugin::test_quickfix_InsertVirtualMethods_BaseClassInNamespace()
+{
+    QList<QuickFixTestDocument::Ptr> testFiles;
+    QByteArray original;
+    QByteArray expected;
+
+    // Header File
+    original =
+        "namespace BaseNS {enum BaseEnum {EnumA = 1};}\n"
+        "namespace BaseNS {\n"
+        "class Base {\n"
+        "public:\n"
+        "    virtual BaseEnum a(BaseEnum e) = 0;\n"
+        "};\n"
+        "}\n"
+        "class Deri@ved : public BaseNS::Base {\n"
+        "public:\n"
+        "    Derived();\n"
+        "};";
+    expected =
+        "namespace BaseNS {enum BaseEnum {EnumA = 1};}\n"
+        "namespace BaseNS {\n"
+        "class Base {\n"
+        "public:\n"
+        "    virtual BaseEnum a(BaseEnum e) = 0;\n"
+        "};\n"
+        "}\n"
+        "class Deri@ved : public BaseNS::Base {\n"
+        "public:\n"
+        "    Derived();\n"
+        "\n"
+        "    // Base interface\n"
+        "public:\n"
+        "    virtual BaseNS::BaseEnum a(BaseNS::BaseEnum e);\n"
+        "};\n";
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
+
+    // Source File
+    original = "#include \"file.h\"\n";
+    expected =
+        "#include \"file.h\"\n"
+        "\n\n"
+        "BaseNS::BaseEnum Derived::a(BaseNS::BaseEnum e)\n"
+        "{\n}\n";
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
+
+    InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest(
+                                     InsertVirtualMethodsDialog::ModeImplementationFile, true));
+    QuickFixTestCase(testFiles, &factory);
+}
+#endif
+
+#include "cppinsertvirtualmethods.moc"
diff --git a/src/plugins/cppeditor/cppquickfix_test_utils.h b/src/plugins/cppeditor/cppinsertvirtualmethods.h
similarity index 69%
rename from src/plugins/cppeditor/cppquickfix_test_utils.h
rename to src/plugins/cppeditor/cppinsertvirtualmethods.h
index 71f2c14bff5..e6ffdb8f23d 100644
--- a/src/plugins/cppeditor/cppquickfix_test_utils.h
+++ b/src/plugins/cppeditor/cppinsertvirtualmethods.h
@@ -27,22 +27,32 @@
 **
 ****************************************************************************/
 
+#ifndef INSERTVIRTUALMETHODS_H
+#define INSERTVIRTUALMETHODS_H
 
-#ifndef CPPQUICKFIX_TEST_UTILS_H
-#define CPPQUICKFIX_TEST_UTILS_H
+#include "cppquickfix.h"
 
-#include "cppquickfixes.h"
+namespace CppEditor {
+namespace Internal {
 
-/// Fake dialog of InsertVirtualMethodsDialog that does not pop up anything.
-class InsertVirtualMethodsDialogTest : public CppEditor::Internal::InsertVirtualMethodsDialog
+class InsertVirtualMethodsDialog;
+
+class InsertVirtualMethods : public CppQuickFixFactory
 {
+    Q_OBJECT
 public:
-    InsertVirtualMethodsDialogTest(ImplementationMode mode, bool insertVirtualKeyword,
-                                   QWidget *parent = 0);
+    InsertVirtualMethods(InsertVirtualMethodsDialog *dialog = 0);
+    ~InsertVirtualMethods();
+    void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result);
+#ifdef WITH_TESTS
+    static InsertVirtualMethods *createTestFactory();
+#endif
 
-    bool gather();
-    ImplementationMode implementationMode() const;
-    bool insertKeywordVirtual() const;
+private:
+    InsertVirtualMethodsDialog *m_dialog;
 };
 
-#endif // CPPQUICKFIX_TEST_UTILS_H
+} // namespace Internal
+} // namespace CppEditor
+
+#endif // INSERTVIRTUALMETHODS_H
diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp
index 1a87985f17c..182d74f44e1 100644
--- a/src/plugins/cppeditor/cppquickfix_test.cpp
+++ b/src/plugins/cppeditor/cppquickfix_test.cpp
@@ -27,13 +27,12 @@
 **
 ****************************************************************************/
 
-#include "cppquickfix_test_utils.h"
-
 #include "cppeditor.h"
 #include "cppeditorplugin.h"
 #include "cppeditortestcase.h"
 #include "cppquickfixassistant.h"
 #include "cppquickfixes.h"
+#include "cppquickfix_test.h"
 
 #include <cpptools/cppcodestylepreferences.h>
 #include <cpptools/cppmodelmanager.h>
@@ -55,94 +54,45 @@ using namespace Core;
 using namespace CPlusPlus;
 using namespace CppEditor;
 using namespace CppEditor::Internal;
+using namespace CppEditor::Internal::Tests;
 using namespace CppTools;
 using namespace IncludeUtils;
 using namespace TextEditor;
 
 using CppTools::Tests::TestIncludePaths;
 
-namespace {
-
-typedef QByteArray _;
-
-class TestDocument;
-typedef QSharedPointer<TestDocument> TestDocumentPtr;
+namespace CppEditor {
+namespace Internal {
+namespace Tests {
 
-/**
- * Represents a test document before and after applying the quick fix.
- *
- * A TestDocument's source may contain an '@' character to denote
- * the cursor position. This marker is removed before the Editor reads
- * the document.
- */
-class TestDocument : public CppEditor::Internal::Tests::TestDocument
+QuickFixTestDocument::Ptr QuickFixTestDocument::create(const QByteArray &fileName,
+                                                       const QByteArray &source,
+                                                       const QByteArray &expectedSource)
 {
-public:
-    TestDocument(const QByteArray &fileName, const QByteArray &source,
-                 const QByteArray &expectedSource)
-        : CppEditor::Internal::Tests::TestDocument(fileName, source)
-        , m_expectedSource(expectedSource)
-    {
-        m_source.remove(m_cursorPosition, 1);
-        m_expectedSource.remove(expectedSource.indexOf(m_cursorMarker), 1);
-    }
-
-    static TestDocumentPtr create(const QByteArray &fileName, const QByteArray &source,
-                                  const QByteArray &expectedSource)
-    {
-        return TestDocumentPtr(new TestDocument(fileName, source, expectedSource));
-    }
+    return Ptr(new QuickFixTestDocument(fileName, source, expectedSource));
+}
 
-public:
-    QByteArray m_expectedSource;
-};
 
-QList<TestDocumentPtr> singleDocument(const QByteArray &original, const QByteArray &expected)
+QuickFixTestDocument::QuickFixTestDocument(const QByteArray &fileName,
+                                           const QByteArray &source,
+                                           const QByteArray &expectedSource)
+    : TestDocument(fileName, source)
+    , m_expectedSource(expectedSource)
 {
-    return QList<TestDocumentPtr>() << TestDocument::create("file.cpp", original, expected);
+    m_source.remove(m_cursorPosition, 1);
+    m_expectedSource.remove(expectedSource.indexOf(m_cursorMarker), 1);
 }
 
-/**
- * Encapsulates the whole process of setting up an editor, getting the
- * quick-fix, applying it, and checking the result.
- */
-class QuickFixTestCase : public CppEditor::Internal::Tests::TestCase
+QList<QuickFixTestDocument::Ptr> singleDocument(const QByteArray &original,
+                                                const QByteArray &expected)
 {
-public:
-    QuickFixTestCase(const QList<TestDocumentPtr> theTestFiles,
-                     CppQuickFixFactory *factory,
-                     const QStringList &includePaths = QStringList(),
-                     int resultIndex = 0);
-    ~QuickFixTestCase();
-
-private:
-    QuickFixOperation::Ptr getFix(CppQuickFixFactory *factory, CPPEditorWidget *editorWidget,
-                                  int resultIndex = 0);
-
-private:
-    QList<TestDocumentPtr> m_testFiles;
-
-    CppCodeStylePreferences *m_cppCodeStylePreferences;
-    QByteArray m_cppCodeStylePreferencesOriginalDelegateId;
-
-    QStringList m_includePathsToRestore;
-    bool m_restoreIncludePaths;
-};
-
-/// Apply the factory on the source and get back the resultIndex'th result or a null pointer.
-QuickFixOperation::Ptr QuickFixTestCase::getFix(CppQuickFixFactory *factory,
-                                                CPPEditorWidget *editorWidget,
-                                                int resultIndex)
-{
-    CppQuickFixInterface qfi(new CppQuickFixAssistInterface(editorWidget, ExplicitlyInvoked));
-    TextEditor::QuickFixOperations results;
-    factory->match(qfi, results);
-    return results.isEmpty() ? QuickFixOperation::Ptr() : results.at(resultIndex);
+    return QList<QuickFixTestDocument::Ptr>()
+            << QuickFixTestDocument::create("file.cpp", original, expected);
 }
 
 /// Leading whitespace is not removed, so we can check if the indetation ranges
 /// have been set correctly by the quick-fix.
-QByteArray &removeTrailingWhitespace(QByteArray &input)
+static QByteArray &removeTrailingWhitespace(QByteArray &input)
 {
     QList<QByteArray> lines = input.split('\n');
     input.resize(0);
@@ -160,9 +110,13 @@ QByteArray &removeTrailingWhitespace(QByteArray &input)
     return input;
 }
 
+} // namespace Tests
+} // namespace Internal
+} // namespace CppEditor
+
 /// The '@' in the originalSource is the position from where the quick-fix discovery is triggered.
 /// Exactly one TestFile must contain the cursor position marker '@' in the originalSource.
-QuickFixTestCase::QuickFixTestCase(const QList<TestDocumentPtr> theTestFiles,
+QuickFixTestCase::QuickFixTestCase(const QList<QuickFixTestDocument::Ptr> theTestFiles,
                                    CppQuickFixFactory *factory,
                                    const QStringList &includePaths,
                                    int resultIndex)
@@ -174,14 +128,14 @@ QuickFixTestCase::QuickFixTestCase(const QList<TestDocumentPtr> theTestFiles,
 
     // Check if there is exactly one cursor marker
     unsigned cursorMarkersCount = 0;
-    foreach (const TestDocumentPtr testFile, m_testFiles) {
+    foreach (const QuickFixTestDocument::Ptr testFile, m_testFiles) {
         if (testFile->hasCursorMarker())
             ++cursorMarkersCount;
     }
     QVERIFY2(cursorMarkersCount == 1, "Exactly one cursor marker is allowed.");
 
     // Write files to disk
-    foreach (TestDocumentPtr testFile, m_testFiles)
+    foreach (QuickFixTestDocument::Ptr testFile, m_testFiles)
         testFile->writeToDisk();
 
     // Set appropriate include paths
@@ -193,12 +147,12 @@ QuickFixTestCase::QuickFixTestCase(const QList<TestDocumentPtr> theTestFiles,
 
     // Update Code Model
     QStringList filePaths;
-    foreach (const TestDocumentPtr &testFile, m_testFiles)
+    foreach (const QuickFixTestDocument::Ptr &testFile, m_testFiles)
         filePaths << testFile->filePath();
     QVERIFY(parseFiles(filePaths));
 
     // Open Files
-    foreach (TestDocumentPtr testFile, m_testFiles) {
+    foreach (QuickFixTestDocument::Ptr testFile, m_testFiles) {
         QVERIFY(openCppEditor(testFile->filePath(), &testFile->m_editor,
                               &testFile->m_editorWidget));
         closeEditorAtEndOfTestCase(testFile->m_editor);
@@ -220,8 +174,8 @@ QuickFixTestCase::QuickFixTestCase(const QList<TestDocumentPtr> theTestFiles,
     m_cppCodeStylePreferences->setCurrentDelegate("qt");
 
     // Run the fix in the file having the cursor marker
-    TestDocumentPtr testFile;
-    foreach (const TestDocumentPtr file, m_testFiles) {
+    QuickFixTestDocument::Ptr testFile;
+    foreach (const QuickFixTestDocument::Ptr file, m_testFiles) {
         if (file->hasCursorMarker())
             testFile = file;
     }
@@ -233,7 +187,7 @@ QuickFixTestCase::QuickFixTestCase(const QList<TestDocumentPtr> theTestFiles,
         qDebug() << "Quickfix was not triggered";
 
     // Compare all files
-    foreach (const TestDocumentPtr testFile, m_testFiles) {
+    foreach (const QuickFixTestDocument::Ptr testFile, m_testFiles) {
         // Check
         QByteArray result = testFile->m_editorWidget->document()->toPlainText().toUtf8();
         removeTrailingWhitespace(result);
@@ -258,7 +212,7 @@ QuickFixTestCase::~QuickFixTestCase()
         m_modelManager->setIncludePaths(m_includePathsToRestore);
 
     // Remove created files from file system
-    foreach (const TestDocumentPtr &testDocument, m_testFiles)
+    foreach (const QuickFixTestDocument::Ptr &testDocument, m_testFiles)
         QVERIFY(QFile::remove(testDocument->filePath()));
 }
 
@@ -279,7 +233,15 @@ private:
     const QString m_include;
 };
 
-} // anonymous namespace
+/// Apply the factory on the source and get back the resultIndex'th result or a null pointer.
+QSharedPointer<TextEditor::QuickFixOperation> QuickFixTestCase::getFix(
+        CppQuickFixFactory *factory, CPPEditorWidget *editorWidget, int resultIndex)
+{
+    CppQuickFixInterface qfi(new CppQuickFixAssistInterface(editorWidget, ExplicitlyInvoked));
+    TextEditor::QuickFixOperations results;
+    factory->match(qfi, results);
+    return results.isEmpty() ? QuickFixOperation::Ptr() : results.at(resultIndex);
+}
 
 typedef QSharedPointer<CppQuickFixFactory> CppQuickFixFactoryPtr;
 
@@ -1194,7 +1156,7 @@ void CppEditorPlugin::test_quickfix()
 /// generated definitions should fit in the namespace.
 void CppEditorPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithPrefixAndNamespaceToCpp()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -1217,7 +1179,7 @@ void CppEditorPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithPrefixAn
         "    void setIt(int value);\n"
         "};\n"
         "}\n\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -1237,7 +1199,7 @@ void CppEditorPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithPrefixAn
         "    it = value;\n"
         "}\n\n"
         "}\n\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     GenerateGetterSetter factory;
     QuickFixTestCase(testFiles, &factory);
@@ -1246,7 +1208,7 @@ void CppEditorPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithPrefixAn
 /// Check if definition is inserted right after class for insert definition outside
 void CppEditorPlugin::test_quickfix_InsertDefFromDecl_afterClass()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -1270,7 +1232,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_afterClass()
         "{\n\n}\n"
         "\n"
         "class Bar {};\n\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -1280,7 +1242,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_afterClass()
         "{\n\n"
         "}\n";
     expected = original + "\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     InsertDefFromDecl factory;
     QuickFixTestCase(testFiles, &factory, QStringList(), 1);
@@ -1290,7 +1252,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_afterClass()
 /// Case: Source file is empty.
 void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_basic1()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -1302,7 +1264,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_basic1()
         "    Foo()@;\n"
         "};\n";
     expected = original + "\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original.resize(0);
@@ -1313,7 +1275,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_basic1()
         "}\n"
         "\n"
         ;
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     InsertDefFromDecl factory;
     QuickFixTestCase(testFiles, &factory);
@@ -1323,7 +1285,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_basic1()
 /// Case: Source file is not empty.
 void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_basic2()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -1331,7 +1293,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_basic2()
     // Header File
     original = "void f()@;\n";
     expected = original + "\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -1351,7 +1313,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_basic2()
             "}\n"
             "\n"
             ;
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     InsertDefFromDecl factory;
     QuickFixTestCase(testFiles, &factory);
@@ -1360,13 +1322,13 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_basic2()
 /// Check from source file: Insert in source file, not header file.
 void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_basic3()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
 
     // Empty Header File
-    testFiles << TestDocument::create("file.h", "", "\n");
+    testFiles << QuickFixTestDocument::create("file.h", "", "\n");
 
     // Source File
     original =
@@ -1382,7 +1344,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_basic3()
         "}\n"
         "\n"
         ;
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     InsertDefFromDecl factory;
     QuickFixTestCase(testFiles, &factory);
@@ -1392,7 +1354,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_basic3()
 /// name must be qualified accordingly.
 void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_namespace1()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -1406,7 +1368,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_namespace1()
         "};\n"
         "}\n";
     expected = original + "\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original.resize(0);
@@ -1417,7 +1379,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_namespace1()
         "}\n"
         "\n"
         ;
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     InsertDefFromDecl factory;
     QuickFixTestCase(testFiles, &factory);
@@ -1427,7 +1389,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_namespace1()
 /// "using namespace N" line, the function definition name must be qualified accordingly.
 void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_namespace2()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -1441,7 +1403,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_namespace2()
         "};\n"
         "}\n";
     expected = original + "\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -1456,7 +1418,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_namespace2()
             "}\n"
             "\n"
             ;
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     InsertDefFromDecl factory;
     QuickFixTestCase(testFiles, &factory);
@@ -1497,7 +1459,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_notTriggeringWhenDefinitio
 /// Find right implementation file.
 void CppEditorPlugin::test_quickfix_InsertDefFromDecl_findRightImplementationFile()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -1512,7 +1474,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_findRightImplementationFil
         "};\n"
         "}\n";
     expected = original + "\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File #1
     original =
@@ -1523,7 +1485,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_findRightImplementationFil
             "}\n"
             "\n";
     expected = original + "\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
 
     // Source File #2
@@ -1539,7 +1501,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_findRightImplementationFil
             "{\n\n"
             "}\n"
             "\n";
-    testFiles << TestDocument::create("file2.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file2.cpp", original, expected);
 
     InsertDefFromDecl factory;
     QuickFixTestCase(testFiles, &factory);
@@ -1549,7 +1511,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_findRightImplementationFil
 /// functions declarations in order to find the right implementation file.
 void CppEditorPlugin::test_quickfix_InsertDefFromDecl_ignoreSurroundingGeneratedDeclarations()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -1565,7 +1527,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_ignoreSurroundingGenerated
         "};\n"
         "}\n";
     expected = original + '\n';
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File #1
     original =
@@ -1585,7 +1547,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_ignoreSurroundingGenerated
             "{\n\n"
             "}\n"
             "\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     // Source File #2
     original =
@@ -1595,7 +1557,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_ignoreSurroundingGenerated
             "{\n\n"
             "}\n";
     expected = original + '\n';
-    testFiles << TestDocument::create("file2.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file2.cpp", original, expected);
 
     InsertDefFromDecl factory;
     QuickFixTestCase(testFiles, &factory);
@@ -1655,7 +1617,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_respectWsInOperatorNames2(
 /// Case: Macro preceded by preproceesor directives and declaration.
 void CppEditorPlugin::test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile1()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -1663,7 +1625,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile1()
     // Header File
     original = "void f()@;\n";
     expected = original + "\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -1688,7 +1650,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile1()
             "MACRO(int)\n"
             "\n"
             ;
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     InsertDefFromDecl factory;
     QuickFixTestCase(testFiles, &factory);
@@ -1698,7 +1660,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile1()
 /// Case: Marco preceded only by preprocessor directives.
 void CppEditorPlugin::test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile2()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -1706,7 +1668,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile2()
     // Header File
     original = "void f()@;\n";
     expected = original + "\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -1729,7 +1691,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile2()
             "MACRO(int)\n"
             "\n"
             ;
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     InsertDefFromDecl factory;
     QuickFixTestCase(testFiles, &factory);
@@ -1738,7 +1700,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile2()
 /// Check if insertion happens before syntactically erroneous statements at end of file.
 void CppEditorPlugin::test_quickfix_InsertDefFromDecl_erroneousStatementAtEndOfFile()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -1746,7 +1708,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_erroneousStatementAtEndOfF
     // Header File
     original = "void f()@;\n";
     expected = original + "\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -1767,7 +1729,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_erroneousStatementAtEndOfF
             "MissingSemicolon(int)\n"
             "\n"
             ;
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     InsertDefFromDecl factory;
     QuickFixTestCase(testFiles, &factory);
@@ -1776,7 +1738,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_erroneousStatementAtEndOfF
 /// Check: Respect rvalue references
 void CppEditorPlugin::test_quickfix_InsertDefFromDecl_rvalueReference()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -1784,7 +1746,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_rvalueReference()
     // Header File
     original = "void f(Foo &&)@;\n";
     expected = original + "\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original = "";
@@ -1796,7 +1758,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_rvalueReference()
             "}\n"
             "\n"
             ;
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     InsertDefFromDecl factory;
     QuickFixTestCase(testFiles, &factory);
@@ -1805,7 +1767,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_rvalueReference()
 // Function for one of InsertDeclDef section cases
 void insertToSectionDeclFromDef(const QByteArray &section, int sectionIndex)
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -1821,7 +1783,7 @@ void insertToSectionDeclFromDef(const QByteArray &section, int sectionIndex)
         + section + ":\n" +
         "    Foo();\n"
         "@};\n\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -1833,7 +1795,7 @@ void insertToSectionDeclFromDef(const QByteArray &section, int sectionIndex)
         "\n"
         ;
     expected = original + "\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     InsertDeclFromDef factory;
     QuickFixTestCase(testFiles, &factory, QStringList(), sectionIndex);
@@ -2009,7 +1971,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_detectInclu
 /// Check: Add include if there is already an include
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_normal()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2017,7 +1979,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_normal()
     // Header File
     original = "class Foo {};\n";
     expected = original + "\n";
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8() + "/afile.h",
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8() + "/afile.h",
                                       original, expected);
 
     // Source File
@@ -2039,7 +2001,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_normal()
         "}\n"
         "\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
                                       + "/afile.cpp", original, expected);
 
     // Do not use the test factory, at least once we want to go through the "full stack".
@@ -2050,7 +2012,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_normal()
 /// Check: Ignore *.moc includes
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_ignoremoc()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2066,7 +2028,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_ignoremoc()
         "#include \"file.moc\";\n"
         "\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
                                       + "/file.cpp", original, expected);
 
     AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\""));
@@ -2076,7 +2038,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_ignoremoc()
 /// Check: Insert include at top for a sorted group
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_sortingTop()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2092,7 +2054,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_sortingTop(
         "#include \"z.h\"\n"
         "\n\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
                                       + "/file.cpp", original, expected);
 
     AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\""));
@@ -2102,7 +2064,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_sortingTop(
 /// Check: Insert include in the middle for a sorted group
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_sortingMiddle()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2118,7 +2080,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_sortingMidd
         "#include \"z.h\"\n"
         "\n\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
                                       + "/file.cpp", original, expected);
 
     AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\""));
@@ -2128,7 +2090,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_sortingMidd
 /// Check: Insert include at bottom for a sorted group
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_sortingBottom()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2144,7 +2106,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_sortingBott
         "#include \"file.h\"\n"
         "\n\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
                                       + "/file.cpp", original, expected);
 
     AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\""));
@@ -2154,7 +2116,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_sortingBott
 /// Check: For an unsorted group the new include is appended
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_appendToUnsorted()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2170,7 +2132,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_appendToUns
         "#include \"file.h\"\n"
         "\n\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8() +
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8() +
                                       + "/file.cpp", original, expected);
 
     AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\""));
@@ -2180,7 +2142,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_appendToUns
 /// Check: Insert a local include at front if there are only global includes
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_firstLocalIncludeAtFront()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2197,7 +2159,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_firstLocalI
         "#include <b.h>\n"
         "\n\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
                                       + "/file.cpp", original, expected);
 
     AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\""));
@@ -2207,7 +2169,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_firstLocalI
 /// Check: Insert a global include at back if there are only local includes
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_firstGlobalIncludeAtBack()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2227,7 +2189,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_firstGlobal
         "void f();\n"
         "\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
                                       + "/file.cpp", original, expected);
 
     AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("<file.h>"));
@@ -2237,7 +2199,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_firstGlobal
 /// Check: Prefer group with longest matching prefix
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_preferGroupWithLongerMatchingPrefix()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2257,7 +2219,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_preferGroup
         "#include \"foo.h\"\n"
         "\n\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
                                       + "/file.cpp", original, expected);
 
     AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"prefixc.h\""));
@@ -2267,7 +2229,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_preferGroup
 /// Check: Create a new include group if there are only include groups with a different include dir
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_newGroupIfOnlyDifferentIncludeDirs()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2284,7 +2246,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_newGroupIfO
         "#include \"file.h\"\n"
         "\n\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
                                       + "/file.cpp", original, expected);
 
     AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\""));
@@ -2294,7 +2256,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_newGroupIfO
 /// Check: Include group with mixed include dirs, sorted --> insert properly
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedDirsSorted()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2312,7 +2274,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedDirsSo
         "#include <utils/file.h>\n"
         "\n\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
                                       + "/file.cpp", original, expected);
 
     AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("<firstlib/file.h>"));
@@ -2322,7 +2284,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedDirsSo
 /// Check: Include group with mixed include dirs, unsorted --> append
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedDirsUnsorted()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2340,7 +2302,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedDirsUn
         "#include <lastlib/file.h>\n"
         "\n\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
                                       + "/file.cpp", original, expected);
 
     AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("<lastlib/file.h>"));
@@ -2350,7 +2312,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedDirsUn
 /// Check: Include group with mixed include types
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedIncludeTypes1()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2366,7 +2328,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedInclud
         "#include <global.h>\n"
         "\n\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
                                       + "/file.cpp", original, expected);
 
     AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"z.h\""));
@@ -2376,7 +2338,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedInclud
 /// Check: Include group with mixed include types
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedIncludeTypes2()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2392,7 +2354,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedInclud
         "#include <global.h>\n"
         "\n\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
                                       + "/file.cpp", original, expected);
 
     AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"a.h\""));
@@ -2402,7 +2364,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedInclud
 /// Check: Include group with mixed include types
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedIncludeTypes3()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2418,7 +2380,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedInclud
         "#include <global.h>\n"
         "\n\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
                                       + "/file.cpp", original, expected);
 
     AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"lib/file.h\""));
@@ -2428,7 +2390,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedInclud
 /// Check: Include group with mixed include types
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedIncludeTypes4()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2444,7 +2406,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedInclud
         "#include <lib/file.h>\n"
         "\n\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
                                       + "/file.cpp", original, expected);
 
     AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("<lib/file.h>"));
@@ -2454,7 +2416,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_mixedInclud
 /// Check: Insert very first include
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_noinclude()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2468,7 +2430,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_noinclude()
         "void f();\n"
         "\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
                                       + "/file.cpp", original, expected);
 
     AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\""));
@@ -2478,7 +2440,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_noinclude()
 /// Check: Insert very first include if there is a c++ style comment on top
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_veryFirstIncludeCppStyleCommentOnTop()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2498,7 +2460,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_veryFirstIn
         "void @f();\n"
         "\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
                                       + "/file.cpp", original, expected);
 
     AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\""));
@@ -2508,7 +2470,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_veryFirstIn
 /// Check: Insert very first include if there is a c style comment on top
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_veryFirstIncludeCStyleCommentOnTop()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2532,7 +2494,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_veryFirstIn
         "void @f();\n"
         "\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
                                       + "/file.cpp", original, expected);
 
     AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\""));
@@ -2543,7 +2505,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_veryFirstIn
 /// include paths
 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_checkQSomethingInQtIncludePaths()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
 
     QByteArray original;
     QByteArray expected;
@@ -2557,7 +2519,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_checkQSomet
         "QDir dir;\n"
         "\n"
         ;
-    testFiles << TestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
+    testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
                                       + "/file.cpp", original, expected);
 
     AddIncludeForUndefinedIdentifier factory;
@@ -2568,7 +2530,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_checkQSomet
 /// Check: Move definition from header to cpp.
 void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCpp()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -2588,7 +2550,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCpp()
         "\n"
         "    void bar();\n"
         "};\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -2602,7 +2564,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCpp()
         "    return 5;\n"
         "}\n"
         "\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     MoveFuncDefOutside factory;
     QuickFixTestCase(testFiles, &factory);
@@ -2610,7 +2572,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCpp()
 
 void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCppInsideNS()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -2630,7 +2592,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCppInsideNS()
         "  int ba@r();\n"
         "};\n"
         "}\n\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -2648,7 +2610,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCppInsideNS()
         "}\n"
         "\n"
         "}\n\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     MoveFuncDefOutside factory;
     QuickFixTestCase(testFiles, &factory);
@@ -2691,7 +2653,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncOutside1()
 /// Check: Move definition outside class
 void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncOutside2()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -2716,7 +2678,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncOutside2()
         "{\n"
         "    return 1;\n"
         "}\n\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -2724,7 +2686,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncOutside2()
         "void Foo::f1() {}\n"
         "void Foo::f3() {}\n";
     expected = original + "\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     MoveFuncDefOutside factory;
     QuickFixTestCase(testFiles, &factory, QStringList(), 1);
@@ -2733,7 +2695,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncOutside2()
 /// Check: Move definition from header to cpp (with namespace).
 void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCppNS()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -2753,7 +2715,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCppNS()
         "  inline int number() const;\n"
         "};\n"
         "}\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -2767,7 +2729,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCppNS()
         "    return 5;\n"
         "}\n"
         "\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     MoveFuncDefOutside factory;
     QuickFixTestCase(testFiles, &factory);
@@ -2776,7 +2738,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCppNS()
 /// Check: Move definition from header to cpp (with namespace + using).
 void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCppNSUsing()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -2796,7 +2758,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCppNSUsing()
         "  inline int number() const;\n"
         "};\n"
         "}\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -2812,7 +2774,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCppNSUsing()
         "    return 5;\n"
         "}\n"
         "\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     MoveFuncDefOutside factory;
     QuickFixTestCase(testFiles, &factory);
@@ -2848,7 +2810,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncOutsideWithNs()
 /// Check: Move free function from header to cpp.
 void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_FreeFuncToCpp()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -2861,7 +2823,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_FreeFuncToCpp()
     expected =
         "int number() const;\n"
         "\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -2875,7 +2837,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_FreeFuncToCpp()
         "    return 5;\n"
         "}\n"
         "\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     MoveFuncDefOutside factory;
     QuickFixTestCase(testFiles, &factory);
@@ -2884,7 +2846,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_FreeFuncToCpp()
 /// Check: Move free function from header to cpp (with namespace).
 void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_FreeFuncToCppNS()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -2901,7 +2863,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_FreeFuncToCppNS()
         "int number() const;\n"
         "}\n"
         "\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -2915,7 +2877,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_FreeFuncToCppNS()
         "    return 5;\n"
         "}\n"
         "\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     MoveFuncDefOutside factory;
     QuickFixTestCase(testFiles, &factory);
@@ -2924,7 +2886,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_FreeFuncToCppNS()
 /// Check: Move Ctor with member initialization list (QTCREATORBUG-9157).
 void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_CtorWithInitialization1()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -2945,7 +2907,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_CtorWithInitialization1()
         "    int a;\n"
         "    float b;\n"
         "};\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original ="#include \"file.h\"\n";
@@ -2955,7 +2917,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_CtorWithInitialization1()
         "\n"
         "Foo::Foo() : a(42), b(3.141) {}\n"
         "\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     MoveFuncDefOutside factory;
     QuickFixTestCase(testFiles, &factory);
@@ -2964,7 +2926,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_CtorWithInitialization1()
 /// Check: Move Ctor with member initialization list (QTCREATORBUG-9462).
 void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_CtorWithInitialization2()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -2988,7 +2950,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_CtorWithInitialization2()
         "\n"
         "    int member;\n"
         "};\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original ="#include \"file.h\"\n";
@@ -3000,7 +2962,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_CtorWithInitialization2()
         "{\n"
         "}\n"
         "\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     MoveFuncDefOutside factory;
     QuickFixTestCase(testFiles, &factory);
@@ -3009,7 +2971,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_CtorWithInitialization2()
 /// Check if definition is inserted right after class for move definition outside
 void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_afterClass()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -3032,7 +2994,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_afterClass()
         "void Foo::a() {}\n"
         "\n"
         "class Bar {};\n\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -3042,7 +3004,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_afterClass()
         "{\n\n"
         "}\n";
     expected = original + "\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     MoveFuncDefOutside factory;
     QuickFixTestCase(testFiles, &factory, QStringList(), 1);
@@ -3095,7 +3057,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_respectWsInOperatorNames2
 /// Check: revert test_quickfix_MoveFuncDefOutside_MemberFuncToCpp()
 void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFunc()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -3108,7 +3070,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFunc()
         "class Foo {\n"
         "    inline int number() const {return 5;}\n"
         "};\n\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -3118,7 +3080,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFunc()
     expected =
         "#include \"file.h\"\n"
         "\n\n\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     MoveFuncDefToDecl factory;
     QuickFixTestCase(testFiles, &factory);
@@ -3153,7 +3115,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFuncOutside()
 /// Check: revert test_quickfix_MoveFuncDefOutside_MemberFuncToCppNS()
 void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFuncToCppNS()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -3173,7 +3135,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFuncToCppNS()
         "    }\n"
         "};\n"
         "}\n\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -3184,7 +3146,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFuncToCppNS()
         "    return 5;\n"
         "}\n";
     expected = "#include \"file.h\"\n\n\n\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     MoveFuncDefToDecl factory;
     QuickFixTestCase(testFiles, &factory);
@@ -3193,7 +3155,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFuncToCppNS()
 /// Check: revert test_quickfix_MoveFuncDefOutside_MemberFuncToCppNSUsing()
 void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFuncToCppNSUsing()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -3213,7 +3175,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFuncToCppNSUsing()
         "    }\n"
         "};\n"
         "}\n\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -3228,7 +3190,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFuncToCppNSUsing()
         "#include \"file.h\"\n"
         "using namespace MyNs;\n"
         "\n\n\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     MoveFuncDefToDecl factory;
     QuickFixTestCase(testFiles, &factory);
@@ -3264,7 +3226,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFuncOutsideWithNs()
 /// Check: revert test_quickfix_MoveFuncDefOutside_FreeFuncToCpp()
 void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_FreeFuncToCpp()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -3275,7 +3237,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_FreeFuncToCpp()
         "{\n"
         "    return 5;\n"
         "}\n\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -3287,7 +3249,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_FreeFuncToCpp()
         "    return 5;\n"
         "}\n";
     expected = "#include \"file.h\"\n\n\n\n\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     MoveFuncDefToDecl factory;
     QuickFixTestCase(testFiles, &factory);
@@ -3296,7 +3258,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_FreeFuncToCpp()
 /// Check: revert test_quickfix_MoveFuncDefOutside_FreeFuncToCppNS()
 void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_FreeFuncToCppNS()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -3312,7 +3274,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_FreeFuncToCppNS()
         "    return 5;\n"
         "}\n"
         "}\n\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -3325,7 +3287,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_FreeFuncToCppNS()
     expected =
         "#include \"file.h\"\n"
         "\n\n\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     MoveFuncDefToDecl factory;
     QuickFixTestCase(testFiles, &factory);
@@ -3334,7 +3296,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_FreeFuncToCppNS()
 /// Check: revert test_quickfix_MoveFuncDefOutside_CtorWithInitialization()
 void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_CtorWithInitialization()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -3355,7 +3317,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_CtorWithInitialization()
         "    int a;\n"
         "    float b;\n"
         "};\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -3364,7 +3326,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_CtorWithInitialization()
         "Foo::F@oo() : a(42), b(3.141) {}"
         ;
     expected ="#include \"file.h\"\n\n\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     MoveFuncDefToDecl factory;
     QuickFixTestCase(testFiles, &factory);
@@ -3399,7 +3361,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_structWithAssignedVariable
 void CppEditorPlugin::test_quickfix_AssignToLocalVariable_templates()
 {
 
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -3412,7 +3374,7 @@ void CppEditorPlugin::test_quickfix_AssignToLocalVariable_templates()
         "};\n"
         ;
     expected = original + "\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -3427,7 +3389,7 @@ void CppEditorPlugin::test_quickfix_AssignToLocalVariable_templates()
         "    List<int> list;\n"
         "    int localFirst = list.first();\n"
         "}\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     AssignToLocalVariable factory;
     QuickFixTestCase(testFiles, &factory);
@@ -3499,7 +3461,7 @@ void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_typeDeduction()
 
 void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_freeFunction_separateFiles()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -3508,7 +3470,7 @@ void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_freeFunction_separ
         "void foo(const char *a, long b = 1);";
     expected =
         "void foo(const char *a, long b = 1, int newParameter = 156);\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -3517,7 +3479,7 @@ void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_freeFunction_separ
     expected =
         "void foo(const char *a, long b, int newParameter)\n"
         "{return newParameter + 123 + newParameter;}\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     ExtractLiteralAsParameter factory;
     QuickFixTestCase(testFiles, &factory);
@@ -3525,7 +3487,7 @@ void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_freeFunction_separ
 
 void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_memberFunction_separateFiles()
 {
-    QList<TestDocumentPtr> testFiles;
+    QList<QuickFixTestDocument::Ptr> testFiles;
     QByteArray original;
     QByteArray expected;
 
@@ -3540,7 +3502,7 @@ void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_memberFunction_sep
         "public:\n"
         "    int zort(int newParameter = 155);\n"
         "};\n";
-    testFiles << TestDocument::create("file.h", original, expected);
+    testFiles << QuickFixTestDocument::create("file.h", original, expected);
 
     // Source File
     original =
@@ -3551,538 +3513,8 @@ void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_memberFunction_sep
         "#include \"file.h\"\n\n"
         "int Narf::zort(int newParameter)\n"
         "{ return newParameter + 1; }\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
+    testFiles << QuickFixTestDocument::create("file.cpp", original, expected);
 
     ExtractLiteralAsParameter factory;
     QuickFixTestCase(testFiles, &factory);
 }
-
-Q_DECLARE_METATYPE(InsertVirtualMethodsDialog::ImplementationMode)
-
-void CppEditorPlugin::test_quickfix_InsertVirtualMethods_data()
-{
-    QTest::addColumn<InsertVirtualMethodsDialog::ImplementationMode>("implementationMode");
-    QTest::addColumn<bool>("insertVirtualKeyword");
-    QTest::addColumn<QByteArray>("original");
-    QTest::addColumn<QByteArray>("expected");
-
-    // Check: Insert only declarations
-    QTest::newRow("onlyDecl")
-        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int virtualFuncA() = 0;\n"
-        "};\n\n"
-        "class Derived : public Bas@eA {\n"
-        "};"
-        ) << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int virtualFuncA() = 0;\n"
-        "};\n\n"
-        "class Derived : public BaseA {\n"
-        "\n"
-        "    // BaseA interface\n"
-        "public:\n"
-        "    virtual int virtualFuncA();\n"
-        "};\n"
-    );
-
-    // Check: Insert only declarations vithout virtual keyword
-    QTest::newRow("onlyDeclWithoutVirtual")
-        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << false << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int virtualFuncA() = 0;\n"
-        "};\n\n"
-        "class Derived : public Bas@eA {\n"
-        "};"
-        ) << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int virtualFuncA() = 0;\n"
-        "};\n\n"
-        "class Derived : public BaseA {\n"
-        "\n"
-        "    // BaseA interface\n"
-        "public:\n"
-        "    int virtualFuncA();\n"
-        "};\n"
-    );
-
-    // Check: Are access specifiers considered
-    QTest::newRow("Access")
-        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int a() = 0;\n"
-        "protected:\n"
-        "    virtual int b() = 0;\n"
-        "private:\n"
-        "    virtual int c() = 0;\n"
-        "public slots:\n"
-        "    virtual int d() = 0;\n"
-        "protected slots:\n"
-        "    virtual int e() = 0;\n"
-        "private slots:\n"
-        "    virtual int f() = 0;\n"
-        "signals:\n"
-        "    virtual int g() = 0;\n"
-        "};\n\n"
-        "class Der@ived : public BaseA {\n"
-        "};"
-        ) << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int a() = 0;\n"
-        "protected:\n"
-        "    virtual int b() = 0;\n"
-        "private:\n"
-        "    virtual int c() = 0;\n"
-        "public slots:\n"
-        "    virtual int d() = 0;\n"
-        "protected slots:\n"
-        "    virtual int e() = 0;\n"
-        "private slots:\n"
-        "    virtual int f() = 0;\n"
-        "signals:\n"
-        "    virtual int g() = 0;\n"
-        "};\n\n"
-        "class Derived : public BaseA {\n"
-        "\n"
-        "    // BaseA interface\n"
-        "public:\n"
-        "    virtual int a();\n\n"
-        "protected:\n"
-        "    virtual int b();\n\n"
-        "private:\n"
-        "    virtual int c();\n\n"
-        "public slots:\n"
-        "    virtual int d();\n\n"
-        "protected slots:\n"
-        "    virtual int e();\n\n"
-        "private slots:\n"
-        "    virtual int f();\n\n"
-        "signals:\n"
-        "    virtual int g();\n"
-        "};\n"
-    );
-
-    // Check: Is a base class of a base class considered.
-    QTest::newRow("Superclass")
-        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int a() = 0;\n"
-        "};\n\n"
-        "class BaseB : public BaseA {\n"
-        "public:\n"
-        "    virtual int b() = 0;\n"
-        "};\n\n"
-        "class Der@ived : public BaseB {\n"
-        "};"
-        ) << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int a() = 0;\n"
-        "};\n\n"
-        "class BaseB : public BaseA {\n"
-        "public:\n"
-        "    virtual int b() = 0;\n"
-        "};\n\n"
-        "class Der@ived : public BaseB {\n"
-        "\n"
-        "    // BaseA interface\n"
-        "public:\n"
-        "    virtual int a();\n"
-        "\n"
-        "    // BaseB interface\n"
-        "public:\n"
-        "    virtual int b();\n"
-        "};\n"
-    );
-
-
-    // Check: Do not insert reimplemented functions twice.
-    QTest::newRow("SuperclassOverride")
-        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int a() = 0;\n"
-        "};\n\n"
-        "class BaseB : public BaseA {\n"
-        "public:\n"
-        "    virtual int a() = 0;\n"
-        "};\n\n"
-        "class Der@ived : public BaseB {\n"
-        "};"
-        ) << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int a() = 0;\n"
-        "};\n\n"
-        "class BaseB : public BaseA {\n"
-        "public:\n"
-        "    virtual int a() = 0;\n"
-        "};\n\n"
-        "class Der@ived : public BaseB {\n"
-        "\n"
-        "    // BaseA interface\n"
-        "public:\n"
-        "    virtual int a();\n"
-        "};\n"
-    );
-
-    // Check: Insert only declarations for pure virtual function
-    QTest::newRow("PureVirtualOnlyDecl")
-        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int virtualFuncA() = 0;\n"
-        "};\n\n"
-        "class Derived : public Bas@eA {\n"
-        "};"
-        ) << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int virtualFuncA() = 0;\n"
-        "};\n\n"
-        "class Derived : public BaseA {\n"
-        "\n"
-        "    // BaseA interface\n"
-        "public:\n"
-        "    virtual int virtualFuncA();\n"
-        "};\n"
-    );
-
-    // Check: Insert pure virtual functions inside class
-    QTest::newRow("PureVirtualInside")
-        << InsertVirtualMethodsDialog::ModeInsideClass << true << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int virtualFuncA() = 0;\n"
-        "};\n\n"
-        "class Derived : public Bas@eA {\n"
-        "};"
-        ) << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int virtualFuncA() = 0;\n"
-        "};\n\n"
-        "class Derived : public BaseA {\n"
-        "\n"
-        "    // BaseA interface\n"
-        "public:\n"
-        "    virtual int virtualFuncA()\n"
-        "    {\n"
-        "    }\n"
-        "};\n"
-    );
-
-    // Check: Insert inside class
-    QTest::newRow("inside")
-        << InsertVirtualMethodsDialog::ModeInsideClass << true << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int virtualFuncA() = 0;\n"
-        "};\n\n"
-        "class Derived : public Bas@eA {\n"
-        "};"
-        ) << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int virtualFuncA() = 0;\n"
-        "};\n\n"
-        "class Derived : public BaseA {\n"
-        "\n"
-        "    // BaseA interface\n"
-        "public:\n"
-        "    virtual int virtualFuncA()\n"
-        "    {\n"
-        "    }\n"
-        "};\n"
-    );
-
-    // Check: Insert outside class
-    QTest::newRow("outside")
-        << InsertVirtualMethodsDialog::ModeOutsideClass << true << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int virtualFuncA() = 0;\n"
-        "};\n\n"
-        "class Derived : public Bas@eA {\n"
-        "};"
-        ) << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int virtualFuncA() = 0;\n"
-        "};\n\n"
-        "class Derived : public BaseA {\n"
-        "\n"
-        "    // BaseA interface\n"
-        "public:\n"
-        "    virtual int virtualFuncA();\n"
-        "};\n\n"
-        "int Derived::virtualFuncA()\n"
-        "{\n"
-        "}\n"
-    );
-
-    // Check: No trigger: all implemented
-    QTest::newRow("notrigger_allImplemented")
-        << InsertVirtualMethodsDialog::ModeOutsideClass << true << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int virtualFuncA();\n"
-        "};\n\n"
-        "class Derived : public Bas@eA {\n"
-        "public:\n"
-        "    virtual int virtualFuncA() = 0;\n"
-        "};"
-        ) << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int virtualFuncA();\n"
-        "};\n\n"
-        "class Derived : public Bas@eA {\n"
-        "public:\n"
-        "    virtual int virtualFuncA() = 0;\n"
-        "};\n"
-    );
-
-    // Check: One pure, one not
-    QTest::newRow("Some_Pure")
-        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int virtualFuncA() = 0;\n"
-        "    virtual int virtualFuncB();\n"
-        "};\n\n"
-        "class Derived : public Bas@eA {\n"
-        "};"
-        ) << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int virtualFuncA() = 0;\n"
-        "    virtual int virtualFuncB();\n"
-        "};\n\n"
-        "class Derived : public BaseA {\n"
-        "\n"
-        "    // BaseA interface\n"
-        "public:\n"
-        "    virtual int virtualFuncA();\n"
-        "};\n"
-    );
-
-    // Check: Pure function in derived class
-    QTest::newRow("Pure_in_Derived")
-        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int a();\n"
-        "};\n\n"
-        "class BaseB : public BaseA {\n"
-        "public:\n"
-        "    virtual int a() = 0;\n"
-        "};\n\n"
-        "class Der@ived : public BaseB {\n"
-        "};"
-        ) << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int a();\n"
-        "};\n\n"
-        "class BaseB : public BaseA {\n"
-        "public:\n"
-        "    virtual int a() = 0;\n"
-        "};\n\n"
-        "class Der@ived : public BaseB {\n"
-        "\n"
-        "    // BaseA interface\n"
-        "public:\n"
-        "    virtual int a();\n"
-        "};\n"
-    );
-
-    // Check: One pure function in base class, one in derived
-    QTest::newRow("Pure_in_Base_And_Derived")
-        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int a() = 0;\n"
-        "    virtual int b();\n"
-        "};\n\n"
-        "class BaseB : public BaseA {\n"
-        "public:\n"
-        "    virtual int b() = 0;\n"
-        "};\n\n"
-        "class Der@ived : public BaseB {\n"
-        "};"
-        ) << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int a() = 0;\n"
-        "    virtual int b();\n"
-        "};\n\n"
-        "class BaseB : public BaseA {\n"
-        "public:\n"
-        "    virtual int b() = 0;\n"
-        "};\n\n"
-        "class Der@ived : public BaseB {\n"
-        "\n"
-        "    // BaseA interface\n"
-        "public:\n"
-        "    virtual int a();\n"
-        "    virtual int b();\n"
-        "};\n"
-    );
-
-    // Check: One pure function in base class, two in derived
-    QTest::newRow("Pure_in_Base_And_Derived_2")
-        << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int a() = 0;\n"
-        "    virtual int b();\n"
-        "};\n\n"
-        "class BaseB : public BaseA {\n"
-        "public:\n"
-        "    virtual int b() = 0;\n"
-        "    virtual int c() = 0;\n"
-        "};\n\n"
-        "class Der@ived : public BaseB {\n"
-        "};"
-        ) << _(
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int a() = 0;\n"
-        "    virtual int b();\n"
-        "};\n\n"
-        "class BaseB : public BaseA {\n"
-        "public:\n"
-        "    virtual int b() = 0;\n"
-        "    virtual int c() = 0;\n"
-        "};\n\n"
-        "class Der@ived : public BaseB {\n"
-        "\n"
-        "    // BaseA interface\n"
-        "public:\n"
-        "    virtual int a();\n"
-        "    virtual int b();\n"
-        "\n"
-        "    // BaseB interface\n"
-        "public:\n"
-        "    virtual int c();\n"
-        "};\n"
-    );
-}
-
-void CppEditorPlugin::test_quickfix_InsertVirtualMethods()
-{
-    QFETCH(InsertVirtualMethodsDialog::ImplementationMode, implementationMode);
-    QFETCH(bool, insertVirtualKeyword);
-    QFETCH(QByteArray, original);
-    QFETCH(QByteArray, expected);
-
-    InsertVirtualMethods factory(
-                new InsertVirtualMethodsDialogTest(implementationMode, insertVirtualKeyword));
-    QuickFixTestCase(singleDocument(original, expected), &factory);
-}
-
-/// Check: Insert in implementation file
-void CppEditorPlugin::test_quickfix_InsertVirtualMethods_implementationFile()
-{
-    QList<TestDocumentPtr> testFiles;
-    QByteArray original;
-    QByteArray expected;
-
-    // Header File
-    original =
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int a() = 0;\n"
-        "};\n\n"
-        "class Derived : public Bas@eA {\n"
-        "public:\n"
-        "    Derived();\n"
-        "};";
-    expected =
-        "class BaseA {\n"
-        "public:\n"
-        "    virtual int a() = 0;\n"
-        "};\n\n"
-        "class Derived : public BaseA {\n"
-        "public:\n"
-        "    Derived();\n"
-        "\n"
-        "    // BaseA interface\n"
-        "public:\n"
-        "    virtual int a();\n"
-        "};\n";
-    testFiles << TestDocument::create("file.h", original, expected);
-
-    // Source File
-    original = "#include \"file.h\"\n";
-    expected =
-        "#include \"file.h\"\n"
-        "\n\n"
-        "int Derived::a()\n"
-        "{\n}\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
-
-    InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest(
-                                     InsertVirtualMethodsDialog::ModeImplementationFile, true));
-    QuickFixTestCase(testFiles, &factory);
-}
-
-/// Check: Qualified names.
-void CppEditorPlugin::test_quickfix_InsertVirtualMethods_BaseClassInNamespace()
-{
-    QList<TestDocumentPtr> testFiles;
-    QByteArray original;
-    QByteArray expected;
-
-    // Header File
-    original =
-        "namespace BaseNS {enum BaseEnum {EnumA = 1};}\n"
-        "namespace BaseNS {\n"
-        "class Base {\n"
-        "public:\n"
-        "    virtual BaseEnum a(BaseEnum e) = 0;\n"
-        "};\n"
-        "}\n"
-        "class Deri@ved : public BaseNS::Base {\n"
-        "public:\n"
-        "    Derived();\n"
-        "};";
-    expected =
-        "namespace BaseNS {enum BaseEnum {EnumA = 1};}\n"
-        "namespace BaseNS {\n"
-        "class Base {\n"
-        "public:\n"
-        "    virtual BaseEnum a(BaseEnum e) = 0;\n"
-        "};\n"
-        "}\n"
-        "class Deri@ved : public BaseNS::Base {\n"
-        "public:\n"
-        "    Derived();\n"
-        "\n"
-        "    // Base interface\n"
-        "public:\n"
-        "    virtual BaseNS::BaseEnum a(BaseNS::BaseEnum e);\n"
-        "};\n";
-    testFiles << TestDocument::create("file.h", original, expected);
-
-    // Source File
-    original = "#include \"file.h\"\n";
-    expected =
-        "#include \"file.h\"\n"
-        "\n\n"
-        "BaseNS::BaseEnum Derived::a(BaseNS::BaseEnum e)\n"
-        "{\n}\n";
-    testFiles << TestDocument::create("file.cpp", original, expected);
-
-    InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest(
-                                     InsertVirtualMethodsDialog::ModeImplementationFile, true));
-    QuickFixTestCase(testFiles, &factory);
-}
diff --git a/src/plugins/cppeditor/cppquickfix_test.h b/src/plugins/cppeditor/cppquickfix_test.h
new file mode 100644
index 00000000000..58eaa1f949e
--- /dev/null
+++ b/src/plugins/cppeditor/cppquickfix_test.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "cppeditortestcase.h"
+
+#include <QByteArray>
+#include <QList>
+#include <QSharedPointer>
+#include <QStringList>
+
+typedef QByteArray _;
+
+namespace CppTools { class CppCodeStylePreferences; }
+namespace TextEditor { class QuickFixOperation; }
+
+namespace CppEditor {
+namespace Internal {
+namespace Tests {
+
+/**
+ * Represents a test document before and after applying the quick fix.
+ *
+ * A TestDocument's source may contain an '@' character to denote
+ * the cursor position. This marker is removed before the Editor reads
+ * the document.
+ */
+class QuickFixTestDocument : public TestDocument
+{
+public:
+    typedef QSharedPointer<QuickFixTestDocument> Ptr;
+
+    QuickFixTestDocument(const QByteArray &fileName, const QByteArray &source,
+                         const QByteArray &expectedSource);
+
+    static Ptr create(const QByteArray &fileName, const QByteArray &source,
+                                  const QByteArray &expectedSource);
+
+public:
+    QByteArray m_expectedSource;
+};
+
+/**
+ * Encapsulates the whole process of setting up an editor, getting the
+ * quick-fix, applying it, and checking the result.
+ */
+class QuickFixTestCase : public TestCase
+{
+public:
+    QuickFixTestCase(const QList<QuickFixTestDocument::Ptr> theTestFiles,
+                     CppQuickFixFactory *factory,
+                     const QStringList &includePaths = QStringList(),
+                     int resultIndex = 0);
+    ~QuickFixTestCase();
+
+private:
+    QSharedPointer<TextEditor::QuickFixOperation> getFix(CppQuickFixFactory *factory,
+                                                         CPPEditorWidget *editorWidget,
+                                                         int resultIndex = 0);
+
+private:
+    QList<QuickFixTestDocument::Ptr> m_testFiles;
+
+    CppTools::CppCodeStylePreferences *m_cppCodeStylePreferences;
+    QByteArray m_cppCodeStylePreferencesOriginalDelegateId;
+
+    QStringList m_includePathsToRestore;
+    bool m_restoreIncludePaths;
+};
+
+QList<QuickFixTestDocument::Ptr> singleDocument(const QByteArray &original,
+                                                const QByteArray &expected);
+
+} // namespace Tests
+} // namespace Internal
+} // namespace CppEditor
diff --git a/src/plugins/cppeditor/cppquickfix_test_utils.cpp b/src/plugins/cppeditor/cppquickfix_test_utils.cpp
deleted file mode 100644
index c4eae0afb26..00000000000
--- a/src/plugins/cppeditor/cppquickfix_test_utils.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia.  For licensing terms and
-** conditions see http://qt.digia.com/licensing.  For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights.  These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-****************************************************************************/
-
-#include "cppquickfix_test_utils.h"
-
-#include "cppquickfixes.h"
-
-using namespace CppEditor::Internal;
-
-InsertVirtualMethodsDialogTest::InsertVirtualMethodsDialogTest(ImplementationMode mode,
-                                                               bool insertVirtualKeyword,
-                                                               QWidget *parent)
-    : InsertVirtualMethodsDialog(parent)
-{
-    setImplementationsMode(mode);
-    setInsertKeywordVirtual(insertVirtualKeyword);
-}
-
-InsertVirtualMethodsDialog::ImplementationMode InsertVirtualMethodsDialogTest::implementationMode() const
-{
-    return m_implementationMode;
-}
-
-bool InsertVirtualMethodsDialogTest::insertKeywordVirtual() const
-{
-    return m_insertKeywordVirtual;
-}
-
-bool InsertVirtualMethodsDialogTest::gather()
-{
-    return true;
-}
diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp
index 9a0107f330b..b3c729a9d1b 100644
--- a/src/plugins/cppeditor/cppquickfixes.cpp
+++ b/src/plugins/cppeditor/cppquickfixes.cpp
@@ -33,6 +33,7 @@
 #include "cppfunctiondecldeflink.h"
 #include "cppquickfixassistant.h"
 #include "cppvirtualfunctionassistprovider.h"
+#include "cppinsertvirtualmethods.h"
 
 #include <coreplugin/icore.h>
 
@@ -41,7 +42,6 @@
 #include <cpptools/cpppointerdeclarationformatter.h>
 #include <cpptools/cpptoolsconstants.h>
 #include <cpptools/cpptoolsreuse.h>
-#include <cpptools/functionutils.h>
 #include <cpptools/includeutils.h>
 #include <cpptools/insertionpointlocator.h>
 #include <cpptools/symbolfinder.h>
@@ -54,33 +54,15 @@
 
 #include <extensionsystem/pluginmanager.h>
 
-#include <texteditor/fontsettings.h>
-#include <texteditor/texteditorsettings.h>
-
 #include <utils/qtcassert.h>
 
 #include <QApplication>
-#include <QCheckBox>
-#include <QComboBox>
-#include <QDialogButtonBox>
 #include <QDir>
 #include <QFileInfo>
-#include <QGroupBox>
-#include <QHBoxLayout>
 #include <QInputDialog>
-#include <QItemDelegate>
-#include <QLabel>
 #include <QMessageBox>
-#include <QPointer>
-#include <QPushButton>
-#include <QQueue>
 #include <QSharedPointer>
-#include <QSortFilterProxyModel>
-#include <QStandardItemModel>
-#include <QTextBlock>
 #include <QTextCursor>
-#include <QTreeView>
-#include <QVBoxLayout>
 
 #include <cctype>
 
@@ -89,7 +71,6 @@ using namespace CppEditor;
 using namespace CppEditor::Internal;
 using namespace CppTools;
 using namespace TextEditor;
-using namespace Utils;
 
 void CppEditor::Internal::registerQuickFixes(ExtensionSystem::IPlugin *plugIn)
 {
@@ -4679,728 +4660,6 @@ void AssignToLocalVariable::match(const CppQuickFixInterface &interface, QuickFi
 
 namespace {
 
-class InsertVirtualMethodsOp : public CppQuickFixOperation
-{
-public:
-    InsertVirtualMethodsOp(const QSharedPointer<const CppQuickFixAssistInterface> &interface,
-                           InsertVirtualMethodsDialog *factory)
-        : CppQuickFixOperation(interface, 0)
-        , m_factory(factory)
-        , m_classAST(0)
-        , m_valid(false)
-        , m_cppFileName(QString::null)
-        , m_insertPosDecl(0)
-        , m_insertPosOutside(0)
-        , m_functionCount(0)
-    {
-        setDescription(QCoreApplication::translate(
-                           "CppEditor::QuickFix", "Insert Virtual Functions of Base Classes"));
-
-        const QList<AST *> &path = interface->path();
-        const int pathSize = path.size();
-        if (pathSize < 2)
-            return;
-
-        // Determine if cursor is on a class or a base class
-        if (SimpleNameAST *nameAST = path.at(pathSize - 1)->asSimpleName()) {
-            if (!interface->isCursorOn(nameAST))
-                return;
-
-            if (!(m_classAST = path.at(pathSize - 2)->asClassSpecifier())) { // normal class
-                int index = pathSize - 2;
-                const BaseSpecifierAST *baseAST = path.at(index)->asBaseSpecifier();// simple bclass
-                if (!baseAST) {
-                    if (index > 0 && path.at(index)->asQualifiedName()) // namespaced base class
-                        baseAST = path.at(--index)->asBaseSpecifier();
-                }
-                --index;
-                if (baseAST && index >= 0)
-                    m_classAST = path.at(index)->asClassSpecifier();
-            }
-        }
-        if (!m_classAST || !m_classAST->base_clause_list)
-            return;
-
-        // Determine insert positions
-        const int endOfClassAST = interface->currentFile()->endOf(m_classAST);
-        m_insertPosDecl = endOfClassAST - 1; // Skip last "}"
-        m_insertPosOutside = endOfClassAST + 1; // Step over ";"
-
-        // Determine base classes
-        QList<const Class *> baseClasses;
-        QQueue<ClassOrNamespace *> baseClassQueue;
-        QSet<ClassOrNamespace *> visitedBaseClasses;
-        if (ClassOrNamespace *clazz = interface->context().lookupType(m_classAST->symbol))
-            baseClassQueue.enqueue(clazz);
-        while (!baseClassQueue.isEmpty()) {
-            ClassOrNamespace *clazz = baseClassQueue.dequeue();
-            visitedBaseClasses.insert(clazz);
-            const QList<ClassOrNamespace *> bases = clazz->usings();
-            foreach (ClassOrNamespace *baseClass, bases) {
-                foreach (Symbol *symbol, baseClass->symbols()) {
-                    Class *base = symbol->asClass();
-                    if (base
-                            && (clazz = interface->context().lookupType(symbol))
-                            && !visitedBaseClasses.contains(clazz)
-                            && !baseClasses.contains(base)) {
-                        baseClasses.prepend(base);
-                        baseClassQueue.enqueue(clazz);
-                    }
-                }
-            }
-        }
-
-        // Determine virtual functions
-        m_factory->classFunctionModel->clear();
-        Overview printer = CppCodeStyleSettings::currentProjectCodeStyleOverview();
-        printer.showFunctionSignatures = true;
-        const TextEditor::FontSettings &fs = TextEditor::TextEditorSettings::fontSettings();
-        const Format formatReimpFunc = fs.formatFor(C_DISABLED_CODE);
-        QHash<const Function *, QStandardItem *> virtualFunctions;
-        foreach (const Class *clazz, baseClasses) {
-            QStandardItem *itemBase = new QStandardItem(printer.prettyName(clazz->name()));
-            itemBase->setData(false, InsertVirtualMethodsDialog::Reimplemented);
-            itemBase->setData(qVariantFromValue((void *) clazz),
-                              InsertVirtualMethodsDialog::ClassOrFunction);
-            for (Scope::iterator it = clazz->firstMember(); it != clazz->lastMember(); ++it) {
-                if (const Function *func = (*it)->type()->asFunctionType()) {
-                    // Filter virtual destructors
-                    if (func->name()->asDestructorNameId())
-                        continue;
-
-                    const Function *firstVirtual = 0;
-                    const bool isVirtual = FunctionUtils::isVirtualFunction(
-                                func, interface->context(), &firstVirtual);
-                    if (!isVirtual)
-                        continue;
-
-                    // Filter OQbject's
-                    //   - virtual const QMetaObject *metaObject() const;
-                    //   - virtual void *qt_metacast(const char *);
-                    //   - virtual int qt_metacall(QMetaObject::Call, int, void **);
-                    if (printer.prettyName(firstVirtual->enclosingClass()->name())
-                            == QLatin1String("QObject")) {
-                        const QString funcName = printer.prettyName(func->name());
-                        if (funcName == QLatin1String("metaObject")
-                                || funcName == QLatin1String("qt_metacast")
-                                || funcName == QLatin1String("qt_metacall")) {
-                            continue;
-                        }
-                    }
-
-                    // Do not implement existing functions inside target class
-                    bool funcExistsInClass = false;
-                    const Name *funcName = func->name();
-                    for (Symbol *symbol = m_classAST->symbol->find(funcName->identifier());
-                         symbol; symbol = symbol->next()) {
-                        if (!symbol->name()
-                                || !funcName->identifier()->isEqualTo(symbol->identifier())) {
-                            continue;
-                        }
-                        if (symbol->type().isEqualTo(func->type())) {
-                            funcExistsInClass = true;
-                            break;
-                        }
-                    }
-
-                    // Construct function item
-                    const bool isReimplemented = (func != firstVirtual);
-                    const bool isPureVirtual = func->isPureVirtual();
-                    QString itemName = printer.prettyType(func->type(), func->name());
-                    if (isPureVirtual)
-                        itemName += QLatin1String(" = 0");
-                    const QString itemReturnTypeString = printer.prettyType(func->returnType());
-                    itemName += QLatin1String(" : ") + itemReturnTypeString;
-                    if (isReimplemented)
-                        itemName += QLatin1String(" (redeclared)");
-                    QStandardItem *funcItem = new QStandardItem(itemName);
-                    funcItem->setCheckable(true);
-                    if (isReimplemented) {
-                        factory->setHasReimplementedFunctions(true);
-                        funcItem->setEnabled(false);
-                        funcItem->setCheckState(Qt::Unchecked);
-                        if (QStandardItem *first = virtualFunctions[firstVirtual]) {
-                            if (!first->data(InsertVirtualMethodsDialog::Reimplemented).toBool()) {
-                                first->setCheckState(isPureVirtual ? Qt::Checked : Qt::Unchecked);
-                                factory->updateCheckBoxes(first);
-                            }
-                        }
-                    } else {
-                        if (!funcExistsInClass) {
-                            funcItem->setCheckState(isPureVirtual ? Qt::Checked : Qt::Unchecked);
-                        } else {
-                            funcItem->setEnabled(false);
-                            funcItem->setCheckState(Qt::Checked);
-                            funcItem->setData(formatReimpFunc.foreground(), Qt::ForegroundRole);
-                            factory->setHasReimplementedFunctions(true);
-                            if (formatReimpFunc.background().isValid())
-                                funcItem->setData(formatReimpFunc.background(), Qt::BackgroundRole);
-                        }
-                    }
-
-                    funcItem->setData(qVariantFromValue((void *) func),
-                                      InsertVirtualMethodsDialog::ClassOrFunction);
-                    funcItem->setData(isPureVirtual, InsertVirtualMethodsDialog::PureVirtual);
-                    funcItem->setData(acessSpec(*it), InsertVirtualMethodsDialog::AccessSpec);
-                    funcItem->setData(funcExistsInClass || isReimplemented,
-                                      InsertVirtualMethodsDialog::Reimplemented);
-
-                    itemBase->appendRow(funcItem);
-                    virtualFunctions[func] = funcItem;
-
-                    // update internal counters
-                    if (!funcExistsInClass)
-                        ++m_functionCount;
-                }
-            }
-            if (itemBase->hasChildren()) {
-                itemBase->setData(false, InsertVirtualMethodsDialog::Reimplemented);
-                bool enabledFound = false;
-                Qt::CheckState state = Qt::Unchecked;
-                for (int i = 0; i < itemBase->rowCount(); ++i) {
-                    QStandardItem *childItem = itemBase->child(i, 0);
-                    if (!childItem->isEnabled())
-                        continue;
-                    if (!enabledFound) {
-                        state = childItem->checkState();
-                        enabledFound = true;
-                    }
-                    if (childItem->isCheckable()) {
-                        if (!itemBase->isCheckable()) {
-                            itemBase->setCheckable(true);
-                            itemBase->setTristate(true);
-                            itemBase->setCheckState(state);
-                        }
-                        if (state != childItem->checkState()) {
-                            itemBase->setCheckState(Qt::PartiallyChecked);
-                            break;
-                        }
-                    }
-                }
-                if (!enabledFound) {
-                    itemBase->setCheckable(true);
-                    itemBase->setEnabled(false);
-                }
-                m_factory->classFunctionModel->invisibleRootItem()->appendRow(itemBase);
-            }
-        }
-        if (!m_factory->classFunctionModel->invisibleRootItem()->hasChildren()
-                || m_functionCount == 0) {
-            return;
-        }
-
-        bool isHeaderFile = false;
-        m_cppFileName = correspondingHeaderOrSource(interface->fileName(), &isHeaderFile);
-        m_factory->setHasImplementationFile(isHeaderFile && !m_cppFileName.isEmpty());
-
-        m_valid = true;
-    }
-
-    bool isValid() const
-    {
-        return m_valid;
-    }
-
-    InsertionPointLocator::AccessSpec acessSpec(const Symbol *symbol)
-    {
-        const Function *func = symbol->type()->asFunctionType();
-        if (!func)
-            return InsertionPointLocator::Invalid;
-        if (func->isSignal())
-            return InsertionPointLocator::Signals;
-
-        InsertionPointLocator::AccessSpec spec = InsertionPointLocator::Invalid;
-        if (symbol->isPrivate())
-            spec = InsertionPointLocator::Private;
-        else if (symbol->isProtected())
-            spec = InsertionPointLocator::Protected;
-        else if (symbol->isPublic())
-            spec = InsertionPointLocator::Public;
-        else
-            return InsertionPointLocator::Invalid;
-
-        if (func->isSlot()) {
-            switch (spec) {
-            case InsertionPointLocator::Private:
-                return InsertionPointLocator::PrivateSlot;
-            case InsertionPointLocator::Protected:
-                return InsertionPointLocator::ProtectedSlot;
-            case InsertionPointLocator::Public:
-                return InsertionPointLocator::PublicSlot;
-            default:
-                return spec;
-            }
-        }
-        return spec;
-    }
-
-    void perform()
-    {
-        if (!m_factory->gather())
-            return;
-
-        Core::ICore::settings()->setValue(
-                    QLatin1String("QuickFix/InsertVirtualMethods/insertKeywordVirtual"),
-                    m_factory->insertKeywordVirtual());
-        Core::ICore::settings()->setValue(
-                    QLatin1String("QuickFix/InsertVirtualMethods/implementationMode"),
-                    m_factory->implementationMode());
-        Core::ICore::settings()->setValue(
-                    QLatin1String("QuickFix/InsertVirtualMethods/hideReimplementedFunctions"),
-                    m_factory->hideReimplementedFunctions());
-
-        // Insert declarations (and definition if Inside-/OutsideClass)
-        Overview printer = CppCodeStyleSettings::currentProjectCodeStyleOverview();
-        printer.showFunctionSignatures = true;
-        printer.showReturnTypes = true;
-        printer.showArgumentNames = true;
-        ChangeSet headerChangeSet;
-        const CppRefactoringChanges refactoring(assistInterface()->snapshot());
-        const QString filename = assistInterface()->currentFile()->fileName();
-        const CppRefactoringFilePtr headerFile = refactoring.file(filename);
-        const LookupContext targetContext(headerFile->cppDocument(), assistInterface()->snapshot());
-
-        const Class *targetClass = m_classAST->symbol;
-        ClassOrNamespace *targetCoN = targetContext.lookupType(targetClass->enclosingScope());
-        if (!targetCoN)
-            targetCoN = targetContext.globalNamespace();
-        UseMinimalNames useMinimalNames(targetCoN);
-        Control *control = assistInterface()->context().bindings()->control().data();
-        for (int i = 0; i < m_factory->classFunctionModel->rowCount(); ++i) {
-            const QStandardItem *parent =
-                    m_factory->classFunctionModel->invisibleRootItem()->child(i, 0);
-            if (!parent->isCheckable() || parent->checkState() == Qt::Unchecked)
-                continue;
-            const Class *clazz = (const Class *)
-                    parent->data(InsertVirtualMethodsDialog::ClassOrFunction).value<void *>();
-
-            // Add comment
-            const QString comment = QLatin1String("\n// ") + printer.prettyName(clazz->name()) +
-                    QLatin1String(" interface\n");
-            headerChangeSet.insert(m_insertPosDecl, comment);
-
-            // Insert Declarations (+ definitions)
-            QString lastAccessSpecString;
-            for (int j = 0; j < parent->rowCount(); ++j) {
-                const QStandardItem *item = parent->child(j, 0);
-                if (!item->isEnabled() || !item->isCheckable() || item->checkState() == Qt::Unchecked)
-                    continue;
-                const Function *func = (const Function *)
-                        item->data(InsertVirtualMethodsDialog::ClassOrFunction).value<void *>();
-
-                // Construct declaration
-                // setup rewriting to get minimally qualified names
-                SubstitutionEnvironment env;
-                env.setContext(assistInterface()->context());
-                env.switchScope(clazz->enclosingScope());
-                env.enter(&useMinimalNames);
-
-                QString declaration;
-                const FullySpecifiedType tn = rewriteType(func->type(), &env, control);
-                declaration += printer.prettyType(tn, func->unqualifiedName());
-
-                if (m_factory->insertKeywordVirtual())
-                    declaration = QLatin1String("virtual ") + declaration;
-                if (m_factory->implementationMode() & InsertVirtualMethodsDialog::ModeInsideClass)
-                    declaration += QLatin1String("\n{\n}\n");
-                else
-                    declaration += QLatin1String(";\n");
-
-                const InsertionPointLocator::AccessSpec spec =
-                        static_cast<InsertionPointLocator::AccessSpec>(
-                            item->data(InsertVirtualMethodsDialog::AccessSpec).toInt());
-                const QString accessSpecString = InsertionPointLocator::accessSpecToString(spec);
-                if (accessSpecString != lastAccessSpecString) {
-                    declaration = accessSpecString + declaration;
-                    if (!lastAccessSpecString.isEmpty()) // separate if not direct after the comment
-                        declaration = QLatin1String("\n") + declaration;
-                    lastAccessSpecString = accessSpecString;
-                }
-                headerChangeSet.insert(m_insertPosDecl, declaration);
-
-                // Insert definition outside class
-                if (m_factory->implementationMode() & InsertVirtualMethodsDialog::ModeOutsideClass) {
-                    const QString name = printer.prettyName(targetClass->name()) +
-                            QLatin1String("::") + printer.prettyName(func->name());
-                    const QString defText = printer.prettyType(tn, name) + QLatin1String("\n{\n}");
-                    headerChangeSet.insert(m_insertPosOutside,  QLatin1String("\n\n") + defText);
-                }
-            }
-        }
-
-        // Write header file
-        headerFile->setChangeSet(headerChangeSet);
-        headerFile->appendIndentRange(ChangeSet::Range(m_insertPosDecl, m_insertPosDecl + 1));
-        headerFile->setOpenEditor(true, m_insertPosDecl);
-        headerFile->apply();
-
-        // Insert in implementation file
-        if (m_factory->implementationMode() & InsertVirtualMethodsDialog::ModeImplementationFile) {
-            const Symbol *symbol = headerFile->cppDocument()->lastVisibleSymbolAt(
-                        targetClass->line(), targetClass->column());
-            if (!symbol)
-                return;
-            const Class *clazz = symbol->asClass();
-            if (!clazz)
-                return;
-
-            CppRefactoringFilePtr implementationFile = refactoring.file(m_cppFileName);
-            ChangeSet implementationChangeSet;
-            const int insertPos = qMax(0, implementationFile->document()->characterCount() - 1);
-
-            // make target lookup context
-            Document::Ptr implementationDoc = implementationFile->cppDocument();
-            unsigned line, column;
-            implementationDoc->translationUnit()->getPosition(insertPos, &line, &column);
-            Scope *targetScope = implementationDoc->scopeAt(line, column);
-            const LookupContext targetContext(implementationDoc, assistInterface()->snapshot());
-            ClassOrNamespace *targetCoN = targetContext.lookupType(targetScope);
-            if (!targetCoN)
-                targetCoN = targetContext.globalNamespace();
-
-            // Loop through inserted declarations
-            for (unsigned i = targetClass->memberCount(); i < clazz->memberCount(); ++i) {
-                Declaration *decl = clazz->memberAt(i)->asDeclaration();
-                if (!decl)
-                    continue;
-
-                // setup rewriting to get minimally qualified names
-                SubstitutionEnvironment env;
-                env.setContext(assistInterface()->context());
-                env.switchScope(decl->enclosingScope());
-                UseMinimalNames q(targetCoN);
-                env.enter(&q);
-                Control *control = assistInterface()->context().bindings()->control().data();
-
-                // rewrite the function type and name + create definition
-                const FullySpecifiedType type = rewriteType(decl->type(), &env, control);
-                const QString name = printer.prettyName(
-                            LookupContext::minimalName(decl, targetCoN, control));
-                const QString defText = printer.prettyType(type, name) + QLatin1String("\n{\n}");
-
-                implementationChangeSet.insert(insertPos,  QLatin1String("\n\n") + defText);
-            }
-
-            implementationFile->setChangeSet(implementationChangeSet);
-            implementationFile->appendIndentRange(ChangeSet::Range(insertPos, insertPos + 1));
-            implementationFile->apply();
-        }
-    }
-
-private:
-    InsertVirtualMethodsDialog *m_factory;
-    const ClassSpecifierAST *m_classAST;
-    bool m_valid;
-    QString m_cppFileName;
-    int m_insertPosDecl;
-    int m_insertPosOutside;
-    unsigned m_functionCount;
-};
-
-class InsertVirtualMethodsFilterModel : public QSortFilterProxyModel
-{
-    Q_OBJECT
-public:
-    InsertVirtualMethodsFilterModel(QObject *parent = 0)
-        : QSortFilterProxyModel(parent)
-        , m_hideReimplemented(false)
-    {}
-
-    bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
-    {
-        QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
-
-        // Handle base class
-        if (!sourceParent.isValid()) {
-            // check if any child is valid
-            if (!sourceModel()->hasChildren(index))
-                return false;
-            if (!m_hideReimplemented)
-                return true;
-
-            for (int i = 0; i < sourceModel()->rowCount(index); ++i) {
-                const QModelIndex child = sourceModel()->index(i, 0, index);
-                if (!child.data(InsertVirtualMethodsDialog::Reimplemented).toBool())
-                    return true;
-            }
-            return false;
-        }
-
-        if (m_hideReimplemented)
-            return !index.data(InsertVirtualMethodsDialog::Reimplemented).toBool();
-        return true;
-    }
-
-    bool hideReimplemented() const
-    {
-        return m_hideReimplemented;
-    }
-
-    void setHideReimplementedFunctions(bool show)
-    {
-        m_hideReimplemented = show;
-        invalidateFilter();
-    }
-
-private:
-    bool m_hideReimplemented;
-};
-
-} // anonymous namespace
-
-InsertVirtualMethodsDialog::InsertVirtualMethodsDialog(QWidget *parent)
-    : QDialog(parent)
-    , m_view(0)
-    , m_hideReimplementedFunctions(0)
-    , m_insertMode(0)
-    , m_virtualKeyword(0)
-    , m_buttons(0)
-    , m_hasImplementationFile(false)
-    , m_hasReimplementedFunctions(false)
-    , m_implementationMode(ModeOnlyDeclarations)
-    , m_insertKeywordVirtual(false)
-    , classFunctionModel(new QStandardItemModel(this))
-    , classFunctionFilterModel(new InsertVirtualMethodsFilterModel(this))
-{
-    classFunctionFilterModel->setSourceModel(classFunctionModel);
-}
-
-void InsertVirtualMethodsDialog::initGui()
-{
-    if (m_view)
-        return;
-
-    setWindowTitle(tr("Insert Virtual Functions"));
-    QVBoxLayout *globalVerticalLayout = new QVBoxLayout;
-
-    // View
-    QGroupBox *groupBoxView = new QGroupBox(tr("&Functions to insert:"), this);
-    QVBoxLayout *groupBoxViewLayout = new QVBoxLayout(groupBoxView);
-    m_view = new QTreeView(this);
-    m_view->setEditTriggers(QAbstractItemView::NoEditTriggers);
-    m_view->setHeaderHidden(true);
-    groupBoxViewLayout->addWidget(m_view);
-    m_hideReimplementedFunctions =
-            new QCheckBox(tr("&Hide reimplemented functions"), this);
-    groupBoxViewLayout->addWidget(m_hideReimplementedFunctions);
-
-    // Insertion options
-    QGroupBox *groupBoxImplementation = new QGroupBox(tr("&Insertion options:"), this);
-    QVBoxLayout *groupBoxImplementationLayout = new QVBoxLayout(groupBoxImplementation);
-    m_insertMode = new QComboBox(this);
-    m_insertMode->addItem(tr("Insert only declarations"), ModeOnlyDeclarations);
-    m_insertMode->addItem(tr("Insert definitions inside class"), ModeInsideClass);
-    m_insertMode->addItem(tr("Insert definitions outside class"), ModeOutsideClass);
-    m_insertMode->addItem(tr("Insert definitions in implementation file"), ModeImplementationFile);
-    m_virtualKeyword = new QCheckBox(tr("&Add keyword 'virtual' to function declaration"), this);
-    groupBoxImplementationLayout->addWidget(m_insertMode);
-    groupBoxImplementationLayout->addWidget(m_virtualKeyword);
-    groupBoxImplementationLayout->addStretch(99);
-
-    // Bottom button box
-    m_buttons = new QDialogButtonBox(this);
-    m_buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
-    connect(m_buttons, SIGNAL(accepted()), this, SLOT(accept()));
-    connect(m_buttons, SIGNAL(rejected()), this, SLOT(reject()));
-
-    globalVerticalLayout->addWidget(groupBoxView, 9);
-    globalVerticalLayout->addWidget(groupBoxImplementation, 0);
-    globalVerticalLayout->addWidget(m_buttons, 0);
-    setLayout(globalVerticalLayout);
-
-    connect(classFunctionModel, SIGNAL(itemChanged(QStandardItem*)),
-            this, SLOT(updateCheckBoxes(QStandardItem*)));
-    connect(m_hideReimplementedFunctions, SIGNAL(toggled(bool)),
-            this, SLOT(setHideReimplementedFunctions(bool)));
-}
-
-void InsertVirtualMethodsDialog::initData()
-{
-    m_insertKeywordVirtual = Core::ICore::settings()->value(
-                QLatin1String("QuickFix/InsertVirtualMethods/insertKeywordVirtual"),
-                false).toBool();
-    m_implementationMode = static_cast<InsertVirtualMethodsDialog::ImplementationMode>(
-                Core::ICore::settings()->value(
-                    QLatin1String("QuickFix/InsertVirtualMethods/implementationMode"), 1).toInt());
-    m_hideReimplementedFunctions->setChecked(
-                Core::ICore::settings()->value(
-                    QLatin1String("QuickFix/InsertVirtualMethods/hideReimplementedFunctions"),
-                    false).toBool());
-
-    m_view->setModel(classFunctionFilterModel);
-    m_expansionStateNormal.clear();
-    m_expansionStateReimp.clear();
-    m_hideReimplementedFunctions->setEnabled(m_hasReimplementedFunctions);
-    m_virtualKeyword->setChecked(m_insertKeywordVirtual);
-    m_insertMode->setCurrentIndex(m_insertMode->findData(m_implementationMode));
-
-    setHideReimplementedFunctions(m_hideReimplementedFunctions->isChecked());
-
-    if (m_hasImplementationFile) {
-        if (m_insertMode->count() == 3) {
-            m_insertMode->addItem(tr("Insert definitions in implementation file"),
-                                  ModeImplementationFile);
-        }
-    } else {
-        if (m_insertMode->count() == 4)
-            m_insertMode->removeItem(3);
-    }
-}
-
-bool InsertVirtualMethodsDialog::gather()
-{
-    initGui();
-    initData();
-
-    // Expand the dialog a little bit
-    adjustSize();
-    resize(size() * 1.5);
-
-    QPointer<InsertVirtualMethodsDialog> that(this);
-    const int ret = exec();
-    if (!that)
-        return false;
-
-    m_implementationMode = implementationMode();
-    m_insertKeywordVirtual = insertKeywordVirtual();
-    return (ret == QDialog::Accepted);
-}
-
-InsertVirtualMethodsDialog::ImplementationMode
-InsertVirtualMethodsDialog::implementationMode() const
-{
-    return static_cast<InsertVirtualMethodsDialog::ImplementationMode>(
-                m_insertMode->itemData(m_insertMode->currentIndex()).toInt());
-}
-
-void InsertVirtualMethodsDialog::setImplementationsMode(InsertVirtualMethodsDialog::ImplementationMode mode)
-{
-    m_implementationMode = mode;
-}
-
-bool InsertVirtualMethodsDialog::insertKeywordVirtual() const
-{
-    return m_virtualKeyword->isChecked();
-}
-
-void InsertVirtualMethodsDialog::setInsertKeywordVirtual(bool insert)
-{
-    m_insertKeywordVirtual = insert;
-}
-
-void InsertVirtualMethodsDialog::setHasImplementationFile(bool file)
-{
-    m_hasImplementationFile = file;
-}
-
-void InsertVirtualMethodsDialog::setHasReimplementedFunctions(bool functions)
-{
-    m_hasReimplementedFunctions = functions;
-}
-
-bool InsertVirtualMethodsDialog::hideReimplementedFunctions() const
-{
-    // Safty check necessary because of testing class
-    return (m_hideReimplementedFunctions && m_hideReimplementedFunctions->isChecked());
-}
-
-void InsertVirtualMethodsDialog::updateCheckBoxes(QStandardItem *item)
-{
-    if (item->hasChildren()) {
-        const Qt::CheckState state = item->checkState();
-        if (!item->isCheckable() || state == Qt::PartiallyChecked)
-            return;
-        for (int i = 0; i < item->rowCount(); ++i) {
-            QStandardItem *childItem = item->child(i, 0);
-            if (childItem->isCheckable() && childItem->isEnabled())
-                childItem->setCheckState(state);
-        }
-    } else {
-        QStandardItem *parent = item->parent();
-        if (!parent->isCheckable())
-            return;
-        const Qt::CheckState state = item->checkState();
-        for (int i = 0; i < parent->rowCount(); ++i) {
-            QStandardItem *childItem = parent->child(i, 0);
-            if (childItem->isEnabled() && state != childItem->checkState()) {
-                parent->setCheckState(Qt::PartiallyChecked);
-                return;
-            }
-        }
-        parent->setCheckState(state);
-    }
-}
-
-void InsertVirtualMethodsDialog::setHideReimplementedFunctions(bool hide)
-{
-    InsertVirtualMethodsFilterModel *model =
-            qobject_cast<InsertVirtualMethodsFilterModel *>(classFunctionFilterModel);
-
-    if (m_expansionStateNormal.isEmpty() && m_expansionStateReimp.isEmpty()) {
-        model->setHideReimplementedFunctions(hide);
-        m_view->expandAll();
-        saveExpansionState();
-        return;
-    }
-
-    if (model->hideReimplemented() == hide)
-        return;
-
-    saveExpansionState();
-    model->setHideReimplementedFunctions(hide);
-    restoreExpansionState();
-}
-
-void InsertVirtualMethodsDialog::saveExpansionState()
-{
-    InsertVirtualMethodsFilterModel *model =
-            qobject_cast<InsertVirtualMethodsFilterModel *>(classFunctionFilterModel);
-
-    QList<bool> &state = model->hideReimplemented() ? m_expansionStateReimp
-                                                    : m_expansionStateNormal;
-    state.clear();
-    for (int i = 0; i < model->rowCount(); ++i)
-        state << m_view->isExpanded(model->index(i, 0));
-}
-
-void InsertVirtualMethodsDialog::restoreExpansionState()
-{
-    InsertVirtualMethodsFilterModel *model =
-            qobject_cast<InsertVirtualMethodsFilterModel *>(classFunctionFilterModel);
-
-    const QList<bool> &state = model->hideReimplemented() ? m_expansionStateReimp
-                                                          : m_expansionStateNormal;
-    const int stateCount = state.count();
-    for (int i = 0; i < model->rowCount(); ++i) {
-        if (i < stateCount && !state.at(i)) {
-            m_view->collapse(model->index(i, 0));
-            continue;
-        }
-        m_view->expand(model->index(i, 0));
-    }
-}
-
-InsertVirtualMethods::InsertVirtualMethods(InsertVirtualMethodsDialog *dialog)
-    : m_dialog(dialog)
-{}
-
-InsertVirtualMethods::~InsertVirtualMethods()
-{
-    if (m_dialog)
-        m_dialog->deleteLater();
-}
-
-void InsertVirtualMethods::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
-{
-    InsertVirtualMethodsOp *op = new InsertVirtualMethodsOp(interface, m_dialog);
-    if (op->isValid())
-        result.append(QuickFixOperation::Ptr(op));
-    else
-        delete op;
-}
-
-namespace {
-
 class OptimizeForLoopOperation: public CppQuickFixOperation
 {
 public:
@@ -5581,5 +4840,3 @@ void OptimizeForLoop::match(const CppQuickFixInterface &interface, QuickFixOpera
         result.append(QuickFixOperation::Ptr(op));
     }
 }
-
-#include "cppquickfixes.moc"
diff --git a/src/plugins/cppeditor/cppquickfixes.h b/src/plugins/cppeditor/cppquickfixes.h
index 1ae1f20053d..01ae9229c81 100644
--- a/src/plugins/cppeditor/cppquickfixes.h
+++ b/src/plugins/cppeditor/cppquickfixes.h
@@ -40,14 +40,6 @@
 
 QT_BEGIN_NAMESPACE
 class QByteArray;
-class QCheckBox;
-class QComboBox;
-class QDialogButtonBox;
-class QStandardItem;
-class QSortFilterProxyModel;
-class QStandardItemModel;
-class QString;
-class QTreeView;
 template <class> class QList;
 QT_END_NAMESPACE
 
@@ -522,81 +514,6 @@ public:
     void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result);
 };
 
-/*!
- Insert (pure) virtual functions of a base class.
- Exposed for tests.
- */
-class InsertVirtualMethodsDialog : public QDialog
-{
-    Q_OBJECT
-public:
-    enum CustomItemRoles {
-        ClassOrFunction = Qt::UserRole + 1,
-        Reimplemented = Qt::UserRole + 2,
-        PureVirtual = Qt::UserRole + 3,
-        AccessSpec = Qt::UserRole + 4
-    };
-
-    enum ImplementationMode {
-        ModeOnlyDeclarations = 0x00000001,
-        ModeInsideClass = 0x00000002,
-        ModeOutsideClass = 0x00000004,
-        ModeImplementationFile = 0x00000008
-    };
-
-    InsertVirtualMethodsDialog(QWidget *parent = 0);
-    void initGui();
-    void initData();
-    virtual ImplementationMode implementationMode() const;
-    void setImplementationsMode(ImplementationMode mode);
-    virtual bool insertKeywordVirtual() const;
-    void setInsertKeywordVirtual(bool insert);
-    void setHasImplementationFile(bool file);
-    void setHasReimplementedFunctions(bool functions);
-    bool hideReimplementedFunctions() const;
-    virtual bool gather();
-
-public slots:
-    void updateCheckBoxes(QStandardItem *item);
-
-private slots:
-    void setHideReimplementedFunctions(bool hide);
-
-private:
-    QTreeView *m_view;
-    QCheckBox *m_hideReimplementedFunctions;
-    QComboBox *m_insertMode;
-    QCheckBox *m_virtualKeyword;
-    QDialogButtonBox *m_buttons;
-    QList<bool> m_expansionStateNormal;
-    QList<bool> m_expansionStateReimp;
-    bool m_hasImplementationFile;
-    bool m_hasReimplementedFunctions;
-
-    void saveExpansionState();
-    void restoreExpansionState();
-
-protected:
-    ImplementationMode m_implementationMode;
-    bool m_insertKeywordVirtual;
-
-public:
-    QStandardItemModel *classFunctionModel;
-    QSortFilterProxyModel *classFunctionFilterModel;
-};
-
-class InsertVirtualMethods: public CppQuickFixFactory
-{
-    Q_OBJECT
-public:
-    InsertVirtualMethods(InsertVirtualMethodsDialog *dialog = new InsertVirtualMethodsDialog);
-    ~InsertVirtualMethods();
-    void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result);
-
-private:
-    InsertVirtualMethodsDialog *m_dialog;
-};
-
 /*!
   Optimizes a for loop to avoid permanent condition check and forces to use preincrement
   or predecrement operators in the expression of the for loop.
diff --git a/src/plugins/cppeditor/fileandtokenactions_test.cpp b/src/plugins/cppeditor/fileandtokenactions_test.cpp
index 156a4d06768..a5e6601a32b 100644
--- a/src/plugins/cppeditor/fileandtokenactions_test.cpp
+++ b/src/plugins/cppeditor/fileandtokenactions_test.cpp
@@ -31,9 +31,9 @@
 #include "cppeditorplugin.h"
 #include "cppeditortestcase.h"
 #include "cppquickfix.h"
-#include "cppquickfix_test_utils.h"
 #include "cppquickfixassistant.h"
 #include "cppquickfixes.h"
+#include "cppinsertvirtualmethods.h"
 
 #include <coreplugin/editormanager/editormanager.h>
 #include <cpptools/cppmodelmanagerinterface.h>
@@ -474,10 +474,7 @@ void RunAllQuickFixesTokenAction::run(CPPEditorWidget *editorWidget)
         // Where possible, use a guiless version of the factory.
         if (qobject_cast<InsertVirtualMethods *>(quickFixFactory)) {
             QScopedPointer<CppQuickFixFactory> factoryProducingGuiLessOperations;
-            factoryProducingGuiLessOperations.reset(
-                new InsertVirtualMethods(
-                    new InsertVirtualMethodsDialogTest(
-                        InsertVirtualMethodsDialog::ModeOutsideClass, true)));
+            factoryProducingGuiLessOperations.reset(InsertVirtualMethods::createTestFactory());
             factoryProducingGuiLessOperations->match(qfi, operations);
         } else {
             quickFixFactory->match(qfi, operations);
-- 
GitLab