diff --git a/share/qtcreator/qmlicons/Qt/16x16/BorderImage.png b/share/qtcreator/qmlicons/Qt/16x16/BorderImage.png
new file mode 100644
index 0000000000000000000000000000000000000000..ef21dd9710709b536736c433368d595b2fe298fc
Binary files /dev/null and b/share/qtcreator/qmlicons/Qt/16x16/BorderImage.png differ
diff --git a/share/qtcreator/qmlicons/Qt/16x16/Flickable.png b/share/qtcreator/qmlicons/Qt/16x16/Flickable.png
new file mode 100644
index 0000000000000000000000000000000000000000..963a7afea358303873397bfd01b9088d6b990287
Binary files /dev/null and b/share/qtcreator/qmlicons/Qt/16x16/Flickable.png differ
diff --git a/share/qtcreator/qmlicons/Qt/16x16/Flipable.png b/share/qtcreator/qmlicons/Qt/16x16/Flipable.png
new file mode 100644
index 0000000000000000000000000000000000000000..354f5bd91c30220917b3863200ee6c874c4bd015
Binary files /dev/null and b/share/qtcreator/qmlicons/Qt/16x16/Flipable.png differ
diff --git a/share/qtcreator/qmlicons/Qt/16x16/FocusScope.png b/share/qtcreator/qmlicons/Qt/16x16/FocusScope.png
new file mode 100644
index 0000000000000000000000000000000000000000..3a65e43525e391b936ca47531dc5dd382ebe8870
Binary files /dev/null and b/share/qtcreator/qmlicons/Qt/16x16/FocusScope.png differ
diff --git a/share/qtcreator/qmlicons/Qt/16x16/GridView.png b/share/qtcreator/qmlicons/Qt/16x16/GridView.png
new file mode 100644
index 0000000000000000000000000000000000000000..011392dc557b73596cde95264b91dff8e2624bfc
Binary files /dev/null and b/share/qtcreator/qmlicons/Qt/16x16/GridView.png differ
diff --git a/share/qtcreator/qmlicons/Qt/16x16/Image.png b/share/qtcreator/qmlicons/Qt/16x16/Image.png
new file mode 100644
index 0000000000000000000000000000000000000000..fc4c7eccc1fc5d76ea874b2adbe4fb501df8d9b9
Binary files /dev/null and b/share/qtcreator/qmlicons/Qt/16x16/Image.png differ
diff --git a/share/qtcreator/qmlicons/Qt/16x16/Item.png b/share/qtcreator/qmlicons/Qt/16x16/Item.png
new file mode 100644
index 0000000000000000000000000000000000000000..6d1e0f214d5076df6648f36330e8e16dc7460ac6
Binary files /dev/null and b/share/qtcreator/qmlicons/Qt/16x16/Item.png differ
diff --git a/share/qtcreator/qmlicons/Qt/16x16/ListView.png b/share/qtcreator/qmlicons/Qt/16x16/ListView.png
new file mode 100644
index 0000000000000000000000000000000000000000..b2e62ca068f82f81e9f09e778f63f8387f7d2776
Binary files /dev/null and b/share/qtcreator/qmlicons/Qt/16x16/ListView.png differ
diff --git a/share/qtcreator/qmlicons/Qt/16x16/MouseArea.png b/share/qtcreator/qmlicons/Qt/16x16/MouseArea.png
new file mode 100644
index 0000000000000000000000000000000000000000..b28576ac8772a6ae778ee1ac543be04c1ab5f665
Binary files /dev/null and b/share/qtcreator/qmlicons/Qt/16x16/MouseArea.png differ
diff --git a/share/qtcreator/qmlicons/Qt/16x16/PathView.png b/share/qtcreator/qmlicons/Qt/16x16/PathView.png
new file mode 100644
index 0000000000000000000000000000000000000000..23c3a2f5dae22b63da65a3f127c8481dd3377d0e
Binary files /dev/null and b/share/qtcreator/qmlicons/Qt/16x16/PathView.png differ
diff --git a/share/qtcreator/qmlicons/Qt/16x16/Rectangle.png b/share/qtcreator/qmlicons/Qt/16x16/Rectangle.png
new file mode 100644
index 0000000000000000000000000000000000000000..f6c33cacd7b16f55cce98ba1cf22443762f380ad
Binary files /dev/null and b/share/qtcreator/qmlicons/Qt/16x16/Rectangle.png differ
diff --git a/share/qtcreator/qmlicons/Qt/16x16/State.png b/share/qtcreator/qmlicons/Qt/16x16/State.png
new file mode 100644
index 0000000000000000000000000000000000000000..d400b013aeb020c7a656826ad25c2afd827f9a48
Binary files /dev/null and b/share/qtcreator/qmlicons/Qt/16x16/State.png differ
diff --git a/share/qtcreator/qmlicons/Qt/16x16/Text.png b/share/qtcreator/qmlicons/Qt/16x16/Text.png
new file mode 100644
index 0000000000000000000000000000000000000000..a49a39c33c6a882f898ead68dc81122f2d0ddf05
Binary files /dev/null and b/share/qtcreator/qmlicons/Qt/16x16/Text.png differ
diff --git a/share/qtcreator/qmlicons/Qt/16x16/TextEdit.png b/share/qtcreator/qmlicons/Qt/16x16/TextEdit.png
new file mode 100644
index 0000000000000000000000000000000000000000..4f41cd9bc5269d0f4eb348e8a0fc25ff44ffbcc9
Binary files /dev/null and b/share/qtcreator/qmlicons/Qt/16x16/TextEdit.png differ
diff --git a/share/qtcreator/qmlicons/Qt/16x16/TextInput.png b/share/qtcreator/qmlicons/Qt/16x16/TextInput.png
new file mode 100644
index 0000000000000000000000000000000000000000..394ac907cf686515d102e0b366fec7665deb920b
Binary files /dev/null and b/share/qtcreator/qmlicons/Qt/16x16/TextInput.png differ
diff --git a/share/qtcreator/qmlicons/Qt/16x16/Transition.png b/share/qtcreator/qmlicons/Qt/16x16/Transition.png
new file mode 100644
index 0000000000000000000000000000000000000000..86f591ff7bdc287872b1170e1d5c54f3fa639115
Binary files /dev/null and b/share/qtcreator/qmlicons/Qt/16x16/Transition.png differ
diff --git a/share/qtcreator/qmlicons/QtWebkit/16x16/WebView.png b/share/qtcreator/qmlicons/QtWebkit/16x16/WebView.png
new file mode 100644
index 0000000000000000000000000000000000000000..3f61ad0b1c0740c7c671686cffc3ddaf8c6a232f
Binary files /dev/null and b/share/qtcreator/qmlicons/QtWebkit/16x16/WebView.png differ
diff --git a/src/libs/qmljs/qmljsicons.cpp b/src/libs/qmljs/qmljsicons.cpp
index 710e619847f8431f19a0a44c0486518a1b6a0b6b..f423c124466f51a65dd00f275abbe132743fc446 100644
--- a/src/libs/qmljs/qmljsicons.cpp
+++ b/src/libs/qmljs/qmljsicons.cpp
@@ -28,17 +28,29 @@
 **************************************************************************/
 
 #include "qmljsicons.h"
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QHash>
+#include <QtCore/QPair>
 
 using namespace QmlJS;
 using namespace QmlJS::AST;
 
+enum {
+    debug = false
+};
+
 namespace QmlJS {
 
+Icons *Icons::m_instance = 0;
+
 class IconsPrivate
 {
 public:
     QIcon elementIcon;
     QIcon propertyIcon;
+    QHash<QPair<QString,QString>,QIcon> iconHash;
+    QString resourcePath;
 };
 
 } // namespace QmlJS
@@ -52,9 +64,55 @@ Icons::Icons()
 
 Icons::~Icons()
 {
+    m_instance = 0;
     delete m_d;
 }
 
+Icons *Icons::instance()
+{
+    if (!m_instance)
+        m_instance = new Icons();
+    return m_instance;
+}
+
+void Icons::setIconFilesPath(const QString &iconPath)
+{
+    if (iconPath == m_d->resourcePath)
+        return;
+
+    m_d->resourcePath = iconPath;
+
+    if (debug)
+        qDebug() << "QmlJSIcons -" << "parsing" << iconPath;
+    QDir topDir(iconPath);
+    foreach (const QFileInfo &subDirInfo, topDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) {
+        if (debug)
+            qDebug() << "QmlJSIcons - parsing" << subDirInfo.absoluteFilePath();
+        const QString packageName = subDirInfo.fileName();
+        QDir subDir(subDirInfo.absoluteFilePath() + QLatin1String("/16x16"));
+        foreach (const QFileInfo &iconFile, subDir.entryInfoList(QDir::Files)) {
+            QIcon icon(iconFile.absoluteFilePath());
+            if (icon.isNull()) {
+                if (debug)
+                    qDebug() << "QmlJSIcons - skipping" << iconFile.absoluteFilePath();
+                continue;
+            }
+            if (debug)
+                qDebug() << "QmlJSIcons - adding" << packageName << iconFile.baseName() << "icon to database";
+            QPair<QString,QString> element(packageName, iconFile.baseName());
+            m_d->iconHash.insert(element, icon);
+        }
+    }
+}
+
+QIcon Icons::icon(const QString &packageName, const QString typeName) const
+{
+    QPair<QString,QString> element(packageName, typeName);
+    if (debug)
+        qDebug() << "QmlJSIcons - icon for" << packageName << typeName << "requested" << m_d->iconHash.contains(element);
+    return m_d->iconHash.value(element);
+}
+
 QIcon Icons::icon(Node *node) const
 {
     if (dynamic_cast<AST::UiObjectDefinition*>(node)) {
diff --git a/src/libs/qmljs/qmljsicons.h b/src/libs/qmljs/qmljsicons.h
index 783e5ac4d6d00b600a8d834966274445e365296c..47cec83ef16e8cf2939353c3718888dbd81af749 100644
--- a/src/libs/qmljs/qmljsicons.h
+++ b/src/libs/qmljs/qmljsicons.h
@@ -41,14 +41,21 @@ class IconsPrivate;
 class QMLJS_EXPORT Icons
 {
 public:
-    Icons();
     ~Icons();
 
+    static Icons *instance();
+
+    void setIconFilesPath(const QString &iconPath);
+
+    QIcon icon(const QString &packageName, const QString typeName) const;
     QIcon icon(AST::Node *node) const;
 
     QIcon objectDefinitionIcon() const;
     QIcon scriptBindingIcon() const;
 
+private:
+    Icons();
+    static Icons *m_instance;
     IconsPrivate *m_d;
 };
 
diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp
index b7144f1f30d940d91d393afd260bd20d54cea703..7528acd51b2a84d434aacc5bb2cb9edde19e64db 100644
--- a/src/plugins/qmljseditor/qmljseditor.cpp
+++ b/src/plugins/qmljseditor/qmljseditor.cpp
@@ -850,7 +850,7 @@ void QmlJSTextEditor::updateOutlineNow()
         return;
     }
 
-    m_outlineModel->update(document);
+    m_outlineModel->update(document, snapshot);
     updateOutlineIndexNow();
 }
 
diff --git a/src/plugins/qmljseditor/qmljseditorplugin.cpp b/src/plugins/qmljseditor/qmljseditorplugin.cpp
index d55d5b31dcfa9f5b59c1edf0e404791f5756fac4..944d34ae4cee24504091bdda71a42a35e10d4030 100644
--- a/src/plugins/qmljseditor/qmljseditorplugin.cpp
+++ b/src/plugins/qmljseditor/qmljseditorplugin.cpp
@@ -39,6 +39,7 @@
 #include "qmljsoutline.h"
 #include "qmljspreviewrunner.h"
 #include "qmljsquickfix.h"
+#include "qmljs/qmljsicons.h"
 
 #include <qmldesigner/qmldesignerconstants.h>
 
@@ -186,6 +187,13 @@ void QmlJSEditorPlugin::extensionsInitialized()
 {
 }
 
+ExtensionSystem::IPlugin::ShutdownFlag QmlJSEditorPlugin::aboutToShutdown()
+{
+    delete QmlJS::Icons::instance(); // delete object held by singleton
+
+    return IPlugin::aboutToShutdown();
+}
+
 void QmlJSEditorPlugin::openPreview()
 {
     Core::EditorManager *em = Core::EditorManager::instance();
diff --git a/src/plugins/qmljseditor/qmljseditorplugin.h b/src/plugins/qmljseditor/qmljseditorplugin.h
index af6e5f9280cfa75258bcbcdbb320fdf31855b93a..9fa7ba4a97e916bd6d8290d6517a5b784f0a699c 100644
--- a/src/plugins/qmljseditor/qmljseditorplugin.h
+++ b/src/plugins/qmljseditor/qmljseditorplugin.h
@@ -77,6 +77,7 @@ public:
     // IPlugin
     bool initialize(const QStringList &arguments, QString *errorMessage = 0);
     void extensionsInitialized();
+    ShutdownFlag aboutToShutdown();
 
     static QmlJSEditorPlugin *instance()
     { return m_instance; }
diff --git a/src/plugins/qmljseditor/qmloutlinemodel.cpp b/src/plugins/qmljseditor/qmloutlinemodel.cpp
index bad1f2b7b3cc6426383c48b970225ecd52532a89..0a56622ba11d8a9d0cdf9a27cf984f15b880e56c 100644
--- a/src/plugins/qmljseditor/qmloutlinemodel.cpp
+++ b/src/plugins/qmljseditor/qmloutlinemodel.cpp
@@ -1,7 +1,11 @@
 #include "qmloutlinemodel.h"
 #include <qmljs/parser/qmljsastvisitor_p.h>
+#include <qmljs/qmljsinterpreter.h>
+#include <qmljs/qmljslookupcontext.h>
 
+#include <coreplugin/icore.h>
 #include <QtCore/QDebug>
+#include <QtCore/QTime>
 #include <typeinfo>
 
 using namespace QmlJS;
@@ -11,7 +15,8 @@ enum {
     debug = false
 };
 
-namespace {
+namespace QmlJSEditor {
+namespace Internal {
 
 class QmlOutlineModelSync : protected AST::Visitor
 {
@@ -22,14 +27,23 @@ public:
     {
     }
 
-    void operator()(Document::Ptr doc)
+    void operator()(Document::Ptr doc, const Snapshot &snapshot)
     {
         m_nodeToIndex.clear();
 
+        // Set up lookup context once to do the element type lookup
+        //
+        // We're simplifying here by using the root context everywhere
+        // (empty node list). However, creating the LookupContext is quite expensive (about 3ms),
+        // and there is AFAIK no way to introduce new type names in a sub-context.
+        m_context = LookupContext::create(doc, snapshot, QList<AST::Node*>());
+
         if (debug)
             qDebug() << "QmlOutlineModel ------";
         if (doc && doc->ast())
             doc->ast()->accept(this);
+
+        m_context.clear();
     }
 
 private:
@@ -64,7 +78,7 @@ private:
     }
 
 
-
+    typedef QPair<QString,QString> ElementType;
     bool visit(AST::UiObjectDefinition *objDef)
     {
         if (!validElement(objDef)) {
@@ -78,8 +92,14 @@ private:
                 + objDef->lastSourceLocation().length;
 
         const QString typeName = asString(objDef->qualifiedTypeNameId);
-        const QString id = getId(objDef);
-        QModelIndex index = m_model->enterElement(typeName, id, location);
+
+        if (!m_typeToIcon.contains(typeName)) {
+            m_typeToIcon.insert(typeName, getIcon(objDef));
+        }
+        const QIcon icon = m_typeToIcon.value(typeName);
+        QString id = getId(objDef);
+
+        QModelIndex index = m_model->enterElement(typeName, id, icon, location);
         m_nodeToIndex.insert(objDef, index);
         return true;
     }
@@ -112,10 +132,33 @@ private:
     }
 
     bool validElement(AST::UiObjectDefinition *objDef) {
-        // For 'Rectangle { id }', id is parsed as UiObjectDefinition ... Filter this out.ctan
+        // For 'Rectangle { id }', id is parsed as UiObjectDefinition ... Filter this out.
         return objDef->qualifiedTypeNameId->name->asString().at(0).isUpper();
     }
 
+    QIcon getIcon(AST::UiObjectDefinition *objDef) {
+        const QmlJS::Interpreter::Value *value = m_context->evaluate(objDef->qualifiedTypeNameId);
+
+        if (const Interpreter::ObjectValue *objectValue = value->asObjectValue()) {
+            do {
+                QString module;
+                QString typeName;
+                if (const Interpreter::QmlObjectValue *qmlObjectValue =
+                        dynamic_cast<const Interpreter::QmlObjectValue*>(objectValue)) {
+                    module = qmlObjectValue->packageName();
+                }
+                typeName = objectValue->className();
+
+                QIcon icon = m_model->m_icons->icon(module, typeName);
+                if (! icon.isNull())
+                    return icon;
+
+                objectValue = objectValue->prototype(m_context->context());
+            } while (objectValue);
+        }
+        return QIcon();
+    }
+
     QString getId(AST::UiObjectDefinition *objDef) {
         QString id;
         for (AST::UiObjectMemberList *it = objDef->initializer->members; it; it = it->next) {
@@ -137,19 +180,19 @@ private:
 
 
     QmlOutlineModel *m_model;
+    LookupContext::Ptr m_context;
+
     QHash<AST::Node*, QModelIndex> m_nodeToIndex;
+    QHash<QString, QIcon> m_typeToIcon;
     int indent;
 };
 
-
-} // namespace
-
-namespace QmlJSEditor {
-namespace Internal {
-
 QmlOutlineModel::QmlOutlineModel(QObject *parent) :
     QStandardItemModel(parent)
 {
+    m_icons = Icons::instance();
+    const QString resourcePath = Core::ICore::instance()->resourcePath();
+    QmlJS::Icons::instance()->setIconFilesPath(resourcePath + "/qmlicons");
 }
 
 QmlJS::Document::Ptr QmlOutlineModel::document() const
@@ -157,7 +200,7 @@ QmlJS::Document::Ptr QmlOutlineModel::document() const
     return m_document;
 }
 
-void QmlOutlineModel::update(QmlJS::Document::Ptr doc)
+void QmlOutlineModel::update(QmlJS::Document::Ptr doc, const QmlJS::Snapshot &snapshot)
 {
     m_document = doc;
 
@@ -166,12 +209,12 @@ void QmlOutlineModel::update(QmlJS::Document::Ptr doc)
     m_currentItem = invisibleRootItem();
 
     QmlOutlineModelSync syncModel(this);
-    syncModel(doc);
+    syncModel(doc, snapshot);
 
     emit updated();
 }
 
-QModelIndex QmlOutlineModel::enterElement(const QString &type, const QString &id, const AST::SourceLocation &sourceLocation)
+QModelIndex QmlOutlineModel::enterElement(const QString &type, const QString &id, const QIcon &icon, const AST::SourceLocation &sourceLocation)
 {
     QStandardItem *item = enterNode(sourceLocation);
     if (!id.isEmpty()) {
@@ -179,8 +222,8 @@ QModelIndex QmlOutlineModel::enterElement(const QString &type, const QString &id
     } else {
         item->setText(type);
     }
+    item->setIcon(icon);
     item->setToolTip(type);
-    item->setIcon(m_icons.objectDefinitionIcon());
     return item->index();
 }
 
@@ -193,7 +236,7 @@ QModelIndex QmlOutlineModel::enterProperty(const QString &name, const AST::Sourc
 {
     QStandardItem *item = enterNode(sourceLocation);
     item->setText(name);
-    item->setIcon(m_icons.scriptBindingIcon());
+    item->setIcon(m_icons->scriptBindingIcon());
     return item->index();
 }
 
diff --git a/src/plugins/qmljseditor/qmloutlinemodel.h b/src/plugins/qmljseditor/qmloutlinemodel.h
index f2e914a36c79e982bf0dda8210a1ec36776887f4..dbc3e7f217b9d5d45c382bfaf91c1f5eb93e7725 100644
--- a/src/plugins/qmljseditor/qmloutlinemodel.h
+++ b/src/plugins/qmljseditor/qmloutlinemodel.h
@@ -20,9 +20,9 @@ public:
     QmlOutlineModel(QObject *parent = 0);
 
     QmlJS::Document::Ptr document() const;
-    void update(QmlJS::Document::Ptr doc);
+    void update(QmlJS::Document::Ptr doc, const QmlJS::Snapshot &snapshot);
 
-    QModelIndex enterElement(const QString &typeName, const QString &id, const QmlJS::AST::SourceLocation &location);
+    QModelIndex enterElement(const QString &typeName, const QString &id, const QIcon &icon, const QmlJS::AST::SourceLocation &location);
     void leaveElement();
 
     QModelIndex enterProperty(const QString &name, const QmlJS::AST::SourceLocation &location);
@@ -40,7 +40,9 @@ private:
     QmlJS::Document::Ptr m_document;
     QList<int> m_treePos;
     QStandardItem *m_currentItem;
-    QmlJS::Icons m_icons;
+    QmlJS::Icons *m_icons;
+
+    friend class QmlOutlineModelSync;
 };
 
 } // namespace Internal