diff --git a/share/qtcreator/qml/qmldump/main.cpp b/share/qtcreator/qml/qmldump/main.cpp
index 93f349c98be11ed4a23b6392a2c5752f8726fd25..9ebdc172e649446e959ddfec7766cff0c9145d0a 100644
--- a/share/qtcreator/qml/qmldump/main.cpp
+++ b/share/qtcreator/qml/qmldump/main.cpp
@@ -82,13 +82,17 @@ void processDeclarativeType(const QDeclarativeType *ty, QSet<const QMetaObject *
     processMetaObject(ty->metaObject(), metas);
 }
 
-void writeType(QXmlStreamAttributes *attrs, QByteArray typeName)
+void writeType(QXmlStreamAttributes *attrs, QByteArray typeName, bool isWritable = false)
 {
     bool isList = false, isPointer = false;
     erasure(&typeName, &isList, &isPointer);
     attrs->append(QXmlStreamAttribute("type", typeName));
     if (isList)
         attrs->append(QXmlStreamAttribute("isList", "true"));
+    if (isWritable)
+        attrs->append(QXmlStreamAttribute("isWritable", "true"));
+    if (isPointer)
+        attrs->append(QXmlStreamAttribute("isPointer", "true"));
 }
 
 void dump(const QMetaProperty &prop, QXmlStreamWriter *xml)
@@ -98,7 +102,7 @@ void dump(const QMetaProperty &prop, QXmlStreamWriter *xml)
     QXmlStreamAttributes attributes;
     attributes.append(QXmlStreamAttribute("name", QString::fromUtf8(prop.name())));
 
-    writeType(&attributes, prop.typeName());
+    writeType(&attributes, prop.typeName(), prop.isWritable());
 
     xml->writeAttributes(attributes);
     xml->writeEndElement();
diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp
index 7ecb6e076b0f660aa1e74cb618c6a02df5f97936..be633b1222ddc934117c6c403909351759636eb4 100644
--- a/src/libs/qmljs/qmljsinterpreter.cpp
+++ b/src/libs/qmljs/qmljsinterpreter.cpp
@@ -182,10 +182,12 @@ class FakeMetaProperty {
     QString m_propertyName;
     QString m_type;
     bool m_isList;
+    bool m_isWritable;
+    bool m_isPointer;
 
 public:
-    FakeMetaProperty(const QString &name, const QString &type, bool isList)
-        : m_propertyName(name), m_type(type), m_isList(isList)
+    FakeMetaProperty(const QString &name, const QString &type, bool isList, bool isWritable, bool isPointer)
+        : m_propertyName(name), m_type(type), m_isList(isList), m_isWritable(isWritable), m_isPointer(isPointer)
     {}
 
     QString name() const
@@ -196,6 +198,12 @@ public:
 
     bool isList() const
     { return m_isList; }
+
+    bool isWritable() const
+    { return m_isWritable; }
+
+    bool isPointer() const
+    { return m_isPointer; }
 };
 
 class FakeMetaObject {
@@ -490,6 +498,8 @@ private:
 
         QString name, type;
         bool isList = false;
+        bool isWritable = false;
+        bool isPointer = false;
         foreach (const QXmlStreamAttribute &attr, _xml.attributes()) {
             if (attr.name() == QLatin1String("name")) {
                 name = attr.value().toString();
@@ -501,7 +511,25 @@ private:
                 } else if (attr.value() == QLatin1String("false")) {
                     isList = false;
                 } else {
-                    invalidAttr(attr.value().toString(), QLatin1String("idList"), tag);
+                    invalidAttr(attr.value().toString(), QLatin1String("isList"), tag);
+                    return;
+                }
+            } else if (attr.name() == QLatin1String("isWritable")) {
+                if (attr.value() == QLatin1String("true")) {
+                    isWritable = true;
+                } else if (attr.value() == QLatin1String("false")) {
+                    isWritable = false;
+                } else {
+                    invalidAttr(attr.value().toString(), QLatin1String("isWritable"), tag);
+                    return;
+                }
+            } else if (attr.name() == QLatin1String("isPointer")) {
+                if (attr.value() == QLatin1String("true")) {
+                    isPointer = true;
+                } else if (attr.value() == QLatin1String("false")) {
+                    isPointer = false;
+                } else {
+                    invalidAttr(attr.value().toString(), QLatin1String("isPointer"), tag);
                     return;
                 }
             } else {
@@ -514,7 +542,7 @@ private:
         else if (type.isEmpty())
             noValidAttr(QLatin1String("type"), tag);
         else
-            createProperty(metaObject, name, type, isList);
+            createProperty(metaObject, name, type, isList, isWritable, isPointer);
 
         while (_xml.readNextStartElement()) {
             unexpectedElement(_xml.name(), tag);
@@ -522,10 +550,10 @@ private:
     }
 
     void createProperty(FakeMetaObject *metaObject, const QString &name,
-                        const QString &type, bool isList) {
+                        const QString &type, bool isList, bool isWritable, bool isPointer) {
         Q_ASSERT(metaObject);
 
-        metaObject->addProperty(FakeMetaProperty(name, type, isList));
+        metaObject->addProperty(FakeMetaProperty(name, type, isList, isWritable, isPointer));
     }
 
     void readEnum(FakeMetaObject *metaObject)
@@ -641,6 +669,7 @@ private:
                 name = attr.value().toString();
             } else if (attr.name() == QLatin1String("type")) {
                 type = attr.value().toString();
+            } else if (attr.name() == QLatin1String("isPointer")) {
             } else {
                 ignoreAttr(attr);
             }
@@ -912,6 +941,28 @@ bool QmlObjectValue::isEnum(const QString &typeName) const
     return _metaObject->enumeratorIndex(typeName) != -1;
 }
 
+bool QmlObjectValue::isWritable(const QString &propertyName) const
+{
+    for (const FakeMetaObject *iter = _metaObject; iter; iter = iter->superClass()) {
+        int propIdx = iter->propertyIndex(propertyName);
+        if (propIdx != -1) {
+            return iter->property(propIdx).isWritable();
+        }
+    }
+    return false;
+}
+
+bool QmlObjectValue::isPointer(const QString &propertyName) const
+{
+    for (const FakeMetaObject *iter = _metaObject; iter; iter = iter->superClass()) {
+        int propIdx = iter->propertyIndex(propertyName);
+        if (propIdx != -1) {
+            return iter->property(propIdx).isPointer();
+        }
+    }
+    return false;
+}
+
 bool QmlObjectValue::enumContainsKey(const QString &enumName, const QString &enumKeyName) const
 {
     int idx = _metaObject->enumeratorIndex(enumName);
diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h
index 586e8a81629714d2f80dfa58b5cba4690b56b493..074e794183de75349b86db4a5749e5d11d02120c 100644
--- a/src/libs/qmljs/qmljsinterpreter.h
+++ b/src/libs/qmljs/qmljsinterpreter.h
@@ -395,6 +395,8 @@ public:
     QString defaultPropertyName() const;
     QString propertyType(const QString &propertyName) const;
     bool isListProperty(const QString &name) const;
+    bool isWritable(const QString &propertyName) const;
+    bool isPointer(const QString &propertyName) const;
     bool isEnum(const QString &typeName) const;
     bool enumContainsKey(const QString &enumName, const QString &enumKeyName) const;
     bool hasChildInPackage() const;