diff --git a/src/plugins/qmljseditor/qmljseditor.pro b/src/plugins/qmljseditor/qmljseditor.pro
index f92ba23c6cbb619b90d035c4226eeacf3b225375..e35f6e40e303b73b76e39c677b02be38b41b89f0 100644
--- a/src/plugins/qmljseditor/qmljseditor.pro
+++ b/src/plugins/qmljseditor/qmljseditor.pro
@@ -24,7 +24,8 @@ HEADERS += \
     qmljsquickfix.h \
     qmljsrefactoringchanges.h \
     qmljscomponentfromobjectdef.h \
-    qmljsoutline.h
+    qmljsoutline.h \
+    qmloutlinemodel.h
 
 SOURCES += \
     qmljscodecompletion.cpp \
@@ -41,7 +42,8 @@ SOURCES += \
     qmljsquickfix.cpp \
     qmljsrefactoringchanges.cpp \
     qmljscomponentfromobjectdef.cpp \
-    qmljsoutline.cpp
+    qmljsoutline.cpp \
+    qmloutlinemodel.cpp
 
 RESOURCES += qmljseditor.qrc
 OTHER_FILES += QmlJSEditor.pluginspec QmlJSEditor.mimetypes.xml
diff --git a/src/plugins/qmljseditor/qmljsoutline.cpp b/src/plugins/qmljseditor/qmljsoutline.cpp
index 251121008633d3b4db909e1c38a94b6fb50705aa..a95c0842c90dc48277cb0cf2acb319d0d34335d5 100644
--- a/src/plugins/qmljseditor/qmljsoutline.cpp
+++ b/src/plugins/qmljseditor/qmljsoutline.cpp
@@ -1,15 +1,9 @@
 #include "qmljsoutline.h"
+#include "qmloutlinemodel.h"
 
-#include <coreplugin/icore.h>
-#include <extensionsystem/pluginmanager.h>
-#include <qmljs/parser/qmljsast_p.h>
-#include <qmljs/qmljsmodelmanagerinterface.h>
-
-#include <QtCore/QDebug>
+#include <coreplugin/ifile.h>
 #include <QtGui/QVBoxLayout>
 
-#include <typeinfo>
-
 using namespace QmlJS;
 
 enum {
@@ -19,11 +13,6 @@ enum {
 namespace QmlJSEditor {
 namespace Internal {
 
-QmlOutlineModel::QmlOutlineModel(QObject *parent) :
-    QStandardItemModel(parent)
-{
-}
-
 QmlJSOutlineTreeView::QmlJSOutlineTreeView(QWidget *parent) :
     QTreeView(parent)
 {
@@ -38,203 +27,6 @@ QmlJSOutlineTreeView::QmlJSOutlineTreeView(QWidget *parent) :
     setExpandsOnDoubleClick(false);
 }
 
-void QmlOutlineModel::startSync()
-{
-    m_treePos.clear();
-    m_treePos.append(0);
-    m_currentItem = invisibleRootItem();
-}
-
-QModelIndex QmlOutlineModel::enterElement(const QString &type, const AST::SourceLocation &sourceLocation)
-{
-    QStandardItem *item = enterNode(sourceLocation);
-    item->setText(type);
-    item->setIcon(m_icons.objectDefinitionIcon());
-    return item->index();
-}
-
-void QmlOutlineModel::leaveElement()
-{
-    leaveNode();
-}
-
-QModelIndex QmlOutlineModel::enterProperty(const QString &name, const AST::SourceLocation &sourceLocation)
-{
-    QStandardItem *item = enterNode(sourceLocation);
-    item->setText(name);
-    item->setIcon(m_icons.scriptBindingIcon());
-    return item->index();
-}
-
-void QmlOutlineModel::leaveProperty()
-{
-    leaveNode();
-}
-
-QStandardItem *QmlOutlineModel::enterNode(const QmlJS::AST::SourceLocation &location)
-{
-    int siblingIndex = m_treePos.last();
-    if (siblingIndex == 0) {
-        // first child
-        if (!m_currentItem->hasChildren()) {
-            QStandardItem *parentItem = m_currentItem;
-            m_currentItem = new QStandardItem;
-            m_currentItem->setEditable(false);
-            parentItem->appendRow(m_currentItem);
-            if (debug)
-                qDebug() << "QmlOutlineModel - Adding" << "element to" << parentItem->text();
-        } else {
-            m_currentItem = m_currentItem->child(0);
-        }
-    } else {
-        // sibling
-        if (m_currentItem->rowCount() <= siblingIndex) {
-            // attach
-            QStandardItem *oldItem = m_currentItem;
-            m_currentItem = new QStandardItem;
-            m_currentItem->setEditable(false);
-            oldItem->appendRow(m_currentItem);
-            if (debug)
-                qDebug() << "QmlOutlineModel - Adding" << "element to" << oldItem->text();
-        } else {
-            m_currentItem = m_currentItem->child(siblingIndex);
-        }
-    }
-
-    m_treePos.append(0);
-    m_currentItem->setData(QVariant::fromValue(location), SourceLocationRole);
-
-    return m_currentItem;
-}
-
-void QmlOutlineModel::leaveNode()
-{
-    int lastIndex = m_treePos.takeLast();
-
-
-    if (lastIndex > 0) {
-        // element has children
-        if (lastIndex < m_currentItem->rowCount()) {
-            if (debug)
-                qDebug() << "QmlOutlineModel - removeRows from " << m_currentItem->text() << lastIndex << m_currentItem->rowCount() - lastIndex;
-            m_currentItem->removeRows(lastIndex, m_currentItem->rowCount() - lastIndex);
-        }
-        m_currentItem = parentItem();
-    } else {
-        if (m_currentItem->hasChildren()) {
-            if (debug)
-                qDebug() << "QmlOutlineModel - removeRows from " << m_currentItem->text() << 0 << m_currentItem->rowCount();
-            m_currentItem->removeRows(0, m_currentItem->rowCount());
-        }
-        m_currentItem = parentItem();
-    }
-
-
-    m_treePos.last()++;
-}
-
-QStandardItem *QmlOutlineModel::parentItem()
-{
-    QStandardItem *parent = m_currentItem->parent();
-    if (!parent)
-        parent = invisibleRootItem();
-    return parent;
-}
-
-class QmlOutlineModelSync : protected AST::Visitor
-{
-public:
-    QmlOutlineModelSync(QmlOutlineModel *model) :
-        m_model(model),
-        indent(0)
-    {
-    }
-
-    void operator()(Document::Ptr doc)
-    {
-        m_nodeToIndex.clear();
-
-        if (debug)
-            qDebug() << "QmlOutlineModel ------";
-        m_model->startSync();
-        if (doc && doc->ast())
-            doc->ast()->accept(this);
-    }
-
-private:
-    bool preVisit(AST::Node *node)
-    {
-        if (!node)
-            return false;
-        if (debug)
-            qDebug() << "QmlOutlineModel -" << QByteArray(indent++, '-').constData() << node << typeid(*node).name();
-        return true;
-    }
-
-    void postVisit(AST::Node *)
-    {
-        indent--;
-    }
-
-    QString asString(AST::UiQualifiedId *id)
-    {
-        QString text;
-        for (; id; id = id->next) {
-            if (id->name)
-                text += id->name->asString();
-            else
-                text += QLatin1Char('?');
-
-            if (id->next)
-                text += QLatin1Char('.');
-        }
-
-        return text;
-    }
-
-    bool visit(AST::UiObjectDefinition *objDef)
-    {
-        AST::SourceLocation location;
-        location.offset = objDef->firstSourceLocation().offset;
-        location.length = objDef->lastSourceLocation().offset
-                - objDef->firstSourceLocation().offset
-                + objDef->lastSourceLocation().length;
-
-        QModelIndex index = m_model->enterElement(asString(objDef->qualifiedTypeNameId), location);
-        m_nodeToIndex.insert(objDef, index);
-        return true;
-    }
-
-    void endVisit(AST::UiObjectDefinition * /*objDefinition*/)
-    {
-        m_model->leaveElement();
-    }
-
-    bool visit(AST::UiScriptBinding *scriptBinding)
-    {
-        AST::SourceLocation location;
-        location.offset = scriptBinding->firstSourceLocation().offset;
-        location.length = scriptBinding->lastSourceLocation().offset
-                - scriptBinding->firstSourceLocation().offset
-                + scriptBinding->lastSourceLocation().length;
-
-        QModelIndex index = m_model->enterProperty(asString(scriptBinding->qualifiedId), location);
-        m_nodeToIndex.insert(scriptBinding, index);
-
-        return true;
-    }
-
-    void endVisit(AST::UiScriptBinding * /*scriptBinding*/)
-    {
-        m_model->leaveProperty();
-    }
-
-    QmlOutlineModel *m_model;
-    QHash<AST::Node*, QModelIndex> m_nodeToIndex;
-    int indent;
-};
-
-
 QmlJSOutlineWidget::QmlJSOutlineWidget(QWidget *parent) :
     TextEditor::IOutlineWidget(parent),
     m_treeView(new QmlJSOutlineTreeView()),
@@ -295,8 +87,7 @@ void QmlJSOutlineWidget::updateOutline(const QmlJSEditor::Internal::SemanticInfo
         // got a correctly parsed (or recovered) file.
 
         if (QmlOutlineModel *qmlModel = qobject_cast<QmlOutlineModel*>(m_model)) {
-            QmlOutlineModelSync syncModel(qmlModel);
-            syncModel(doc);
+            qmlModel->update(doc);
         }
     } else {
         // TODO: Maybe disable view?
diff --git a/src/plugins/qmljseditor/qmljsoutline.h b/src/plugins/qmljseditor/qmljsoutline.h
index 1571069afb12a3f78e32561dc3c7c52d42a29561..14441eff865f686dd8877759a287da42a51af5c4 100644
--- a/src/plugins/qmljseditor/qmljsoutline.h
+++ b/src/plugins/qmljseditor/qmljsoutline.h
@@ -3,16 +3,9 @@
 
 #include "qmljseditor.h"
 
-#include <coreplugin/editormanager/editormanager.h>
-#include <coreplugin/inavigationwidgetfactory.h>
 #include <texteditor/ioutlinewidget.h>
-#include <qmljs/parser/qmljsastvisitor_p.h>
-#include <qmljs/qmljsdocument.h>
-#include <qmljs/qmljsicons.h>
 
-#include <QtGui/QStandardItemModel>
 #include <QtGui/QTreeView>
-#include <QtGui/QWidget>
 
 namespace Core {
 class IEditor;
@@ -25,35 +18,6 @@ class Editor;
 namespace QmlJSEditor {
 namespace Internal {
 
-class QmlOutlineModel : public QStandardItemModel
-{
-    Q_OBJECT
-public:
-    enum CustomRoles {
-        SourceLocationRole = Qt::UserRole + 1
-    };
-
-    QmlOutlineModel(QObject *parent = 0);
-
-    void startSync();
-
-    QModelIndex enterElement(const QString &typeName, const QmlJS::AST::SourceLocation &location);
-    void leaveElement();
-
-    QModelIndex enterProperty(const QString &name, const QmlJS::AST::SourceLocation &location);
-    void leaveProperty();
-
-private:
-    QStandardItem *enterNode(const QmlJS::AST::SourceLocation &location);
-    void leaveNode();
-
-    QStandardItem *parentItem();
-
-    QList<int> m_treePos;
-    QStandardItem *m_currentItem;
-    QmlJS::Icons m_icons;
-};
-
 class QmlJSOutlineTreeView : public QTreeView
 {
     Q_OBJECT
@@ -61,7 +25,6 @@ public:
     QmlJSOutlineTreeView(QWidget *parent = 0);
 };
 
-
 class QmlJSOutlineWidget : public TextEditor::IOutlineWidget
 {
     Q_OBJECT
@@ -103,6 +66,4 @@ public:
 } // namespace Internal
 } // namespace QmlJSEditor
 
-Q_DECLARE_METATYPE(QmlJS::AST::SourceLocation);
-
 #endif // QMLJSOUTLINE_H
diff --git a/src/plugins/qmljseditor/qmloutlinemodel.cpp b/src/plugins/qmljseditor/qmloutlinemodel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e0d7129640a83a054e2614b7a3ad2b917ff718a0
--- /dev/null
+++ b/src/plugins/qmljseditor/qmloutlinemodel.cpp
@@ -0,0 +1,226 @@
+#include "qmloutlinemodel.h"
+#include <qmljs/parser/qmljsastvisitor_p.h>
+
+#include <QtCore/QDebug>
+#include <typeinfo>
+
+using namespace QmlJS;
+using namespace QmlJSEditor::Internal;
+
+enum {
+    debug = false
+};
+
+namespace {
+
+class QmlOutlineModelSync : protected AST::Visitor
+{
+public:
+    QmlOutlineModelSync(QmlOutlineModel *model) :
+        m_model(model),
+        indent(0)
+    {
+    }
+
+    void operator()(Document::Ptr doc)
+    {
+        m_nodeToIndex.clear();
+
+        if (debug)
+            qDebug() << "QmlOutlineModel ------";
+        if (doc && doc->ast())
+            doc->ast()->accept(this);
+    }
+
+private:
+    bool preVisit(AST::Node *node)
+    {
+        if (!node)
+            return false;
+        if (debug)
+            qDebug() << "QmlOutlineModel -" << QByteArray(indent++, '-').constData() << node << typeid(*node).name();
+        return true;
+    }
+
+    void postVisit(AST::Node *)
+    {
+        indent--;
+    }
+
+    QString asString(AST::UiQualifiedId *id)
+    {
+        QString text;
+        for (; id; id = id->next) {
+            if (id->name)
+                text += id->name->asString();
+            else
+                text += QLatin1Char('?');
+
+            if (id->next)
+                text += QLatin1Char('.');
+        }
+
+        return text;
+    }
+
+    bool visit(AST::UiObjectDefinition *objDef)
+    {
+        AST::SourceLocation location;
+        location.offset = objDef->firstSourceLocation().offset;
+        location.length = objDef->lastSourceLocation().offset
+                - objDef->firstSourceLocation().offset
+                + objDef->lastSourceLocation().length;
+
+        QModelIndex index = m_model->enterElement(asString(objDef->qualifiedTypeNameId), location);
+        m_nodeToIndex.insert(objDef, index);
+        return true;
+    }
+
+    void endVisit(AST::UiObjectDefinition * /*objDefinition*/)
+    {
+        m_model->leaveElement();
+    }
+
+    bool visit(AST::UiScriptBinding *scriptBinding)
+    {
+        AST::SourceLocation location;
+        location.offset = scriptBinding->firstSourceLocation().offset;
+        location.length = scriptBinding->lastSourceLocation().offset
+                - scriptBinding->firstSourceLocation().offset
+                + scriptBinding->lastSourceLocation().length;
+
+        QModelIndex index = m_model->enterProperty(asString(scriptBinding->qualifiedId), location);
+        m_nodeToIndex.insert(scriptBinding, index);
+
+        return true;
+    }
+
+    void endVisit(AST::UiScriptBinding * /*scriptBinding*/)
+    {
+        m_model->leaveProperty();
+    }
+
+    QmlOutlineModel *m_model;
+    QHash<AST::Node*, QModelIndex> m_nodeToIndex;
+    int indent;
+};
+
+
+} // namespace
+
+namespace QmlJSEditor {
+namespace Internal {
+
+QmlOutlineModel::QmlOutlineModel(QObject *parent) :
+    QStandardItemModel(parent)
+{
+}
+
+void QmlOutlineModel::update(QmlJS::Document::Ptr doc)
+{
+    m_treePos.clear();
+    m_treePos.append(0);
+    m_currentItem = invisibleRootItem();
+
+    QmlOutlineModelSync syncModel(this);
+    syncModel(doc);
+}
+
+QModelIndex QmlOutlineModel::enterElement(const QString &type, const AST::SourceLocation &sourceLocation)
+{
+    QStandardItem *item = enterNode(sourceLocation);
+    item->setText(type);
+    item->setIcon(m_icons.objectDefinitionIcon());
+    return item->index();
+}
+
+void QmlOutlineModel::leaveElement()
+{
+    leaveNode();
+}
+
+QModelIndex QmlOutlineModel::enterProperty(const QString &name, const AST::SourceLocation &sourceLocation)
+{
+    QStandardItem *item = enterNode(sourceLocation);
+    item->setText(name);
+    item->setIcon(m_icons.scriptBindingIcon());
+    return item->index();
+}
+
+void QmlOutlineModel::leaveProperty()
+{
+    leaveNode();
+}
+
+QStandardItem *QmlOutlineModel::enterNode(const QmlJS::AST::SourceLocation &location)
+{
+    int siblingIndex = m_treePos.last();
+    if (siblingIndex == 0) {
+        // first child
+        if (!m_currentItem->hasChildren()) {
+            QStandardItem *parentItem = m_currentItem;
+            m_currentItem = new QStandardItem;
+            m_currentItem->setEditable(false);
+            parentItem->appendRow(m_currentItem);
+            if (debug)
+                qDebug() << "QmlOutlineModel - Adding" << "element to" << parentItem->text();
+        } else {
+            m_currentItem = m_currentItem->child(0);
+        }
+    } else {
+        // sibling
+        if (m_currentItem->rowCount() <= siblingIndex) {
+            // attach
+            QStandardItem *oldItem = m_currentItem;
+            m_currentItem = new QStandardItem;
+            m_currentItem->setEditable(false);
+            oldItem->appendRow(m_currentItem);
+            if (debug)
+                qDebug() << "QmlOutlineModel - Adding" << "element to" << oldItem->text();
+        } else {
+            m_currentItem = m_currentItem->child(siblingIndex);
+        }
+    }
+
+    m_treePos.append(0);
+    m_currentItem->setData(QVariant::fromValue(location), SourceLocationRole);
+
+    return m_currentItem;
+}
+
+void QmlOutlineModel::leaveNode()
+{
+    int lastIndex = m_treePos.takeLast();
+
+
+    if (lastIndex > 0) {
+        // element has children
+        if (lastIndex < m_currentItem->rowCount()) {
+            if (debug)
+                qDebug() << "QmlOutlineModel - removeRows from " << m_currentItem->text() << lastIndex << m_currentItem->rowCount() - lastIndex;
+            m_currentItem->removeRows(lastIndex, m_currentItem->rowCount() - lastIndex);
+        }
+        m_currentItem = parentItem();
+    } else {
+        if (m_currentItem->hasChildren()) {
+            if (debug)
+                qDebug() << "QmlOutlineModel - removeRows from " << m_currentItem->text() << 0 << m_currentItem->rowCount();
+            m_currentItem->removeRows(0, m_currentItem->rowCount());
+        }
+        m_currentItem = parentItem();
+    }
+
+
+    m_treePos.last()++;
+}
+
+QStandardItem *QmlOutlineModel::parentItem()
+{
+    QStandardItem *parent = m_currentItem->parent();
+    if (!parent)
+        parent = invisibleRootItem();
+    return parent;
+}
+
+} // namespace Internal
+} // namespace QmlJSEditor
diff --git a/src/plugins/qmljseditor/qmloutlinemodel.h b/src/plugins/qmljseditor/qmloutlinemodel.h
new file mode 100644
index 0000000000000000000000000000000000000000..67c2628f0dce585ffcd4be3a0fc7c8845e3da289
--- /dev/null
+++ b/src/plugins/qmljseditor/qmloutlinemodel.h
@@ -0,0 +1,46 @@
+#ifndef QMLOUTLINEMODEL_H
+#define QMLOUTLINEMODEL_H
+
+#include <qmljs/qmljsdocument.h>
+#include <qmljs/qmljsicons.h>
+
+#include <QStandardItemModel>
+
+namespace QmlJSEditor {
+namespace Internal {
+
+class QmlOutlineModel : public QStandardItemModel
+{
+    Q_OBJECT
+public:
+    enum CustomRoles {
+        SourceLocationRole = Qt::UserRole + 1
+    };
+
+    QmlOutlineModel(QObject *parent = 0);
+
+    void update(QmlJS::Document::Ptr doc);
+
+    QModelIndex enterElement(const QString &typeName, const QmlJS::AST::SourceLocation &location);
+    void leaveElement();
+
+    QModelIndex enterProperty(const QString &name, const QmlJS::AST::SourceLocation &location);
+    void leaveProperty();
+
+private:
+    QStandardItem *enterNode(const QmlJS::AST::SourceLocation &location);
+    void leaveNode();
+
+    QStandardItem *parentItem();
+
+    QList<int> m_treePos;
+    QStandardItem *m_currentItem;
+    QmlJS::Icons m_icons;
+};
+
+} // namespace Internal
+} // namespace QmlJSEditor
+
+Q_DECLARE_METATYPE(QmlJS::AST::SourceLocation);
+
+#endif // QMLOUTLINEMODEL_H