diff --git a/src/plugins/duieditor/duicompletionvisitor.cpp b/src/plugins/duieditor/duicompletionvisitor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2dd407b1f413ca143102ae98faf47deb2f8e5222
--- /dev/null
+++ b/src/plugins/duieditor/duicompletionvisitor.cpp
@@ -0,0 +1,90 @@
+#include <QtCore/QDebug>
+
+#include "duicompletionvisitor.h"
+#include "qmljsast_p.h"
+
+using namespace QmlJS;
+using namespace QmlJS::AST;
+
+namespace DuiEditor {
+namespace Internal {
+
+DuiCompletionVisitor::DuiCompletionVisitor()
+{
+}
+
+QSet<QString> DuiCompletionVisitor::operator()(QmlJS::AST::UiProgram *ast, int pos)
+{
+    m_completions.clear();
+    m_pos = (quint32) pos;
+
+    Node::acceptChild(ast, this);
+
+    return m_completions;
+}
+
+bool DuiCompletionVisitor::preVisit(QmlJS::AST::Node *node)
+{
+    if (!m_parentStack.isEmpty())
+        m_nodeParents[node] = m_parentStack.top();
+    m_parentStack.push(node);
+    return true;
+}
+
+static QString toString(Statement *stmt)
+{
+    if (ExpressionStatement *exprStmt = AST::cast<ExpressionStatement*>(stmt)) {
+        if (IdentifierExpression *idExpr = AST::cast<IdentifierExpression *>(exprStmt->expression)) {
+            return idExpr->name->asString();
+        }
+    }
+
+    return QString();
+}
+
+bool DuiCompletionVisitor::visit(UiScriptBinding *ast)
+{
+    if (!ast)
+        return false;
+
+    UiObjectDefinition *parentObject = findParentObject(ast);
+
+    if (ast->qualifiedId && ast->qualifiedId->name->asString() == QLatin1String("id")) {
+        const QString nodeId = toString(ast->statement);
+        if (!nodeId.isEmpty())
+            m_objectToId[parentObject] = nodeId;
+    } else if (m_objectToId.contains(parentObject)) {
+        if (ast->qualifiedId && ast->qualifiedId->name) {
+            const QString parentId = m_objectToId[parentObject];
+            m_completions.insert(parentId + "." + ast->qualifiedId->name->asString());
+        }
+    }
+
+    if (ast->firstSourceLocation().begin() >= m_pos && m_pos <= ast->lastSourceLocation().end()) {
+        UiObjectDefinition *parentsParent = findParentObject(parentObject);
+
+        if (parentsParent) {
+            m_completions.insert(QLatin1String("parent"));
+        }
+    }
+
+    return true;
+}
+
+UiObjectDefinition *DuiCompletionVisitor::findParentObject(Node *node) const
+{
+    if (!node)
+        return 0;
+
+    Node *candidate = m_nodeParents[node];
+    if (candidate == 0)
+        return 0;
+
+    if (UiObjectDefinition *parentObject = AST::cast<UiObjectDefinition *>(candidate))
+        return parentObject;
+    else
+        return findParentObject(candidate);
+}
+
+} // namespace Internal
+} // namespace DuiEditor
diff --git a/src/plugins/duieditor/duicompletionvisitor.h b/src/plugins/duieditor/duicompletionvisitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..473ed160257979294d19366d4044179c5301c04f
--- /dev/null
+++ b/src/plugins/duieditor/duicompletionvisitor.h
@@ -0,0 +1,43 @@
+#ifndef COMPLETIONVISITOR_H
+#define COMPLETIONVISITOR_H
+
+#include <QtCore/QMap>
+#include <QtCore/QSet>
+#include <QtCore/QStack>
+#include <QtCore/QString>
+
+#include "qmljsastfwd_p.h"
+#include "qmljsastvisitor_p.h"
+#include "qmljsengine_p.h"
+
+namespace DuiEditor {
+namespace Internal {
+
+class DuiCompletionVisitor: protected QmlJS::AST::Visitor
+{
+public:
+    DuiCompletionVisitor();
+
+    QSet<QString> operator()(QmlJS::AST::UiProgram *ast, int pos);
+
+protected:
+    virtual bool preVisit(QmlJS::AST::Node *node);
+    virtual void postVisit(QmlJS::AST::Node *) { m_parentStack.pop(); }
+
+    virtual bool visit(QmlJS::AST::UiScriptBinding *ast);
+
+private:
+    QmlJS::AST::UiObjectDefinition *findParentObject(QmlJS::AST::Node *node) const;
+
+private:
+    QSet<QString> m_completions;
+    quint32 m_pos;
+    QStack<QmlJS::AST::Node *> m_parentStack;
+    QMap<QmlJS::AST::Node *, QmlJS::AST::Node *> m_nodeParents;
+    QMap<QmlJS::AST::Node *, QString> m_objectToId;
+};
+
+} // namespace Internal
+} // namespace DuiEditor
+
+#endif // COMPLETIONVISITOR_H