diff --git a/src/libs/qmljs/qmljsdocument.cpp b/src/libs/qmljs/qmljsdocument.cpp
index fc3fb9ec88343287c7f675e0303b4703733aa86f..3ba72a4bee614bd477946bae8c88f57f19e50198 100644
--- a/src/libs/qmljs/qmljsdocument.cpp
+++ b/src/libs/qmljs/qmljsdocument.cpp
@@ -129,7 +129,7 @@ void Document::setDocumentRevision(int revision)
     _documentRevision = revision;
 }
 
-bool Document::parseQml()
+bool Document::parse_helper(int startToken)
 {
     Q_ASSERT(! _engine);
     Q_ASSERT(! _pool);
@@ -144,8 +144,21 @@ bool Document::parseQml()
 
     lexer.setCode(_source, /*line = */ 1);
 
-    _parsedCorrectly = parser.parse();
-    _ast = parser.ast();
+    switch (startToken) {
+    case QmlJSGrammar::T_FEED_UI_PROGRAM:
+        _parsedCorrectly = parser.parse();
+        break;
+    case QmlJSGrammar::T_FEED_JS_PROGRAM:
+        _parsedCorrectly = parser.parseProgram();
+        break;
+    case QmlJSGrammar::T_FEED_JS_EXPRESSION:
+        _parsedCorrectly = parser.parseExpression();
+        break;
+    default:
+        Q_ASSERT(0);
+    }
+
+    _ast = parser.rootNode();
     _diagnosticMessages = parser.diagnosticMessages();
 
     _bind = new Bind(this);
@@ -153,51 +166,19 @@ bool Document::parseQml()
     return _parsedCorrectly;
 }
 
-bool Document::parseJavaScript()
+bool Document::parseQml()
 {
-    Q_ASSERT(! _engine);
-    Q_ASSERT(! _pool);
-    Q_ASSERT(! _ast);
-    Q_ASSERT(! _bind);
-
-    _engine = new Engine();
-    _pool = new NodePool(_fileName, _engine);
-
-    Lexer lexer(_engine);
-    Parser parser(_engine);
-
-    lexer.setCode(_source, /*line = */ 1);
-
-    _parsedCorrectly = parser.parseProgram();
-    _ast = cast<Program*>(parser.rootNode());
-    _diagnosticMessages = parser.diagnosticMessages();
-
-    _bind = new Bind(this);
+    return parse_helper(QmlJSGrammar::T_FEED_UI_PROGRAM);
+}
 
-    return _parsedCorrectly;
+bool Document::parseJavaScript()
+{
+    return parse_helper(QmlJSGrammar::T_FEED_JS_PROGRAM);
 }
 
 bool Document::parseExpression()
 {
-    Q_ASSERT(! _engine);
-    Q_ASSERT(! _pool);
-    Q_ASSERT(! _ast);
-
-    _engine = new Engine();
-    _pool = new NodePool(_fileName, _engine);
-
-    Lexer lexer(_engine);
-    Parser parser(_engine);
-
-    lexer.setCode(_source, /*line = */ 1);
-
-    _parsedCorrectly = parser.parseExpression();
-    _ast = parser.rootNode();
-    if (_ast)
-        _ast = _ast->expressionCast();
-    _diagnosticMessages = parser.diagnosticMessages();
-
-    return _parsedCorrectly;
+    return parse_helper(QmlJSGrammar::T_FEED_JS_EXPRESSION);
 }
 
 Bind *Document::bind() const
diff --git a/src/libs/qmljs/qmljsdocument.h b/src/libs/qmljs/qmljsdocument.h
index 5cc07ccf6bbf9c7988b1f7093e79e39f4545e4e1..767ca281235012a8ec5cc8b3d37f1bab07c48ee8 100644
--- a/src/libs/qmljs/qmljsdocument.h
+++ b/src/libs/qmljs/qmljsdocument.h
@@ -81,6 +81,9 @@ public:
     QString path() const { return _path; }
     QString componentName() const { return _componentName; }
 
+private:
+    bool parse_helper(int kind);
+
 private:
     QmlJS::Engine *_engine;
     NodePool *_pool;
diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp
index f39b91c04e3ce2d2ab2fbd773672033bf5bedcd7..e2f9316df33adef2ec78629263837623c31b7d97 100644
--- a/src/libs/qmljs/qmljslink.cpp
+++ b/src/libs/qmljs/qmljslink.cpp
@@ -45,17 +45,31 @@ void Link::scopeChainAt(Document::Ptr doc, Node *currentObject)
 
     // ### FIXME: May want to link to instantiating components from here.
 
-    if (bind->_rootObjectValue)
-        _context->pushScope(bind->_rootObjectValue);
+    qDebug() << "**** here" << currentObject;
 
     ObjectValue *scopeObject = 0;
     if (UiObjectDefinition *definition = cast<UiObjectDefinition *>(currentObject))
         scopeObject = bind->_qmlObjects.value(definition);
     else if (UiObjectBinding *binding = cast<UiObjectBinding *>(currentObject))
         scopeObject = bind->_qmlObjects.value(binding);
+    else if (FunctionDeclaration *fun = cast<FunctionDeclaration *>(currentObject)) {
+        _context->pushScope(bind->_rootObjectValue);
 
-    if (scopeObject && scopeObject != bind->_rootObjectValue)
-        _context->pushScope(scopeObject);
+        ObjectValue *activation = engine()->newObject(/*prototype = */ 0);
+        for (FormalParameterList *it = fun->formals; it; it = it->next) {
+            if (it->name)
+                activation->setProperty(it->name->asString(), engine()->undefinedValue());
+        }
+        _context->pushScope(activation);
+    }
+
+    if (scopeObject) {
+        if (bind->_rootObjectValue)
+            _context->pushScope(bind->_rootObjectValue);
+
+        if (scopeObject != bind->_rootObjectValue)
+            _context->pushScope(scopeObject);
+    }
 
     const QStringList &includedScripts = bind->includedScripts();
     for (int index = includedScripts.size() - 1; index != -1; --index) {
diff --git a/src/plugins/qmljseditor/qmlcodecompletion.cpp b/src/plugins/qmljseditor/qmlcodecompletion.cpp
index 6d1bb3f064f375095cd3000d9e8900baf222779b..e063819295dad7459e2e5ae36e9b4559a36a8d23 100644
--- a/src/plugins/qmljseditor/qmlcodecompletion.cpp
+++ b/src/plugins/qmljseditor/qmlcodecompletion.cpp
@@ -654,6 +654,7 @@ int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
 
     // Set up the current scope chain.
     AST::Node *declaringMember = semanticInfo.declaringMember(editor->position());
+    qDebug() << "*** declaring member:" << declaringMember;
     context.build(declaringMember, document, snapshot);
 
     // Search for the operator that triggered the completion.
diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp
index 786d6e76418fb78ac1bdaca8b7230d2f384fb56e..65ddfe75489bcf25d6dede3b5635fa4a9ad81b36 100644
--- a/src/plugins/qmljseditor/qmljseditor.cpp
+++ b/src/plugins/qmljseditor/qmljseditor.cpp
@@ -387,8 +387,8 @@ public:
     {
         _textDocument = textDocument;
         _ranges.clear();
-        if (doc && doc->qmlProgram() != 0)
-            doc->qmlProgram()->accept(this);
+        if (doc && doc->ast() != 0)
+            doc->ast()->accept(this);
         return _ranges;
     }
 
@@ -409,7 +409,6 @@ protected:
         return true;
     }
 
-#if 0 // ### create ranges for function declarations.
     virtual bool visit(AST::FunctionExpression *ast)
     {
         _ranges.append(createRange(ast));
@@ -421,7 +420,6 @@ protected:
         _ranges.append(createRange(ast));
         return true;
     }
-#endif
 
     Range createRange(AST::UiObjectMember *member, AST::UiObjectInitializer *ast)
     {
@@ -448,6 +446,7 @@ protected:
 
         range.end = QTextCursor(_textDocument);
         range.end.setPosition(ast->rbraceToken.end());
+
         return range;
     }
 
@@ -649,8 +648,9 @@ void QmlJSTextEditor::updateDocumentNow()
 
 void QmlJSTextEditor::onDocumentUpdated(QmlJS::Document::Ptr doc)
 {
-    if (file()->fileName() != doc->fileName())
+    if (file()->fileName() != doc->fileName()) {
         return;
+    }
 
     if (doc->documentRevision() != document()->revision()) {
         // got an outdated document.