Index: src/ch/MainWnd.cpp
===================================================================
diff -u -r8422e5787e56453d78c7270066c3e8d1743ca757 -rd0bc3c187684f54894c7280a936d5507a5e49f35
--- src/ch/MainWnd.cpp	(.../MainWnd.cpp)	(revision 8422e5787e56453d78c7270066c3e8d1743ca757)
+++ src/ch/MainWnd.cpp	(.../MainWnd.cpp)	(revision d0bc3c187684f54894c7280a936d5507a5e49f35)
@@ -244,7 +244,7 @@
 
 	try
 	{
-		m_spTasks.reset(new chcore::TTaskManager(spSerializerFactory, spFeedbackFactory));
+		m_spTasks.reset(new chcore::TTaskManager(spSerializerFactory, spFeedbackFactory, PathFromString(strTasksDir)));
 	}
 	catch(const std::exception& e)
 	{
@@ -255,7 +255,7 @@
 	{
 		if(MsgBox(IDS_TASKMANAGER_LOAD_FAILED, MB_ICONERROR | MB_OKCANCEL) == IDOK)
 		{
-			m_spTasks.reset(new chcore::TTaskManager(spSerializerFactory, spFeedbackFactory, true));
+			m_spTasks.reset(new chcore::TTaskManager(spSerializerFactory, spFeedbackFactory, PathFromString(strTasksDir), true));
 		}
 		else
 			return false;
Index: src/libchcore/TSQLiteTaskSchema.cpp
===================================================================
diff -u -rff16e23b043c1c3f3ea883372b6f81d7ad4adca3 -rd0bc3c187684f54894c7280a936d5507a5e49f35
--- src/libchcore/TSQLiteTaskSchema.cpp	(.../TSQLiteTaskSchema.cpp)	(revision ff16e23b043c1c3f3ea883372b6f81d7ad4adca3)
+++ src/libchcore/TSQLiteTaskSchema.cpp	(.../TSQLiteTaskSchema.cpp)	(revision d0bc3c187684f54894c7280a936d5507a5e49f35)
@@ -75,17 +75,17 @@
 		tStatement.Prepare(_T("CREATE TABLE subtasks_info(id BIGINT UNIQUE, operation INT NOT NULL)"));
 		tStatement.Step();
 
-		tStatement.Prepare(_T("CREATE TABLE subtask_fastmove(id BIGINT UNIQUE, current_index INT NOT NULL, is_running boolean NOT NULL, total_size BIGINT NOT NULL, processed_size BIGINT NOT NULL, size_speed varchar(1024) NOT NULL, ")
+		tStatement.Prepare(_T("CREATE TABLE subtask_fastmove(id BIGINT UNIQUE, current_index INT NOT NULL, is_running boolean NOT NULL, is_initialized boolean NOT NULL, total_size BIGINT NOT NULL, processed_size BIGINT NOT NULL, size_speed varchar(1024) NOT NULL, ")
 							_T("total_count BIGINT NOT NULL, processed_count BIGINT NOT NULL, count_speed varchar(1024) NOT NULL, ci_processed_size BIGINT NOT NULL, ci_total_size BIGINT NOT NULL, timer BIGINT NOT NULL, ")
 							_T("buffer_index INT NOT NULL, current_path varchar(32768) NOT NULL, suboperation_type INT NOT NULL)"));
 		tStatement.Step();
 
-		tStatement.Prepare(_T("CREATE TABLE subtask_delete(id BIGINT UNIQUE, current_index INT NOT NULL, is_running boolean NOT NULL, total_size BIGINT NOT NULL, processed_size BIGINT NOT NULL, size_speed varchar(1024) NOT NULL, ")
+		tStatement.Prepare(_T("CREATE TABLE subtask_delete(id BIGINT UNIQUE, current_index INT NOT NULL, is_running boolean NOT NULL, is_initialized boolean NOT NULL, total_size BIGINT NOT NULL, processed_size BIGINT NOT NULL, size_speed varchar(1024) NOT NULL, ")
 							_T("total_count BIGINT NOT NULL, processed_count BIGINT NOT NULL, count_speed varchar(1024) NOT NULL, ci_processed_size BIGINT NOT NULL, ci_total_size BIGINT NOT NULL, timer BIGINT NOT NULL, ")
 							_T("buffer_index INT NOT NULL, current_path varchar(32768) NOT NULL, suboperation_type INT NOT NULL)"));
 		tStatement.Step();
 
-		tStatement.Prepare(_T("CREATE TABLE subtask_copymove(id BIGINT UNIQUE, current_index INT NOT NULL, cf_processed_size BIGINT NOT NULL, is_running boolean NOT NULL, total_size BIGINT NOT NULL, processed_size BIGINT NOT NULL, size_speed varchar(1024) NOT NULL, ")
+		tStatement.Prepare(_T("CREATE TABLE subtask_copymove(id BIGINT UNIQUE, current_index INT NOT NULL, cf_processed_size BIGINT NOT NULL, is_running boolean NOT NULL, is_initialized boolean NOT NULL, total_size BIGINT NOT NULL, processed_size BIGINT NOT NULL, size_speed varchar(1024) NOT NULL, ")
 							_T("total_count BIGINT NOT NULL, processed_count BIGINT NOT NULL, count_speed varchar(1024) NOT NULL, ci_processed_size BIGINT NOT NULL, ci_total_size BIGINT NOT NULL, timer BIGINT NOT NULL, ")
 							_T("buffer_index INT NOT NULL, current_path varchar(32768) NOT NULL, suboperation_type INT NOT NULL)"));
 		tStatement.Step();
Index: src/libchcore/TSubTaskArray.cpp
===================================================================
diff -u -rff16e23b043c1c3f3ea883372b6f81d7ad4adca3 -rd0bc3c187684f54894c7280a936d5507a5e49f35
--- src/libchcore/TSubTaskArray.cpp	(.../TSubTaskArray.cpp)	(revision ff16e23b043c1c3f3ea883372b6f81d7ad4adca3)
+++ src/libchcore/TSubTaskArray.cpp	(.../TSubTaskArray.cpp)	(revision d0bc3c187684f54894c7280a936d5507a5e49f35)
@@ -120,7 +120,7 @@
 	size_t stSize = m_vSubTasks.size();
 	long lIndex = m_lSubOperationIndex.load(boost::memory_order_acquire);
 
-	while(lIndex < stSize && eResult == TSubTaskBase::eSubResult_Continue)
+	while(boost::numeric_cast<size_t>(lIndex) < stSize)
 	{
 		std::pair<TSubTaskBasePtr, bool>& rCurrentSubTask = m_vSubTasks.at(lIndex);
 		TSubTaskBasePtr spCurrentSubTask = rCurrentSubTask.first;
@@ -133,6 +133,8 @@
 		}
 
 		eResult = spCurrentSubTask->Exec();
+		if(eResult != TSubTaskBase::eSubResult_Continue)
+			break;
 
 		lIndex = m_lSubOperationIndex.fetch_add(1, boost::memory_order_release) + 1;
 	}
@@ -222,7 +224,7 @@
 		if(bAdded || lCurrentIndex != m_lLastStoredIndex)
 		{
 			// mark subtask at current index as "current"; don't do that if we just finished.
-			if(lCurrentIndex != m_vSubTasks.size())
+			if(boost::numeric_cast<size_t>(lCurrentIndex) != m_vSubTasks.size())
 			{
 				spRow = spContainer->GetRow(lCurrentIndex);
 				*spRow % TRowData(_T("is_current"), true);
@@ -298,7 +300,7 @@
 			TSubTaskBasePtr spSubTask = CreateSubtask((ESubOperationType)iType, m_rSubTaskContext);
 			spSubTask->Load(spSerializer);
 
-			if(lID != m_vSubTasks.size())
+			if(boost::numeric_cast<size_t>(lID) != m_vSubTasks.size())
 				THROW_CORE_EXCEPTION(eErr_InvalidData);
 
 			m_vSubTasks.push_back(std::make_pair(spSubTask, bIsEstimation));
Index: src/libchcore/TSubTaskCopyMove.cpp
===================================================================
diff -u -r19925be73ffcadd9f345f10e03e55aadb3f0eeac -rd0bc3c187684f54894c7280a936d5507a5e49f35
--- src/libchcore/TSubTaskCopyMove.cpp	(.../TSubTaskCopyMove.cpp)	(revision 19925be73ffcadd9f345f10e03e55aadb3f0eeac)
+++ src/libchcore/TSubTaskCopyMove.cpp	(.../TSubTaskCopyMove.cpp)	(revision d0bc3c187684f54894c7280a936d5507a5e49f35)
@@ -102,6 +102,12 @@
 		m_ullCurrentFileProcessedSize.Modify() += ullSizeToAdd;
 	}
 
+	void TCopyMoveProgressInfo::DecreaseCurrentFileProcessedSize(unsigned long long ullSizeToSubtract)
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		m_ullCurrentFileProcessedSize.Modify() -= ullSizeToSubtract;
+	}
+
 	void TCopyMoveProgressInfo::Store(const ISerializerRowDataPtr& spRowData) const
 	{
 		boost::shared_lock<boost::shared_mutex> lock(m_lock);
@@ -182,13 +188,13 @@
 	// log
 	rLog.logi(_T("Processing files/folders (ProcessFiles)"));
 
-	// new stats
-	m_tSubTaskStats.SetCurrentBufferIndex(TBufferSizes::eBuffer_Default);
-	m_tSubTaskStats.SetTotalCount(rFilesCache.GetSize());
-	m_tSubTaskStats.SetProcessedCount(rFilesCache.GetSize());
-	m_tSubTaskStats.SetTotalSize(rFilesCache.CalculateTotalSize());
-	m_tSubTaskStats.SetProcessedSize(rFilesCache.CalculatePartialSize(m_tProgressInfo.GetCurrentIndex()));
-	m_tSubTaskStats.SetCurrentPath(TString());
+	// initialize stats if not resuming (when resuming we have already initialized
+	// the stats once - it is being restored in Load() too).
+	if(!m_tSubTaskStats.IsInitialized())
+	{
+		m_tSubTaskStats.Init(TBufferSizes::eBuffer_Default, rFilesCache.GetSize(), 0/*rFilesCache.GetSize()*/,
+			rFilesCache.CalculateTotalSize(), rFilesCache.CalculatePartialSize(m_tProgressInfo.GetCurrentIndex()), TString());
+	}
 
 	// now it's time to check if there is enough space on destination device
 	TSubTaskBase::ESubOperationResult eResult = CheckForFreeSpaceFB();
@@ -503,10 +509,11 @@
 	else if(!fileSrc.IsOpen())
 	{
 		// invalid handle = operation skipped by user
-		// new stats
-		m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
-		m_tSubTaskStats.IncreaseCurrentItemProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
+		unsigned long long ullDiff = pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize();
 
+		m_tSubTaskStats.IncreaseProcessedSize(ullDiff);
+		m_tSubTaskStats.IncreaseCurrentItemProcessedSize(ullDiff);
+
 		pData->bProcessed = false;
 		bSkip = true;
 		return TSubTaskBase::eSubResult_Continue;
@@ -519,7 +526,7 @@
 		SetFileAttributes(pData->pathDstFile.ToString(), FILE_ATTRIBUTE_NORMAL);
 
 	// open destination file, handle the failures and possibly existence of the destination file
-	unsigned long long ullSeekTo = 0;
+	unsigned long long ullSeekTo = m_tProgressInfo.GetCurrentFileProcessedSize();
 	bool bDstFileFreshlyCreated = false;
 
 	if(m_tProgressInfo.GetCurrentFileProcessedSize() == 0)
@@ -531,10 +538,11 @@
 			return eResult;
 		else if(!fileDst.IsOpen())
 		{
-			// new stats
-			m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
-			m_tSubTaskStats.IncreaseCurrentItemProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
+			unsigned long long ullDiff = pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize();
 
+			m_tSubTaskStats.IncreaseProcessedSize(ullDiff);
+			m_tSubTaskStats.IncreaseCurrentItemProcessedSize(ullDiff);
+
 			pData->bProcessed = false;
 			bSkip = true;
 			return TSubTaskBase::eSubResult_Continue;
@@ -548,24 +556,25 @@
 			return eResult;
 		else if(!fileDst.IsOpen())
 		{
-			// new stats
-			m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
-			m_tSubTaskStats.IncreaseCurrentItemProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
+			unsigned long long ullDiff = pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize();
 
+			m_tSubTaskStats.IncreaseProcessedSize(ullDiff);
+			m_tSubTaskStats.IncreaseCurrentItemProcessedSize(ullDiff);
+
 			pData->bProcessed = false;
 			bSkip = true;
 			return TSubTaskBase::eSubResult_Continue;
 		}
-
-		ullSeekTo = m_tProgressInfo.GetCurrentFileProcessedSize();
 	}
 
 	if(pData->bOnlyCreate)
 	{
 		// we don't copy contents, but need to increase processed size
-		// new stats
-		m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
-		m_tSubTaskStats.IncreaseCurrentItemProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
+		unsigned long long ullDiff = pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize();
+
+		m_tSubTaskStats.IncreaseProcessedSize(ullDiff);
+		m_tSubTaskStats.IncreaseCurrentItemProcessedSize(ullDiff);
+
 		return TSubTaskBase::eSubResult_Continue;
 	}
 
@@ -580,10 +589,11 @@
 			return eResult;
 		else if(bSkip)
 		{
-			// new stats
-			m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
-			m_tSubTaskStats.IncreaseCurrentItemProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
+			unsigned long long ullDiff = pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize();
 
+			m_tSubTaskStats.IncreaseProcessedSize(ullDiff);
+			m_tSubTaskStats.IncreaseCurrentItemProcessedSize(ullDiff);
+
 			pData->bProcessed = false;
 			return TSubTaskBase::eSubResult_Continue;
 		}
@@ -594,18 +604,29 @@
 		else if(bSkip)
 		{
 			// with either first or second seek we got 'skip' answer...
-			// new stats
-			m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
-			m_tSubTaskStats.IncreaseCurrentItemProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
+			unsigned long long ullDiff = pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize();
 
+			m_tSubTaskStats.IncreaseProcessedSize(ullDiff);
+			m_tSubTaskStats.IncreaseCurrentItemProcessedSize(ullDiff);
+
 			pData->bProcessed = false;
 			return TSubTaskBase::eSubResult_Continue;
 		}
 
-		m_tProgressInfo.IncreaseCurrentFileProcessedSize(ullMove);
-		// new stats
-		m_tSubTaskStats.IncreaseProcessedSize(ullMove);
-		m_tSubTaskStats.IncreaseCurrentItemProcessedSize(ullMove);
+		// ullSeekTo (== m_tProgressInfo.GetCurrentFileProcessedSize()) is already a part of stats
+		// so the only correction that might need to be done is subtracting the difference
+		// between stored last file position (aka ullSeekTo) and the real position
+		// to which the file pos was set to.
+		m_tSubTaskStats.SetCurrentItemProcessedSize(ullMove);
+		if(ullMove < ullSeekTo)
+		{
+			unsigned long long ullDiff = ullSeekTo - ullMove;
+
+			m_tProgressInfo.DecreaseCurrentFileProcessedSize(ullDiff);
+			// new stats
+			m_tSubTaskStats.IncreaseProcessedSize(ullMove);
+			m_tSubTaskStats.IncreaseCurrentItemProcessedSize(ullMove);
+		}
 	}
 
 	// if the destination file already exists - truncate it to the current file position
Index: src/libchcore/TSubTaskCopyMove.h
===================================================================
diff -u -r19925be73ffcadd9f345f10e03e55aadb3f0eeac -rd0bc3c187684f54894c7280a936d5507a5e49f35
--- src/libchcore/TSubTaskCopyMove.h	(.../TSubTaskCopyMove.h)	(revision 19925be73ffcadd9f345f10e03e55aadb3f0eeac)
+++ src/libchcore/TSubTaskCopyMove.h	(.../TSubTaskCopyMove.h)	(revision d0bc3c187684f54894c7280a936d5507a5e49f35)
@@ -61,6 +61,7 @@
 		void SetCurrentFileProcessedSize(unsigned long long ullSize);
 		unsigned long long GetCurrentFileProcessedSize() const;
 		void IncreaseCurrentFileProcessedSize(unsigned long long ullSizeToAdd);
+		void DecreaseCurrentFileProcessedSize(unsigned long long ullSizeToSubtract);
 
 		void Store(const ISerializerRowDataPtr& spRowData) const;
 		static void InitLoader(const IColumnsDefinitionPtr& spColumns);
Index: src/libchcore/TSubTaskStatsInfo.cpp
===================================================================
diff -u -r19925be73ffcadd9f345f10e03e55aadb3f0eeac -rd0bc3c187684f54894c7280a936d5507a5e49f35
--- src/libchcore/TSubTaskStatsInfo.cpp	(.../TSubTaskStatsInfo.cpp)	(revision 19925be73ffcadd9f345f10e03e55aadb3f0eeac)
+++ src/libchcore/TSubTaskStatsInfo.cpp	(.../TSubTaskStatsInfo.cpp)	(revision d0bc3c187684f54894c7280a936d5507a5e49f35)
@@ -61,7 +61,8 @@
 	m_ullCurrentItemProcessedSize(m_setModifications, 0),
 	m_ullCurrentItemTotalSize(m_setModifications, 0),
 	m_eSubOperationType(m_setModifications, eSubOperation_None),
-	m_tTimer(m_setModifications)
+	m_tTimer(m_setModifications),
+	m_bIsInitialized(m_setModifications, false)
 {
 }
 
@@ -80,6 +81,7 @@
 	m_ullCurrentItemProcessedSize = 0;
 	m_ullCurrentItemTotalSize = 0;
 	m_eSubOperationType = eSubOperation_None;
+	m_bIsInitialized = false;
 }
 
 void TSubTaskStatsInfo::GetSnapshot(TSubTaskStatsSnapshotPtr& spStatsSnapshot) const
@@ -137,7 +139,7 @@
 {
 	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 
-	m_tCountSpeed.Modify().AddSample(stProcessedCount - m_stProcessedCount, m_tTimer.Modify().Tick());
+	m_tCountSpeed.Modify().AddSample(0/*stProcessedCount - m_stProcessedCount*/, m_tTimer.Modify().Tick());
 
 	m_stProcessedCount = stProcessedCount;
 
@@ -167,11 +169,24 @@
 		THROW_CORE_EXCEPTION(eErr_InternalProblem);
 }
 
+void TSubTaskStatsInfo::DecreaseProcessedSize(unsigned long long ullDecreaseBy)
+{
+	boost::unique_lock<boost::shared_mutex> lock(m_lock);
+	m_ullProcessedSize.Modify() -= ullDecreaseBy;
+
+	// we didn't process anything here - hence the 0-sized sample
+	m_tSizeSpeed.Modify().AddSample(0, m_tTimer.Modify().Tick());
+
+	_ASSERTE(m_ullProcessedSize <= m_ullTotalSize);
+	if(m_ullProcessedSize > m_ullTotalSize)
+		THROW_CORE_EXCEPTION(eErr_InternalProblem);
+}
+
 void TSubTaskStatsInfo::SetProcessedSize(unsigned long long ullProcessedSize)
 {
 	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 
-	m_tSizeSpeed.Modify().AddSample(ullProcessedSize - m_ullProcessedSize, m_tTimer.Modify().Tick());
+	m_tSizeSpeed.Modify().AddSample(0/*ullProcessedSize - m_ullProcessedSize*/, m_tTimer.Modify().Tick());
 
 	m_ullProcessedSize = ullProcessedSize;
 	_ASSERTE(m_ullProcessedSize <= m_ullTotalSize);
@@ -199,6 +214,16 @@
 		THROW_CORE_EXCEPTION(eErr_InternalProblem);
 }
 
+void TSubTaskStatsInfo::DecreaseCurrentItemProcessedSize(unsigned long long ullDecreaseBy)
+{
+	boost::unique_lock<boost::shared_mutex> lock(m_lock);
+	m_ullCurrentItemProcessedSize.Modify() -= ullDecreaseBy;
+
+	_ASSERTE(m_ullCurrentItemProcessedSize <= m_ullCurrentItemTotalSize);
+	if(m_ullCurrentItemProcessedSize > m_ullCurrentItemTotalSize)
+		THROW_CORE_EXCEPTION(eErr_InternalProblem);
+}
+
 void TSubTaskStatsInfo::SetCurrentItemProcessedSize(unsigned long long ullProcessedSize)
 {
 	boost::unique_lock<boost::shared_mutex> lock(m_lock);
@@ -258,6 +283,8 @@
 
 	if(m_bSubTaskIsRunning.IsModified())
 		*spRowData % TRowData(_T("is_running"), m_bSubTaskIsRunning);
+	if(m_bIsInitialized.IsModified())
+		*spRowData % TRowData(_T("is_initialized"), m_bIsInitialized);
 
 	if(m_ullTotalSize.IsModified())
 		*spRowData % TRowData(_T("total_size"), m_ullTotalSize);
@@ -300,6 +327,7 @@
 
 	*spColumnDefs 
 		% _T("is_running")
+		% _T("is_initialized")
 		% _T("total_size")
 		% _T("processed_size")
 		% _T("size_speed")
@@ -319,6 +347,7 @@
 	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 
 	spRowReader->GetValue(_T("is_running"), m_bSubTaskIsRunning.Modify());
+	spRowReader->GetValue(_T("is_initialized"), m_bIsInitialized.Modify());
 
 	spRowReader->GetValue(_T("total_size"), m_ullTotalSize.Modify());
 
@@ -349,4 +378,39 @@
 	m_setModifications.reset();
 }
 
+void TSubTaskStatsInfo::Init(int iCurrentBufferIndex, size_t stTotalCount, size_t stProcessedCount, unsigned long long ullTotalSize, unsigned long long ullProcessedSize, const TString& strCurrentPath)
+{
+	boost::unique_lock<boost::shared_mutex> lock(m_lock);
+
+	if(m_bIsInitialized)
+		THROW_CORE_EXCEPTION(eErr_InvalidData);
+
+	m_iCurrentBufferIndex = iCurrentBufferIndex;
+
+	m_stTotalCount = stTotalCount;
+	m_stProcessedCount = stProcessedCount;
+
+	_ASSERTE(m_stProcessedCount <= m_stTotalCount);
+	if(m_stProcessedCount > m_stTotalCount)
+		THROW_CORE_EXCEPTION(eErr_InternalProblem);
+
+	m_ullTotalSize = ullTotalSize;
+	m_ullProcessedSize = ullProcessedSize;
+	_ASSERTE(m_ullProcessedSize <= m_ullTotalSize);
+	if(m_ullProcessedSize > m_ullTotalSize)
+		THROW_CORE_EXCEPTION(eErr_InternalProblem);
+
+	m_strCurrentPath = strCurrentPath;
+
+	m_bIsInitialized = true;
+}
+
+bool TSubTaskStatsInfo::IsInitialized() const
+{
+	boost::shared_lock<boost::shared_mutex> lock(m_lock);
+	bool bInitialized = m_bIsInitialized;
+
+	return bInitialized;
+}
+
 END_CHCORE_NAMESPACE
Index: src/libchcore/TSubTaskStatsInfo.h
===================================================================
diff -u -r19925be73ffcadd9f345f10e03e55aadb3f0eeac -rd0bc3c187684f54894c7280a936d5507a5e49f35
--- src/libchcore/TSubTaskStatsInfo.h	(.../TSubTaskStatsInfo.h)	(revision 19925be73ffcadd9f345f10e03e55aadb3f0eeac)
+++ src/libchcore/TSubTaskStatsInfo.h	(.../TSubTaskStatsInfo.h)	(revision d0bc3c187684f54894c7280a936d5507a5e49f35)
@@ -63,8 +63,11 @@
 public:
 	TSubTaskStatsInfo();
 
+	void Init(int iCurrentBufferIndex, size_t stTotalCount, size_t stProcessedCount, unsigned long long ullTotalSize, unsigned long long ullProcessedSize, const TString& strCurrentPath);
 	void Clear();
 
+	bool IsInitialized() const;
+
 	void GetSnapshot(TSubTaskStatsSnapshotPtr& spStatsSnapshot) const;
 
 	void IncreaseProcessedCount(size_t stIncreaseBy);
@@ -74,12 +77,14 @@
 
 	// size stats
 	void IncreaseProcessedSize(unsigned long long ullIncreaseBy);
+	void DecreaseProcessedSize(unsigned long long ullDecreaseBy);
 	void SetProcessedSize(unsigned long long ullProcessedSize);
 
 	void SetTotalSize(unsigned long long ullTotalSize);
 
 	// current item
 	void IncreaseCurrentItemProcessedSize(unsigned long long ullIncreaseBy);
+	void DecreaseCurrentItemProcessedSize(unsigned long long ullDecreaseBy);
 	void SetCurrentItemProcessedSize(unsigned long long ullProcessedSize);
 
 	void SetCurrentItemTotalSize(unsigned long long ullTotalSize);
@@ -128,6 +133,7 @@
 		eMod_CurrentBufferIndex,
 		eMod_CurrentPath,
 		eMod_SubOperationType,
+		eMod_IsInitialized,
 
 		// last item
 		eMod_Last
@@ -157,6 +163,8 @@
 
 	TSharedModificationTracker<ESubOperationType, Bitset, eMod_SubOperationType> m_eSubOperationType;
 
+	TSharedModificationTracker<bool, Bitset, eMod_IsInitialized> m_bIsInitialized;
+
 #pragma warning(push)
 #pragma warning(disable: 4251)
 	mutable boost::shared_mutex m_lock;
Index: src/libchcore/TTask.cpp
===================================================================
diff -u -r19925be73ffcadd9f345f10e03e55aadb3f0eeac -rd0bc3c187684f54894c7280a936d5507a5e49f35
--- src/libchcore/TTask.cpp	(.../TTask.cpp)	(revision 19925be73ffcadd9f345f10e03e55aadb3f0eeac)
+++ src/libchcore/TTask.cpp	(.../TTask.cpp)	(revision d0bc3c187684f54894c7280a936d5507a5e49f35)
@@ -153,6 +153,10 @@
 		m_tLocalStats.Load(spContainer);
 
 		m_tSubTasksArray.Load(m_spSerializer);
+
+		// ensure copy-based context entries are properly updated after loading
+		m_tSubTaskContext.SetDestinationPath(m_tBaseData.GetDestinationPath());
+		m_tSubTaskContext.SetOperationType(m_tSubTasksArray.GetOperationType());
 	}
 }
 
Index: src/libchcore/TTaskManager.cpp
===================================================================
diff -u -r1f438ded9f2d8e972ed7c6840793b2faf8e3b9c8 -rd0bc3c187684f54894c7280a936d5507a5e49f35
--- src/libchcore/TTaskManager.cpp	(.../TTaskManager.cpp)	(revision 1f438ded9f2d8e972ed7c6840793b2faf8e3b9c8)
+++ src/libchcore/TTaskManager.cpp	(.../TTaskManager.cpp)	(revision d0bc3c187684f54894c7280a936d5507a5e49f35)
@@ -33,9 +33,11 @@
 // TTaskManager members
 TTaskManager::TTaskManager(const ISerializerFactoryPtr& spSerializerFactory,
 						const IFeedbackHandlerFactoryPtr& spFeedbackHandlerFactory,
+						const TSmartPath& pathLogDir,
 						bool bForceRecreateSerializer) :
 	m_spSerializerFactory(spSerializerFactory),
-	m_spFeedbackFactory(spFeedbackHandlerFactory)
+	m_spFeedbackFactory(spFeedbackHandlerFactory),
+	m_pathLogDir(pathLogDir)
 {
 	if(!spFeedbackHandlerFactory || !spSerializerFactory)
 		THROW_CORE_EXCEPTION(eErr_InvalidPointer);
Index: src/libchcore/TTaskManager.h
===================================================================
diff -u -r293e52b38d46653068006262172018a0f0d0a31c -rd0bc3c187684f54894c7280a936d5507a5e49f35
--- src/libchcore/TTaskManager.h	(.../TTaskManager.h)	(revision 293e52b38d46653068006262172018a0f0d0a31c)
+++ src/libchcore/TTaskManager.h	(.../TTaskManager.h)	(revision d0bc3c187684f54894c7280a936d5507a5e49f35)
@@ -40,6 +40,7 @@
 public:
 	TTaskManager(const ISerializerFactoryPtr& spSerializerFactory,
 		const IFeedbackHandlerFactoryPtr& spFeedbackHandlerFactory,
+		const TSmartPath& pathLogDir,
 		bool bForceRecreateSerializer = false);
 
 	~TTaskManager();