Index: src/ch/ch.rc
===================================================================
diff -u -rd88274a4bbfd4ef005d44c4d179b7596cb627486 -rbebda797ec6983535a8940f8f9f15453fe6b1785
--- src/ch/ch.rc	(.../ch.rc)	(revision d88274a4bbfd4ef005d44c4d179b7596cb627486)
+++ src/ch/ch.rc	(.../ch.rc)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
@@ -809,7 +809,7 @@
                             "Changed:\n%count paths primarily got from clipboard"
     IDS_TASKNOTPAUSED_STRING "Selected task isn't paused"
     IDS_TASKNOTSELECTED_STRING "Task not selected"
-    IDS_NONEINPUTFILE_STRING "(waiting...)"
+    IDS_NONEINPUTFILE_STRING "none"
 END
 
 STRINGTABLE 
Fisheye: Tag bebda797ec6983535a8940f8f9f15453fe6b1785 refers to a dead (removed) revision in file `src/libchcore/TBasicProgressInfo.cpp'.
Fisheye: No comparison available.  Pass `N' to diff?
Fisheye: Tag bebda797ec6983535a8940f8f9f15453fe6b1785 refers to a dead (removed) revision in file `src/libchcore/TBasicProgressInfo.h'.
Fisheye: No comparison available.  Pass `N' to diff?
Index: src/libchcore/TSubTaskArray.cpp
===================================================================
diff -u -r297ce850732d4243414c851df145ca97bd696baa -rbebda797ec6983535a8940f8f9f15453fe6b1785
--- src/libchcore/TSubTaskArray.cpp	(.../TSubTaskArray.cpp)	(revision 297ce850732d4243414c851df145ca97bd696baa)
+++ src/libchcore/TSubTaskArray.cpp	(.../TSubTaskArray.cpp)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
@@ -28,15 +28,101 @@
 #include "TSubTaskCopyMove.h"
 #include "TSubTaskDelete.h"
 #include "TSubTaskContext.h"
-#include "TBasicProgressInfo.h"
 #include "TTaskLocalStats.h"
 #include "TSubTaskFastMove.h"
+#include "SerializationHelpers.h"
+#include "TBinarySerializer.h"
 
 BEGIN_CHCORE_NAMESPACE
 
-TSubTasksArray::TSubTasksArray(const TOperationPlan& rOperationPlan, TSubTaskContext& rSubTaskContext) :
-	m_rSubTaskContext(rSubTaskContext)
+namespace details
 {
+	///////////////////////////////////////////////////////////////////////////
+	// TTaskBasicProgressInfo
+
+	TTaskBasicProgressInfo::TTaskBasicProgressInfo() :
+		m_stSubOperationIndex(0)
+	{
+	}
+
+	TTaskBasicProgressInfo::~TTaskBasicProgressInfo()
+	{
+	}
+
+	void TTaskBasicProgressInfo::ResetProgress()
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		m_stSubOperationIndex = 0;
+	}
+
+	void TTaskBasicProgressInfo::SetSubOperationIndex(size_t stSubOperationIndex)
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		m_stSubOperationIndex = stSubOperationIndex;
+	}
+
+	size_t TTaskBasicProgressInfo::GetSubOperationIndex() const
+	{
+		boost::shared_lock<boost::shared_mutex> lock(m_lock);
+		return m_stSubOperationIndex;
+	}
+
+	void TTaskBasicProgressInfo::IncreaseSubOperationIndex()
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		++m_stSubOperationIndex;
+	}
+
+	void TTaskBasicProgressInfo::Serialize(TReadBinarySerializer& rSerializer)
+	{
+		using Serializers::Serialize;
+
+		size_t stSubOperationIndex = 0;
+		Serialize(rSerializer, stSubOperationIndex);
+
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+
+		m_stSubOperationIndex = stSubOperationIndex;
+	}
+
+	void TTaskBasicProgressInfo::Serialize(TWriteBinarySerializer& rSerializer) const
+	{
+		using Serializers::Serialize;
+
+		size_t stSubOperationIndex = 0;
+		{
+			boost::shared_lock<boost::shared_mutex> lock(m_lock);
+			stSubOperationIndex = m_stSubOperationIndex;
+		}
+
+		Serialize(rSerializer, stSubOperationIndex);
+	}
+}
+
+///////////////////////////////////////////////////////////////////////////
+// TSubTasksArray
+
+TSubTasksArray::TSubTasksArray() :
+	m_pSubTaskContext(NULL)
+{
+}
+
+	TSubTasksArray::TSubTasksArray(const TOperationPlan& rOperationPlan, TSubTaskContext& rSubTaskContext) :
+m_pSubTaskContext(NULL)
+{
+	Init(rOperationPlan, rSubTaskContext);
+}
+
+TSubTasksArray::~TSubTasksArray()
+{
+}
+
+void TSubTasksArray::Init(const TOperationPlan& rOperationPlan, TSubTaskContext& rSubTaskContext)
+{
+	m_vSubTasks.clear();
+	m_tProgressInfo.ResetProgress();
+	m_pSubTaskContext = &rSubTaskContext;
+
 	switch(rOperationPlan.GetOperationType())
 	{
 	case eOperation_Copy:
@@ -66,24 +152,56 @@
 	}
 }
 
-TSubTasksArray::~TSubTasksArray()
+void TSubTasksArray::ResetProgress()
 {
+	m_tProgressInfo.ResetProgress();
+
+	boost::tuples::tuple<TSubTaskBasePtr, double, bool> tupleRow;
+	BOOST_FOREACH(tupleRow, m_vSubTasks)
+	{
+		if(tupleRow.get<0>() == NULL)
+			THROW_CORE_EXCEPTION(eErr_InternalProblem);
+
+		tupleRow.get<0>()->GetProgressInfo().ResetProgress();
+	}
 }
 
+void TSubTasksArray::SerializeProgress(TReadBinarySerializer& rSerializer)
+{
+	m_tProgressInfo.Serialize(rSerializer);
+	boost::tuples::tuple<TSubTaskBasePtr, double, bool> tupleRow;
+	BOOST_FOREACH(tupleRow, m_vSubTasks)
+	{
+		tupleRow.get<0>()->GetProgressInfo().Serialize(rSerializer);
+	}
+}
+
+void TSubTasksArray::SerializeProgress(TWriteBinarySerializer& rSerializer) const
+{
+	m_tProgressInfo.Serialize(rSerializer);
+	boost::tuples::tuple<TSubTaskBasePtr, double, bool> tupleRow;
+	BOOST_FOREACH(tupleRow, m_vSubTasks)
+	{
+		tupleRow.get<0>()->GetProgressInfo().Serialize(rSerializer);
+	}
+}
+
 TSubTaskBase::ESubOperationResult TSubTasksArray::Execute(bool bRunOnlyEstimationSubTasks)
 {
+	if(!m_pSubTaskContext)
+		THROW_CORE_EXCEPTION(eErr_InternalProblem);
+
 	TSubTaskBase::ESubOperationResult eResult = TSubTaskBase::eSubResult_Continue;
-	TTaskBasicProgressInfo& rBasicProgressInfo = m_rSubTaskContext.GetTaskBasicProgressInfo();
 
-	size_t stSubOperationIndex = m_rSubTaskContext.GetTaskBasicProgressInfo().GetSubOperationIndex();
+	size_t stSubOperationIndex = m_tProgressInfo.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());
+		m_pSubTaskContext->GetTaskLocalStats().SetCurrentSubOperationType(spCurrentSubTask->GetSubOperationType());
 		// set current sub-operation index to allow resuming
-		m_rSubTaskContext.GetTaskBasicProgressInfo().SetSubOperationIndex(stSubOperationIndex);
+		m_tProgressInfo.SetSubOperationIndex(stSubOperationIndex);
 
 		// if we run in estimation mode only, then stop processing and return to the caller
 		if(bRunOnlyEstimationSubTasks && !rCurrentSubTask.get<2>())
@@ -93,11 +211,6 @@
 		}
 
 		eResult = spCurrentSubTask->Exec();
-		if(eResult == TSubTaskBase::eSubResult_Continue)
-		{
-			// reset progress for each subtask
-			rBasicProgressInfo.SetCurrentIndex(0);
-		}
 	}
 
 	return eResult;
Index: src/libchcore/TSubTaskArray.h
===================================================================
diff -u -r835e0344e9677ff02eb3b539061c48c9f3a616ce -rbebda797ec6983535a8940f8f9f15453fe6b1785
--- src/libchcore/TSubTaskArray.h	(.../TSubTaskArray.h)	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
+++ src/libchcore/TSubTaskArray.h	(.../TSubTaskArray.h)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
@@ -32,24 +32,71 @@
 class TOperationPlan;
 class TSubTaskContext;
 
+class TReadBinarySerializer;
+class TWriteBinarySerializer;
+
+namespace details
+{
+	///////////////////////////////////////////////////////////////////////////
+	// TTaskBasicProgressInfo
+
+	class LIBCHCORE_API TTaskBasicProgressInfo
+	{
+	public:
+		TTaskBasicProgressInfo();
+		~TTaskBasicProgressInfo();
+
+		void ResetProgress();
+
+		void SetSubOperationIndex(size_t stSubOperationIndex);
+		size_t GetSubOperationIndex() const;
+		void IncreaseSubOperationIndex();
+
+		void Serialize(TReadBinarySerializer& rSerializer);
+		void Serialize(TWriteBinarySerializer& rSerializer) const;
+
+	private:
+		TTaskBasicProgressInfo(const TTaskBasicProgressInfo& rSrc);
+
+	private:
+		volatile size_t m_stSubOperationIndex;		 // index of sub-operation from TOperationDescription
+
+#pragma warning(push)
+#pragma warning(disable: 4251)
+		mutable boost::shared_mutex m_lock;
+#pragma warning(pop)
+	};
+}
+
+///////////////////////////////////////////////////////////////////////////
+// TTaskBasicProgressInfo
 class LIBCHCORE_API TSubTasksArray
 {
 public:
+	TSubTasksArray();
 	TSubTasksArray(const TOperationPlan& rOperationPlan, TSubTaskContext& rSubTaskContext);
 	~TSubTasksArray();
 
+	void Init(const TOperationPlan& rOperationPlan, TSubTaskContext& rSubTaskContext);
+	void ResetProgress();
+
+	void SerializeProgress(TReadBinarySerializer& rSerializer);
+	void SerializeProgress(TWriteBinarySerializer& rSerializer) const;
+
 	TSubTaskBase::ESubOperationResult Execute(bool bRunOnlyEstimationSubTasks);
 
 private:
 	TSubTasksArray(const TSubTasksArray& rSrc);
 	TSubTasksArray& operator=(const TSubTasksArray& rSrc);
 
 private:
+	TSubTaskContext* m_pSubTaskContext;
+
 #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?
+	details::TTaskBasicProgressInfo m_tProgressInfo;
 #pragma warning(pop)
-	TSubTaskContext& m_rSubTaskContext;
 };
 
 END_CHCORE_NAMESPACE
Index: src/libchcore/TSubTaskBase.h
===================================================================
diff -u -rd88274a4bbfd4ef005d44c4d179b7596cb627486 -rbebda797ec6983535a8940f8f9f15453fe6b1785
--- src/libchcore/TSubTaskBase.h	(.../TSubTaskBase.h)	(revision d88274a4bbfd4ef005d44c4d179b7596cb627486)
+++ src/libchcore/TSubTaskBase.h	(.../TSubTaskBase.h)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
@@ -36,6 +36,17 @@
 ///////////////////////////////////////////////////////////////////////////
 // TSubTaskBase
 
+class LIBCHCORE_API TSubTaskProgressInfo
+{
+public:
+	virtual ~TSubTaskProgressInfo() {}
+
+	virtual void Serialize(TReadBinarySerializer& rSerializer) = 0;
+	virtual void Serialize(TWriteBinarySerializer& rSerializer) const = 0;
+
+	virtual void ResetProgress() = 0;
+};
+
 class LIBCHCORE_API TSubTaskBase
 {
 public:
@@ -55,6 +66,8 @@
 	virtual ESubOperationResult Exec() = 0;
 	virtual ESubOperationType GetSubOperationType() const = 0;
 
+	virtual TSubTaskProgressInfo& GetProgressInfo() = 0;
+
 	TSubTaskContext& GetContext() { return m_rContext; }
 	const TSubTaskContext& GetContext() const { return m_rContext; }
 
Index: src/libchcore/TSubTaskContext.cpp
===================================================================
diff -u -r4d20d0e58f37f06ac91287015b960308db54d47e -rbebda797ec6983535a8940f8f9f15453fe6b1785
--- src/libchcore/TSubTaskContext.cpp	(.../TSubTaskContext.cpp)	(revision 4d20d0e58f37f06ac91287015b960308db54d47e)
+++ src/libchcore/TSubTaskContext.cpp	(.../TSubTaskContext.cpp)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
@@ -26,13 +26,12 @@
 BEGIN_CHCORE_NAMESPACE
 
 TSubTaskContext::TSubTaskContext(TTaskDefinition& rTaskDefinition, TBasePathDataContainer& rBasePathDataContainer, TFileInfoArray& rFilesCache, TTaskLocalStats& rTaskLocalStats, 
-								 TTaskBasicProgressInfo& rTaskBasicProgressInfo, TTaskConfigTracker& rCfgTracker, icpf::log_file& rLog, IFeedbackHandler* piFeedbackHandler,
+								 TTaskConfigTracker& rCfgTracker, icpf::log_file& rLog, IFeedbackHandler* piFeedbackHandler,
 								 TWorkerThreadController& rThreadController, TLocalFilesystem& rfsLocal) :
 	m_rTaskDefinition(rTaskDefinition),
 	m_rBasePathDataContainer(rBasePathDataContainer),
 	m_rFilesCache(rFilesCache),
 	m_rTaskLocalStats(rTaskLocalStats),
-	m_rTaskBasicProgressInfo(rTaskBasicProgressInfo),
 	m_rCfgTracker(rCfgTracker),
 	m_rLog(rLog),
 	m_piFeedbackHandler(piFeedbackHandler),
Index: src/libchcore/TSubTaskContext.h
===================================================================
diff -u -r4d20d0e58f37f06ac91287015b960308db54d47e -rbebda797ec6983535a8940f8f9f15453fe6b1785
--- src/libchcore/TSubTaskContext.h	(.../TSubTaskContext.h)	(revision 4d20d0e58f37f06ac91287015b960308db54d47e)
+++ src/libchcore/TSubTaskContext.h	(.../TSubTaskContext.h)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
@@ -49,7 +49,7 @@
 {
 public:
 	TSubTaskContext(TTaskDefinition& rTaskDefinition, TBasePathDataContainer& rBasePathDataContainer, TFileInfoArray& rFilesCache, TTaskLocalStats& rTaskLocalStats,
-		TTaskBasicProgressInfo& rTaskBasicProgressInfo, TTaskConfigTracker& rCfgTracker, icpf::log_file& rLog,
+		TTaskConfigTracker& rCfgTracker, icpf::log_file& rLog,
 		IFeedbackHandler* piFeedbackHandler, TWorkerThreadController& rThreadController, TLocalFilesystem& rfsLocal);
 	~TSubTaskContext();
 
@@ -65,9 +65,6 @@
 	TTaskLocalStats& GetTaskLocalStats() { return m_rTaskLocalStats; }
 	const TTaskLocalStats& GetTaskLocalStats() const { return m_rTaskLocalStats; }
 
-	TTaskBasicProgressInfo& GetTaskBasicProgressInfo() { return m_rTaskBasicProgressInfo; }
-	const TTaskBasicProgressInfo& GetTaskBasicProgressInfo() const { return m_rTaskBasicProgressInfo; }
-
 	TTaskConfigTracker& GetCfgTracker() { return m_rCfgTracker; }
 	const TTaskConfigTracker& GetCfgTracker() const { return m_rCfgTracker; }
 
@@ -98,7 +95,6 @@
 
 	// local stats for task
 	TTaskLocalStats& m_rTaskLocalStats;
-	TTaskBasicProgressInfo& m_rTaskBasicProgressInfo;
 
 	// configuration changes tracking
 	TTaskConfigTracker& m_rCfgTracker;
Index: src/libchcore/TSubTaskCopyMove.cpp
===================================================================
diff -u -r297ce850732d4243414c851df145ca97bd696baa -rbebda797ec6983535a8940f8f9f15453fe6b1785
--- src/libchcore/TSubTaskCopyMove.cpp	(.../TSubTaskCopyMove.cpp)	(revision 297ce850732d4243414c851df145ca97bd696baa)
+++ src/libchcore/TSubTaskCopyMove.cpp	(.../TSubTaskCopyMove.cpp)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
@@ -29,7 +29,6 @@
 #include "DataBuffer.h"
 #include "../libicpf/log.h"
 #include "TTaskLocalStats.h"
-#include "TBasicProgressInfo.h"
 #include "TTaskConfigTracker.h"
 #include "TWorkerThreadController.h"
 #include "FeedbackHandlerBase.h"
@@ -38,9 +37,98 @@
 #include <boost/smart_ptr/make_shared.hpp>
 #include "TFileInfo.h"
 #include "TFileInfoArray.h"
+#include "SerializationHelpers.h"
+#include "TBinarySerializer.h"
 
 BEGIN_CHCORE_NAMESPACE
 
+namespace details
+{
+	///////////////////////////////////////////////////////////////////////////////////////////////////
+	// class TCopyMoveProgressInfo
+
+	TCopyMoveProgressInfo::TCopyMoveProgressInfo() :
+		m_stCurrentIndex(0),
+		m_ullCurrentFileProcessedSize(0)
+	{
+	}
+
+	TCopyMoveProgressInfo::~TCopyMoveProgressInfo()
+	{
+	}
+
+	void TCopyMoveProgressInfo::Serialize(TReadBinarySerializer& rSerializer)
+	{
+		size_t stIndex = 0;
+		unsigned long long ullFilePos = 0;
+
+		Serializers::Serialize(rSerializer, stIndex);
+		Serializers::Serialize(rSerializer, ullFilePos);
+
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		m_stCurrentIndex = stIndex;
+		m_ullCurrentFileProcessedSize = ullFilePos;
+	}
+
+	void TCopyMoveProgressInfo::Serialize(TWriteBinarySerializer& rSerializer) const
+	{
+		size_t stIndex = 0;
+		unsigned long long ullFilePos = 0;
+
+		{
+			boost::shared_lock<boost::shared_mutex> lock(m_lock);
+			stIndex = m_stCurrentIndex;
+			ullFilePos = m_ullCurrentFileProcessedSize;
+		}
+
+		Serializers::Serialize(rSerializer, stIndex);
+		Serializers::Serialize(rSerializer, ullFilePos);
+	}
+
+	void TCopyMoveProgressInfo::ResetProgress()
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		m_stCurrentIndex = 0;
+	}
+
+	void TCopyMoveProgressInfo::SetCurrentIndex(size_t stIndex)
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		m_stCurrentIndex = stIndex;
+	}
+
+	void TCopyMoveProgressInfo::IncreaseCurrentIndex()
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		++m_stCurrentIndex;
+	}
+
+	size_t TCopyMoveProgressInfo::GetCurrentIndex() const
+	{
+		boost::shared_lock<boost::shared_mutex> lock(m_lock);
+		return m_stCurrentIndex;
+	}
+
+	void TCopyMoveProgressInfo::SetCurrentFileProcessedSize(unsigned long long ullSize)
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		m_ullCurrentFileProcessedSize = ullSize;
+	}
+
+	unsigned long long TCopyMoveProgressInfo::GetCurrentFileProcessedSize() const
+	{
+		boost::shared_lock<boost::shared_mutex> lock(m_lock);
+		return m_ullCurrentFileProcessedSize;
+	}
+
+	void TCopyMoveProgressInfo::IncreaseCurrentFileProcessedSize(unsigned long long ullSizeToAdd)
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		m_ullCurrentFileProcessedSize += ullSizeToAdd;
+	}
+
+}
+
 // assume max sectors of 4kB (for rounding)
 #define MAXSECTORSIZE			4096
 
@@ -54,6 +142,9 @@
 	bool bProcessed;			// has the element been processed ? (false if skipped)
 };
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// class TSubTaskCopyMove
+
 TSubTaskCopyMove::TSubTaskCopyMove(TSubTaskContext& tSubTaskContext) :
 	TSubTaskBase(tSubTaskContext)
 {
@@ -65,7 +156,6 @@
 	TFileInfoArray& rFilesCache = GetContext().GetFilesCache();
 	TTaskDefinition& rTaskDefinition = GetContext().GetTaskDefinition();
 	TTaskConfigTracker& rCfgTracker = GetContext().GetCfgTracker();
-	TTaskBasicProgressInfo& rBasicProgressInfo = GetContext().GetTaskBasicProgressInfo();
 	TWorkerThreadController& rThreadController = GetContext().GetThreadController();
 	IFeedbackHandler* piFeedbackHandler = GetContext().GetFeedbackHandler();
 	TTaskLocalStats& rLocalStats = GetContext().GetTaskLocalStats();
@@ -77,8 +167,12 @@
 	// log
 	rLog.logi(_T("Processing files/folders (ProcessFiles)"));
 
-	// count how much has been done (updates also a member in TSubTaskCopyMoveArray)
-	rLocalStats.SetProcessedSize(rFilesCache.CalculatePartialSize(rBasicProgressInfo.GetCurrentIndex()));
+	// update stats
+	rLocalStats.SetProcessedSize(rFilesCache.CalculatePartialSize(m_tProgressInfo.GetCurrentIndex()));
+	rLocalStats.SetTotalSize(rFilesCache.CalculateTotalSize());
+	rLocalStats.SetCurrentIndex(m_tProgressInfo.GetCurrentIndex());
+	rLocalStats.SetTotalItems(rFilesCache.GetSize());
+	rLocalStats.SetCurrentPath(TString());
 
 	// now it's time to check if there is enough space on destination device
 	TSubTaskBase::ESubOperationResult eResult = CheckForFreeSpaceFB();
@@ -125,13 +219,14 @@
 	strFormat.Replace(_T("%filecount"), boost::lexical_cast<std::wstring>(stSize).c_str());
 	strFormat.Replace(_T("%ignorefolders"), boost::lexical_cast<std::wstring>(bIgnoreFolders).c_str());
 	strFormat.Replace(_T("%dstpath"), rTaskDefinition.GetDestinationPath().ToString());
-	strFormat.Replace(_T("%currindex"), boost::lexical_cast<std::wstring>(rBasicProgressInfo.GetCurrentIndex()).c_str());
+	strFormat.Replace(_T("%currindex"), boost::lexical_cast<std::wstring>(m_tProgressInfo.GetCurrentIndex()).c_str());
 
 	rLog.logi(strFormat);
 
-	for(size_t stIndex = rBasicProgressInfo.GetCurrentIndex(); stIndex < stSize; stIndex++)
+	size_t stIndex = m_tProgressInfo.GetCurrentIndex();
+	for(; stIndex < stSize; stIndex++)
 	{
-		rBasicProgressInfo.SetCurrentIndex(stIndex);
+		m_tProgressInfo.SetCurrentIndex(stIndex);
 
 		// should we kill ?
 		if(rThreadController.KillRequested())
@@ -142,19 +237,23 @@
 		}
 
 		// next file to be copied
-		TFileInfoPtr spFileInfo = rFilesCache.GetAt(rBasicProgressInfo.GetCurrentIndex());
+		TFileInfoPtr spFileInfo = rFilesCache.GetAt(stIndex);
+		TSmartPath pathCurrent = spFileInfo->GetFullFilePath();
 
+		rLocalStats.SetCurrentIndex(stIndex);
+		rLocalStats.SetCurrentPath(pathCurrent.ToString());
+
 		// set dest path with filename
 		ccp.pathDstFile = CalculateDestinationPath(spFileInfo, rTaskDefinition.GetDestinationPath(), ((int)bForceDirectories) << 1 | (int)bIgnoreFolders);
 
 		// are the files/folders lie on the same partition ?
 		bool bMove = rTaskDefinition.GetOperationType() == eOperation_Move;
-		TSmartPath pathCurrent = spFileInfo->GetFullFilePath();
+
 		// if folder - create it
 		if(spFileInfo->IsDirectory())
 		{
 			bool bRetry = true;
-			if(bRetry && !TLocalFilesystem::CreateDirectory(ccp.pathDstFile, false) && (dwLastError=GetLastError()) != ERROR_ALREADY_EXISTS )
+			if(bRetry && !TLocalFilesystem::CreateDirectory(ccp.pathDstFile, false) && (dwLastError = GetLastError()) != ERROR_ALREADY_EXISTS)
 			{
 				// log
 				strFormat = _T("Error %errno while calling CreateDirectory %path (ProcessFiles)");
@@ -219,12 +318,13 @@
 			TLocalFilesystem::SetAttributes(ccp.pathDstFile, spFileInfo->GetAttributes());	// as above
 	}
 
+	m_tProgressInfo.SetCurrentIndex(stIndex);
+	rLocalStats.SetCurrentIndex(stIndex);
+	rLocalStats.SetCurrentPath(TString());
+
 	// delete buffer - it's not needed
 	ccp.dbBuffer.Delete();
 
-	// to look better (as 100%) - increase current index by 1
-	rBasicProgressInfo.SetCurrentIndex(stSize);
-
 	// log
 	rLog.logi(_T("Finished processing in ProcessFiles"));
 
@@ -263,7 +363,6 @@
 TSubTaskBase::ESubOperationResult TSubTaskCopyMove::CustomCopyFileFB(CUSTOM_COPY_PARAMS* pData)
 {
 	TTaskDefinition& rTaskDefinition = GetContext().GetTaskDefinition();
-	TTaskBasicProgressInfo& rBasicProgressInfo = GetContext().GetTaskBasicProgressInfo();
 	TWorkerThreadController& rThreadController = GetContext().GetThreadController();
 	TTaskLocalStats& rLocalStats = GetContext().GetTaskLocalStats();
 	icpf::log_file& rLog = GetContext().GetLog();
@@ -290,7 +389,7 @@
 	else if(!fileSrc.IsOpen())
 	{
 		// invalid handle = operation skipped by user
-		rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize());
+		rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 		pData->bProcessed = false;
 		return TSubTaskBase::eSubResult_Continue;
 	}
@@ -305,7 +404,7 @@
 	unsigned long long ullSeekTo = 0;
 	bool bDstFileFreshlyCreated = false;
 
-	if(rBasicProgressInfo.GetCurrentFileProcessedSize() == 0)
+	if(m_tProgressInfo.GetCurrentFileProcessedSize() == 0)
 	{
 		// open destination file for case, when we start operation on this file (i.e. it is not resume of the
 		// old operation)
@@ -314,7 +413,7 @@
 			return eResult;
 		else if(!fileDst.IsOpen())
 		{
-			rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize());
+			rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 			pData->bProcessed = false;
 			return TSubTaskBase::eSubResult_Continue;
 		}
@@ -327,12 +426,12 @@
 			return eResult;
 		else if(!fileDst.IsOpen())
 		{
-			rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize());
+			rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 			pData->bProcessed = false;
 			return TSubTaskBase::eSubResult_Continue;
 		}
 
-		ullSeekTo = rBasicProgressInfo.GetCurrentFileProcessedSize();
+		ullSeekTo = m_tProgressInfo.GetCurrentFileProcessedSize();
 	}
 
 	if(!pData->bOnlyCreate)
@@ -348,7 +447,7 @@
 				return eResult;
 			else if(bSkip)
 			{
-				rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize());
+				rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 				pData->bProcessed = false;
 				return TSubTaskBase::eSubResult_Continue;
 			}
@@ -359,12 +458,12 @@
 			else if(bSkip)
 			{
 				// with either first or second seek we got 'skip' answer...
-				rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize());
+				rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 				pData->bProcessed = false;
 				return TSubTaskBase::eSubResult_Continue;
 			}
 
-			rBasicProgressInfo.IncreaseCurrentFileProcessedSize(ullMove);
+			m_tProgressInfo.IncreaseCurrentFileProcessedSize(ullMove);
 			rLocalStats.IncreaseProcessedSize(ullMove);
 		}
 
@@ -450,7 +549,7 @@
 				return eResult;
 			else if(bSkip)
 			{
-				rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize());
+				rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 				pData->bProcessed = false;
 				return TSubTaskBase::eSubResult_Continue;
 			}
@@ -476,13 +575,13 @@
 							return eResult;
 						else if(bSkip)
 						{
-							rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize());
+							rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 							pData->bProcessed = false;
 							return TSubTaskBase::eSubResult_Continue;
 						}
 
 						// increase count of processed data
-						rBasicProgressInfo.IncreaseCurrentFileProcessedSize(ulWritten);
+						m_tProgressInfo.IncreaseCurrentFileProcessedSize(ulWritten);
 						rLocalStats.IncreaseProcessedSize(ulWritten);
 
 						// calculate count of bytes left to be written
@@ -504,19 +603,19 @@
 							return eResult;
 						else if(!fileDst.IsOpen())
 						{
-							rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize());
+							rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 							pData->bProcessed = false;
 							return TSubTaskBase::eSubResult_Continue;
 						}
 
 						// move file pointer to the end of destination file
-						eResult = SetFilePointerFB(fileDst, rBasicProgressInfo.GetCurrentFileProcessedSize(), pData->pathDstFile, bSkip);
+						eResult = SetFilePointerFB(fileDst, m_tProgressInfo.GetCurrentFileProcessedSize(), pData->pathDstFile, bSkip);
 						if(eResult != TSubTaskBase::eSubResult_Continue)
 							return eResult;
 						else if(bSkip)
 						{
 							// with either first or second seek we got 'skip' answer...
-							rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize());
+							rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 							pData->bProcessed = false;
 							return TSubTaskBase::eSubResult_Continue;
 						}
@@ -531,13 +630,13 @@
 						return eResult;
 					else if(bSkip)
 					{
-						rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize());
+						rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 						pData->bProcessed = false;
 						return TSubTaskBase::eSubResult_Continue;
 					}
 
 					// increase count of processed data
-					rBasicProgressInfo.IncreaseCurrentFileProcessedSize(ulRead);
+					m_tProgressInfo.IncreaseCurrentFileProcessedSize(ulRead);
 					rLocalStats.IncreaseProcessedSize(ulRead);
 				}
 			}
@@ -547,11 +646,11 @@
 	else
 	{
 		// we don't copy contents, but need to increase processed size
-		rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize());
+		rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 	}
 
 	pData->bProcessed = true;
-	rBasicProgressInfo.SetCurrentFileProcessedSize(0);
+	m_tProgressInfo.SetCurrentFileProcessedSize(0);
 
 	return TSubTaskBase::eSubResult_Continue;
 }
Index: src/libchcore/TSubTaskCopyMove.h
===================================================================
diff -u -rd88274a4bbfd4ef005d44c4d179b7596cb627486 -rbebda797ec6983535a8940f8f9f15453fe6b1785
--- src/libchcore/TSubTaskCopyMove.h	(.../TSubTaskCopyMove.h)	(revision d88274a4bbfd4ef005d44c4d179b7596cb627486)
+++ src/libchcore/TSubTaskCopyMove.h	(.../TSubTaskCopyMove.h)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
@@ -32,7 +32,42 @@
 class TLocalFilesystemFile;
 typedef boost::shared_ptr<TFileInfo> TFileInfoPtr;
 struct CUSTOM_COPY_PARAMS;
+class TReadBinarySerializer;
+class TWriteBinarySerializer;
 
+namespace details
+{
+	///////////////////////////////////////////////////////////////////////////
+	// TCopyMoveProgressInfo
+
+	class TCopyMoveProgressInfo : public TSubTaskProgressInfo
+	{
+	public:
+		TCopyMoveProgressInfo();
+		virtual ~TCopyMoveProgressInfo();
+
+		virtual void Serialize(TReadBinarySerializer& rSerializer);
+		virtual void Serialize(TWriteBinarySerializer& rSerializer) const;
+
+		virtual void ResetProgress();
+
+		// file being processed
+		void SetCurrentIndex(size_t stIndex);
+		void IncreaseCurrentIndex();
+		size_t GetCurrentIndex() const;
+
+		// part of file being processed
+		void SetCurrentFileProcessedSize(unsigned long long ullSize);
+		unsigned long long GetCurrentFileProcessedSize() const;
+		void IncreaseCurrentFileProcessedSize(unsigned long long ullSizeToAdd);
+
+	private:
+		volatile size_t m_stCurrentIndex;
+		volatile unsigned long long m_ullCurrentFileProcessedSize;	// count of bytes processed for current file
+		mutable boost::shared_mutex m_lock;
+	};
+}
+
 class LIBCHCORE_API TSubTaskCopyMove : public TSubTaskBase
 {
 public:
@@ -41,6 +76,8 @@
 	virtual ESubOperationResult Exec();
 	virtual ESubOperationType GetSubOperationType() const { return eSubOperation_Copying; }
 
+	virtual TSubTaskProgressInfo& GetProgressInfo() { return m_tProgressInfo; }
+
 private:
 	int GetBufferIndex(const TFileInfoPtr& spFileInfo);
 
@@ -58,6 +95,12 @@
 	ESubOperationResult CreateDirectoryFB(const TSmartPath& pathDirectory);
 
 	ESubOperationResult CheckForFreeSpaceFB();
+
+private:
+#pragma warning(push)
+#pragma warning(disable: 4251)
+	details::TCopyMoveProgressInfo m_tProgressInfo;
+#pragma warning(pop)
 };
 
 END_CHCORE_NAMESPACE
Index: src/libchcore/TSubTaskDelete.cpp
===================================================================
diff -u -r297ce850732d4243414c851df145ca97bd696baa -rbebda797ec6983535a8940f8f9f15453fe6b1785
--- src/libchcore/TSubTaskDelete.cpp	(.../TSubTaskDelete.cpp)	(revision 297ce850732d4243414c851df145ca97bd696baa)
+++ src/libchcore/TSubTaskDelete.cpp	(.../TSubTaskDelete.cpp)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
@@ -23,7 +23,6 @@
 #include "stdafx.h"
 #include "TSubTaskDelete.h"
 #include "TSubTaskContext.h"
-#include "TBasicProgressInfo.h"
 #include "TWorkerThreadController.h"
 #include "TTaskConfiguration.h"
 #include "TTaskDefinition.h"
@@ -33,9 +32,66 @@
 #include <boost\lexical_cast.hpp>
 #include "TFileInfoArray.h"
 #include "TFileInfo.h"
+#include "SerializationHelpers.h"
+#include "TBinarySerializer.h"
+#include "TTaskLocalStats.h"
 
 BEGIN_CHCORE_NAMESPACE
 
+namespace details
+{
+	///////////////////////////////////////////////////////////////////////////////////////////////////
+	// class TDeleteProgressInfo
+
+	TDeleteProgressInfo::TDeleteProgressInfo() :
+		m_stCurrentIndex(0)
+	{
+	}
+
+	TDeleteProgressInfo::~TDeleteProgressInfo()
+	{
+	}
+
+	void TDeleteProgressInfo::Serialize(TReadBinarySerializer& rSerializer)
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		Serializers::Serialize(rSerializer, m_stCurrentIndex);
+	}
+
+	void TDeleteProgressInfo::Serialize(TWriteBinarySerializer& rSerializer) const
+	{
+		boost::shared_lock<boost::shared_mutex> lock(m_lock);
+		Serializers::Serialize(rSerializer, m_stCurrentIndex);
+	}
+
+	void TDeleteProgressInfo::ResetProgress()
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		m_stCurrentIndex = 0;
+	}
+
+	void TDeleteProgressInfo::SetCurrentIndex(size_t stIndex)
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		m_stCurrentIndex = stIndex;
+	}
+
+	void TDeleteProgressInfo::IncreaseCurrentIndex()
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		++m_stCurrentIndex;
+	}
+
+	size_t TDeleteProgressInfo::GetCurrentIndex() const
+	{
+		boost::shared_lock<boost::shared_mutex> lock(m_lock);
+		return m_stCurrentIndex;
+	}
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// class TSubTaskDelete
+
 TSubTaskDelete::TSubTaskDelete(TSubTaskContext& rContext) : 
 	TSubTaskBase(rContext)
 {
@@ -47,25 +103,35 @@
 	icpf::log_file& rLog = GetContext().GetLog();
 	TFileInfoArray& rFilesCache = GetContext().GetFilesCache();
 	TTaskDefinition& rTaskDefinition = GetContext().GetTaskDefinition();
-	TTaskBasicProgressInfo& rBasicProgressInfo = GetContext().GetTaskBasicProgressInfo();
 	TWorkerThreadController& rThreadController = GetContext().GetThreadController();
 	IFeedbackHandler* piFeedbackHandler = GetContext().GetFeedbackHandler();
+	TTaskLocalStats& rTaskLocalStats = GetContext().GetTaskLocalStats();
 
 	// log
 	rLog.logi(_T("Deleting files (DeleteFiles)..."));
 
+	rTaskLocalStats.SetProcessedSize(0);
+	rTaskLocalStats.SetTotalSize(0);
+	rTaskLocalStats.SetCurrentIndex(0);
+	rTaskLocalStats.SetTotalItems(rFilesCache.GetSize());
+	rTaskLocalStats.SetCurrentPath(TString());
+
 	// current processed path
 	BOOL bSuccess;
 	TFileInfoPtr spFileInfo;
 	TString strFormat;
 
 	// index points to 0 or next item to process
-	size_t stIndex = rBasicProgressInfo.GetCurrentIndex();
+	size_t stIndex = m_tProgressInfo.GetCurrentIndex();
 	while(stIndex < rFilesCache.GetSize())
 	{
-		// set index in pTask to currently deleted element
-		rBasicProgressInfo.SetCurrentIndex(stIndex);
+		spFileInfo = rFilesCache.GetAt(rFilesCache.GetSize() - stIndex - 1);
 
+		m_tProgressInfo.SetCurrentIndex(stIndex);
+
+		rTaskLocalStats.SetCurrentIndex(stIndex);
+		rTaskLocalStats.SetCurrentPath(spFileInfo->GetFullFilePath().ToString());
+
 		// check for kill flag
 		if(rThreadController.KillRequested())
 		{
@@ -75,7 +141,6 @@
 		}
 
 		// current processed element
-		spFileInfo = rFilesCache.GetAt(rFilesCache.GetSize() - stIndex - 1);
 		if(!(spFileInfo->GetFlags() & FIF_PROCESSED))
 		{
 			++stIndex;
@@ -133,8 +198,9 @@
 		++stIndex;
 	}//while
 
-	// add 1 to current index
-	rBasicProgressInfo.IncreaseCurrentIndex();
+	m_tProgressInfo.SetCurrentIndex(stIndex);
+	rTaskLocalStats.SetCurrentIndex(stIndex);
+	rTaskLocalStats.SetCurrentPath(TString());
 
 	// log
 	rLog.logi(_T("Deleting files finished"));
Index: src/libchcore/TSubTaskDelete.h
===================================================================
diff -u -r835e0344e9677ff02eb3b539061c48c9f3a616ce -rbebda797ec6983535a8940f8f9f15453fe6b1785
--- src/libchcore/TSubTaskDelete.h	(.../TSubTaskDelete.h)	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
+++ src/libchcore/TSubTaskDelete.h	(.../TSubTaskDelete.h)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
@@ -28,13 +28,53 @@
 
 BEGIN_CHCORE_NAMESPACE
 
+class TReadBinarySerializer;
+class TWriteBinarySerializer;
+
+namespace details
+{
+	///////////////////////////////////////////////////////////////////////////
+	// TDeleteProgressInfo
+
+	class TDeleteProgressInfo : public TSubTaskProgressInfo
+	{
+	public:
+		TDeleteProgressInfo();
+		virtual ~TDeleteProgressInfo();
+
+		virtual void Serialize(TReadBinarySerializer& rSerializer);
+		virtual void Serialize(TWriteBinarySerializer& rSerializer) const;
+
+		virtual void ResetProgress();
+
+		void SetCurrentIndex(size_t stIndex);
+		void IncreaseCurrentIndex();
+		size_t GetCurrentIndex() const;
+
+	private:
+		size_t m_stCurrentIndex;
+		mutable boost::shared_mutex m_lock;
+	};
+}
+
+///////////////////////////////////////////////////////////////////////////
+// TSubTaskDelete
+
 class LIBCHCORE_API TSubTaskDelete : public TSubTaskBase
 {
 public:
 	TSubTaskDelete(TSubTaskContext& rContext);
 
 	virtual ESubOperationResult Exec();
 	virtual ESubOperationType GetSubOperationType() const { return eSubOperation_Deleting; }
+
+	virtual TSubTaskProgressInfo& GetProgressInfo() { return m_tProgressInfo; }
+
+private:
+#pragma warning(push)
+#pragma warning(disable: 4251)
+	details::TDeleteProgressInfo m_tProgressInfo;
+#pragma warning(pop)
 };
 
 END_CHCORE_NAMESPACE
Index: src/libchcore/TSubTaskFastMove.cpp
===================================================================
diff -u -r297ce850732d4243414c851df145ca97bd696baa -rbebda797ec6983535a8940f8f9f15453fe6b1785
--- src/libchcore/TSubTaskFastMove.cpp	(.../TSubTaskFastMove.cpp)	(revision 297ce850732d4243414c851df145ca97bd696baa)
+++ src/libchcore/TSubTaskFastMove.cpp	(.../TSubTaskFastMove.cpp)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
@@ -33,11 +33,63 @@
 #include "TTaskLocalStats.h"
 #include "..\libicpf\log.h"
 #include "TFileInfo.h"
-#include "TBasicProgressInfo.h"
 #include <boost\lexical_cast.hpp>
+#include "SerializationHelpers.h"
+#include "TBinarySerializer.h"
 
 BEGIN_CHCORE_NAMESPACE
 
+namespace details
+{
+	///////////////////////////////////////////////////////////////////////////////////////////////////
+	// class TFastMoveProgressInfo
+
+	TFastMoveProgressInfo::TFastMoveProgressInfo() :
+		m_stCurrentIndex(0)
+	{
+	}
+
+	TFastMoveProgressInfo::~TFastMoveProgressInfo()
+	{
+	}
+
+	void TFastMoveProgressInfo::Serialize(TReadBinarySerializer& rSerializer)
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		Serializers::Serialize(rSerializer, m_stCurrentIndex);
+	}
+
+	void TFastMoveProgressInfo::Serialize(TWriteBinarySerializer& rSerializer) const
+	{
+		boost::shared_lock<boost::shared_mutex> lock(m_lock);
+		Serializers::Serialize(rSerializer, m_stCurrentIndex);
+	}
+
+	void TFastMoveProgressInfo::ResetProgress()
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		m_stCurrentIndex = 0;
+	}
+
+	void TFastMoveProgressInfo::SetCurrentIndex(size_t stIndex)
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		m_stCurrentIndex = stIndex;
+	}
+
+	void TFastMoveProgressInfo::IncreaseCurrentIndex()
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		++m_stCurrentIndex;
+	}
+
+	size_t TFastMoveProgressInfo::GetCurrentIndex() const
+	{
+		boost::shared_lock<boost::shared_mutex> lock(m_lock);
+		return m_stCurrentIndex;
+	}
+}
+
 TSubTaskFastMove::TSubTaskFastMove(TSubTaskContext& rContext) :
 	TSubTaskBase(rContext)
 {
@@ -55,14 +107,16 @@
 	IFeedbackHandler* piFeedbackHandler = GetContext().GetFeedbackHandler();
 	TWorkerThreadController& rThreadController = GetContext().GetThreadController();
 	TTaskLocalStats& rTaskLocalStats = GetContext().GetTaskLocalStats();
-	TTaskBasicProgressInfo& rProgressInfo = GetContext().GetTaskBasicProgressInfo();
 	TBasePathDataContainer& rBasePathDataContainer = GetContext().GetBasePathDataContainer();
 
 	rLog.logi(_T("Performing initial fast-move operation..."));
 
 	// reset progress
 	rTaskLocalStats.SetProcessedSize(0);
 	rTaskLocalStats.SetTotalSize(0);
+	rTaskLocalStats.SetCurrentIndex(0);
+	rTaskLocalStats.SetTotalItems(rTaskDefinition.GetSourcePathCount());
+	rTaskLocalStats.SetCurrentPath(TString());
 
 	// read filtering options
 	TFileFiltersArray afFilters;
@@ -84,11 +138,17 @@
 	bool bSkipInputPath = false;
 
 	size_t stSize = rTaskDefinition.GetSourcePathCount();
-	for(size_t stIndex = rProgressInfo.GetCurrentIndex(); stIndex < stSize ; stIndex++)
+	size_t stIndex = m_tProgressInfo.GetCurrentIndex();
+	for(; stIndex < stSize ; stIndex++)
 	{
+		TSmartPath pathCurrent = rTaskDefinition.GetSourcePathAt(stIndex);
+
 		// store currently processed index
-		rProgressInfo.SetCurrentIndex(stIndex);
+		m_tProgressInfo.SetCurrentIndex(stIndex);
 
+		rTaskLocalStats.SetCurrentIndex(stIndex);
+		rTaskLocalStats.SetCurrentPath(pathCurrent.ToString());
+
 		// retrieve base path data
 		TBasePathDataPtr spBasePathData = rBasePathDataContainer.GetAt(stIndex);
 		if(!spBasePathData)
@@ -106,7 +166,7 @@
 			bRetry = false;
 
 			// read attributes of src file/folder
-			bool bExists = TLocalFilesystem::GetFileInfo(rTaskDefinition.GetSourcePathAt(stIndex), spFileInfo, stIndex, &rTaskDefinition.GetSourcePaths());
+			bool bExists = TLocalFilesystem::GetFileInfo(pathCurrent, spFileInfo, stIndex, &rTaskDefinition.GetSourcePaths());
 			if(!bExists)
 			{
 				FEEDBACK_FILEERROR ferr = { rTaskDefinition.GetSourcePathAt(stIndex).ToString(), NULL, eFastMoveError, ERROR_FILE_NOT_FOUND };
@@ -209,6 +269,11 @@
 		}
 	}
 
+	m_tProgressInfo.SetCurrentIndex(stIndex);
+	rTaskLocalStats.SetCurrentIndex(stIndex);
+	rTaskLocalStats.SetCurrentPath(TString());
+
+
 	// log
 	rLog.logi(_T("Fast moving finished"));
 
Index: src/libchcore/TSubTaskFastMove.h
===================================================================
diff -u -rd88274a4bbfd4ef005d44c4d179b7596cb627486 -rbebda797ec6983535a8940f8f9f15453fe6b1785
--- src/libchcore/TSubTaskFastMove.h	(.../TSubTaskFastMove.h)	(revision d88274a4bbfd4ef005d44c4d179b7596cb627486)
+++ src/libchcore/TSubTaskFastMove.h	(.../TSubTaskFastMove.h)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
@@ -30,7 +30,35 @@
 BEGIN_CHCORE_NAMESPACE
 
 class TFileFiltersArray;
+class TReadBinarySerializer;
+class TWriteBinarySerializer;
 
+namespace details
+{
+	///////////////////////////////////////////////////////////////////////////
+	// TFastMoveProgressInfo
+
+	class TFastMoveProgressInfo : public TSubTaskProgressInfo
+	{
+	public:
+		TFastMoveProgressInfo();
+		virtual ~TFastMoveProgressInfo();
+
+		virtual void Serialize(TReadBinarySerializer& rSerializer);
+		virtual void Serialize(TWriteBinarySerializer& rSerializer) const;
+
+		virtual void ResetProgress();
+
+		void SetCurrentIndex(size_t stIndex);
+		void IncreaseCurrentIndex();
+		size_t GetCurrentIndex() const;
+
+	private:
+		size_t m_stCurrentIndex;
+		mutable boost::shared_mutex m_lock;
+	};
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // TSubTaskFastMove
 
@@ -43,8 +71,16 @@
 	virtual ESubOperationResult Exec();
 	virtual ESubOperationType GetSubOperationType() const { return eSubOperation_Scanning; }
 
+	virtual TSubTaskProgressInfo& GetProgressInfo() { return m_tProgressInfo; }
+
 private:
 	int ScanDirectory(TSmartPath pathDirName, size_t stSrcIndex, bool bRecurse, bool bIncludeDirs, TFileFiltersArray& afFilters);
+
+private:
+#pragma warning(push)
+#pragma warning(disable: 4251)
+	details::TFastMoveProgressInfo m_tProgressInfo;
+#pragma warning(pop)
 };
 
 END_CHCORE_NAMESPACE
Index: src/libchcore/TSubTaskScanDirectory.cpp
===================================================================
diff -u -rd88274a4bbfd4ef005d44c4d179b7596cb627486 -rbebda797ec6983535a8940f8f9f15453fe6b1785
--- src/libchcore/TSubTaskScanDirectory.cpp	(.../TSubTaskScanDirectory.cpp)	(revision d88274a4bbfd4ef005d44c4d179b7596cb627486)
+++ src/libchcore/TSubTaskScanDirectory.cpp	(.../TSubTaskScanDirectory.cpp)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
@@ -25,7 +25,6 @@
 #include "TSubTaskContext.h"
 #include "TTaskConfiguration.h"
 #include "TTaskDefinition.h"
-//#include "FeedbackHandler.h"
 #include "TLocalFilesystem.h"
 #include "FeedbackHandlerBase.h"
 #include "TBasePathData.h"
@@ -35,9 +34,64 @@
 #include "..\libicpf\log.h"
 #include "TFileInfoArray.h"
 #include "TFileInfo.h"
+#include "SerializationHelpers.h"
+#include "TBinarySerializer.h"
 
 BEGIN_CHCORE_NAMESPACE
 
+namespace details
+{
+	///////////////////////////////////////////////////////////////////////////////////////////////////
+	// class TScanDirectoriesProgressInfo
+
+	TScanDirectoriesProgressInfo::TScanDirectoriesProgressInfo() :
+		m_stCurrentIndex(0)
+	{
+	}
+
+	TScanDirectoriesProgressInfo::~TScanDirectoriesProgressInfo()
+	{
+	}
+
+	void TScanDirectoriesProgressInfo::Serialize(TReadBinarySerializer& rSerializer)
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		Serializers::Serialize(rSerializer, m_stCurrentIndex);
+	}
+
+	void TScanDirectoriesProgressInfo::Serialize(TWriteBinarySerializer& rSerializer) const
+	{
+		boost::shared_lock<boost::shared_mutex> lock(m_lock);
+		Serializers::Serialize(rSerializer, m_stCurrentIndex);
+	}
+
+	void TScanDirectoriesProgressInfo::ResetProgress()
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		m_stCurrentIndex = 0;
+	}
+
+	void TScanDirectoriesProgressInfo::SetCurrentIndex(size_t stIndex)
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		m_stCurrentIndex = stIndex;
+	}
+
+	void TScanDirectoriesProgressInfo::IncreaseCurrentIndex()
+	{
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+		++m_stCurrentIndex;
+	}
+
+	size_t TScanDirectoriesProgressInfo::GetCurrentIndex() const
+	{
+		boost::shared_lock<boost::shared_mutex> lock(m_lock);
+		return m_stCurrentIndex;
+	}
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// class TSubTaskScanDirectories
 TSubTaskScanDirectories::TSubTaskScanDirectories(TSubTaskContext& rContext) :
 	TSubTaskBase(rContext)
 {
@@ -64,6 +118,9 @@
 	rFilesCache.SetComplete(false);
 	rTaskLocalStats.SetProcessedSize(0);
 	rTaskLocalStats.SetTotalSize(0);
+	rTaskLocalStats.SetCurrentIndex(0);
+	rTaskLocalStats.SetTotalItems(rTaskDefinition.GetSourcePathCount());
+	rTaskLocalStats.SetCurrentPath(TString());
 
 	// delete the content of rFilesCache
 	rFilesCache.Clear();
@@ -81,8 +138,17 @@
 	bool bSkipInputPath = false;
 
 	size_t stSize = rTaskDefinition.GetSourcePathCount();
-	for(size_t stIndex = 0; stIndex < stSize ; stIndex++)
+	// NOTE: in theory, we should resume the scanning, but in practice we are always restarting scanning if interrupted.
+	size_t stIndex = 0;		// m_tProgressInfo.GetCurrentIndex()
+	for(; stIndex < stSize; stIndex++)
 	{
+		TSmartPath pathCurrent = rTaskDefinition.GetSourcePathAt(stIndex);
+
+		m_tProgressInfo.SetCurrentIndex(stIndex);
+
+		rTaskLocalStats.SetCurrentIndex(stIndex);
+		rTaskLocalStats.SetCurrentPath(pathCurrent.ToString());
+
 		bSkipInputPath = false;
 		TFileInfoPtr spFileInfo(boost::make_shared<TFileInfo>());
 
@@ -101,7 +167,7 @@
 			bRetry = false;
 
 			// read attributes of src file/folder
-			bool bExists = TLocalFilesystem::GetFileInfo(rTaskDefinition.GetSourcePathAt(stIndex), spFileInfo, stIndex, &rTaskDefinition.GetSourcePaths());
+			bool bExists = TLocalFilesystem::GetFileInfo(pathCurrent, spFileInfo, stIndex, &rTaskDefinition.GetSourcePaths());
 			if(!bExists)
 			{
 				FEEDBACK_FILEERROR ferr = { rTaskDefinition.GetSourcePathAt(stIndex).ToString(), NULL, eFastMoveError, ERROR_FILE_NOT_FOUND };
@@ -187,7 +253,10 @@
 	}
 
 	// calc size of all files
-	rTaskLocalStats.SetTotalSize(rFilesCache.CalculateTotalSize());
+	m_tProgressInfo.SetCurrentIndex(stIndex);
+	rTaskLocalStats.SetCurrentIndex(stIndex);
+	rTaskLocalStats.SetCurrentPath(TString());
+
 	rFilesCache.SetComplete(true);
 
 	// log
Index: src/libchcore/TSubTaskScanDirectory.h
===================================================================
diff -u -r835e0344e9677ff02eb3b539061c48c9f3a616ce -rbebda797ec6983535a8940f8f9f15453fe6b1785
--- src/libchcore/TSubTaskScanDirectory.h	(.../TSubTaskScanDirectory.h)	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
+++ src/libchcore/TSubTaskScanDirectory.h	(.../TSubTaskScanDirectory.h)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
@@ -30,7 +30,35 @@
 BEGIN_CHCORE_NAMESPACE
 
 class TFileFiltersArray;
+class TReadBinarySerializer;
+class TWriteBinarySerializer;
 
+namespace details
+{
+	///////////////////////////////////////////////////////////////////////////
+	// TScanDirectoriesProgressInfo
+
+	class TScanDirectoriesProgressInfo : public TSubTaskProgressInfo
+	{
+	public:
+		TScanDirectoriesProgressInfo();
+		virtual ~TScanDirectoriesProgressInfo();
+
+		virtual void Serialize(TReadBinarySerializer& rSerializer);
+		virtual void Serialize(TWriteBinarySerializer& rSerializer) const;
+
+		virtual void ResetProgress();
+
+		void SetCurrentIndex(size_t stIndex);
+		void IncreaseCurrentIndex();
+		size_t GetCurrentIndex() const;
+
+	private:
+		size_t m_stCurrentIndex;
+		mutable boost::shared_mutex m_lock;
+	};
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // TSubTaskScanDirectories
 
@@ -43,8 +71,16 @@
 	virtual ESubOperationResult Exec();
 	virtual ESubOperationType GetSubOperationType() const { return eSubOperation_Scanning; }
 
+	virtual TSubTaskProgressInfo& GetProgressInfo() { return m_tProgressInfo; }
+
 private:
 	int ScanDirectory(TSmartPath pathDirName, size_t stSrcIndex, bool bRecurse, bool bIncludeDirs, TFileFiltersArray& afFilters);
+
+private:
+#pragma warning(push)
+#pragma warning(disable: 4251)
+	details::TScanDirectoriesProgressInfo m_tProgressInfo;
+#pragma warning(pop)
 };
 
 END_CHCORE_NAMESPACE
Index: src/libchcore/TTask.cpp
===================================================================
diff -u -r835e0344e9677ff02eb3b539061c48c9f3a616ce -rbebda797ec6983535a8940f8f9f15453fe6b1785
--- src/libchcore/TTask.cpp	(.../TTask.cpp)	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
+++ src/libchcore/TTask.cpp	(.../TTask.cpp)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
@@ -27,7 +27,6 @@
 #pragma warning(pop)
 
 #include <fstream>
-#include "TSubTaskContext.h"
 #include "TSubTaskScanDirectory.h"
 #include "TSubTaskCopyMove.h"
 #include "TSubTaskDelete.h"
@@ -56,7 +55,8 @@
 	m_bOftenStateModified(false),
 	m_stSessionUniqueID(stSessionUniqueID),
 	m_localStats(),
-	m_eCurrentState(eTaskState_None)
+	m_eCurrentState(eTaskState_None),
+	m_tSubTaskContext(m_tTaskDefinition, m_arrSourcePathsInfo, m_files, m_localStats, m_cfgTracker, m_log, piFeedbackHandler, m_workerThread, m_fsLocal)
 {
 	BOOST_ASSERT(piFeedbackHandler);
 }
@@ -72,6 +72,7 @@
 {
 	m_tTaskDefinition = rTaskDefinition;
 
+	m_tSubTasksArray.Init(m_tTaskDefinition.GetOperationPlan(), m_tSubTaskContext);
 	m_arrSourcePathsInfo.SetCount(m_tTaskDefinition.GetSourcePathCount());
 	m_files.Clear();
 }
@@ -132,17 +133,6 @@
 	SetTaskPropValue<eTO_ThreadPriority>(m_tTaskDefinition.GetConfiguration(), nPriority);
 }
 
-void TTask::CalculateProcessedSize()
-{
-	boost::shared_lock<boost::shared_mutex> lock(m_lock);
-	CalculateProcessedSizeNL();
-}
-
-void TTask::CalculateProcessedSizeNL()
-{
-	m_localStats.SetProcessedSize(m_files.CalculatePartialSize(m_tTaskBasicProgressInfo.GetCurrentIndex()));
-}
-
 void TTask::Load(const TSmartPath& strPath)
 {
 	using Serializers::Serialize;
@@ -168,17 +158,14 @@
 	m_arrSourcePathsInfo.Serialize(readSerializer, true);
 	m_files.Serialize(readSerializer, false);
 
-	CalculateTotalSizeNL();
-
 	///////////////////////////////////
 	// and often changing data
 	TSmartPath pathOftenChangingPath = GetRelatedPathNL(ePathType_TaskOftenChangingState);
 	readSerializer.Init(pathOftenChangingPath);
 
-	Serialize(readSerializer, m_tTaskBasicProgressInfo);
+	m_tSubTasksArray.Init(m_tTaskDefinition.GetOperationPlan(), m_tSubTaskContext);
+	m_tSubTasksArray.SerializeProgress(readSerializer);
 
-	CalculateProcessedSizeNL();
-
 	// load task state, convert "waiting" state to "processing"
 	int iState = eTaskState_None;
 	Serialize(readSerializer, iState);
@@ -238,7 +225,7 @@
 		TWriteBinarySerializer writeSerializer;
 		writeSerializer.Init(GetRelatedPathNL(ePathType_TaskOftenChangingState));
 
-		Serialize(writeSerializer, m_tTaskBasicProgressInfo);
+		m_tSubTasksArray.SerializeProgress(writeSerializer);
 
 		// store current state (convert from waiting to processing state before storing)
 		int iState = m_eCurrentState;
@@ -299,7 +286,7 @@
 	SetTaskState(eTaskState_None);
 
 	m_localStats.SetTimeElapsed(0);
-	m_tTaskBasicProgressInfo.SetCurrentIndex(0);
+	m_tSubTasksArray.ResetProgress();
 
 	BeginProcessing();
 }
@@ -329,68 +316,24 @@
 void TTask::GetMiniSnapshot(TASK_MINI_DISPLAY_DATA *pData)
 {
 	boost::shared_lock<boost::shared_mutex> lock(m_lock);
-	size_t stCurrentIndex = m_tTaskBasicProgressInfo.GetCurrentIndex();
-
-	if(stCurrentIndex < m_files.GetSize())
-		pData->m_strPath = m_files.GetAt(stCurrentIndex)->GetFullFilePath().GetFileName().ToString();
-	else
-	{
-		if(m_files.GetSize() > 0)
-			pData->m_strPath = m_files.GetAt(0)->GetFullFilePath().GetFileName().ToString();
-		else
-		{
-			if(m_tTaskDefinition.GetSourcePathCount() > 0)
-				pData->m_strPath = m_tTaskDefinition.GetSourcePathAt(0).GetFileName().ToString();
-			else
-				pData->m_strPath.Clear();
-		}
-	}
-
+	pData->m_strPath = m_localStats.GetCurrentPath();
 	pData->m_eTaskState = m_eCurrentState;
-
-	// percents
 	pData->m_nPercent = m_localStats.GetProgressInPercent();
 }
 
 void TTask::GetSnapshot(TASK_DISPLAY_DATA *pData)
 {
 	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 
-	size_t stCurrentIndex = m_tTaskBasicProgressInfo.GetCurrentIndex();
-	if(stCurrentIndex < m_files.GetSize())
-	{
-		pData->m_strFullFilePath = m_files.GetAt(stCurrentIndex)->GetFullFilePath().ToString();
-		pData->m_strFileName = m_files.GetAt(stCurrentIndex)->GetFullFilePath().GetFileName().ToString();
-	}
-	else
-	{
-		if(m_files.GetSize() > 0)
-		{
-			pData->m_strFullFilePath = m_files.GetAt(0)->GetFullFilePath().ToString();
-			pData->m_strFileName = m_files.GetAt(0)->GetFullFilePath().GetFileName().ToString();
-		}
-		else
-		{
-			if(m_tTaskDefinition.GetSourcePathCount() > 0)
-			{
-				pData->m_strFullFilePath = m_tTaskDefinition.GetSourcePathAt(0).ToString();
-				pData->m_strFileName = m_tTaskDefinition.GetSourcePathAt(0).GetFileName().ToString();
-			}
-			else
-			{
-				pData->m_strFullFilePath.Clear();
-				pData->m_strFileName.Clear();
-			}
-		}
-	}
-
+	pData->m_strFullFilePath = m_localStats.GetCurrentPath();
+	pData->m_strFileName = chcore::PathFromString(pData->m_strFullFilePath).GetFileName().ToString();
 	pData->m_nPriority = GetTaskPropValue<eTO_ThreadPriority>(m_tTaskDefinition.GetConfiguration());
 	pData->m_pathDstPath = m_tTaskDefinition.GetDestinationPath();
 	pData->m_pafFilters = &m_afFilters;
 	pData->m_eTaskState = m_eCurrentState;
-	pData->m_stIndex = stCurrentIndex;
+	pData->m_stIndex = m_localStats.GetCurrentIndex();
+	pData->m_stSize = m_localStats.GetTotalItems();
 	pData->m_ullProcessedSize = m_localStats.GetProcessedSize();
-	pData->m_stSize = m_files.GetSize();
 	pData->m_ullSizeAll = m_localStats.GetTotalSize();
 	pData->m_strUniqueName = m_tTaskDefinition.GetTaskUniqueID();
 	pData->m_eOperationType = m_tTaskDefinition.GetOperationType();
@@ -399,10 +342,7 @@
 	pData->m_bIgnoreDirectories = GetTaskPropValue<eTO_IgnoreDirectories>(m_tTaskDefinition.GetConfiguration());
 	pData->m_bCreateEmptyFiles = GetTaskPropValue<eTO_CreateEmptyFiles>(m_tTaskDefinition.GetConfiguration());
 
-	if(m_files.GetSize() > 0)
-		pData->m_iCurrentBufferIndex = m_localStats.GetCurrentBufferIndex();
-	else
-		pData->m_iCurrentBufferIndex = TBufferSizes::eBuffer_Default;
+	pData->m_iCurrentBufferIndex = m_localStats.GetCurrentBufferIndex();
 
 	switch(pData->m_iCurrentBufferIndex)
 	{
@@ -521,11 +461,6 @@
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-void TTask::CalculateTotalSizeNL()
-{
-	m_localStats.SetTotalSize(m_files.CalculateTotalSize());
-}
-
 void TTask::SetForceFlagNL(bool bFlag)
 {
 	m_bForce=bFlag;
@@ -615,19 +550,16 @@
 		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);
-		TSubTasksArray tOperation(m_tTaskDefinition.GetOperationPlan(), tSubTaskContext);
-		
 		if(bReadTasksSize)
-			eResult = tOperation.Execute(true);
+			eResult = m_tSubTasksArray.Execute(true);
 		if(eResult == TSubTaskBase::eSubResult_Continue)
 		{
 			m_localStats.DisableTimeTracking();
 			eResult = CheckForWaitState();	// operation limiting
 			m_localStats.EnableTimeTracking();
 		}
 		if(eResult == TSubTaskBase::eSubResult_Continue)
-			eResult = tOperation.Execute(false);
+			eResult = m_tSubTasksArray.Execute(false);
 
 		// change status to finished
 		if(eResult == TSubTaskBase::eSubResult_Continue)
Index: src/libchcore/TTask.h
===================================================================
diff -u -rba802caea92ee56a154d1da3fe89a4b2f7875f0e -rbebda797ec6983535a8940f8f9f15453fe6b1785
--- src/libchcore/TTask.h	(.../TTask.h)	(revision ba802caea92ee56a154d1da3fe89a4b2f7875f0e)
+++ src/libchcore/TTask.h	(.../TTask.h)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
@@ -27,10 +27,11 @@
 #include "TBasePathData.h"
 #include "TSubTaskBase.h"
 #include "TTaskLocalStats.h"
-#include "TBasicProgressInfo.h"
 #include "..\libicpf\log.h"
 #include "TLocalFilesystem.h"
 #include "TFileInfoArray.h"
+#include "TSubTaskArray.h"
+#include "TSubTaskContext.h"
 
 BEGIN_CHCORE_NAMESPACE
 
@@ -179,11 +180,6 @@
 	void SetStatusNL(UINT nStatus, UINT nMask);
 	UINT GetStatusNL(UINT nMask = 0xffffffff);
 
-	void CalculateProcessedSize();
-	void CalculateProcessedSizeNL();
-
-	void CalculateTotalSizeNL();
-
 	void DeleteProgress();
 
 	void SetForceFlagNL(bool bFlag = true);
@@ -207,6 +203,9 @@
 	// task initial information (needed to start a task); might be a bit processed.
 	TTaskDefinition m_tTaskDefinition;
 
+	TSubTasksArray m_tSubTasksArray;
+	TSubTaskContext m_tSubTaskContext;
+
 	TTaskConfigTracker m_cfgTracker;
 
 	TBasePathDataContainer m_arrSourcePathsInfo;
@@ -218,8 +217,6 @@
 	// changing fast
 	volatile ETaskCurrentState m_eCurrentState;     // current state of processing this task represents
 
-	TTaskBasicProgressInfo m_tTaskBasicProgressInfo;	// task progress information
-
 	// task control variables (per-session state)
 	TTaskLocalStats m_localStats;       // local statistics
 
Index: src/libchcore/TTaskLocalStats.cpp
===================================================================
diff -u -r835e0344e9677ff02eb3b539061c48c9f3a616ce -rbebda797ec6983535a8940f8f9f15453fe6b1785
--- src/libchcore/TTaskLocalStats.cpp	(.../TTaskLocalStats.cpp)	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
+++ src/libchcore/TTaskLocalStats.cpp	(.../TTaskLocalStats.cpp)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
@@ -30,13 +30,15 @@
 ////////////////////////////////////////////////////////////////////////////////
 // TTasksGlobalStats members
 TTaskLocalStats::TTaskLocalStats() :
-m_prtGlobalStats(NULL),
-m_ullProcessedSize(0),
-m_ullTotalSize(0),
-m_bTaskIsRunning(false),
-m_timeElapsed(0),
-m_timeLast(-1),
-m_iCurrentBufferIndex(0)
+	m_prtGlobalStats(NULL),
+	m_ullProcessedSize(0),
+	m_ullTotalSize(0),
+	m_stCurrentIndex(0),
+	m_stTotalItems(0),
+	m_bTaskIsRunning(false),
+	m_timeElapsed(0),
+	m_timeLast(-1),
+	m_iCurrentBufferIndex(0)
 {
 }
 
@@ -156,6 +158,30 @@
 	return m_ullTotalSize;
 }
 
+size_t TTaskLocalStats::GetCurrentIndex() const
+{
+	boost::shared_lock<boost::shared_mutex> lock(m_lock);
+	return m_stCurrentIndex;
+}
+
+void TTaskLocalStats::SetCurrentIndex(size_t stIndex)
+{
+	boost::unique_lock<boost::shared_mutex> lock(m_lock);
+	m_stCurrentIndex = stIndex;
+}
+
+size_t TTaskLocalStats::GetTotalItems()
+{
+	boost::shared_lock<boost::shared_mutex> lock(m_lock);
+	return m_stTotalItems;
+}
+
+void TTaskLocalStats::SetTotalItems(size_t stCount)
+{
+	boost::unique_lock<boost::shared_mutex> lock(m_lock);
+	m_stTotalItems = stCount;
+}
+
 int TTaskLocalStats::GetProgressInPercent() const
 {
 	boost::shared_lock<boost::shared_mutex> lock(m_lock);
@@ -168,6 +194,18 @@
 	return boost::numeric_cast<int>(ullPercent);
 }
 
+void TTaskLocalStats::SetCurrentPath(const TString& strPath)
+{
+	boost::unique_lock<boost::shared_mutex> lock(m_lock);
+	m_strCurrentPath = strPath;
+}
+
+const TString& TTaskLocalStats::GetCurrentPath() const
+{
+	boost::shared_lock<boost::shared_mutex> lock(m_lock);
+	return m_strCurrentPath;
+}
+
 void TTaskLocalStats::MarkTaskAsRunning()
 {
 	boost::unique_lock<boost::shared_mutex> lock(m_lock);
Index: src/libchcore/TTaskLocalStats.h
===================================================================
diff -u -r835e0344e9677ff02eb3b539061c48c9f3a616ce -rbebda797ec6983535a8940f8f9f15453fe6b1785
--- src/libchcore/TTaskLocalStats.h	(.../TTaskLocalStats.h)	(revision 835e0344e9677ff02eb3b539061c48c9f3a616ce)
+++ src/libchcore/TTaskLocalStats.h	(.../TTaskLocalStats.h)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
@@ -25,6 +25,7 @@
 
 #include "libchcore.h"
 #include "ESubTaskTypes.h"
+#include "TString.h"
 
 BEGIN_CHCORE_NAMESPACE
 
@@ -50,8 +51,17 @@
 	void SetTotalSize(unsigned long long ullSet);
 	unsigned long long GetTotalSize() const;
 
+	size_t GetCurrentIndex() const;
+	void SetCurrentIndex(size_t stIndex);
+
+	size_t GetTotalItems();
+	void SetTotalItems(size_t stCount);
+
 	int GetProgressInPercent() const;
 
+	void SetCurrentPath(const TString& strPath);
+	const TString& GetCurrentPath() const;
+
 	void MarkTaskAsRunning();
 	void MarkTaskAsNotRunning();
 	bool IsRunning() const;
@@ -73,6 +83,9 @@
 	volatile unsigned long long m_ullProcessedSize;
 	volatile unsigned long long m_ullTotalSize;
 
+	volatile size_t m_stCurrentIndex;
+	volatile size_t m_stTotalItems;
+
 	volatile bool m_bTaskIsRunning;
 
 	// time
@@ -83,6 +96,8 @@
 
 	volatile ESubOperationType m_eCurrentSubOperationType;
 
+	TString m_strCurrentPath;
+
 #pragma warning(push)
 #pragma warning(disable: 4251)
 	mutable boost::shared_mutex m_lock;
Index: src/libchcore/libchcore.vc90.vcproj
===================================================================
diff -u -rd88274a4bbfd4ef005d44c4d179b7596cb627486 -rbebda797ec6983535a8940f8f9f15453fe6b1785
--- src/libchcore/libchcore.vc90.vcproj	(.../libchcore.vc90.vcproj)	(revision d88274a4bbfd4ef005d44c4d179b7596cb627486)
+++ src/libchcore/libchcore.vc90.vcproj	(.../libchcore.vc90.vcproj)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="windows-1250"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="9,00"
+	Version="9.00"
 	Name="libchcore"
 	ProjectGUID="{CBBF380B-7B16-4A1E-8194-758DAD7D8011}"
 	RootNamespace="libchcore"
@@ -360,14 +360,6 @@
 					>
 				</File>
 				<File
-					RelativePath=".\TBasicProgressInfo.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\TBasicProgressInfo.h"
-					>
-				</File>
-				<File
 					RelativePath=".\TFileFilter.cpp"
 					>
 				</File>