diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h
index 7c9d0201d9d9a32f040f3f17c35c876d447be80d..83bcce2be8eca9f5c6a16535202867da8421679a 100644
--- a/src/libs/qmljs/qmljsinterpreter.h
+++ b/src/libs/qmljs/qmljsinterpreter.h
@@ -401,7 +401,7 @@ private:
     QString _className;
 };
 
-class QmlObjectValue: public ObjectValue
+class QMLJS_EXPORT QmlObjectValue: public ObjectValue
 {
 public:
     static const int NoVersion;
diff --git a/src/plugins/qmldesigner/QmlDesigner.pluginspec b/src/plugins/qmldesigner/QmlDesigner.pluginspec
index 916d7b8229fddbb4afd959d4424fcb59a7fa8439..bb2ed107848474f10f783688182f796c621becdd 100644
--- a/src/plugins/qmldesigner/QmlDesigner.pluginspec
+++ b/src/plugins/qmldesigner/QmlDesigner.pluginspec
@@ -22,5 +22,6 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license>
     <dependencyList>
         <dependency name="Core" version="1.3.82"/>
         <dependency name="TextEditor" version="1.3.82"/>
+        <dependency name="QmlJSEditor" version="1.3.82"/>
     </dependencyList>
 </plugin>
diff --git a/src/plugins/qmldesigner/core/include/basetexteditmodifier.h b/src/plugins/qmldesigner/core/include/basetexteditmodifier.h
index b2d50a3c3da9b062cff1b892ad344a883d4004fa..5c1538bb7773e43acb7ad647efddff413c287a75 100644
--- a/src/plugins/qmldesigner/core/include/basetexteditmodifier.h
+++ b/src/plugins/qmldesigner/core/include/basetexteditmodifier.h
@@ -36,6 +36,10 @@
 
 #include <texteditor/basetexteditor.h>
 
+namespace QmlJS {
+class Snapshot;
+} // namespace QmlJS
+
 namespace QmlDesigner {
 
 class CORESHARED_EXPORT BaseTextEditModifier: public PlainTextEditModifier
@@ -46,6 +50,8 @@ public:
     virtual void indent(int offset, int length);
 
     virtual int indentDepth() const;
+
+    static QmlJS::Snapshot getSnapshot();
 };
 
 } // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/core/model/basetexteditmodifier.cpp b/src/plugins/qmldesigner/core/model/basetexteditmodifier.cpp
index 4e22eb6835246ab69ee02a656f4be93796b823f7..424858f38d06816f0501065e5a8a135b01906c17 100644
--- a/src/plugins/qmldesigner/core/model/basetexteditmodifier.cpp
+++ b/src/plugins/qmldesigner/core/model/basetexteditmodifier.cpp
@@ -29,9 +29,13 @@
 
 #include "basetexteditmodifier.h"
 
+#include <extensionsystem/pluginmanager.h>
+#include <qmljs/qmljsdocument.h>
+#include <qmljseditor/qmljsmodelmanagerinterface.h>
 #include <texteditor/tabsettings.h>
 
 using namespace QmlDesigner;
+using namespace QmlJSEditor;
 
 BaseTextEditModifier::BaseTextEditModifier(TextEditor::BaseTextEditor *textEdit):
         PlainTextEditModifier(textEdit)
@@ -63,3 +67,13 @@ int BaseTextEditModifier::indentDepth() const
         return 0;
     }
 }
+
+QmlJS::Snapshot BaseTextEditModifier::getSnapshot()
+{
+    ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance();
+    QmlJSEditor::ModelManagerInterface *modelManager = pluginManager->getObject<QmlJSEditor::ModelManagerInterface>();
+    if (modelManager)
+        return modelManager->snapshot();
+    else
+        return QmlJS::Snapshot();
+}
diff --git a/src/plugins/qmldesigner/core/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/core/model/texttomodelmerger.cpp
index 173d43d444a989e52da4cb24ccd3b67e65b7c8e6..3d3cfb3a2a6dce1e6b4714be2c023e26208d5fcf 100644
--- a/src/plugins/qmldesigner/core/model/texttomodelmerger.cpp
+++ b/src/plugins/qmldesigner/core/model/texttomodelmerger.cpp
@@ -34,17 +34,151 @@
 #include "nodemetainfo.h"
 #include "nodeproperty.h"
 #include "propertymetainfo.h"
+#include "basetexteditmodifier.h"
 #include "texttomodelmerger.h"
 #include "rewriterview.h"
 #include "variantproperty.h"
+#include <qmljseditor/qmljseditor.h>
+#include <qmljs/qmljsinterpreter.h>
+#include <qmljs/parser/qmljsast_p.h>
 
 #include <QDeclarativeEngine>
 #include <QSet>
 #include <private/qdeclarativedom_p.h>
 
+using namespace QmlJS;
+using namespace QmlJS::AST;
+
+namespace QmlDesigner {
+namespace Internal {
+
+struct ReadingContext {
+    ReadingContext(const Snapshot &snapshot, const Document::Ptr &doc)
+        : snapshot(snapshot)
+        , doc(doc)
+        , engine(new Interpreter::Engine)
+        , ctxt(new Interpreter::Context(engine))
+    {
+        ctxt->build(QList<Node *>(), doc, snapshot);
+    }
+
+    ~ReadingContext()
+    { delete ctxt; delete engine; }
+
+    void lookup(UiQualifiedId *astTypeNode, QString &typeName, int &majorVersion, int &minorVersion)
+    {
+        const Interpreter::ObjectValue *value = ctxt->lookupType(doc.data(), astTypeNode);
+        if (const Interpreter::QmlObjectValue * qmlValue = dynamic_cast<const Interpreter::QmlObjectValue *>(value)) {
+            typeName = qmlValue->packageName() + QLatin1String("/") + qmlValue->className();
+            majorVersion = qmlValue->majorVersion();
+            minorVersion = qmlValue->minorVersion();
+        }
+    }
+
+    Snapshot snapshot;
+    Document::Ptr doc;
+    Interpreter::Engine *engine;
+    Interpreter::Context *ctxt;
+};
+
+} // namespace Internal
+} // namespace QmlDesigner
+
 using namespace QmlDesigner;
 using namespace QmlDesigner::Internal;
 
+namespace {
+
+static inline QString stripQuotes(const QString &str)
+{
+    if ((str.startsWith(QLatin1Char('"')) && str.endsWith(QLatin1Char('"')))
+            || (str.startsWith(QLatin1Char('\'')) && str.endsWith(QLatin1Char('\''))))
+        return str.mid(1, str.length() - 2);
+
+    return str;
+}
+
+static inline bool isSignalPropertyName(const QString &signalName)
+{
+    // see QmlCompiler::isSignalPropertyName
+    return signalName.length() >= 3 && signalName.startsWith(QLatin1String("on")) &&
+           signalName.at(2).isLetter();
+}
+
+static QString flatten(UiQualifiedId *qualifiedId)
+{
+    QString result;
+
+    for (UiQualifiedId *iter = qualifiedId; iter; iter = iter->next) {
+        if (!iter->name)
+            continue;
+
+        if (!result.isEmpty())
+            result.append(QLatin1Char('.'));
+
+        result.append(iter->name->asString());
+    }
+
+    return result;
+}
+
+static bool isLiteralValue(ExpressionNode *expr)
+{
+    if (cast<NumericLiteral*>(expr))
+        return true;
+    else if (cast<StringLiteral*>(expr))
+        return true;
+    else if (UnaryPlusExpression *plusExpr = cast<UnaryPlusExpression*>(expr))
+        return isLiteralValue(plusExpr->expression);
+    else if (UnaryMinusExpression *minusExpr = cast<UnaryMinusExpression*>(expr))
+        return isLiteralValue(minusExpr->expression);
+    else if (cast<TrueLiteral*>(expr))
+        return true;
+    else if (cast<FalseLiteral*>(expr))
+        return true;
+    else
+        return false;
+}
+
+static inline bool isLiteralValue(UiScriptBinding *script)
+{
+    if (!script || !script->statement)
+        return false;
+
+    return isLiteralValue((cast<ExpressionStatement *>(script->statement))->expression);
+}
+
+static inline bool isValidPropertyForNode(const ModelNode &modelNode,
+                                          const QString &propertyName)
+{
+    return modelNode.metaInfo().hasProperty(propertyName, true)
+            || modelNode.type() == QLatin1String("Qt/PropertyChanges");
+}
+
+static inline int propertyType(const QString &typeName)
+{
+    if (typeName == QLatin1String("bool"))
+        return QMetaType::type("bool");
+    else if (typeName == QLatin1String("color"))
+        return QMetaType::type("QColor");
+    else if (typeName == QLatin1String("date"))
+        return QMetaType::type("QDate");
+    else if (typeName == QLatin1String("int"))
+        return QMetaType::type("int");
+    else if (typeName == QLatin1String("real"))
+        return QMetaType::type("double");
+    else if (typeName == QLatin1String("string"))
+        return QMetaType::type("QString");
+    else if (typeName == QLatin1String("url"))
+        return QMetaType::type("QUrl");
+    else if (typeName == QLatin1String("var") || typeName == QLatin1String("variant"))
+        return QMetaType::type("QVariant");
+    else
+        return -1;
+}
+
+} // anonymous namespace
+
 static inline bool equals(const QVariant &a, const QVariant &b)
 {
     if (a.type() == QVariant::Double && b.type() == QVariant::Double)
@@ -70,26 +204,36 @@ bool TextToModelMerger::isActive() const
     return m_isActive;
 }
 
-void TextToModelMerger::setupImports(QDeclarativeDomDocument &doc,
+void TextToModelMerger::setupImports(const Document::Ptr &doc,
                                      DifferenceHandler &differenceHandler)
 {
     QSet<Import> existingImports = m_rewriterView->model()->imports();
 
-    foreach (const QDeclarativeDomImport &qmlImport, doc.imports()) {
-        if (qmlImport.type() == QDeclarativeDomImport::Library) {
-            Import import(Import::createLibraryImport(qmlImport.uri(),
-                                                      qmlImport.version(),
-                                                      qmlImport.qualifier()));
-
-            if (!existingImports.remove(import))
-                differenceHandler.modelMissesImport(import);
-        } else if (qmlImport.type() == QDeclarativeDomImport::File) {
-            Import import(Import:: createFileImport(qmlImport.uri(),
-                                                    qmlImport.version(),
-                                                    qmlImport.qualifier()));
-
-            if (!existingImports.remove(import))
-                differenceHandler.modelMissesImport(import);
+    for (UiImportList *iter = doc->qmlProgram()->imports; iter; iter = iter->next) {
+        UiImport *import = iter->import;
+        if (!import)
+            continue;
+
+        QString version;
+        if (import->versionToken.isValid())
+            version = textAt(doc, import->versionToken);
+        QString as;
+        if (import->importId)
+            as = import->importId->asString();
+
+        if (import->fileName) {
+            const QString strippedFileName = stripQuotes(import->fileName->asString());
+            Import newImport(Import::createFileImport(strippedFileName,
+                                                      version, as));
+
+            if (!existingImports.remove(newImport))
+                differenceHandler.modelMissesImport(newImport);
+        } else {
+            Import newImport(Import::createLibraryImport(flatten(import->importUri),
+                                                         as, version));
+
+            if (!existingImports.remove(newImport))
+                differenceHandler.modelMissesImport(newImport);
         }
     }
 
@@ -99,25 +243,37 @@ void TextToModelMerger::setupImports(QDeclarativeDomDocument &doc,
 
 bool TextToModelMerger::load(const QByteArray &data, DifferenceHandler &differenceHandler)
 {
+    qDebug() << "**** Starting to load the file...";
     setActive(true);
 
     try {
         QDeclarativeEngine engine;
-        QDeclarativeDomDocument doc;
+        QDeclarativeDomDocument domDoc;
         const QUrl url = m_rewriterView->model()->fileUrl();
-        const bool success = doc.load(&engine, data, url);
+        const bool success = domDoc.load(&engine, data, url);
 
         if (success) {
+            Snapshot snapshot = BaseTextEditModifier::getSnapshot();
+            const QString fileName = url.toLocalFile();
+            Document::Ptr doc = Document::create(fileName);
+            doc->setSource(QString::fromUtf8(data.constData()));
+            doc->parseQml();
+            snapshot.insert(doc);
+            ReadingContext ctxt(snapshot, doc);
+
             setupImports(doc, differenceHandler);
 
-            const QDeclarativeDomObject rootDomObject = doc.rootObject();
+            UiObjectMember *astRootNode = 0;
+            if (UiProgram *program = doc->qmlProgram())
+                if (program->members)
+                    astRootNode = program->members->member;
             ModelNode modelRootNode = m_rewriterView->rootModelNode();
-            syncNode(modelRootNode, rootDomObject, differenceHandler);
+            syncNode(modelRootNode, astRootNode, &ctxt, differenceHandler);
             m_rewriterView->positionStorage()->cleanupInvalidOffsets();
             m_rewriterView->clearErrors();
         } else {
             QList<RewriterView::Error> errors;
-            foreach (const QDeclarativeError &qmlError, doc.errors())
+            foreach (const QDeclarativeError &qmlError, domDoc.errors())
                 errors.append(RewriterView::Error(qmlError));
             m_rewriterView->setErrors(errors);
         }
@@ -139,207 +295,289 @@ bool TextToModelMerger::load(const QByteArray &data, DifferenceHandler &differen
 }
 
 void TextToModelMerger::syncNode(ModelNode &modelNode,
-                                 const QDeclarativeDomObject &domObject,
+                                 UiObjectMember *astNode,
+                                 ReadingContext *context,
                                  DifferenceHandler &differenceHandler)
 {
-    m_rewriterView->positionStorage()->setNodeOffset(modelNode, domObject.position());
+    UiQualifiedId *astObjectType = 0;
+    UiObjectInitializer *astInitializer = 0;
+    if (UiObjectDefinition *def = cast<UiObjectDefinition *>(astNode)) {
+        astObjectType = def->qualifiedTypeNameId;
+        astInitializer = def->initializer;
+    } else if (UiObjectBinding *bin = cast<UiObjectBinding *>(astNode)) {
+        astObjectType = bin->qualifiedTypeNameId;
+        astInitializer = bin->initializer;
+    }
+
+    if (!astObjectType || !astInitializer)
+        return;
+
+    m_rewriterView->positionStorage()->setNodeOffset(modelNode, astNode->firstSourceLocation().offset);
+
+    QString typeName;
+    int majorVersion;
+    int minorVersion;
+    context->lookup(astObjectType, typeName, majorVersion, minorVersion);
+
+    if (typeName.isEmpty()) {
+        qWarning() << "Skipping node with unknown type" << flatten(astObjectType);
+        return;
+    }
 
-    if (modelNode.type() != domObject.objectType()
-            || modelNode.majorVersion() != domObject.objectTypeMajorVersion()
-            || modelNode.minorVersion() != domObject.objectTypeMinorVersion()) {
+    if (modelNode.type() != typeName
+            /*|| modelNode.majorVersion() != domObject.objectTypeMajorVersion()
+            || modelNode.minorVersion() != domObject.objectTypeMinorVersion()*/) {
         const bool isRootNode = m_rewriterView->rootModelNode() == modelNode;
-        differenceHandler.typeDiffers(isRootNode, modelNode, domObject);
+        differenceHandler.typeDiffers(isRootNode, modelNode, typeName,
+                                      majorVersion, minorVersion,
+                                      astNode, context);
         if (!isRootNode)
             return; // the difference handler will create a new node, so we're done.
     }
 
-    {
-        QString domObjectId = domObject.objectId();
-        const QDeclarativeDomProperty domIdProperty = domObject.property("id");
-        if (domObjectId.isEmpty() && domIdProperty.value().isLiteral())
-            domObjectId = domIdProperty.value().toLiteral().literal();
-
-        if (domObjectId.isEmpty()) {
-            if (!modelNode.id().isEmpty()) {
-                ModelNode existingNodeWithId = m_rewriterView->modelNodeForId(domObjectId);
-                if (existingNodeWithId.isValid())
-                    existingNodeWithId.setId(QString());
-                differenceHandler.idsDiffer(modelNode, domObjectId);
-            }
-        } else {
-            if (modelNode.id() != domObjectId) {
-                ModelNode existingNodeWithId = m_rewriterView->modelNodeForId(domObjectId);
-                if (existingNodeWithId.isValid())
-                    existingNodeWithId.setId(QString());
-                differenceHandler.idsDiffer(modelNode, domObjectId);
-            }
-        }
-    }
-
     QSet<QString> modelPropertyNames = QSet<QString>::fromList(modelNode.propertyNames());
+    QList<UiObjectMember *> defaultPropertyItems;
 
-    foreach (const QDeclarativeDomProperty &domProperty, domObject.properties()) {
-        const QString domPropertyName = domProperty.propertyName();
-
-        if (isSignalPropertyName(domPropertyName.toUtf8()))
+    for (UiObjectMemberList *iter = astInitializer->members; iter; iter = iter->next) {
+        UiObjectMember *member = iter->member;
+        if (!member)
             continue;
 
-        if (domPropertyName == QLatin1String("id")) {
-            // already done before
-            continue;
-        } else if (domPropertyName.isEmpty()) {
-            qWarning() << "QML DOM returned an empty property name";
-            continue;
-        } else if (domPropertyName.at(0).isUpper() && domPropertyName.contains('.')) {
-            // An attached property, which we currently don't handle.
-            // So, skipping it.
-            modelPropertyNames.remove(domPropertyName);
-            continue;
-        } else {
-            const QDeclarativeDomDynamicProperty dynamicProperty = domObject.dynamicProperty(domProperty.propertyName());
-            if (dynamicProperty.isValid() || modelNode.metaInfo().hasProperty(domPropertyName, true) || modelNode.type() == QLatin1String("Qt/PropertyChanges")) {
-                AbstractProperty modelProperty = modelNode.property(domPropertyName);
-                syncProperty(modelProperty, domProperty, dynamicProperty, differenceHandler);
-                modelPropertyNames.remove(domPropertyName);
+        if (UiArrayBinding *array = cast<UiArrayBinding *>(member)) {
+            const QString astPropertyName = flatten(array->qualifiedId);
+            if (isValidPropertyForNode(modelNode, astPropertyName)) {
+                AbstractProperty modelProperty = modelNode.property(astPropertyName);
+                syncArrayProperty(modelProperty, array, context, differenceHandler);
+                modelPropertyNames.remove(astPropertyName);
+            } else {
+                qWarning() << "Skipping invalid array property" << astPropertyName
+                           << "for node type" << modelNode.type();
+            }
+        } else if (cast<UiObjectDefinition *>(member)) {
+            defaultPropertyItems.append(member);
+        } else if (UiObjectBinding *binding = cast<UiObjectBinding *>(member)) {
+            const QString astPropertyName = flatten(binding->qualifiedId);
+            if (binding->hasOnToken) {
+                // skip value sources
+            } else {
+                if (isValidPropertyForNode(modelNode, astPropertyName)) {
+                    AbstractProperty modelProperty = modelNode.property(astPropertyName);
+                    syncNodeProperty(modelProperty, binding, context, differenceHandler);
+                    modelPropertyNames.remove(astPropertyName);
+                } else {
+                    qWarning() << "Skipping invalid node property" << astPropertyName
+                               << "for node type" << modelNode.type();
+                }
+            }
+        } else if (UiScriptBinding *script = cast<UiScriptBinding *>(member)) {
+            const QString astPropertyName = flatten(script->qualifiedId);
+            QString astValue;
+            if (script->statement)
+                astValue = textAt(context->doc,
+                                  script->statement->firstSourceLocation(),
+                                  script->statement->lastSourceLocation());
+
+            if (astPropertyName == QLatin1String("id")) {
+                syncNodeId(modelNode, astValue, differenceHandler);
+            } else if (isSignalPropertyName(astPropertyName)) {
+                // skip signals
+            } else if (isLiteralValue(script)) {
+                if (isValidPropertyForNode(modelNode, astPropertyName)) {
+                    AbstractProperty modelProperty = modelNode.property(astPropertyName);
+                    syncVariantProperty(modelProperty, astPropertyName, astValue, QString(), differenceHandler);
+                    modelPropertyNames.remove(astPropertyName);
+                } else {
+                    qWarning() << "Skipping invalid variant property" << astPropertyName
+                               << "for node type" << modelNode.type();
+                }
+            } else {
+                if (isValidPropertyForNode(modelNode, astPropertyName)) {
+                    AbstractProperty modelProperty = modelNode.property(astPropertyName);
+                    syncExpressionProperty(modelProperty, astValue, differenceHandler);
+                    modelPropertyNames.remove(astPropertyName);
+                } else {
+                    qWarning() << "Skipping invalid expression property" << astPropertyName
+                               << "for node type" << modelNode.type();
+                }
             }
+        } else if (UiPublicMember *property = cast<UiPublicMember *>(member)) {
+            const QString astName = property->name->asString();
+            QString astValue;
+            if (property->expression)
+                astValue = textAt(context->doc,
+                                  property->expression->firstSourceLocation(),
+                                  property->expression->lastSourceLocation());
+            const QString astType = property->memberType->asString();
+            AbstractProperty modelProperty = modelNode.property(astName);
+            if (!property->expression || isLiteralValue(property->expression))
+                syncVariantProperty(modelProperty, astName, astValue, astType, differenceHandler);
+            else
+                syncExpressionProperty(modelProperty, astValue, differenceHandler);
+            modelPropertyNames.remove(astName);
+        } else {
+            qWarning() << "Found an unknown QML value of type"
+                       << typeid(*member).name();
         }
     }
 
-    { // for new dynamic properties which have no property definitions:
-        foreach (const QDeclarativeDomDynamicProperty &dynamicDomProperty, domObject.dynamicProperties()) {
-            const QByteArray propertyName = dynamicDomProperty.propertyName();
-            if (domObject.property(propertyName).isValid())
-                continue;
-
-            if (dynamicDomProperty.isAlias())
-                continue; // we don't handle alias properties yet.
-
-            AbstractProperty modelProperty = modelNode.property(propertyName);
-            const QString dynamicTypeName = QMetaType::typeName(dynamicDomProperty.propertyType());
-
-            // a dynamic property definition without a value
-            if (modelProperty.isValid() && modelProperty.isVariantProperty()) {
-                VariantProperty modelVariantProperty = modelProperty.toVariantProperty();
-                if (modelVariantProperty.value() != QVariant())
-                    differenceHandler.variantValuesDiffer(modelVariantProperty, QVariant(), dynamicTypeName);
+    if (!defaultPropertyItems.isEmpty()) {
+        QString defaultPropertyName = modelNode.metaInfo().defaultProperty();
+        if (defaultPropertyName.isEmpty()) {
+            qWarning() << "No default property for node type" << modelNode.type() << ", ignoring child items.";
+        } else {
+            AbstractProperty modelProperty = modelNode.property(defaultPropertyName);
+            if (modelProperty.isNodeListProperty()) {
+                NodeListProperty nodeListProperty = modelProperty.toNodeListProperty();
+                syncNodeListProperty(nodeListProperty, defaultPropertyItems, context,
+                                     differenceHandler);
             } else {
-                differenceHandler.shouldBeVariantProperty(modelProperty, QVariant(), dynamicTypeName);
+                differenceHandler.shouldBeNodeListProperty(modelProperty,
+                                                           defaultPropertyItems,
+                                                           context);
             }
+            modelPropertyNames.remove(defaultPropertyName);
         }
     }
 
     foreach (const QString &modelPropertyName, modelPropertyNames) {
         AbstractProperty modelProperty = modelNode.property(modelPropertyName);
-        const QDeclarativeDomDynamicProperty dynamicDomProperty = domObject.dynamicProperty(modelPropertyName.toUtf8());
 
-        if (dynamicDomProperty.isValid()) {
-            const QString dynamicTypeName = QMetaType::typeName(dynamicDomProperty.propertyType());
+        // property deleted.
+        differenceHandler.propertyAbsentFromQml(modelProperty);
+    }
+}
 
-            // a dynamic property definition without a value
-            if (modelProperty.isValid() && modelProperty.isVariantProperty()) {
-                VariantProperty modelVariantProperty = modelProperty.toVariantProperty();
-                if (modelVariantProperty.value() != QVariant())
-                    differenceHandler.variantValuesDiffer(modelVariantProperty, QVariant(), dynamicTypeName);
-            } else {
-                differenceHandler.shouldBeVariantProperty(modelProperty, QVariant(), dynamicTypeName);
-            }
-        } else {
-            // property deleted.
-            differenceHandler.propertyAbsentFromQml(modelProperty);
+void TextToModelMerger::syncNodeId(ModelNode &modelNode, const QString &astObjectId,
+                                   DifferenceHandler &differenceHandler)
+{
+    if (astObjectId.isEmpty()) {
+        if (!modelNode.id().isEmpty()) {
+            ModelNode existingNodeWithId = m_rewriterView->modelNodeForId(astObjectId);
+            if (existingNodeWithId.isValid())
+                existingNodeWithId.setId(QString());
+            differenceHandler.idsDiffer(modelNode, astObjectId);
+        }
+    } else {
+        if (modelNode.id() != astObjectId) {
+            ModelNode existingNodeWithId = m_rewriterView->modelNodeForId(astObjectId);
+            if (existingNodeWithId.isValid())
+                existingNodeWithId.setId(QString());
+            differenceHandler.idsDiffer(modelNode, astObjectId);
         }
     }
 }
 
-void TextToModelMerger::syncProperty(AbstractProperty &modelProperty,
-                                     const QDeclarativeDomProperty &qmlProperty,
-                                     const QDeclarativeDomDynamicProperty &qmlDynamicProperty,
-                                     DifferenceHandler &differenceHandler)
+void TextToModelMerger::syncNodeProperty(AbstractProperty &modelProperty,
+                                         UiObjectBinding *binding,
+                                         ReadingContext *context,
+                                         DifferenceHandler &differenceHandler)
 {
-    Q_ASSERT(modelProperty.name() == qmlProperty.propertyName());
+    QString typeName;
+    int majorVersion;
+    int minorVersion;
+    context->lookup(binding->qualifiedTypeNameId, typeName, majorVersion, minorVersion);
 
-    const QDeclarativeDomValue qmlValue = qmlProperty.value();
+    if (typeName.isEmpty()) {
+        qWarning() << "Skipping node with unknown type" << flatten(binding->qualifiedTypeNameId);
+        return;
+    }
 
-    if (qmlValue.isBinding()) {
-        const QString QDeclarativeBinding = qmlValue.toBinding().binding();
-        if (modelProperty.isBindingProperty()) {
-            BindingProperty bindingProperty = modelProperty.toBindingProperty();
-            if (bindingProperty.expression() != QDeclarativeBinding) {
-                differenceHandler.bindingExpressionsDiffer(bindingProperty, QDeclarativeBinding);
-            }
-        } else {
-            differenceHandler.shouldBeBindingProperty(modelProperty, QDeclarativeBinding);
-        }
-    } else if (qmlValue.isList()) {
-        if (modelProperty.isNodeListProperty()) {
-            NodeListProperty nodeListProperty = modelProperty.toNodeListProperty();
-            syncNodeListProperty(nodeListProperty, qmlValue.toList(), differenceHandler);
-        } else {
-            differenceHandler.shouldBeNodeListProperty(modelProperty, qmlValue.toList());
-        }
-    } else if (qmlValue.isLiteral()) {
-        const QVariant qmlVariantValue = convertToVariant(modelProperty.parentModelNode(), qmlProperty, qmlDynamicProperty);
-        QString dynamicTypeName;
-        if (qmlDynamicProperty.isValid())
-            dynamicTypeName = QMetaType::typeName(qmlDynamicProperty.propertyType());
-
-        if (modelProperty.isVariantProperty()) {
-            VariantProperty modelVariantProperty = modelProperty.toVariantProperty();
-
-            if (!equals(modelVariantProperty.value(), qmlVariantValue)
-                    || qmlDynamicProperty.isValid() != modelVariantProperty.isDynamic()
-                    || dynamicTypeName != modelVariantProperty.dynamicTypeName()) {
-                differenceHandler.variantValuesDiffer(modelVariantProperty, qmlVariantValue, dynamicTypeName);
-            }
-        } else {
-            differenceHandler.shouldBeVariantProperty(modelProperty, qmlVariantValue, dynamicTypeName);
-        }
-    } else if (qmlValue.isObject()) {
-        if (modelProperty.isNodeProperty()) {
-            ModelNode nodePropertyNode = modelProperty.toNodeProperty().modelNode();
-            syncNode(nodePropertyNode, qmlValue.toObject(), differenceHandler);
-        } else {
-            differenceHandler.shouldBeNodeProperty(modelProperty, qmlValue.toObject());
+    if (modelProperty.isNodeProperty()) {
+        ModelNode nodePropertyNode = modelProperty.toNodeProperty().modelNode();
+        syncNode(nodePropertyNode, binding, context, differenceHandler);
+    } else {
+        differenceHandler.shouldBeNodeProperty(modelProperty,
+                                               typeName,
+                                               majorVersion,
+                                               minorVersion,
+                                               binding, context);
+    }
+}
+
+void TextToModelMerger::syncExpressionProperty(AbstractProperty &modelProperty,
+                                               const QString &javascript,
+                                               DifferenceHandler &differenceHandler)
+{
+    if (modelProperty.isBindingProperty()) {
+        BindingProperty bindingProperty = modelProperty.toBindingProperty();
+        if (bindingProperty.expression() != javascript) {
+            differenceHandler.bindingExpressionsDiffer(bindingProperty, javascript);
         }
-    } else if (qmlValue.isValueSource()) {
-        if (modelProperty.isNodeProperty()) {
-            ModelNode nodePropertyNode = modelProperty.toNodeProperty().modelNode();
-            syncNode(nodePropertyNode, qmlValue.toValueSource().object(), differenceHandler);
-        } else {
-            differenceHandler.shouldBeNodeProperty(modelProperty, qmlValue.toValueSource().object());
+    } else {
+        differenceHandler.shouldBeBindingProperty(modelProperty, javascript);
+    }
+}
+
+void TextToModelMerger::syncArrayProperty(AbstractProperty &modelProperty,
+                                          UiArrayBinding *array,
+                                          ReadingContext *context,
+                                          DifferenceHandler &differenceHandler)
+{
+    QList<UiObjectMember *> arrayMembers;
+    for (UiArrayMemberList *iter = array->members; iter; iter = iter->next)
+        if (UiObjectMember *member = iter->member)
+            arrayMembers.append(member);
+
+    if (modelProperty.isNodeListProperty()) {
+        NodeListProperty nodeListProperty = modelProperty.toNodeListProperty();
+        syncNodeListProperty(nodeListProperty, arrayMembers, context, differenceHandler);
+    } else {
+        differenceHandler.shouldBeNodeListProperty(modelProperty,
+                                                   arrayMembers,
+                                                   context);
+    }
+}
+
+void TextToModelMerger::syncVariantProperty(AbstractProperty &modelProperty,
+                                            const QString &astName,
+                                            const QString &astValue,
+                                            const QString &astType,
+                                            DifferenceHandler &differenceHandler)
+{
+    const QVariant astVariantValue = convertToVariant(modelProperty.parentModelNode(),
+                                                      astName,
+                                                      astValue,
+                                                      astType);
+
+    if (modelProperty.isVariantProperty()) {
+        VariantProperty modelVariantProperty = modelProperty.toVariantProperty();
+
+        if (!equals(modelVariantProperty.value(), astVariantValue)
+                || !astType.isEmpty() != modelVariantProperty.isDynamic()
+                || astType != modelVariantProperty.dynamicTypeName()) {
+            differenceHandler.variantValuesDiffer(modelVariantProperty,
+                                                  astVariantValue,
+                                                  astType);
         }
-    } else if (qmlValue.isInvalid()) {
-        // skip these nodes
     } else {
-        qWarning() << "Found an unknown qml value!";
+        differenceHandler.shouldBeVariantProperty(modelProperty,
+                                                  astVariantValue,
+                                                  astType);
     }
 }
 
-void TextToModelMerger::syncNodeListProperty(NodeListProperty &modelListProperty, const QDeclarativeDomList &domList, DifferenceHandler &differenceHandler)
+void TextToModelMerger::syncNodeListProperty(NodeListProperty &modelListProperty,
+                                             const QList<UiObjectMember *> arrayMembers,
+                                             ReadingContext *context,
+                                             DifferenceHandler &differenceHandler)
 {
     QList<ModelNode> modelNodes = modelListProperty.toModelNodeList();
-    QList<QDeclarativeDomValue> domValues = domList.values();
     int i = 0;
-    for (; i < modelNodes.size() && i < domValues.size(); ++i) {
-        QDeclarativeDomValue value = domValues.at(i);
-        if (value.isObject()) {
-            ModelNode modelNode = modelNodes.at(i);
-            syncNode(modelNode, value.toObject(), differenceHandler);
-        } else {
-            qDebug() << "*** Oops, we got a non-object item in the list!";
-        }
+    for (; i < modelNodes.size() && i < arrayMembers.size(); ++i) {
+        ModelNode modelNode = modelNodes.at(i);
+        syncNode(modelNode, arrayMembers.at(i), context, differenceHandler);
     }
 
-    for (int j = i; j < domValues.size(); ++j) {
+    for (int j = i; j < arrayMembers.size(); ++j) {
         // more elements in the dom-list, so add them to the model
-        QDeclarativeDomValue value = domValues.at(j);
-        if (value.isObject()) {
-            const QDeclarativeDomObject qmlObject = value.toObject();
-            const ModelNode newNode = differenceHandler.listPropertyMissingModelNode(modelListProperty, qmlObject);
-            if (QString::fromUtf8(qmlObject.objectType()) == QLatin1String("Qt/Component"))
-                setupComponent(newNode);
-        } else {
-            qDebug() << "*** Oops, we got a non-object item in the list!";
-        }
+        UiObjectMember *arrayMember = arrayMembers.at(j);
+        const ModelNode newNode = differenceHandler.listPropertyMissingModelNode(modelListProperty, context, arrayMember);
+        QString name;
+        if (UiObjectDefinition *definition = cast<UiObjectDefinition *>(arrayMember))
+            name = flatten(definition->qualifiedTypeNameId);
+        // TODO: resolve name here!
+        if (name == QLatin1String("Qt/Component"))
+            setupComponent(newNode);
     }
 
     for (int j = i; j < modelNodes.size(); ++j) {
@@ -349,20 +587,31 @@ void TextToModelMerger::syncNodeListProperty(NodeListProperty &modelListProperty
     }
 }
 
-ModelNode TextToModelMerger::createModelNode(const QDeclarativeDomObject &domObject, DifferenceHandler &differenceHandler)
+ModelNode TextToModelMerger::createModelNode(const QString &typeName,
+                                             int majorVersion,
+                                             int minorVersion,
+                                             UiObjectMember *astNode,
+                                             ReadingContext *context,
+                                             DifferenceHandler &differenceHandler)
 {
-    ModelNode newNode = m_rewriterView->createModelNode(domObject.objectType(), domObject.objectTypeMajorVersion(), domObject.objectTypeMinorVersion());
-    syncNode(newNode, domObject, differenceHandler);
+    qDebug() << "Creating model node for" << typeName << majorVersion << minorVersion;
+    ModelNode newNode = m_rewriterView->createModelNode(typeName,
+                                                        majorVersion,
+                                                        minorVersion);
+    syncNode(newNode, astNode, context, differenceHandler);
     return newNode;
 }
 
-QVariant TextToModelMerger::convertToVariant(const ModelNode &node, const QDeclarativeDomProperty &qmlProperty, const QDeclarativeDomDynamicProperty &qmlDynamicProperty)
+QVariant TextToModelMerger::convertToVariant(const ModelNode &node,
+                                             const QString &astName,
+                                             const QString &astValue,
+                                             const QString &astType)
 {
-    QString stringValue = qmlProperty.value().toLiteral().literal();
+    const QString cleanedValue = stripQuotes(astValue.trimmed());
 
-    if (qmlDynamicProperty.isValid()) {
-        const int type = qmlDynamicProperty.propertyType();
-        QVariant value(stringValue);
+    if (!astType.isEmpty()) {
+        const int type = propertyType(astType);
+        QVariant value(cleanedValue);
         value.convert(static_cast<QVariant::Type>(type));
         return value;
     }
@@ -370,23 +619,30 @@ QVariant TextToModelMerger::convertToVariant(const ModelNode &node, const QDecla
     const NodeMetaInfo nodeMetaInfo = node.metaInfo();
 
     if (nodeMetaInfo.isValid()) {
-        const PropertyMetaInfo propertyMetaInfo = nodeMetaInfo.property(qmlProperty.propertyName(), true);
+        const PropertyMetaInfo propertyMetaInfo = nodeMetaInfo.property(astName, true);
 
         if (propertyMetaInfo.isValid()) {
-            QVariant castedValue = propertyMetaInfo.castedValue(stringValue);
+            QVariant castedValue = propertyMetaInfo.castedValue(cleanedValue);
             if (!castedValue.isValid())
-                qWarning() << "Casting the value" << stringValue << "of property" << propertyMetaInfo.name() << "to the property type" << propertyMetaInfo.type() << "failed";
+                qWarning() << "Casting the value" << cleanedValue
+                           << "of property" << astName
+                           << "to the property type" << propertyMetaInfo.type()
+                           << "failed";
             return castedValue;
         } else if (node.type() == QLatin1String("Qt/PropertyChanges")) {
             // In the future, we should do the type resolving in a second pass, or delay setting properties until the full file has been parsed.
-            return QVariant(stringValue);
+            return QVariant(cleanedValue);
         } else {
-            qWarning() << "Unknown property" << qmlProperty.propertyName() << "in node" << node.type() << "with value" << stringValue;
+            qWarning() << "Unknown property" << astName
+                       << "in node" << node.type()
+                       << "with value" << cleanedValue;
             return QVariant();
         }
     } else {
-        qWarning() << "Unknown property" << qmlProperty.propertyName() << "in node" << node.type() << "with value" << stringValue;
-        return QVariant::fromValue(stringValue);
+        qWarning() << "Unknown property" << astName
+                   << "in node" << node.type()
+                   << "with value" << cleanedValue;
+        return QVariant::fromValue(cleanedValue);
     }
 }
 
@@ -400,19 +656,23 @@ void ModelValidator::importAbsentInQMl(const Import &import)
     Q_ASSERT(! m_merger->view()->model()->imports().contains(import));
 }
 
-void ModelValidator::bindingExpressionsDiffer(BindingProperty &modelProperty, const QString &QDeclarativeBinding)
+void ModelValidator::bindingExpressionsDiffer(BindingProperty &modelProperty,
+                                              const QString &javascript)
 {
-    Q_ASSERT(modelProperty.expression() == QDeclarativeBinding);
+    Q_ASSERT(modelProperty.expression() == javascript);
     Q_ASSERT(0);
 }
 
-void ModelValidator::shouldBeBindingProperty(AbstractProperty &modelProperty, const QString &/*QDeclarativeBinding*/)
+void ModelValidator::shouldBeBindingProperty(AbstractProperty &modelProperty,
+                                             const QString &/*javascript*/)
 {
     Q_ASSERT(modelProperty.isBindingProperty());
     Q_ASSERT(0);
 }
 
-void ModelValidator::shouldBeNodeListProperty(AbstractProperty &modelProperty, const QDeclarativeDomList &/*domList*/)
+void ModelValidator::shouldBeNodeListProperty(AbstractProperty &modelProperty,
+                                              const QList<UiObjectMember *> /*arrayMembers*/,
+                                              ReadingContext * /*context*/)
 {
     Q_ASSERT(modelProperty.isNodeListProperty());
     Q_ASSERT(0);
@@ -435,7 +695,12 @@ void ModelValidator::shouldBeVariantProperty(AbstractProperty &modelProperty, co
     Q_ASSERT(0);
 }
 
-void ModelValidator::shouldBeNodeProperty(AbstractProperty &modelProperty, const QDeclarativeDomObject &/*qmlObject*/)
+void ModelValidator::shouldBeNodeProperty(AbstractProperty &modelProperty,
+                                          const QString &/*typeName*/,
+                                          int /*majorVersion*/,
+                                          int /*minorVersion*/,
+                                          UiObjectMember * /*astNode*/,
+                                          ReadingContext * /*context*/)
 {
     Q_ASSERT(modelProperty.isNodeProperty());
     Q_ASSERT(0);
@@ -447,17 +712,25 @@ void ModelValidator::modelNodeAbsentFromQml(ModelNode &modelNode)
     Q_ASSERT(0);
 }
 
-ModelNode ModelValidator::listPropertyMissingModelNode(NodeListProperty &/*modelProperty*/, const QDeclarativeDomObject &/*qmlObject*/)
+ModelNode ModelValidator::listPropertyMissingModelNode(NodeListProperty &/*modelProperty*/,
+                                                       ReadingContext * /*context*/,
+                                                       UiObjectMember * /*arrayMember*/)
 {
     Q_ASSERT(0);
     return ModelNode();
 }
 
-void ModelValidator::typeDiffers(bool /*isRootNode*/, ModelNode &modelNode, const QDeclarativeDomObject &domObject)
+void ModelValidator::typeDiffers(bool /*isRootNode*/,
+                                 ModelNode &modelNode,
+                                 const QString &typeName,
+                                 int majorVersion,
+                                 int minorVersion,
+                                 QmlJS::AST::UiObjectMember * /*astNode*/,
+                                 ReadingContext * /*context*/)
 {
-    Q_ASSERT(modelNode.type() == domObject.objectType());
-    Q_ASSERT(modelNode.majorVersion() == domObject.objectTypeMajorVersion());
-    Q_ASSERT(modelNode.minorVersion() == domObject.objectTypeMinorVersion());
+    Q_ASSERT(modelNode.type() == typeName);
+    Q_ASSERT(modelNode.majorVersion() == majorVersion);
+    Q_ASSERT(modelNode.minorVersion() == minorVersion);
     Q_ASSERT(0);
 }
 
@@ -483,23 +756,30 @@ void ModelAmender::importAbsentInQMl(const Import &import)
     m_merger->view()->model()->removeImport(import);
 }
 
-void ModelAmender::bindingExpressionsDiffer(BindingProperty &modelProperty, const QString &QDeclarativeBinding)
+void ModelAmender::bindingExpressionsDiffer(BindingProperty &modelProperty,
+                                            const QString &javascript)
 {
-    modelProperty.toBindingProperty().setExpression(QDeclarativeBinding);
+    modelProperty.toBindingProperty().setExpression(javascript);
 }
 
-void ModelAmender::shouldBeBindingProperty(AbstractProperty &modelProperty, const QString &QDeclarativeBinding)
+void ModelAmender::shouldBeBindingProperty(AbstractProperty &modelProperty,
+                                           const QString &javascript)
 {
     ModelNode theNode = modelProperty.parentModelNode();
     BindingProperty newModelProperty = theNode.bindingProperty(modelProperty.name());
-    newModelProperty.setExpression(QDeclarativeBinding);
+    newModelProperty.setExpression(javascript);
 }
 
-void ModelAmender::shouldBeNodeListProperty(AbstractProperty &modelProperty, const QDeclarativeDomList &domList)
+void ModelAmender::shouldBeNodeListProperty(AbstractProperty &modelProperty,
+                                            const QList<UiObjectMember *> arrayMembers,
+                                            ReadingContext *context)
 {
     ModelNode theNode = modelProperty.parentModelNode();
     NodeListProperty newNodeListProperty = theNode.nodeListProperty(modelProperty.name());
-    m_merger->syncNodeListProperty(newNodeListProperty, domList, *this);
+    m_merger->syncNodeListProperty(newNodeListProperty,
+                                   arrayMembers,
+                                   context,
+                                   *this);
 }
 
 void ModelAmender::variantValuesDiffer(VariantProperty &modelProperty, const QVariant &qmlVariantValue, const QString &dynamicType)
@@ -522,11 +802,21 @@ void ModelAmender::shouldBeVariantProperty(AbstractProperty &modelProperty, cons
         newModelProperty.setDynamicTypeNameAndValue(dynamicTypeName, qmlVariantValue);
 }
 
-void ModelAmender::shouldBeNodeProperty(AbstractProperty &modelProperty, const QDeclarativeDomObject &qmlObject)
+void ModelAmender::shouldBeNodeProperty(AbstractProperty &modelProperty,
+                                        const QString &typeName,
+                                        int majorVersion,
+                                        int minorVersion,
+                                        UiObjectMember *astNode,
+                                        ReadingContext *context)
 {
     ModelNode theNode = modelProperty.parentModelNode();
     NodeProperty newNodeProperty = theNode.nodeProperty(modelProperty.name());
-    newNodeProperty.setModelNode(m_merger->createModelNode(qmlObject, *this));
+    newNodeProperty.setModelNode(m_merger->createModelNode(typeName,
+                                                           majorVersion,
+                                                           minorVersion,
+                                                           astNode,
+                                                           context,
+                                                           *this));
 }
 
 void ModelAmender::modelNodeAbsentFromQml(ModelNode &modelNode)
@@ -534,17 +824,53 @@ void ModelAmender::modelNodeAbsentFromQml(ModelNode &modelNode)
     modelNode.destroy();
 }
 
-ModelNode ModelAmender::listPropertyMissingModelNode(NodeListProperty &modelProperty, const QDeclarativeDomObject &qmlObject)
+ModelNode ModelAmender::listPropertyMissingModelNode(NodeListProperty &modelProperty,
+                                                     ReadingContext *context,
+                                                     UiObjectMember *arrayMember)
 {
-    const ModelNode &newNode = m_merger->createModelNode(qmlObject, *this);
+    UiQualifiedId *astObjectType = 0;
+    UiObjectInitializer *astInitializer = 0;
+    if (UiObjectDefinition *def = cast<UiObjectDefinition *>(arrayMember)) {
+        astObjectType = def->qualifiedTypeNameId;
+        astInitializer = def->initializer;
+    } else if (UiObjectBinding *bin = cast<UiObjectBinding *>(arrayMember)) {
+        astObjectType = bin->qualifiedTypeNameId;
+        astInitializer = bin->initializer;
+    }
+
+    if (!astObjectType || !astInitializer)
+        return ModelNode();
+
+    QString typeName;
+    int majorVersion;
+    int minorVersion;
+    context->lookup(astObjectType, typeName, majorVersion, minorVersion);
+
+    if (typeName.isEmpty()) {
+        qWarning() << "Skipping node with unknown type" << flatten(astObjectType);
+        return ModelNode();
+    }
+
+    const ModelNode &newNode = m_merger->createModelNode(typeName,
+                                                         majorVersion,
+                                                         minorVersion,
+                                                         arrayMember,
+                                                         context,
+                                                         *this);
     modelProperty.reparentHere(newNode);
     return newNode;
 }
 
-void ModelAmender::typeDiffers(bool isRootNode, ModelNode &modelNode, const QDeclarativeDomObject &domObject)
+void ModelAmender::typeDiffers(bool isRootNode,
+                               ModelNode &modelNode,
+                               const QString &typeName,
+                               int majorVersion,
+                               int minorVersion,
+                               QmlJS::AST::UiObjectMember *astNode,
+                               ReadingContext *context)
 {
     if (isRootNode) {
-        modelNode.view()->changeRootNodeType(domObject.objectType(), domObject.objectTypeMajorVersion(), domObject.objectTypeMinorVersion());
+        modelNode.view()->changeRootNodeType(typeName, majorVersion, minorVersion);
     } else {
         NodeAbstractProperty parentProperty = modelNode.parentProperty();
         int nodeIndex = -1;
@@ -555,7 +881,12 @@ void ModelAmender::typeDiffers(bool isRootNode, ModelNode &modelNode, const QDec
 
         modelNode.destroy();
 
-        const ModelNode &newNode = m_merger->createModelNode(domObject, *this);
+        const ModelNode &newNode = m_merger->createModelNode(typeName,
+                                                             majorVersion,
+                                                             minorVersion,
+                                                             astNode,
+                                                             context,
+                                                             *this);
         parentProperty.reparentHere(newNode);
         if (nodeIndex >= 0) {
             int currentIndex = parentProperty.toNodeListProperty().toModelNodeList().indexOf(newNode);
@@ -575,13 +906,6 @@ void ModelAmender::idsDiffer(ModelNode &modelNode, const QString &qmlId)
     modelNode.setId(qmlId);
 }
 
-bool TextToModelMerger::isSignalPropertyName(const QString &signalName)
-{
-    // see QmlCompiler::isSignalPropertyName
-    return signalName.length() >= 3 && signalName.startsWith(QLatin1String("on")) &&
-           signalName.at(2).isLetter();
-}
-
 void TextToModelMerger::setupComponent(const ModelNode &node)
 {
     Q_ASSERT(node.type() == QLatin1String("Qt/Component"));
@@ -605,3 +929,16 @@ void TextToModelMerger::setupComponent(const ModelNode &node)
 
     node.variantProperty("__component_data") = result;
 }
+
+QString TextToModelMerger::textAt(const Document::Ptr &doc,
+                                  const SourceLocation &location)
+{
+    return doc->source().mid(location.offset, location.length);
+}
+
+QString TextToModelMerger::textAt(const Document::Ptr &doc,
+                                  const SourceLocation &from,
+                                  const SourceLocation &to)
+{
+    return doc->source().mid(from.offset, to.end() - from.begin());
+}
diff --git a/src/plugins/qmldesigner/core/model/texttomodelmerger.h b/src/plugins/qmldesigner/core/model/texttomodelmerger.h
index 0ac60b2ba1b41f767b56c68cd840a19d8d2a4f70..f71974c71b19020aace9f5ee67c95d3f7c4be8ef 100644
--- a/src/plugins/qmldesigner/core/model/texttomodelmerger.h
+++ b/src/plugins/qmldesigner/core/model/texttomodelmerger.h
@@ -34,6 +34,7 @@
 #include "import.h"
 #include "nodelistproperty.h"
 #include "modelnode.h"
+#include <qmljs/qmljsdocument.h>
 
 #include <private/qdeclarativedom_p.h>
 
@@ -43,6 +44,7 @@ class CORESHARED_EXPORT RewriterView;
 
 namespace Internal {
 
+class ReadingContext;
 class DifferenceHandler;
 
 class TextToModelMerger
@@ -54,7 +56,7 @@ public:
     TextToModelMerger(RewriterView *reWriterView);
     bool isActive() const;
 
-    void setupImports(QDeclarativeDomDocument &doc, DifferenceHandler &differenceHandler);
+    void setupImports(const QmlJS::Document::Ptr &doc, DifferenceHandler &differenceHandler);
     bool load(const QByteArray &data, DifferenceHandler &differenceHandler);
 
     RewriterView *view() const
@@ -65,25 +67,51 @@ protected:
 
 public:
     void syncNode(ModelNode &modelNode,
-                  const QDeclarativeDomObject &qmlObject,
+                  QmlJS::AST::UiObjectMember *astNode,
+                  ReadingContext *context,
                   DifferenceHandler &differenceHandler);
-    void syncProperty(AbstractProperty &modelProperty,
-                      const QDeclarativeDomProperty &qmlProperty,
-                      const QDeclarativeDomDynamicProperty &qmlDynamicProperty,
-                      DifferenceHandler &differenceHandler);
+    void syncNodeId(ModelNode &modelNode, const QString &astObjectId,
+                    DifferenceHandler &differenceHandler);
+    void syncNodeProperty(AbstractProperty &modelProperty,
+                          QmlJS::AST::UiObjectBinding *binding,
+                          ReadingContext *context,
+                          DifferenceHandler &differenceHandler);
+    void syncExpressionProperty(AbstractProperty &modelProperty,
+                                const QString &javascript,
+                                DifferenceHandler &differenceHandler);
+    void syncArrayProperty(AbstractProperty &modelProperty,
+                           QmlJS::AST::UiArrayBinding *array,
+                           ReadingContext *context,
+                           DifferenceHandler &differenceHandler);
+    void syncVariantProperty(AbstractProperty &modelProperty,
+                             const QString &astName,
+                             const QString &astValue,
+                             const QString &astType,
+                             DifferenceHandler &differenceHandler);
     void syncNodeListProperty(NodeListProperty &modelListProperty,
-                              const QDeclarativeDomList &domList,
+                              const QList<QmlJS::AST::UiObjectMember *> arrayMembers,
+                              ReadingContext *context,
                               DifferenceHandler &differenceHandler);
-    ModelNode createModelNode(const QDeclarativeDomObject &domObject,
+    ModelNode createModelNode(const QString &typeName,
+                              int majorVersion,
+                              int minorVersion,
+                              QmlJS::AST::UiObjectMember *astNode,
+                              ReadingContext *context,
                               DifferenceHandler &differenceHandler);
     static QVariant convertToVariant(const ModelNode &node,
-                                     const QDeclarativeDomProperty &qmlProperty,
-                                     const QDeclarativeDomDynamicProperty &qmlDynamicProperty);
+                                     const QString &astName,
+                                     const QString &astValue,
+                                     const QString &astType);
 
 private:
-    static bool isSignalPropertyName(const QString &signalName);
     void setupComponent(const ModelNode &node);
 
+    static QString textAt(const QmlJS::Document::Ptr &doc,
+                          const QmlJS::AST::SourceLocation &location);
+    static QString textAt(const QmlJS::Document::Ptr &doc,
+                          const QmlJS::AST::SourceLocation &from,
+                          const QmlJS::AST::SourceLocation &to);
+
 private:
     RewriterView *m_rewriterView;
     bool m_isActive;
@@ -100,15 +128,32 @@ public:
 
     virtual void modelMissesImport(const Import &import) = 0;
     virtual void importAbsentInQMl(const Import &import) = 0;
-    virtual void bindingExpressionsDiffer(BindingProperty &modelProperty, const QString &QDeclarativeBinding) = 0;
-    virtual void shouldBeBindingProperty(AbstractProperty &modelProperty, const QString &QDeclarativeBinding) = 0;
-    virtual void shouldBeNodeListProperty(AbstractProperty &modelProperty, const QDeclarativeDomList &domList) = 0;
+    virtual void bindingExpressionsDiffer(BindingProperty &modelProperty,
+                                          const QString &javascript) = 0;
+    virtual void shouldBeBindingProperty(AbstractProperty &modelProperty,
+                                         const QString &javascript) = 0;
+    virtual void shouldBeNodeListProperty(AbstractProperty &modelProperty,
+                                          const QList<QmlJS::AST::UiObjectMember *> arrayMembers,
+                                          ReadingContext *context) = 0;
     virtual void variantValuesDiffer(VariantProperty &modelProperty, const QVariant &qmlVariantValue, const QString &dynamicTypeName) = 0;
     virtual void shouldBeVariantProperty(AbstractProperty &modelProperty, const QVariant &qmlVariantValue, const QString &dynamicTypeName) = 0;
-    virtual void shouldBeNodeProperty(AbstractProperty &modelProperty, const QDeclarativeDomObject &qmlObject) = 0;
+    virtual void shouldBeNodeProperty(AbstractProperty &modelProperty,
+                                      const QString &typeName,
+                                      int majorVersion,
+                                      int minorVersion,
+                                      QmlJS::AST::UiObjectMember *astNode,
+                                      ReadingContext *context) = 0;
     virtual void modelNodeAbsentFromQml(ModelNode &modelNode) = 0;
-    virtual ModelNode listPropertyMissingModelNode(NodeListProperty &modelProperty, const QDeclarativeDomObject &qmlObject) = 0;
-    virtual void typeDiffers(bool isRootNode, ModelNode &modelNode, const QDeclarativeDomObject &domObject) = 0;
+    virtual ModelNode listPropertyMissingModelNode(NodeListProperty &modelProperty,
+                                                   ReadingContext *context,
+                                                   QmlJS::AST::UiObjectMember *arrayMember) = 0;
+    virtual void typeDiffers(bool isRootNode,
+                             ModelNode &modelNode,
+                             const QString &typeName,
+                             int majorVersion,
+                             int minorVersion,
+                             QmlJS::AST::UiObjectMember *astNode,
+                             ReadingContext *context) = 0;
     virtual void propertyAbsentFromQml(AbstractProperty &modelProperty) = 0;
     virtual void idsDiffer(ModelNode &modelNode, const QString &qmlId) = 0;
 
@@ -127,15 +172,32 @@ public:
 
     virtual void modelMissesImport(const Import &import);
     virtual void importAbsentInQMl(const Import &import);
-    virtual void bindingExpressionsDiffer(BindingProperty &modelProperty, const QString &QDeclarativeBinding);
-    virtual void shouldBeBindingProperty(AbstractProperty &modelProperty, const QString &QDeclarativeBinding);
-    virtual void shouldBeNodeListProperty(AbstractProperty &modelProperty, const QDeclarativeDomList &domList);
+    virtual void bindingExpressionsDiffer(BindingProperty &modelProperty,
+                                          const QString &javascript);
+    virtual void shouldBeBindingProperty(AbstractProperty &modelProperty,
+                                         const QString &javascript);
+    virtual void shouldBeNodeListProperty(AbstractProperty &modelProperty,
+                                          const QList<QmlJS::AST::UiObjectMember *> arrayMembers,
+                                          ReadingContext *context);
     virtual void variantValuesDiffer(VariantProperty &modelProperty, const QVariant &qmlVariantValue, const QString &dynamicTypeName);
     virtual void shouldBeVariantProperty(AbstractProperty &modelProperty, const QVariant &qmlVariantValue, const QString &dynamicTypeName);
-    virtual void shouldBeNodeProperty(AbstractProperty &modelProperty, const QDeclarativeDomObject &qmlObject);
+    virtual void shouldBeNodeProperty(AbstractProperty &modelProperty,
+                                      const QString &typeName,
+                                      int majorVersion,
+                                      int minorVersion,
+                                      QmlJS::AST::UiObjectMember *astNode,
+                                      ReadingContext *context);
     virtual void modelNodeAbsentFromQml(ModelNode &modelNode);
-    virtual ModelNode listPropertyMissingModelNode(NodeListProperty &modelProperty, const QDeclarativeDomObject &qmlObject);
-    virtual void typeDiffers(bool isRootNode, ModelNode &modelNode, const QDeclarativeDomObject &domObject);
+    virtual ModelNode listPropertyMissingModelNode(NodeListProperty &modelProperty,
+                                                   ReadingContext *context,
+                                                   QmlJS::AST::UiObjectMember *arrayMember);
+    virtual void typeDiffers(bool isRootNode,
+                             ModelNode &modelNode,
+                             const QString &typeName,
+                             int majorVersion,
+                             int minorVersion,
+                             QmlJS::AST::UiObjectMember *astNode,
+                             ReadingContext *context);
     virtual void propertyAbsentFromQml(AbstractProperty &modelProperty);
     virtual void idsDiffer(ModelNode &modelNode, const QString &qmlId);
 };
@@ -151,15 +213,32 @@ public:
 
     virtual void modelMissesImport(const Import &import);
     virtual void importAbsentInQMl(const Import &import);
-    virtual void bindingExpressionsDiffer(BindingProperty &modelProperty, const QString &QDeclarativeBinding);
-    virtual void shouldBeBindingProperty(AbstractProperty &modelProperty, const QString &QDeclarativeBinding);
-    virtual void shouldBeNodeListProperty(AbstractProperty &modelProperty, const QDeclarativeDomList &domList);
+    virtual void bindingExpressionsDiffer(BindingProperty &modelProperty,
+                                          const QString &javascript);
+    virtual void shouldBeBindingProperty(AbstractProperty &modelProperty,
+                                         const QString &javascript);
+    virtual void shouldBeNodeListProperty(AbstractProperty &modelProperty,
+                                          const QList<QmlJS::AST::UiObjectMember *> arrayMembers,
+                                          ReadingContext *context);
     virtual void variantValuesDiffer(VariantProperty &modelProperty, const QVariant &qmlVariantValue, const QString &dynamicType);
     virtual void shouldBeVariantProperty(AbstractProperty &modelProperty, const QVariant &qmlVariantValue, const QString &dynamicTypeName);
-    virtual void shouldBeNodeProperty(AbstractProperty &modelProperty, const QDeclarativeDomObject &qmlObject);
+    virtual void shouldBeNodeProperty(AbstractProperty &modelProperty,
+                                      const QString &typeName,
+                                      int majorVersion,
+                                      int minorVersion,
+                                      QmlJS::AST::UiObjectMember *astNode,
+                                      ReadingContext *context);
     virtual void modelNodeAbsentFromQml(ModelNode &modelNode);
-    virtual ModelNode listPropertyMissingModelNode(NodeListProperty &modelProperty, const QDeclarativeDomObject &qmlObject);
-    virtual void typeDiffers(bool isRootNode, ModelNode &modelNode, const QDeclarativeDomObject &domObject);
+    virtual ModelNode listPropertyMissingModelNode(NodeListProperty &modelProperty,
+                                                   ReadingContext *context,
+                                                   QmlJS::AST::UiObjectMember *arrayMember);
+    virtual void typeDiffers(bool isRootNode,
+                             ModelNode &modelNode,
+                             const QString &typeName,
+                             int majorVersion,
+                             int minorVersion,
+                             QmlJS::AST::UiObjectMember *astNode,
+                             ReadingContext *context);
     virtual void propertyAbsentFromQml(AbstractProperty &modelProperty);
     virtual void idsDiffer(ModelNode &modelNode, const QString &qmlId);
 };
diff --git a/src/plugins/qmldesigner/qmldesignerplugin.pro b/src/plugins/qmldesigner/qmldesignerplugin.pro
index 508e5c26bb3cf8dc1fc823999574ebacee35619e..a20079903e07c7a7a83a461bc2971dbc43507e61 100644
--- a/src/plugins/qmldesigner/qmldesignerplugin.pro
+++ b/src/plugins/qmldesigner/qmldesignerplugin.pro
@@ -4,6 +4,7 @@ TARGET = QmlDesigner
 include(../../qtcreatorplugin.pri)
 include(../private_headers.pri)
 include(qmldesigner_dependencies.pri)
+include(../qmljseditor/qmljseditor.pri)
 
 include(core/core.pri)
 include(components/integration/integration.pri)