diff --git a/src/plugins/qmljsinspector/qmljsdelta.cpp b/src/plugins/qmljsinspector/qmljsdelta.cpp
index d31e7ce99e73622c815609b40191ac3345aad07c..491571cd3d973ad8768af9065c6a0654cf4c981e 100644
--- a/src/plugins/qmljsinspector/qmljsdelta.cpp
+++ b/src/plugins/qmljsinspector/qmljsdelta.cpp
@@ -39,66 +39,309 @@ using namespace QmlJS;
 using namespace QmlJS::AST;
 using namespace QmlJSInspector::Internal;
 
-UiObjectMember *ScriptBindingParser::parent(UiScriptBinding *script) const
-{ return _parent.value(script); }
-
-UiScriptBinding *ScriptBindingParser::id(UiObjectMember *parent) const
-{ return _id.value(parent); }
+/*!
+    Build a hash of the parents
+ */
+struct BuildParentHash : public Visitor
+{
+    virtual void postVisit(Node* );
+    virtual bool preVisit(Node* );
+    QHash<UiObjectMember *, UiObjectMember *> parent;
+private:
+    QList<UiObjectMember *> stack;
+};
+
+bool BuildParentHash::preVisit(Node* ast)
+{
+    if (ast->uiObjectMemberCast()) {
+        stack.append(ast->uiObjectMemberCast());
+    }
+    return true;
+}
 
-QList<UiScriptBinding *> ScriptBindingParser::ids() const
-{ return _id.values(); }
 
-QString ScriptBindingParser::header(UiObjectMember *member) const
+void BuildParentHash::postVisit(Node* ast)
 {
-    if (member) {
-        if (UiObjectDefinition *def = cast<UiObjectDefinition *>(member)) {
-            const int begin = def->firstSourceLocation().begin();
-            const int end = def->initializer->lbraceToken.begin();
-            return doc->source().mid(begin, end - begin);
-        } else if (UiObjectBinding *binding = cast<UiObjectBinding *>(member)) {
-            const int begin = binding->firstSourceLocation().begin();
-            const int end = binding->initializer->lbraceToken.begin();
-            return doc->source().mid(begin, end - begin);
+    if (ast->uiObjectMemberCast()) {
+        stack.removeLast();
+        if (!stack.isEmpty()) {
+            parent.insert(ast->uiObjectMemberCast(), stack.last());
         }
     }
+}
 
-    return QString();
+QString label(UiObjectMember *member, Document::Ptr doc)
+{
+    QString str;
+    if(!member)
+        return str;
+
+    if (UiObjectDefinition* foo = cast<UiObjectDefinition *>(member)) {
+        quint32 start = foo->firstSourceLocation().begin();
+        quint32 end = foo->initializer->lbraceToken.begin();
+        str = doc->source().mid(start, end-start);
+    } else if(UiObjectBinding *foo = cast<UiObjectBinding *>(member)) {
+        quint32 start = foo->firstSourceLocation().begin();
+        quint32 end = foo->initializer->lbraceToken.begin();
+        str = doc->source().mid(start, end-start);
+    } else if(cast<UiArrayBinding *>(member)) {
+        //TODO
+    } else {
+        quint32 start = member->firstSourceLocation().begin();
+        quint32 end = member->lastSourceLocation().end();
+        str = doc->source().mid(start, end-start);
+    }
+    return str;
 }
 
-QString ScriptBindingParser::scriptCode(UiScriptBinding *script) const
+struct FindObjectMemberWithLabel : public Visitor
+{
+    virtual void endVisit(UiObjectDefinition *ast) ;
+    virtual void endVisit(UiObjectBinding *ast) ;
+
+    QList<UiObjectMember *> found;
+    QString cmp;
+    Document::Ptr doc;
+};
+
+void FindObjectMemberWithLabel::endVisit(UiObjectDefinition* ast)
+{
+    if (label(ast, doc) == cmp)
+        found.append(ast);
+}
+void FindObjectMemberWithLabel::endVisit(UiObjectBinding* ast)
+{
+    if (label(ast, doc) == cmp)
+        found.append(ast);
+}
+
+struct Map {
+    typedef UiObjectMember*T;
+    QHash<T, T> way1;
+    QHash<T, T> way2;
+    void insert(T t1, T t2) {
+        way1.insert(t1,t2);
+        way2.insert(t2,t1);
+    }
+    int count() { return way1.count(); }
+    void operator+=(const Map &other) {
+        way1.unite(other.way1);
+        way2.unite(other.way2);
+    }
+    bool contains(T t1, T t2) {
+        return way1.value(t1) == t2;
+    }
+};
+
+QList<UiObjectMember *> children(UiObjectMember *ast)
+{
+    QList<UiObjectMember *> ret;
+    if (UiObjectDefinition* foo = cast<UiObjectDefinition *>(ast)) {
+        UiObjectMemberList* list = foo->initializer->members;
+        while (list) {
+            ret.append(list->member);
+            list = list->next;
+        }
+    }
+    return ret;
+}
+
+Map MatchFragment(UiObjectMember *x, UiObjectMember *y, const Map &M, Document::Ptr doc1, Document::Ptr doc2) {
+    Map M2;
+    if (M.way1.contains(x))
+        return M2;
+    if (M.way2.contains(y))
+        return M2;
+    if(label(x, doc1) != label(y, doc2))
+        return M2;
+    M2.insert(x, y);
+    const QList<UiObjectMember *> list1 = children(x);
+    const QList<UiObjectMember *> list2 = children(y);
+    for (int i = 0; i < qMin(list1.count(), list2.count()); i++) {
+        M2 += MatchFragment(list1[i], list2[i], M, doc1, doc2);
+    }
+    return M2;
+}
+
+Map Mapping(Document::Ptr doc1, Document::Ptr doc2)
+{
+    Map M;
+    QList<UiObjectMember *> todo;
+    todo.append(doc1->qmlProgram()->members->member);
+    while(!todo.isEmpty()) {
+        UiObjectMember *x = todo.takeFirst();
+        todo += children(x);
+
+        if (M.way1.contains(x))
+            continue;
+
+        //If this is too slow, we could use some sort of indexing
+        FindObjectMemberWithLabel v3;
+        v3.cmp = label(x, doc1);
+        v3.doc = doc2;
+        doc2->qmlProgram()->accept(&v3);
+        Map M2;
+        foreach (UiObjectMember *y, v3.found) {
+            if (M.way2.contains(y))
+                continue;
+            Map M3 = MatchFragment(x, y, M, doc1, doc2);
+            if (M3.count() > M2.count())
+                M2 = M3;
+        }
+        M += M2;
+    }
+    return M;
+}
+
+
+static QString _scriptCode(UiScriptBinding *script, Document::Ptr doc)
 {
     if (script) {
         const int begin = script->statement->firstSourceLocation().begin();
         const int end = script->statement->lastSourceLocation().end();
         return doc->source().mid(begin, end - begin);
     }
-
     return QString();
 }
 
-
-QString ScriptBindingParser::methodName(UiSourceElement *source) const
+static QString _methodCode(UiSourceElement *source, Document::Ptr doc)
 {
     if (source) {
         if (FunctionDeclaration *declaration = cast<FunctionDeclaration*>(source->sourceElement)) {
-            return declaration->name->asString();
+            const int begin = declaration->lbraceToken.begin() + 1;
+            const int end = declaration->rbraceToken.end() - 1;
+            return doc->source().mid(begin, end - begin);
         }
     }
     return QString();
 }
 
-QString ScriptBindingParser::methodCode(UiSourceElement *source) const
+
+static QString _propertyName(UiQualifiedId *id)
+{
+    QString s;
+
+    for (; id; id = id->next) {
+        if (! id->name)
+            return QString();
+
+        s += id->name->asString();
+
+        if (id->next)
+            s += QLatin1Char('.');
+    }
+
+    return s;
+}
+
+static QString _methodName(UiSourceElement *source)
 {
     if (source) {
         if (FunctionDeclaration *declaration = cast<FunctionDeclaration*>(source->sourceElement)) {
-            const int begin = declaration->lbraceToken.begin() + 1;
-            const int end = declaration->rbraceToken.end() - 1;
-            return doc->source().mid(begin, end - begin);
+            return declaration->name->asString();
         }
     }
     return QString();
 }
 
+
+
+Delta::DebugIdMap Delta::operator()(Document::Ptr doc1, Document::Ptr doc2, const DebugIdMap &debugIds)
+{
+    QHash< UiObjectMember*, QList<QDeclarativeDebugObjectReference > > newDebuggIds;
+
+    Map M = Mapping(doc1, doc2);
+
+    BuildParentHash parents2;
+    doc2->qmlProgram()->accept(&parents2);
+    BuildParentHash parents1;
+    doc1->qmlProgram()->accept(&parents1);
+
+    QList<UiObjectMember *> todo;
+    todo.append(doc2->qmlProgram()->members->member);
+    //UiObjectMemberList *list = 0;
+    while(!todo.isEmpty()) {
+        UiObjectMember *y = todo.takeFirst();
+        todo += children(y);
+        if (!M.way2.contains(y)) {
+            qDebug () << "insert " << label(y, doc2) << " to " << label(parents2.parent.value(y), doc2);
+            continue;
+        }
+        UiObjectMember *x = M.way2[y];
+
+
+//--8<---------------------------------------------------------------------------------------
+        if (debugIds.contains(x)) {
+            newDebuggIds[y] = debugIds[x];
+
+            UiObjectMember *object = y;
+            UiObjectMember *previousObject = x;
+
+            for (UiObjectMemberList *objectMemberIt = objectMembers(object); objectMemberIt; objectMemberIt = objectMemberIt->next) {
+                if (UiScriptBinding *script = cast<UiScriptBinding *>(objectMemberIt->member)) {
+                    for (UiObjectMemberList *previousObjectMemberIt = Delta::objectMembers(previousObject); previousObjectMemberIt; previousObjectMemberIt = previousObjectMemberIt->next) {
+                        if (UiScriptBinding *previousScript = cast<UiScriptBinding *>(previousObjectMemberIt->member)) {
+                            if (compare(script->qualifiedId, previousScript->qualifiedId)) {
+                                const QString scriptCode = _scriptCode(script, doc2);
+                                const QString previousScriptCode = _scriptCode(previousScript, doc1);
+
+                                if (scriptCode != previousScriptCode) {
+                                    const QString property = _propertyName(script->qualifiedId);
+                                    foreach (const QDeclarativeDebugObjectReference &ref, debugIds[x]) {
+                                        if (ref.debugId() != -1)
+                                            updateScriptBinding(ref, script, property, scriptCode);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                } else if (UiSourceElement *uiSource = cast<UiSourceElement*>(objectMemberIt->member)) {
+                    for (UiObjectMemberList *previousObjectMemberIt = objectMembers(previousObject);
+                    previousObjectMemberIt; previousObjectMemberIt = previousObjectMemberIt->next)
+                    {
+                        if (UiSourceElement *previousSource = cast<UiSourceElement*>(previousObjectMemberIt->member)) {
+                            if (compare(uiSource, previousSource))
+                            {
+                                const QString methodCode = _methodCode(uiSource, doc2);
+                                const QString previousMethodCode = _methodCode(previousSource, doc1);
+
+                                if (methodCode != previousMethodCode) {
+                                    const QString methodName = _methodName(uiSource);
+                                    foreach (const QDeclarativeDebugObjectReference &ref, debugIds[x]) {
+                                        if (ref.debugId() != -1)
+                                            updateMethodBody(ref, script, methodName, methodCode);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+//--8<--------------------------------------------------------------------------------------------------
+
+        //qDebug() << "match "<< label(x, doc1) << "with parent " << label(parents1.parent.value(x), doc1)
+        //     << " to "<< label(y, doc2) << "with parent " << label(parents2.parent.value(y), doc2);
+        if (!M.contains(parents1.parent.value(x),parents2.parent.value(y))) {
+            qDebug () << "move " << label(y, doc2) << " from " << label(parents1.parent.value(x), doc1)
+            << " to " << label(parents2.parent.value(y), doc2);
+            continue;
+        }
+    }
+
+    todo.append(doc1->qmlProgram()->members->member);
+    while(!todo.isEmpty()) {
+        UiObjectMember *x = todo.takeFirst();
+        todo += children(x);
+        if (!M.way1.contains(x)) {
+            qDebug () << "remove " << label(x, doc1);
+            continue;
+        }
+    }
+    return newDebuggIds;
+}
+
 static bool isLiteralValue(ExpressionNode *expr)
 {
     if (cast<NumericLiteral*>(expr))
@@ -191,227 +434,6 @@ static QVariant castToLiteral(const QString &expression, UiScriptBinding *script
     return castedExpression;
 }
 
-ScriptBindingParser::ScriptBindingParser(QmlJS::Document::Ptr doc,
-                                         const QList<QDeclarativeDebugObjectReference> &objectReferences)
-    : doc(doc), objectReferences(objectReferences), m_searchElementOffset(-1)
-{
-
-}
-
-void ScriptBindingParser::process()
-{
-    if (!doc.isNull() && doc->qmlProgram())
-        doc->qmlProgram()->accept(this);
-}
-
-QDeclarativeDebugObjectReference ScriptBindingParser::objectReferenceForOffset(unsigned int offset)
-{
-    m_searchElementOffset = offset;
-    if (!doc.isNull() && doc->qmlProgram())
-        doc->qmlProgram()->accept(this);
-
-    return m_foundObjectReference;
-}
-
-QDeclarativeDebugObjectReference ScriptBindingParser::objectReference(const QString &id) const
-{
-    foreach (const QDeclarativeDebugObjectReference &ref, objectReferences) {
-        if (ref.idString() == id)
-            return ref;
-    }
-
-    return QDeclarativeDebugObjectReference();
-}
-
-
-QDeclarativeDebugObjectReference ScriptBindingParser::objectReferenceForPosition(const QUrl &url, int line, int col) const
-{
-    foreach (const QDeclarativeDebugObjectReference &ref, objectReferences) {
-        if (ref.source().lineNumber() == line
-         && ref.source().columnNumber() == col
-         && ref.source().url() == url)
-        {
-            return ref;
-        }
-    }
-
-    return QDeclarativeDebugObjectReference();
-}
-
-bool ScriptBindingParser::visit(UiObjectDefinition *ast)
-{
-    objectStack.append(ast);
-    return true;
-}
-
-void ScriptBindingParser::endVisit(UiObjectDefinition *)
-{
-    objectStack.removeLast();
-}
-
-bool ScriptBindingParser::visit(UiObjectBinding *ast)
-{
-    objectStack.append(ast);
-    return true;
-}
-
-void ScriptBindingParser::endVisit(UiObjectBinding *)
-{
-    objectStack.removeLast();
-}
-
-bool ScriptBindingParser::visit(UiScriptBinding *ast)
-{
-    scripts.append(ast);
-    _parent[ast] = objectStack.back();
-
-    if (ast->qualifiedId && ast->qualifiedId->name && ! ast->qualifiedId->next) {
-        const QString bindingName = ast->qualifiedId->name->asString();
-
-        if (bindingName == QLatin1String("id")) {
-            _id[objectStack.back()] = ast;
-
-            if (ExpressionStatement *s = cast<ExpressionStatement *>(ast->statement)) {
-                if (IdentifierExpression *id = cast<IdentifierExpression *>(s->expression)) {
-                    if (id->name) {
-                        _idBindings.insert(ast, objectReference(id->name->asString()));
-
-                        if (parent(ast)->firstSourceLocation().offset == m_searchElementOffset)
-                            m_foundObjectReference = objectReference(id->name->asString());
-                    }
-                }
-            }
-        }
-    }
-
-    return true;
-}
-
-QDeclarativeDebugObjectReference ScriptBindingParser::objectReferenceForScriptBinding(UiScriptBinding *binding) const
-{
-    return _idBindings.value(binding);
-}
-
-// Delta
-
-static QString propertyName(UiQualifiedId *id)
-{
-    QString s;
-
-    for (; id; id = id->next) {
-        if (! id->name)
-            return QString();
-
-        s += id->name->asString();
-
-        if (id->next)
-            s += QLatin1Char('.');
-    }
-
-    return s;
-}
-
-QDeclarativeDebugObjectReference Delta::objectReferenceForUiObject(const ScriptBindingParser &bindingParser, UiObjectMember *object)
-{
-    if (UiScriptBinding *idBinding = bindingParser.id(object)) {
-        if (ExpressionStatement *s = cast<ExpressionStatement *>(idBinding->statement)) {
-            if (IdentifierExpression *idExpr = cast<IdentifierExpression *>(s->expression)) {
-                const QString idString = idExpr->name->asString();
-
-                const QList<QDeclarativeDebugObjectReference> refs = ClientProxy::instance()->objectReferences(_url);
-                foreach (const QDeclarativeDebugObjectReference &ref, refs) {
-                    if (ref.idString() == idString)
-                        return ref;
-                }
-            }
-        }
-    }
-    return QDeclarativeDebugObjectReference();
-}
-
-
-void Delta::operator()(Document::Ptr doc, Document::Ptr previousDoc)
-{
-    _doc = doc;
-    _previousDoc = previousDoc;
-    _changes.clear();
-
-    _url = QUrl::fromLocalFile(doc->fileName());
-    const QList<QDeclarativeDebugObjectReference> references = ClientProxy::instance()->objectReferences(_url);
-
-    ScriptBindingParser bindingParser(doc, references);
-    bindingParser.process();
-
-    ScriptBindingParser previousBindingParser(previousDoc, references);
-    previousBindingParser.process();
-
-    QHash<UiObjectMember *, UiObjectMember *> preservedObjects;
-
-    foreach (UiScriptBinding *id, bindingParser.ids()) {
-        UiObjectMember *parent = bindingParser.parent(id);
-        const QString idCode = bindingParser.scriptCode(id);
-
-        foreach (UiScriptBinding *otherId, previousBindingParser.ids()) {
-            const QString otherIdCode = previousBindingParser.scriptCode(otherId);
-
-            if (idCode == otherIdCode) {
-                preservedObjects.insert(parent, previousBindingParser.parent(otherId));
-            }
-        }
-    }
-
-    QHashIterator<UiObjectMember *, UiObjectMember *> it(preservedObjects);
-    while (it.hasNext()) {
-        it.next();
-
-        UiObjectMember *object = it.key();
-        UiObjectMember *previousObject = it.value();
-
-        for (UiObjectMemberList *objectMemberIt = objectMembers(object); objectMemberIt; objectMemberIt = objectMemberIt->next) {
-            if (UiScriptBinding *script = cast<UiScriptBinding *>(objectMemberIt->member)) {
-                for (UiObjectMemberList *previousObjectMemberIt = objectMembers(previousObject); previousObjectMemberIt; previousObjectMemberIt = previousObjectMemberIt->next) {
-                    if (UiScriptBinding *previousScript = cast<UiScriptBinding *>(previousObjectMemberIt->member)) {
-                        if (compare(script->qualifiedId, previousScript->qualifiedId)) {
-                            const QString scriptCode = bindingParser.scriptCode(script);
-                            const QString previousScriptCode = previousBindingParser.scriptCode(previousScript);
-
-                            if (scriptCode != previousScriptCode) {
-                                const QString property = propertyName(script->qualifiedId);
-
-                                QDeclarativeDebugObjectReference ref = objectReferenceForUiObject(bindingParser, object);
-                                if (ref.debugId() != -1)
-                                    updateScriptBinding(ref, script, property, scriptCode);
-                            }
-                        }
-                    }
-                }
-            } else if (UiSourceElement *uiSource = cast<UiSourceElement*>(objectMemberIt->member)) {
-
-                for (UiObjectMemberList *previousObjectMemberIt = objectMembers(previousObject);
-                     previousObjectMemberIt; previousObjectMemberIt = previousObjectMemberIt->next)
-                {
-                    if (UiSourceElement *previousSource = cast<UiSourceElement*>(previousObjectMemberIt->member)) {
-                        if (compare(uiSource, previousSource))
-                        {
-                            const QString methodCode = bindingParser.methodCode(uiSource);
-                            const QString previousMethodCode = previousBindingParser.methodCode(previousSource);
-
-                            if (methodCode != previousMethodCode) {
-                                const QString methodName = bindingParser.methodName(uiSource);
-                                QDeclarativeDebugObjectReference ref = objectReferenceForUiObject(bindingParser, object);
-                                if (ref.debugId() != -1)
-                                    updateMethodBody(ref, script, methodName, methodCode);
-                            }
-                        }
-                    }
-                }
-
-            }
-        }
-
-    }
-}
-
 void Delta::updateMethodBody(const QDeclarativeDebugObjectReference &objectReference,
                                UiScriptBinding *scriptBinding,
                                const QString &methodName,
diff --git a/src/plugins/qmljsinspector/qmljsdelta.h b/src/plugins/qmljsinspector/qmljsdelta.h
index 6d462bced79cf34c4655dcc5d6a1ca5f77a1ec04..30f06fce93c5bf3236e83c8477aca19a96cd49e2 100644
--- a/src/plugins/qmljsinspector/qmljsdelta.h
+++ b/src/plugins/qmljsinspector/qmljsdelta.h
@@ -43,53 +43,6 @@ using namespace QmlJS::AST;
 namespace QmlJSInspector {
 namespace Internal {
 
-class ScriptBindingParser : protected Visitor
-{
-public:
-    QmlJS::Document::Ptr doc;
-    QList<UiScriptBinding *> scripts;
-
-    ScriptBindingParser(Document::Ptr doc,
-                        const QList<QDeclarativeDebugObjectReference> &objectReferences = QList<QDeclarativeDebugObjectReference>());
-    void process();
-
-    UiObjectMember *parent(UiScriptBinding *script) const;
-    UiScriptBinding *id(UiObjectMember *parent) const;
-    QList<UiScriptBinding *> ids() const;
-
-    QDeclarativeDebugObjectReference objectReferenceForPosition(const QUrl &url, int line, int col) const;
-
-    QDeclarativeDebugObjectReference objectReferenceForScriptBinding(UiScriptBinding *binding) const;
-
-    QDeclarativeDebugObjectReference objectReferenceForOffset(unsigned int offset);
-
-    QString header(UiObjectMember *member) const;
-
-    QString scriptCode(UiScriptBinding *script) const;
-    QString methodName(UiSourceElement *source) const;
-    QString methodCode(UiSourceElement *source) const;
-
-protected:
-    QDeclarativeDebugObjectReference objectReference(const QString &id) const;
-
-    virtual bool visit(UiObjectDefinition *ast);
-    virtual void endVisit(UiObjectDefinition *);
-    virtual bool visit(UiObjectBinding *ast);
-    virtual void endVisit(UiObjectBinding *);
-    virtual bool visit(UiScriptBinding *ast);
-
-private:
-    QList<UiObjectMember *> objectStack;
-    QHash<UiScriptBinding *, UiObjectMember *> _parent;
-    QHash<UiObjectMember *, UiScriptBinding *> _id;
-    QHash<UiScriptBinding *, QDeclarativeDebugObjectReference> _idBindings;
-
-    QList<QDeclarativeDebugObjectReference> objectReferences;
-    QDeclarativeDebugObjectReference m_foundObjectReference;
-    unsigned int m_searchElementOffset;
-};
-
-
 class Delta
 {
 public:
@@ -102,14 +55,15 @@ public:
     };
 
 public:
-    void operator()(QmlJS::Document::Ptr doc, QmlJS::Document::Ptr previousDoc);
+    typedef QHash< UiObjectMember*, QList<QDeclarativeDebugObjectReference > > DebugIdMap;
+    DebugIdMap operator()(Document::Ptr doc1, Document::Ptr doc2, const DebugIdMap& debugIds);
 
     QList<Change> changes() const;
 
     QmlJS::Document::Ptr document() const;
     QmlJS::Document::Ptr previousDocument() const;
 
-private:
+public:
     void updateScriptBinding(const QDeclarativeDebugObjectReference &objectReference,
                              QmlJS::AST::UiScriptBinding *scriptBinding,
                              const QString &propertyName,
@@ -119,10 +73,9 @@ private:
                             const QString &methodName,
                             const QString &methodBody);
 
-    bool compare(UiSourceElement *source, UiSourceElement *other);
-    bool compare(QmlJS::AST::UiQualifiedId *id, QmlJS::AST::UiQualifiedId *other);
-    QmlJS::AST::UiObjectMemberList *objectMembers(QmlJS::AST::UiObjectMember *object);
-    QDeclarativeDebugObjectReference objectReferenceForUiObject(const ScriptBindingParser &bindingParser, UiObjectMember *object);
+    static bool compare(UiSourceElement *source, UiSourceElement *other);
+    static bool compare(QmlJS::AST::UiQualifiedId *id, QmlJS::AST::UiQualifiedId *other);
+    static QmlJS::AST::UiObjectMemberList *objectMembers(QmlJS::AST::UiObjectMember *object);
 
 private:
     QmlJS::Document::Ptr _doc;
diff --git a/src/plugins/qmljsinspector/qmljsinspector.cpp b/src/plugins/qmljsinspector/qmljsinspector.cpp
index b26df17f53f15da35c8d12ae234fca3088f0f9d5..57aed3284a044a65fa326ba66b876487d61d05dd 100644
--- a/src/plugins/qmljsinspector/qmljsinspector.cpp
+++ b/src/plugins/qmljsinspector/qmljsinspector.cpp
@@ -101,6 +101,11 @@ using namespace QmlJS::AST;
 using namespace QmlJSInspector::Internal;
 using namespace Debugger::Internal;
 
+
+
+
+
+
 enum {
     MaxConnectionAttempts = 50,
     ConnectionAttemptDefaultInterval = 75,
@@ -138,6 +143,7 @@ Inspector::Inspector(QObject *parent)
     connect(m_clientProxy, SIGNAL(aboutToReloadEngines()), SLOT(aboutToReloadEngines()));
     connect(m_clientProxy, SIGNAL(enginesChanged()), SLOT(updateEngineList()));
     connect(m_clientProxy, SIGNAL(aboutToDisconnect()), SLOT(disconnectWidgets()));
+    connect(m_clientProxy, SIGNAL(objectTreeUpdated(QDeclarativeDebugObjectReference)),SLOT(objectTreeUpdated(QDeclarativeDebugObjectReference)));
 
     connect(Debugger::DebuggerPlugin::instance(),
             SIGNAL(stateChanged(int)), this, SLOT(debuggerStateChanged(int)));
@@ -145,6 +151,7 @@ Inspector::Inspector(QObject *parent)
     connect(m_connectionTimer, SIGNAL(timeout()), SLOT(pollInspector()));
 }
 
+
 Inspector::~Inspector()
 {
 }
@@ -562,3 +569,68 @@ bool Inspector::addQuotesForData(const QVariant &value) const
 
     return false;
 }
+
+/*!
+   Associates the UiObjectMember* to their QDeclarativeDebugObjectReference.
+ */
+class MapObjectWithDebugReference : public Visitor
+{
+    public:
+        virtual void endVisit(UiObjectDefinition *ast) ;
+        virtual void endVisit(UiObjectBinding *ast) ;
+
+        QDeclarativeDebugObjectReference root;
+        QString filename;
+        QHash<UiObjectMember *, QList<QDeclarativeDebugObjectReference> > result;
+    private:
+        void processRecursive(const QDeclarativeDebugObjectReference &object, UiObjectMember *ast);
+};
+
+void MapObjectWithDebugReference::endVisit(UiObjectDefinition* ast)
+{
+    if (ast->qualifiedTypeNameId->name->asString().at(0).isUpper())
+        processRecursive(root, ast);
+}
+void MapObjectWithDebugReference::endVisit(UiObjectBinding* ast)
+{
+    if (ast->qualifiedId->name->asString().at(0).isUpper())
+        processRecursive(root, ast);
+}
+
+void MapObjectWithDebugReference::processRecursive(const QDeclarativeDebugObjectReference& object, UiObjectMember* ast)
+{
+    // If this is too slow, it can be speed up by indexing
+    // the QDeclarativeDebugObjectReference by filename/loc in a fist pass
+
+    SourceLocation loc = ast->firstSourceLocation();
+    if (object.source().lineNumber() == int(loc.startLine) && object.source().url().toLocalFile() == filename) {
+        result[ast] += object;
+    }
+
+    foreach (const QDeclarativeDebugObjectReference &it, object.children()) {
+        processRecursive(it, ast);
+    }
+}
+
+void QmlJSInspector::Internal::Inspector::objectTreeUpdated(const QDeclarativeDebugObjectReference &ref)
+{
+    QmlJS::ModelManagerInterface *m = QmlJS::ModelManagerInterface::instance();
+    Snapshot snapshot = m->snapshot();
+    QHash<QString, QHash<UiObjectMember *, QList< QDeclarativeDebugObjectReference> > > allDebugIds;
+    foreach(const Document::Ptr &doc, snapshot) {
+        if (!doc->qmlProgram())
+            continue;
+        MapObjectWithDebugReference visitor;
+        visitor.root = ref;
+        QString filename = doc->fileName();
+        visitor.filename = filename;
+        doc->qmlProgram()->accept(&visitor);
+        allDebugIds[filename] = visitor.result;
+    }
+
+    //FIXME
+    m_textPreview->m_initialTable = allDebugIds;
+    m_textPreview->m_debugIds.clear();
+}
+
+
diff --git a/src/plugins/qmljsinspector/qmljsinspector.h b/src/plugins/qmljsinspector/qmljsinspector.h
index 228011280be7b639692cdf4c5dec538eaa595f74..ac8de8f6362fd185ee62b14ddcb586c505aa94a3 100644
--- a/src/plugins/qmljsinspector/qmljsinspector.h
+++ b/src/plugins/qmljsinspector/qmljsinspector.h
@@ -72,6 +72,8 @@ public:
         QmlProjectWithCppPlugins
     };
 
+    QHash< QString, QList< QPair< QmlJS::AST::UiObjectMember*, int > > > m_initialTable;
+
 public:
     Inspector(QObject *parent = 0);
     virtual ~Inspector();
@@ -115,6 +117,8 @@ private slots:
     void disconnectWidgets();
     void disconnected();
 
+    void objectTreeUpdated(const QDeclarativeDebugObjectReference &ref);
+
 private:
     Debugger::DebuggerRunControl *createDebuggerRunControl(ProjectExplorer::RunConfiguration *runConfig,
                                                            const QString &executableFile = QString(),
diff --git a/src/plugins/qmljsinspector/qmljslivetextpreview.cpp b/src/plugins/qmljsinspector/qmljslivetextpreview.cpp
index 9cce2ea13d925cd4885d348a8256dd59ceaafe39..0dd55e22451809fdb3bbe2fe165d347434b01b8e 100644
--- a/src/plugins/qmljsinspector/qmljslivetextpreview.cpp
+++ b/src/plugins/qmljsinspector/qmljslivetextpreview.cpp
@@ -60,7 +60,7 @@ void QmlJSLiveTextPreview::changeSelectedElement(int offset, const QString &word
     ClientProxy *clientProxy = ClientProxy::instance();
     QUrl url = QUrl::fromLocalFile(m_currentEditor.data()->file()->fileName());
     QmlJS::Document::Ptr doc = modelManager()->snapshot().document(m_currentEditor.data()->file()->fileName());
-    ScriptBindingParser info(doc, clientProxy->objectReferences(url));
+    //ScriptBindingParser info(doc, clientProxy->objectReferences(url));
 
     QDeclarativeDebugObjectReference objectRef;
 
@@ -72,9 +72,10 @@ void QmlJSLiveTextPreview::changeSelectedElement(int offset, const QString &word
         }
     }
 
+   /* FIXME
     if (objectRef.debugId() == -1 && offset >= 0) {
         objectRef = info.objectReferenceForOffset(offset);
-    }
+    }*/
 
     if (objectRef.debugId() != -1)
         emit selectedItemsChanged(QList<QDeclarativeDebugObjectReference>() << objectRef);
@@ -96,20 +97,28 @@ void QmlJSLiveTextPreview::setEditor(Core::IEditor *editor)
     }
 }
 
+
 void QmlJSLiveTextPreview::documentChanged(QmlJS::Document::Ptr doc)
-{    
+{
+   /* FIXME
     Core::ICore *core = Core::ICore::instance();
     const int dbgcontext = core->uniqueIDManager()->uniqueIdentifier(Debugger::Constants::C_DEBUGMODE);
 
     if (!core->hasContext(dbgcontext))
         return;
+    */
 
     if (doc && m_previousDoc && doc->fileName() == m_previousDoc->fileName()) {
+
+        if (m_debugIds.isEmpty())
+            m_debugIds = m_initialTable.value(doc->fileName());
         Delta delta;
-        delta(doc, m_previousDoc);
+        m_debugIds = delta(m_previousDoc, doc,  m_debugIds);
         m_previousDoc = doc;
+
     }
 }
 
+
 } // namespace Internal
 } // namespace QmlJSInspector
diff --git a/src/plugins/qmljsinspector/qmljslivetextpreview.h b/src/plugins/qmljsinspector/qmljslivetextpreview.h
index 6b22721b2676a30abfea98bd4e968c18c9789bc9..a843c914b9ccffadf01ff6c70520086612c3bac6 100644
--- a/src/plugins/qmljsinspector/qmljslivetextpreview.h
+++ b/src/plugins/qmljsinspector/qmljslivetextpreview.h
@@ -31,6 +31,7 @@ namespace Internal {
 class QmlJSLiveTextPreview : public QObject
 {
     Q_OBJECT
+
 public:
     explicit QmlJSLiveTextPreview(QObject *parent = 0);
     static QmlJS::ModelManagerInterface *modelManager();
@@ -39,6 +40,9 @@ public:
     void setActiveObject(const QDeclarativeDebugObjectReference &object);
     void mapObjectToQml(const QDeclarativeDebugObjectReference &object);
 
+    QHash<QString, QHash<QmlJS::AST::UiObjectMember *, QList< QDeclarativeDebugObjectReference> > > m_initialTable;
+    QHash< QmlJS::AST::UiObjectMember*, QList<QDeclarativeDebugObjectReference > > m_debugIds;
+
 signals:
     void selectedItemsChanged(const QList<QDeclarativeDebugObjectReference> &objects);