diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp
index ae8ebccb619ef84bc87211c80f5aa15bf0b5317e..f24b9943335e87bab482b97ffc9928d842d8b73e 100644
--- a/src/libs/qmljs/qmljsinterpreter.cpp
+++ b/src/libs/qmljs/qmljsinterpreter.cpp
@@ -28,14 +28,17 @@
 **************************************************************************/
 
 #include "qmljsinterpreter.h"
+
+#include <QtCore/QMetaObject>
+#include <QtCore/QMetaProperty>
 #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>
+#  include <QtDeclarative/private/qmlgraphicsrectangle_p.h> // ### remove me
+#  include <QtDeclarative/private/qmlvaluetype_p.h> // ### remove me
 #endif
 
 using namespace QmlJS::Interpreter;
@@ -1405,6 +1408,10 @@ ObjectValue *Engine::newQmlObject(const QString &name)
         QmlObjectValue *object = new QmlObjectValue(&QmlGraphicsAnchors::staticMetaObject, this);
         _objects.append(object);
         return object;
+    } else if (name == QLatin1String("QmlGraphicsPen")) {
+        QmlObjectValue *object = new QmlObjectValue(&QmlGraphicsPen::staticMetaObject, this);
+        _objects.append(object);
+        return object;
     }
 
     // ### TODO: add support for QML packages
diff --git a/src/plugins/qmljseditor/qmlcodecompletion.cpp b/src/plugins/qmljseditor/qmlcodecompletion.cpp
index 88de8b468d5e3e52530e4fd2a340f96614a3ecf6..2f98abf9563ae725698f44141f72bc1124760752 100644
--- a/src/plugins/qmljseditor/qmlcodecompletion.cpp
+++ b/src/plugins/qmljseditor/qmlcodecompletion.cpp
@@ -99,11 +99,11 @@ class FindMembers: protected AST::Visitor
     QList<AST::UiObjectMember *> _members;
 
 public:
-    QList<AST::UiObjectMember *> operator()(AST::Node *node)
+    QList<AST::UiObjectMember *> operator()(Document::Ptr doc)
     {
         _members.clear();
-        if (node)
-            node->accept(this);
+        if (doc && doc->qmlProgram())
+            doc->qmlProgram()->accept(this);
         return _members;
     }
 
@@ -657,6 +657,23 @@ bool QmlCodeCompletion::triggersCompletion(TextEditor::ITextEditable *editor)
     return false;
 }
 
+static QString qualifiedNameId(AST::UiQualifiedId *it)
+{
+    QString text;
+
+    for (; it; it = it->next) {
+        if (! it->name)
+            continue;
+
+        text += it->name->asString();
+
+        if (it->next)
+            text += QLatin1Char('.');
+    }
+
+    return text;
+}
+
 int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
 {
     m_editor = editor;
@@ -717,19 +734,86 @@ int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
     // Set up the current scope chain.
     Interpreter::ObjectValue *scope = interp.newObject(/* prototype = */ 0);
 
-    // ### FIXME: get the declaring item
-    Interpreter::ObjectValue *declaringItem = interp.newQmlObject(QLatin1String("Item"));
+    AST::UiObjectMember *declaringMember = 0;
+    AST::UiObjectMember *parentMember = 0;
 
-    scope->setScope(declaringItem);
-    declaringItem->setScope(interp.globalObject());
+    const int cursorLine = edit->textCursor().blockNumber() + 1;
+    const int cursorColumn = edit->textCursor().columnNumber() + 1;
 
-    if (qmlDocument && qmlDocument->qmlProgram()) {
-        const Interpreter::ObjectValue *parentItem = 0;
-        const QString declaringItem = QLatin1String("Item"); // ### FIXME: resolve the parent of the declaring item
-        parentItem = interp.newQmlObject(declaringItem);
-        scope->setProperty(QLatin1String("parent"), parentItem);
+    FindMembers findMembers;
+    const QList<AST::UiObjectMember *> members = findMembers(qmlDocument);
+    for (int index = 0; index < members.size(); ++index) {
+        AST::UiObjectMember *member = members.at(index);
+
+        AST::SourceLocation pos = member->firstSourceLocation();
+        const int startLine = pos.startLine;
+        const int startColumn = pos.startColumn;
+
+        if (startLine < cursorLine || (startLine == cursorLine && cursorColumn >= startColumn)) {
+            AST::SourceLocation endPos = member->lastSourceLocation();
+            const int endLine = endPos.startLine;
+            const int endColumn = endPos.startColumn + endPos.length;
+
+            if (cursorLine < endLine || (cursorLine == endLine && cursorColumn <= endColumn)) {
+                parentMember = declaringMember;
+                declaringMember = member;
+            }
+        }
     }
 
+    // ### TODO: remove me. This is just a quick and dirty hack to get some completion
+    // for the property definitions.
+    SearchPropertyDefinitions searchPropertyDefinitions;
+
+    const QList<AST::UiPublicMember *> properties = searchPropertyDefinitions(qmlDocument);
+    foreach (AST::UiPublicMember *prop, properties) {
+        if (! (prop->name && prop->memberType))
+            continue;
+
+        const QString propName = prop->name->asString();
+        const QString propType = prop->memberType->asString();
+
+        // ### TODO: generalize
+        if (propType == QLatin1String("string"))
+            interp.globalObject()->setProperty(propName, interp.stringValue());
+        else if (propType == QLatin1String("bool"))
+            interp.globalObject()->setProperty(propName, interp.booleanValue());
+        else if (propType == QLatin1String("int") || propType == QLatin1String("real"))
+            interp.globalObject()->setProperty(propName, interp.numberValue());
+    }
+
+    // Get the name of the declaring item.
+    QString declaringItemName = QLatin1String("Item");
+
+    if (AST::UiObjectDefinition *binding = AST::cast<AST::UiObjectDefinition *>(declaringMember))
+        declaringItemName = qualifiedNameId(binding->qualifiedTypeNameId);
+    else if (AST::UiObjectBinding *binding = AST::cast<AST::UiObjectBinding *>(declaringMember))
+        declaringItemName = qualifiedNameId(binding->qualifiedTypeNameId);
+
+    Interpreter::ObjectValue *declaringItem = interp.newQmlObject(declaringItemName);
+    if (! declaringItem)
+        declaringItem = interp.newQmlObject(QLatin1String("Item"));
+
+    if (declaringItem) {
+        scope->setScope(declaringItem);
+        declaringItem->setScope(interp.globalObject());
+    }
+
+    // Get the name of the parent of the declaring item.
+    QString parentItemName = QLatin1String("Item");
+
+    if (AST::UiObjectDefinition *binding = AST::cast<AST::UiObjectDefinition *>(parentMember))
+        parentItemName = qualifiedNameId(binding->qualifiedTypeNameId);
+    else if (AST::UiObjectBinding *binding = AST::cast<AST::UiObjectBinding *>(parentMember))
+        parentItemName = qualifiedNameId(binding->qualifiedTypeNameId);
+
+    Interpreter::ObjectValue *parentItem = interp.newQmlObject(declaringItemName);
+    if (! parentItem)
+        parentItem = interp.newQmlObject(QLatin1String("Item"));
+
+    if (parentItem)
+        scope->setProperty(QLatin1String("parent"), parentItem);
+
     // Search for the operator that triggered the completion.
     QChar completionOperator;
     if (m_startPosition > 0)
@@ -784,27 +868,6 @@ int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
             Evaluate evaluate(&interp);
             evaluate.setScope(scope);
 
-            // ### TODO: remove me. This is just a quick and dirty hack to get some completion
-            // for the property definitions.
-            SearchPropertyDefinitions searchPropertyDefinitions;
-
-            const QList<AST::UiPublicMember *> properties = searchPropertyDefinitions(qmlDocument);
-            foreach (AST::UiPublicMember *prop, properties) {
-                if (! (prop->name && prop->memberType))
-                    continue;
-
-                const QString propName = prop->name->asString();
-                const QString propType = prop->memberType->asString();
-
-                // ### TODO: generalize
-                if (propType == QLatin1String("string"))
-                    interp.globalObject()->setProperty(propName, interp.stringValue());
-                else if (propType == QLatin1String("bool"))
-                    interp.globalObject()->setProperty(propName, interp.booleanValue());
-                else if (propType == QLatin1String("int") || propType == QLatin1String("real"))
-                    interp.globalObject()->setProperty(propName, interp.numberValue());
-            }
-
             // Evaluate the expression under cursor.
             const Interpreter::Value *value = interp.convertToObject(evaluate(exprDoc->ast()));
             //qDebug() << "type:" << interp.typeId(value);