Fisheye: tag 4d20d0e58f37f06ac91287015b960308db54d47e is not in file src/libchcore/ESubTaskTypes.h
Index: src/libchcore/ErrorCodes.h
===================================================================
diff -u -r25b3c85ea493809ee084271d5101a015d349da95 -r835e0344e9677ff02eb3b539061c48c9f3a616ce
--- src/libchcore/ErrorCodes.h	(.../ErrorCodes.h)	(revision 25b3c85ea493809ee084271d5101a015d349da95)
+++ src/libchcore/ErrorCodes.h	(.../ErrorCodes.h)	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
@@ -75,7 +75,7 @@
 
 	// Task handling errors
 	eErr_MissingTaskSerializationPath = 4000,
-
+	eErr_UndefinedOperation = 4001,
 };
 
 END_CHCORE_NAMESPACE
Index: src/libchcore/TFileInfoArray.cpp
===================================================================
diff -u -r25b3c85ea493809ee084271d5101a015d349da95 -r835e0344e9677ff02eb3b539061c48c9f3a616ce
--- src/libchcore/TFileInfoArray.cpp	(.../TFileInfoArray.cpp)	(revision 25b3c85ea493809ee084271d5101a015d349da95)
+++ src/libchcore/TFileInfoArray.cpp	(.../TFileInfoArray.cpp)	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
@@ -31,7 +31,8 @@
 ///////////////////////////////////////////////////////////////////////
 // Array
 TFileInfoArray::TFileInfoArray(const TPathContainer& rBasePaths) :
-	m_rBasePaths(rBasePaths)
+	m_rBasePaths(rBasePaths),
+	m_bComplete(false)
 {
 }
 
@@ -78,6 +79,7 @@
 {
 	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 	m_vFiles.clear();
+	m_bComplete = false;
 }
 
 unsigned long long TFileInfoArray::CalculateTotalSize()
@@ -93,10 +95,24 @@
 	return ullSize;
 }
 
+void TFileInfoArray::SetComplete(bool bComplete)
+{
+	boost::unique_lock<boost::shared_mutex> lock(m_lock);
+	m_bComplete = bComplete;
+}
+
+bool TFileInfoArray::IsComplete() const
+{
+	boost::shared_lock<boost::shared_mutex> lock(m_lock);
+	return m_bComplete;
+}
+
 void TFileInfoArray::Serialize(TReadBinarySerializer& rSerializer, bool bOnlyFlags)
 {
 	using Serializers::Serialize;
 
+	boost::unique_lock<boost::shared_mutex> lock(m_lock);
+
 	size_t stCount;
 	Serialize(rSerializer, stCount);
 
@@ -127,24 +143,33 @@
 			m_vFiles.push_back(spFileInfo);
 		}
 	}
+
+	// we assume here that if the array was saved with at least one item, then it must have been complete at the time of writing
+	if(!bOnlyFlags && stCount > 0)
+		m_bComplete = true;
 }
 
 void TFileInfoArray::Serialize(TWriteBinarySerializer& rSerializer, bool bOnlyFlags) const
 {
 	using Serializers::Serialize;
 
-	size_t stCount = m_vFiles.size();
+	boost::shared_lock<boost::shared_mutex> lock(m_lock);
+
+	size_t stCount = m_bComplete ? m_vFiles.size() : 0;
 	Serialize(rSerializer, stCount);
 
-	for(std::vector<TFileInfoPtr>::const_iterator iterFile = m_vFiles.begin(); iterFile != m_vFiles.end(); ++iterFile)
+	if(m_bComplete)
 	{
-		if(bOnlyFlags)
+		for(std::vector<TFileInfoPtr>::const_iterator iterFile = m_vFiles.begin(); iterFile != m_vFiles.end(); ++iterFile)
 		{
-			uint_t uiFlags = (*iterFile)->GetFlags();
-			Serialize(rSerializer, uiFlags);
+			if(bOnlyFlags)
+			{
+				uint_t uiFlags = (*iterFile)->GetFlags();
+				Serialize(rSerializer, uiFlags);
+			}
+			else
+				Serialize(rSerializer, *(*iterFile));
 		}
-		else
-			Serialize(rSerializer, *(*iterFile));
 	}
 }
 
Index: src/libchcore/TFileInfoArray.h
===================================================================
diff -u -r25b3c85ea493809ee084271d5101a015d349da95 -r835e0344e9677ff02eb3b539061c48c9f3a616ce
--- src/libchcore/TFileInfoArray.h	(.../TFileInfoArray.h)	(revision 25b3c85ea493809ee084271d5101a015d349da95)
+++ src/libchcore/TFileInfoArray.h	(.../TFileInfoArray.h)	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
@@ -62,12 +62,16 @@
 	/// Calculates the size of all file info objects inside this object
 	unsigned long long CalculateTotalSize();
 
+	void SetComplete(bool bComplete);
+	bool IsComplete() const;
+
 	/// Stores infos about elements in the archive
 	void Serialize(TReadBinarySerializer& rSerializer, bool bOnlyFlags);
 	void Serialize(TWriteBinarySerializer& rSerializer, bool bOnlyFlags) const;
 
 protected:
 	const TPathContainer& m_rBasePaths;
+	bool m_bComplete;
 
 #pragma warning(push)
 #pragma warning(disable: 4251)
Index: src/libchcore/TSubTaskArray.cpp
===================================================================
diff -u
--- src/libchcore/TSubTaskArray.cpp	(revision 0)
+++ src/libchcore/TSubTaskArray.cpp	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
@@ -0,0 +1,97 @@
+// ============================================================================
+//  Copyright (C) 2001-2011 by Jozef Starosczyk
+//  ixen@copyhandler.com
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU Library General Public License
+//  (version 2) as published by the Free Software Foundation;
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU Library General Public
+//  License along with this program; if not, write to the
+//  Free Software Foundation, Inc.,
+//  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// ============================================================================
+/// @file  TSubTaskArray.cpp
+/// @date  2011/11/08
+/// @brief File contain implementation of a class handling a sequence of subtasks.
+// ============================================================================
+#include "stdafx.h"
+#include "TSubTaskArray.h"
+#include "TTaskOperationPlan.h"
+#include <boost\smart_ptr\make_shared.hpp>
+#include "TSubTaskScanDirectory.h"
+#include "TSubTaskCopyMove.h"
+#include "TSubTaskDelete.h"
+#include "TSubTaskContext.h"
+#include "TBasicProgressInfo.h"
+#include "TTaskLocalStats.h"
+
+BEGIN_CHCORE_NAMESPACE
+
+TSubTasksArray::TSubTasksArray(const TOperationPlan& rOperationPlan, TSubTaskContext& rSubTaskContext) :
+	m_rSubTaskContext(rSubTaskContext)
+{
+	switch(rOperationPlan.GetOperationType())
+	{
+	case eOperation_Copy:
+		{
+			TSubTaskBasePtr spOperation = boost::make_shared<TSubTaskScanDirectories>(boost::ref(rSubTaskContext));
+			m_vSubTasks.push_back(boost::make_tuple(spOperation, 0.05, true));
+			spOperation = boost::make_shared<TSubTaskCopyMove>(boost::ref(rSubTaskContext));
+			m_vSubTasks.push_back(boost::make_tuple(spOperation, 0.95, false));
+
+			break;
+		}
+	case eOperation_Move:
+		{
+			TSubTaskBasePtr spOperation = boost::make_shared<TSubTaskScanDirectories>(boost::ref(rSubTaskContext));
+			m_vSubTasks.push_back(boost::make_tuple(spOperation, 0.05, true));
+			spOperation = boost::make_shared<TSubTaskCopyMove>(boost::ref(rSubTaskContext));
+			m_vSubTasks.push_back(boost::make_tuple(spOperation, 0.90, false));
+			spOperation = boost::make_shared<TSubTaskDelete>(boost::ref(rSubTaskContext));
+			m_vSubTasks.push_back(boost::make_tuple(spOperation, 0.05, false));
+
+			break;
+		}
+	default:
+		THROW_CORE_EXCEPTION(eErr_UndefinedOperation);
+	}
+}
+
+TSubTasksArray::~TSubTasksArray()
+{
+}
+
+TSubTaskBase::ESubOperationResult TSubTasksArray::Execute(bool bRunOnlyEstimationSubTasks)
+{
+	TSubTaskBase::ESubOperationResult eResult = TSubTaskBase::eSubResult_Continue;
+
+	size_t stSubOperationIndex = m_rSubTaskContext.GetTaskBasicProgressInfo().GetSubOperationIndex();
+	for(; stSubOperationIndex < m_vSubTasks.size() && eResult == TSubTaskBase::eSubResult_Continue; ++stSubOperationIndex)
+	{
+		boost::tuples::tuple<TSubTaskBasePtr, double, bool>& rCurrentSubTask = m_vSubTasks[stSubOperationIndex];
+		TSubTaskBasePtr spCurrentSubTask = rCurrentSubTask.get<0>();
+
+		m_rSubTaskContext.GetTaskLocalStats().SetCurrentSubOperationType(spCurrentSubTask->GetSubOperationType());
+		// set current sub-operation index to allow resuming
+		m_rSubTaskContext.GetTaskBasicProgressInfo().SetSubOperationIndex(stSubOperationIndex);
+
+		// if we run in estimation mode only, then stop processing and return to the caller
+		if(bRunOnlyEstimationSubTasks && !rCurrentSubTask.get<2>())
+		{
+			eResult = TSubTaskBase::eSubResult_Continue;
+			break;
+		}
+
+		eResult = spCurrentSubTask->Exec();
+	}
+
+	return eResult;
+}
+
+END_CHCORE_NAMESPACE
Index: src/libchcore/TSubTaskArray.h
===================================================================
diff -u
--- src/libchcore/TSubTaskArray.h	(revision 0)
+++ src/libchcore/TSubTaskArray.h	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
@@ -0,0 +1,57 @@
+// ============================================================================
+//  Copyright (C) 2001-2011 by Jozef Starosczyk
+//  ixen@copyhandler.com
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU Library General Public License
+//  (version 2) as published by the Free Software Foundation;
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU Library General Public
+//  License along with this program; if not, write to the
+//  Free Software Foundation, Inc.,
+//  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// ============================================================================
+/// @file  TSubTaskArray.h
+/// @date  2011/11/08
+/// @brief File contain definition of a class handling a sequence of subtasks.
+// ============================================================================
+#ifndef __TSUBTASKSARRAY_H__
+#define __TSUBTASKSARRAY_H__
+
+#include "libchcore.h"
+#include <boost/tuple/tuple.hpp>
+#include "TSubTaskBase.h"
+
+BEGIN_CHCORE_NAMESPACE
+
+class TOperationPlan;
+class TSubTaskContext;
+
+class LIBCHCORE_API TSubTasksArray
+{
+public:
+	TSubTasksArray(const TOperationPlan& rOperationPlan, TSubTaskContext& rSubTaskContext);
+	~TSubTasksArray();
+
+	TSubTaskBase::ESubOperationResult Execute(bool bRunOnlyEstimationSubTasks);
+
+private:
+	TSubTasksArray(const TSubTasksArray& rSrc);
+	TSubTasksArray& operator=(const TSubTasksArray& rSrc);
+
+private:
+#pragma warning(push)
+#pragma warning(disable: 4251)
+	std::vector<boost::tuples::tuple<TSubTaskBasePtr, double, bool> > m_vSubTasks;	// pointer to the subtask object / part of the whole process / is this the part of estimation?
+#pragma warning(pop)
+	TSubTaskContext& m_rSubTaskContext;
+};
+
+END_CHCORE_NAMESPACE
+
+#endif
Index: src/libchcore/TSubTaskBase.h
===================================================================
diff -u -r25b3c85ea493809ee084271d5101a015d349da95 -r835e0344e9677ff02eb3b539061c48c9f3a616ce
--- src/libchcore/TSubTaskBase.h	(.../TSubTaskBase.h)	(revision 25b3c85ea493809ee084271d5101a015d349da95)
+++ src/libchcore/TSubTaskBase.h	(.../TSubTaskBase.h)	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
@@ -25,6 +25,7 @@
 
 #include "libchcore.h"
 #include "TPath.h"
+#include "ESubTaskTypes.h"
 
 BEGIN_CHCORE_NAMESPACE
 
@@ -52,6 +53,7 @@
 	virtual ~TSubTaskBase();
 
 	virtual ESubOperationResult Exec() = 0;
+	virtual ESubOperationType GetSubOperationType() const = 0;
 
 	TSubTaskContext& GetContext() { return m_rContext; }
 	const TSubTaskContext& GetContext() const { return m_rContext; }
@@ -69,6 +71,8 @@
 	TSubTaskContext& m_rContext;
 };
 
+typedef boost::shared_ptr<TSubTaskBase> TSubTaskBasePtr;
+
 END_CHCORE_NAMESPACE
 
 #endif
Index: src/libchcore/TSubTaskCopyMove.h
===================================================================
diff -u -r4d20d0e58f37f06ac91287015b960308db54d47e -r835e0344e9677ff02eb3b539061c48c9f3a616ce
--- src/libchcore/TSubTaskCopyMove.h	(.../TSubTaskCopyMove.h)	(revision 4d20d0e58f37f06ac91287015b960308db54d47e)
+++ src/libchcore/TSubTaskCopyMove.h	(.../TSubTaskCopyMove.h)	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
@@ -38,7 +38,8 @@
 public:
 	TSubTaskCopyMove(TSubTaskContext& tSubTaskContext);
 
-	ESubOperationResult Exec();
+	virtual ESubOperationResult Exec();
+	virtual ESubOperationType GetSubOperationType() const { return eSubOperation_Copying; }
 
 private:
 	bool GetMove(const TFileInfoPtr& spFileInfo);
Index: src/libchcore/TSubTaskDelete.h
===================================================================
diff -u -r4d20d0e58f37f06ac91287015b960308db54d47e -r835e0344e9677ff02eb3b539061c48c9f3a616ce
--- src/libchcore/TSubTaskDelete.h	(.../TSubTaskDelete.h)	(revision 4d20d0e58f37f06ac91287015b960308db54d47e)
+++ src/libchcore/TSubTaskDelete.h	(.../TSubTaskDelete.h)	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
@@ -33,7 +33,8 @@
 public:
 	TSubTaskDelete(TSubTaskContext& rContext);
 
-	ESubOperationResult Exec();
+	virtual ESubOperationResult Exec();
+	virtual ESubOperationType GetSubOperationType() const { return eSubOperation_Deleting; }
 };
 
 END_CHCORE_NAMESPACE
Index: src/libchcore/TSubTaskScanDirectory.cpp
===================================================================
diff -u -rba802caea92ee56a154d1da3fe89a4b2f7875f0e -r835e0344e9677ff02eb3b539061c48c9f3a616ce
--- src/libchcore/TSubTaskScanDirectory.cpp	(.../TSubTaskScanDirectory.cpp)	(revision ba802caea92ee56a154d1da3fe89a4b2f7875f0e)
+++ src/libchcore/TSubTaskScanDirectory.cpp	(.../TSubTaskScanDirectory.cpp)	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
@@ -61,6 +61,7 @@
 	rLog.logi(_T("Searching for files..."));
 
 	// reset progress
+	rFilesCache.SetComplete(false);
 	rTaskLocalStats.SetProcessedSize(0);
 	rTaskLocalStats.SetTotalSize(0);
 
@@ -217,6 +218,7 @@
 
 	// calc size of all files
 	rTaskLocalStats.SetTotalSize(rFilesCache.CalculateTotalSize());
+	rFilesCache.SetComplete(true);
 
 	// log
 	rLog.logi(_T("Searching for files finished"));
Index: src/libchcore/TSubTaskScanDirectory.h
===================================================================
diff -u -rba802caea92ee56a154d1da3fe89a4b2f7875f0e -r835e0344e9677ff02eb3b539061c48c9f3a616ce
--- src/libchcore/TSubTaskScanDirectory.h	(.../TSubTaskScanDirectory.h)	(revision ba802caea92ee56a154d1da3fe89a4b2f7875f0e)
+++ src/libchcore/TSubTaskScanDirectory.h	(.../TSubTaskScanDirectory.h)	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
@@ -41,6 +41,7 @@
 	virtual ~TSubTaskScanDirectories();
 
 	virtual ESubOperationResult Exec();
+	virtual ESubOperationType GetSubOperationType() const { return eSubOperation_Scanning; }
 
 private:
 	int ScanDirectory(TSmartPath pathDirName, size_t stSrcIndex, bool bRecurse, bool bIncludeDirs, TFileFiltersArray& afFilters);
Index: src/libchcore/TTask.cpp
===================================================================
diff -u -r25b3c85ea493809ee084271d5101a015d349da95 -r835e0344e9677ff02eb3b539061c48c9f3a616ce
--- src/libchcore/TTask.cpp	(.../TTask.cpp)	(revision 25b3c85ea493809ee084271d5101a015d349da95)
+++ src/libchcore/TTask.cpp	(.../TTask.cpp)	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
@@ -38,6 +38,7 @@
 #include <atlconv.h>
 #include "DataBuffer.h"
 #include "TFileInfo.h"
+#include "TSubTaskArray.h"
 
 BEGIN_CHCORE_NAMESPACE
 
@@ -229,14 +230,7 @@
 
 		m_arrSourcePathsInfo.Serialize(writeSerializer, true);
 
-		ESubOperationType eSubOperation = m_tTaskDefinition.GetOperationPlan().GetSubOperationAt(m_tTaskBasicProgressInfo.GetSubOperationIndex());
-		if(eSubOperation != eSubOperation_Scanning)
-			m_files.Serialize(writeSerializer, false);
-		else
-		{
-			size_t stFakeSize(0);
-			Serialize(writeSerializer, stFakeSize);
-		}
+		m_files.Serialize(writeSerializer, false);
 	}
 
 	if(m_bOftenStateModified)
@@ -258,14 +252,7 @@
 
 		m_arrSourcePathsInfo.Serialize(writeSerializer, false);
 
-		ESubOperationType eSubOperation = m_tTaskDefinition.GetOperationPlan().GetSubOperationAt(m_tTaskBasicProgressInfo.GetSubOperationIndex());
-		if(eSubOperation != eSubOperation_Scanning)
-			m_files.Serialize(writeSerializer, true);
-		else
-		{
-			size_t stFakeSize(0);
-			Serialize(writeSerializer, stFakeSize);
-		}
+		m_files.Serialize(writeSerializer, true);
 	}
 }
 
@@ -403,11 +390,11 @@
 	pData->m_eTaskState = m_eCurrentState;
 	pData->m_stIndex = stCurrentIndex;
 	pData->m_ullProcessedSize = m_localStats.GetProcessedSize();
-	pData->m_stSize=m_files.GetSize();
+	pData->m_stSize = m_files.GetSize();
 	pData->m_ullSizeAll = m_localStats.GetTotalSize();
 	pData->m_strUniqueName = m_tTaskDefinition.GetTaskUniqueID();
 	pData->m_eOperationType = m_tTaskDefinition.GetOperationType();
-	pData->m_eSubOperationType = m_tTaskDefinition.GetOperationPlan().GetSubOperationAt(m_tTaskBasicProgressInfo.GetSubOperationIndex());
+	pData->m_eSubOperationType = m_localStats.GetCurrentSubOperationType();
 
 	pData->m_bIgnoreDirectories = GetTaskPropValue<eTO_IgnoreDirectories>(m_tTaskDefinition.GetConfiguration());
 	pData->m_bCreateEmptyFiles = GetTaskPropValue<eTO_CreateEmptyFiles>(m_tTaskDefinition.GetConfiguration());
@@ -624,64 +611,23 @@
 		// determine when to scan directories
 		bool bReadTasksSize = GetTaskPropValue<eTO_ScanDirectoriesBeforeBlocking>(m_tTaskDefinition.GetConfiguration());
 
-		// wait for permission to really start (but only if search for files is not allowed to start regardless of the lock)
-		size_t stSubOperationIndex = m_tTaskBasicProgressInfo.GetSubOperationIndex();
-		if(!bReadTasksSize || stSubOperationIndex != 0 || m_tTaskDefinition.GetOperationPlan().GetSubOperationsCount() == 0 || m_tTaskDefinition.GetOperationPlan().GetSubOperationAt(0) != eSubOperation_Scanning)
-			eResult = CheckForWaitState();	// operation limiting
-
 		// start tracking time for this thread
 		m_localStats.EnableTimeTracking();
 
 		// prepare context for subtasks
 		TSubTaskContext tSubTaskContext(m_tTaskDefinition, m_arrSourcePathsInfo, m_files, m_localStats, m_tTaskBasicProgressInfo, m_cfgTracker, m_log, m_piFeedbackHandler, m_workerThread, m_fsLocal);
-
-		for(; stSubOperationIndex < m_tTaskDefinition.GetOperationPlan().GetSubOperationsCount() && eResult == TSubTaskBase::eSubResult_Continue; ++stSubOperationIndex)
+		TSubTasksArray tOperation(m_tTaskDefinition.GetOperationPlan(), tSubTaskContext);
+		
+		if(bReadTasksSize)
+			eResult = tOperation.Execute(true);
+		if(eResult == TSubTaskBase::eSubResult_Continue)
 		{
-			// set current sub-operation index to allow resuming
-			m_tTaskBasicProgressInfo.SetSubOperationIndex(stSubOperationIndex);
-
-			ESubOperationType eSubOperation = m_tTaskDefinition.GetOperationPlan().GetSubOperationAt(stSubOperationIndex);
-			switch(eSubOperation)
-			{
-			case eSubOperation_Scanning:
-				{
-					// start searching
-					TSubTaskScanDirectories tSubTaskScanDir(tSubTaskContext);
-					eResult = tSubTaskScanDir.Exec();
-
-					// if we didn't wait for permission to start earlier, then ask now (but only in case this is the first search)
-					if(eResult == TSubTaskBase::eSubResult_Continue && bReadTasksSize && stSubOperationIndex == 0)
-					{
-						m_localStats.DisableTimeTracking();
-
-						eResult = CheckForWaitState();
-
-						m_localStats.EnableTimeTracking();
-					}
-
-					break;
-				}
-
-			case eSubOperation_Copying:
-				{
-					TSubTaskCopyMove tSubTaskCopyMove(tSubTaskContext);
-
-					eResult = tSubTaskCopyMove.Exec();
-					break;
-				}
-
-			case eSubOperation_Deleting:
-				{
-					TSubTaskDelete tSubTaskDelete(tSubTaskContext);
-					eResult = tSubTaskDelete.Exec();
-					break;
-				}
-
-			default:
-				BOOST_ASSERT(false);
-				THROW_CORE_EXCEPTION(eErr_UnhandledCase);
-			}
+			m_localStats.DisableTimeTracking();
+			eResult = CheckForWaitState();	// operation limiting
+			m_localStats.EnableTimeTracking();
 		}
+		if(eResult == TSubTaskBase::eSubResult_Continue)
+			eResult = tOperation.Execute(false);
 
 		// change status to finished
 		if(eResult == TSubTaskBase::eSubResult_Continue)
@@ -723,14 +669,9 @@
 			THROW_CORE_EXCEPTION(eErr_UnhandledCase);
 		}
 
-		// perform cleanup dependent on currently executing subtask
-		switch(m_tTaskDefinition.GetOperationPlan().GetSubOperationAt(m_tTaskBasicProgressInfo.GetSubOperationIndex()))
-		{
-		case eSubOperation_Scanning:
-			m_files.Clear();		// get rid of m_files contents
-			m_bRareStateModified = true;
-			break;
-		}
+		// if the files cache is not completely read - clean it up
+		if(!m_files.IsComplete())
+			m_files.Clear();		// get rid of m_files contents; rare state not modified, since incomplete cache is not being stored
 
 		// save progress before killed
 		m_bOftenStateModified = true;
Index: src/libchcore/TTaskLocalStats.cpp
===================================================================
diff -u -rfb4c4006dee5aaf815d08bc3e89312445b994307 -r835e0344e9677ff02eb3b539061c48c9f3a616ce
--- src/libchcore/TTaskLocalStats.cpp	(.../TTaskLocalStats.cpp)	(revision fb4c4006dee5aaf815d08bc3e89312445b994307)
+++ src/libchcore/TTaskLocalStats.cpp	(.../TTaskLocalStats.cpp)	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
@@ -259,4 +259,16 @@
 	return iResult;
 }
 
+ESubOperationType TTaskLocalStats::GetCurrentSubOperationType() const
+{
+	boost::shared_lock<boost::shared_mutex> lock(m_lock);
+	return m_eCurrentSubOperationType;
+}
+
+void TTaskLocalStats::SetCurrentSubOperationType(ESubOperationType eSubOperationType)
+{
+	boost::unique_lock<boost::shared_mutex> lock(m_lock);
+	m_eCurrentSubOperationType = eSubOperationType;
+}
+
 END_CHCORE_NAMESPACE
Index: src/libchcore/TTaskLocalStats.h
===================================================================
diff -u -rfb4c4006dee5aaf815d08bc3e89312445b994307 -r835e0344e9677ff02eb3b539061c48c9f3a616ce
--- src/libchcore/TTaskLocalStats.h	(.../TTaskLocalStats.h)	(revision fb4c4006dee5aaf815d08bc3e89312445b994307)
+++ src/libchcore/TTaskLocalStats.h	(.../TTaskLocalStats.h)	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
@@ -24,6 +24,7 @@
 #define __TTASKLOCALSTATS_H__
 
 #include "libchcore.h"
+#include "ESubTaskTypes.h"
 
 BEGIN_CHCORE_NAMESPACE
 
@@ -65,6 +66,9 @@
 	void SetCurrentBufferIndex(int iCurrentIndex);
 	int GetCurrentBufferIndex() const;
 
+	ESubOperationType GetCurrentSubOperationType() const;
+	void SetCurrentSubOperationType(ESubOperationType eSubOperationType);
+
 private:
 	volatile unsigned long long m_ullProcessedSize;
 	volatile unsigned long long m_ullTotalSize;
@@ -77,6 +81,8 @@
 
 	volatile int m_iCurrentBufferIndex;
 
+	volatile ESubOperationType m_eCurrentSubOperationType;
+
 #pragma warning(push)
 #pragma warning(disable: 4251)
 	mutable boost::shared_mutex m_lock;
Index: src/libchcore/TTaskOperationPlan.h
===================================================================
diff -u -rbe30619d750d8663d54cf02e7d4bde2ed2dd8d05 -r835e0344e9677ff02eb3b539061c48c9f3a616ce
--- src/libchcore/TTaskOperationPlan.h	(.../TTaskOperationPlan.h)	(revision be30619d750d8663d54cf02e7d4bde2ed2dd8d05)
+++ src/libchcore/TTaskOperationPlan.h	(.../TTaskOperationPlan.h)	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
@@ -25,23 +25,13 @@
 
 #include "libchcore.h"
 #include "EOperationTypes.h"
+#include "ESubTaskTypes.h"
 
 BEGIN_CHCORE_NAMESPACE
 
 class TReadBinarySerializer;
 class TWriteBinarySerializer;
 
-enum ESubOperationType
-{
-	eSubOperation_None,
-	eSubOperation_Scanning,
-	eSubOperation_Copying,
-	eSubOperation_Deleting,
-
-	// add new operation types before this one
-	eSubOperation_Max
-};
-
 ///////////////////////////////////////////////////////////////////////////
 // TOperationPlan
 
@@ -58,13 +48,14 @@
 	void SetOperationType(EOperationType eOperation);
 	EOperationType GetOperationType() const;
 
+	void Serialize(TReadBinarySerializer& rSerializer);
+	void Serialize(TWriteBinarySerializer& rSerializer) const;
+
+private:
 	size_t GetSubOperationsCount() const;
 	ESubOperationType GetSubOperationAt(size_t stIndex) const;
 	double GetEstimatedTimeAt(size_t stIndex) const;
 
-	void Serialize(TReadBinarySerializer& rSerializer);
-	void Serialize(TWriteBinarySerializer& rSerializer) const;
-
 private:
 	EOperationType m_eOperation;
 #pragma warning(push)
Index: src/libchcore/libchcore.vc90.vcproj
===================================================================
diff -u -rba802caea92ee56a154d1da3fe89a4b2f7875f0e -r835e0344e9677ff02eb3b539061c48c9f3a616ce
--- src/libchcore/libchcore.vc90.vcproj	(.../libchcore.vc90.vcproj)	(revision ba802caea92ee56a154d1da3fe89a4b2f7875f0e)
+++ src/libchcore/libchcore.vc90.vcproj	(.../libchcore.vc90.vcproj)	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
@@ -463,6 +463,18 @@
 					Name="SubTasks"
 					>
 					<File
+						RelativePath=".\ESubTaskTypes.h"
+						>
+					</File>
+					<File
+						RelativePath=".\TSubTaskArray.cpp"
+						>
+					</File>
+					<File
+						RelativePath=".\TSubTaskArray.h"
+						>
+					</File>
+					<File
 						RelativePath=".\TSubTaskBase.cpp"
 						>
 					</File>