diff --git a/src/plugins/qt4projectmanager/profilereader.cpp b/src/plugins/qt4projectmanager/profilereader.cpp
index b5b447ad602c76f42273d283487f91fccbd055cb..90c6241b1bf2409ce2ad086c430608c8cda7cb85 100644
--- a/src/plugins/qt4projectmanager/profilereader.cpp
+++ b/src/plugins/qt4projectmanager/profilereader.cpp
@@ -42,35 +42,27 @@ ProFileReader::ProFileReader(ProFileOption *option) : ProFileEvaluator(option)
 ProFileReader::~ProFileReader()
 {
     foreach (ProFile *pf, m_proFiles)
-        delete pf;
+        pf->deref();
 }
 
 bool ProFileReader::readProFile(const QString &fileName)
 {
-    //disable caching -> list of include files is not updated otherwise
-    ProFile *pro = new ProFile(fileName);
-    if (!queryProFile(pro)) {
-        delete pro;
-        return false;
+    if (ProFile *pro = parsedProFile(fileName)) {
+        aboutToEval(pro);
+        bool ok = accept(pro);
+        pro->deref();
+        return ok;
     }
-    m_includeFiles.insert(fileName, pro);
-    m_proFiles.append(pro);
-    return accept(pro);
+    return false;
 }
 
-ProFile *ProFileReader::parsedProFile(const QString &fileName)
+void ProFileReader::aboutToEval(ProFile *pro)
 {
-    ProFile *pro = ProFileEvaluator::parsedProFile(fileName);
-    if (pro) {
-        m_includeFiles.insert(fileName, pro);
+    if (!m_includeFiles.contains(pro->fileName())) {
+        m_includeFiles.insert(pro->fileName(), pro);
         m_proFiles.append(pro);
+        pro->ref();
     }
-    return pro;
-}
-
-void ProFileReader::releaseParsedProFile(ProFile *)
-{
-    return;
 }
 
 QList<ProFile*> ProFileReader::includeFiles() const
@@ -117,3 +109,52 @@ ProFile *ProFileReader::proFileFor(const QString &name)
 {
     return m_includeFiles.value(name);
 }
+
+
+
+ProFileCacheManager *ProFileCacheManager::s_instance = 0;
+
+ProFileCacheManager::ProFileCacheManager(QObject *parent) :
+        QObject(parent),
+        m_cache(0)
+{
+    s_instance = this;
+    m_timer.setSingleShot(true);
+    m_timer.setInterval(5000);
+    connect(&m_timer, SIGNAL(timeout()), SLOT(clear()));
+}
+
+ProFileCacheManager::~ProFileCacheManager()
+{
+    s_instance = 0;
+    clear();
+}
+
+ProFileCache *ProFileCacheManager::cache()
+{
+    m_timer.start();
+    if (!m_cache)
+        m_cache = new ProFileCache;
+    return m_cache;
+}
+
+void ProFileCacheManager::clear()
+{
+    // Just deleting the cache will be safe as long as the sequence of
+    // obtaining a cache pointer and using it is atomic as far as the main
+    // loop is concerned. Use a shared pointer once this is not true anymore.
+    delete m_cache;
+    m_cache = 0;
+}
+
+void ProFileCacheManager::discardFiles(const QString &prefix)
+{
+    if (m_cache)
+        m_cache->discardFiles(prefix);
+}
+
+void ProFileCacheManager::discardFile(const QString &fileName)
+{
+    if (m_cache)
+        m_cache->discardFile(fileName);
+}
diff --git a/src/plugins/qt4projectmanager/profilereader.h b/src/plugins/qt4projectmanager/profilereader.h
index 7e927d181b214acdb77dc9c5a1ea4174ab2a0162..f77df8d890009dda2c3a6ab1c44b4f8616c7c473 100644
--- a/src/plugins/qt4projectmanager/profilereader.h
+++ b/src/plugins/qt4projectmanager/profilereader.h
@@ -34,6 +34,7 @@
 
 #include <QtCore/QObject>
 #include <QtCore/QMap>
+#include <QtCore/QTimer>
 
 namespace Qt4ProjectManager {
 namespace Internal {
@@ -56,8 +57,7 @@ signals:
     void errorFound(const QString &error);
 
 private:
-    virtual ProFile *parsedProFile(const QString &fileName);
-    virtual void releaseParsedProFile(ProFile *proFile);
+    virtual void aboutToEval(ProFile *proFile);
     virtual void logMessage(const QString &msg);
     virtual void fileMessage(const QString &msg);
     virtual void errorMessage(const QString &msg);
@@ -67,6 +67,28 @@ private:
     QList<ProFile *> m_proFiles;
 };
 
+class ProFileCacheManager : public QObject
+{
+    Q_OBJECT
+
+public:
+    static ProFileCacheManager *instance() { return s_instance; }
+    ProFileCache *cache();
+    void discardFiles(const QString &prefix);
+    void discardFile(const QString &fileName);
+
+private:
+    ProFileCacheManager(QObject *parent);
+    ~ProFileCacheManager();
+    Q_SLOT void clear();
+    QTimer m_timer;
+    ProFileCache *m_cache;
+
+    static ProFileCacheManager *s_instance;
+
+    friend class Qt4ProjectManagerPlugin;
+};
+
 } // namespace Internal
 } // namespace Qt4ProjectManager
 
diff --git a/src/plugins/qt4projectmanager/qt4nodes.cpp b/src/plugins/qt4projectmanager/qt4nodes.cpp
index f4f228f6e11a0f7b15e0cc41a69c7c7c17855b9c..4da6c377c629d11a5da6da7a6e4909295d6add10 100644
--- a/src/plugins/qt4projectmanager/qt4nodes.cpp
+++ b/src/plugins/qt4projectmanager/qt4nodes.cpp
@@ -115,6 +115,7 @@ Qt4PriFileNode::Qt4PriFileNode(Qt4Project *project, Qt4ProFileNode* qt4ProFileNo
 
 void Qt4PriFileNode::scheduleUpdate()
 {
+    ProFileCacheManager::instance()->discardFile(m_projectFilePath);
     m_qt4ProFileNode->scheduleUpdate();
 }
 
diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp
index 1d9a753dbc86d2bee3d88b6ccf6f5633fde4568c..d0f9941246ceaabf0e0ff2bff9b26dad9a272f11 100644
--- a/src/plugins/qt4projectmanager/qt4project.cpp
+++ b/src/plugins/qt4projectmanager/qt4project.cpp
@@ -867,6 +867,8 @@ ProFileReader *Qt4Project::createProFileReader(Qt4ProFileNode *qt4ProFileNode)
             if (version->isValid())
                 m_proFileOption->properties = version->versionInfo();
         }
+
+        m_proFileOption->cache = ProFileCacheManager::instance()->cache();
     }
     ++m_proFileOptionRefCnt;
 
@@ -883,6 +885,11 @@ void Qt4Project::destroyProFileReader(ProFileReader *reader)
 {
     delete reader;
     if (!--m_proFileOptionRefCnt) {
+        QString dir = QFileInfo(m_fileInfo->fileName()).absolutePath();
+        if (!dir.endsWith(QLatin1Char('/')))
+            dir += QLatin1Char('/');
+        m_proFileOption->cache->discardFiles(dir);
+
         delete m_proFileOption;
         m_proFileOption = 0;
     }
@@ -1040,8 +1047,10 @@ void Qt4Project::notifyChanged(const QString &name)
     if (files(Qt4Project::ExcludeGeneratedFiles).contains(name)) {
         QList<Qt4ProFileNode *> list;
         findProFile(name, rootProjectNode(), list);
-        foreach(Qt4ProFileNode *node, list)
+        foreach(Qt4ProFileNode *node, list) {
+            ProFileCacheManager::instance()->discardFile(name);
             node->update();
+        }
     }
 }
 
diff --git a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp
index 040691c56a0e3b23b95b99b3a3b251b1f4c1f75c..5261ee74e02904ae6cda091cc157b9ec2e2d94e9 100644
--- a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp
+++ b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp
@@ -169,6 +169,8 @@ bool Qt4ProjectManagerPlugin::initialize(const QStringList &arguments, QString *
     addAutoReleasedObject(MaemoManager::instance());
 #endif
 
+    new ProFileCacheManager(this);
+
     // TODO reenable
     //m_embeddedPropertiesPage = new EmbeddedPropertiesPage;
     //addObject(m_embeddedPropertiesPage);
diff --git a/src/plugins/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp
index db1888399f025050eebc8afeb17ebad5e7fbec51..48f59817692df638af7a0f87df3916c8b17540af 100644
--- a/src/plugins/qt4projectmanager/qtversionmanager.cpp
+++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp
@@ -1207,6 +1207,7 @@ void QtVersion::updateToolChainAndMkspec() const
 
     ProFileOption option;
     option.properties = versionInfo();
+    option.cache = ProFileCacheManager::instance()->cache();
     ProFileReader *reader = new ProFileReader(&option);
     reader->setCumulative(false);
     reader->setParsePreAndPostFiles(false);
diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp
index 035e7d4c234a1f7d4670523675606a4c8eca7387..7c8c5bfa179750f17312135afa3af9e82d48a787 100644
--- a/src/shared/proparser/profileevaluator.cpp
+++ b/src/shared/proparser/profileevaluator.cpp
@@ -85,11 +85,59 @@ static void clearFunctions(ProFileEvaluator::FunctionDefs *defs)
 
 ///////////////////////////////////////////////////////////////////////
 //
-// ProFileOption
+// ProFileCache
 //
 ///////////////////////////////////////////////////////////////////////
 
+ProFileCache::~ProFileCache()
+{
+    foreach (ProFile *pro, parsed_files)
+        pro->deref();
+}
+
+void ProFileCache::discardFile(const QString &fileName)
+{
+    QHash<QString, ProFile *>::Iterator it = parsed_files.find(fileName);
+    if (it != parsed_files.end()) {
+        it.value()->deref();
+        parsed_files.erase(it);
+    }
+}
+
+void ProFileCache::discardFiles(const QString &prefix)
+{
+    QHash<QString, ProFile *>::Iterator
+            it = parsed_files.begin(),
+            end = parsed_files.end();
+    while (it != end)
+        if (it.key().startsWith(prefix)) {
+            it.value()->deref();
+            it = parsed_files.erase(it);
+        } else {
+            ++it;
+        }
+}
+
+void ProFileCache::addFile(ProFile *pro)
+{
+    parsed_files[pro->fileName()] = pro;
+    pro->ref();
+}
+
+ProFile *ProFileCache::getFile(const QString &fileName)
+{
+    ProFile *pro = parsed_files.value(fileName);
+    if (pro)
+        pro->ref();
+    return pro;
+}
+
+///////////////////////////////////////////////////////////////////////
+//
 // ProFileOption
+//
+///////////////////////////////////////////////////////////////////////
+
 ProFileOption::ProFileOption()
 {
 #ifdef Q_OS_WIN
@@ -112,6 +160,8 @@ ProFileOption::ProFileOption()
 #endif
 
     field_sep = QLatin1String(" ");
+
+    cache = 0;
 }
 
 ProFileOption::~ProFileOption()
@@ -199,6 +249,8 @@ public:
     ProFile *currentProFile() const;
 
     ProItem::ProItemReturn evaluateConditionalFunction(const QString &function, const QString &arguments);
+    ProFile *parsedProFile(const QString &fileName, bool cache,
+                           const QString &contents = QString());
     bool evaluateFile(const QString &fileName);
     bool evaluateFeatureFile(const QString &fileName,
                              QHash<QString, QStringList> *values = 0, FunctionDefs *defs = 0);
@@ -2776,20 +2828,20 @@ QStringList ProFileEvaluator::Private::values(const QString &variableName, const
     return values(variableName, m_filevaluemap[pro], pro);
 }
 
-// virtual
-ProFile *ProFileEvaluator::parsedProFile(const QString &fileName)
-{
-    ProFile *pro = new ProFile(fileName);
-    if (d->read(pro))
-        return pro;
-    delete pro;
-    return 0;
-}
-
-// virtual
-void ProFileEvaluator::releaseParsedProFile(ProFile *proFile)
+ProFile *ProFileEvaluator::Private::parsedProFile(const QString &fileName, bool cache,
+                                                  const QString &contents)
 {
-    delete proFile;
+    ProFile *pro;
+    if (!m_option->cache || !(pro = m_option->cache->getFile(fileName))) {
+        pro = new ProFile(fileName);
+        if (!(contents.isNull() ? read(pro) : read(pro, contents))) {
+            delete pro;
+            return 0;
+        }
+        if (m_option->cache && cache)
+            m_option->cache->addFile(pro);
+    }
+    return pro;
 }
 
 bool ProFileEvaluator::Private::evaluateFile(const QString &fileName)
@@ -2803,10 +2855,10 @@ bool ProFileEvaluator::Private::evaluateFile(const QString &fileName)
             errorMessage(format("circular inclusion of %1").arg(fn));
             return false;
         }
-    ProFile *pro = q->parsedProFile(fn);
-    if (pro) {
+    if (ProFile *pro = parsedProFile(fn, true)) {
+        q->aboutToEval(pro);
         bool ok = (pro->Accept(this) == ProItem::ReturnTrue);
-        q->releaseParsedProFile(pro);
+        pro->deref();
         return ok;
     } else {
         return false;
@@ -2857,12 +2909,13 @@ bool ProFileEvaluator::Private::evaluateFeatureFile(
         bool cumulative = m_cumulative;
         m_cumulative = false;
 
-        // Don't use evaluateFile() here to avoid the virtual parsedProFile().
+        // Don't use evaluateFile() here to avoid calling aboutToEval().
         // The path is fully normalized already.
-        ProFile pro(fn);
         bool ok = false;
-        if (read(&pro))
-            ok = (pro.Accept(this) == ProItem::ReturnTrue);
+        if (ProFile *pro = parsedProFile(fn, true)) {
+            ok = (pro->Accept(this) == ProItem::ReturnTrue);
+            pro->deref();
+        }
 
         m_cumulative = cumulative;
         return ok;
@@ -3019,14 +3072,9 @@ ProFileEvaluator::TemplateType ProFileEvaluator::templateType()
     return TT_Unknown;
 }
 
-bool ProFileEvaluator::queryProFile(ProFile *pro)
+ProFile *ProFileEvaluator::parsedProFile(const QString &fileName, const QString &contents)
 {
-    return d->read(pro);
-}
-
-bool ProFileEvaluator::queryProFile(ProFile *pro, const QString &content)
-{
-    return d->read(pro, content);
+    return d->parsedProFile(fileName, false, contents);
 }
 
 bool ProFileEvaluator::accept(ProFile *pro)
@@ -3039,6 +3087,10 @@ QString ProFileEvaluator::propertyValue(const QString &name) const
     return d->propertyValue(name);
 }
 
+void ProFileEvaluator::aboutToEval(ProFile *)
+{
+}
+
 void ProFileEvaluator::logMessage(const QString &message)
 {
     qWarning("%s", qPrintable(message));
diff --git a/src/shared/proparser/profileevaluator.h b/src/shared/proparser/profileevaluator.h
index ee21f4544b69e5d7658e1306153b878eaaa052ad..3537a12a6a4cc8789f139d48dad17998bc2e778d 100644
--- a/src/shared/proparser/profileevaluator.h
+++ b/src/shared/proparser/profileevaluator.h
@@ -42,6 +42,22 @@ QT_BEGIN_NAMESPACE
 
 class ProFileOption;
 
+class ProFileCache
+{
+public:
+    ProFileCache() {}
+    ~ProFileCache();
+
+    void addFile(ProFile *pro);
+    ProFile *getFile(const QString &fileName);
+
+    void discardFile(const QString &fileName);
+    void discardFiles(const QString &prefix);
+
+private:
+    QHash<QString, ProFile *> parsed_files;
+};
+
 class ProFileEvaluator
 {
     class Private;
@@ -74,8 +90,8 @@ public:
     void setConfigCommandLineArguments(const QStringList &addUserConfigCmdArgs, const QStringList &removeUserConfigCmdArgs);
     void setParsePreAndPostFiles(bool on); // Default is true
 
-    bool queryProFile(ProFile *pro);
-    bool queryProFile(ProFile *pro, const QString &content); // the same as above but the content is read from "content" string, not from filesystem
+    // If contents is non-null, it will be used instead of the file's actual content
+    ProFile *parsedProFile(const QString &fileName, const QString &contents = QString());
     bool accept(ProFile *pro);
 
     QStringList values(const QString &variableName) const;
@@ -87,8 +103,7 @@ public:
     QString propertyValue(const QString &val) const;
 
     // for our descendents
-    virtual ProFile *parsedProFile(const QString &fileName);
-    virtual void releaseParsedProFile(ProFile *proFile);
+    virtual void aboutToEval(ProFile *proFile); // only .pri, but not .prf. or .pro
     virtual void logMessage(const QString &msg);
     virtual void errorMessage(const QString &msg); // .pro parse errors
     virtual void fileMessage(const QString &msg); // error() and message() from .pro file
@@ -130,6 +145,7 @@ struct ProFileOption
     QString qmakespec;
     QString cachefile;
     QHash<QString, QString> properties;
+    ProFileCache *cache;
 
     enum TARG_MODE { TARG_UNIX_MODE, TARG_WIN_MODE, TARG_MACX_MODE, TARG_MAC9_MODE, TARG_QNX6_MODE };
     TARG_MODE target_mode;