diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecontents.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecontents.cpp
index 3541325b09e1abaaa2cbaf5b0bd5263faeea3176..1e84cfdf055ad558509c6a7cfba204ae856f9827 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecontents.cpp
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecontents.cpp
@@ -31,14 +31,12 @@
 
 #include "maemopackagecreationstep.h"
 #include "maemotoolchain.h"
+#include "profilewrapper.h"
 
-#include <qt4projectmanager/profilereader.h>
 #include <qt4projectmanager/qt4buildconfiguration.h>
 #include <qt4projectmanager/qt4project.h>
 #include <qt4projectmanager/qt4target.h>
 
-#include <prowriter.h>
-
 #include <QtCore/QCryptographicHash>
 #include <QtCore/QFile>
 #include <QtCore/QFileInfo>
@@ -64,47 +62,32 @@ namespace Internal {
 MaemoPackageContents::MaemoPackageContents(MaemoPackageCreationStep *packageStep)
     : QAbstractTableModel(packageStep),
       m_packageStep(packageStep),
-      m_proFileOption(new ProFileOption),
-      m_proFileReader(new ProFileReader(m_proFileOption.data())),
       m_modified(false),
-      m_proFile(0)
+      m_initialized(false)
 {
 }
 
 MaemoPackageContents::~MaemoPackageContents() {}
 
-bool MaemoPackageContents::init()
-{
-    return m_proFile ? true : buildModel();
-}
-
 bool MaemoPackageContents::buildModel() const
 {
-    m_deployables.clear();
-    const Qt4ProFileNode * const proFileNode = m_packageStep
-        ->qt4BuildConfiguration()->qt4Target()->qt4Project()->rootProjectNode();
-    if (m_proFileName.isEmpty()) {
-        m_proFileName = proFileNode->path();
-        m_proDir = QFileInfo(m_proFileName).dir();
-    }
-
-    resetProFileContents();
-    if (!m_proFile)
-        return false;
+    if (m_initialized)
+        return true;
 
-    const QStringList elemList = m_proFileReader->values(InstallsVar, m_proFile);
+    m_deployables.clear();
+    QSharedPointer<ProFileWrapper> proFileWrapper
+        = m_packageStep->proFileWrapper();
+    const QStringList &elemList = proFileWrapper->varValues(InstallsVar);
     bool targetFound = false;
     foreach (const QString &elem, elemList) {
-        const QStringList paths
-            = m_proFileReader->values(pathVar(elem), m_proFile);
+        const QStringList &paths = proFileWrapper->varValues(pathVar(elem));
         if (paths.count() != 1) {
             qWarning("Error: Variable %s has %d values.",
                 qPrintable(pathVar(elem)), paths.count());
             continue;
         }
 
-        const QStringList files
-            = m_proFileReader->values(filesVar(elem), m_proFile);
+        const QStringList &files = proFileWrapper->varValues(filesVar(elem));
         if (files.isEmpty() && elem != TargetVar) {
             qWarning("Error: Variable %s has no RHS.",
                 qPrintable(filesVar(elem)));
@@ -117,29 +100,29 @@ bool MaemoPackageContents::buildModel() const
             targetFound = true;
         } else {
             foreach (const QString &file, files)
-                m_deployables << MaemoDeployable(cleanPath(file), paths.first());
+                m_deployables << MaemoDeployable(
+                    proFileWrapper->absFilePath(file), paths.first());
         }
     }
 
     if (!targetFound) {
+        const Qt4ProFileNode * const proFileNode
+            = m_packageStep->qt4BuildConfiguration()->qt4Target()
+                ->qt4Project()->rootProjectNode();
         const QString remoteDir = proFileNode->projectType() == LibraryTemplate
             ? QLatin1String("/usr/local/lib")
             : QLatin1String("/usr/local/bin");
         m_deployables.prepend(MaemoDeployable(m_packageStep->localExecutableFilePath(),
             remoteDir));
-        QString errorString;
-        if (!readProFileContents(&errorString)) {
-            qWarning("Error reading .pro file: %s", qPrintable(errorString));
-            return false;
-        }
-        addValueToProFile(pathVar(TargetVar), remoteDir);
-        addValueToProFile(InstallsVar, TargetVar);
-        if (!writeProFileContents(&errorString)) {
-            qWarning("Error writing .pro file: %s", qPrintable(errorString));
+
+        if (!proFileWrapper->addVarValue(pathVar(TargetVar), remoteDir)
+            || !proFileWrapper->addVarValue(InstallsVar, TargetVar)) {
+            qWarning("Error updating .pro file.");
             return false;
         }
     }
 
+    m_initialized = true;
     m_modified = true;
     return true;
 }
@@ -153,21 +136,18 @@ MaemoDeployable MaemoPackageContents::deployableAt(int row) const
 bool MaemoPackageContents::addDeployable(const MaemoDeployable &deployable,
     QString *error)
 {
-    if (m_deployables.contains(deployable) || deployableAt(0) == deployable)
-        return false;
-
-    if (!readProFileContents(error))
+    if (m_deployables.contains(deployable)) {
+        *error = tr("File already in list.");
         return false;
-
+    }
+    const QSharedPointer<ProFileWrapper> proFileWrapper
+        = m_packageStep->proFileWrapper();
     QCryptographicHash elemHash(QCryptographicHash::Md5);
     elemHash.addData(deployable.localFilePath.toUtf8());
     const QString elemName = QString::fromAscii(elemHash.result().toHex());
-    addFileToProFile(filesVar(elemName), deployable.localFilePath);
-    addValueToProFile(pathVar(elemName), deployable.remoteDir);
-    addValueToProFile(InstallsVar, elemName);
-
-    if (!writeProFileContents(error))
-        return false;
+    proFileWrapper->addFile(filesVar(elemName), deployable.localFilePath);
+    proFileWrapper->addVarValue(pathVar(elemName), deployable.remoteDir);
+    proFileWrapper->addVarValue(InstallsVar, elemName);
 
     beginInsertRows(QModelIndex(), rowCount(), rowCount());
     m_deployables << deployable;
@@ -186,28 +166,24 @@ bool MaemoPackageContents::removeDeployableAt(int row, QString *error)
         return false;
     }
 
-    if (!readProFileContents(error))
-        return false;
-
-    const QString filesVarName = filesVar(elemToRemove);
+    const QString &filesVarName = filesVar(elemToRemove);
+    QSharedPointer<ProFileWrapper> proFileWrapper
+        = m_packageStep->proFileWrapper();
     const bool isOnlyElem
-        = m_proFileReader->values(filesVarName, m_proFile).count() == 1;
+        = proFileWrapper->varValues(filesVarName).count() == 1;
     bool success
-        = removeFileFromProFile(filesVarName, deployable.localFilePath);
+        = proFileWrapper->removeFile(filesVarName, deployable.localFilePath);
     if (success && isOnlyElem) {
-        success = removeValueFromProFile(pathVar(elemToRemove),
+        success = proFileWrapper->removeVarValue(pathVar(elemToRemove),
             deployable.remoteDir);
         if (success)
-            success = removeValueFromProFile(InstallsVar, elemToRemove);
+            success = proFileWrapper->removeVarValue(InstallsVar, elemToRemove);
     }
     if (!success) {
         *error = tr("Could not remove deployable from .pro file.");
         return false;
     }
 
-    if (!writeProFileContents(error))
-        return false;
-
     beginRemoveRows(QModelIndex(), row, row);
     m_deployables.removeAt(row - 1);
     endRemoveRows();
@@ -216,8 +192,7 @@ bool MaemoPackageContents::removeDeployableAt(int row, QString *error)
 
 int MaemoPackageContents::rowCount(const QModelIndex &parent) const
 {
-    if (!m_proFile)
-        buildModel();
+    buildModel();
     return parent.isValid() ? 0 : m_deployables.count();
 }
 
@@ -254,12 +229,6 @@ bool MaemoPackageContents::setData(const QModelIndex &index,
         || role != Qt::EditRole)
         return false;
 
-    QString error;
-    if (!readProFileContents(&error)) {
-        qWarning("%s", qPrintable(error));
-        return false;
-    }
-
     MaemoDeployable &deployable = m_deployables[index.row()];
     const QString elemToChange = findInstallsElem(deployable);
     if (elemToChange.isEmpty()) {
@@ -267,16 +236,13 @@ bool MaemoPackageContents::setData(const QModelIndex &index,
             "INSTALLS element not found in .pro file");
         return false;
     }
-    const QString pathElem = pathVar(elemToChange);
-    if (!removeValueFromProFile(pathElem, deployable.remoteDir)) {
-        qWarning("Error: Could not change remote path in .pro file.");
-        return false;
-    }
-    const QString &newRemoteDir = value.toString();
-    addValueToProFile(pathElem, newRemoteDir);
 
-    if (!writeProFileContents(&error)) {
-        qWarning("%s", qPrintable(error));
+    const QString &newRemoteDir = value.toString();
+    QSharedPointer<ProFileWrapper> proFileWrapper
+        = m_packageStep->proFileWrapper();
+    if (!proFileWrapper->replaceVarValue(pathVar(elemToChange),
+        deployable.remoteDir, newRemoteDir)) {
+        qWarning("Error: Could not change remote path in .pro file.");
         return false;
     }
 
@@ -295,149 +261,29 @@ QVariant MaemoPackageContents::headerData(int section,
 
 QString MaemoPackageContents::remoteExecutableFilePath() const
 {
-    if (!m_proFile)
-        buildModel();
-    return deployableAt(0).remoteDir + '/' + m_packageStep->executableFileName();
-}
-
-bool MaemoPackageContents::readProFileContents(QString *error) const
-{
-    if (!m_proFileLines.isEmpty())
-        return true;
-
-    QFile proFileOnDisk(m_proFileName);
-    if (!proFileOnDisk.open(QIODevice::ReadOnly)) {
-        *error = tr("Project file '%1' could not be opened for reading.")
-            .arg(m_proFileName);
-        return false;
-    }
-    const QString proFileContents
-        = QString::fromLatin1(proFileOnDisk.readAll());
-    if (proFileOnDisk.error() != QFile::NoError) {
-        *error = tr("Project file '%1' could not be read.")
-            .arg(m_proFileName);
-        return false;
-    }
-    m_proFileLines = proFileContents.split('\n');
-    return true;
-}
-
-bool MaemoPackageContents::writeProFileContents(QString *error) const
-{
-    QFile proFileOnDisk(m_proFileName);
-    if (!proFileOnDisk.open(QIODevice::WriteOnly)) {
-        *error = tr("Project file '%1' could not be opened for writing.")
-            .arg(m_proFileName);
-        resetProFileContents();
-        return false;
-    }
-
-    // TODO: Disconnect and reconnect FS watcher here.
-    proFileOnDisk.write(m_proFileLines.join("\n").toLatin1());
-    proFileOnDisk.close();
-    if (proFileOnDisk.error() != QFile::NoError) {
-        *error = tr("Project file '%1' could not be written.")
-            .arg(m_proFileName);
-        resetProFileContents();
-        return false;
-    }
-    m_modified = true;
-    return true;
-}
-
-QString MaemoPackageContents::cleanPath(const QString &relFileName) const
-{
-    // I'd rather use QDir::cleanPath(), but that doesn't work well
-    // enough for redundant ".." dirs.
-    return QFileInfo(m_proFile->directoryName() + '/'
-        + relFileName).canonicalFilePath();
+    return buildModel() ? deployableAt(0).remoteDir + '/'
+        + m_packageStep->executableFileName() : QString();
 }
 
 QString MaemoPackageContents::findInstallsElem(const MaemoDeployable &deployable) const
 {
-    const QStringList elems = m_proFileReader->values(InstallsVar, m_proFile);
+    QSharedPointer<ProFileWrapper> proFileWrapper
+        = m_packageStep->proFileWrapper();
+    const QStringList &elems = proFileWrapper->varValues(InstallsVar);
     foreach (const QString &elem, elems) {
-        const QStringList elemPaths
-            = m_proFileReader->values(pathVar(elem), m_proFile);
+        const QStringList elemPaths = proFileWrapper->varValues(pathVar(elem));
         if (elemPaths.count() != 1 || elemPaths.first() != deployable.remoteDir)
             continue;
         if (elem == TargetVar)
             return elem;
-        const QStringList elemFiles
-            = m_proFileReader->values(filesVar(elem), m_proFile);
+        const QStringList elemFiles = proFileWrapper->varValues(filesVar(elem));
         foreach (const QString &file, elemFiles) {
-            if (cleanPath(file) == deployable.localFilePath)
+            if (proFileWrapper->absFilePath(file) == deployable.localFilePath)
                 return elem;
         }
     }
     return QString();
 }
 
-void MaemoPackageContents::addFileToProFile(const QString &var,
-    const QString &absFilePath)
-{
-    ProWriter::addFiles(m_proFile, &m_proFileLines, m_proDir,
-        QStringList(absFilePath), var);
-    parseProFile(ParseFromLines);
-}
-
-void MaemoPackageContents::addValueToProFile(const QString &var,
-    const QString &value) const
-{
-    ProWriter::addVarValues(m_proFile, &m_proFileLines, m_proDir,
-        QStringList(value), var);
-    parseProFile(ParseFromLines);
-}
-
-bool MaemoPackageContents::removeFileFromProFile(const QString &var,
-    const QString &absFilePath)
-{
-    const bool success = ProWriter::removeFiles(m_proFile, &m_proFileLines,
-        m_proDir, QStringList(absFilePath),
-        QStringList(var)).isEmpty();
-    if (success)
-        parseProFile(ParseFromLines);
-    else
-        resetProFileContents();
-    return success;
-}
-
-bool MaemoPackageContents::removeValueFromProFile(const QString &var,
-    const QString &value)
-{
-    const bool success = ProWriter::removeVarValues(m_proFile,
-        &m_proFileLines, m_proDir, QStringList(value),
-        QStringList(var)).isEmpty();
-    if (success)
-        parseProFile(ParseFromLines);
-    else
-        resetProFileContents();
-    return success;
-}
-
-void MaemoPackageContents::parseProFile(ParseType type) const
-{
-    if (type == ParseFromLines) {
-        m_proFile = m_proFileReader->parsedProFile(m_proFileName, false,
-            m_proFileLines.join("\n"));
-    } else {
-        m_proFile = 0;
-        if (ProFile *pro = m_proFileReader->parsedProFile(m_proFileName)) {
-            if (m_proFileReader->accept(pro))
-                m_proFile = pro;
-            pro->deref();
-        }
-    }
-}
-
-void MaemoPackageContents::resetProFileContents() const
-{
-    m_proFileLines.clear();
-    parseProFile(ParseFromFile);
-    if (!m_proFile)
-        qWarning("Fatal: Could not parse .pro file '%s'.",
-            qPrintable(m_proFileName));
-}
-
 } // namespace Qt4ProjectManager
 } // namespace Internal
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecontents.h b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecontents.h
index d5d491d67315c8305daf037a48ae33aede850cba..079cd325a9dc46f1c7227f0ae42cd21334b423a6 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecontents.h
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecontents.h
@@ -31,17 +31,9 @@
 #define MAEMOPACKAGECONTENTS_H
 
 #include <QtCore/QAbstractTableModel>
-#include <QtCore/QDir>
 #include <QtCore/QHash>
 #include <QtCore/QList>
-#include <QtCore/QScopedPointer>
 #include <QtCore/QString>
-#include <QtCore/QStringList>
-
-QT_BEGIN_NAMESPACE
-class ProFile;
-struct ProFileOption;
-QT_END_NAMESPACE
 
 namespace Qt4ProjectManager {
 namespace Internal {
@@ -75,8 +67,6 @@ public:
     MaemoPackageContents(MaemoPackageCreationStep *packageStep);
     ~MaemoPackageContents();
 
-    bool init();
-
     virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
 
     MaemoDeployable deployableAt(int row) const;
@@ -98,29 +88,13 @@ private:
 
     bool buildModel() const;
     void resetProFileContents() const;
-    bool readProFileContents(QString *error) const;
-    bool writeProFileContents(QString *error) const;
-
-    QString cleanPath(const QString &relFileName) const;
 
     QString findInstallsElem(const MaemoDeployable &deployable) const;
-    void addFileToProFile(const QString &var, const QString &absFilePath);
-    void addValueToProFile(const QString &var, const QString &value) const;
-    bool removeFileFromProFile(const QString &var, const QString &absFilePath);
-    bool removeValueFromProFile(const QString &var, const QString &value);
-
-    enum ParseType { ParseFromFile, ParseFromLines };
-    void parseProFile(ParseType type) const;
 
     const MaemoPackageCreationStep * const m_packageStep;
-    QScopedPointer<ProFileOption> m_proFileOption;
-    QScopedPointer<ProFileReader> m_proFileReader;
     mutable QList<MaemoDeployable> m_deployables;
     mutable bool m_modified;
-    mutable ProFile *m_proFile;
-    mutable QStringList m_proFileLines; // TODO: FS watcher
-    mutable QString m_proFileName;
-    mutable QDir m_proDir;
+    mutable bool m_initialized;
 };
 
 } // namespace Qt4ProjectManager
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.cpp
index 861c0a9738e85d09994e503befda5d1d6e58a866..31e9297f1c33fbb23bcaf79508a20673461ba8a8 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.cpp
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.cpp
@@ -45,6 +45,7 @@
 #include "maemopackagecreationwidget.h"
 #include "maemopackagecontents.h"
 #include "maemotoolchain.h"
+#include "profilewrapper.h"
 
 #include <projectexplorer/projectexplorerconstants.h>
 #include <qt4buildconfiguration.h>
@@ -90,6 +91,8 @@ MaemoPackageCreationStep::MaemoPackageCreationStep(BuildConfiguration *buildConf
 {
 }
 
+MaemoPackageCreationStep::~MaemoPackageCreationStep() {}
+
 bool MaemoPackageCreationStep::init()
 {
     return true;
@@ -364,6 +367,18 @@ void MaemoPackageCreationStep::raiseError(const QString &shortMsg,
                       TASK_CATEGORY_BUILDSYSTEM));
 }
 
+QSharedPointer<ProFileWrapper> MaemoPackageCreationStep::proFileWrapper() const
+{
+    if (!m_proFileWrapper) {
+        const Qt4ProFileNode * const proFileNode = qt4BuildConfiguration()
+            ->qt4Target()->qt4Project()->rootProjectNode();
+        m_proFileWrapper = QSharedPointer<ProFileWrapper>(
+            new ProFileWrapper(proFileNode->path()));
+    }
+
+    return m_proFileWrapper;
+}
+
 const QLatin1String MaemoPackageCreationStep::CreatePackageId("Qt4ProjectManager.MaemoPackageCreationStep");
 
 } // namespace Internal
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.h b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.h
index 92241e650229a7cfe8a2772ca59664c9f426f560..58bc96644304b9e5e338cb069b1b8dd644280d4b 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.h
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.h
@@ -44,6 +44,8 @@
 
 #include <projectexplorer/buildstep.h>
 
+#include <QtCore/QSharedPointer>
+
 QT_BEGIN_NAMESPACE
 class QFile;
 class QProcess;
@@ -54,6 +56,7 @@ namespace Internal {
 
 class MaemoPackageContents;
 class MaemoToolChain;
+class ProFileWrapper;
 class Qt4BuildConfiguration;
 
 class MaemoPackageCreationStep : public ProjectExplorer::BuildStep
@@ -62,12 +65,14 @@ class MaemoPackageCreationStep : public ProjectExplorer::BuildStep
     friend class MaemoPackageCreationFactory;
 public:
     MaemoPackageCreationStep(ProjectExplorer::BuildConfiguration *buildConfig);
+    ~MaemoPackageCreationStep();
 
     QString packageFilePath() const;
     QString localExecutableFilePath() const;
     QString executableFileName() const;
     MaemoPackageContents *packageContents() const { return m_packageContents; }
     const Qt4BuildConfiguration *qt4BuildConfiguration() const;
+    QSharedPointer<ProFileWrapper> proFileWrapper() const;
 
     bool isPackagingEnabled() const { return m_packagingEnabled; }
     void setPackagingEnabled(bool enabled) { m_packagingEnabled = enabled; }
@@ -101,6 +106,7 @@ private:
     MaemoPackageContents *const m_packageContents;
     bool m_packagingEnabled;
     QString m_versionString;
+    mutable QSharedPointer<ProFileWrapper> m_proFileWrapper;
 };
 
 } // namespace Internal
diff --git a/src/plugins/qt4projectmanager/qt-maemo/profilewrapper.cpp b/src/plugins/qt4projectmanager/qt-maemo/profilewrapper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..392660006568d2281e0f7c8df77276065585ef4f
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-maemo/profilewrapper.cpp
@@ -0,0 +1,159 @@
+#include "profilewrapper.h"
+
+#include <prowriter.h>
+#include <qt4projectmanager/profilereader.h>
+
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+
+namespace Qt4ProjectManager {
+namespace Internal {
+
+ProFileWrapper::ProFileWrapper(const QString &proFileName)
+    : m_proFileName(proFileName), m_proDir(QFileInfo(m_proFileName).dir()),
+      m_proFileOption(new ProFileOption)
+{
+    parseProFile(ParseFromFile);
+}
+
+ProFileWrapper::~ProFileWrapper() {}
+
+QStringList ProFileWrapper::varValues(const QString &var) const
+{
+    return m_proFileReader->values(var, m_proFile);
+}
+
+bool ProFileWrapper::addVarValue(const QString &var, const QString &value)
+{
+    if (!readProFileContents())
+        return false;
+    ProWriter::addVarValues(m_proFile, &m_proFileContents, m_proDir,
+        QStringList(value), var);
+    parseProFile(ParseFromLines);
+    return writeProFileContents();
+}
+
+bool ProFileWrapper::addFile(const QString &var, const QString &absFilePath)
+{
+    if (!readProFileContents())
+        return false;
+    ProWriter::addFiles(m_proFile, &m_proFileContents, m_proDir,
+        QStringList(absFilePath), var);
+    parseProFile(ParseFromLines);
+    return writeProFileContents();
+}
+
+bool ProFileWrapper::removeVarValue(const QString &var, const QString &value)
+{
+    if (!readProFileContents())
+        return false;
+    const bool success = ProWriter::removeVarValues(m_proFile,
+        &m_proFileContents, m_proDir, QStringList(value), QStringList(var))
+        .isEmpty();
+    if (success) {
+        parseProFile(ParseFromLines);
+        return writeProFileContents();
+    } else {
+        parseProFile(ParseFromFile);
+        return false;
+    }
+}
+
+bool ProFileWrapper::removeFile(const QString &var, const QString &absFilePath)
+{
+    if (!readProFileContents())
+        return false;
+    const bool success = ProWriter::removeFiles(m_proFile, &m_proFileContents,
+        m_proDir, QStringList(absFilePath), QStringList(var)).isEmpty();
+    if (success) {
+        parseProFile(ParseFromLines);
+        return writeProFileContents();
+    } else {
+        parseProFile(ParseFromFile);
+        return false;
+    }
+}
+
+bool ProFileWrapper::replaceVarValue(const QString &var,
+    const QString &oldValue, const QString &newValue)
+{
+    if (!readProFileContents())
+        return false;
+    const bool success = ProWriter::removeVarValues(m_proFile,
+        &m_proFileContents, m_proDir, QStringList(oldValue), QStringList(var))
+        .isEmpty();
+    if (!success) {
+        parseProFile(ParseFromFile);
+        return false;
+    }
+    ProWriter::addVarValues(m_proFile, &m_proFileContents, m_proDir,
+        QStringList(newValue), var);
+    parseProFile(ParseFromLines);
+    return writeProFileContents();
+}
+
+QString ProFileWrapper::absFilePath(const QString &relFilePath) const
+{
+    // I'd rather use QDir::cleanPath(), but that doesn't work well
+    // enough for redundant ".." dirs.
+    return QFileInfo(m_proFile->directoryName() + '/' + relFilePath)
+        .canonicalFilePath();
+}
+
+void ProFileWrapper::parseProFile(ParseType type) const
+{
+    m_proFileReader.reset(new ProFileReader(m_proFileOption.data()));
+    if (type == ParseFromLines) {
+        m_proFile = m_proFileReader->parsedProFile(m_proFileName, false,
+            m_proFileContents.join("\n"));
+    } else {
+        m_proFileContents.clear();
+        m_proFile = m_proFileReader->parsedProFile(m_proFileName);
+    }
+
+    if (!m_proFile) {
+        qWarning("Fatal: Could not parse .pro file '%s'.",
+            qPrintable(m_proFileName));
+        return;
+    }
+
+    m_proFileReader->accept(m_proFile);
+    m_proFile->deref();
+}
+
+bool ProFileWrapper::writeProFileContents()
+{
+    QFile proFileOnDisk(m_proFileName);
+    if (!proFileOnDisk.open(QIODevice::WriteOnly)) {
+        parseProFile(ParseFromFile);
+        return false;
+    }
+
+    // TODO: Disconnect and reconnect FS watcher here.
+    proFileOnDisk.write(m_proFileContents.join("\n").toLatin1());
+    proFileOnDisk.close();
+    if (proFileOnDisk.error() != QFile::NoError) {
+        parseProFile(ParseFromFile);
+        return false;
+    }
+    return true;
+}
+
+bool ProFileWrapper::readProFileContents()
+{
+    if (!m_proFileContents.isEmpty())
+        return true;
+
+    QFile proFileOnDisk(m_proFileName);
+    if (!proFileOnDisk.open(QIODevice::ReadOnly))
+        return false;
+    const QString proFileContents
+        = QString::fromLatin1(proFileOnDisk.readAll());
+    if (proFileOnDisk.error() != QFile::NoError)
+        return false;
+    m_proFileContents = proFileContents.split('\n');
+    return true;
+}
+
+} // namespace Internal
+} // namespace Qt4ProjectManager
diff --git a/src/plugins/qt4projectmanager/qt-maemo/profilewrapper.h b/src/plugins/qt4projectmanager/qt-maemo/profilewrapper.h
new file mode 100644
index 0000000000000000000000000000000000000000..60a72c30c097ca95c03546d965d455b534dc9428
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-maemo/profilewrapper.h
@@ -0,0 +1,51 @@
+#ifndef PROFILEWRAPPER_H
+#define PROFILEWRAPPER_H
+
+#include <QtCore/QDir>
+#include <QtCore/QScopedPointer>
+#include <QtCore/QString>
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+class ProFile;
+struct ProFileOption;
+QT_END_NAMESPACE
+
+namespace Qt4ProjectManager {
+namespace Internal {
+class ProFileReader;
+
+class ProFileWrapper
+{
+public:
+    ProFileWrapper(const QString &proFileName);
+    ~ProFileWrapper();
+
+    // TODO: Higher-level versions of these specifically for INSTALLS vars
+    QStringList varValues(const QString &var) const;
+    bool addVarValue(const QString &var, const QString &value);
+    bool addFile(const QString &var, const QString &absFilePath);
+    bool removeVarValue(const QString &var, const QString &value);
+    bool removeFile(const QString &var, const QString &absFilePath);
+    bool replaceVarValue(const QString &var, const QString &oldValue,
+        const QString &newValue);
+    QString absFilePath(const QString &relFilePath) const;
+
+private:
+    enum ParseType { ParseFromFile, ParseFromLines };
+    void parseProFile(ParseType type) const;
+    bool writeProFileContents();
+    bool readProFileContents();
+
+    const QString m_proFileName;
+    const QDir m_proDir;
+    mutable QStringList m_proFileContents;
+    QScopedPointer<ProFileOption> m_proFileOption;
+    mutable QScopedPointer<ProFileReader> m_proFileReader;
+    mutable ProFile *m_proFile;
+};
+
+} // namespace Internal
+} // namespace Qt4ProjectManager
+
+#endif // PROFILEWRAPPER_H
diff --git a/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri
index 61b754b138fc3a78e8df93c7456b27ed42553abc..2a0d8e02f178df3589aca17a968fc6517abb7748 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri
+++ b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri
@@ -16,7 +16,8 @@ HEADERS += \
     $$PWD/maemopackagecreationfactory.h \
     $$PWD/maemopackagecreationwidget.h \
     $$PWD/maemopackagecontents.h \
-    $$PWD/qemuruntimemanager.h
+    $$PWD/qemuruntimemanager.h \
+    $$PWD/profilewrapper.h
 
 SOURCES += \
     $$PWD/maemoconfigtestdialog.cpp \
@@ -35,7 +36,8 @@ SOURCES += \
     $$PWD/maemopackagecreationfactory.cpp \
     $$PWD/maemopackagecreationwidget.cpp \
     $$PWD/maemopackagecontents.cpp \
-    $$PWD/qemuruntimemanager.cpp
+    $$PWD/qemuruntimemanager.cpp \
+    $$PWD/profilewrapper.cpp
 
 FORMS += \
     $$PWD/maemoconfigtestdialog.ui \