[Pkg-owncloud-commits] [owncloud-client] 29/498: Pass SyncFileItems by pointer instead of by value

Sandro Knauß hefee-guest at moszumanska.debian.org
Tue Aug 11 14:48:30 UTC 2015


This is an automated email from the git hooks/post-receive script.

hefee-guest pushed a commit to branch master
in repository owncloud-client.

commit 12d7484b85c92a0c897daf37fa992a330fb91d9f
Author: Jocelyn Turcotte <jturcotte at woboq.com>
Date:   Wed Apr 15 15:19:11 2015 +0200

    Pass SyncFileItems by pointer instead of by value
    
    Use a QSharedPointer to keep the same ownership and
    continue passing the SyncFileItems as a const& when
    ownership isn't taken. This allows sharing the same
    allocations between the jobs and the result vectors.
    
    This saves about 20MB of memory (off 120MB) once all
    jobs are created.
---
 src/gui/folder.cpp                    |  78 +++----
 src/gui/socketapi.cpp                 |   8 +-
 src/libsync/owncloudpropagator.cpp    | 130 ++++++------
 src/libsync/owncloudpropagator.h      |  28 +--
 src/libsync/propagatedownload.cpp     |  78 +++----
 src/libsync/propagatedownload.h       |   2 +-
 src/libsync/propagateremotedelete.cpp |  18 +-
 src/libsync/propagateremotedelete.h   |   2 +-
 src/libsync/propagateremotemkdir.cpp  |  28 +--
 src/libsync/propagateremotemkdir.h    |   2 +-
 src/libsync/propagateremotemove.cpp   |  32 +--
 src/libsync/propagateremotemove.h     |   2 +-
 src/libsync/propagateupload.cpp       | 128 ++++++------
 src/libsync/propagateupload.h         |   6 +-
 src/libsync/propagator_legacy.cpp     |   8 +-
 src/libsync/propagatorjobs.cpp        |  44 ++--
 src/libsync/propagatorjobs.h          |   6 +-
 src/libsync/syncengine.cpp            | 382 ++++++++++++++++------------------
 src/libsync/syncengine.h              |   4 +-
 src/libsync/syncfileitem.h            |   8 +-
 20 files changed, 493 insertions(+), 501 deletions(-)

diff --git a/src/gui/folder.cpp b/src/gui/folder.cpp
index 0b37518..96713d0 100644
--- a/src/gui/folder.cpp
+++ b/src/gui/folder.cpp
@@ -337,11 +337,11 @@ void Folder::bubbleUpSyncResult()
     int renamedItems = 0;
     int errorItems = 0;
 
-    SyncFileItem firstItemNew;
-    SyncFileItem firstItemDeleted;
-    SyncFileItem firstItemUpdated;
-    SyncFileItem firstItemRenamed;
-    SyncFileItem firstItemError;
+    SyncFileItemPtr firstItemNew;
+    SyncFileItemPtr firstItemDeleted;
+    SyncFileItemPtr firstItemUpdated;
+    SyncFileItemPtr firstItemRenamed;
+    SyncFileItemPtr firstItemError;
 
     SyncRunFileLog syncFileLog;
 
@@ -350,52 +350,52 @@ void Folder::bubbleUpSyncResult()
     QElapsedTimer timer;
     timer.start();
 
-    foreach (const SyncFileItem &item, _syncResult.syncFileItemVector() ) {
+    foreach (const SyncFileItemPtr &item, _syncResult.syncFileItemVector() ) {
         // Log the item
-        syncFileLog.logItem( item );
+        syncFileLog.logItem( *item );
 
         // and process the item to the gui
-        if( item._status == SyncFileItem::FatalError || item._status == SyncFileItem::NormalError ) {
-            slotSyncError( tr("%1: %2").arg(item._file, item._errorString) );
+        if( item->_status == SyncFileItem::FatalError || item->_status == SyncFileItem::NormalError ) {
+            slotSyncError( tr("%1: %2").arg(item->_file, item->_errorString) );
             errorItems++;
-            if (firstItemError.isEmpty()) {
+            if (!firstItemError) {
                 firstItemError = item;
             }
-        } else if( item._status == SyncFileItem::FileIgnored ) {
+        } else if( item->_status == SyncFileItem::FileIgnored ) {
             // ignored files don't show up in notifications
             continue;
         } else {
             // add new directories or remove gone away dirs to the watcher
-            if (item._isDirectory && item._instruction == CSYNC_INSTRUCTION_NEW ) {
-                FolderMan::instance()->addMonitorPath( alias(), path()+item._file );
+            if (item->_isDirectory && item->_instruction == CSYNC_INSTRUCTION_NEW ) {
+                FolderMan::instance()->addMonitorPath( alias(), path()+item->_file );
             }
-            if (item._isDirectory && item._instruction == CSYNC_INSTRUCTION_REMOVE ) {
-                FolderMan::instance()->removeMonitorPath( alias(), path()+item._file );
+            if (item->_isDirectory && item->_instruction == CSYNC_INSTRUCTION_REMOVE ) {
+                FolderMan::instance()->removeMonitorPath( alias(), path()+item->_file );
             }
 
-            if (!item.hasErrorStatus() && item._direction == SyncFileItem::Down) {
-                switch (item._instruction) {
+            if (!item->hasErrorStatus() && item->_direction == SyncFileItem::Down) {
+                switch (item->_instruction) {
                 case CSYNC_INSTRUCTION_NEW:
                     newItems++;
-                    if (firstItemNew.isEmpty())
+                    if (!firstItemNew)
                         firstItemNew = item;
                     break;
                 case CSYNC_INSTRUCTION_REMOVE:
                     removedItems++;
-                    if (firstItemDeleted.isEmpty())
+                    if (!firstItemDeleted)
                         firstItemDeleted = item;
                     break;
                 case CSYNC_INSTRUCTION_CONFLICT:
                 case CSYNC_INSTRUCTION_SYNC:
                     updatedItems++;
-                    if (firstItemUpdated.isEmpty())
+                    if (!firstItemUpdated)
                         firstItemUpdated = item;
                     break;
                 case CSYNC_INSTRUCTION_ERROR:
                     qDebug() << "Got Instruction ERROR. " << _syncResult.errorString();
                     break;
                 case CSYNC_INSTRUCTION_RENAME:
-                    if (firstItemRenamed.isEmpty()) {
+                    if (!firstItemRenamed) {
                         firstItemRenamed = item;
                     }
                     renamedItems++;
@@ -404,8 +404,8 @@ void Folder::bubbleUpSyncResult()
                     // nothing.
                     break;
                 }
-            } else if( item._direction == SyncFileItem::None ) { // ignored files counting.
-                if( item._instruction == CSYNC_INSTRUCTION_IGNORE ) {
+            } else if( item->_direction == SyncFileItem::None ) { // ignored files counting.
+                if( item->_instruction == CSYNC_INSTRUCTION_IGNORE ) {
                     ignoredItems++;
                 }
             }
@@ -416,28 +416,28 @@ void Folder::bubbleUpSyncResult()
     qDebug() << "Processing result list and logging took " << timer.elapsed() << " Milliseconds.";
     _syncResult.setWarnCount(ignoredItems);
 
-    if( !firstItemNew.isEmpty() ) {
-        createGuiLog( firstItemNew._file,     SyncFileStatus::STATUS_NEW, newItems );
+    if( firstItemNew ) {
+        createGuiLog( firstItemNew->_file,     SyncFileStatus::STATUS_NEW, newItems );
     }
-    if( !firstItemDeleted.isEmpty() ) {
-        createGuiLog( firstItemDeleted._file, SyncFileStatus::STATUS_REMOVE, removedItems );
+    if( firstItemDeleted ) {
+        createGuiLog( firstItemDeleted->_file, SyncFileStatus::STATUS_REMOVE, removedItems );
     }
-    if( ! firstItemUpdated.isEmpty() ) {
-        createGuiLog( firstItemUpdated._file, SyncFileStatus::STATUS_UPDATED, updatedItems );
+    if( firstItemUpdated ) {
+        createGuiLog( firstItemUpdated->_file, SyncFileStatus::STATUS_UPDATED, updatedItems );
     }
 
-    if( !firstItemRenamed.isEmpty() ) {
+    if( firstItemRenamed ) {
         SyncFileStatus status(SyncFileStatus::STATUS_RENAME);
         // if the path changes it's rather a move
-        QDir renTarget = QFileInfo(firstItemRenamed._renameTarget).dir();
-        QDir renSource = QFileInfo(firstItemRenamed._file).dir();
+        QDir renTarget = QFileInfo(firstItemRenamed->_renameTarget).dir();
+        QDir renSource = QFileInfo(firstItemRenamed->_file).dir();
         if(renTarget != renSource) {
             status.set(SyncFileStatus::STATUS_MOVE);
         }
-        createGuiLog( firstItemRenamed._file, status, renamedItems, firstItemRenamed._renameTarget );
+        createGuiLog( firstItemRenamed->_file, status, renamedItems, firstItemRenamed->_renameTarget );
     }
 
-    createGuiLog( firstItemError._file,   SyncFileStatus::STATUS_ERROR, errorItems );
+    createGuiLog( firstItemError->_file,   SyncFileStatus::STATUS_ERROR, errorItems );
 
     qDebug() << "OO folder slotSyncFinished: result: " << int(_syncResult.status());
 }
@@ -578,9 +578,9 @@ QString Folder::configFile()
 }
 
 static void addErroredSyncItemPathsToList(const SyncFileItemVector& items, QSet<QString>* set) {
-    Q_FOREACH(const SyncFileItem &item, items) {
-        if (item.hasErrorStatus()) {
-            set->insert(item._file);
+    Q_FOREACH(const SyncFileItemPtr &item, items) {
+        if (item->hasErrorStatus()) {
+            set->insert(item->_file);
         }
     }
 }
@@ -805,8 +805,8 @@ void Folder::startSync(const QStringList &pathList)
                     SLOT(slotAboutToRemoveAllFiles(SyncFileItem::Direction,bool*)));
     connect(_engine.data(), SIGNAL(folderDiscovered(bool,QString)), this, SLOT(slotFolderDiscovered(bool,QString)));
     connect(_engine.data(), SIGNAL(transmissionProgress(Progress::Info)), this, SLOT(slotTransmissionProgress(Progress::Info)));
-    connect(_engine.data(), SIGNAL(jobCompleted(SyncFileItem)), this, SLOT(slotJobCompleted(SyncFileItem)));
-    connect(_engine.data(), SIGNAL(syncItemDiscovered(SyncFileItem)), this, SLOT(slotSyncItemDiscovered(SyncFileItem)));
+    connect(_engine.data(), SIGNAL(jobCompleted(const SyncFileItem &)), this, SLOT(slotJobCompleted(const SyncFileItem &)));
+    connect(_engine.data(), SIGNAL(syncItemDiscovered(const SyncFileItem &)), this, SLOT(slotSyncItemDiscovered(const SyncFileItem &)));
 
     setDirtyNetworkLimits();
     _engine->setSelectiveSyncBlackList(selectiveSyncBlackList());
diff --git a/src/gui/socketapi.cpp b/src/gui/socketapi.cpp
index 0f42154..af6edba 100644
--- a/src/gui/socketapi.cpp
+++ b/src/gui/socketapi.cpp
@@ -128,10 +128,10 @@ SocketApi::SocketApi(QObject* parent)
 
     // folder watcher
     connect(FolderMan::instance(), SIGNAL(folderSyncStateChange(QString)), this, SLOT(slotUpdateFolderView(QString)));
-    connect(ProgressDispatcher::instance(), SIGNAL(jobCompleted(QString,SyncFileItem)),
-            SLOT(slotJobCompleted(QString,SyncFileItem)));
-    connect(ProgressDispatcher::instance(), SIGNAL(syncItemDiscovered(QString,SyncFileItem)),
-            this, SLOT(slotSyncItemDiscovered(QString,SyncFileItem)));
+    connect(ProgressDispatcher::instance(), SIGNAL(jobCompleted(QString, const SyncFileItem &)),
+            SLOT(slotJobCompleted(QString, const SyncFileItem &)));
+    connect(ProgressDispatcher::instance(), SIGNAL(syncItemDiscovered(QString, const SyncFileItem &)),
+            this, SLOT(slotSyncItemDiscovered(QString, const SyncFileItem &)));
 }
 
 SocketApi::~SocketApi()
diff --git a/src/libsync/owncloudpropagator.cpp b/src/libsync/owncloudpropagator.cpp
index 1ccefaf..49b3d0b 100644
--- a/src/libsync/owncloudpropagator.cpp
+++ b/src/libsync/owncloudpropagator.cpp
@@ -79,15 +79,15 @@ static bool blacklist(SyncJournalDb* journal, const SyncFileItem& item)
 void PropagateItemJob::done(SyncFileItem::Status status, const QString &errorString)
 {
     _state = Finished;
-    if (_item._isRestoration) {
+    if (_item->_isRestoration) {
         if( status == SyncFileItem::Success || status == SyncFileItem::Conflict) {
             status = SyncFileItem::Restoration;
         } else {
-            _item._errorString += tr("; Restoration Failed: %1").arg(errorString);
+            _item->_errorString += tr("; Restoration Failed: %1").arg(errorString);
         }
     } else {
-        if( _item._errorString.isEmpty() ) {
-            _item._errorString = errorString;
+        if( _item->_errorString.isEmpty() ) {
+            _item->_errorString = errorString;
         }
     }
 
@@ -103,20 +103,20 @@ void PropagateItemJob::done(SyncFileItem::Status status, const QString &errorStr
         // do not blacklist in case of soft error or fatal error.
         break;
     case SyncFileItem::NormalError:
-        if (blacklist(_propagator->_journal, _item) && _item._hasBlacklistEntry) {
+        if (blacklist(_propagator->_journal, *_item) && _item->_hasBlacklistEntry) {
             // do not error if the item was, and continues to be, blacklisted
             status = SyncFileItem::FileIgnored;
-            _item._errorString.prepend(tr("Continue blacklisting:") + " ");
+            _item->_errorString.prepend(tr("Continue blacklisting:") + " ");
         }
         break;
     case SyncFileItem::Success:
     case SyncFileItem::Restoration:
-        if( _item._hasBlacklistEntry ) {
+        if( _item->_hasBlacklistEntry ) {
             // wipe blacklist entry.
-            _propagator->_journal->wipeErrorBlacklistEntry(_item._file);
+            _propagator->_journal->wipeErrorBlacklistEntry(_item->_file);
             // remove a blacklist entry in case the file was moved.
-            if( _item._originalFile != _item._file ) {
-                _propagator->_journal->wipeErrorBlacklistEntry(_item._originalFile);
+            if( _item->_originalFile != _item->_file ) {
+                _propagator->_journal->wipeErrorBlacklistEntry(_item->_originalFile);
             }
         }
         break;
@@ -127,9 +127,9 @@ void PropagateItemJob::done(SyncFileItem::Status status, const QString &errorStr
         break;
     }
 
-    _item._status = status;
+    _item->_status = status;
 
-    emit completed(_item);
+    emit completed(*_item);
     emit finished(status);
 }
 
@@ -143,24 +143,24 @@ bool PropagateItemJob::checkForProblemsWithShared(int httpStatusCode, const QStr
 {
     PropagateItemJob *newJob = NULL;
 
-    if( httpStatusCode == 403 && _propagator->isInSharedDirectory(_item._file )) {
-        if( !_item._isDirectory ) {
-            SyncFileItem downloadItem(_item);
-            if (downloadItem._instruction == CSYNC_INSTRUCTION_NEW) {
+    if( httpStatusCode == 403 && _propagator->isInSharedDirectory(_item->_file )) {
+        if( !_item->_isDirectory ) {
+            SyncFileItemPtr downloadItem(new SyncFileItem(*_item));
+            if (downloadItem->_instruction == CSYNC_INSTRUCTION_NEW) {
                 // don't try to recover pushing new files
                 return false;
-            } else if (downloadItem._instruction == CSYNC_INSTRUCTION_SYNC) {
+            } else if (downloadItem->_instruction == CSYNC_INSTRUCTION_SYNC) {
                 // we modified the file locally, jsut create a conflict then
-                downloadItem._instruction = CSYNC_INSTRUCTION_CONFLICT;
+                downloadItem->_instruction = CSYNC_INSTRUCTION_CONFLICT;
 
                 // HACK to avoid continuation: See task #1448:  We do not know the _modtime from the
                 //  server, at this point, so just set the current one. (rather than the one locally)
-                downloadItem._modtime = Utility::qDateTimeToTime_t(QDateTime::currentDateTime());
+                downloadItem->_modtime = Utility::qDateTimeToTime_t(QDateTime::currentDateTime());
             } else {
                 // the file was removed or renamed, just recover the old one
-                downloadItem._instruction = CSYNC_INSTRUCTION_SYNC;
+                downloadItem->_instruction = CSYNC_INSTRUCTION_SYNC;
             }
-            downloadItem._direction = SyncFileItem::Down;
+            downloadItem->_direction = SyncFileItem::Down;
 #ifdef USE_NEON
             newJob = new PropagateDownloadFileLegacy(_propagator, downloadItem);
 #else
@@ -169,20 +169,20 @@ bool PropagateItemJob::checkForProblemsWithShared(int httpStatusCode, const QStr
         } else {
             // Directories are harder to recover.
             // But just re-create the directory, next sync will be able to recover the files
-            SyncFileItem mkdirItem(_item);
-            mkdirItem._instruction = CSYNC_INSTRUCTION_SYNC;
-            mkdirItem._direction = SyncFileItem::Down;
+            SyncFileItemPtr mkdirItem(new SyncFileItem(*_item));
+            mkdirItem->_instruction = CSYNC_INSTRUCTION_SYNC;
+            mkdirItem->_direction = SyncFileItem::Down;
             newJob = new PropagateLocalMkdir(_propagator, mkdirItem);
             // Also remove the inodes and fileid from the db so no further renames are tried for
             // this item.
-            _propagator->_journal->avoidRenamesOnNextSync(_item._file);
+            _propagator->_journal->avoidRenamesOnNextSync(_item->_file);
             _propagator->_anotherSyncNeeded = true;
         }
         if( newJob )  {
             newJob->setRestoreJobMsg(msg);
             _restoreJob.reset(newJob);
-            connect(_restoreJob.data(), SIGNAL(completed(SyncFileItem)),
-                    this, SLOT(slotRestoreJobCompleted(SyncFileItem)));
+            connect(_restoreJob.data(), SIGNAL(completed(const SyncFileItemPtr &)),
+                    this, SLOT(slotRestoreJobCompleted(const SyncFileItemPtr &)));
             QMetaObject::invokeMethod(newJob, "start");
         }
         return true;
@@ -208,25 +208,25 @@ void PropagateItemJob::slotRestoreJobCompleted(const SyncFileItem& item )
 
 // ================================================================================
 
-PropagateItemJob* OwncloudPropagator::createJob(const SyncFileItem& item) {
-    switch(item._instruction) {
+PropagateItemJob* OwncloudPropagator::createJob(const SyncFileItemPtr &item) {
+    switch(item->_instruction) {
         case CSYNC_INSTRUCTION_REMOVE:
-            if (item._direction == SyncFileItem::Down) return new PropagateLocalRemove(this, item);
+            if (item->_direction == SyncFileItem::Down) return new PropagateLocalRemove(this, item);
             else return new PropagateRemoteDelete(this, item);
         case CSYNC_INSTRUCTION_NEW:
-            if (item._isDirectory) {
-                if (item._direction == SyncFileItem::Down) return new PropagateLocalMkdir(this, item);
+            if (item->_isDirectory) {
+                if (item->_direction == SyncFileItem::Down) return new PropagateLocalMkdir(this, item);
                 else return new PropagateRemoteMkdir(this, item);
             }   //fall trough
         case CSYNC_INSTRUCTION_SYNC:
         case CSYNC_INSTRUCTION_CONFLICT:
-            if (item._isDirectory) {
+            if (item->_isDirectory) {
                 // Should we set the mtime?
                 return 0;
             }
 #ifdef USE_NEON
             if (useLegacyJobs()) {
-                if (item._direction != SyncFileItem::Up) {
+                if (item->_direction != SyncFileItem::Up) {
                     return new PropagateDownloadFileLegacy(this, item);
                 } else {
                     return new PropagateUploadFileLegacy(this, item);
@@ -234,14 +234,14 @@ PropagateItemJob* OwncloudPropagator::createJob(const SyncFileItem& item) {
             } else
 #endif
             {
-                if (item._direction != SyncFileItem::Up) {
+                if (item->_direction != SyncFileItem::Up) {
                     return new PropagateDownloadFileQNAM(this, item);
                 } else {
                     return new PropagateUploadFileQNAM(this, item);
                 }
             }
         case CSYNC_INSTRUCTION_RENAME:
-            if (item._direction == SyncFileItem::Up) {
+            if (item->_direction == SyncFileItem::Up) {
                 return new PropagateRemoteMove(this, item);
             } else {
                 return new PropagateLocalRename(this, item);
@@ -269,13 +269,13 @@ void OwncloudPropagator::start(const SyncFileItemVector& items)
     directories.push(qMakePair(QString(), _rootJob.data()));
     QVector<PropagatorJob*> directoriesToRemove;
     QString removedDirectory;
-    foreach(const SyncFileItem &item, items) {
+    foreach(const SyncFileItemPtr &item, items) {
 
-        if (!removedDirectory.isEmpty() && item._file.startsWith(removedDirectory)) {
+        if (!removedDirectory.isEmpty() && item->_file.startsWith(removedDirectory)) {
             // this is an item in a directory which is going to be removed.
             PropagateDirectory *delDirJob = dynamic_cast<PropagateDirectory*>(directoriesToRemove.last());
 
-            if (item._instruction == CSYNC_INSTRUCTION_REMOVE) {
+            if (item->_instruction == CSYNC_INSTRUCTION_REMOVE) {
                 //already taken care of.  (by the removal of the parent directory)
 
                 // increase the number of subjobs that would be there.
@@ -283,7 +283,7 @@ void OwncloudPropagator::start(const SyncFileItemVector& items)
                     delDirJob->increaseAffectedCount();
                 }
                 continue;
-            } else if (item._instruction == CSYNC_INSTRUCTION_NEW && item._isDirectory) {
+            } else if (item->_instruction == CSYNC_INSTRUCTION_NEW && item->_isDirectory) {
                 // create a new directory within a deleted directory? That can happen if the directory
                 // etag were not fetched properly on the previous sync because the sync was aborted
                 // while uploading this directory (which is now removed).  We can ignore it.
@@ -291,39 +291,39 @@ void OwncloudPropagator::start(const SyncFileItemVector& items)
                     delDirJob->increaseAffectedCount();
                 }
                 continue;
-            } else if (item._instruction == CSYNC_INSTRUCTION_IGNORE) {
+            } else if (item->_instruction == CSYNC_INSTRUCTION_IGNORE) {
                 continue;
             }
 
             qWarning() << "WARNING:  Job within a removed directory?  This should not happen!"
-                       << item._file << item._instruction;
+                       << item->_file << item->_instruction;
         }
 
-        while (!item.destination().startsWith(directories.top().first)) {
+        while (!item->destination().startsWith(directories.top().first)) {
             directories.pop();
         }
 
-        if (item._isDirectory) {
+        if (item->_isDirectory) {
             PropagateDirectory *dir = new PropagateDirectory(this, item);
             dir->_firstJob.reset(createJob(item));
-            if (item._instruction == CSYNC_INSTRUCTION_REMOVE) {
+            if (item->_instruction == CSYNC_INSTRUCTION_REMOVE) {
                 //We do the removal of directories at the end, because there might be moves from
                 // this directories that will happen later.
                 directoriesToRemove.append(dir);
-                removedDirectory = item._file + "/";
+                removedDirectory = item->_file + "/";
 
                 // We should not update the etag of parent directories of the removed directory
                 // since it would be done before the actual remove (issue #1845)
                 // NOTE: Currently this means that we don't update those etag at all in this sync,
                 //       but it should not be a problem, they will be updated in the next sync.
                 for (int i = 0; i < directories.size(); ++i) {
-                    directories[i].second->_item._should_update_etag = false;
+                    directories[i].second->_item->_should_update_etag = false;
                 }
             } else {
                 PropagateDirectory* currentDirJob = directories.top().second;
                 currentDirJob->append(dir);
             }
-            directories.push(qMakePair(item.destination() + "/" , dir));
+            directories.push(qMakePair(item->destination() + "/" , dir));
         } else if (PropagateItemJob* current = createJob(item)) {
             directories.top().second->append(current);
         }
@@ -333,8 +333,8 @@ void OwncloudPropagator::start(const SyncFileItemVector& items)
         _rootJob->append(it);
     }
 
-    connect(_rootJob.data(), SIGNAL(completed(SyncFileItem)), this, SIGNAL(completed(SyncFileItem)));
-    connect(_rootJob.data(), SIGNAL(progress(SyncFileItem,quint64)), this, SIGNAL(progress(SyncFileItem,quint64)));
+    connect(_rootJob.data(), SIGNAL(completed(const SyncFileItem &)), this, SIGNAL(completed(const SyncFileItem &)));
+    connect(_rootJob.data(), SIGNAL(progress(const SyncFileItem &,quint64)), this, SIGNAL(progress(const SyncFileItem &,quint64)));
     connect(_rootJob.data(), SIGNAL(finished(SyncFileItem::Status)), this, SLOT(emitFinished()));
     connect(_rootJob.data(), SIGNAL(ready()), this, SLOT(scheduleNextJob()), Qt::QueuedConnection);
 
@@ -616,19 +616,19 @@ void PropagateDirectory::slotSubJobFinished(SyncFileItem::Status status)
 
 void PropagateDirectory::finalize()
 {
-    if (!_item.isEmpty() && _hasError == SyncFileItem::NoStatus) {
-        if( !_item._renameTarget.isEmpty() ) {
-            _item._file = _item._renameTarget;
+    if (!_item->isEmpty() && _hasError == SyncFileItem::NoStatus) {
+        if( !_item->_renameTarget.isEmpty() ) {
+            _item->_file = _item->_renameTarget;
         }
 
-        if (_item._should_update_etag && _item._instruction != CSYNC_INSTRUCTION_REMOVE) {
+        if (_item->_should_update_etag && _item->_instruction != CSYNC_INSTRUCTION_REMOVE) {
             if (PropagateRemoteMkdir* mkdir = qobject_cast<PropagateRemoteMkdir*>(_firstJob.data())) {
                 // special case from MKDIR, get the fileId from the job there
-                if (_item._fileId.isEmpty() && !mkdir->_item._fileId.isEmpty()) {
-                    _item._fileId = mkdir->_item._fileId;
+                if (_item->_fileId.isEmpty() && !mkdir->_item->_fileId.isEmpty()) {
+                    _item->_fileId = mkdir->_item->_fileId;
                 }
             }
-            SyncJournalFileRecord record(_item,  _propagator->_localDir + _item._file);
+            SyncJournalFileRecord record(*_item,  _propagator->_localDir + _item->_file);
             _propagator->_journal->setFileRecord(record);
         }
     }
@@ -649,9 +649,9 @@ void CleanupPollsJob::start()
 
     auto info = _pollInfos.first();
     _pollInfos.pop_front();
-    SyncFileItem item;
-    item._file = info._file;
-    item._modtime = info._modtime;
+    SyncFileItemPtr item(new SyncFileItem);
+    item->_file = info._file;
+    item->_modtime = info._modtime;
     PollJob *job = new PollJob(_account, info._url, item, _journal, _localPath, this);
     connect(job, SIGNAL(finishedSignal()), SLOT(slotPollFinished()));
     job->start();
@@ -661,13 +661,13 @@ void CleanupPollsJob::slotPollFinished()
 {
     PollJob *job = qobject_cast<PollJob *>(sender());
     Q_ASSERT(job);
-    if (job->_item._status == SyncFileItem::FatalError) {
-        emit aborted(job->_item._errorString);
+    if (job->_item->_status == SyncFileItem::FatalError) {
+        emit aborted(job->_item->_errorString);
         return;
-    } else if (job->_item._status != SyncFileItem::Success) {
-        qDebug() << "There was an error with file " << job->_item._file << job->_item._errorString;
+    } else if (job->_item->_status != SyncFileItem::Success) {
+        qDebug() << "There was an error with file " << job->_item->_file << job->_item->_errorString;
     } else {
-        _journal->setFileRecord(SyncJournalFileRecord(job->_item, _localPath + job->_item._file));
+        _journal->setFileRecord(SyncJournalFileRecord(*job->_item, _localPath + job->_item->_file));
     }
     // Continue with the next entry, or finish
     start();
diff --git a/src/libsync/owncloudpropagator.h b/src/libsync/owncloudpropagator.h
index 860eed2..add39be 100644
--- a/src/libsync/owncloudpropagator.h
+++ b/src/libsync/owncloudpropagator.h
@@ -125,11 +125,11 @@ protected:
      * It is displayed in the activity view.
      */
     QString restoreJobMsg() const {
-        return _item._isRestoration ? _item._errorString : QString();
+        return _item->_isRestoration ? _item->_errorString : QString();
     }
     void setRestoreJobMsg( const QString& msg = QString() ) {
-        _item._isRestoration = true;
-        _item._errorString = msg;
+        _item->_isRestoration = true;
+        _item->_errorString = msg;
     }
 
 protected slots:
@@ -139,7 +139,7 @@ private:
     QScopedPointer<PropagateItemJob> _restoreJob;
 
 public:
-    PropagateItemJob(OwncloudPropagator* propagator, const SyncFileItem &item)
+    PropagateItemJob(OwncloudPropagator* propagator, const SyncFileItemPtr &item)
         : PropagatorJob(propagator), _item(item) {}
 
     bool scheduleNextJob() Q_DECL_OVERRIDE {
@@ -151,7 +151,7 @@ public:
         return true;
     }
 
-    SyncFileItem  _item;
+    SyncFileItemPtr  _item;
 
 public slots:
     virtual void start() = 0;
@@ -170,13 +170,13 @@ public:
     // all the sub files or sub directories.
     QVector<PropagatorJob *> _subJobs;
 
-    SyncFileItem _item;
+    SyncFileItemPtr _item;
 
     int _current; // index of the current running job
     int _runningNow; // number of subJob running now
     SyncFileItem::Status _hasError;  // NoStatus,  or NormalError / SoftError if there was an error
 
-    explicit PropagateDirectory(OwncloudPropagator *propagator, const SyncFileItem &item = SyncFileItem())
+    explicit PropagateDirectory(OwncloudPropagator *propagator, const SyncFileItemPtr &item = SyncFileItemPtr(new SyncFileItem))
         : PropagatorJob(propagator)
         , _firstJob(0), _item(item),  _current(-1), _runningNow(0), _hasError(SyncFileItem::NoStatus)
     { }
@@ -199,7 +199,7 @@ public:
     }
 
     void increaseAffectedCount() {
-        _firstJob->_item._affectedItems++;
+        _firstJob->_item->_affectedItems++;
     }
 
     void finalize();
@@ -208,8 +208,8 @@ private slots:
     bool possiblyRunNextJob(PropagatorJob *next) {
         if (next->_state == NotYetStarted) {
             connect(next, SIGNAL(finished(SyncFileItem::Status)), this, SLOT(slotSubJobFinished(SyncFileItem::Status)), Qt::QueuedConnection);
-            connect(next, SIGNAL(completed(SyncFileItem)), this, SIGNAL(completed(SyncFileItem)));
-            connect(next, SIGNAL(progress(SyncFileItem,quint64)), this, SIGNAL(progress(SyncFileItem,quint64)));
+            connect(next, SIGNAL(completed(const SyncFileItem &)), this, SIGNAL(completed(const SyncFileItem &)));
+            connect(next, SIGNAL(progress(const SyncFileItem &,quint64)), this, SIGNAL(progress(const SyncFileItem &,quint64)));
             connect(next, SIGNAL(ready()), this, SIGNAL(ready()));
             _runningNow++;
         }
@@ -224,18 +224,18 @@ private slots:
 class PropagateIgnoreJob : public PropagateItemJob {
     Q_OBJECT
 public:
-    PropagateIgnoreJob(OwncloudPropagator* propagator,const SyncFileItem& item)
+    PropagateIgnoreJob(OwncloudPropagator* propagator,const SyncFileItemPtr& item)
         : PropagateItemJob(propagator, item) {}
     void start() Q_DECL_OVERRIDE {
-        SyncFileItem::Status status = _item._status;
-        done(status == SyncFileItem::NoStatus ? SyncFileItem::FileIgnored : status, _item._errorString);
+        SyncFileItem::Status status = _item->_status;
+        done(status == SyncFileItem::NoStatus ? SyncFileItem::FileIgnored : status, _item->_errorString);
     }
 };
 
 class OwncloudPropagator : public QObject {
     Q_OBJECT
 
-    PropagateItemJob *createJob(const SyncFileItem& item);
+    PropagateItemJob *createJob(const SyncFileItemPtr& item);
     QScopedPointer<PropagateDirectory> _rootJob;
     bool useLegacyJobs();
 
diff --git a/src/libsync/propagatedownload.cpp b/src/libsync/propagatedownload.cpp
index 98a78b4..f251da3 100644
--- a/src/libsync/propagatedownload.cpp
+++ b/src/libsync/propagatedownload.cpp
@@ -280,25 +280,25 @@ void PropagateDownloadFileQNAM::start()
     if (_propagator->_abortRequested.fetchAndAddRelaxed(0))
         return;
 
-    qDebug() << Q_FUNC_INFO << _item._file << _propagator->_activeJobs;
+    qDebug() << Q_FUNC_INFO << _item->_file << _propagator->_activeJobs;
 
     // do a klaas' case clash check.
-    if( _propagator->localFileNameClash(_item._file) ) {
+    if( _propagator->localFileNameClash(_item->_file) ) {
         done( SyncFileItem::NormalError, tr("File %1 can not be downloaded because of a local file name clash!")
-              .arg(QDir::toNativeSeparators(_item._file)) );
+              .arg(QDir::toNativeSeparators(_item->_file)) );
         return;
     }
 
-    emit progress(_item, 0);
+    emit progress(*_item, 0);
 
     QString tmpFileName;
     QByteArray expectedEtagForResume;
-    const SyncJournalDb::DownloadInfo progressInfo = _propagator->_journal->getDownloadInfo(_item._file);
+    const SyncJournalDb::DownloadInfo progressInfo = _propagator->_journal->getDownloadInfo(_item->_file);
     if (progressInfo._valid) {
         // if the etag has changed meanwhile, remove the already downloaded part.
-        if (progressInfo._etag != _item._etag) {
+        if (progressInfo._etag != _item->_etag) {
             QFile::remove(_propagator->getFilePath(progressInfo._tmpfile));
-            _propagator->_journal->setDownloadInfo(_item._file, SyncJournalDb::DownloadInfo());
+            _propagator->_journal->setDownloadInfo(_item->_file, SyncJournalDb::DownloadInfo());
         } else {
             tmpFileName = progressInfo._tmpfile;
             expectedEtagForResume = progressInfo._etag;
@@ -307,7 +307,7 @@ void PropagateDownloadFileQNAM::start()
     }
 
     if (tmpFileName.isEmpty()) {
-        tmpFileName = _item._file;
+        tmpFileName = _item->_file;
         //add a dot at the begining of the filename to hide the file.
         int slashPos = tmpFileName.lastIndexOf('/');
         tmpFileName.insert(slashPos+1, '.');
@@ -325,10 +325,10 @@ void PropagateDownloadFileQNAM::start()
 
     {
         SyncJournalDb::DownloadInfo pi;
-        pi._etag = _item._etag;
+        pi._etag = _item->_etag;
         pi._tmpfile = tmpFileName;
         pi._valid = true;
-        _propagator->_journal->setDownloadInfo(_item._file, pi);
+        _propagator->_journal->setDownloadInfo(_item->_file, pi);
         _propagator->_journal->commit("download file start");
     }
 
@@ -337,27 +337,27 @@ void PropagateDownloadFileQNAM::start()
 
     quint64 startSize = _tmpFile.size();
     if (startSize > 0) {
-        if (startSize == _item._size) {
+        if (startSize == _item->_size) {
             qDebug() << "File is already complete, no need to download";
             downloadFinished();
             return;
         }
     }
 
-    if (_item._directDownloadUrl.isEmpty()) {
+    if (_item->_directDownloadUrl.isEmpty()) {
         // Normal job, download from oC instance
         _job = new GETFileJob(_propagator->account(),
-                            _propagator->_remoteFolder + _item._file,
+                            _propagator->_remoteFolder + _item->_file,
                             &_tmpFile, headers, expectedEtagForResume, startSize);
     } else {
         // We were provided a direct URL, use that one
-        qDebug() << Q_FUNC_INFO << "directDownloadUrl given for " << _item._file << _item._directDownloadUrl;
+        qDebug() << Q_FUNC_INFO << "directDownloadUrl given for " << _item->_file << _item->_directDownloadUrl;
 
-        if (!_item._directDownloadCookies.isEmpty()) {
-            headers["Cookie"] = _item._directDownloadCookies.toUtf8();
+        if (!_item->_directDownloadCookies.isEmpty()) {
+            headers["Cookie"] = _item->_directDownloadCookies.toUtf8();
         }
 
-        QUrl url = QUrl::fromUserInput(_item._directDownloadUrl);
+        QUrl url = QUrl::fromUserInput(_item->_directDownloadUrl);
         _job = new GETFileJob(_propagator->account(),
                               url,
                               &_tmpFile, headers, expectedEtagForResume, startSize);
@@ -383,11 +383,11 @@ void PropagateDownloadFileQNAM::slotGetFinished()
 
     QNetworkReply::NetworkError err = job->reply()->error();
     if (err != QNetworkReply::NoError) {
-        _item._httpErrorCode = job->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+        _item->_httpErrorCode = job->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
 
         // If we sent a 'Range' header and get 416 back, we want to retry
         // without the header.
-        bool badRangeHeader = job->resumeStart() > 0 && _item._httpErrorCode == 416;
+        bool badRangeHeader = job->resumeStart() > 0 && _item->_httpErrorCode == 416;
         if (badRangeHeader) {
             qDebug() << Q_FUNC_INFO << "server replied 416 to our range request, trying again without";
             _propagator->_anotherSyncNeeded = true;
@@ -398,13 +398,13 @@ void PropagateDownloadFileQNAM::slotGetFinished()
         if (_tmpFile.size() == 0 || badRangeHeader) {
             _tmpFile.close();
             _tmpFile.remove();
-            _propagator->_journal->setDownloadInfo(_item._file, SyncJournalDb::DownloadInfo());
+            _propagator->_journal->setDownloadInfo(_item->_file, SyncJournalDb::DownloadInfo());
         }
 
-        if(!_item._directDownloadUrl.isEmpty() && err != QNetworkReply::OperationCanceledError) {
+        if(!_item->_directDownloadUrl.isEmpty() && err != QNetworkReply::OperationCanceledError) {
             // If this was with a direct download, retry without direct download
-            qWarning() << "Direct download of" << _item._directDownloadUrl << "failed. Retrying through owncloud.";
-            _item._directDownloadUrl.clear();
+            qWarning() << "Direct download of" << _item->_directDownloadUrl << "failed. Retrying through owncloud.";
+            _item->_directDownloadUrl.clear();
             start();
             return;
         }
@@ -422,7 +422,7 @@ void PropagateDownloadFileQNAM::slotGetFinished()
 
 
         if (status == SyncFileItem::NoStatus) {
-            status = classifyError(err, _item._httpErrorCode);
+            status = classifyError(err, _item->_httpErrorCode);
         }
         if (badRangeHeader) {
             // Can't do this in classifyError() because 416 without a
@@ -436,15 +436,15 @@ void PropagateDownloadFileQNAM::slotGetFinished()
     if (!job->etag().isEmpty()) {
         // The etag will be empty if we used a direct download URL.
         // (If it was really empty by the server, the GETFileJob will have errored
-        _item._etag = parseEtag(job->etag());
+        _item->_etag = parseEtag(job->etag());
     }
     if (job->lastModified()) {
         // It is possible that the file was modified on the server since we did the discovery phase
         // so make sure we have the up-to-date time
-        _item._modtime = job->lastModified();
+        _item->_modtime = job->lastModified();
     }
-    _item._requestDuration = job->duration();
-    _item._responseTimeStamp = job->responseTimestamp();
+    _item->_requestDuration = job->duration();
+    _item->_responseTimeStamp = job->responseTimestamp();
 
     _tmpFile.close();
     _tmpFile.flush();
@@ -490,23 +490,23 @@ QString makeConflictFileName(const QString &fn, const QDateTime &dt)
 void PropagateDownloadFileQNAM::downloadFinished()
 {
 
-    QString fn = _propagator->getFilePath(_item._file);
+    QString fn = _propagator->getFilePath(_item->_file);
 
     // In case of file name clash, report an error
     // This can happen if another parallel download saved a clashing file.
-    if (_propagator->localFileNameClash(_item._file)) {
+    if (_propagator->localFileNameClash(_item->_file)) {
         done( SyncFileItem::NormalError, tr("File %1 cannot be saved because of a local file name clash!")
-              .arg(QDir::toNativeSeparators(_item._file)) );
+              .arg(QDir::toNativeSeparators(_item->_file)) );
         return;
     }
 
     // In case of conflict, make a backup of the old file
     // Ignore conflicts where both files are binary equal
-    bool isConflict = _item._instruction == CSYNC_INSTRUCTION_CONFLICT
+    bool isConflict = _item->_instruction == CSYNC_INSTRUCTION_CONFLICT
             && !FileSystem::fileEquals(fn, _tmpFile.fileName());
     if (isConflict) {
         QString renameError;
-        QString conflictFileName = makeConflictFileName(fn, Utility::qDateTimeFromTime_t(_item._modtime));
+        QString conflictFileName = makeConflictFileName(fn, Utility::qDateTimeFromTime_t(_item->_modtime));
         if (!FileSystem::rename(fn, conflictFileName, &renameError)) {
             //If the rename fails, don't replace it.
             done(SyncFileItem::SoftError, renameError);
@@ -519,10 +519,10 @@ void PropagateDownloadFileQNAM::downloadFinished()
         _tmpFile.setPermissions(existingFile.permissions());
     }
 
-    FileSystem::setModTime(_tmpFile.fileName(), _item._modtime);
+    FileSystem::setModTime(_tmpFile.fileName(), _item->_modtime);
     // We need to fetch the time again because some file system such as FAT have a less than a second
     // Accuracy, and we really need the time from the file system. (#3103)
-    _item._modtime = FileSystem::getModTime(_tmpFile.fileName());
+    _item->_modtime = FileSystem::getModTime(_tmpFile.fileName());
 
     QString error;
     _propagator->addTouchedFile(fn);
@@ -547,10 +547,10 @@ void PropagateDownloadFileQNAM::downloadFinished()
 
     // Maybe we downloaded a newer version of the file than we thought we would...
     // Get up to date information for the journal.
-    _item._size = FileSystem::getSize(fn);
+    _item->_size = FileSystem::getSize(fn);
 
-    _propagator->_journal->setFileRecord(SyncJournalFileRecord(_item, fn));
-    _propagator->_journal->setDownloadInfo(_item._file, SyncJournalDb::DownloadInfo());
+    _propagator->_journal->setFileRecord(SyncJournalFileRecord(*_item, fn));
+    _propagator->_journal->setDownloadInfo(_item->_file, SyncJournalDb::DownloadInfo());
     _propagator->_journal->commit("download file start2");
     done(isConflict ? SyncFileItem::Conflict : SyncFileItem::Success);
 }
@@ -558,7 +558,7 @@ void PropagateDownloadFileQNAM::downloadFinished()
 void PropagateDownloadFileQNAM::slotDownloadProgress(qint64 received, qint64)
 {
     if (!_job) return;
-    emit progress(_item, received + _job->resumeStart());
+    emit progress(*_item, received + _job->resumeStart());
 }
 
 
diff --git a/src/libsync/propagatedownload.h b/src/libsync/propagatedownload.h
index 47c6070..c63aa2a 100644
--- a/src/libsync/propagatedownload.h
+++ b/src/libsync/propagatedownload.h
@@ -106,7 +106,7 @@ class PropagateDownloadFileQNAM : public PropagateItemJob {
 //  QFile *_file;
     QFile _tmpFile;
 public:
-    PropagateDownloadFileQNAM(OwncloudPropagator* propagator,const SyncFileItem& item)
+    PropagateDownloadFileQNAM(OwncloudPropagator* propagator,const SyncFileItemPtr& item)
         : PropagateItemJob(propagator, item) {}
     void start() Q_DECL_OVERRIDE;
 private slots:
diff --git a/src/libsync/propagateremotedelete.cpp b/src/libsync/propagateremotedelete.cpp
index 15f1c88..5f7fc89 100644
--- a/src/libsync/propagateremotedelete.cpp
+++ b/src/libsync/propagateremotedelete.cpp
@@ -58,10 +58,10 @@ void PropagateRemoteDelete::start()
     if (_propagator->_abortRequested.fetchAndAddRelaxed(0))
         return;
 
-    qDebug() << Q_FUNC_INFO << _item._file;
+    qDebug() << Q_FUNC_INFO << _item->_file;
 
     _job = new DeleteJob(_propagator->account(),
-                         _propagator->_remoteFolder + _item._file,
+                         _propagator->_remoteFolder + _item->_file,
                          this);
     connect(_job, SIGNAL(finishedSignal()), this, SLOT(slotDeleteJobFinished()));
     _propagator->_activeJobs ++;
@@ -86,22 +86,22 @@ void PropagateRemoteDelete::slotDeleteJobFinished()
 
     QNetworkReply::NetworkError err = _job->reply()->error();
     const int httpStatus = _job->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
-    _item._httpErrorCode = httpStatus;
+    _item->_httpErrorCode = httpStatus;
 
     if (err != QNetworkReply::NoError && err != QNetworkReply::ContentNotFoundError) {
 
-        if( checkForProblemsWithShared(_item._httpErrorCode,
+        if( checkForProblemsWithShared(_item->_httpErrorCode,
             tr("The file has been removed from a read only share. It was restored.")) ) {
             return;
         }
 
-        SyncFileItem::Status status = classifyError(err, _item._httpErrorCode);
+        SyncFileItem::Status status = classifyError(err, _item->_httpErrorCode);
         done(status, _job->errorString());
         return;
     }
 
-    _item._requestDuration = _job->duration();
-    _item._responseTimeStamp = _job->responseTimestamp();
+    _item->_requestDuration = _job->duration();
+    _item->_responseTimeStamp = _job->responseTimestamp();
 
     // A 404 reply is also considered a success here: We want to make sure
     // a file is gone from the server. It not being there in the first place
@@ -112,11 +112,11 @@ void PropagateRemoteDelete::slotDeleteJobFinished()
         // If it is not the case, it might be because of a proxy or gateway intercepting the request, so we must
         // throw an error.
         done(SyncFileItem::NormalError, tr("Wrong HTTP code returned by server. Expected 204, but received \"%1 %2\".")
-            .arg(_item._httpErrorCode).arg(_job->reply()->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()));
+            .arg(_item->_httpErrorCode).arg(_job->reply()->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()));
         return;
     }
 
-    _propagator->_journal->deleteFileRecord(_item._originalFile, _item._isDirectory);
+    _propagator->_journal->deleteFileRecord(_item->_originalFile, _item->_isDirectory);
     _propagator->_journal->commit("Remote Remove");
     done(SyncFileItem::Success);
 }
diff --git a/src/libsync/propagateremotedelete.h b/src/libsync/propagateremotedelete.h
index 9a75c9a..e40289d 100644
--- a/src/libsync/propagateremotedelete.h
+++ b/src/libsync/propagateremotedelete.h
@@ -37,7 +37,7 @@ class PropagateRemoteDelete : public PropagateItemJob {
     Q_OBJECT
     QPointer<DeleteJob> _job;
 public:
-    PropagateRemoteDelete (OwncloudPropagator* propagator,const SyncFileItem& item)
+    PropagateRemoteDelete (OwncloudPropagator* propagator,const SyncFileItemPtr& item)
         : PropagateItemJob(propagator, item) {}
     void start() Q_DECL_OVERRIDE;
     void abort() Q_DECL_OVERRIDE;
diff --git a/src/libsync/propagateremotemkdir.cpp b/src/libsync/propagateremotemkdir.cpp
index 1b724da..6d97ec1 100644
--- a/src/libsync/propagateremotemkdir.cpp
+++ b/src/libsync/propagateremotemkdir.cpp
@@ -25,10 +25,10 @@ void PropagateRemoteMkdir::start()
     if (_propagator->_abortRequested.fetchAndAddRelaxed(0))
         return;
 
-    qDebug() << Q_FUNC_INFO << _item._file;
+    qDebug() << Q_FUNC_INFO << _item->_file;
 
     _job = new MkColJob(_propagator->account(),
-                        _propagator->_remoteFolder + _item._file,
+                        _propagator->_remoteFolder + _item->_file,
                         this);
     connect(_job, SIGNAL(finished(QNetworkReply::NetworkError)), this, SLOT(slotMkcolJobFinished()));
     _propagator->_activeJobs++;
@@ -52,32 +52,32 @@ void PropagateRemoteMkdir::slotMkcolJobFinished()
         << (_job->reply()->error() == QNetworkReply::NoError ? QLatin1String("") : _job->reply()->errorString());
 
     QNetworkReply::NetworkError err = _job->reply()->error();
-    _item._httpErrorCode = _job->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+    _item->_httpErrorCode = _job->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
 
-    if (_item._httpErrorCode == 405) {
+    if (_item->_httpErrorCode == 405) {
         // This happens when the directory already exist. Nothing to do.
     } else if (err != QNetworkReply::NoError) {
-        SyncFileItem::Status status = classifyError(err, _item._httpErrorCode);
+        SyncFileItem::Status status = classifyError(err, _item->_httpErrorCode);
         auto errorString = _job->reply()->errorString();
         if (_job->reply()->hasRawHeader("OC-ErrorString")) {
             errorString = _job->reply()->rawHeader("OC-ErrorString");
         }
         done(status, errorString);
         return;
-    } else if (_item._httpErrorCode != 201) {
+    } else if (_item->_httpErrorCode != 201) {
         // Normaly we expect "201 Created"
         // If it is not the case, it might be because of a proxy or gateway intercepting the request, so we must
         // throw an error.
         done(SyncFileItem::NormalError, tr("Wrong HTTP code returned by server. Expected 201, but received \"%1 %2\".")
-            .arg(_item._httpErrorCode).arg(_job->reply()->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()));
+            .arg(_item->_httpErrorCode).arg(_job->reply()->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()));
         return;
     }
 
-    _item._requestDuration = _job->duration();
-    _item._responseTimeStamp = _job->responseTimestamp();
-    _item._fileId = _job->reply()->rawHeader("OC-FileId");
+    _item->_requestDuration = _job->duration();
+    _item->_responseTimeStamp = _job->responseTimestamp();
+    _item->_fileId = _job->reply()->rawHeader("OC-FileId");
 
-    if (_item._fileId.isEmpty()) {
+    if (_item->_fileId.isEmpty()) {
         // Owncloud 7.0.0 and before did not have a header with the file id.
         // (https://github.com/owncloud/core/issues/9000)
         // So we must get the file id using a PROPFIND
@@ -99,10 +99,10 @@ void PropagateRemoteMkdir::propfindResult(const QVariantMap &result)
 {
     _propagator->_activeJobs--;
     if (result.contains("getetag")) {
-        _item._etag = result["getetag"].toByteArray();
+        _item->_etag = result["getetag"].toByteArray();
     }
     if (result.contains("id")) {
-        _item._fileId = result["id"].toByteArray();
+        _item->_fileId = result["id"].toByteArray();
     }
     success();
 }
@@ -117,7 +117,7 @@ void PropagateRemoteMkdir::propfindError()
 void PropagateRemoteMkdir::success()
 {
     // save the file id already so we can detect rename or remove
-    SyncJournalFileRecord record(_item, _propagator->_localDir + _item.destination());
+    SyncJournalFileRecord record(*_item, _propagator->_localDir + _item->destination());
     _propagator->_journal->setFileRecord(record);
 
     done(SyncFileItem::Success);
diff --git a/src/libsync/propagateremotemkdir.h b/src/libsync/propagateremotemkdir.h
index 01f5623..de556b8 100644
--- a/src/libsync/propagateremotemkdir.h
+++ b/src/libsync/propagateremotemkdir.h
@@ -23,7 +23,7 @@ class PropagateRemoteMkdir : public PropagateItemJob {
     QPointer<AbstractNetworkJob> _job;
     friend class PropagateDirectory; // So it can access the _item;
 public:
-    PropagateRemoteMkdir (OwncloudPropagator* propagator,const SyncFileItem& item)
+    PropagateRemoteMkdir (OwncloudPropagator* propagator,const SyncFileItemPtr& item)
         : PropagateItemJob(propagator, item) {}
     void start() Q_DECL_OVERRIDE;
     void abort() Q_DECL_OVERRIDE;
diff --git a/src/libsync/propagateremotemove.cpp b/src/libsync/propagateremotemove.cpp
index c6c45f8..8b9af4e 100644
--- a/src/libsync/propagateremotemove.cpp
+++ b/src/libsync/propagateremotemove.cpp
@@ -64,16 +64,16 @@ void PropagateRemoteMove::start()
     if (_propagator->_abortRequested.fetchAndAddRelaxed(0))
         return;
 
-    qDebug() << Q_FUNC_INFO << _item._file << _item._renameTarget;
+    qDebug() << Q_FUNC_INFO << _item->_file << _item->_renameTarget;
 
-    QString targetFile(_propagator->getFilePath(_item._renameTarget));
+    QString targetFile(_propagator->getFilePath(_item->_renameTarget));
 
-    if (_item._file == _item._renameTarget) {
+    if (_item->_file == _item->_renameTarget) {
         // The parents has been renamed already so there is nothing more to do.
         finalize();
         return;
     }
-    if (_item._file == QLatin1String("Shared") ) {
+    if (_item->_file == QLatin1String("Shared") ) {
         // Before owncloud 7, there was no permissions system. At the time all the shared files were
         // in a directory called "Shared" and were not supposed to be moved, otherwise bad things happens
 
@@ -93,8 +93,8 @@ void PropagateRemoteMove::start()
     }
 
     _job = new MoveJob(_propagator->account(),
-                        _propagator->_remoteFolder + _item._file,
-                        _propagator->_remoteDir + _item._renameTarget,
+                        _propagator->_remoteFolder + _item->_file,
+                        _propagator->_remoteDir + _item->_renameTarget,
                         this);
     connect(_job, SIGNAL(finishedSignal()), this, SLOT(slotMoveJobFinished()));
     _propagator->_activeJobs++;
@@ -119,29 +119,29 @@ void PropagateRemoteMove::slotMoveJobFinished()
         << (_job->reply()->error() == QNetworkReply::NoError ? QLatin1String("") : _job->reply()->errorString());
 
     QNetworkReply::NetworkError err = _job->reply()->error();
-    _item._httpErrorCode = _job->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+    _item->_httpErrorCode = _job->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
 
     if (err != QNetworkReply::NoError) {
 
-        if( checkForProblemsWithShared(_item._httpErrorCode,
+        if( checkForProblemsWithShared(_item->_httpErrorCode,
                 tr("The file was renamed but is part of a read only share. The original file was restored."))) {
             return;
         }
 
-        SyncFileItem::Status status = classifyError(err, _item._httpErrorCode);
+        SyncFileItem::Status status = classifyError(err, _item->_httpErrorCode);
         done(status, _job->errorString());
         return;
     }
 
-    _item._requestDuration = _job->duration();
-    _item._responseTimeStamp = _job->responseTimestamp();
+    _item->_requestDuration = _job->duration();
+    _item->_responseTimeStamp = _job->responseTimestamp();
 
-    if (_item._httpErrorCode != 201 ) {
+    if (_item->_httpErrorCode != 201 ) {
         // Normaly we expect "201 Created"
         // If it is not the case, it might be because of a proxy or gateway intercepting the request, so we must
         // throw an error.
         done(SyncFileItem::NormalError, tr("Wrong HTTP code returned by server. Expected 201, but received \"%1 %2\".")
-            .arg(_item._httpErrorCode).arg(_job->reply()->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()));
+            .arg(_item->_httpErrorCode).arg(_job->reply()->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()));
         return;
     }
 
@@ -151,9 +151,9 @@ void PropagateRemoteMove::slotMoveJobFinished()
 
 void PropagateRemoteMove::finalize()
 {
-    _propagator->_journal->deleteFileRecord(_item._originalFile);
-    SyncJournalFileRecord record(_item, _propagator->getFilePath(_item._renameTarget));
-    record._path = _item._renameTarget;
+    _propagator->_journal->deleteFileRecord(_item->_originalFile);
+    SyncJournalFileRecord record(*_item, _propagator->getFilePath(_item->_renameTarget));
+    record._path = _item->_renameTarget;
 
     _propagator->_journal->setFileRecord(record);
     _propagator->_journal->commit("Remote Rename");
diff --git a/src/libsync/propagateremotemove.h b/src/libsync/propagateremotemove.h
index dad7d75..741b9a4 100644
--- a/src/libsync/propagateremotemove.h
+++ b/src/libsync/propagateremotemove.h
@@ -39,7 +39,7 @@ class PropagateRemoteMove : public PropagateItemJob {
     Q_OBJECT
     QPointer<MoveJob> _job;
 public:
-    PropagateRemoteMove (OwncloudPropagator* propagator,const SyncFileItem& item)
+    PropagateRemoteMove (OwncloudPropagator* propagator,const SyncFileItemPtr& item)
         : PropagateItemJob(propagator, item) {}
     void start() Q_DECL_OVERRIDE;
     void abort() Q_DECL_OVERRIDE;
diff --git a/src/libsync/propagateupload.cpp b/src/libsync/propagateupload.cpp
index ce112c9..cfe57ad 100644
--- a/src/libsync/propagateupload.cpp
+++ b/src/libsync/propagateupload.cpp
@@ -110,19 +110,19 @@ bool PollJob::finished()
 {
     QNetworkReply::NetworkError err = reply()->error();
     if (err != QNetworkReply::NoError) {
-        _item._httpErrorCode = reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
-        _item._status = classifyError(err, _item._httpErrorCode);
-        _item._errorString = reply()->errorString();
+        _item->_httpErrorCode = reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+        _item->_status = classifyError(err, _item->_httpErrorCode);
+        _item->_errorString = reply()->errorString();
 
         if (reply()->hasRawHeader("OC-ErrorString")) {
-            _item._errorString = reply()->rawHeader("OC-ErrorString");
+            _item->_errorString = reply()->rawHeader("OC-ErrorString");
         }
 
-        if (_item._status == SyncFileItem::FatalError || _item._httpErrorCode >= 400) {
-            if (_item._status != SyncFileItem::FatalError
-                    && _item._httpErrorCode != 503) {
+        if (_item->_status == SyncFileItem::FatalError || _item->_httpErrorCode >= 400) {
+            if (_item->_status != SyncFileItem::FatalError
+                    && _item->_httpErrorCode != 503) {
                 SyncJournalDb::PollInfo info;
-                info._file = _item._file;
+                info._file = _item->_file;
                 // no info._url removes it from the database
                 _journal->setPollInfo(info);
                 _journal->commit("remove poll info");
@@ -140,8 +140,8 @@ bool PollJob::finished()
     qDebug() << Q_FUNC_INFO << ">" << jsonData << "<" << reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
     QVariantMap status = QtJson::parse(QString::fromUtf8(jsonData), ok).toMap();
     if (!ok || status.isEmpty()) {
-        _item._errorString = tr("Invalid JSON reply from the poll URL");
-        _item._status = SyncFileItem::NormalError;
+        _item->_errorString = tr("Invalid JSON reply from the poll URL");
+        _item->_status = SyncFileItem::NormalError;
         emit finishedSignal();
         return true;
     }
@@ -151,14 +151,14 @@ bool PollJob::finished()
         return false;
     }
 
-    _item._errorString = status["error"].toString();
-    _item._status = _item._errorString.isEmpty() ? SyncFileItem::Success : SyncFileItem::NormalError;
-    _item._fileId = status["fileid"].toByteArray();
-    _item._etag = status["etag"].toByteArray();
-    _item._responseTimeStamp = responseTimestamp();
+    _item->_errorString = status["error"].toString();
+    _item->_status = _item->_errorString.isEmpty() ? SyncFileItem::Success : SyncFileItem::NormalError;
+    _item->_fileId = status["fileid"].toByteArray();
+    _item->_etag = status["etag"].toByteArray();
+    _item->_responseTimeStamp = responseTimestamp();
 
     SyncJournalDb::PollInfo info;
-    info._file = _item._file;
+    info._file = _item->_file;
     // no info._url removes it from the database
     _journal->setPollInfo(info);
     _journal->commit("remove poll info");
@@ -174,7 +174,7 @@ void PropagateUploadFileQNAM::start()
         return;
     }
 
-    const QString fullFilePath(_propagator->getFilePath(_item._file));
+    const QString fullFilePath(_propagator->getFilePath(_item->_file));
 
     if (!FileSystem::fileExists(fullFilePath)) {
         done(SyncFileItem::SoftError, tr("File Removed"));
@@ -182,14 +182,14 @@ void PropagateUploadFileQNAM::start()
     }
 
     // Update the mtime and size, it might have changed since discovery.
-    _item._modtime = FileSystem::getModTime(fullFilePath);
+    _item->_modtime = FileSystem::getModTime(fullFilePath);
     quint64 fileSize = FileSystem::getSize(fullFilePath);
-    _item._size = fileSize;
+    _item->_size = fileSize;
 
     // But skip the file if the mtime is too close to 'now'!
     // That usually indicates a file that is still being changed
     // or not yet fully copied to the destination.
-    if (fileIsStillChanging(_item)) {
+    if (fileIsStillChanging(*_item)) {
         _propagator->_anotherSyncNeeded = true;
         done(SyncFileItem::SoftError, tr("Local file changed during sync."));
         return;
@@ -197,20 +197,20 @@ void PropagateUploadFileQNAM::start()
 
     _chunkCount = std::ceil(fileSize/double(chunkSize()));
     _startChunk = 0;
-    _transferId = qrand() ^ _item._modtime ^ (_item._size << 16);
+    _transferId = qrand() ^ _item->_modtime ^ (_item->_size << 16);
 
-    const SyncJournalDb::UploadInfo progressInfo = _propagator->_journal->getUploadInfo(_item._file);
+    const SyncJournalDb::UploadInfo progressInfo = _propagator->_journal->getUploadInfo(_item->_file);
 
-    if (progressInfo._valid && Utility::qDateTimeToTime_t(progressInfo._modtime) == _item._modtime ) {
+    if (progressInfo._valid && Utility::qDateTimeToTime_t(progressInfo._modtime) == _item->_modtime ) {
         _startChunk = progressInfo._chunk;
         _transferId = progressInfo._transferid;
-        qDebug() << Q_FUNC_INFO << _item._file << ": Resuming from chunk " << _startChunk;
+        qDebug() << Q_FUNC_INFO << _item->_file << ": Resuming from chunk " << _startChunk;
     }
 
     _currentChunk = 0;
     _duration.start();
 
-    emit progress(_item, 0);
+    emit progress(*_item, 0);
     this->startNextChunk();
 }
 
@@ -362,22 +362,22 @@ void PropagateUploadFileQNAM::startNextChunk()
         // is sent last.
         return;
     }
-    quint64 fileSize = _item._size;
+    quint64 fileSize = _item->_size;
     QMap<QByteArray, QByteArray> headers;
     headers["OC-Total-Length"] = QByteArray::number(fileSize);
     headers["OC-Async"] = "1";
     headers["OC-Chunk-Size"]= QByteArray::number(quint64(chunkSize()));
     headers["Content-Type"] = "application/octet-stream";
-    headers["X-OC-Mtime"] = QByteArray::number(qint64(_item._modtime));
-    if (!_item._etag.isEmpty() && _item._etag != "empty_etag" &&
-            _item._instruction != CSYNC_INSTRUCTION_NEW  // On new files never send a If-Match
+    headers["X-OC-Mtime"] = QByteArray::number(qint64(_item->_modtime));
+    if (!_item->_etag.isEmpty() && _item->_etag != "empty_etag" &&
+            _item->_instruction != CSYNC_INSTRUCTION_NEW  // On new files never send a If-Match
             ) {
         // We add quotes because the owncloud server always add quotes around the etag, and
         //  csync_owncloud.c's owncloud_file_id always strip the quotes.
-        headers["If-Match"] = '"' + _item._etag + '"';
+        headers["If-Match"] = '"' + _item->_etag + '"';
     }
 
-    QString path = _item._file;
+    QString path = _item->_file;
 
     UploadDevice *device = new UploadDevice(&_propagator->_bandwidthManager);
     qint64 chunkStart = 0;
@@ -400,7 +400,7 @@ void PropagateUploadFileQNAM::startNextChunk()
         }
     }
 
-    if (! device->prepareAndOpen(_propagator->getFilePath(_item._file), chunkStart, currentChunkSize)) {
+    if (! device->prepareAndOpen(_propagator->getFilePath(_item->_file), chunkStart, currentChunkSize)) {
         qDebug() << "ERR: Could not prepare upload device: " << device->errorString();
         // Soft error because this is likely caused by the user modifying his files while syncing
         abortWithError( SyncFileItem::SoftError, device->errorString() );
@@ -472,8 +472,8 @@ void PropagateUploadFileQNAM::slotPutFinished()
 
     QNetworkReply::NetworkError err = job->reply()->error();
     if (err != QNetworkReply::NoError) {
-        _item._httpErrorCode = job->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
-        if(checkForProblemsWithShared(_item._httpErrorCode,
+        _item->_httpErrorCode = job->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+        if(checkForProblemsWithShared(_item->_httpErrorCode,
             tr("The file was edited locally but is part of a read only share. "
                "It is restored and your edit is in the conflict file."))) {
             return;
@@ -491,20 +491,20 @@ void PropagateUploadFileQNAM::slotPutFinished()
             errorString = job->reply()->rawHeader("OC-ErrorString");
         }
 
-        if (_item._httpErrorCode == 412) {
+        if (_item->_httpErrorCode == 412) {
             // Precondition Failed:   Maybe the bad etag is in the database, we need to clear the
             // parent folder etag so we won't read from DB next sync.
-            _propagator->_journal->avoidReadFromDbOnNextSync(_item._file);
+            _propagator->_journal->avoidReadFromDbOnNextSync(_item->_file);
             _propagator->_anotherSyncNeeded = true;
         }
 
-        abortWithError(classifyError(err, _item._httpErrorCode), errorString);
+        abortWithError(classifyError(err, _item->_httpErrorCode), errorString);
         return;
     }
 
-    _item._httpErrorCode = job->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+    _item->_httpErrorCode = job->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
     // The server needs some time to process the request and provide with a poll URL
-    if (_item._httpErrorCode == 202) {
+    if (_item->_httpErrorCode == 202) {
         _finished = true;
         QString path =  QString::fromUtf8(job->reply()->rawHeader("OC-Finish-Poll"));
         if (path.isEmpty()) {
@@ -528,7 +528,7 @@ void PropagateUploadFileQNAM::slotPutFinished()
     bool finished = etag.length() > 0;
 
     // Check if the file still exists
-    const QString fullFilePath(_propagator->getFilePath(_item._file));
+    const QString fullFilePath(_propagator->getFilePath(_item->_file));
     if( !FileSystem::fileExists(fullFilePath) ) {
         if (!finished) {
             abortWithError(SyncFileItem::SoftError, tr("The local file was removed during sync."));
@@ -541,11 +541,11 @@ void PropagateUploadFileQNAM::slotPutFinished()
     // compare expected and real modification time of the file and size
     const time_t new_mtime = FileSystem::getModTime(fullFilePath);
     const quint64 new_size = static_cast<quint64>(FileSystem::getSize(fullFilePath));
-    QFileInfo fi(_propagator->getFilePath(_item._file));
-    if (new_mtime != _item._modtime || new_size != _item._size) {
+    QFileInfo fi(_propagator->getFilePath(_item->_file));
+    if (new_mtime != _item->_modtime || new_size != _item->_size) {
         qDebug() << "The local file has changed during upload:"
-                 << "mtime: " << _item._modtime << "<->" << new_mtime
-                 << ", size: " << _item._size << "<->" << new_size
+                 << "mtime: " << _item->_modtime << "<->" << new_mtime
+                 << ", size: " << _item->_size << "<->" << new_size
                  << ", QFileInfo: " << Utility::qDateTimeToTime_t(fi.lastModified()) << fi.lastModified();
         _propagator->_anotherSyncNeeded = true;
         if( !finished ) {
@@ -577,8 +577,8 @@ void PropagateUploadFileQNAM::slotPutFinished()
         }
         pi._chunk = (currentChunk + _startChunk + 1) % _chunkCount ; // next chunk to start with
         pi._transferid = _transferId;
-        pi._modtime =  Utility::qDateTimeFromTime_t(_item._modtime);
-        _propagator->_journal->setUploadInfo(_item._file, pi);
+        pi._modtime =  Utility::qDateTimeFromTime_t(_item->_modtime);
+        _propagator->_journal->setUploadInfo(_item->_file, pi);
         _propagator->_journal->commit("Upload info");
         startNextChunk();
         return;
@@ -589,15 +589,15 @@ void PropagateUploadFileQNAM::slotPutFinished()
     // the file id should only be empty for new files up- or downloaded
     QByteArray fid = job->reply()->rawHeader("OC-FileID");
     if( !fid.isEmpty() ) {
-        if( !_item._fileId.isEmpty() && _item._fileId != fid ) {
-            qDebug() << "WARN: File ID changed!" << _item._fileId << fid;
+        if( !_item->_fileId.isEmpty() && _item->_fileId != fid ) {
+            qDebug() << "WARN: File ID changed!" << _item->_fileId << fid;
         }
-        _item._fileId = fid;
+        _item->_fileId = fid;
     }
 
-    _item._etag = etag;
+    _item->_etag = etag;
 
-    _item._responseTimeStamp = job->responseTimestamp();
+    _item->_responseTimeStamp = job->responseTimestamp();
 
     if (job->reply()->rawHeader("X-OC-MTime") != "accepted") {
         // X-OC-MTime is supported since owncloud 5.0.   But not when chunking.
@@ -612,21 +612,21 @@ void PropagateUploadFileQNAM::slotPutFinished()
         // Well, the mtime was not set
 #endif
     }
-    finalize(_item);
+    finalize(*_item);
 }
 
 void PropagateUploadFileQNAM::finalize(const SyncFileItem &copy)
 {
     // Normally, copy == _item,   but when it comes from the UpdateMTimeAndETagJob, we need to do
     // some updates
-    _item._etag = copy._etag;
-    _item._fileId = copy._fileId;
+    _item->_etag = copy._etag;
+    _item->_fileId = copy._fileId;
 
-    _item._requestDuration = _duration.elapsed();
+    _item->_requestDuration = _duration.elapsed();
 
-    _propagator->_journal->setFileRecord(SyncJournalFileRecord(_item, _propagator->getFilePath(_item._file)));
+    _propagator->_journal->setFileRecord(SyncJournalFileRecord(*_item, _propagator->getFilePath(_item->_file)));
     // Remove from the progress database:
-    _propagator->_journal->setUploadInfo(_item._file, SyncJournalDb::UploadInfo());
+    _propagator->_journal->setUploadInfo(_item->_file, SyncJournalDb::UploadInfo());
     _propagator->_journal->commit("upload file start");
 
     _finished = true;
@@ -658,7 +658,7 @@ void PropagateUploadFileQNAM::slotUploadProgress(qint64 sent, qint64 total)
         // sender() is the only current job, no need to look at the byteWritten properties
         amount += sent;
     }
-    emit progress(_item, amount);
+    emit progress(*_item, amount);
 }
 
 void PropagateUploadFileQNAM::startPollJob(const QString& path)
@@ -667,9 +667,9 @@ void PropagateUploadFileQNAM::startPollJob(const QString& path)
                                _propagator->_journal, _propagator->_localDir, this);
     connect(job, SIGNAL(finishedSignal()), SLOT(slotPollFinished()));
     SyncJournalDb::PollInfo info;
-    info._file = _item._file;
+    info._file = _item->_file;
     info._url = path;
-    info._modtime = _item._modtime;
+    info._modtime = _item->_modtime;
     _propagator->_journal->setPollInfo(info);
     _propagator->_journal->commit("add poll info");
     _propagator->_activeJobs++;
@@ -683,13 +683,13 @@ void PropagateUploadFileQNAM::slotPollFinished()
 
     _propagator->_activeJobs--;
 
-    if (job->_item._status != SyncFileItem::Success) {
+    if (job->_item->_status != SyncFileItem::Success) {
         _finished = true;
-        done(job->_item._status, job->_item._errorString);
+        done(job->_item->_status, job->_item->_errorString);
         return;
     }
 
-    finalize(job->_item);
+    finalize(*job->_item);
 }
 
 void PropagateUploadFileQNAM::slotJobDestroyed(QObject* job)
@@ -701,7 +701,7 @@ void PropagateUploadFileQNAM::abort()
 {
     foreach(auto *job, _jobs) {
         if (job->reply()) {
-            qDebug() << Q_FUNC_INFO << job << this->_item._file;
+            qDebug() << Q_FUNC_INFO << job << this->_item->_file;
             job->reply()->abort();
         }
     }
diff --git a/src/libsync/propagateupload.h b/src/libsync/propagateupload.h
index 3e345fa..9955595 100644
--- a/src/libsync/propagateupload.h
+++ b/src/libsync/propagateupload.h
@@ -108,9 +108,9 @@ class PollJob : public AbstractNetworkJob {
     SyncJournalDb *_journal;
     QString _localPath;
 public:
-    SyncFileItem _item;
+    SyncFileItemPtr _item;
     // Takes ownership of the device
-    explicit PollJob(AccountPtr account, const QString &path, const SyncFileItem &item,
+    explicit PollJob(AccountPtr account, const QString &path, const SyncFileItemPtr &item,
                      SyncJournalDb *journal, const QString &localPath, QObject *parent)
         : AbstractNetworkJob(account, path, parent), _journal(journal), _localPath(localPath), _item(item) {}
 
@@ -149,7 +149,7 @@ class PropagateUploadFileQNAM : public PropagateItemJob {
     QVector<PUTFileJob*> _jobs; /// network jobs that are currently in transit
     bool _finished; // Tells that all the jobs have been finished
 public:
-    PropagateUploadFileQNAM(OwncloudPropagator* propagator,const SyncFileItem& item)
+    PropagateUploadFileQNAM(OwncloudPropagator* propagator,const SyncFileItemPtr& item)
         : PropagateItemJob(propagator, item), _startChunk(0), _currentChunk(0), _chunkCount(0), _transferId(0), _finished(false) {}
     void start() Q_DECL_OVERRIDE;
 private slots:
diff --git a/src/libsync/propagator_legacy.cpp b/src/libsync/propagator_legacy.cpp
index b9dc7e8..613935b 100644
--- a/src/libsync/propagator_legacy.cpp
+++ b/src/libsync/propagator_legacy.cpp
@@ -186,7 +186,7 @@ void PropagateUploadFileLegacy::start()
             _item._modtime = trans->oc_header_modtime;
 
         }
-        emit progress(_item, 0);
+        emit progress(*_item, 0);
 
         if (progressInfo._valid) {
             if (Utility::qDateTimeToTime_t(progressInfo._modtime) == _item._modtime) {
@@ -267,7 +267,7 @@ void PropagateUploadFileLegacy::start()
                 return;
         }
 
-        _propagator->_journal->setFileRecord(SyncJournalFileRecord(_item, _propagator->getFilePath(_item._file)));
+        _propagator->_journal->setFileRecord(SyncJournalFileRecord(*_item, _propagator->getFilePath(_item._file)));
         // Remove from the progress database:
         _propagator->_journal->setUploadInfo(_item._file, SyncJournalDb::UploadInfo());
         _propagator->_journal->commit("upload file start");
@@ -569,7 +569,7 @@ void PropagateDownloadFileLegacy::start()
         return;
     }
 
-    emit progress(_item, 0);
+    emit progress(*_item, 0);
 
     QString tmpFileName;
     const SyncJournalDb::DownloadInfo progressInfo = _propagator->_journal->getDownloadInfo(_item._file);
@@ -721,7 +721,7 @@ void PropagateDownloadFileLegacy::start()
 
     FileSystem::setModTime(fn, _item._modtime);
 
-    _propagator->_journal->setFileRecord(SyncJournalFileRecord(_item, fn));
+    _propagator->_journal->setFileRecord(SyncJournalFileRecord(*_item, fn));
     _propagator->_journal->setDownloadInfo(_item._file, SyncJournalDb::DownloadInfo());
     _propagator->_journal->commit("download file start2");
     done(isConflict ? SyncFileItem::Conflict : SyncFileItem::Success);
diff --git a/src/libsync/propagatorjobs.cpp b/src/libsync/propagatorjobs.cpp
index 9f95257..2b7318a 100644
--- a/src/libsync/propagatorjobs.cpp
+++ b/src/libsync/propagatorjobs.cpp
@@ -81,14 +81,14 @@ void PropagateLocalRemove::start()
     if (_propagator->_abortRequested.fetchAndAddRelaxed(0))
         return;
 
-    QString filename = _propagator->_localDir +  _item._file;
-    if( _propagator->localFileNameClash(_item._file)) {
+    QString filename = _propagator->_localDir +  _item->_file;
+    if( _propagator->localFileNameClash(_item->_file)) {
         done(SyncFileItem::NormalError, tr("Could not remove %1 because of a local file name clash")
              .arg(QDir::toNativeSeparators(filename)));
         return;
     }
 
-    if (_item._isDirectory) {
+    if (_item->_isDirectory) {
         QString error;
         if (QDir(filename).exists() && !removeRecursively(filename, error)) {
             done(SyncFileItem::NormalError, error);
@@ -101,8 +101,8 @@ void PropagateLocalRemove::start()
             return;
         }
     }
-    emit progress(_item, 0);
-    _propagator->_journal->deleteFileRecord(_item._originalFile, _item._isDirectory);
+    emit progress(*_item, 0);
+    _propagator->_journal->deleteFileRecord(_item->_originalFile, _item->_isDirectory);
     _propagator->_journal->commit("Local remove");
     done(SyncFileItem::Success);
 }
@@ -112,15 +112,15 @@ void PropagateLocalMkdir::start()
     if (_propagator->_abortRequested.fetchAndAddRelaxed(0))
         return;
 
-    QDir newDir(_propagator->_localDir + _item._file);
+    QDir newDir(_propagator->_localDir + _item->_file);
     QString newDirStr = QDir::toNativeSeparators(newDir.path());
-    if( Utility::fsCasePreserving() && _propagator->localFileNameClash(_item._file ) ) {
+    if( Utility::fsCasePreserving() && _propagator->localFileNameClash(_item->_file ) ) {
         qDebug() << "WARN: new directory to create locally already exists!";
         done( SyncFileItem::NormalError, tr("Attention, possible case sensitivity clash with %1").arg(newDirStr) );
         return;
     }
     QDir localDir(_propagator->_localDir);
-    if (!localDir.mkpath(_item._file)) {
+    if (!localDir.mkpath(_item->_file)) {
         done( SyncFileItem::NormalError, tr("could not create directory %1").arg(newDirStr) );
         return;
     }
@@ -132,24 +132,24 @@ void PropagateLocalRename::start()
     if (_propagator->_abortRequested.fetchAndAddRelaxed(0))
         return;
 
-    QString existingFile = _propagator->getFilePath(_item._file);
-    QString targetFile = _propagator->getFilePath(_item._renameTarget);
+    QString existingFile = _propagator->getFilePath(_item->_file);
+    QString targetFile = _propagator->getFilePath(_item->_renameTarget);
 
-    // if the file is a file underneath a moved dir, the _item.file is equal
-    // to _item.renameTarget and the file is not moved as a result.
-    if (_item._file != _item._renameTarget) {
-        emit progress(_item, 0);
+    // if the file is a file underneath a moved dir, the _item->file is equal
+    // to _item->renameTarget and the file is not moved as a result.
+    if (_item->_file != _item->_renameTarget) {
+        emit progress(*_item, 0);
         qDebug() << "MOVE " << existingFile << " => " << targetFile;
 
-        if (QString::compare(_item._file, _item._renameTarget, Qt::CaseInsensitive) != 0
-                && _propagator->localFileNameClash(_item._renameTarget)) {
+        if (QString::compare(_item->_file, _item->_renameTarget, Qt::CaseInsensitive) != 0
+                && _propagator->localFileNameClash(_item->_renameTarget)) {
             // Only use localFileNameClash for the destination if we know that the source was not
             // the one conflicting  (renaming  A.txt -> a.txt is OK)
 
             // Fixme: the file that is the reason for the clash could be named here,
             // it would have to come out the localFileNameClash function
             done(SyncFileItem::NormalError, tr( "File %1 can not be renamed to %2 because of a local file name clash")
-                 .arg(QDir::toNativeSeparators(_item._file)).arg(QDir::toNativeSeparators(_item._renameTarget)) );
+                 .arg(QDir::toNativeSeparators(_item->_file)).arg(QDir::toNativeSeparators(_item->_renameTarget)) );
             return;
         }
 
@@ -162,15 +162,15 @@ void PropagateLocalRename::start()
         }
     }
 
-    _propagator->_journal->deleteFileRecord(_item._originalFile);
+    _propagator->_journal->deleteFileRecord(_item->_originalFile);
 
     // store the rename file name in the item.
-    _item._file = _item._renameTarget;
+    _item->_file = _item->_renameTarget;
 
-    SyncJournalFileRecord record(_item, targetFile);
-    record._path = _item._renameTarget;
+    SyncJournalFileRecord record(*_item, targetFile);
+    record._path = _item->_renameTarget;
 
-    if (!_item._isDirectory) { // Directory are saved at the end
+    if (!_item->_isDirectory) { // Directory are saved at the end
         _propagator->_journal->setFileRecord(record);
     }
     _propagator->_journal->commit("localRename");
diff --git a/src/libsync/propagatorjobs.h b/src/libsync/propagatorjobs.h
index 99343fe..06b3c23 100644
--- a/src/libsync/propagatorjobs.h
+++ b/src/libsync/propagatorjobs.h
@@ -24,20 +24,20 @@ namespace OCC {
 class PropagateLocalRemove : public PropagateItemJob {
     Q_OBJECT
 public:
-    PropagateLocalRemove (OwncloudPropagator* propagator,const SyncFileItem& item)  : PropagateItemJob(propagator, item) {}
+    PropagateLocalRemove (OwncloudPropagator* propagator,const SyncFileItemPtr& item)  : PropagateItemJob(propagator, item) {}
     void start() Q_DECL_OVERRIDE;
 };
 class PropagateLocalMkdir : public PropagateItemJob {
     Q_OBJECT
 public:
-    PropagateLocalMkdir (OwncloudPropagator* propagator,const SyncFileItem& item)  : PropagateItemJob(propagator, item) {}
+    PropagateLocalMkdir (OwncloudPropagator* propagator,const SyncFileItemPtr& item)  : PropagateItemJob(propagator, item) {}
     void start() Q_DECL_OVERRIDE;
 
 };
 class PropagateLocalRename : public PropagateItemJob {
     Q_OBJECT
 public:
-    PropagateLocalRename (OwncloudPropagator* propagator,const SyncFileItem& item)  : PropagateItemJob(propagator, item) {}
+    PropagateLocalRename (OwncloudPropagator* propagator,const SyncFileItemPtr& item)  : PropagateItemJob(propagator, item) {}
     void start() Q_DECL_OVERRIDE;
     JobParallelism parallelism() Q_DECL_OVERRIDE { return WaitForFinishedInParentDirectory; }
 };
diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp
index 81d0872..ea46e83 100644
--- a/src/libsync/syncengine.cpp
+++ b/src/libsync/syncengine.cpp
@@ -173,45 +173,45 @@ QString SyncEngine::csyncErrorToString(CSYNC_STATUS err)
 
 }
 
-bool SyncEngine::checkErrorBlacklisting( SyncFileItem *item )
+bool SyncEngine::checkErrorBlacklisting( SyncFileItem &item )
 {
     if( !_journal ) {
         qWarning() << "Journal is undefined!";
         return false;
     }
 
-    SyncJournalErrorBlacklistRecord entry = _journal->errorBlacklistEntry(item->_file);
-    item->_hasBlacklistEntry = false;
+    SyncJournalErrorBlacklistRecord entry = _journal->errorBlacklistEntry(item._file);
+    item._hasBlacklistEntry = false;
 
     if( !entry.isValid() ) {
         return false;
     }
 
-    item->_hasBlacklistEntry = true;
+    item._hasBlacklistEntry = true;
 
     // If duration has expired, it's not blacklisted anymore
     time_t now = Utility::qDateTimeToTime_t(QDateTime::currentDateTime());
     if( now > entry._lastTryTime + entry._ignoreDuration ) {
-        qDebug() << "blacklist entry for " << item->_file << " has expired!";
+        qDebug() << "blacklist entry for " << item._file << " has expired!";
         return false;
     }
 
     // If the file has changed locally or on the server, the blacklist
     // entry no longer applies
-    if( item->_direction == SyncFileItem::Up ) { // check the modtime
-        if(item->_modtime == 0 || entry._lastTryModtime == 0) {
+    if( item._direction == SyncFileItem::Up ) { // check the modtime
+        if(item._modtime == 0 || entry._lastTryModtime == 0) {
             return false;
-        } else if( item->_modtime != entry._lastTryModtime ) {
-            qDebug() << item->_file << " is blacklisted, but has changed mtime!";
+        } else if( item._modtime != entry._lastTryModtime ) {
+            qDebug() << item._file << " is blacklisted, but has changed mtime!";
             return false;
         }
-    } else if( item->_direction == SyncFileItem::Down ) {
+    } else if( item._direction == SyncFileItem::Down ) {
         // download, check the etag.
-        if( item->_etag.isEmpty() || entry._lastTryEtag.isEmpty() ) {
-            qDebug() << item->_file << "one ETag is empty, no blacklisting";
+        if( item._etag.isEmpty() || entry._lastTryEtag.isEmpty() ) {
+            qDebug() << item._file << "one ETag is empty, no blacklisting";
             return false;
-        } else if( item->_etag != entry._lastTryEtag ) {
-            qDebug() << item->_file << " is blacklisted, but has changed etag!";
+        } else if( item._etag != entry._lastTryEtag ) {
+            qDebug() << item._file << " is blacklisted, but has changed etag!";
             return false;
         }
     }
@@ -219,9 +219,9 @@ bool SyncEngine::checkErrorBlacklisting( SyncFileItem *item )
     qDebug() << "Item is on blacklist: " << entry._file
              << "retries:" << entry._retryCount
              << "for another" << (entry._lastTryTime + entry._ignoreDuration - now) << "s";
-    item->_instruction = CSYNC_INSTRUCTION_ERROR;
-    item->_status = SyncFileItem::FileIgnored;
-    item->_errorString = tr("The item is not synced because of previous errors: %1").arg(entry._errorString);
+    item._instruction = CSYNC_INSTRUCTION_ERROR;
+    item._status = SyncFileItem::FileIgnored;
+    item._errorString = tr("The item is not synced because of previous errors: %1").arg(entry._errorString);
 
     return true;
 }
@@ -230,11 +230,11 @@ void SyncEngine::deleteStaleDownloadInfos()
 {
     // Find all downloadinfo paths that we want to preserve.
     QSet<QString> download_file_paths;
-    foreach(const SyncFileItem& it, _syncedItems) {
-        if (it._direction == SyncFileItem::Down
-                && it._type == SyncFileItem::File)
+    foreach(const SyncFileItemPtr &it, _syncedItems) {
+        if (it->_direction == SyncFileItem::Down
+                && it->_type == SyncFileItem::File)
         {
-            download_file_paths.insert(it._file);
+            download_file_paths.insert(it->_file);
         }
     }
 
@@ -252,11 +252,11 @@ void SyncEngine::deleteStaleUploadInfos()
 {
     // Find all blacklisted paths that we want to preserve.
     QSet<QString> upload_file_paths;
-    foreach(const SyncFileItem& it, _syncedItems) {
-        if (it._direction == SyncFileItem::Up
-                && it._type == SyncFileItem::File)
+    foreach(const SyncFileItemPtr &it, _syncedItems) {
+        if (it->_direction == SyncFileItem::Up
+                && it->_type == SyncFileItem::File)
         {
-            upload_file_paths.insert(it._file);
+            upload_file_paths.insert(it->_file);
         }
     }
 
@@ -268,9 +268,9 @@ void SyncEngine::deleteStaleErrorBlacklistEntries()
 {
     // Find all blacklisted paths that we want to preserve.
     QSet<QString> blacklist_file_paths;
-    foreach(const SyncFileItem& it, _syncedItems) {
-        if (it._hasBlacklistEntry)
-            blacklist_file_paths.insert(it._file);
+    foreach(const SyncFileItemPtr &it, _syncedItems) {
+        if (it->_hasBlacklistEntry)
+            blacklist_file_paths.insert(it->_file);
     }
 
     // Delete from journal.
@@ -313,113 +313,116 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
         }
     }
 
-    // Gets a default-contructed SyncFileItem or the one from the first walk (=local walk)
-    SyncFileItem item = _syncItemMap.value(key);
-    if (item._file.isEmpty() || instruction == CSYNC_INSTRUCTION_RENAME) {
-        item._file = fileUtf8;
+    // Gets a default-contructed SyncFileItemPtr or the one from the first walk (=local walk)
+    SyncFileItemPtr item = _syncItemMap.value(key);
+    if (!item)
+        item = SyncFileItemPtr(new SyncFileItem);
+
+    if (item->_file.isEmpty() || instruction == CSYNC_INSTRUCTION_RENAME) {
+        item->_file = fileUtf8;
     }
-    item._originalFile = item._file;
+    item->_originalFile = item->_file;
 
-    if (item._instruction == CSYNC_INSTRUCTION_NONE
-            || (item._instruction == CSYNC_INSTRUCTION_IGNORE && instruction != CSYNC_INSTRUCTION_NONE)) {
-        item._instruction = instruction;
-        item._modtime = file->modtime;
+    if (item->_instruction == CSYNC_INSTRUCTION_NONE
+            || (item->_instruction == CSYNC_INSTRUCTION_IGNORE && instruction != CSYNC_INSTRUCTION_NONE)) {
+        item->_instruction = instruction;
+        item->_modtime = file->modtime;
     } else {
         if (instruction != CSYNC_INSTRUCTION_NONE) {
-            qDebug() << "ERROR: Instruction" << item._instruction << "vs" << instruction << "for" << fileUtf8;
+            qDebug() << "ERROR: Instruction" << item->_instruction << "vs" << instruction << "for" << fileUtf8;
             Q_ASSERT(!"Instructions are both unequal NONE");
             return -1;
         }
     }
 
     if (file->file_id && strlen(file->file_id) > 0) {
-        item._fileId = file->file_id;
+        item->_fileId = file->file_id;
     }
     if (file->directDownloadUrl) {
-        item._directDownloadUrl = QString::fromUtf8( file->directDownloadUrl );
+        item->_directDownloadUrl = QString::fromUtf8( file->directDownloadUrl );
     }
     if (file->directDownloadCookies) {
-        item._directDownloadCookies = QString::fromUtf8( file->directDownloadCookies );
+        item->_directDownloadCookies = QString::fromUtf8( file->directDownloadCookies );
     }
     if (file->remotePerm && file->remotePerm[0]) {
-        item._remotePerm = QByteArray(file->remotePerm);
+        item->_remotePerm = QByteArray(file->remotePerm);
     }
-    item._should_update_etag = item._should_update_etag || file->should_update_etag;
+    item->_should_update_etag = item->_should_update_etag || file->should_update_etag;
 
     // record the seen files to be able to clean the journal later
-    _seenFiles.insert(item._file);
+    _seenFiles.insert(item->_file);
     if (!renameTarget.isEmpty()) {
         // Yes, this record both the rename renameTarget and the original so we keep both in case of a rename
         _seenFiles.insert(renameTarget);
     }
 
     if (remote && file->remotePerm && file->remotePerm[0]) {
-        _remotePerms[item._file] = file->remotePerm;
+        _remotePerms[item->_file] = file->remotePerm;
     }
 
     switch(file->error_status) {
     case CSYNC_STATUS_OK:
         break;
     case CSYNC_STATUS_INDIVIDUAL_IS_SYMLINK:
-        item._errorString = tr("Symbolic links are not supported in syncing.");
+        item->_errorString = tr("Symbolic links are not supported in syncing.");
         break;
     case CSYNC_STATUS_INDIVIDUAL_IS_HARDLINK:
-        item._errorString = tr("Hard links are not supported in syncing.");
+        item->_errorString = tr("Hard links are not supported in syncing.");
         break;
     case CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST:
-        item._errorString = tr("File is listed on the ignore list.");
+        item->_errorString = tr("File is listed on the ignore list.");
         break;
     case CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS:
-        item._errorString = tr("File contains invalid characters that can not be synced cross platform.");
+        item->_errorString = tr("File contains invalid characters that can not be synced cross platform.");
         break;
     case CSYNC_STATUS_INDIVIDUAL_EXCLUDE_LONG_FILENAME:
-        item._errorString = tr("Filename is too long.");
+        item->_errorString = tr("Filename is too long.");
         break;
     case CYSNC_STATUS_FILE_LOCKED_OR_OPEN:
-        item._errorString = QLatin1String("File locked"); // don't translate, internal use!
+        item->_errorString = QLatin1String("File locked"); // don't translate, internal use!
         break;
     case CSYNC_STATUS_SERVICE_UNAVAILABLE:
-        item._errorString = QLatin1String("Server temporarily unavailable.");
+        item->_errorString = QLatin1String("Server temporarily unavailable.");
         break;
     case CSYNC_STATUS_STORAGE_UNAVAILABLE:
-        item._errorString = QLatin1String("Directory temporarily not available on server.");
-        item._status = SyncFileItem::SoftError;
-        _temporarilyUnavailablePaths.insert(item._file);
+        item->_errorString = QLatin1String("Directory temporarily not available on server.");
+        item->_status = SyncFileItem::SoftError;
+        _temporarilyUnavailablePaths.insert(item->_file);
         break;
     default:
         Q_ASSERT("Non handled error-status");
         /* No error string */
     }
 
-    if (item._instruction == CSYNC_INSTRUCTION_IGNORE && (utf8State.invalidChars > 0 || utf8State.remainingChars > 0)) {
-        item._status = SyncFileItem::NormalError;
-        //item._instruction = CSYNC_INSTRUCTION_ERROR;
-        item._errorString = tr("Filename encoding is not valid");
+    if (item->_instruction == CSYNC_INSTRUCTION_IGNORE && (utf8State.invalidChars > 0 || utf8State.remainingChars > 0)) {
+        item->_status = SyncFileItem::NormalError;
+        //item->_instruction = CSYNC_INSTRUCTION_ERROR;
+        item->_errorString = tr("Filename encoding is not valid");
     }
 
-    item._isDirectory = file->type == CSYNC_FTW_TYPE_DIR;
+    item->_isDirectory = file->type == CSYNC_FTW_TYPE_DIR;
 
     // The etag is already set in the previous sync phases somewhere. Maybe we should remove it there
     // and do it here so we have a consistent state about which tree stores information from which source.
-    item._etag = file->etag;
-    item._size = file->size;
+    item->_etag = file->etag;
+    item->_size = file->size;
 
     if (!remote) {
-        item._inode = file->inode;
+        item->_inode = file->inode;
     }
 
     switch( file->type ) {
     case CSYNC_FTW_TYPE_DIR:
-        item._type = SyncFileItem::Directory;
+        item->_type = SyncFileItem::Directory;
         break;
     case CSYNC_FTW_TYPE_FILE:
-        item._type = SyncFileItem::File;
+        item->_type = SyncFileItem::File;
         break;
     case CSYNC_FTW_TYPE_SLINK:
-        item._type = SyncFileItem::SoftLink;
+        item->_type = SyncFileItem::SoftLink;
         break;
     default:
-        item._type = SyncFileItem::UnknownType;
+        item->_type = SyncFileItem::UnknownType;
     }
 
     SyncFileItem::Direction dir;
@@ -427,7 +430,7 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
     int re = 0;
     switch(file->instruction) {
     case CSYNC_INSTRUCTION_NONE:
-        if (remote && item._should_update_etag && !item._isDirectory && item._instruction == CSYNC_INSTRUCTION_NONE) {
+        if (remote && item->_should_update_etag && !item->_isDirectory && item->_instruction == CSYNC_INSTRUCTION_NONE) {
             // Update the database now already:  New fileid or Etag or RemotePerm
             // Or for files that were detected as "resolved conflict".
             // They should have been a conflict because they both were new, or both
@@ -437,12 +440,12 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
 
             // Even if the mtime is different on the server, we always want to keep the mtime from
             // the file system in the DB, this is to avoid spurious upload on the next sync
-            item._modtime = file->other.modtime;
+            item->_modtime = file->other.modtime;
 
-            _journal->setFileRecord(SyncJournalFileRecord(item, _localPath + item._file));
-            item._should_update_etag = false;
+            _journal->setFileRecord(SyncJournalFileRecord(*item, _localPath + item->_file));
+            item->_should_update_etag = false;
         }
-        if (item._isDirectory && (remote || file->should_update_etag)) {
+        if (item->_isDirectory && (remote || file->should_update_etag)) {
             // Because we want still to update etags of directories
             dir = SyncFileItem::None;
         } else {
@@ -451,15 +454,15 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
                 _hasNoneFiles = true;
             }
 
-            emit syncItemDiscovered(item);
+            emit syncItemDiscovered(*item);
             return re;
         }
         break;
     case CSYNC_INSTRUCTION_RENAME:
         dir = !remote ? SyncFileItem::Down : SyncFileItem::Up;
-        item._renameTarget = renameTarget;
-        if (item._isDirectory)
-            _renamedFolders.insert(item._file, item._renameTarget);
+        item->_renameTarget = renameTarget;
+        if (item->_isDirectory)
+            _renamedFolders.insert(item->_file, item->_renameTarget);
         break;
     case CSYNC_INSTRUCTION_REMOVE:
         _hasRemoveFile = true;
@@ -484,14 +487,14 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
         break;
     }
 
-    item._direction = dir;
+    item->_direction = dir;
     if (instruction != CSYNC_INSTRUCTION_NONE) {
         // check for blacklisting of this item.
         // if the item is on blacklist, the instruction was set to ERROR
-        checkErrorBlacklisting( &item );
+        checkErrorBlacklisting( *item );
     }
 
-    if (!item._isDirectory) {
+    if (!item->_isDirectory) {
         _progressInfo._totalFileCount++;
         if (Progress::isSizeDependent(file->instruction)) {
             _progressInfo._totalSize += file->size;
@@ -502,21 +505,21 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
     }
     _needsUpdate = true;
 
-    item.log._etag          = file->etag;
-    item.log._fileId        = file->file_id;
-    item.log._instruction   = file->instruction;
-    item.log._modtime       = file->modtime;
-    item.log._size          = file->size;
+    item->log._etag          = file->etag;
+    item->log._fileId        = file->file_id;
+    item->log._instruction   = file->instruction;
+    item->log._modtime       = file->modtime;
+    item->log._size          = file->size;
 
-    item.log._other_etag        = file->other.etag;
-    item.log._other_fileId      = file->other.file_id;
-    item.log._other_instruction = file->other.instruction;
-    item.log._other_modtime     = file->other.modtime;
-    item.log._other_size        = file->other.size;
+    item->log._other_etag        = file->other.etag;
+    item->log._other_fileId      = file->other.file_id;
+    item->log._other_instruction = file->other.instruction;
+    item->log._other_modtime     = file->other.modtime;
+    item->log._other_size        = file->other.size;
 
     _syncItemMap.insert(key, item);
 
-    emit syncItemDiscovered(item);
+    emit syncItemDiscovered(*item);
     return re;
 }
 
@@ -730,7 +733,7 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
     // Adjust the paths for the renames.
     for (SyncFileItemVector::iterator it = _syncedItems.begin();
             it != _syncedItems.end(); ++it) {
-        it->_file = adjustRenamedPath(it->_file);
+        (*it)->_file = adjustRenamedPath((*it)->_file);
     }
 
     // Sort items per destination
@@ -748,7 +751,7 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
     if (!_hasNoneFiles && _hasRemoveFile) {
         qDebug() << Q_FUNC_INFO << "All the files are going to be changed, asking the user";
         bool cancel = false;
-        emit aboutToRemoveAllFiles(_syncedItems.first()._direction, &cancel);
+        emit aboutToRemoveAllFiles(_syncedItems.first()->_direction, &cancel);
         if (cancel) {
             qDebug() << Q_FUNC_INFO << "Abort sync";
             finalize();
@@ -779,10 +782,10 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
 
     _propagator = QSharedPointer<OwncloudPropagator>(
         new OwncloudPropagator (_account, session, _localPath, _remoteUrl, _remotePath, _journal, &_thread));
-    connect(_propagator.data(), SIGNAL(completed(SyncFileItem)),
-            this, SLOT(slotJobCompleted(SyncFileItem)));
-    connect(_propagator.data(), SIGNAL(progress(SyncFileItem,quint64)),
-            this, SLOT(slotProgress(SyncFileItem,quint64)));
+    connect(_propagator.data(), SIGNAL(completed(const SyncFileItem &)),
+            this, SLOT(slotJobCompleted(const SyncFileItem &)));
+    connect(_propagator.data(), SIGNAL(progress(const SyncFileItem &,quint64)),
+            this, SLOT(slotProgress(const SyncFileItem &,quint64)));
     connect(_propagator.data(), SIGNAL(adjustTotalTransmissionSize(qint64)), this, SLOT(slotAdjustTotalTransmissionSize(qint64)));
     connect(_propagator.data(), SIGNAL(finished()), this, SLOT(slotFinished()), Qt::QueuedConnection);
 
@@ -840,20 +843,6 @@ void SyncEngine::slotJobCompleted(const SyncFileItem &item)
     const char * instruction_str = csync_instruction_str(item._instruction);
     qDebug() << Q_FUNC_INFO << item._file << instruction_str << item._status << item._errorString;
 
-    /* Update the _syncedItems vector */
-    int idx = _syncedItems.indexOf(item);
-    if (idx >= 0) {
-        _syncedItems[idx]._instruction = item._instruction;
-        _syncedItems[idx]._errorString = item._errorString;
-        _syncedItems[idx]._status = item._status;
-
-        _syncedItems[idx]._requestDuration = item._requestDuration;
-        _syncedItems[idx]._responseTimeStamp = item._responseTimeStamp;
-    } else {
-        qWarning() << Q_FUNC_INFO << "Could not find index in synced items!";
-
-    }
-
     _progressInfo.setProgressComplete(item);
 
     if (item._status == SyncFileItem::FatalError) {
@@ -933,114 +922,113 @@ QString SyncEngine::adjustRenamedPath(const QString& original)
 void SyncEngine::checkForPermission()
 {
     for (SyncFileItemVector::iterator it = _syncedItems.begin(); it != _syncedItems.end(); ++it) {
-
-        if (it->_direction != SyncFileItem::Up) {
+        if ((*it)->_direction != SyncFileItem::Up) {
             // Currently we only check server-side permissions
             continue;
         }
 
         // Do not propagate anything in the server if it is in the selective sync blacklist
-        const QString path = it->destination() + QLatin1Char('/');
+        const QString path = (*it)->destination() + QLatin1Char('/');
         if (std::binary_search(_selectiveSyncBlackList.constBegin(), _selectiveSyncBlackList.constEnd(),
                                 path)) {
-            it->_instruction = CSYNC_INSTRUCTION_IGNORE;
-            it->_status = SyncFileItem::FileIgnored;
-            it->_errorString = tr("Ignored because of the \"choose what to sync\" blacklist");
+            (*it)->_instruction = CSYNC_INSTRUCTION_IGNORE;
+            (*it)->_status = SyncFileItem::FileIgnored;
+            (*it)->_errorString = tr("Ignored because of the \"choose what to sync\" blacklist");
 
-            if (it->_isDirectory) {
-                for (SyncFileItemVector::iterator it_next = it + 1; it_next != _syncedItems.end() && it_next->_file.startsWith(path); ++it_next) {
+            if ((*it)->_isDirectory) {
+                for (SyncFileItemVector::iterator it_next = it + 1; it_next != _syncedItems.end() && (*it_next)->_file.startsWith(path); ++it_next) {
                     it = it_next;
-                    it->_instruction = CSYNC_INSTRUCTION_IGNORE;
-                    it->_status = SyncFileItem::FileIgnored;
-                    it->_errorString = tr("Ignored because of the \"choose what to sync\" blacklist");
+                    (*it)->_instruction = CSYNC_INSTRUCTION_IGNORE;
+                    (*it)->_status = SyncFileItem::FileIgnored;
+                    (*it)->_errorString = tr("Ignored because of the \"choose what to sync\" blacklist");
                 }
             }
             continue;
         }
 
-        switch(it->_instruction) {
+        switch((*it)->_instruction) {
             case CSYNC_INSTRUCTION_NEW: {
-                int slashPos = it->_file.lastIndexOf('/');
-                QString parentDir = slashPos <= 0 ? "" : it->_file.mid(0, slashPos);
+                int slashPos = (*it)->_file.lastIndexOf('/');
+                QString parentDir = slashPos <= 0 ? "" : (*it)->_file.mid(0, slashPos);
                 const QByteArray perms = getPermissions(parentDir);
                 if (perms.isNull()) {
                     // No permissions set
                     break;
-                } else if (it->_isDirectory && !perms.contains("K")) {
-                    qDebug() << "checkForPermission: ERROR" << it->_file;
-                    it->_instruction = CSYNC_INSTRUCTION_ERROR;
-                    it->_status = SyncFileItem::NormalError;
-                    it->_errorString = tr("Not allowed because you don't have permission to add sub-directories in that directory");
+                } else if ((*it)->_isDirectory && !perms.contains("K")) {
+                    qDebug() << "checkForPermission: ERROR" << (*it)->_file;
+                    (*it)->_instruction = CSYNC_INSTRUCTION_ERROR;
+                    (*it)->_status = SyncFileItem::NormalError;
+                    (*it)->_errorString = tr("Not allowed because you don't have permission to add sub-directories in that directory");
 
-                    for (SyncFileItemVector::iterator it_next = it + 1; it_next != _syncedItems.end() && it_next->_file.startsWith(path); ++it_next) {
+                    for (SyncFileItemVector::iterator it_next = it + 1; it_next != _syncedItems.end() && (*it_next)->_file.startsWith(path); ++it_next) {
                         it = it_next;
-                        it->_instruction = CSYNC_INSTRUCTION_ERROR;
-                        it->_status = SyncFileItem::NormalError;
-                        it->_errorString = tr("Not allowed because you don't have permission to add parent directory");
+                        (*it)->_instruction = CSYNC_INSTRUCTION_ERROR;
+                        (*it)->_status = SyncFileItem::NormalError;
+                        (*it)->_errorString = tr("Not allowed because you don't have permission to add parent directory");
                     }
 
-                } else if (!it->_isDirectory && !perms.contains("C")) {
-                    qDebug() << "checkForPermission: ERROR" << it->_file;
-                    it->_instruction = CSYNC_INSTRUCTION_ERROR;
-                    it->_status = SyncFileItem::NormalError;
-                    it->_errorString = tr("Not allowed because you don't have permission to add files in that directory");
+                } else if (!(*it)->_isDirectory && !perms.contains("C")) {
+                    qDebug() << "checkForPermission: ERROR" << (*it)->_file;
+                    (*it)->_instruction = CSYNC_INSTRUCTION_ERROR;
+                    (*it)->_status = SyncFileItem::NormalError;
+                    (*it)->_errorString = tr("Not allowed because you don't have permission to add files in that directory");
                 }
                 break;
             }
             case CSYNC_INSTRUCTION_SYNC: {
-                const QByteArray perms = getPermissions(it->_file);
+                const QByteArray perms = getPermissions((*it)->_file);
                 if (perms.isNull()) {
                     // No permissions set
                     break;
-                } if (!it->_isDirectory && !perms.contains("W")) {
-                    qDebug() << "checkForPermission: RESTORING" << it->_file;
-                    it->_should_update_etag = true;
-                    it->_instruction = CSYNC_INSTRUCTION_CONFLICT;
-                    it->_direction = SyncFileItem::Down;
-                    it->_isRestoration = true;
+                } if (!(*it)->_isDirectory && !perms.contains("W")) {
+                    qDebug() << "checkForPermission: RESTORING" << (*it)->_file;
+                    (*it)->_should_update_etag = true;
+                    (*it)->_instruction = CSYNC_INSTRUCTION_CONFLICT;
+                    (*it)->_direction = SyncFileItem::Down;
+                    (*it)->_isRestoration = true;
                     // take the things to write to the db from the "other" node (i.e: info from server)
-                    it->_modtime = it->log._other_modtime;
-                    it->_size = it->log._other_size;
-                    it->_fileId = it->log._other_fileId;
-                    it->_etag = it->log._other_etag;
-                    it->_errorString = tr("Not allowed to upload this file because it is read-only on the server, restoring");
+                    (*it)->_modtime = (*it)->log._other_modtime;
+                    (*it)->_size = (*it)->log._other_size;
+                    (*it)->_fileId = (*it)->log._other_fileId;
+                    (*it)->_etag = (*it)->log._other_etag;
+                    (*it)->_errorString = tr("Not allowed to upload this file because it is read-only on the server, restoring");
                     continue;
                 }
                 break;
             }
             case CSYNC_INSTRUCTION_REMOVE: {
-                const QByteArray perms = getPermissions(it->_file);
+                const QByteArray perms = getPermissions((*it)->_file);
                 if (perms.isNull()) {
                     // No permissions set
                     break;
                 }
                 if (!perms.contains("D")) {
-                    qDebug() << "checkForPermission: RESTORING" << it->_file;
-                    it->_should_update_etag = true;
-                    it->_instruction = CSYNC_INSTRUCTION_NEW;
-                    it->_direction = SyncFileItem::Down;
-                    it->_isRestoration = true;
-                    it->_errorString = tr("Not allowed to remove, restoring");
-
-                    if (it->_isDirectory) {
+                    qDebug() << "checkForPermission: RESTORING" << (*it)->_file;
+                    (*it)->_should_update_etag = true;
+                    (*it)->_instruction = CSYNC_INSTRUCTION_NEW;
+                    (*it)->_direction = SyncFileItem::Down;
+                    (*it)->_isRestoration = true;
+                    (*it)->_errorString = tr("Not allowed to remove, restoring");
+
+                    if ((*it)->_isDirectory) {
                         // restore all sub items
                         for (SyncFileItemVector::iterator it_next = it + 1;
-                             it_next != _syncedItems.end() && it_next->_file.startsWith(path); ++it_next) {
+                             it_next != _syncedItems.end() && (*it_next)->_file.startsWith(path); ++it_next) {
                             it = it_next;
 
-                            if (it->_instruction != CSYNC_INSTRUCTION_REMOVE) {
+                            if ((*it)->_instruction != CSYNC_INSTRUCTION_REMOVE) {
                                 qWarning() << "non-removed job within a removed directory"
-                                           << it->_file << it->_instruction;
+                                           << (*it)->_file << (*it)->_instruction;
                                 continue;
                             }
 
-                            qDebug() << "checkForPermission: RESTORING" << it->_file;
-                            it->_should_update_etag = true;
+                            qDebug() << "checkForPermission: RESTORING" << (*it)->_file;
+                            (*it)->_should_update_etag = true;
 
-                            it->_instruction = CSYNC_INSTRUCTION_NEW;
-                            it->_direction = SyncFileItem::Down;
-                            it->_isRestoration = true;
-                            it->_errorString = tr("Not allowed to remove, restoring");
+                            (*it)->_instruction = CSYNC_INSTRUCTION_NEW;
+                            (*it)->_direction = SyncFileItem::Down;
+                            (*it)->_isRestoration = true;
+                            (*it)->_errorString = tr("Not allowed to remove, restoring");
                         }
                     }
                 } else if(perms.contains("S") && perms.contains("D")) {
@@ -1050,14 +1038,14 @@ void SyncEngine::checkForPermission()
                     // not delete permission we fast forward the iterator and leave the
                     // delete jobs intact. It is not physically tried to remove this files
                     // underneath, propagator sees that.
-                    if( it->_isDirectory ) {
+                    if( (*it)->_isDirectory ) {
                         // put a more descriptive message if really a top level share dir is removed.
-                        if( it == _syncedItems.begin() || !(path.startsWith((it-1)->_file)) ) {
-                            it->_errorString = tr("Local files and share folder removed.");
+                        if( it == _syncedItems.begin() || !(path.startsWith((*(it-1))->_file)) ) {
+                            (*it)->_errorString = tr("Local files and share folder removed.");
                         }
 
                         for (SyncFileItemVector::iterator it_next = it + 1;
-                             it_next != _syncedItems.end() && it_next->_file.startsWith(path); ++it_next) {
+                             it_next != _syncedItems.end() && (*it_next)->_file.startsWith(path); ++it_next) {
                             it = it_next;
                         }
                     }
@@ -1067,13 +1055,13 @@ void SyncEngine::checkForPermission()
 
             case CSYNC_INSTRUCTION_RENAME: {
 
-                int slashPos = it->_renameTarget.lastIndexOf('/');
-                const QString parentDir = slashPos <= 0 ? "" : it->_renameTarget.mid(0, slashPos);
+                int slashPos = (*it)->_renameTarget.lastIndexOf('/');
+                const QString parentDir = slashPos <= 0 ? "" : (*it)->_renameTarget.mid(0, slashPos);
                 const QByteArray destPerms = getPermissions(parentDir);
-                const QByteArray filePerms = getPermissions(it->_file);
+                const QByteArray filePerms = getPermissions((*it)->_file);
 
                 //true when it is just a rename in the same directory. (not a move)
-                bool isRename = it->_file.startsWith(parentDir) && it->_file.lastIndexOf('/') == slashPos;
+                bool isRename = (*it)->_file.startsWith(parentDir) && (*it)->_file.lastIndexOf('/') == slashPos;
 
 
                 // Check if we are allowed to move to the destination.
@@ -1081,9 +1069,9 @@ void SyncEngine::checkForPermission()
                 if (isRename || destPerms.isNull()) {
                     // no need to check for the destination dir permission
                     destinationOK = true;
-                } else if (it->_isDirectory && !destPerms.contains("K")) {
+                } else if ((*it)->_isDirectory && !destPerms.contains("K")) {
                     destinationOK = false;
-                } else if (!it->_isDirectory && !destPerms.contains("C")) {
+                } else if (!(*it)->_isDirectory && !destPerms.contains("C")) {
                     destinationOK = false;
                 }
 
@@ -1106,39 +1094,39 @@ void SyncEngine::checkForPermission()
 
                 if (!sourceOK && !destinationOK) {
                     // Both the source and the destination won't allow move.  Move back to the original
-                    std::swap(it->_file, it->_renameTarget);
-                    it->_direction = SyncFileItem::Down;
-                    it->_errorString = tr("Move not allowed, item restored");
-                    it->_isRestoration = true;
-                    qDebug() << "checkForPermission: MOVING BACK" << it->_file;
+                    std::swap((*it)->_file, (*it)->_renameTarget);
+                    (*it)->_direction = SyncFileItem::Down;
+                    (*it)->_errorString = tr("Move not allowed, item restored");
+                    (*it)->_isRestoration = true;
+                    qDebug() << "checkForPermission: MOVING BACK" << (*it)->_file;
                 } else
 #endif
                 if (!sourceOK || !destinationOK) {
                     // One of them is not possible, just throw an error
-                    it->_instruction = CSYNC_INSTRUCTION_ERROR;
-                    it->_status = SyncFileItem::NormalError;
+                    (*it)->_instruction = CSYNC_INSTRUCTION_ERROR;
+                    (*it)->_status = SyncFileItem::NormalError;
                     const QString errorString = tr("Move not allowed because %1 is read-only").arg(
                         sourceOK ? tr("the destination") : tr("the source"));
-                    it->_errorString = errorString;
+                    (*it)->_errorString = errorString;
 
-                    qDebug() << "checkForPermission: ERROR MOVING" << it->_file << errorString;
+                    qDebug() << "checkForPermission: ERROR MOVING" << (*it)->_file << errorString;
 
                     // Avoid a rename on next sync:
                     // TODO:  do the resolution now already so we don't need two sync
                     //  At this point we would need to go back to the propagate phase on both remote to take
                     //  the decision.
-                    _journal->avoidRenamesOnNextSync(it->_file);
+                    _journal->avoidRenamesOnNextSync((*it)->_file);
                     _anotherSyncNeeded = true;
 
 
-                    if (it->_isDirectory) {
+                    if ((*it)->_isDirectory) {
                         for (SyncFileItemVector::iterator it_next = it + 1;
-                             it_next != _syncedItems.end() && it_next->destination().startsWith(path); ++it_next) {
+                             it_next != _syncedItems.end() && (*it_next)->destination().startsWith(path); ++it_next) {
                             it = it_next;
-                            it->_instruction = CSYNC_INSTRUCTION_ERROR;
-                            it->_status = SyncFileItem::NormalError;
-                            it->_errorString = errorString;
-                            qDebug() << "checkForPermission: ERROR MOVING" << it->_file;
+                            (*it)->_instruction = CSYNC_INSTRUCTION_ERROR;
+                            (*it)->_status = SyncFileItem::NormalError;
+                            (*it)->_errorString = errorString;
+                            qDebug() << "checkForPermission: ERROR MOVING" << (*it)->_file;
                         }
                     }
                 }
@@ -1175,11 +1163,11 @@ bool SyncEngine::estimateState(QString fn, csync_ftw_type_e t, SyncFileStatus* s
         pat.append(QLatin1Char('/'));
     }
 
-    Q_FOREACH(const SyncFileItem &item, _syncedItems) {
+    Q_FOREACH(const SyncFileItemPtr &item, _syncedItems) {
         //qDebug() << Q_FUNC_INFO << fn << item._file << fn.startsWith(item._file) << item._file.startsWith(fn);
 
-        if (item._file.startsWith(pat) ||
-                item._file == fn /* the same directory or file */) {
+        if (item->_file.startsWith(pat) ||
+                item->_file == fn /* the same directory or file */) {
             qDebug() << Q_FUNC_INFO << "Setting" << fn << " to STATUS_EVAL";
             s->set(SyncFileStatus::STATUS_EVAL);
             return true;
diff --git a/src/libsync/syncengine.h b/src/libsync/syncengine.h
index 6106677..bd74066 100644
--- a/src/libsync/syncengine.h
+++ b/src/libsync/syncengine.h
@@ -124,7 +124,7 @@ private:
     static int treewalkLocal( TREE_WALK_FILE*, void *);
     static int treewalkRemote( TREE_WALK_FILE*, void *);
     int treewalkFile( TREE_WALK_FILE*, bool );
-    bool checkErrorBlacklisting( SyncFileItem *item );
+    bool checkErrorBlacklisting( SyncFileItem &item );
 
     // Cleans up unnecessary downloadinfo entries in the journal as well
     // as their temporary files.
@@ -142,7 +142,7 @@ private:
     static bool _syncRunning; //true when one sync is running somewhere (for debugging)
 
     // Must only be acessed during update and reconcile
-    QMap<QString, SyncFileItem> _syncItemMap;
+    QMap<QString, SyncFileItemPtr> _syncItemMap;
 
     // should be called _syncItems (present tense). It's the items from the _syncItemMap but
     // sorted and re-adjusted based on permissions.
diff --git a/src/libsync/syncfileitem.h b/src/libsync/syncfileitem.h
index dc2bf4a..3a9ee81 100644
--- a/src/libsync/syncfileitem.h
+++ b/src/libsync/syncfileitem.h
@@ -18,6 +18,7 @@
 #include <QString>
 #include <QDateTime>
 #include <QMetaType>
+#include <QSharedPointer>
 
 #include <csync.h>
 
@@ -167,9 +168,12 @@ public:
     } log;
 };
 
+typedef QSharedPointer<SyncFileItem> SyncFileItemPtr;
+inline bool operator<(const SyncFileItemPtr& item1, const SyncFileItemPtr& item2) {
+    return *item1 < *item2;
+}
 
-
-typedef QVector<SyncFileItem> SyncFileItemVector;
+typedef QVector<SyncFileItemPtr> SyncFileItemVector;
 
 }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud-client.git



More information about the Pkg-owncloud-commits mailing list