diff --git a/src/assistant/assistant/centralwidget.cpp b/src/assistant/assistant/centralwidget.cpp
index 8df808f783e984c24d5015d4df5b33e82bd4f945..e9737399b1c55f56f03544e0d8ed0f0cedcef44b 100644
--- a/src/assistant/assistant/centralwidget.cpp
+++ b/src/assistant/assistant/centralwidget.cpp
@@ -339,6 +339,7 @@ void CentralWidget::connectTabBar()
 }
 
 // -- public slots
+
 #ifndef QT_NO_CLIPBOARD
 void CentralWidget::copy()
 {
@@ -587,6 +588,17 @@ void CentralWidget::handleSourceChanged(const QUrl &url)
         emit sourceChanged(url);
 }
 
+void CentralWidget::slotHighlighted(const QString &link)
+{
+    TRACE_OBJ
+    QString resolvedLink = m_resolvedLinks.value(link);
+    if (!link.isEmpty() && resolvedLink.isEmpty()) {
+        resolvedLink = HelpEngineWrapper::instance().findFile(link).toString();
+        m_resolvedLinks.insert(link, resolvedLink);
+    }
+    emit highlighted(resolvedLink);
+}
+
 // -- private
 
 void CentralWidget::initPrinter()
@@ -609,9 +621,8 @@ void CentralWidget::connectSignals(HelpViewer *page)
         SIGNAL(backwardAvailable(bool)));
     connect(page, SIGNAL(sourceChanged(QUrl)), this,
         SLOT(handleSourceChanged(QUrl)));
-    connect(page, SIGNAL(highlighted(QString)), this,
-            SIGNAL(highlighted(QString)));
     connect(page, SIGNAL(printRequested()), this, SLOT(print()));
+    connect(page, SIGNAL(highlighted(QString)), this, SLOT(slotHighlighted(QString)));
 }
 
 bool CentralWidget::eventFilter(QObject *object, QEvent *e)
diff --git a/src/assistant/assistant/centralwidget.h b/src/assistant/assistant/centralwidget.h
index 2c6c4eef911c0e3109e2693aac97592720569eaf..4ff66a0af47410c75043adb28907afa4ea97b461 100644
--- a/src/assistant/assistant/centralwidget.h
+++ b/src/assistant/assistant/centralwidget.h
@@ -155,6 +155,7 @@ private slots:
     void highlightSearchTerms();
     void printPreview(QPrinter *printer);
     void handleSourceChanged(const QUrl &url);
+    void slotHighlighted(const QString &link);
 
 private:
     void initPrinter();
@@ -168,6 +169,7 @@ private:
     FindWidget *m_findWidget;
     QStackedWidget *m_stackedWidget;
     TabBar *m_tabBar;
+    QHash<QString, QString> m_resolvedLinks;
 };
 
 QT_END_NAMESPACE
diff --git a/src/assistant/assistant/helpenginewrapper.cpp b/src/assistant/assistant/helpenginewrapper.cpp
index e5e84412fc8b5788dabde33ec51f1492fecb234a..1fcaecc0faba7f4d5a160f772d78319d99f4ad3b 100644
--- a/src/assistant/assistant/helpenginewrapper.cpp
+++ b/src/assistant/assistant/helpenginewrapper.cpp
@@ -337,12 +337,6 @@ QString HelpEngineWrapper::error() const
     return d->m_helpEngine->error();
 }
 
-QString HelpEngineWrapper::virtualFolderForNameSpace(const QString &nameSpace) const
-{
-    TRACE_OBJ
-    return d->m_helpEngine->d->nameSpaceVirtualFolderMap.value(nameSpace, QString());
-}
-
 const QStringList HelpEngineWrapper::qtDocInfo(const QString &component) const
 {
     TRACE_OBJ
diff --git a/src/assistant/assistant/helpenginewrapper.h b/src/assistant/assistant/helpenginewrapper.h
index d352bd69b1e9201a7410dd5e5367eb5a2dae0fe9..33ebf955b2035e733147b37ac5c49a11dff33e92 100644
--- a/src/assistant/assistant/helpenginewrapper.h
+++ b/src/assistant/assistant/helpenginewrapper.h
@@ -100,7 +100,6 @@ public:
     const QStringList filterAttributes() const;
     const QStringList filterAttributes(const QString &filterName) const;
     QString error() const;
-    QString virtualFolderForNameSpace(const QString &nameSpace) const;
 
     /*
      * To be called after assistant has finished looking for new documentation.
diff --git a/src/assistant/assistant/helpviewer.cpp b/src/assistant/assistant/helpviewer.cpp
index 314a765e8beeb4afb7121466a93188d52bb08724..17084e6e31f1089a972ef3842a54447663d84331 100644
--- a/src/assistant/assistant/helpviewer.cpp
+++ b/src/assistant/assistant/helpviewer.cpp
@@ -143,7 +143,7 @@ QString HelpViewer::mimeFromUrl(const QUrl &url)
             return QLatin1String(e->mimeType);
         ++e;
     }
-    return QLatin1String("");
+    return QLatin1String("application/octet-stream");
 }
 
 bool HelpViewer::launchWithExternalApp(const QUrl &url)
@@ -177,31 +177,6 @@ bool HelpViewer::launchWithExternalApp(const QUrl &url)
     return false;
 }
 
-QString HelpViewer::fixupVirtualFolderForUrl(const HelpEngineWrapper *engine, const QUrl &url, bool *fixed)
-{
-    TRACE_OBJ
-    Q_ASSERT(engine);
-
-    QString ret = url.toString();
-    const QString virtualFolder = engine->virtualFolderForNameSpace(url.host());
-    QString effectiveVirtualFolder = virtualFolder;
-    const QStringList tokens = url.path().split('/');
-    Q_FOREACH (const QString& token, tokens) {
-        if (!token.isEmpty()) {
-            effectiveVirtualFolder = token;
-            break;
-        }
-    }
-
-    if (QString::localeAwareCompare(effectiveVirtualFolder, virtualFolder)) {
-        ret = url.scheme() + QLatin1String("://") + url.host() + QLatin1Char('/')
-                + virtualFolder + QLatin1String("/..") + url.path();
-    }
-    if (fixed && engine->findFile(ret).isValid())
-        *fixed = true;
-    return ret;
-}
-
 // -- public slots
 
 void HelpViewer::home()
diff --git a/src/assistant/assistant/helpviewer.h b/src/assistant/assistant/helpviewer.h
index e6148585924586e6688843e1659b2e903ef00621..a7c3893f0f777fbe97c918e94d2632f48e8b91cc 100644
--- a/src/assistant/assistant/helpviewer.h
+++ b/src/assistant/assistant/helpviewer.h
@@ -110,7 +110,6 @@ public:
     static bool canOpenPage(const QString &url);
     static QString mimeFromUrl(const QUrl &url);
     static bool launchWithExternalApp(const QUrl &url);
-    static QString fixupVirtualFolderForUrl(const HelpEngineWrapper *engine, const QUrl &url, bool *fixed = 0);
 
 public slots:
 #ifndef QT_NO_CLIPBOARD
diff --git a/src/assistant/assistant/helpviewer_qtb.cpp b/src/assistant/assistant/helpviewer_qtb.cpp
index 146a55bebd562a2299bb36f82ce94b367d7b280d..debcf679cce5120b9d69c026f38d60b5bff2e513 100644
--- a/src/assistant/assistant/helpviewer_qtb.cpp
+++ b/src/assistant/assistant/helpviewer_qtb.cpp
@@ -163,18 +163,14 @@ void HelpViewer::setSource(const QUrl &url)
         return;
 
     emit loadStarted();
-    QString string = url.toString();
-    const HelpEngineWrapper &engine = HelpEngineWrapper::instance();
-    QUrl resolvedUrl = (string == QLatin1String("help") ? LocalHelpFile :
-        engine.findFile(string));
-    bool fileFound = resolvedUrl.isValid();
-    if (!fileFound && isLocalUrl(url))
-        resolvedUrl = fixupVirtualFolderForUrl(&engine, url, &fileFound);
+    bool helpOrAbout = (url.toString() == QLatin1String("help"));
+    const QUrl resolvedUrl = (helpOrAbout ? LocalHelpFile : HelpEngineWrapper::instance().findFile(url));
 
     QTextBrowser::setSource(resolvedUrl);
-    if (!fileFound) {
-        setHtml(string == QLatin1String("about:blank") ? AboutBlank
-            : PageNotFoundMessage.arg(url.toString()));
+
+    if (!resolvedUrl.isValid()) {
+        helpOrAbout = (url.toString() == QLatin1String("about:blank"));
+        setHtml(helpOrAbout ? AboutBlank : PageNotFoundMessage.arg(url.toString()));
     }
     emit loadFinished(true);
 }
@@ -382,7 +378,7 @@ QVariant HelpViewer::loadResource(int type, const QUrl &name)
     TRACE_OBJ
     QByteArray ba;
     if (type < 4) {
-        QUrl url = fixupVirtualFolderForUrl(&HelpEngineWrapper::instance(), name);
+        const QUrl url = HelpEngineWrapper::instance().findFile(name);
         ba = HelpEngineWrapper::instance().fileData(url);
         if (url.toString().endsWith(QLatin1String(".svg"), Qt::CaseInsensitive)) {
             QImage image;
diff --git a/src/assistant/assistant/helpviewer_qwv.cpp b/src/assistant/assistant/helpviewer_qwv.cpp
index 81fb828383afa5b13438f3915bf782a2bb477571..57cfa40d4b0b0440ec904be7ae04f08934b485d9 100644
--- a/src/assistant/assistant/helpviewer_qwv.cpp
+++ b/src/assistant/assistant/helpviewer_qwv.cpp
@@ -47,6 +47,7 @@
 #include "openpagesmanager.h"
 #include "tracer.h"
 
+#include <QClipboard>
 #include <QtCore/QFileInfo>
 #include <QtCore/QString>
 #include <QtCore/QTimer>
@@ -133,6 +134,25 @@ qint64 HelpNetworkReply::readData(char *buffer, qint64 maxlen)
     return len;
 }
 
+// -- HelpRedirectNetworkReply
+
+class HelpRedirectNetworkReply : public QNetworkReply
+{
+public:
+    HelpRedirectNetworkReply(const QNetworkRequest &request, const QUrl &newUrl)
+    {
+        setRequest(request);
+        setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 301);
+        setAttribute(QNetworkRequest::RedirectionTargetAttribute, newUrl);
+
+        QTimer::singleShot(0, this, SIGNAL(finished()));
+    }
+
+protected:
+    void abort() { TRACE_OBJ }
+    qint64 readData(char*, qint64) { TRACE_OBJ return qint64(-1); }
+};
+
 // -- HelpNetworkAccessManager
 
 class HelpNetworkAccessManager : public QNetworkAccessManager
@@ -151,24 +171,21 @@ HelpNetworkAccessManager::HelpNetworkAccessManager(QObject *parent)
     TRACE_OBJ
 }
 
-QNetworkReply *HelpNetworkAccessManager::createRequest(Operation /*op*/,
-    const QNetworkRequest &request, QIODevice* /*outgoingData*/)
+QNetworkReply *HelpNetworkAccessManager::createRequest(Operation, const QNetworkRequest &request, QIODevice*)
 {
     TRACE_OBJ
-    QString url = request.url().toString();
-
     const HelpEngineWrapper &engine = HelpEngineWrapper::instance();
 
-    bool fileFound = engine.findFile(url).isValid();
-    if (!fileFound && HelpViewer::isLocalUrl(request.url()))
-        url = HelpViewer::fixupVirtualFolderForUrl(&engine, request.url(), &fileFound);
+    const QUrl url = engine.findFile(request.url());
+    if (url.isValid() && (url != request.url()))
+        return new HelpRedirectNetworkReply(request, url);
 
-    const QString &mimeType = HelpViewer::mimeFromUrl(url);
-    const QByteArray &data = fileFound ? engine.fileData(url) : QString::fromLatin1(g_htmlPage)
-        .arg(g_percent1, g_percent2, HelpViewer::tr("Error loading: %1").arg(url), g_percent4).toUtf8();
+    if (url.isValid())
+        return new HelpNetworkReply(request, engine.fileData(url), HelpViewer::mimeFromUrl(url));
 
-    return new HelpNetworkReply(request, data, mimeType.isEmpty()
-        ? QLatin1String("application/octet-stream") : mimeType);
+    return new HelpNetworkReply(request, QString::fromLatin1(g_htmlPage).arg(g_percent1, g_percent2,
+        HelpViewer::tr("Error loading: %1").arg(request.url().toString()), g_percent4).toUtf8(),
+        QLatin1String("text/html"));
 }
 
 // -- HelpPage
@@ -223,6 +240,13 @@ void HelpPage::triggerAction(WebAction action, bool checked)
             QWebPage::triggerAction(action, checked);
             break;
     }
+
+#ifndef QT_NO_CLIPBOARD
+    if (action == CopyLinkToClipboard || action == CopyImageUrlToClipboard) {
+        const QString link = QApplication::clipboard()->text();
+        QApplication::clipboard()->setText(HelpEngineWrapper::instance().findFile(link).toString());
+    }
+#endif
 }
 
 bool HelpPage::acceptNavigationRequest(QWebFrame *,
@@ -403,6 +427,7 @@ bool HelpViewer::findText(const QString &text, FindFlags flags, bool incremental
 }
 
 // -- public slots
+
 #ifndef QT_NO_CLIPBOARD
 void HelpViewer::copy()
 {
diff --git a/src/assistant/help/qhelpcontentwidget.cpp b/src/assistant/help/qhelpcontentwidget.cpp
index e25dd03669258bab5ecc8171b2e314e030e19291..6697ba6683f22190bb8981c6587a63548e009b08 100644
--- a/src/assistant/help/qhelpcontentwidget.cpp
+++ b/src/assistant/help/qhelpcontentwidget.cpp
@@ -541,11 +541,8 @@ QModelIndex QHelpContentWidget::indexOf(const QUrl &link)
             contentModel->contentItemAt(contentModel->index(i, 0));
         if (itm && itm->url().host() == link.host()) {
             QString path = link.path();
-            if (path.startsWith(QLatin1Char('/')))
-                path = path.mid(1);
-            if (searchContentItem(contentModel, contentModel->index(i, 0), path)) {
+            if (searchContentItem(contentModel, contentModel->index(i, 0), link.path()))
                 return m_syncIndex;
-            }
         }
     }
     return QModelIndex();
diff --git a/src/assistant/help/qhelpengine_p.h b/src/assistant/help/qhelpengine_p.h
index a24b5173edd5eaa82565f16860dd940d1ad0ed13..19df2803624796a768351ba5d0e8fe4264129905 100644
--- a/src/assistant/help/qhelpengine_p.h
+++ b/src/assistant/help/qhelpengine_p.h
@@ -89,7 +89,6 @@ public:
     QMap<QString, QHelpDBReader*> fileNameReaderMap;
     QMultiMap<QString, QHelpDBReader*> virtualFolderMap;
     QStringList orderedFileNameList;
-    QHash<QString, QString> nameSpaceVirtualFolderMap;
 
     QHelpCollectionHandler *collectionHandler;
     QString currentFilter;
diff --git a/src/assistant/help/qhelpenginecore.cpp b/src/assistant/help/qhelpenginecore.cpp
index 4f05b2e6c04586edfeea134cff4b36b7f1816fa8..8695cb3848369708337618bb721e588ac7c5e66a 100644
--- a/src/assistant/help/qhelpenginecore.cpp
+++ b/src/assistant/help/qhelpenginecore.cpp
@@ -88,7 +88,6 @@ void QHelpEngineCorePrivate::clearMaps()
     fileNameReaderMap.clear();
     virtualFolderMap.clear();
     orderedFileNameList.clear();
-    nameSpaceVirtualFolderMap.clear();
 }
 
 bool QHelpEngineCorePrivate::setup()
@@ -129,7 +128,6 @@ bool QHelpEngineCorePrivate::setup()
         fileNameReaderMap.insert(absFileName, reader);
         virtualFolderMap.insert(info.folderName, reader);
         orderedFileNameList.append(absFileName);
-        nameSpaceVirtualFolderMap.insert(info.namespaceName, info.folderName);
     }
     q->currentFilter();
     emit q->setupFinished();