diff --git a/src/libs/qmljs/qmljs-lib.pri b/src/libs/qmljs/qmljs-lib.pri
index aaa9cacbb3823b6230a29cefbb28b940437fe5f7..d63d85bc21bff8f39c2ed75b286ee108acb30212 100644
--- a/src/libs/qmljs/qmljs-lib.pri
+++ b/src/libs/qmljs/qmljs-lib.pri
@@ -39,13 +39,13 @@ SOURCES += \
 contains(QT_CONFIG, declarative) {
     QT += declarative
 
-    DEFINES += BUILD_DECLARATIVE_BACKEND
-
     HEADERS += \
         $$PWD/qtdeclarativemetatypebackend.h
 
     SOURCES += \
         $$PWD/qtdeclarativemetatypebackend.cpp
+} else {
+    DEFINES += NO_DECLARATIVE_BACKEND
 }
 
 contains(QT, gui) {
diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp
index 6985b221915858d84c907e6f1b815edacd5099ca..aab501ce0e88f45e56c88103aedce879f79053c1 100644
--- a/src/libs/qmljs/qmljsinterpreter.cpp
+++ b/src/libs/qmljs/qmljsinterpreter.cpp
@@ -30,10 +30,93 @@
 #include "qmljsinterpreter.h"
 #include <QtCore/QDebug>
 
+#ifndef NO_DECLARATIVE_BACKEND
+#  include <QtDeclarative/QmlType>
+#  include <QtDeclarative/QmlMetaType>
+#  include <QtDeclarative/private/qmlgraphicsanchors_p.h> // ### remove me
+#  include <QtCore/QMetaObject>
+#  include <QtCore/QMetaProperty>
+#endif
+
 using namespace QmlJS::Interpreter;
 
 namespace {
 
+#ifndef NO_DECLARATIVE_BACKEND
+
+class QmlObjectValue: public ObjectValue
+{
+public:
+    QmlObjectValue(const QMetaObject *metaObject, Engine *engine)
+        : ObjectValue(engine), _metaObject(metaObject) {}
+
+    virtual ~QmlObjectValue() {}
+
+    virtual const Value *lookupMember(const QString &name) const
+    {
+        for (int index = 0; index < _metaObject->propertyCount(); ++index) {
+            QMetaProperty prop = _metaObject->property(index);
+
+            if (name == QString::fromUtf8(prop.name()))
+                return propertyValue(prop);
+        }
+
+        return ObjectValue::lookupMember(name);
+    }
+
+    virtual void processMembers(MemberProcessor *processor) const
+    {
+        for (int index = 0; index < _metaObject->propertyCount(); ++index) {
+            QMetaProperty prop = _metaObject->property(index);
+
+            processor->process(prop.name(), propertyValue(prop));
+        }
+    }
+
+    const Value *propertyValue(const QMetaProperty &prop) const {
+        const Value *value = engine()->undefinedValue();
+
+        if (QmlMetaType::isObject(prop.userType())) {
+            QString typeName = QString::fromUtf8(prop.typeName());
+
+            if (typeName.endsWith(QLatin1Char('*')))
+                typeName.truncate(typeName.length() - 1);
+
+            typeName.replace(QLatin1Char('.'), QLatin1Char('/'));
+
+            if (const ObjectValue *objectValue = engine()->newQmlObject(typeName))
+                return objectValue;
+        }
+
+        switch (prop.type()) {
+        case QMetaType::QByteArray:
+        case QMetaType::QString:
+            value = engine()->stringValue();
+            break;
+
+        case QMetaType::Bool:
+            value = engine()->booleanValue();
+            break;
+
+        case QMetaType::Int:
+        case QMetaType::Float:
+        case QMetaType::Double:
+            value = engine()->numberValue();
+            break;
+
+        default:
+            break;
+        } // end of switch
+
+        return value;
+    }
+
+private:
+    const QMetaObject *_metaObject;
+};
+
+#endif
+
 ////////////////////////////////////////////////////////////////////////////////
 // constructors
 ////////////////////////////////////////////////////////////////////////////////
@@ -511,21 +594,11 @@ void ObjectValue::processMembers(MemberProcessor *processor) const
     while (it.hasNext()) {
         it.next();
 
-        if (! processor->processMember(it.key(), it.value()))
+        if (! processor->process(it.key(), it.value()))
             break;
     }
 }
 
-const Value *ObjectValue::member(const QString &name) const
-{
-    QHash<QString, const Value *>::const_iterator it = _members.find(name);
-
-    if (it != _members.end())
-        return it.value();
-    else
-        return 0;
-}
-
 const Environment *ObjectValue::parent() const
 {
     return _scope;
@@ -533,7 +606,7 @@ const Environment *ObjectValue::parent() const
 
 const Value *ObjectValue::lookupMember(const QString &name) const
 {
-    if (const Value *m = member(name))
+    if (const Value *m = _members.value(name))
         return m;
 
     if (_prototype) {
@@ -1325,6 +1398,38 @@ void Engine::initializePrototypes()
     _globalObject->setProperty("RegExp", regexpCtor());
 }
 
+const ObjectValue *Engine::newQmlObject(const QString &name)
+{
+    if (const ObjectValue *object = _qmlObjects.value(name))
+        return object;
+
+#ifndef NO_DECLARATIVE_BACKEND
+    if (name == QLatin1String("QmlGraphicsAnchors")) {
+        QmlObjectValue *object = new QmlObjectValue(&QmlGraphicsAnchors::staticMetaObject, this);
+        _objects.append(object);
+        return object;
+    }
+
+    // ### TODO: add support for QML packages
+    QString componentName;
+    componentName += QLatin1String("Qt/");
+    componentName += name;
+    componentName.replace(QLatin1Char('.'), QLatin1Char('/'));
+
+    if (QmlType *qmlType = QmlMetaType::qmlType(componentName.toUtf8(), 4, 6)) {
+        QmlObjectValue *object = new QmlObjectValue(qmlType->metaObject(), this);
+        _qmlObjects.insert(name, object);
+        _objects.append(object);
+        return object;
+    }
+#endif
+
+    //qDebug() << name;
+
+    return 0;
+}
+
+
 const Value *FunctionValue::invoke(const Activation *activation) const
 {
     return activation->thisObject(); // ### FIXME: it should return undefined
diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h
index 4b4bed6755e86346d1346bdb2d48f60f1562c5bd..c303602279045ba118eb352cce598d1ff7c734e3 100644
--- a/src/libs/qmljs/qmljsinterpreter.h
+++ b/src/libs/qmljs/qmljsinterpreter.h
@@ -202,7 +202,7 @@ public:
     virtual ~MemberProcessor() {}
 
     // Returns false to stop the processor.
-    virtual bool processMember(const QString &name, const Value *value) = 0;
+    virtual bool process(const QString &name, const Value *value) = 0;
 };
 
 class QMLJS_EXPORT ObjectValue: public Value, public Environment
@@ -224,7 +224,6 @@ public:
 
     virtual void processMembers(MemberProcessor *processor) const;
 
-    virtual const Value *member(const QString &name) const;
     virtual const Value *property(const QString &name) const;
     virtual void setProperty(const QString &name, const Value *value);
     virtual void removeProperty(const QString &name);
@@ -435,6 +434,9 @@ public:
     Function *newFunction();
     const Value *newArray(); // ### remove me
 
+    // QML objects
+    const ObjectValue *newQmlObject(const QString &name);
+
     // global object
     ObjectValue *globalObject() const;
     const ObjectValue *mathObject() const;
@@ -500,6 +502,7 @@ private:
     BooleanValue _booleanValue;
     StringValue _stringValue;
     QList<ObjectValue *> _objects;
+    QHash<QString, const ObjectValue *> _qmlObjects;
 
     ConvertToNumber _convertToNumber;
     ConvertToString _convertToString;
diff --git a/src/libs/qmljs/qmljstypesystem.cpp b/src/libs/qmljs/qmljstypesystem.cpp
index b4add55970dab203c9cb373716d698aaedca7d23..2a8ca0e68e4163d5ec7995b25225fad82e5cbc08 100644
--- a/src/libs/qmljs/qmljstypesystem.cpp
+++ b/src/libs/qmljs/qmljstypesystem.cpp
@@ -30,9 +30,9 @@
 #include "qmljsmetatypebackend.h"
 #include "qmljstypesystem.h"
 
-#ifdef BUILD_DECLARATIVE_BACKEND
+#ifndef NO_DECLARATIVE_BACKEND
 #  include "qtdeclarativemetatypebackend.h"
-#endif // BUILD_DECLARATIVE_BACKEND
+#endif // NO_DECLARATIVE_BACKEND
 
 #include <QDebug>
 
@@ -40,9 +40,9 @@ using namespace QmlJS;
 
 TypeSystem::TypeSystem()
 {
-#ifdef BUILD_DECLARATIVE_BACKEND
+#ifndef NO_DECLARATIVE_BACKEND
     backends.append(new Internal::QtDeclarativeMetaTypeBackend(this));
-#endif // BUILD_DECLARATIVE_BACKEND
+#endif // NO_DECLARATIVE_BACKEND
 }
 
 TypeSystem::~TypeSystem()
diff --git a/src/plugins/qmljseditor/qmlcodecompletion.cpp b/src/plugins/qmljseditor/qmlcodecompletion.cpp
index eff8925820ba044911c52a22df427c4f3d75521b..3f240f6af00556f06fabccbddce32b5ef255d066 100644
--- a/src/plugins/qmljseditor/qmlcodecompletion.cpp
+++ b/src/plugins/qmljseditor/qmlcodecompletion.cpp
@@ -315,7 +315,7 @@ public:
     }
 
 private:
-    virtual bool processMember(const QString &name, const Interpreter::Value *value)
+    virtual bool process(const QString &name, const Interpreter::Value *value)
     {
         _properties.insert(name, value);
         return true;
@@ -703,6 +703,35 @@ int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
 
         if (exprDoc->ast()) {
             Interpreter::Engine interp;
+
+            foreach (Document::Ptr doc, snapshot) {
+                const QFileInfo fileInfo(doc->fileName());
+
+                if (fileInfo.suffix() != QLatin1String("qml"))
+                    continue;
+                else if (fileInfo.absolutePath() != currentFilePath) // ### FIXME includ `imported' components
+                    continue;
+
+                const QString typeName = fileInfo.baseName();
+                if (typeName.isEmpty())
+                    continue;
+
+                QMapIterator<QString, IdSymbol *> it(doc->ids());
+                while (it.hasNext()) {
+                    it.next();
+
+                    if (IdSymbol *symbol = it.value()) {
+                        const QString id = it.key();
+
+                        if (symbol->parentNode()) {
+                            const QString component = symbol->parentNode()->name();
+                            if (const Interpreter::ObjectValue *object = interp.newQmlObject(component))
+                                interp.globalObject()->setProperty(id, object);
+                        }
+                    }
+                }
+            }
+
             Evaluate evaluate(&interp);
 
             SearchPropertyDefinitions searchPropertyDefinitions;