diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp
index a68a4cd127c778474197865d43658732e0ecb267..09166ef0528b0a39900b4ca6ab83062f2386da5b 100644
--- a/src/plugins/cpptools/cppcodecompletion.cpp
+++ b/src/plugins/cpptools/cppcodecompletion.cpp
@@ -767,11 +767,18 @@ int CppCodeCompletion::startCompletionInternal(TextEditor::BaseTextEditor *edit,
         return -1;
 
     typeOfExpression.init(thisDocument, snapshot);
-    Symbol *lastVisibleSymbol = thisDocument->lastVisibleSymbolAt(line, column);
+
+    Scope *scope = thisDocument->scopeAt(line, column);
+    Q_ASSERT(scope != 0);
 
     if (expression.isEmpty()) {
-        if (m_completionOperator == T_EOF_SYMBOL || m_completionOperator == T_COLON_COLON)
-            return globalCompletion(lastVisibleSymbol, thisDocument, snapshot);
+        if (m_completionOperator == T_EOF_SYMBOL || m_completionOperator == T_COLON_COLON) {
+            (void) typeOfExpression(expression, scope);
+            globalCompletion(scope);
+            if (m_completions.isEmpty())
+                return -1;
+            return m_startPosition;
+        }
 
         else if (m_completionOperator == T_SIGNAL || m_completionOperator == T_SLOT) {
             // Apply signal/slot completion on 'this'
@@ -779,9 +786,6 @@ int CppCodeCompletion::startCompletionInternal(TextEditor::BaseTextEditor *edit,
         }
     }
 
-    Scope *scope = thisDocument->scopeAt(line, column);
-    Q_ASSERT(scope != 0);
-
     if (debug)
         qDebug() << "scope:" << scope->owner()->fileName() << scope->owner()->line() << scope->owner()->column();
 
@@ -871,26 +875,69 @@ int CppCodeCompletion::startCompletionInternal(TextEditor::BaseTextEditor *edit,
     return -1;
 }
 
-int CppCodeCompletion::globalCompletion(Symbol *lastVisibleSymbol,
-                                        Document::Ptr thisDocument,
-                                        const Snapshot &snapshot)
+void CppCodeCompletion::globalCompletion(Scope *currentScope)
 {
-    if (m_completionOperator == T_EOF_SYMBOL) {
-        addKeywords();
-        addMacros(thisDocument->fileName(), snapshot);
+    const LookupContext &context = typeOfExpression.context();
+
+    if (m_completionOperator == T_COLON_COLON) {
+        completeNamespace(context.globalNamespace());
+        return;
     }
 
-    Document::Ptr exprDoc = Document::create(QLatin1String("<expression>"));
-    const DeprecatedLookupContext context(lastVisibleSymbol, exprDoc, thisDocument, snapshot);
-    const QList<Scope *> scopes = context.expand(context.visibleScopes());
+    addKeywords();
+    addMacros(context.thisDocument()->fileName(), context.snapshot());
+
+    QList<ClassOrNamespace *> usingBindings;
+    ClassOrNamespace *currentBinding = 0;
 
-    foreach (Scope *scope, scopes) {
-        for (unsigned i = 0; i < scope->symbolCount(); ++i) {
-            addCompletionItem(scope->symbolAt(i));
+    for (Scope *scope = currentScope; scope; scope = scope->enclosingScope()) {
+        if (scope->isBlockScope()) {
+            if (ClassOrNamespace *binding = context.lookupType(scope->owner())) {
+                for (unsigned i = 0; i < scope->symbolCount(); ++i) {
+                    Symbol *member = scope->symbolAt(i);
+                    if (! member->name())
+                        continue;
+                    else if (UsingNamespaceDirective *u = member->asUsingNamespaceDirective()) {
+                        if (ClassOrNamespace *b = binding->lookupType(u->name()))
+                            usingBindings.append(b);
+                    }
+                }
+            }
+        } else if (scope->isFunctionScope() || scope->isClassScope() || scope->isNamespaceScope()) {
+            currentBinding = context.lookupType(scope->owner());
+            break;
+        }
+    }
+
+    for (; currentBinding; currentBinding = currentBinding->parent()) {
+        const QList<Symbol *> symbols = currentBinding->symbols();
+
+        if (! symbols.isEmpty()) {
+            if (symbols.first()->isNamespace())
+                completeNamespace(currentBinding);
+            else
+                completeClass(currentBinding, false);
         }
     }
 
-    return m_startPosition;
+    foreach (ClassOrNamespace *b, usingBindings)
+        completeNamespace(b);
+
+    for (Scope *scope = currentScope; scope; scope = scope->enclosingScope()) {
+        if (scope->isBlockScope()) {
+            for (unsigned i = 0; i < scope->symbolCount(); ++i) {
+                addCompletionItem(scope->symbolAt(i));
+            }
+        } else if (scope->isFunctionScope()) {
+            Scope *arguments = scope->owner()->asFunction()->arguments();
+            for (unsigned i = 0; i < arguments->symbolCount(); ++i) {
+                addCompletionItem(arguments->symbolAt(i));
+            }
+            break;
+        } else {
+            break;
+        }
+    }
 }
 
 bool CppCodeCompletion::completeConstructorOrFunction(const QList<LookupItem> &results,
@@ -1508,6 +1555,9 @@ bool CppCodeCompletion::completeQtMethod(const QList<LookupItem> &results,
 void CppCodeCompletion::completions(QList<TextEditor::CompletionItem> *completions)
 {
     const int length = m_editor->position() - m_startPosition;
+    if (length < 0)
+        return;
+
     const QString key = m_editor->textAt(m_startPosition, length);
 
     if (length == 0)
diff --git a/src/plugins/cpptools/cppcodecompletion.h b/src/plugins/cpptools/cppcodecompletion.h
index edc76104bf0ac96a4b904b4d7b13bd0262fc3bbd..39d23adf68bf6d2b4278becbf7cd6044b1fa5bf0 100644
--- a/src/plugins/cpptools/cppcodecompletion.h
+++ b/src/plugins/cpptools/cppcodecompletion.h
@@ -96,9 +96,7 @@ private:
     bool completeInclude(const QTextCursor &cursor);
     void completePreprocessor();
 
-    int globalCompletion(CPlusPlus::Symbol *lastVisibleSymbol,
-                         CPlusPlus::Document::Ptr thisDocument,
-                         const CPlusPlus::Snapshot &snapshot);
+    void globalCompletion(CPlusPlus::Scope *scope);
 
     bool completeConstructorOrFunction(const QList<CPlusPlus::LookupItem> &results,
                                        int endOfExpression, bool toolTipOnly);