diff --git a/src/libs/cplusplus/TypeHierarchyBuilder.cpp b/src/libs/cplusplus/TypeHierarchyBuilder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6db175889b62cc4cb71eee50b9fde2d4fee8d334
--- /dev/null
+++ b/src/libs/cplusplus/TypeHierarchyBuilder.cpp
@@ -0,0 +1,201 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+#include "TypeHierarchyBuilder.h"
+#include "FindUsages.h"
+#include "Symbols.h"
+#include "SymbolVisitor.h"
+#include "DependencyTable.h"
+#include "CppDocument.h"
+#include "Literals.h"
+#include "TranslationUnit.h"
+#include "CoreTypes.h"
+
+using namespace CPlusPlus;
+
+namespace {
+
+QString unqualifyName(const QString &qualifiedName)
+{
+    const int index = qualifiedName.lastIndexOf(QLatin1String("::"));
+    if (index == -1)
+        return qualifiedName;
+    return qualifiedName.right(qualifiedName.length() - index - 2);
+}
+
+class DerivedHierarchyVisitor : public SymbolVisitor
+{
+public:
+    DerivedHierarchyVisitor(const QString &qualifiedName)
+        : _qualifiedName(qualifiedName)
+        , _unqualifiedName(unqualifyName(qualifiedName))
+    {}
+
+    void execute(const Document::Ptr &doc, const Snapshot &snapshot);
+
+    virtual bool visit(Class *);
+
+    const QList<Symbol *> &derived() { return _derived; }
+    const QStringList otherBases() { return _otherBases; }
+
+private:
+    LookupContext _context;
+    QString _qualifiedName;
+    QString _unqualifiedName;
+    Overview _overview;
+    QHash<Symbol *, QString> _actualBases;
+    QStringList _otherBases;
+    QList<Symbol *> _derived;
+};
+
+void DerivedHierarchyVisitor::execute(const Document::Ptr &doc, const Snapshot &snapshot)
+{
+    _derived.clear();
+    _otherBases.clear();
+    _context = LookupContext(doc, snapshot);
+
+    for (unsigned i = 0; i < doc->globalSymbolCount(); ++i)
+        accept(doc->globalSymbolAt(i));
+}
+
+bool DerivedHierarchyVisitor::visit(Class *symbol)
+{
+    for (unsigned i = 0; i < symbol->baseClassCount(); ++i) {
+        BaseClass *baseSymbol = symbol->baseClassAt(i);
+
+        QString baseName = _actualBases.value(baseSymbol);
+        if (baseName.isEmpty()) {
+            QList<LookupItem> items = _context.lookup(baseSymbol->name(), symbol->enclosingScope());
+            if (items.isEmpty() || !items.first().declaration())
+                continue;
+
+            Symbol *actualBaseSymbol = items.first().declaration();
+            if (actualBaseSymbol->isTypedef()) {
+                NamedType *namedType = actualBaseSymbol->type()->asNamedType();
+                const QString &typeName = _overview.prettyName(namedType->name());
+                if (namedType &&
+                        (typeName == _unqualifiedName || typeName == _qualifiedName)) {
+                    items = _context.lookup(namedType->name(), actualBaseSymbol->enclosingScope());
+                    if (items.isEmpty() || !items.first().declaration())
+                        continue;
+                    actualBaseSymbol = items.first().declaration();
+                }
+            }
+
+            const QList<const Name *> &full = LookupContext::fullyQualifiedName(actualBaseSymbol);
+            baseName = _overview.prettyName(full);
+            _actualBases.insert(baseSymbol, baseName);
+        }
+
+        if (_qualifiedName == baseName)
+            _derived.append(symbol);
+        else
+            _otherBases.append(baseName);
+    }
+
+    return true;
+}
+
+}
+
+TypeHierarchy::TypeHierarchy() : _symbol(0)
+{}
+
+TypeHierarchy::TypeHierarchy(Symbol *symbol) : _symbol(symbol)
+{}
+
+Symbol *TypeHierarchy::symbol() const
+{
+    return _symbol;
+}
+
+const QList<TypeHierarchy> &TypeHierarchy::hierarchy() const
+{
+    return _hierarchy;
+}
+
+TypeHierarchyBuilder::TypeHierarchyBuilder(Symbol *symbol, const Snapshot &snapshot)
+    : _symbol(symbol)
+    , _snapshot(snapshot)
+    , _dependencies(QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()))
+{
+    DependencyTable dependencyTable;
+    dependencyTable.build(_snapshot);
+    _dependencies.append(dependencyTable.filesDependingOn(_dependencies.first()));
+}
+
+void TypeHierarchyBuilder::reset()
+{
+    _visited.clear();
+    _candidates.clear();
+}
+
+TypeHierarchy TypeHierarchyBuilder::buildDerivedTypeHierarchy()
+{
+    reset();
+    TypeHierarchy hierarchy(_symbol);
+    buildDerived(&hierarchy);
+    return hierarchy;
+}
+
+void TypeHierarchyBuilder::buildDerived(TypeHierarchy *typeHierarchy)
+{
+    Symbol *symbol = typeHierarchy->_symbol;
+    if (_visited.contains(symbol))
+        return;
+
+    _visited.insert(symbol);
+
+    const QString &symbolName = _overview.prettyName(LookupContext::fullyQualifiedName(symbol));
+    DerivedHierarchyVisitor visitor(symbolName);
+
+    foreach (const QString &fileName, _dependencies) {
+        Document::Ptr doc = _snapshot.document(fileName);
+        if ((_candidates.contains(fileName) && !_candidates.value(fileName).contains(symbolName))
+                || !doc->control()->findIdentifier(symbol->identifier()->chars(),
+                                                   symbol->identifier()->size())) {
+            continue;
+        }
+
+        visitor.execute(doc, _snapshot);
+        _candidates.insert(fileName, QSet<QString>());
+
+        foreach (const QString &candidate, visitor.otherBases())
+            _candidates[fileName].insert(candidate);
+
+        foreach (Symbol *s, visitor.derived()) {
+            TypeHierarchy derivedHierarchy(s);
+            buildDerived(&derivedHierarchy);
+            typeHierarchy->_hierarchy.append(derivedHierarchy);
+        }
+    }
+}
diff --git a/src/libs/cplusplus/TypeHierarchyBuilder.h b/src/libs/cplusplus/TypeHierarchyBuilder.h
new file mode 100644
index 0000000000000000000000000000000000000000..f8dceb83bf77f3d5bb4d2db62ee8edfcccc7b130
--- /dev/null
+++ b/src/libs/cplusplus/TypeHierarchyBuilder.h
@@ -0,0 +1,83 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+#ifndef FINDDERIVEDCLASSES_H
+#define FINDDERIVEDCLASSES_H
+
+#include "CppDocument.h"
+#include "ModelManagerInterface.h"
+#include "Overview.h"
+
+#include <QtCore/QList>
+#include <QtCore/QStringList>
+#include <QtCore/QSet>
+
+namespace CPlusPlus {
+
+class CPLUSPLUS_EXPORT TypeHierarchy
+{
+    friend class TypeHierarchyBuilder;
+
+public:
+    TypeHierarchy();
+    TypeHierarchy(Symbol *symbol);
+
+    Symbol *symbol() const;
+    const QList<TypeHierarchy> &hierarchy() const;
+
+private:
+    Symbol *_symbol;
+    QList<TypeHierarchy> _hierarchy;
+};
+
+class CPLUSPLUS_EXPORT TypeHierarchyBuilder
+{
+public:
+    TypeHierarchyBuilder(Symbol *symbol, const Snapshot &snapshot);
+
+    TypeHierarchy buildDerivedTypeHierarchy();
+
+private:
+    void reset();
+    void buildDerived(TypeHierarchy *typeHierarchy);
+
+    Symbol *_symbol;
+    Snapshot _snapshot;
+    QStringList _dependencies;
+    QSet<Symbol *> _visited;
+    QHash<QString, QSet<QString> > _candidates;
+    Overview _overview;
+};
+
+} // CPlusPlus
+
+#endif // FINDDERIVEDCLASSES_H
diff --git a/src/libs/cplusplus/cplusplus-lib.pri b/src/libs/cplusplus/cplusplus-lib.pri
index f2683c7daceda688517d55043d9022b68fa81ec2..d4e12f05999c208d0bdc11c823f753e26d174d6c 100644
--- a/src/libs/cplusplus/cplusplus-lib.pri
+++ b/src/libs/cplusplus/cplusplus-lib.pri
@@ -52,7 +52,8 @@ HEADERS += \
     $$PWD/pp-macro-expander.h \
     $$PWD/pp-scanner.h \
     $$PWD/ModelManagerInterface.h \
-    $$PWD/findcdbbreakpoint.h
+    $$PWD/findcdbbreakpoint.h \
+    $$PWD/TypeHierarchyBuilder.h
 
 SOURCES += \
     $$PWD/SimpleLexer.cpp \
@@ -80,10 +81,7 @@ SOURCES += \
     $$PWD/pp-macro-expander.cpp \
     $$PWD/pp-scanner.cpp \
     $$PWD/ModelManagerInterface.cpp \
-    $$PWD/findcdbbreakpoint.cpp
+    $$PWD/findcdbbreakpoint.cpp \
+    $$PWD/TypeHierarchyBuilder.cpp
 
 RESOURCES += $$PWD/cplusplus.qrc
-
-
-
-
diff --git a/src/plugins/cppeditor/cppelementevaluator.cpp b/src/plugins/cppeditor/cppelementevaluator.cpp
index d3d1b86f7d75fe9f530d3e558e73554f13c1ee26..f4a22e759bd4e73dab4b648e77ddf3096d6d7a3a 100644
--- a/src/plugins/cppeditor/cppelementevaluator.cpp
+++ b/src/plugins/cppeditor/cppelementevaluator.cpp
@@ -33,6 +33,7 @@
 #include "cppelementevaluator.h"
 
 #include <coreplugin/ifile.h>
+#include <cpptools/cpptoolsreuse.h>
 
 #include <FullySpecifiedType.h>
 #include <Literals.h>
@@ -41,6 +42,7 @@
 #include <Scope.h>
 #include <Symbol.h>
 #include <Symbols.h>
+#include <TypeHierarchyBuilder.h>
 #include <cplusplus/ModelManagerInterface.h>
 #include <cplusplus/ExpressionUnderCursor.h>
 #include <cplusplus/Overview.h>
@@ -59,18 +61,6 @@ using namespace Internal;
 using namespace CPlusPlus;
 
 namespace {
-    void moveCursorToEndOfName(QTextCursor *tc) {
-        QTextDocument *doc = tc->document();
-        if (!doc)
-            return;
-
-        QChar ch = doc->characterAt(tc->position());
-        while (ch.isLetterOrNumber() || ch == QLatin1Char('_')) {
-            tc->movePosition(QTextCursor::NextCharacter);
-            ch = doc->characterAt(tc->position());
-        }
-    }
-
     QStringList stripName(const QString &name) {
         QStringList all;
         all << name;
@@ -88,7 +78,8 @@ CppElementEvaluator::CppElementEvaluator(CPPEditorWidget *editor) :
     m_editor(editor),
     m_modelManager(CppModelManagerInterface::instance()),
     m_tc(editor->textCursor()),
-    m_lookupBaseClasses(false)
+    m_lookupBaseClasses(false),
+    m_lookupDerivedClasses(false)
 {}
 
 void CppElementEvaluator::setTextCursor(const QTextCursor &tc)
@@ -97,6 +88,9 @@ void CppElementEvaluator::setTextCursor(const QTextCursor &tc)
 void CppElementEvaluator::setLookupBaseClasses(const bool lookup)
 { m_lookupBaseClasses = lookup; }
 
+void CppElementEvaluator::setLookupDerivedClasses(const bool lookup)
+{ m_lookupDerivedClasses = lookup; }
+
 // @todo: Consider refactoring code from CPPEditor::findLinkAt into here.
 void CppElementEvaluator::execute()
 {
@@ -118,7 +112,7 @@ void CppElementEvaluator::execute()
     checkDiagnosticMessage(doc, line);
 
     if (!matchIncludeFile(doc, line) && !matchMacroInUse(doc, pos)) {
-        moveCursorToEndOfName(&m_tc);
+        CppTools::moveCursorToEndOfIdentifier(&m_tc);
 
         // Fetch the expression's code
         ExpressionUnderCursor expressionUnderCursor;
@@ -185,13 +179,19 @@ void CppElementEvaluator::handleLookupItemMatch(const Snapshot &snapshot,
         const FullySpecifiedType &type = declaration->type();
         if (declaration->isNamespace()) {
             m_element = QSharedPointer<CppElement>(new CppNamespace(declaration));
-        } else if (declaration->isClass() || declaration->isForwardClassDeclaration()) {
+        } else if (declaration->isClass()
+                   || declaration->isForwardClassDeclaration()
+                   || (declaration->isTemplate() && declaration->asTemplate()->declaration()
+                       && (declaration->asTemplate()->declaration()->isClass()
+                           || declaration->asTemplate()->declaration()->isForwardClassDeclaration()))) {
             if (declaration->isForwardClassDeclaration())
                 if (Symbol *classDeclaration = snapshot.findMatchingClassDeclaration(declaration))
                     declaration = classDeclaration;
             CppClass *cppClass = new CppClass(declaration);
             if (m_lookupBaseClasses)
                 cppClass->lookupBases(declaration, context);
+            if (m_lookupDerivedClasses)
+                cppClass->lookupDerived(declaration, snapshot);
             m_element = QSharedPointer<CppElement>(cppClass);
         } else if (Enum *enumDecl = declaration->asEnum()) {
             m_element = QSharedPointer<CppElement>(new CppEnum(enumDecl));
@@ -199,13 +199,13 @@ void CppElementEvaluator::handleLookupItemMatch(const Snapshot &snapshot,
             m_element = QSharedPointer<CppElement>(new CppEnumerator(enumerator));
         } else if (declaration->isTypedef()) {
             m_element = QSharedPointer<CppElement>(new CppTypedef(declaration));
-        } else if (declaration->isFunction() || (type.isValid() && type->isFunctionType())) {
+        } else if (declaration->isFunction()
+                   || (type.isValid() && type->isFunctionType())
+                   || declaration->isTemplate()) {
             m_element = QSharedPointer<CppElement>(new CppFunction(declaration));
         } else if (declaration->isDeclaration() && type.isValid()) {
             m_element = QSharedPointer<CppElement>(
                 new CppVariable(declaration, context, lookupItem.scope()));
-        } else if (declaration->isTemplate() && declaration->asTemplate()->declaration()) {
-            m_element = QSharedPointer<CppElement>(new CppTemplate(declaration));
         } else {
             m_element = QSharedPointer<CppElement>(new CppDeclarableElement(declaration));
         }
@@ -327,6 +327,9 @@ CppMacro::~CppMacro()
 {}
 
 // CppDeclarableElement
+CppDeclarableElement::CppDeclarableElement()
+{}
+
 CppDeclarableElement::CppDeclarableElement(Symbol *declaration) : CppElement()
 {
     m_icon = Icons().iconForSymbol(declaration);
@@ -388,6 +391,9 @@ CppNamespace::~CppNamespace()
 {}
 
 // CppClass
+CppClass::CppClass()
+{}
+
 CppClass::CppClass(Symbol *declaration) : CppDeclarableElement(declaration)
 {
     setHelpCategory(TextEditor::HelpItem::ClassOrNamespace);
@@ -428,9 +434,32 @@ void CppClass::lookupBases(Symbol *declaration, const CPlusPlus::LookupContext &
     }
 }
 
+void CppClass::lookupDerived(CPlusPlus::Symbol *declaration, const CPlusPlus::Snapshot &snapshot)
+{
+    typedef QPair<CppClass *, TypeHierarchy> Data;
+
+    TypeHierarchyBuilder builder(declaration, snapshot);
+    const TypeHierarchy &completeHierarchy = builder.buildDerivedTypeHierarchy();
+
+    QQueue<Data> q;
+    q.enqueue(qMakePair(this, completeHierarchy));
+    while (!q.isEmpty()) {
+        const Data &current = q.dequeue();
+        CppClass *clazz = current.first;
+        const TypeHierarchy &classHierarchy = current.second;
+        foreach (const TypeHierarchy &derivedHierarchy, classHierarchy.hierarchy()) {
+            clazz->m_derived.append(CppClass(derivedHierarchy.symbol()));
+            q.enqueue(qMakePair(&clazz->m_derived.last(), derivedHierarchy));
+        }
+    }
+}
+
 const QList<CppClass> &CppClass::bases() const
 { return m_bases; }
 
+const QList<CppClass> &CppClass::derived() const
+{ return m_derived; }
+
 // CppFunction
 CppFunction::CppFunction(Symbol *declaration) : CppDeclarableElement(declaration)
 {
@@ -515,34 +544,6 @@ CppVariable::CppVariable(Symbol *declaration, const LookupContext &context, Scop
 CppVariable::~CppVariable()
 {}
 
-// CppTemplate
-CppTemplate::CppTemplate(CPlusPlus::Symbol *declaration) : CppDeclarableElement(declaration)
-{
-    Template *templateSymbol = declaration->asTemplate();
-    if (templateSymbol->declaration()->isClass() ||
-        templateSymbol->declaration()->isForwardClassDeclaration()) {
-        m_isClassTemplate = true;
-        setHelpCategory(TextEditor::HelpItem::ClassOrNamespace);
-        setTooltip(qualifiedName());
-    } else {
-        m_isClassTemplate = false;
-        setHelpCategory(TextEditor::HelpItem::Function);
-    }
-}
-
-CppTemplate::~CppTemplate()
-{}
-
-bool CppTemplate::isClassTemplate() const
-{
-    return m_isClassTemplate;
-}
-
-bool CppTemplate::isFunctionTemplate() const
-{
-    return !m_isClassTemplate;
-}
-
 CppEnumerator::CppEnumerator(CPlusPlus::EnumeratorDeclaration *declaration)
     : CppDeclarableElement(declaration)
 {
diff --git a/src/plugins/cppeditor/cppelementevaluator.h b/src/plugins/cppeditor/cppelementevaluator.h
index c20c3c0ff932ed87073a0438342917df77a588a3..ac68784f47874354dd565c9f0b409c169b28721f 100644
--- a/src/plugins/cppeditor/cppelementevaluator.h
+++ b/src/plugins/cppeditor/cppelementevaluator.h
@@ -68,6 +68,7 @@ public:
 
     void setTextCursor(const QTextCursor &tc);
     void setLookupBaseClasses(const bool lookup);
+    void setLookupDerivedClasses(const bool lookup);
 
     void execute();
     bool identifiedCppElement() const;
@@ -88,6 +89,7 @@ private:
     CPlusPlus::CppModelManagerInterface *m_modelManager;
     QTextCursor m_tc;
     bool m_lookupBaseClasses;
+    bool m_lookupDerivedClasses;
     QSharedPointer<CppElement> m_element;
     QString m_diagnosis;
 };
@@ -157,6 +159,7 @@ public:
 class CppDeclarableElement : public CppElement
 {
 public:
+    CppDeclarableElement();
     explicit CppDeclarableElement(CPlusPlus::Symbol *declaration);
     virtual ~CppDeclarableElement();
 
@@ -188,15 +191,19 @@ public:
 class CppClass : public CppDeclarableElement
 {
 public:
+    CppClass();
     explicit CppClass(CPlusPlus::Symbol *declaration);
     virtual ~CppClass();
 
     void lookupBases(CPlusPlus::Symbol *declaration, const CPlusPlus::LookupContext &context);
+    void lookupDerived(CPlusPlus::Symbol *declaration, const CPlusPlus::Snapshot &snapshot);
 
     const QList<CppClass> &bases() const;
+    const QList<CppClass> &derived() const;
 
 private:
     QList<CppClass> m_bases;
+    QList<CppClass> m_derived;
 };
 
 class CppFunction : public CppDeclarableElement
@@ -229,19 +236,6 @@ public:
     virtual ~CppVariable();
 };
 
-class CppTemplate : public CppDeclarableElement
-{
-public:
-    explicit CppTemplate(CPlusPlus::Symbol *declaration);
-    virtual ~CppTemplate();
-
-    bool isClassTemplate() const;
-    bool isFunctionTemplate() const;
-
-private:
-    bool m_isClassTemplate;
-};
-
 class CppEnumerator : public CppDeclarableElement
 {
 public:
diff --git a/src/plugins/cppeditor/cpptypehierarchy.cpp b/src/plugins/cppeditor/cpptypehierarchy.cpp
index 48fd4de85a9a8d2e5bd59ad7dbccb3da8dfcecb5..aa38b8e64cb5705d4c4ecd5b4b8908935b9b1188 100644
--- a/src/plugins/cppeditor/cpptypehierarchy.cpp
+++ b/src/plugins/cppeditor/cpptypehierarchy.cpp
@@ -44,6 +44,7 @@
 #include <QtCore/QLatin1Char>
 #include <QtCore/QLatin1String>
 #include <QtCore/QModelIndex>
+#include <QtCore/QVector>
 #include <QtGui/QVBoxLayout>
 #include <QtGui/QStandardItemModel>
 #include <QtGui/QLabel>
@@ -52,6 +53,28 @@ using namespace CppEditor;
 using namespace Internal;
 using namespace Utils;
 
+namespace {
+
+enum ItemRole {
+    AnnotationRole = Qt::UserRole + 1,
+    LinkRole
+};
+
+QStandardItem *itemForClass(const CppClass &cppClass)
+{
+    QStandardItem *item = new QStandardItem;
+    item->setData(cppClass.name(), Qt::DisplayRole);
+    if (cppClass.name() != cppClass.qualifiedName())
+        item->setData(cppClass.qualifiedName(), AnnotationRole);
+    item->setData(cppClass.icon(), Qt::DecorationRole);
+    QVariant link;
+    link.setValue(CPPEditorWidget::Link(cppClass.link()));
+    item->setData(link, LinkRole);
+    return item;
+}
+
+} // Anonymous
+
 // CppTypeHierarchyWidget
 CppTypeHierarchyWidget::CppTypeHierarchyWidget(Core::IEditor *editor) :
     QWidget(0),
@@ -67,16 +90,18 @@ CppTypeHierarchyWidget::CppTypeHierarchyWidget(Core::IEditor *editor) :
     if (CPPEditor *cppEditor = qobject_cast<CPPEditor *>(editor)) {
         m_cppEditor = static_cast<CPPEditorWidget *>(cppEditor->widget());
 
-        m_model = new QStandardItemModel;
-        m_treeView = new Utils::NavigationTreeView;
-        m_delegate = new AnnotatedItemDelegate;
+        m_model = new QStandardItemModel(this);
+        m_treeView = new NavigationTreeView(this);
+        m_delegate = new AnnotatedItemDelegate(this);
         m_delegate->setDelimiter(QLatin1String(" "));
         m_delegate->setAnnotationRole(AnnotationRole);
         m_treeView->setModel(m_model);
         m_treeView->setEditTriggers(QAbstractItemView::NoEditTriggers);
         m_treeView->setItemDelegate(m_delegate);
+        m_treeView->setRootIsDecorated(false);
         layout->addWidget(m_treeView);
 
+        connect(m_treeView, SIGNAL(clicked(QModelIndex)), this, SLOT(onItemClicked(QModelIndex)));
         connect(m_treeView, SIGNAL(clicked(QModelIndex)), this, SLOT(onItemClicked(QModelIndex)));
         connect(CppPlugin::instance(), SIGNAL(typeHierarchyRequested()), this, SLOT(perform()));
     } else {
@@ -90,10 +115,7 @@ CppTypeHierarchyWidget::CppTypeHierarchyWidget(Core::IEditor *editor) :
 }
 
 CppTypeHierarchyWidget::~CppTypeHierarchyWidget()
-{
-    delete m_model;
-    delete m_delegate;
-}
+{}
 
 bool CppTypeHierarchyWidget::handleEditorChange(Core::IEditor *editor)
 {
@@ -117,32 +139,52 @@ void CppTypeHierarchyWidget::perform()
 
     CppElementEvaluator evaluator(m_cppEditor);
     evaluator.setLookupBaseClasses(true);
+    evaluator.setLookupDerivedClasses(true);
     evaluator.execute();
     if (evaluator.identifiedCppElement()) {
         const QSharedPointer<CppElement> &cppElement = evaluator.cppElement();
         CppElement *element = cppElement.data();
-        if (CppClass *cppClass = dynamic_cast<CppClass *>(element))
-            buildModel(*cppClass, m_model->invisibleRootItem());
+        if (CppClass *cppClass = dynamic_cast<CppClass *>(element)) {
+            QStandardItem *bases = new QStandardItem(tr("Bases"));
+            m_model->invisibleRootItem()->appendRow(bases);
+            QVector<CppClass> v;
+            v.push_back(*cppClass);
+            buildBaseHierarchy(&v);
+            m_treeView->expand(m_model->indexFromItem(bases));
+            QStandardItem *derived = new QStandardItem(tr("Derived"));
+            m_model->invisibleRootItem()->appendRow(derived);
+            buildDerivedHierarchy(*cppClass, derived);
+        }
     }
 }
 
-void CppTypeHierarchyWidget::buildModel(const CppClass &cppClass, QStandardItem *parent)
+void CppTypeHierarchyWidget::buildBaseHierarchy(QVector<CppClass> *s)
 {
-    QStandardItem *item = new QStandardItem;
-    parent->appendRow(item);
-
-    m_model->setData(m_model->indexFromItem(item), cppClass.name(), Qt::DisplayRole);
-    if (cppClass.name() != cppClass.qualifiedName())
-        m_model->setData(m_model->indexFromItem(item), cppClass.qualifiedName(), AnnotationRole);
-    m_model->setData(m_model->indexFromItem(item), cppClass.icon(), Qt::DecorationRole);
-    QVariant link;
-    link.setValue(CPPEditorWidget::Link(cppClass.link()));
-    m_model->setData(m_model->indexFromItem(item), link, LinkRole);
-
-    foreach (const CppClass &cppBase, cppClass.bases())
-        buildModel(cppBase, item);
+    const CppClass &current = s->back();
+    const QList<CppClass> &bases = current.bases();
+    if (!bases.isEmpty()) {
+        foreach (const CppClass &base, bases) {
+            s->push_back(base);
+            buildBaseHierarchy(s);
+            s->pop_back();
+        }
+    } else {
+        QStandardItem *parent = m_model->item(0, 0);
+        for (int i = s->size() - 1; i >= 0; --i) {
+            QStandardItem *item = itemForClass(s->at(i));
+            parent->appendRow(item);
+            parent = item;
+        }
+    }
+}
 
-    m_treeView->expand(m_model->indexFromItem(item));
+void CppTypeHierarchyWidget::buildDerivedHierarchy(const CppClass &cppClass, QStandardItem *parent)
+{
+    QStandardItem *item = itemForClass(cppClass);
+    parent->appendRow(item);
+    foreach (const CppClass &derived, cppClass.derived())
+        buildDerivedHierarchy(derived, item);
+    m_treeView->expand(m_model->indexFromItem(parent));
 }
 
 void CppTypeHierarchyWidget::onItemClicked(const QModelIndex &index)
diff --git a/src/plugins/cppeditor/cpptypehierarchy.h b/src/plugins/cppeditor/cpptypehierarchy.h
index 2685e1f0c5119d85cc916f5e820aa02316108e9b..4be85f3e7319f3a3393f92910cb805a12ab81280 100644
--- a/src/plugins/cppeditor/cpptypehierarchy.h
+++ b/src/plugins/cppeditor/cpptypehierarchy.h
@@ -33,8 +33,6 @@
 #ifndef CPPTYPEHIERARCHY_H
 #define CPPTYPEHIERARCHY_H
 
-#include "cppelementevaluator.h"
-
 #include <coreplugin/inavigationwidgetfactory.h>
 
 #include <QtCore/QString>
@@ -45,6 +43,7 @@ QT_BEGIN_NAMESPACE
 class QStandardItemModel;
 class QStandardItem;
 class QModelIndex;
+template <class> class QVector;
 QT_END_NAMESPACE
 
 namespace Core {
@@ -60,6 +59,7 @@ namespace CppEditor {
 namespace Internal {
 
 class CPPEditorWidget;
+class CppClass;
 
 class CppTypeHierarchyWidget : public QWidget
 {
@@ -77,12 +77,8 @@ private slots:
     void onItemClicked(const QModelIndex &index);
 
 private:
-    enum ItemRole {
-        AnnotationRole = Qt::UserRole + 1,
-        LinkRole
-    };
-
-    void buildModel(const CppClass &cppClass, QStandardItem *item);
+    void buildDerivedHierarchy(const CppClass &cppClass, QStandardItem *parent);
+    void buildBaseHierarchy(QVector<CppClass> *s);
 
     CPPEditorWidget *m_cppEditor;
     Utils::NavigationTreeView *m_treeView;
diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro
index 2351c5c5ea327803370a0a22f61ec9d430e1d956..2821429df624714cf682d54b679790c836d1464b 100644
--- a/src/plugins/cpptools/cpptools.pro
+++ b/src/plugins/cpptools/cpptools.pro
@@ -34,7 +34,8 @@ HEADERS += completionsettingspage.h \
     cpptoolssettings.h \
     cppcodestylesettings.h \
     cppcodestylesettingsfactory.h \
-    cppcodestylepreferences.h
+    cppcodestylepreferences.h \
+    cpptoolsreuse.h
 
 SOURCES += completionsettingspage.cpp \
     cppclassesfilter.cpp \
@@ -60,7 +61,8 @@ SOURCES += completionsettingspage.cpp \
     cpptoolssettings.cpp \
     cppcodestylesettings.cpp \
     cppcodestylesettingsfactory.cpp \
-    cppcodestylepreferences.cpp
+    cppcodestylepreferences.cpp \
+    cpptoolsreuse.cpp
 
 FORMS += completionsettingspage.ui \
     cppfilesettingspage.ui \
diff --git a/src/plugins/cpptools/cpptoolsreuse.cpp b/src/plugins/cpptools/cpptoolsreuse.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ed97b677392a3aa109d6e52b1cbd1e556da18190
--- /dev/null
+++ b/src/plugins/cpptools/cpptoolsreuse.cpp
@@ -0,0 +1,52 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+#include "cpptoolsreuse.h"
+
+#include <QtGui/QTextDocument>
+#include <QtGui/QTextCursor>
+
+namespace CppTools {
+
+void moveCursorToEndOfIdentifier(QTextCursor *tc) {
+    QTextDocument *doc = tc->document();
+    if (!doc)
+        return;
+
+    QChar ch = doc->characterAt(tc->position());
+    while (ch.isLetterOrNumber() || ch == QLatin1Char('_')) {
+        tc->movePosition(QTextCursor::NextCharacter);
+        ch = doc->characterAt(tc->position());
+    }
+}
+
+} // CppTools
diff --git a/src/plugins/cpptools/cpptoolsreuse.h b/src/plugins/cpptools/cpptoolsreuse.h
new file mode 100644
index 0000000000000000000000000000000000000000..3be58382fdb473810853394ffd85e495ca5396fb
--- /dev/null
+++ b/src/plugins/cpptools/cpptoolsreuse.h
@@ -0,0 +1,14 @@
+#ifndef CPPTOOLSREUSE_H
+#define CPPTOOLSREUSE_H
+
+#include "cpptools_global.h"
+
+QT_FORWARD_DECLARE_CLASS(QTextCursor)
+
+namespace CppTools {
+
+void CPPTOOLS_EXPORT moveCursorToEndOfIdentifier(QTextCursor *tc);
+
+} // CppTools
+
+#endif // CPPTOOLSREUSE_H