Index: src/ch/MainWnd.cpp
===================================================================
diff -u -r1d8d51e0dd4d8ebcf0bd457d01fab984585220c0 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/ch/MainWnd.cpp	(.../MainWnd.cpp)	(revision 1d8d51e0dd4d8ebcf0bd457d01fab984585220c0)
+++ src/ch/MainWnd.cpp	(.../MainWnd.cpp)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -40,6 +40,7 @@
 #include "StringHelpers.h"
 #include "../libchcore/TCoreException.h"
 #include "../libicpf/exception.h"
+#include "../libchcore/TTaskManagerStatsSnapshot.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
@@ -361,7 +362,10 @@
 		{
 			if (m_tasks.GetSize() != 0)
 			{
-				_sntprintf(text, _MAX_PATH, _T("%s - %d %%"), GetApp().GetAppName(), m_tasks.GetPercent());
+				chcore::TTaskManagerStatsSnapshot tTMStats;
+				m_tasks.GetStatsSnapshot(tTMStats);
+
+				_sntprintf(text, _MAX_PATH, _T("%s - %d %%"), GetApp().GetAppName(), tTMStats.GetGlobalProgressInPercent());
 				m_ctlTray.SetTooltipText(text);
 			}
 			else
Index: src/ch/MiniViewDlg.cpp
===================================================================
diff -u -r1d8d51e0dd4d8ebcf0bd457d01fab984585220c0 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/ch/MiniViewDlg.cpp	(.../MiniViewDlg.cpp)	(revision 1d8d51e0dd4d8ebcf0bd457d01fab984585220c0)
+++ src/ch/MiniViewDlg.cpp	(.../MiniViewDlg.cpp)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -23,6 +23,7 @@
 #include "ch.h"
 #include <assert.h>
 #include "MemDC.h"
+#include "../libchcore/TTaskManagerStatsSnapshot.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
@@ -206,7 +207,7 @@
 					pItem->m_strText = GetResManager().LoadString(IDS_NONEINPUTFILE_STRING);
 				else
 					pItem->m_strText = m_tMiniDisplayData.m_strPath;
-				pItem->m_uiPos=m_tMiniDisplayData.m_nPercent;
+				pItem->m_uiPos = boost::numeric_cast<int>(m_tMiniDisplayData.m_dPercent);
 				pItem->m_spTask = spTask;
 			}
 		}
@@ -245,11 +246,14 @@
 		}
 	}
 
+	chcore::TTaskManagerStatsSnapshot tTMStats;
+	m_pTasks->GetStatsSnapshot(tTMStats);
+
 	// add all state
 	pItem=m_ctlStatus.GetItemAddress(index++);
 	pItem->m_crColor=GetSysColor(COLOR_HIGHLIGHT);
 	pItem->m_strText=GetResManager().LoadString(IDS_MINIVIEWALL_STRING);
-	pItem->m_uiPos=m_pTasks->GetPercent();
+	pItem->m_uiPos = boost::numeric_cast<int>(tTMStats.GetGlobalProgressInPercent());
 	pItem->m_spTask.reset();
 
 	// get rid of the rest
Index: src/ch/StatusDlg.cpp
===================================================================
diff -u -rd88274a4bbfd4ef005d44c4d179b7596cb627486 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/ch/StatusDlg.cpp	(.../StatusDlg.cpp)	(revision d88274a4bbfd4ef005d44c4d179b7596cb627486)
+++ src/ch/StatusDlg.cpp	(.../StatusDlg.cpp)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -26,6 +26,8 @@
 #include "StringHelpers.h"
 #include "StaticEx.h"
 #include "Structs.h"
+#include "../libchcore/TTaskStatsSnapshot.h"
+#include "../libchcore/TTaskManagerStatsSnapshot.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
@@ -268,7 +270,7 @@
 
 	// insert dest subitem
 	lvi.iSubItem=3;
-	_itot( td.m_nPercent, m_szData, 10 );
+	_itot(boost::numeric_cast<int>(td.m_dPercent), m_szData, 10);
 	_tcscat(m_szData, _T(" %"));
 	lvi.pszText=m_szData;
 	lvi.cchTextMax=lstrlen(lvi.pszText);
@@ -319,7 +321,7 @@
 		m_i64LastProcessed=td.m_ullProcessedSize;
 
 		// set progress
-		m_ctlCurrentProgress.SetPos(td.m_nPercent);
+		m_ctlCurrentProgress.SetPos(boost::numeric_cast<int>(td.m_dPercent));
 
 		SetBufferSizesString(td.m_iCurrentBufferSize, td.m_iCurrentBufferIndex);
 
@@ -344,8 +346,11 @@
 		return;
 
 	CBufferSizeDlg dlg;
+	chcore::TTaskStatsSnapshot tTaskStats;
+	spTask->GetTaskStats(tTaskStats);
+
 	spTask->GetBufferSizes(dlg.m_bsSizes);
-	dlg.m_iActiveIndex = spTask->GetCurrentBufferIndex();
+	dlg.m_iActiveIndex = tTaskStats.GetCurrentSubTaskStats().GetCurrentBufferIndex();
 	if(dlg.DoModal() == IDOK)
 		spTask->SetBufferSizes(dlg.m_bsSizes);
 }
@@ -714,11 +719,12 @@
 	}
 
 	// percent
-	int nPercent=m_pTasks->GetPercent();
+	chcore::TTaskManagerStatsSnapshot tTMStats;
+	m_pTasks->GetStatsSnapshot(tTMStats);
 
 	// set title
 	if (m_pTasks->GetSize() != 0)
-		_sntprintf(m_szData, _MAX_PATH, _T("%s [%d %%]"), GetResManager().LoadString(IDS_STATUSTITLE_STRING), m_pTasks->GetPercent());
+		_sntprintf(m_szData, _MAX_PATH, _T("%s [%.0f %%]"), GetResManager().LoadString(IDS_STATUSTITLE_STRING), tTMStats.GetGlobalProgressInPercent());
 	else
 		_sntprintf(m_szData, _MAX_PATH, _T("%s"), GetResManager().LoadString(IDS_STATUSTITLE_STRING));
 	
@@ -731,24 +737,24 @@
 	// refresh overall progress
 	if (GetPropValue<PP_STATUSSHOWDETAILS>(GetConfig()))
 	{
-		m_ctlProgressAll.SetPos(nPercent);
+		m_ctlProgressAll.SetPos(boost::numeric_cast<int>(tTMStats.GetGlobalProgressInPercent()));
 		
 		// progress - count of processed data/count of data
-		strTemp=GetSizeString(m_pTasks->GetPosition(), m_szData, _MAX_PATH)+CString(_T("/"));
-		strTemp+=GetSizeString(m_pTasks->GetRange(), m_szData, _MAX_PATH);
+		strTemp=GetSizeString(tTMStats.GetProcessedSize(), m_szData, _MAX_PATH)+CString(_T("/"));
+		strTemp+=GetSizeString(tTMStats.GetTotalSize(), m_szData, _MAX_PATH);
 		GetDlgItem(IDC_OVERALL_PROGRESS_STATIC)->SetWindowText(strTemp);
 		
 		// transfer
 		if (m_i64LastAllTasksProcessed == 0)
-			m_i64LastAllTasksProcessed=m_pTasks->GetPosition();
+			m_i64LastAllTasksProcessed=tTMStats.GetProcessedSize();
 		
 		if (dwCurrentTime-m_dwLastUpdate != 0)
-			strTemp=GetSizeString( (static_cast<double>(m_pTasks->GetPosition()) - static_cast<double>(m_i64LastAllTasksProcessed))/static_cast<double>(static_cast<double>(dwCurrentTime-m_dwLastUpdate)/1000.0), m_szData, _MAX_PATH);
+			strTemp=GetSizeString( (static_cast<double>(tTMStats.GetProcessedSize()) - static_cast<double>(m_i64LastAllTasksProcessed))/static_cast<double>(static_cast<double>(dwCurrentTime-m_dwLastUpdate)/1000.0), m_szData, _MAX_PATH);
 		else
 			strTemp=GetSizeString( 0ULL, m_szData, _MAX_PATH);
 		
 		GetDlgItem(IDC_OVERALL_TRANSFER_STATIC)->SetWindowText(strTemp+_T("/s"));
-		m_i64LastAllTasksProcessed=m_pTasks->GetPosition();
+		m_i64LastAllTasksProcessed=tTMStats.GetProcessedSize();
 		m_dwLastUpdate=dwCurrentTime;
 	}
 
Index: src/libchcore/TSubTaskArray.cpp
===================================================================
diff -u -rbebda797ec6983535a8940f8f9f15453fe6b1785 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TSubTaskArray.cpp	(.../TSubTaskArray.cpp)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
+++ src/libchcore/TSubTaskArray.cpp	(.../TSubTaskArray.cpp)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -32,6 +32,7 @@
 #include "TSubTaskFastMove.h"
 #include "SerializationHelpers.h"
 #include "TBinarySerializer.h"
+#include "TTaskStatsSnapshot.h"
 
 BEGIN_CHCORE_NAMESPACE
 
@@ -102,13 +103,15 @@
 ///////////////////////////////////////////////////////////////////////////
 // TSubTasksArray
 
-TSubTasksArray::TSubTasksArray() :
-	m_pSubTaskContext(NULL)
+TSubTasksArray::TSubTasksArray(TTaskLocalStatsInfo& rLocalStats) :
+	m_pSubTaskContext(NULL),
+	m_rLocalStats(rLocalStats)
 {
 }
 
-	TSubTasksArray::TSubTasksArray(const TOperationPlan& rOperationPlan, TSubTaskContext& rSubTaskContext) :
-m_pSubTaskContext(NULL)
+TSubTasksArray::TSubTasksArray(const TOperationPlan& rOperationPlan, TSubTaskContext& rSubTaskContext, TTaskLocalStatsInfo& rLocalStats) :
+	m_pSubTaskContext(NULL),
+	m_rLocalStats(rLocalStats)
 {
 	Init(rOperationPlan, rSubTaskContext);
 }
@@ -128,22 +131,22 @@
 	case eOperation_Copy:
 		{
 			TSubTaskBasePtr spOperation = boost::make_shared<TSubTaskScanDirectories>(boost::ref(rSubTaskContext));
-			m_vSubTasks.push_back(boost::make_tuple(spOperation, 0.05, true));
+			AddSubTask(spOperation, 5, true);
 			spOperation = boost::make_shared<TSubTaskCopyMove>(boost::ref(rSubTaskContext));
-			m_vSubTasks.push_back(boost::make_tuple(spOperation, 0.95, false));
+			AddSubTask(spOperation, 95, false);
 
 			break;
 		}
 	case eOperation_Move:
 		{
 			TSubTaskBasePtr spOperation = boost::make_shared<TSubTaskFastMove>(boost::ref(rSubTaskContext));
-			m_vSubTasks.push_back(boost::make_tuple(spOperation, 0.05, true));
+			AddSubTask(spOperation, 5, true);
 			spOperation = boost::make_shared<TSubTaskScanDirectories>(boost::ref(rSubTaskContext));
-			m_vSubTasks.push_back(boost::make_tuple(spOperation, 0.05, false));
+			AddSubTask(spOperation, 5, false);
 			spOperation = boost::make_shared<TSubTaskCopyMove>(boost::ref(rSubTaskContext));
-			m_vSubTasks.push_back(boost::make_tuple(spOperation, 0.85, false));
+			AddSubTask(spOperation, 85, false);
 			spOperation = boost::make_shared<TSubTaskDelete>(boost::ref(rSubTaskContext));
-			m_vSubTasks.push_back(boost::make_tuple(spOperation, 0.05, false));
+			AddSubTask(spOperation, 5, false);
 
 			break;
 		}
@@ -152,17 +155,18 @@
 	}
 }
 
-void TSubTasksArray::ResetProgress()
+void TSubTasksArray::ResetProgressAndStats()
 {
 	m_tProgressInfo.ResetProgress();
+	m_rLocalStats.Clear();
 
 	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();
+		tupleRow.get<0>()->Reset();
 	}
 }
 
@@ -194,12 +198,14 @@
 	TSubTaskBase::ESubOperationResult eResult = TSubTaskBase::eSubResult_Continue;
 
 	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];
+		boost::tuples::tuple<TSubTaskBasePtr, int, bool>& rCurrentSubTask = m_vSubTasks[stSubOperationIndex];
 		TSubTaskBasePtr spCurrentSubTask = rCurrentSubTask.get<0>();
 
-		m_pSubTaskContext->GetTaskLocalStats().SetCurrentSubOperationType(spCurrentSubTask->GetSubOperationType());
+		m_rLocalStats.SetCurrentSubOperationType(spCurrentSubTask->GetSubOperationType());
+
 		// set current sub-operation index to allow resuming
 		m_tProgressInfo.SetSubOperationIndex(stSubOperationIndex);
 
@@ -216,4 +222,42 @@
 	return eResult;
 }
 
+void TSubTasksArray::AddSubTask(const TSubTaskBasePtr& spOperation, int iPercent, bool bIsPartOfEstimation)
+{
+	m_vSubTasks.push_back(boost::make_tuple(spOperation, iPercent, bIsPartOfEstimation));
+}
+
+void TSubTasksArray::GetTaskStats(TTaskStatsSnapshot& rSnapshot) const
+{
+	rSnapshot.Clear();
+
+	// from local stats
+	m_rLocalStats.GetSnapshot(rSnapshot);
+
+	// current task
+	size_t stSubOperationIndex = m_tProgressInfo.GetSubOperationIndex();
+
+	const boost::tuples::tuple<TSubTaskBasePtr, int, bool>& rCurrentSubTask = m_vSubTasks[stSubOperationIndex];
+	TSubTaskBasePtr spCurrentSubTask = rCurrentSubTask.get<0>();
+
+	spCurrentSubTask->GetStatsSnapshot(rSnapshot.GetCurrentSubTaskStats());
+
+	// progress
+	TSubTaskStatsSnapshot tSnapshot;
+	double dTotalProgress = 0.0;
+	for(stSubOperationIndex = 0; stSubOperationIndex < m_vSubTasks.size(); ++stSubOperationIndex)
+	{
+		const boost::tuples::tuple<TSubTaskBasePtr, int, bool>& rCurrentSubTask = m_vSubTasks[stSubOperationIndex];
+		TSubTaskBasePtr spCurrentSubTask = rCurrentSubTask.get<0>();
+		int iSubTaskPercent = rCurrentSubTask.get<1>();
+
+		spCurrentSubTask->GetStatsSnapshot(tSnapshot);
+
+		double dCurrentTaskPercent = tSnapshot.GetProgressInPercent() * iSubTaskPercent / 100.0;
+		dTotalProgress += dCurrentTaskPercent;
+	}
+
+	rSnapshot.SetTaskProgressInPercent(dTotalProgress);
+}
+
 END_CHCORE_NAMESPACE
Index: src/libchcore/TSubTaskArray.h
===================================================================
diff -u -rbebda797ec6983535a8940f8f9f15453fe6b1785 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TSubTaskArray.h	(.../TSubTaskArray.h)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
+++ src/libchcore/TSubTaskArray.h	(.../TSubTaskArray.h)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -26,6 +26,7 @@
 #include "libchcore.h"
 #include <boost/tuple/tuple.hpp>
 #include "TSubTaskBase.h"
+#include "TTaskLocalStats.h"
 
 BEGIN_CHCORE_NAMESPACE
 
@@ -73,13 +74,17 @@
 class LIBCHCORE_API TSubTasksArray
 {
 public:
-	TSubTasksArray();
-	TSubTasksArray(const TOperationPlan& rOperationPlan, TSubTaskContext& rSubTaskContext);
+	TSubTasksArray(TTaskLocalStatsInfo& rLocalStats);
+	TSubTasksArray(const TOperationPlan& rOperationPlan, TSubTaskContext& rSubTaskContext, TTaskLocalStatsInfo& rLocalStats);
 	~TSubTasksArray();
 
 	void Init(const TOperationPlan& rOperationPlan, TSubTaskContext& rSubTaskContext);
-	void ResetProgress();
 
+	// Stats handling
+	void GetTaskStats(TTaskStatsSnapshot& rSnapshot) const;
+	void ResetProgressAndStats();
+
+	// progress handling
 	void SerializeProgress(TReadBinarySerializer& rSerializer);
 	void SerializeProgress(TWriteBinarySerializer& rSerializer) const;
 
@@ -89,14 +94,20 @@
 	TSubTasksArray(const TSubTasksArray& rSrc);
 	TSubTasksArray& operator=(const TSubTasksArray& rSrc);
 
+	void AddSubTask(const TSubTaskBasePtr& spOperation, int iPercent, bool bIsPartOfEstimation);
+
 private:
 	TSubTaskContext* m_pSubTaskContext;
+	TTaskLocalStatsInfo& m_rLocalStats;
 
 #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?
+	std::vector<boost::tuples::tuple<TSubTaskBasePtr, int, 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)
+
+	friend class TTaskProcessingGuard;
 };
 
 END_CHCORE_NAMESPACE
Index: src/libchcore/TSubTaskBase.h
===================================================================
diff -u -r20aff533ab239b5b41263bb342879b4ea46fdbf6 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TSubTaskBase.h	(.../TSubTaskBase.h)	(revision 20aff533ab239b5b41263bb342879b4ea46fdbf6)
+++ src/libchcore/TSubTaskBase.h	(.../TSubTaskBase.h)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -64,12 +64,17 @@
 	TSubTaskBase(TSubTaskContext& rContext);
 	virtual ~TSubTaskBase();
 
+	virtual void Reset() = 0;
+
 	virtual ESubOperationResult Exec() = 0;
 	virtual ESubOperationType GetSubOperationType() const = 0;
 
+	// progress
 	virtual TSubTaskProgressInfo& GetProgressInfo() = 0;
-	virtual const TSubTaskStatsInfo& GetStatsInfo() const { return m_tSubTaskStats; }
 
+	// stats
+	virtual void GetStatsSnapshot(TSubTaskStatsSnapshot& rStats) const = 0;
+
 protected:
 	// some common operations
 	TSubTaskContext& GetContext() { return m_rContext; }
@@ -82,9 +87,6 @@
 	TSubTaskBase(const TSubTaskBase&);
 	TSubTaskBase& operator=(const TSubTaskBase&);
 
-protected:
-	TSubTaskStatsInfo m_tSubTaskStats;
-
 private:
 	TSubTaskContext& m_rContext;
 };
Index: src/libchcore/TSubTaskContext.cpp
===================================================================
diff -u -rbebda797ec6983535a8940f8f9f15453fe6b1785 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TSubTaskContext.cpp	(.../TSubTaskContext.cpp)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
+++ src/libchcore/TSubTaskContext.cpp	(.../TSubTaskContext.cpp)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -25,13 +25,12 @@
 
 BEGIN_CHCORE_NAMESPACE
 
-TSubTaskContext::TSubTaskContext(TTaskDefinition& rTaskDefinition, TBasePathDataContainer& rBasePathDataContainer, TFileInfoArray& rFilesCache, TTaskLocalStats& rTaskLocalStats, 
+TSubTaskContext::TSubTaskContext(TTaskDefinition& rTaskDefinition, TBasePathDataContainer& rBasePathDataContainer, TFileInfoArray& rFilesCache, 
 								 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_rCfgTracker(rCfgTracker),
 	m_rLog(rLog),
 	m_piFeedbackHandler(piFeedbackHandler),
Index: src/libchcore/TSubTaskContext.h
===================================================================
diff -u -rbebda797ec6983535a8940f8f9f15453fe6b1785 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TSubTaskContext.h	(.../TSubTaskContext.h)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
+++ src/libchcore/TSubTaskContext.h	(.../TSubTaskContext.h)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -38,7 +38,7 @@
 class TBasePathDataContainer;
 class TTaskConfigTracker;
 class TLocalFilesystem;
-class TTaskLocalStats;
+class TTaskLocalStatsInfo;
 class TTaskBasicProgressInfo;
 class TFileInfoArray;
 
@@ -48,7 +48,7 @@
 class LIBCHCORE_API TSubTaskContext
 {
 public:
-	TSubTaskContext(TTaskDefinition& rTaskDefinition, TBasePathDataContainer& rBasePathDataContainer, TFileInfoArray& rFilesCache, TTaskLocalStats& rTaskLocalStats,
+	TSubTaskContext(TTaskDefinition& rTaskDefinition, TBasePathDataContainer& rBasePathDataContainer, TFileInfoArray& rFilesCache,
 		TTaskConfigTracker& rCfgTracker, icpf::log_file& rLog,
 		IFeedbackHandler* piFeedbackHandler, TWorkerThreadController& rThreadController, TLocalFilesystem& rfsLocal);
 	~TSubTaskContext();
@@ -62,9 +62,6 @@
 	TFileInfoArray& GetFilesCache() { return m_rFilesCache; }
 	const TFileInfoArray& GetFilesCache() const { return m_rFilesCache; }
 
-	TTaskLocalStats& GetTaskLocalStats() { return m_rTaskLocalStats; }
-	const TTaskLocalStats& GetTaskLocalStats() const { return m_rTaskLocalStats; }
-
 	TTaskConfigTracker& GetCfgTracker() { return m_rCfgTracker; }
 	const TTaskConfigTracker& GetCfgTracker() const { return m_rCfgTracker; }
 
@@ -93,9 +90,6 @@
 	// data on which to operate
 	TFileInfoArray& m_rFilesCache;
 
-	// local stats for task
-	TTaskLocalStats& m_rTaskLocalStats;
-
 	// configuration changes tracking
 	TTaskConfigTracker& m_rCfgTracker;
 
Index: src/libchcore/TSubTaskCopyMove.cpp
===================================================================
diff -u -r20aff533ab239b5b41263bb342879b4ea46fdbf6 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TSubTaskCopyMove.cpp	(.../TSubTaskCopyMove.cpp)	(revision 20aff533ab239b5b41263bb342879b4ea46fdbf6)
+++ src/libchcore/TSubTaskCopyMove.cpp	(.../TSubTaskCopyMove.cpp)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -149,6 +149,12 @@
 {
 }
 
+void TSubTaskCopyMove::Reset()
+{
+	m_tProgressInfo.ResetProgress();
+	m_tSubTaskStats.Clear();
+}
+
 TSubTaskBase::ESubOperationResult TSubTaskCopyMove::Exec()
 {
 	TSubTaskProcessingGuard guard(m_tSubTaskStats);
@@ -159,7 +165,6 @@
 	TTaskConfigTracker& rCfgTracker = GetContext().GetCfgTracker();
 	TWorkerThreadController& rThreadController = GetContext().GetThreadController();
 	IFeedbackHandler* piFeedbackHandler = GetContext().GetFeedbackHandler();
-	TTaskLocalStats& rLocalStats = GetContext().GetTaskLocalStats();
 
 	BOOST_ASSERT(piFeedbackHandler != NULL);
 	if(piFeedbackHandler == NULL)
@@ -168,15 +173,8 @@
 	// log
 	rLog.logi(_T("Processing files/folders (ProcessFiles)"));
 
-	// old stats
-	rLocalStats.SetProcessedSize(rFilesCache.CalculatePartialSize(m_tProgressInfo.GetCurrentIndex()));
-	rLocalStats.SetTotalSize(rFilesCache.CalculateTotalSize());
-	rLocalStats.SetCurrentIndex(m_tProgressInfo.GetCurrentIndex());
-	rLocalStats.SetTotalItems(rFilesCache.GetSize());
-	rLocalStats.SetCurrentPath(TString());
-
 	// new stats
-	m_tSubTaskStats.SetCurrentBufferIndex(-1);
+	m_tSubTaskStats.SetCurrentBufferIndex(TBufferSizes::eBuffer_Default);
 	m_tSubTaskStats.SetTotalCount(rFilesCache.GetSize());
 	m_tSubTaskStats.SetProcessedCount(rFilesCache.GetSize());
 	m_tSubTaskStats.SetTotalSize(rFilesCache.CalculateTotalSize());
@@ -249,10 +247,6 @@
 		TFileInfoPtr spFileInfo = rFilesCache.GetAt(stIndex);
 		TSmartPath pathCurrent = spFileInfo->GetFullFilePath();
 
-		// old stats
-		rLocalStats.SetCurrentIndex(stIndex);
-		rLocalStats.SetCurrentPath(pathCurrent.ToString());
-
 		// new stats
 		m_tSubTaskStats.SetProcessedCount(stIndex);
 		m_tSubTaskStats.SetCurrentPath(pathCurrent.ToString());
@@ -297,8 +291,6 @@
 				}
 			}
 
-			// old stats
-			rLocalStats.IncreaseProcessedSize(spFileInfo->GetLength64());
 			// new stats
 			m_tSubTaskStats.IncreaseProcessedSize(spFileInfo->GetLength64());
 
@@ -338,10 +330,6 @@
 
 	m_tProgressInfo.SetCurrentIndex(stIndex);
 
-	// old stats
-	rLocalStats.SetCurrentIndex(stIndex);
-	rLocalStats.SetCurrentPath(TString());
-
 	// new stats
 	m_tSubTaskStats.SetProcessedCount(stIndex);
 	m_tSubTaskStats.SetCurrentPath(TString());
@@ -355,6 +343,11 @@
 	return TSubTaskBase::eSubResult_Continue;
 }
 
+void TSubTaskCopyMove::GetStatsSnapshot(TSubTaskStatsSnapshot& rStats) const
+{
+	m_tSubTaskStats.GetSnapshot(rStats);
+}
+
 int TSubTaskCopyMove::GetBufferIndex(const TFileInfoPtr& spFileInfo)
 {
 	if(!spFileInfo)
@@ -388,7 +381,6 @@
 {
 	TTaskDefinition& rTaskDefinition = GetContext().GetTaskDefinition();
 	TWorkerThreadController& rThreadController = GetContext().GetThreadController();
-	TTaskLocalStats& rLocalStats = GetContext().GetTaskLocalStats();
 	icpf::log_file& rLog = GetContext().GetLog();
 	TTaskConfigTracker& rCfgTracker = GetContext().GetCfgTracker();
 
@@ -413,8 +405,6 @@
 	else if(!fileSrc.IsOpen())
 	{
 		// invalid handle = operation skipped by user
-		// old stats
-		rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 		// new stats
 		m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 
@@ -441,8 +431,6 @@
 			return eResult;
 		else if(!fileDst.IsOpen())
 		{
-			// old stats
-			rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 			// new stats
 			m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 
@@ -458,8 +446,6 @@
 			return eResult;
 		else if(!fileDst.IsOpen())
 		{
-			// old stats
-			rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 			// new stats
 			m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 
@@ -484,8 +470,6 @@
 			else if(bSkip)
 			{
 				// old stats
-				rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
-				// old stats
 				m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 
 				pData->bProcessed = false;
@@ -498,8 +482,6 @@
 			else if(bSkip)
 			{
 				// with either first or second seek we got 'skip' answer...
-				// old stats
-				rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 				// new stats
 				m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 
@@ -508,8 +490,6 @@
 			}
 
 			m_tProgressInfo.IncreaseCurrentFileProcessedSize(ullMove);
-			// old stats
-			rLocalStats.IncreaseProcessedSize(ullMove);
 			// new stats
 			m_tSubTaskStats.IncreaseProcessedSize(ullMove);
 		}
@@ -586,8 +566,6 @@
 				iBufferIndex = TBufferSizes::eBuffer_Default;
 			else
 				iBufferIndex = GetBufferIndex(pData->spSrcFile);
-			// old stats
-			rLocalStats.SetCurrentBufferIndex(iBufferIndex);
 			// new stats
 			m_tSubTaskStats.SetCurrentBufferIndex(iBufferIndex);
 
@@ -600,8 +578,6 @@
 			else if(bSkip)
 			{
 				// old stats
-				rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
-				// old stats
 				m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 
 				pData->bProcessed = false;
@@ -630,8 +606,6 @@
 						else if(bSkip)
 						{
 							// old stats
-							rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
-							// old stats
 							m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 
 							pData->bProcessed = false;
@@ -640,8 +614,6 @@
 
 						// increase count of processed data
 						m_tProgressInfo.IncreaseCurrentFileProcessedSize(ulWritten);
-						// old stats
-						rLocalStats.IncreaseProcessedSize(ulWritten);
 						// new stats
 						m_tSubTaskStats.IncreaseProcessedSize(ulWritten);
 
@@ -664,9 +636,7 @@
 							return eResult;
 						else if(!fileDst.IsOpen())
 						{
-							// old stats
-							rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
-							// old stats
+							// new stats
 							m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 
 							pData->bProcessed = false;
@@ -680,8 +650,6 @@
 						else if(bSkip)
 						{
 							// with either first or second seek we got 'skip' answer...
-							// old stats
-							rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 							// new stats
 							m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 
@@ -699,8 +667,6 @@
 						return eResult;
 					else if(bSkip)
 					{
-						// old stats
-						rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 						// new stats
 						m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 
@@ -711,8 +677,6 @@
 					// increase count of processed data
 					m_tProgressInfo.IncreaseCurrentFileProcessedSize(ulRead);
 
-					// old stats
-					rLocalStats.IncreaseProcessedSize(ulRead);
 					// new stats
 					m_tSubTaskStats.IncreaseProcessedSize(ulRead);
 				}
@@ -723,8 +687,6 @@
 	else
 	{
 		// we don't copy contents, but need to increase processed size
-		// old stats
-		rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 		// new stats
 		m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize());
 	}
Index: src/libchcore/TSubTaskCopyMove.h
===================================================================
diff -u -rbebda797ec6983535a8940f8f9f15453fe6b1785 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TSubTaskCopyMove.h	(.../TSubTaskCopyMove.h)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
+++ src/libchcore/TSubTaskCopyMove.h	(.../TSubTaskCopyMove.h)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -73,10 +73,13 @@
 public:
 	TSubTaskCopyMove(TSubTaskContext& tSubTaskContext);
 
+	virtual void Reset();
+
 	virtual ESubOperationResult Exec();
 	virtual ESubOperationType GetSubOperationType() const { return eSubOperation_Copying; }
 
 	virtual TSubTaskProgressInfo& GetProgressInfo() { return m_tProgressInfo; }
+	virtual void GetStatsSnapshot(TSubTaskStatsSnapshot& rStats) const;
 
 private:
 	int GetBufferIndex(const TFileInfoPtr& spFileInfo);
@@ -100,6 +103,7 @@
 #pragma warning(push)
 #pragma warning(disable: 4251)
 	details::TCopyMoveProgressInfo m_tProgressInfo;
+	TSubTaskStatsInfo m_tSubTaskStats;
 #pragma warning(pop)
 };
 
Index: src/libchcore/TSubTaskDelete.cpp
===================================================================
diff -u -r20aff533ab239b5b41263bb342879b4ea46fdbf6 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TSubTaskDelete.cpp	(.../TSubTaskDelete.cpp)	(revision 20aff533ab239b5b41263bb342879b4ea46fdbf6)
+++ src/libchcore/TSubTaskDelete.cpp	(.../TSubTaskDelete.cpp)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -35,6 +35,7 @@
 #include "SerializationHelpers.h"
 #include "TBinarySerializer.h"
 #include "TTaskLocalStats.h"
+#include "DataBuffer.h"
 
 BEGIN_CHCORE_NAMESPACE
 
@@ -97,6 +98,12 @@
 {
 }
 
+void TSubTaskDelete::Reset()
+{
+	m_tProgressInfo.ResetProgress();
+	m_tSubTaskStats.Clear();
+}
+
 TSubTaskBase::ESubOperationResult TSubTaskDelete::Exec()
 {
 	TSubTaskProcessingGuard guard(m_tSubTaskStats);
@@ -107,20 +114,12 @@
 	TTaskDefinition& rTaskDefinition = GetContext().GetTaskDefinition();
 	TWorkerThreadController& rThreadController = GetContext().GetThreadController();
 	IFeedbackHandler* piFeedbackHandler = GetContext().GetFeedbackHandler();
-	TTaskLocalStats& rTaskLocalStats = GetContext().GetTaskLocalStats();
 
 	// log
 	rLog.logi(_T("Deleting files (DeleteFiles)..."));
 
-	// old stats
-	rTaskLocalStats.SetProcessedSize(0);
-	rTaskLocalStats.SetTotalSize(0);
-	rTaskLocalStats.SetCurrentIndex(0);
-	rTaskLocalStats.SetTotalItems(rFilesCache.GetSize());
-	rTaskLocalStats.SetCurrentPath(TString());
-
 	// new stats
-	m_tSubTaskStats.SetCurrentBufferIndex(-1);
+	m_tSubTaskStats.SetCurrentBufferIndex(TBufferSizes::eBuffer_Default);
 	m_tSubTaskStats.SetTotalCount(rFilesCache.GetSize());
 	m_tSubTaskStats.SetProcessedCount(0);
 	m_tSubTaskStats.SetTotalSize(0);
@@ -140,10 +139,6 @@
 
 		m_tProgressInfo.SetCurrentIndex(stIndex);
 
-		// old stats
-		rTaskLocalStats.SetCurrentIndex(stIndex);
-		rTaskLocalStats.SetCurrentPath(spFileInfo->GetFullFilePath().ToString());
-
 		// new stats
 		m_tSubTaskStats.SetProcessedCount(stIndex);
 		m_tSubTaskStats.SetCurrentPath(spFileInfo->GetFullFilePath().ToString());
@@ -216,10 +211,6 @@
 
 	m_tProgressInfo.SetCurrentIndex(stIndex);
 
-	// old stats
-	rTaskLocalStats.SetCurrentIndex(stIndex);
-	rTaskLocalStats.SetCurrentPath(TString());
-
 	// new stats
 	m_tSubTaskStats.SetProcessedCount(stIndex);
 	m_tSubTaskStats.SetCurrentPath(TString());
@@ -230,4 +221,9 @@
 	return TSubTaskBase::eSubResult_Continue;
 }
 
+void TSubTaskDelete::GetStatsSnapshot(TSubTaskStatsSnapshot& rStats) const
+{
+	m_tSubTaskStats.GetSnapshot(rStats);
+}
+
 END_CHCORE_NAMESPACE
Index: src/libchcore/TSubTaskDelete.h
===================================================================
diff -u -rbebda797ec6983535a8940f8f9f15453fe6b1785 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TSubTaskDelete.h	(.../TSubTaskDelete.h)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
+++ src/libchcore/TSubTaskDelete.h	(.../TSubTaskDelete.h)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -65,15 +65,19 @@
 public:
 	TSubTaskDelete(TSubTaskContext& rContext);
 
+	virtual void Reset();
+
 	virtual ESubOperationResult Exec();
 	virtual ESubOperationType GetSubOperationType() const { return eSubOperation_Deleting; }
 
 	virtual TSubTaskProgressInfo& GetProgressInfo() { return m_tProgressInfo; }
+	virtual void GetStatsSnapshot(TSubTaskStatsSnapshot& rStats) const;
 
 private:
 #pragma warning(push)
 #pragma warning(disable: 4251)
 	details::TDeleteProgressInfo m_tProgressInfo;
+	TSubTaskStatsInfo m_tSubTaskStats;
 #pragma warning(pop)
 };
 
Index: src/libchcore/TSubTaskFastMove.cpp
===================================================================
diff -u -r20aff533ab239b5b41263bb342879b4ea46fdbf6 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TSubTaskFastMove.cpp	(.../TSubTaskFastMove.cpp)	(revision 20aff533ab239b5b41263bb342879b4ea46fdbf6)
+++ src/libchcore/TSubTaskFastMove.cpp	(.../TSubTaskFastMove.cpp)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -36,6 +36,7 @@
 #include <boost\lexical_cast.hpp>
 #include "SerializationHelpers.h"
 #include "TBinarySerializer.h"
+#include "DataBuffer.h"
 
 BEGIN_CHCORE_NAMESPACE
 
@@ -99,6 +100,12 @@
 {
 }
 
+void TSubTaskFastMove::Reset()
+{
+	m_tProgressInfo.ResetProgress();
+	m_tSubTaskStats.Clear();
+}
+
 TSubTaskFastMove::ESubOperationResult TSubTaskFastMove::Exec()
 {
 	TSubTaskProcessingGuard guard(m_tSubTaskStats);
@@ -108,20 +115,12 @@
 	TTaskDefinition& rTaskDefinition = GetContext().GetTaskDefinition();
 	IFeedbackHandler* piFeedbackHandler = GetContext().GetFeedbackHandler();
 	TWorkerThreadController& rThreadController = GetContext().GetThreadController();
-	TTaskLocalStats& rTaskLocalStats = GetContext().GetTaskLocalStats();
 	TBasePathDataContainer& rBasePathDataContainer = GetContext().GetBasePathDataContainer();
 
 	rLog.logi(_T("Performing initial fast-move operation..."));
 
-	// old stats
-	rTaskLocalStats.SetProcessedSize(0);
-	rTaskLocalStats.SetTotalSize(0);
-	rTaskLocalStats.SetCurrentIndex(0);
-	rTaskLocalStats.SetTotalItems(rTaskDefinition.GetSourcePathCount());
-	rTaskLocalStats.SetCurrentPath(TString());
-
 	// new stats
-	m_tSubTaskStats.SetCurrentBufferIndex(-1);
+	m_tSubTaskStats.SetCurrentBufferIndex(TBufferSizes::eBuffer_Default);
 	m_tSubTaskStats.SetTotalCount(rTaskDefinition.GetSourcePathCount());
 	m_tSubTaskStats.SetProcessedCount(0);
 	m_tSubTaskStats.SetTotalSize(0);
@@ -156,10 +155,6 @@
 		// store currently processed index
 		m_tProgressInfo.SetCurrentIndex(stIndex);
 
-		// old stats
-		rTaskLocalStats.SetCurrentIndex(stIndex);
-		rTaskLocalStats.SetCurrentPath(pathCurrent.ToString());
-
 		// new stats
 		m_tSubTaskStats.SetProcessedCount(stIndex);
 		m_tSubTaskStats.SetCurrentPath(pathCurrent.ToString());
@@ -286,10 +281,6 @@
 
 	m_tProgressInfo.SetCurrentIndex(stIndex);
 
-	// old stats
-	rTaskLocalStats.SetCurrentIndex(stIndex);
-	rTaskLocalStats.SetCurrentPath(TString());
-
 	// new stats
 	m_tSubTaskStats.SetProcessedCount(stIndex);
 	m_tSubTaskStats.SetCurrentPath(TString());
@@ -300,4 +291,9 @@
 	return eSubResult_Continue;
 }
 
+void TSubTaskFastMove::GetStatsSnapshot(TSubTaskStatsSnapshot& rStats) const
+{
+	m_tSubTaskStats.GetSnapshot(rStats);
+}
+
 END_CHCORE_NAMESPACE
Index: src/libchcore/TSubTaskFastMove.h
===================================================================
diff -u -rbebda797ec6983535a8940f8f9f15453fe6b1785 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TSubTaskFastMove.h	(.../TSubTaskFastMove.h)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
+++ src/libchcore/TSubTaskFastMove.h	(.../TSubTaskFastMove.h)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -68,10 +68,13 @@
 	TSubTaskFastMove(TSubTaskContext& rContext);
 	virtual ~TSubTaskFastMove();
 
+	virtual void Reset();
+
 	virtual ESubOperationResult Exec();
 	virtual ESubOperationType GetSubOperationType() const { return eSubOperation_Scanning; }
 
 	virtual TSubTaskProgressInfo& GetProgressInfo() { return m_tProgressInfo; }
+	virtual void GetStatsSnapshot(TSubTaskStatsSnapshot& rStats) const;
 
 private:
 	int ScanDirectory(TSmartPath pathDirName, size_t stSrcIndex, bool bRecurse, bool bIncludeDirs, TFileFiltersArray& afFilters);
@@ -80,6 +83,7 @@
 #pragma warning(push)
 #pragma warning(disable: 4251)
 	details::TFastMoveProgressInfo m_tProgressInfo;
+	TSubTaskStatsInfo m_tSubTaskStats;
 #pragma warning(pop)
 };
 
Index: src/libchcore/TSubTaskScanDirectory.cpp
===================================================================
diff -u -r20aff533ab239b5b41263bb342879b4ea46fdbf6 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TSubTaskScanDirectory.cpp	(.../TSubTaskScanDirectory.cpp)	(revision 20aff533ab239b5b41263bb342879b4ea46fdbf6)
+++ src/libchcore/TSubTaskScanDirectory.cpp	(.../TSubTaskScanDirectory.cpp)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -36,6 +36,7 @@
 #include "TFileInfo.h"
 #include "SerializationHelpers.h"
 #include "TBinarySerializer.h"
+#include "DataBuffer.h"
 
 BEGIN_CHCORE_NAMESPACE
 
@@ -101,6 +102,12 @@
 {
 }
 
+void TSubTaskScanDirectories::Reset()
+{
+	m_tProgressInfo.ResetProgress();
+	m_tSubTaskStats.Clear();
+}
+
 TSubTaskScanDirectories::ESubOperationResult TSubTaskScanDirectories::Exec()
 {
 	TSubTaskProcessingGuard guard(m_tSubTaskStats);
@@ -111,23 +118,15 @@
 	TTaskDefinition& rTaskDefinition = GetContext().GetTaskDefinition();
 	IFeedbackHandler* piFeedbackHandler = GetContext().GetFeedbackHandler();
 	TWorkerThreadController& rThreadController = GetContext().GetThreadController();
-	TTaskLocalStats& rTaskLocalStats = GetContext().GetTaskLocalStats();
 	TBasePathDataContainer& rBasePathDataContainer = GetContext().GetBasePathDataContainer();
 
 	rLog.logi(_T("Searching for files..."));
 
 	// reset progress
 	rFilesCache.SetComplete(false);
 
-	// old stats
-	rTaskLocalStats.SetProcessedSize(0);
-	rTaskLocalStats.SetTotalSize(0);
-	rTaskLocalStats.SetCurrentIndex(0);
-	rTaskLocalStats.SetTotalItems(rTaskDefinition.GetSourcePathCount());
-	rTaskLocalStats.SetCurrentPath(TString());
-
 	// new stats
-	m_tSubTaskStats.SetCurrentBufferIndex(-1);
+	m_tSubTaskStats.SetCurrentBufferIndex(TBufferSizes::eBuffer_Default);
 	m_tSubTaskStats.SetTotalCount(rTaskDefinition.GetSourcePathCount());
 	m_tSubTaskStats.SetProcessedCount(0);
 	m_tSubTaskStats.SetTotalSize(0);
@@ -158,10 +157,6 @@
 
 		m_tProgressInfo.SetCurrentIndex(stIndex);
 
-		// old stats
-		rTaskLocalStats.SetCurrentIndex(stIndex);
-		rTaskLocalStats.SetCurrentPath(pathCurrent.ToString());
-
 		// new stats
 		m_tSubTaskStats.SetProcessedCount(stIndex);
 		m_tSubTaskStats.SetCurrentPath(pathCurrent.ToString());
@@ -272,10 +267,6 @@
 	// calc size of all files
 	m_tProgressInfo.SetCurrentIndex(stIndex);
 
-	// old stats
-	rTaskLocalStats.SetCurrentIndex(stIndex);
-	rTaskLocalStats.SetCurrentPath(TString());
-
 	// new stats
 	m_tSubTaskStats.SetProcessedCount(stIndex);
 	m_tSubTaskStats.SetCurrentPath(TString());
@@ -288,6 +279,11 @@
 	return eSubResult_Continue;
 }
 
+void TSubTaskScanDirectories::GetStatsSnapshot(TSubTaskStatsSnapshot& rStats) const
+{
+	m_tSubTaskStats.GetSnapshot(rStats);
+}
+
 int TSubTaskScanDirectories::ScanDirectory(TSmartPath pathDirName, size_t stSrcIndex, bool bRecurse, bool bIncludeDirs, TFileFiltersArray& afFilters)
 {
 	TFileInfoArray& rFilesCache = GetContext().GetFilesCache();
Index: src/libchcore/TSubTaskScanDirectory.h
===================================================================
diff -u -rbebda797ec6983535a8940f8f9f15453fe6b1785 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TSubTaskScanDirectory.h	(.../TSubTaskScanDirectory.h)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
+++ src/libchcore/TSubTaskScanDirectory.h	(.../TSubTaskScanDirectory.h)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -68,10 +68,13 @@
 	TSubTaskScanDirectories(TSubTaskContext& rContext);
 	virtual ~TSubTaskScanDirectories();
 
+	virtual void Reset();
+
 	virtual ESubOperationResult Exec();
 	virtual ESubOperationType GetSubOperationType() const { return eSubOperation_Scanning; }
 
 	virtual TSubTaskProgressInfo& GetProgressInfo() { return m_tProgressInfo; }
+	virtual void GetStatsSnapshot(TSubTaskStatsSnapshot& rStats) const;
 
 private:
 	int ScanDirectory(TSmartPath pathDirName, size_t stSrcIndex, bool bRecurse, bool bIncludeDirs, TFileFiltersArray& afFilters);
@@ -80,6 +83,7 @@
 #pragma warning(push)
 #pragma warning(disable: 4251)
 	details::TScanDirectoriesProgressInfo m_tProgressInfo;
+	TSubTaskStatsInfo m_tSubTaskStats;
 #pragma warning(pop)
 };
 
Index: src/libchcore/TSubTaskStatsInfo.cpp
===================================================================
diff -u -r20aff533ab239b5b41263bb342879b4ea46fdbf6 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TSubTaskStatsInfo.cpp	(.../TSubTaskStatsInfo.cpp)	(revision 20aff533ab239b5b41263bb342879b4ea46fdbf6)
+++ src/libchcore/TSubTaskStatsInfo.cpp	(.../TSubTaskStatsInfo.cpp)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -22,6 +22,9 @@
 // ============================================================================
 #include "stdafx.h"
 #include "TSubTaskStatsInfo.h"
+#include <boost\numeric\conversion\cast.hpp>
+#include "DataBuffer.h"
+#include "TSubTaskStatsSnapshot.h"
 
 BEGIN_CHCORE_NAMESPACE
 
@@ -51,10 +54,41 @@
 	m_iCurrentBufferIndex(0),
 	m_strCurrentPath(),
 	m_timeElapsed(0),
-	m_timeLast(0)
+	m_timeLast(-1)
 {
 }
 
+void TSubTaskStatsInfo::Clear()
+{
+	m_bSubTaskIsRunning = false;
+	m_ullTotalSize = 0;
+	m_ullProcessedSize = 0;
+	m_stTotalCount = 0;
+	m_stProcessedCount = 0;
+	m_iCurrentBufferIndex = 0;
+	m_strCurrentPath.Clear();
+	m_timeElapsed = 0;
+	m_timeLast = -1;
+}
+
+void TSubTaskStatsInfo::GetSnapshot(TSubTaskStatsSnapshot& rStatsSnapshot) const
+{
+	rStatsSnapshot.Clear();
+
+	boost::upgrade_lock<boost::shared_mutex> lock(m_lock);
+	UpdateTime(lock);
+
+	rStatsSnapshot.SetRunning(m_bSubTaskIsRunning);
+	rStatsSnapshot.SetProcessedCount(m_stProcessedCount);
+	rStatsSnapshot.SetTotalCount(m_stTotalCount);
+	rStatsSnapshot.SetProcessedSize(m_ullProcessedSize);
+	rStatsSnapshot.SetTotalSize(m_ullTotalSize);
+	rStatsSnapshot.SetProgressInPercent(CalculateProgressInPercent(lock));
+	rStatsSnapshot.SetCurrentBufferIndex(m_iCurrentBufferIndex);
+	rStatsSnapshot.SetCurrentPath(m_strCurrentPath);
+	rStatsSnapshot.SetTimeElapsed(m_timeElapsed);
+}
+
 // is running?
 void TSubTaskStatsInfo::MarkAsRunning()
 {
@@ -68,20 +102,6 @@
 	m_bSubTaskIsRunning = false;
 }
 
-bool TSubTaskStatsInfo::IsRunning() const
-{
-	boost::shared_lock<boost::shared_mutex> lock(m_lock);
-	return m_bSubTaskIsRunning;
-}
-
-// count stats
-void TSubTaskStatsInfo::GetCountStats(size_t& stProcessedCount, size_t& stTotalCount) const
-{
-	boost::shared_lock<boost::shared_mutex> lock(m_lock);
-	stProcessedCount = m_stProcessedCount;
-	stTotalCount = m_stTotalCount;
-}
-
 void TSubTaskStatsInfo::IncreaseProcessedCount(size_t stIncreaseBy)
 {
 	boost::unique_lock<boost::shared_mutex> lock(m_lock);
@@ -109,14 +129,6 @@
 		THROW_CORE_EXCEPTION(eErr_InternalProblem);
 }
 
-// size stats
-void TSubTaskStatsInfo::GetSizeStats(unsigned long long& ullProcessedSize, unsigned long long& ullTotalSize) const
-{
-	boost::shared_lock<boost::shared_mutex> lock(m_lock);
-	ullProcessedSize = m_ullProcessedSize;
-	ullTotalSize = m_ullTotalSize;
-}
-
 void TSubTaskStatsInfo::IncreaseProcessedSize(unsigned long long ullIncreaseBy)
 {
 	boost::unique_lock<boost::shared_mutex> lock(m_lock);
@@ -150,42 +162,20 @@
 	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 	m_iCurrentBufferIndex = iCurrentIndex;
 }
-
-int TSubTaskStatsInfo::GetCurrentBufferIndex() const
-{
-	boost::shared_lock<boost::shared_mutex> lock(m_lock);
-	return m_iCurrentBufferIndex;
-}
-
 // current path
 void TSubTaskStatsInfo::SetCurrentPath(const TString& strPath)
 {
 	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 	m_strCurrentPath = strPath;
 }
 
-const TString& TSubTaskStatsInfo::GetCurrentPath() const
-{
-	boost::shared_lock<boost::shared_mutex> lock(m_lock);
-	return m_strCurrentPath;
-}
-
 // time
 void TSubTaskStatsInfo::SetTimeElapsed(time_t timeElapsed)
 {
 	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 	m_timeElapsed = timeElapsed;
 }
 
-time_t TSubTaskStatsInfo::GetTimeElapsed()
-{
-	boost::upgrade_lock<boost::shared_mutex> lock(m_lock);
-
-	UpdateTime(lock);
-
-	return m_timeElapsed;
-}
-
 void TSubTaskStatsInfo::EnableTimeTracking()
 {
 	boost::upgrade_lock<boost::shared_mutex> lock(m_lock);
@@ -209,7 +199,7 @@
 	}
 }
 
-void TSubTaskStatsInfo::UpdateTime(boost::upgrade_lock<boost::shared_mutex>& lock)
+void TSubTaskStatsInfo::UpdateTime(boost::upgrade_lock<boost::shared_mutex>& lock) const
 {
 	if(m_timeLast != -1)
 	{
@@ -221,4 +211,21 @@
 	}
 }
 
+double TSubTaskStatsInfo::CalculateProgressInPercent(boost::upgrade_lock<boost::shared_mutex>& lock) const
+{
+	lock;	// lock unused; enforced passing as parameter to ensure the code is executed in critical section
+	double dSizePercent = 0;
+	double dCountPercent = 0;
+
+	if(m_ullTotalSize)
+		dSizePercent = 100.0 * boost::numeric_cast<double>(m_ullProcessedSize) / boost::numeric_cast<double>(m_ullTotalSize);
+	if(m_stTotalCount)
+		dCountPercent = 100.0 * boost::numeric_cast<double>(m_stProcessedCount) / boost::numeric_cast<double>(m_stTotalCount);
+
+	if(m_ullTotalSize && m_stTotalCount)
+		return (dSizePercent + dCountPercent) / 2;
+	else
+		return dSizePercent + dCountPercent;
+}
+
 END_CHCORE_NAMESPACE
Index: src/libchcore/TSubTaskStatsInfo.h
===================================================================
diff -u -r20aff533ab239b5b41263bb342879b4ea46fdbf6 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TSubTaskStatsInfo.h	(.../TSubTaskStatsInfo.h)	(revision 20aff533ab239b5b41263bb342879b4ea46fdbf6)
+++ src/libchcore/TSubTaskStatsInfo.h	(.../TSubTaskStatsInfo.h)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -29,6 +29,7 @@
 BEGIN_CHCORE_NAMESPACE
 
 class TSubTaskStatsInfo;
+class TSubTaskStatsSnapshot;
 
 // class used to guard scope of the subtask processing (
 class TSubTaskProcessingGuard
@@ -45,51 +46,51 @@
 	TSubTaskStatsInfo& m_rStats;
 };
 
-class LIBCHCORE_API TSubTaskStatsInfo
+class TSubTaskStatsInfo
 {
 public:
 	TSubTaskStatsInfo();
 
-	// is running?
-	bool IsRunning() const;
+	void Clear();
 
-	// count stats
-	void GetCountStats(size_t& stItemIndex, size_t& stItemsCount) const;
+	void GetSnapshot(TSubTaskStatsSnapshot& rStatsSnapshot) const;
 
 	void IncreaseProcessedCount(size_t stIncreaseBy);
 	void SetProcessedCount(size_t stIndex);
 
 	void SetTotalCount(size_t stCount);
 
 	// size stats
-	void GetSizeStats(unsigned long long& ullProcessedSize, unsigned long long& ullTotalSize) const;
 	void IncreaseProcessedSize(unsigned long long ullIncreaseBy);
 	void SetProcessedSize(unsigned long long ullProcessedSize);
 
 	void SetTotalSize(unsigned long long ullTotalSize);
 
 	// buffer index
 	void SetCurrentBufferIndex(int iCurrentIndex);
-	int GetCurrentBufferIndex() const;
 
 	// current path
 	void SetCurrentPath(const TString& strPath);
-	const TString& GetCurrentPath() const;
 
 	// time
 	void SetTimeElapsed(time_t timeElapsed);
-	time_t GetTimeElapsed();
 
 private:
+	TSubTaskStatsInfo(const TSubTaskStatsInfo&);
+	TSubTaskStatsInfo& operator=(const TSubTaskStatsInfo&);
+
 	// is running?
 	void MarkAsRunning();
 	void MarkAsNotRunning();
 
 	// time tracking
 	void EnableTimeTracking();
 	void DisableTimeTracking();
-	void UpdateTime(boost::upgrade_lock<boost::shared_mutex>& lock);
+	void UpdateTime(boost::upgrade_lock<boost::shared_mutex>& lock) const;
 
+	// calculates progress in percent
+	double CalculateProgressInPercent(boost::upgrade_lock<boost::shared_mutex>& lock) const;
+
 private:
 	bool m_bSubTaskIsRunning;
 
@@ -103,8 +104,8 @@
 
 	TString m_strCurrentPath;		// currently processed path
 
-	time_t m_timeElapsed;
-	time_t m_timeLast;
+	mutable time_t m_timeElapsed;
+	mutable time_t m_timeLast;
 
 #pragma warning(push)
 #pragma warning(disable: 4251)
Index: src/libchcore/TSubTaskStatsSnapshot.cpp
===================================================================
diff -u
--- src/libchcore/TSubTaskStatsSnapshot.cpp	(revision 0)
+++ src/libchcore/TSubTaskStatsSnapshot.cpp	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -0,0 +1,82 @@
+// ============================================================================
+//  Copyright (C) 2001-2012 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  TSubTaskStatsSnapshot.cpp
+/// @date  2012/2/26
+/// @brief Contains class responsible for holding sub task stats.
+// ============================================================================
+#include "stdafx.h"
+#include "TSubTaskStatsSnapshot.h"
+#include "DataBuffer.h"
+
+BEGIN_CHCORE_NAMESPACE
+
+///////////////////////////////////////////////////////////////////////////////////
+// class TSubTaskStats
+TSubTaskStatsSnapshot::TSubTaskStatsSnapshot() :
+	m_bSubTaskIsRunning(false),
+	m_ullTotalSize(0),
+	m_ullProcessedSize(0),
+	m_stTotalCount(0),
+	m_stProcessedCount(0),
+	m_iCurrentBufferIndex(TBufferSizes::eBuffer_Default),
+	m_strCurrentPath(0),
+	m_timeElapsed(0)
+{
+}
+
+TSubTaskStatsSnapshot::TSubTaskStatsSnapshot(const TSubTaskStatsSnapshot& rSrc) :
+	m_bSubTaskIsRunning(rSrc.m_bSubTaskIsRunning),
+	m_ullTotalSize(rSrc.m_ullTotalSize),
+	m_ullProcessedSize(rSrc.m_ullProcessedSize),
+	m_stTotalCount(rSrc.m_stTotalCount),
+	m_stProcessedCount(rSrc.m_stProcessedCount),
+	m_iCurrentBufferIndex(rSrc.m_iCurrentBufferIndex),
+	m_strCurrentPath(rSrc.m_strCurrentPath),
+	m_timeElapsed(rSrc.m_timeElapsed)
+{
+
+}
+
+TSubTaskStatsSnapshot& TSubTaskStatsSnapshot::operator=(const TSubTaskStatsSnapshot& rSrc)
+{
+	m_bSubTaskIsRunning = rSrc.m_bSubTaskIsRunning;
+	m_ullTotalSize = rSrc.m_ullTotalSize;
+	m_ullProcessedSize = rSrc.m_ullProcessedSize;
+	m_stTotalCount = rSrc.m_stTotalCount;
+	m_stProcessedCount = rSrc.m_stProcessedCount;
+	m_iCurrentBufferIndex = rSrc.m_iCurrentBufferIndex;
+	m_strCurrentPath = rSrc.m_strCurrentPath;
+	m_timeElapsed = rSrc.m_timeElapsed;
+
+	return *this;
+}
+
+void TSubTaskStatsSnapshot::Clear()
+{
+	m_bSubTaskIsRunning = false;
+	m_ullTotalSize = 0;
+	m_ullProcessedSize = 0;
+	m_stTotalCount = 0;
+	m_stProcessedCount = 0;
+	m_iCurrentBufferIndex = TBufferSizes::eBuffer_Default;
+	m_strCurrentPath = 0;
+	m_timeElapsed = 0;
+}
+
+END_CHCORE_NAMESPACE
Index: src/libchcore/TSubTaskStatsSnapshot.h
===================================================================
diff -u
--- src/libchcore/TSubTaskStatsSnapshot.h	(revision 0)
+++ src/libchcore/TSubTaskStatsSnapshot.h	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -0,0 +1,95 @@
+// ============================================================================
+//  Copyright (C) 2001-2012 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  TSubTaskStatsSnapshot.h
+/// @date  2012/2/26
+/// @brief Contains class responsible for holding sub task stats.
+// ============================================================================
+#ifndef __TSUBTASKSTATSSNAPSHOT_H__
+#define __TSUBTASKSTATSSNAPSHOT_H__
+
+#include "libchcore.h"
+#include "TString.h"
+
+BEGIN_CHCORE_NAMESPACE
+
+class LIBCHCORE_API TSubTaskStatsSnapshot
+{
+public:
+	TSubTaskStatsSnapshot();
+
+	TSubTaskStatsSnapshot(const TSubTaskStatsSnapshot& rSrc);
+	TSubTaskStatsSnapshot& operator=(const TSubTaskStatsSnapshot& rSrc);
+
+	void Clear();
+
+	// is running?
+	void SetRunning(bool bRunning) { m_bSubTaskIsRunning = bRunning; }
+	bool IsRunning() const { return m_bSubTaskIsRunning; }
+
+	// count stats
+	void SetProcessedCount(size_t stIndex) { m_stProcessedCount = stIndex; }
+	size_t GetProcessedCount() const { return m_stProcessedCount; }
+
+	void SetTotalCount(size_t stCount) { m_stTotalCount = stCount; }
+	size_t GetTotalCount() const { return m_stTotalCount; }
+
+	// size stats
+	void SetProcessedSize(unsigned long long ullProcessedSize) { m_ullProcessedSize = ullProcessedSize; }
+	unsigned long long GetProcessedSize() const { return m_ullProcessedSize; }
+
+	void SetTotalSize(unsigned long long ullTotalSize) { m_ullTotalSize = ullTotalSize; }
+	unsigned long long GetTotalSize() const { return m_ullTotalSize; }
+
+	// progress in percent
+	void SetProgressInPercent(double dPercent) { m_dProgressInPercent = dPercent; }
+	double GetProgressInPercent() const { return m_dProgressInPercent; }
+
+	// buffer index
+	void SetCurrentBufferIndex(int iCurrentIndex) { m_iCurrentBufferIndex = iCurrentIndex; }
+	int GetCurrentBufferIndex() const { return m_iCurrentBufferIndex; }
+
+	// current path
+	void SetCurrentPath(const TString& strPath) { m_strCurrentPath = strPath; }
+	const TString& GetCurrentPath() const { return m_strCurrentPath; }
+
+	// time
+	void SetTimeElapsed(time_t timeElapsed) { m_timeElapsed = timeElapsed; }
+	time_t GetTimeElapsed() { return m_timeElapsed; }
+
+private:
+	bool m_bSubTaskIsRunning;
+
+	unsigned long long m_ullTotalSize;
+	unsigned long long m_ullProcessedSize;
+
+	size_t m_stTotalCount;
+	size_t m_stProcessedCount;
+
+	double m_dProgressInPercent;
+
+	int m_iCurrentBufferIndex;
+
+	TString m_strCurrentPath;		// currently processed path
+
+	time_t m_timeElapsed;
+};
+
+END_CHCORE_NAMESPACE
+
+#endif
Index: src/libchcore/TTask.cpp
===================================================================
diff -u -rbebda797ec6983535a8940f8f9f15453fe6b1785 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TTask.cpp	(.../TTask.cpp)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
+++ src/libchcore/TTask.cpp	(.../TTask.cpp)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -38,6 +38,7 @@
 #include "DataBuffer.h"
 #include "TFileInfo.h"
 #include "TSubTaskArray.h"
+#include "TTaskStatsSnapshot.h"
 
 BEGIN_CHCORE_NAMESPACE
 
@@ -54,9 +55,9 @@
 	m_bRareStateModified(false),
 	m_bOftenStateModified(false),
 	m_stSessionUniqueID(stSessionUniqueID),
-	m_localStats(),
 	m_eCurrentState(eTaskState_None),
-	m_tSubTaskContext(m_tTaskDefinition, m_arrSourcePathsInfo, m_files, m_localStats, m_cfgTracker, m_log, piFeedbackHandler, m_workerThread, m_fsLocal)
+	m_tSubTaskContext(m_tTaskDefinition, m_arrSourcePathsInfo, m_files, m_cfgTracker, m_log, piFeedbackHandler, m_workerThread, m_fsLocal),
+	m_tSubTasksArray(m_tLocalStats)
 {
 	BOOST_ASSERT(piFeedbackHandler);
 }
@@ -77,14 +78,12 @@
 	m_files.Clear();
 }
 
-void TTask::OnRegisterTask(TTasksGlobalStats& rtGlobalStats)
+void TTask::OnRegisterTask()
 {
-	m_localStats.ConnectGlobalStats(rtGlobalStats);
 }
 
 void TTask::OnUnregisterTask()
 {
-	m_localStats.DisconnectGlobalStats();
 }
 
 void TTask::SetTaskState(ETaskCurrentState eTaskState)
@@ -122,11 +121,6 @@
 	bsSizes.SetOnlyDefault(GetTaskPropValue<eTO_UseOnlyDefaultBuffer>(m_tTaskDefinition.GetConfiguration()));
 }
 
-int TTask::GetCurrentBufferIndex()
-{
-	return m_localStats.GetCurrentBufferIndex();
-}
-
 // thread
 void TTask::SetPriority(int nPriority)
 {
@@ -183,7 +177,7 @@
 
 	time_t timeElapsed = 0;
 	Serialize(readSerializer, timeElapsed);
-	m_localStats.SetTimeElapsed(timeElapsed);
+//	m_localStats.SetTimeElapsed(timeElapsed);
 
 	m_arrSourcePathsInfo.Serialize(readSerializer, false);
 	m_files.Serialize(readSerializer, true);
@@ -234,8 +228,8 @@
 
 		Serialize(writeSerializer, iState);
 
-		time_t timeElapsed = m_localStats.GetTimeElapsed();
-		Serialize(writeSerializer, timeElapsed);
+//		time_t timeElapsed = m_localStats.GetTimeElapsed();
+//		Serialize(writeSerializer, timeElapsed);
 
 		m_arrSourcePathsInfo.Serialize(writeSerializer, false);
 
@@ -285,8 +279,7 @@
 
 	SetTaskState(eTaskState_None);
 
-	m_localStats.SetTimeElapsed(0);
-	m_tSubTasksArray.ResetProgress();
+	m_tSubTasksArray.ResetProgressAndStats();
 
 	BeginProcessing();
 }
@@ -315,35 +308,44 @@
 
 void TTask::GetMiniSnapshot(TASK_MINI_DISPLAY_DATA *pData)
 {
+	TTaskStatsSnapshot tStats;
+	m_tSubTasksArray.GetTaskStats(tStats);
+
+	pData->m_strPath = tStats.GetCurrentSubTaskStats().GetCurrentPath();
+	pData->m_dPercent = tStats.GetTaskProgressInPercent();
+
 	boost::shared_lock<boost::shared_mutex> lock(m_lock);
-	pData->m_strPath = m_localStats.GetCurrentPath();
 	pData->m_eTaskState = m_eCurrentState;
-	pData->m_nPercent = m_localStats.GetProgressInPercent();
 }
 
 void TTask::GetSnapshot(TASK_DISPLAY_DATA *pData)
 {
-	boost::unique_lock<boost::shared_mutex> lock(m_lock);
+	TTaskStatsSnapshot tStats;
+	m_tSubTasksArray.GetTaskStats(tStats);
 
-	pData->m_strFullFilePath = m_localStats.GetCurrentPath();
+	pData->m_strFullFilePath = tStats.GetCurrentSubTaskStats().GetCurrentPath();
 	pData->m_strFileName = chcore::PathFromString(pData->m_strFullFilePath).GetFileName().ToString();
+	pData->m_stIndex = tStats.GetCurrentSubTaskStats().GetProcessedCount();
+	pData->m_stSize = tStats.GetCurrentSubTaskStats().GetTotalCount();
+	pData->m_ullProcessedSize = tStats.GetCurrentSubTaskStats().GetProcessedSize();
+	pData->m_ullSizeAll = tStats.GetCurrentSubTaskStats().GetTotalSize();
+	pData->m_eSubOperationType = tStats.GetCurrentSubOperationType();
+	pData->m_iCurrentBufferIndex = tStats.GetCurrentSubTaskStats().GetCurrentBufferIndex();
+	pData->m_dPercent = tStats.GetTaskProgressInPercent();
+	pData->m_timeElapsed = tStats.GetTimeElapsed();
+
+	boost::shared_lock<boost::shared_mutex> lock(m_lock);
+
 	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 = m_localStats.GetCurrentIndex();
-	pData->m_stSize = m_localStats.GetTotalItems();
-	pData->m_ullProcessedSize = m_localStats.GetProcessedSize();
-	pData->m_ullSizeAll = m_localStats.GetTotalSize();
 	pData->m_strUniqueName = m_tTaskDefinition.GetTaskUniqueID();
 	pData->m_eOperationType = m_tTaskDefinition.GetOperationType();
-	pData->m_eSubOperationType = m_localStats.GetCurrentSubOperationType();
 
 	pData->m_bIgnoreDirectories = GetTaskPropValue<eTO_IgnoreDirectories>(m_tTaskDefinition.GetConfiguration());
 	pData->m_bCreateEmptyFiles = GetTaskPropValue<eTO_CreateEmptyFiles>(m_tTaskDefinition.GetConfiguration());
 
-	pData->m_iCurrentBufferIndex = m_localStats.GetCurrentBufferIndex();
-
 	switch(pData->m_iCurrentBufferIndex)
 	{
 	case TBufferSizes::eBuffer_Default:
@@ -366,12 +368,6 @@
 		//BOOST_ASSERT(false);		// assertions are dangerous here, because we're inside critical section
 		// (and there could be conflict with Get(Mini)Snapshot called OnTimer in several places.
 	}
-
-	// percents
-	pData->m_nPercent = m_localStats.GetProgressInPercent();
-
-	// time
-	pData->m_timeElapsed = m_localStats.GetTimeElapsed();
 }
 
 void TTask::DeleteProgress()
@@ -401,7 +397,6 @@
 
 	if(GetContinueFlagNL() || GetForceFlagNL())
 	{
-		m_localStats.MarkTaskAsRunning();
 		SetForceFlagNL(false);
 		SetContinueFlagNL(false);
 	}
@@ -523,6 +518,9 @@
 
 DWORD TTask::ThrdProc()
 {
+	// start tracking time for this thread
+	TTaskProcessingGuard tProcessingGuard(m_tLocalStats);
+
 	try
 	{
 		TSubTaskBase::ESubOperationResult eResult = TSubTaskBase::eSubResult_Continue;
@@ -546,17 +544,14 @@
 		// determine when to scan directories
 		bool bReadTasksSize = GetTaskPropValue<eTO_ScanDirectoriesBeforeBlocking>(m_tTaskDefinition.GetConfiguration());
 
-		// start tracking time for this thread
-		m_localStats.EnableTimeTracking();
-
 		// prepare context for subtasks
 		if(bReadTasksSize)
 			eResult = m_tSubTasksArray.Execute(true);
 		if(eResult == TSubTaskBase::eSubResult_Continue)
 		{
-			m_localStats.DisableTimeTracking();
+			tProcessingGuard.PauseTimeTracking();
 			eResult = CheckForWaitState();	// operation limiting
-			m_localStats.EnableTimeTracking();
+			tProcessingGuard.UnPauseTimeTracking();
 		}
 		if(eResult == TSubTaskBase::eSubResult_Continue)
 			eResult = m_tSubTasksArray.Execute(false);
@@ -565,8 +560,8 @@
 		if(eResult == TSubTaskBase::eSubResult_Continue)
 			SetTaskState(eTaskState_Finished);
 
-		// refresh time
-		m_localStats.DisableTimeTracking();
+		// stop tracking time because of a possible blocking feedback dialogs
+		tProcessingGuard.PauseTimeTracking();
 
 		// finishing processing
 		// change task status
@@ -613,40 +608,37 @@
 		SetContinueFlag(false);
 		SetForceFlag(false);
 
-		// mark this task as dead, so other can start
-		m_localStats.MarkTaskAsNotRunning();
-
 		m_tTaskDefinition.GetConfiguration().DisconnectFromNotifier(TTaskConfigTracker::NotificationProc);
 		m_tTaskDefinition.GetConfiguration().DisconnectFromNotifier(TTask::OnCfgOptionChanged);
 
 		// and the real end
 		OnEndOperation();
+
+		return 0;
 	}
 	catch(...)
 	{
-		m_tTaskDefinition.GetConfiguration().DisconnectFromNotifier(TTaskConfigTracker::NotificationProc);
-		m_tTaskDefinition.GetConfiguration().DisconnectFromNotifier(TTask::OnCfgOptionChanged);
+	}
 
-		// refresh time
-		m_localStats.DisableTimeTracking();
+	m_tTaskDefinition.GetConfiguration().DisconnectFromNotifier(TTaskConfigTracker::NotificationProc);
+	m_tTaskDefinition.GetConfiguration().DisconnectFromNotifier(TTask::OnCfgOptionChanged);
 
-		// log
-		m_log.loge(_T("Caught exception in ThrdProc"));
+	// log
+	m_log.loge(_T("Caught exception in ThrdProc"));
 
-		// let others know some error happened
-		m_piFeedbackHandler->RequestFeedback(IFeedbackHandler::eFT_OperationError, NULL);
-		SetTaskState(eTaskState_Error);
+	// stop tracking time because of a possible blocking feedback dialogs
+	tProcessingGuard.PauseTimeTracking();
 
-		m_localStats.MarkTaskAsNotRunning();
+	// let others know some error happened
+	m_piFeedbackHandler->RequestFeedback(IFeedbackHandler::eFT_OperationError, NULL);
+	SetTaskState(eTaskState_Error);
 
-		SetContinueFlag(false);
-		SetForceFlag(false);
+	SetContinueFlag(false);
+	SetForceFlag(false);
 
-		OnEndOperation();
-		return 1;
-	}
+	OnEndOperation();
 
-	return 0;
+	return 1;
 }
 
 void TTask::OnBeginOperation()
@@ -689,6 +681,11 @@
 	return GetRelatedPathNL(ePathType);
 }
 
+void TTask::GetTaskStats(TTaskStatsSnapshot& rSnapshot) const
+{
+	m_tSubTasksArray.GetTaskStats(rSnapshot);
+}
+
 TSmartPath TTask::GetRelatedPathNL(EPathType ePathType)
 {
 	BOOST_ASSERT(!m_strTaskDirectory.IsEmpty() || !m_strFilePath.IsEmpty());
Index: src/libchcore/TTask.h
===================================================================
diff -u -rbebda797ec6983535a8940f8f9f15453fe6b1785 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TTask.h	(.../TTask.h)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
+++ src/libchcore/TTask.h	(.../TTask.h)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -74,7 +74,7 @@
 
 	ull_t m_ullProcessedSize;
 	ull_t m_ullSizeAll;
-	int m_nPercent;
+	double m_dPercent;
 
 	time_t m_timeElapsed;
 
@@ -90,7 +90,7 @@
 
 	ETaskCurrentState m_eTaskState;
 
-	int m_nPercent;
+	double m_dPercent;
 };
 
 ///////////////////////////////////////////////////////////////////////////
@@ -118,7 +118,6 @@
 	// m_nBufferSize
 	void SetBufferSizes(const TBufferSizes& bsSizes);
 	void GetBufferSizes(TBufferSizes& bsSizes);
-	int GetCurrentBufferIndex();
 
 	// thread
 	void SetPriority(int nPriority);
@@ -150,14 +149,17 @@
 
 	TSmartPath GetRelatedPath(EPathType ePathType);
 
+	// Stats handling
+	void GetTaskStats(TTaskStatsSnapshot& rSnapshot) const;
+
 protected:
 	TTask(IFeedbackHandler* piFeedbackHandler, size_t stSessionUniqueID);
 
 	void SetTaskDefinition(const TTaskDefinition& rTaskDefinition);
 
 	// methods are called when task is being added or removed from the global task array
 	/// Method is called when this task is being added to a TTaskManager object
-	void OnRegisterTask(TTasksGlobalStats& rtGlobalStats);
+	void OnRegisterTask();
 	/// Method is called when task is being removed from the TTaskManager object
 	void OnUnregisterTask();
 
@@ -166,8 +168,6 @@
 	/// Method is called when processing is being ended
 	void OnEndOperation();
 
-	// Processing operations
-
 	/// Thread function that delegates call to the TTask::ThrdProc
 	static DWORD WINAPI DelegateThreadProc(LPVOID pParam);
 
@@ -217,9 +217,6 @@
 	// changing fast
 	volatile ETaskCurrentState m_eCurrentState;     // current state of processing this task represents
 
-	// task control variables (per-session state)
-	TTaskLocalStats m_localStats;       // local statistics
-
 	// task settings
 	TFileFiltersArray m_afFilters;          // filtering settings for files (will be filtered according to the rules inside when searching for files)
 
@@ -246,6 +243,8 @@
 	/// Mutex for locking concurrent access to members of this class
 #pragma warning(push)
 #pragma warning(disable: 4251)
+	TTaskLocalStatsInfo m_tLocalStats;       // local statistics
+
 	mutable boost::shared_mutex m_lock;
 #pragma warning(pop)
 
Fisheye: Tag 12a1725bfd04b0f55fd0fda302975fdcd4174943 refers to a dead (removed) revision in file `src/libchcore/TTaskGlobalStats.cpp'.
Fisheye: No comparison available.  Pass `N' to diff?
Fisheye: Tag 12a1725bfd04b0f55fd0fda302975fdcd4174943 refers to a dead (removed) revision in file `src/libchcore/TTaskGlobalStats.h'.
Fisheye: No comparison available.  Pass `N' to diff?
Index: src/libchcore/TTaskLocalStats.cpp
===================================================================
diff -u -rbebda797ec6983535a8940f8f9f15453fe6b1785 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TTaskLocalStats.cpp	(.../TTaskLocalStats.cpp)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
+++ src/libchcore/TTaskLocalStats.cpp	(.../TTaskLocalStats.cpp)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -16,239 +16,142 @@
 //  Free Software Foundation, Inc.,
 //  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // ============================================================================
-/// @file  TTaskLocalStats.cpp
+/// @file  TTaskLocalStatsInfo.cpp
 /// @date  2011/03/28
 /// @brief Contains implementation of classes responsible for maintaining local task stats.
 // ============================================================================
 #include "stdafx.h"
 #include "TTaskLocalStats.h"
-#include "TTaskGlobalStats.h"
+#include "TSubTaskStatsInfo.h"
 #include <boost\numeric\conversion\cast.hpp>
+#include "DataBuffer.h"
+#include "TTaskStatsSnapshot.h"
 
 BEGIN_CHCORE_NAMESPACE
 
 ////////////////////////////////////////////////////////////////////////////////
-// TTasksGlobalStats members
-TTaskLocalStats::TTaskLocalStats() :
-	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)
-{
-}
+// class TTaskProcessingGuard
 
-TTaskLocalStats::~TTaskLocalStats()
+TTaskProcessingGuard::TTaskProcessingGuard(TTaskLocalStatsInfo& rLocalStats) :
+	m_rLocalStats(rLocalStats)
 {
-	DisconnectGlobalStats();
+	rLocalStats.EnableTimeTracking();
+	rLocalStats.MarkTaskAsRunning();
 }
 
-void TTaskLocalStats::ConnectGlobalStats(TTasksGlobalStats& rtGlobalStats)
+TTaskProcessingGuard::~TTaskProcessingGuard()
 {
-	DisconnectGlobalStats();
-
-	boost::unique_lock<boost::shared_mutex> lock(m_lock);
-
-	m_prtGlobalStats = &rtGlobalStats;
-	m_prtGlobalStats->IncreaseGlobalProgressData(m_ullProcessedSize, m_ullTotalSize);
-	if(m_bTaskIsRunning)
-		m_prtGlobalStats->IncreaseRunningTasks();
+	if(!m_bRunningStatePaused)
+		m_rLocalStats.MarkTaskAsNotRunning();
+	if(!m_bTimeTrackingPaused)
+		m_rLocalStats.DisableTimeTracking();
 }
 
-void TTaskLocalStats::DisconnectGlobalStats()
+void TTaskProcessingGuard::PauseTimeTracking()
 {
-	boost::unique_lock<boost::shared_mutex> lock(m_lock);
-
-	if(m_prtGlobalStats)
+	if(!m_bTimeTrackingPaused)
 	{
-		m_prtGlobalStats->DecreaseGlobalProgressData(m_ullProcessedSize, m_ullTotalSize);
-		if(m_bTaskIsRunning)
-			m_prtGlobalStats->DecreaseRunningTasks();
-		m_prtGlobalStats = NULL;
+		m_rLocalStats.DisableTimeTracking();
+		m_bTimeTrackingPaused = true;
 	}
 }
 
-void TTaskLocalStats::IncreaseProcessedSize(unsigned long long ullAdd)
+void TTaskProcessingGuard::UnPauseTimeTracking()
 {
-	boost::unique_lock<boost::shared_mutex> lock(m_lock);
-
-	if(m_prtGlobalStats)
-		m_prtGlobalStats->IncreaseGlobalProcessedSize(ullAdd);
-
-	m_ullProcessedSize += ullAdd;
+	if(m_bTimeTrackingPaused)
+	{
+		m_rLocalStats.EnableTimeTracking();
+		m_bTimeTrackingPaused = false;
+	}
 }
 
-void TTaskLocalStats::DecreaseProcessedSize(unsigned long long ullSub)
+void TTaskProcessingGuard::PauseRunningState()
 {
-	boost::unique_lock<boost::shared_mutex> lock(m_lock);
-	if(m_prtGlobalStats)
-		m_prtGlobalStats->DecreaseGlobalProcessedSize(ullSub);
-
-	m_ullProcessedSize -= ullSub;
-}
-
-void TTaskLocalStats::SetProcessedSize(unsigned long long ullSet)
-{
-	boost::unique_lock<boost::shared_mutex> lock(m_lock);
-
-	if(m_prtGlobalStats)
+	if(!m_bRunningStatePaused)
 	{
-		if(ullSet < m_ullProcessedSize)
-			m_prtGlobalStats->DecreaseGlobalProcessedSize(m_ullProcessedSize - ullSet);
-		else
-			m_prtGlobalStats->IncreaseGlobalProcessedSize(ullSet - m_ullProcessedSize);
+		m_rLocalStats.MarkTaskAsNotRunning();
+		m_bRunningStatePaused = true;
 	}
-
-	m_ullProcessedSize = ullSet;
 }
 
-unsigned long long TTaskLocalStats::GetProcessedSize() const
+void TTaskProcessingGuard::UnPauseRunningState()
 {
-	boost::shared_lock<boost::shared_mutex> lock(m_lock);
-	return m_ullProcessedSize;
-}
-
-unsigned long long TTaskLocalStats::GetUnProcessedSize() const
-{
-	boost::shared_lock<boost::shared_mutex> lock(m_lock);
-	return m_ullTotalSize - m_ullProcessedSize;
-}
-
-void TTaskLocalStats::IncreaseTotalSize(unsigned long long ullAdd)
-{
-	boost::unique_lock<boost::shared_mutex> lock(m_lock);
-
-	if(m_prtGlobalStats)
-		m_prtGlobalStats->IncreaseGlobalTotalSize(ullAdd);
-	m_ullTotalSize += ullAdd;
-}
-
-void TTaskLocalStats::DecreaseTotalSize(unsigned long long ullSub)
-{
-	boost::unique_lock<boost::shared_mutex> lock(m_lock);
-
-	if(m_prtGlobalStats)
-		m_prtGlobalStats->DecreaseGlobalTotalSize(ullSub);
-
-	m_ullTotalSize -= ullSub;
-}
-
-void TTaskLocalStats::SetTotalSize(unsigned long long ullSet)
-{
-	boost::unique_lock<boost::shared_mutex> lock(m_lock);
-
-	if(m_prtGlobalStats)
+	if(m_bRunningStatePaused)
 	{
-		if(ullSet < m_ullTotalSize)
-			m_prtGlobalStats->DecreaseGlobalTotalSize(m_ullTotalSize - ullSet);
-		else
-			m_prtGlobalStats->IncreaseGlobalTotalSize(ullSet - m_ullTotalSize);
+		m_rLocalStats.MarkTaskAsRunning();
+		m_bRunningStatePaused = false;
 	}
-
-	m_ullTotalSize = ullSet;
 }
 
-unsigned long long TTaskLocalStats::GetTotalSize() const
+////////////////////////////////////////////////////////////////////////////////
+// TTasksGlobalStats members
+TTaskLocalStatsInfo::TTaskLocalStatsInfo() :
+	m_bTaskIsRunning(false),
+	m_timeElapsed(0),
+	m_timeLast(-1),
+	m_eCurrentSubOperationType(eSubOperation_None)
 {
-	boost::shared_lock<boost::shared_mutex> lock(m_lock);
-	return m_ullTotalSize;
 }
 
-size_t TTaskLocalStats::GetCurrentIndex() const
+TTaskLocalStatsInfo::~TTaskLocalStatsInfo()
 {
-	boost::shared_lock<boost::shared_mutex> lock(m_lock);
-	return m_stCurrentIndex;
 }
 
-void TTaskLocalStats::SetCurrentIndex(size_t stIndex)
+void TTaskLocalStatsInfo::Clear()
 {
-	boost::unique_lock<boost::shared_mutex> lock(m_lock);
-	m_stCurrentIndex = stIndex;
-}
+	m_bTaskIsRunning = false;
+	m_timeElapsed = 0;
+	m_timeLast = -1;
 
-size_t TTaskLocalStats::GetTotalItems()
-{
-	boost::shared_lock<boost::shared_mutex> lock(m_lock);
-	return m_stTotalItems;
+	m_eCurrentSubOperationType = eSubOperation_None;
 }
 
-void TTaskLocalStats::SetTotalItems(size_t stCount)
+void TTaskLocalStatsInfo::GetSnapshot(TTaskStatsSnapshot& rSnapshot) const
 {
-	boost::unique_lock<boost::shared_mutex> lock(m_lock);
-	m_stTotalItems = stCount;
-}
+	rSnapshot.Clear();
 
-int TTaskLocalStats::GetProgressInPercent() const
-{
-	boost::shared_lock<boost::shared_mutex> lock(m_lock);
-
-	unsigned long long ullPercent = 0;
-
-	if(m_ullTotalSize != 0)
-		ullPercent = m_ullProcessedSize * 100 / m_ullTotalSize;
-
-	return boost::numeric_cast<int>(ullPercent);
+	boost::upgrade_lock<boost::shared_mutex> lock(m_lock);
+	UpdateTime(lock);
+	rSnapshot.SetIsTaskIsRunning(m_bTaskIsRunning);
+	rSnapshot.SetCurrentSubOperationType(m_eCurrentSubOperationType);
+	rSnapshot.SetTimeElapsed(m_timeElapsed);
 }
 
-void TTaskLocalStats::SetCurrentPath(const TString& strPath)
+void TTaskLocalStatsInfo::MarkTaskAsRunning()
 {
 	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);
 	if(!m_bTaskIsRunning)
-	{
-		if(m_prtGlobalStats)
-			m_prtGlobalStats->IncreaseRunningTasks();
 		m_bTaskIsRunning = true;
-	}
 }
 
-void TTaskLocalStats::MarkTaskAsNotRunning()
+void TTaskLocalStatsInfo::MarkTaskAsNotRunning()
 {
 	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 	if(m_bTaskIsRunning)
-	{
-		if(m_prtGlobalStats)
-			m_prtGlobalStats->DecreaseRunningTasks();
 		m_bTaskIsRunning = false;
-	}
 }
 
-bool TTaskLocalStats::IsRunning() const
+bool TTaskLocalStatsInfo::IsRunning() const
 {
 	boost::shared_lock<boost::shared_mutex> lock(m_lock);
 	return m_bTaskIsRunning;
 }
 
-void TTaskLocalStats::SetTimeElapsed(time_t timeElapsed)
+void TTaskLocalStatsInfo::SetTimeElapsed(time_t timeElapsed)
 {
 	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 	m_timeElapsed = timeElapsed;
 }
 
-time_t TTaskLocalStats::GetTimeElapsed()
+time_t TTaskLocalStatsInfo::GetTimeElapsed()
 {
-	UpdateTime();
+	boost::upgrade_lock<boost::shared_mutex> lock(m_lock);
+	UpdateTime(lock);
 
-	boost::shared_lock<boost::shared_mutex> lock(m_lock);
 	return m_timeElapsed;
 }
 
-void TTaskLocalStats::EnableTimeTracking()
+void TTaskLocalStatsInfo::EnableTimeTracking()
 {
 	boost::upgrade_lock<boost::shared_mutex> lock(m_lock);
 	if(m_timeLast == -1)
@@ -258,21 +161,19 @@
 	}
 }
 
-void TTaskLocalStats::DisableTimeTracking()
+void TTaskLocalStatsInfo::DisableTimeTracking()
 {
-	UpdateTime();
-
 	boost::upgrade_lock<boost::shared_mutex> lock(m_lock);
+	UpdateTime(lock);
 	if(m_timeLast != -1)
 	{
 		boost::upgrade_to_unique_lock<boost::shared_mutex> lock_upgraded(lock);
 		m_timeLast = -1;
 	}
 }
 
-void TTaskLocalStats::UpdateTime()
+void TTaskLocalStatsInfo::UpdateTime(boost::upgrade_lock<boost::shared_mutex>& lock) const
 {
-	boost::upgrade_lock<boost::shared_mutex> lock(m_lock);
 	if(m_timeLast != -1)
 	{
 		time_t timeCurrent = time(NULL);
@@ -283,27 +184,13 @@
 	}
 }
 
-void TTaskLocalStats::SetCurrentBufferIndex(int iCurrentIndex)
+ESubOperationType TTaskLocalStatsInfo::GetCurrentSubOperationType() const
 {
-	boost::unique_lock<boost::shared_mutex> lock(m_lock);
-	m_iCurrentBufferIndex = iCurrentIndex;
-}
-
-int TTaskLocalStats::GetCurrentBufferIndex() const
-{
-	// locking possibly not needed, not entirely sure now
 	boost::shared_lock<boost::shared_mutex> lock(m_lock);
-	int iResult = m_iCurrentBufferIndex;
-	return iResult;
-}
-
-ESubOperationType TTaskLocalStats::GetCurrentSubOperationType() const
-{
-	boost::shared_lock<boost::shared_mutex> lock(m_lock);
 	return m_eCurrentSubOperationType;
 }
 
-void TTaskLocalStats::SetCurrentSubOperationType(ESubOperationType eSubOperationType)
+void TTaskLocalStatsInfo::SetCurrentSubOperationType(ESubOperationType eSubOperationType)
 {
 	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 	m_eCurrentSubOperationType = eSubOperationType;
Index: src/libchcore/TTaskLocalStats.h
===================================================================
diff -u -rbebda797ec6983535a8940f8f9f15453fe6b1785 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TTaskLocalStats.h	(.../TTaskLocalStats.h)	(revision bebda797ec6983535a8940f8f9f15453fe6b1785)
+++ src/libchcore/TTaskLocalStats.h	(.../TTaskLocalStats.h)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -16,7 +16,7 @@
 //  Free Software Foundation, Inc.,
 //  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // ============================================================================
-/// @file  TTaskLocalStats.h
+/// @file  TTaskLocalStatsInfo.h
 /// @date  2011/03/28
 /// @brief Contains classes responsible for maintaining local task stats.
 // ============================================================================
@@ -25,84 +25,87 @@
 
 #include "libchcore.h"
 #include "ESubTaskTypes.h"
-#include "TString.h"
+#include "TSubTaskStatsInfo.h"
 
 BEGIN_CHCORE_NAMESPACE
 
-class TTasksGlobalStats;
+class TTaskLocalStatsInfo;
+class TTaskStatsSnapshot;
 
-class LIBCHCORE_API TTaskLocalStats
+class TTaskProcessingGuard
 {
 public:
-	TTaskLocalStats();
-	~TTaskLocalStats();
+	TTaskProcessingGuard(TTaskLocalStatsInfo& rLocalStats);
+	~TTaskProcessingGuard();
 
-	void ConnectGlobalStats(TTasksGlobalStats& rtGlobalStats);
-	void DisconnectGlobalStats();
+	void PauseTimeTracking();
+	void UnPauseTimeTracking();
 
-	void IncreaseProcessedSize(unsigned long long ullAdd);
-	void DecreaseProcessedSize(unsigned long long ullSub);
-	void SetProcessedSize(unsigned long long ullSet);
-	unsigned long long GetProcessedSize() const;
-	unsigned long long GetUnProcessedSize() const;
+	void PauseRunningState();
+	void UnPauseRunningState();
 
-	void IncreaseTotalSize(unsigned long long ullAdd);
-	void DecreaseTotalSize(unsigned long long ullSub);
-	void SetTotalSize(unsigned long long ullSet);
-	unsigned long long GetTotalSize() const;
+private:
+	TTaskProcessingGuard(const TTaskProcessingGuard& rLocalStats);
+	TTaskProcessingGuard& operator=(const TTaskProcessingGuard& rLocalStats);
 
-	size_t GetCurrentIndex() const;
-	void SetCurrentIndex(size_t stIndex);
+private:
+	TTaskLocalStatsInfo& m_rLocalStats;
+	bool m_bTimeTrackingPaused;
+	bool m_bRunningStatePaused;
+};
 
-	size_t GetTotalItems();
-	void SetTotalItems(size_t stCount);
+class TTaskLocalStatsInfo
+{
+public:
+	TTaskLocalStatsInfo();
+	~TTaskLocalStatsInfo();
 
-	int GetProgressInPercent() const;
+	void Clear();
+	void GetSnapshot(TTaskStatsSnapshot& rSnapshot) const;
 
-	void SetCurrentPath(const TString& strPath);
-	const TString& GetCurrentPath() const;
+	void SetCurrentSubOperationType(ESubOperationType eSubOperationType);
 
+protected:
+	// running/not running state
 	void MarkTaskAsRunning();
 	void MarkTaskAsNotRunning();
+
 	bool IsRunning() const;
 
-	void SetTimeElapsed(time_t timeElapsed);
-	time_t GetTimeElapsed();
-
+	// time tracking
 	void EnableTimeTracking();
 	void DisableTimeTracking();
-	void UpdateTime();
 
-	void SetCurrentBufferIndex(int iCurrentIndex);
-	int GetCurrentBufferIndex() const;
+#pragma warning(push)
+#pragma warning(disable: 4251)
+	void UpdateTime(boost::upgrade_lock<boost::shared_mutex>& lock) const;
+#pragma warning(pop)
 
+	void SetTimeElapsed(time_t timeElapsed);
+	time_t GetTimeElapsed();
+
+	// current subtask
 	ESubOperationType GetCurrentSubOperationType() const;
-	void SetCurrentSubOperationType(ESubOperationType eSubOperationType);
 
 private:
-	volatile unsigned long long m_ullProcessedSize;
-	volatile unsigned long long m_ullTotalSize;
+	TTaskLocalStatsInfo(const TTaskLocalStatsInfo&);
+	TTaskLocalStatsInfo& operator=(const TTaskLocalStatsInfo&);
 
-	volatile size_t m_stCurrentIndex;
-	volatile size_t m_stTotalItems;
-
+private:
 	volatile bool m_bTaskIsRunning;
 
 	// time
-	volatile time_t m_timeElapsed;
-	volatile time_t m_timeLast;
+	mutable time_t m_timeElapsed;
+	mutable time_t m_timeLast;
 
-	volatile int m_iCurrentBufferIndex;
-
 	volatile ESubOperationType m_eCurrentSubOperationType;
 
-	TString m_strCurrentPath;
-
 #pragma warning(push)
 #pragma warning(disable: 4251)
 	mutable boost::shared_mutex m_lock;
 #pragma warning(pop)
-	TTasksGlobalStats* m_prtGlobalStats;
+
+	friend class TTaskProcessingGuard;
 };
 
 END_CHCORE_NAMESPACE
Index: src/libchcore/TTaskManager.cpp
===================================================================
diff -u -r1d8d51e0dd4d8ebcf0bd457d01fab984585220c0 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TTaskManager.cpp	(.../TTaskManager.cpp)	(revision 1d8d51e0dd4d8ebcf0bd457d01fab984585220c0)
+++ src/libchcore/TTaskManager.cpp	(.../TTaskManager.cpp)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -23,6 +23,9 @@
 #include <boost/smart_ptr/shared_array.hpp>
 #include "../libicpf/exception.h"
 #include "TLogger.h"
+#include <boost/numeric/conversion/cast.hpp>
+#include "TTaskStatsSnapshot.h"
+#include "TTaskManagerStatsSnapshot.h"
 
 BEGIN_CHCORE_NAMESPACE
 
@@ -136,7 +139,7 @@
 
 	m_vTasks.push_back(spNewTask);
 
-	spNewTask->OnRegisterTask(m_globalStats);
+	spNewTask->OnRegisterTask();
 
 	return m_vTasks.size() - 1;
 }
@@ -238,17 +241,23 @@
 
 void TTaskManager::ResumeWaitingTasks(size_t stMaxRunningTasks)
 {
-	boost::unique_lock<boost::shared_mutex> lock(m_lock);
+	size_t stRunningCount = GetCountOfRunningTasks();
 
-	if(stMaxRunningTasks == 0 || m_globalStats.GetRunningTasksCount() < stMaxRunningTasks)
+	boost::shared_lock<boost::shared_mutex> lock(m_lock);
+
+	size_t stTasksToRun = stMaxRunningTasks == 0 ? std::numeric_limits<size_t>::max() : stMaxRunningTasks;
+	stTasksToRun -= stRunningCount;
+
+	if(stTasksToRun > 0)
 	{
 		BOOST_FOREACH(TTaskPtr& spTask, m_vTasks)
 		{
 			// turn on some thread - find something with wait state
-			if(spTask->GetTaskState() == eTaskState_Waiting && (stMaxRunningTasks == 0 || m_globalStats.GetRunningTasksCount() < stMaxRunningTasks))
+			if(spTask->GetTaskState() == eTaskState_Waiting)
 			{
-				spTask->m_localStats.MarkTaskAsRunning();
 				spTask->SetContinueFlagNL(true);
+				if(--stTasksToRun == 0)
+					break;
 			}
 		}
 	}
@@ -379,26 +388,11 @@
 	}
 }
 
-ull_t TTaskManager::GetPosition()
-{
-	return m_globalStats.GetGlobalProcessedSize();
-}
-
-ull_t TTaskManager::GetRange()
-{
-	return m_globalStats.GetGlobalTotalSize();
-}
-
-int TTaskManager::GetPercent()
-{
-	return m_globalStats.GetProgressPercents();
-}
-
 bool TTaskManager::AreAllFinished()
 {
 	bool bFlag=true;
 
-	if(m_globalStats.GetRunningTasksCount() != 0)
+	if(GetCountOfRunningTasks() != 0)
 		bFlag = false;
 	else
 	{
@@ -422,6 +416,62 @@
 	m_pathTasksDir = pathDir;
 }
 
+void TTaskManager::GetStatsSnapshot(TTaskManagerStatsSnapshot& rSnapshot) const
+{
+	boost::shared_lock<boost::shared_mutex> lock(m_lock);
+
+	TTaskStatsSnapshot tTaskStats;
+
+	size_t stProcessedCount = 0;
+	size_t stTotalCount = 0;
+	unsigned long long ullProcessedSize = 0;
+	unsigned long long ullTotalSize = 0;
+	size_t stRunningTasks = 0;
+
+	BOOST_FOREACH(const TTaskPtr& spTask, m_vTasks)
+	{
+		spTask->GetTaskStats(tTaskStats);
+		ETaskCurrentState eState = spTask->GetTaskState();
+
+		stProcessedCount += tTaskStats.GetCurrentSubTaskStats().GetProcessedCount();
+		stTotalCount += tTaskStats.GetCurrentSubTaskStats().GetTotalCount();
+		ullProcessedSize += tTaskStats.GetCurrentSubTaskStats().GetProcessedSize();
+		ullTotalSize += tTaskStats.GetCurrentSubTaskStats().GetTotalSize();
+
+		if(tTaskStats.IsTaskRunning() && eState == eTaskState_Processing)
+			++stRunningTasks;
+	}
+
+	rSnapshot.SetProcessedCount(stProcessedCount);
+	rSnapshot.SetTotalCount(stTotalCount);
+	rSnapshot.SetProcessedSize(ullProcessedSize);
+	rSnapshot.SetTotalSize(ullTotalSize);
+	rSnapshot.SetRunningTasks(stRunningTasks);
+	if(ullTotalSize)
+		rSnapshot.SetGlobalProgressInPercent(boost::numeric_cast<double>(ullProcessedSize) / boost::numeric_cast<double>(ullTotalSize) * 100.0);
+	else
+		rSnapshot.SetGlobalProgressInPercent(0.0);
+}
+
+size_t TTaskManager::GetCountOfRunningTasks() const
+{
+	boost::shared_lock<boost::shared_mutex> lock(m_lock);
+
+	TTaskStatsSnapshot tTaskStats;
+
+	size_t stRunningTasks = 0;
+
+	BOOST_FOREACH(const TTaskPtr& spTask, m_vTasks)
+	{
+		ETaskCurrentState eState = spTask->GetTaskState();
+		spTask->GetTaskStats(tTaskStats);
+		if(tTaskStats.IsTaskRunning() && eState == eTaskState_Processing)
+			++stRunningTasks;
+	}
+
+	return stRunningTasks;
+}
+
 void TTaskManager::StopAllTasksNL()
 {
 	// kill all unfinished tasks - send kill request
Index: src/libchcore/TTaskManager.h
===================================================================
diff -u -r1d8d51e0dd4d8ebcf0bd457d01fab984585220c0 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/TTaskManager.h	(.../TTaskManager.h)	(revision 1d8d51e0dd4d8ebcf0bd457d01fab984585220c0)
+++ src/libchcore/TTaskManager.h	(.../TTaskManager.h)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -21,13 +21,13 @@
 
 #include "libchcore.h"
 #include "FeedbackHandlerBase.h"
-#include "TTaskGlobalStats.h"
 #include "TPath.h"
 
 BEGIN_CHCORE_NAMESPACE
 
 class TTaskDefinition;
 class TTask;
+class TTaskManagerStatsSnapshot;
 typedef boost::shared_ptr<TTask> TTaskPtr;
 
 // special value representing no task
@@ -72,14 +72,13 @@
 	bool TasksRetryProcessing();
 	void TasksCancelProcessing();
 
-	ull_t GetPosition();
-	ull_t GetRange();
-	int GetPercent();
-
 	bool AreAllFinished();
 
 	void SetTasksDir(const TSmartPath& pathDir);
 
+	void GetStatsSnapshot(TTaskManagerStatsSnapshot& rSnapshot) const;
+	size_t GetCountOfRunningTasks() const;
+
 protected:
 	void StopAllTasksNL();
 
@@ -95,8 +94,6 @@
 	std::vector<TTaskPtr> m_vTasks;		// vector with tasks objects
 #pragma warning(pop)
 
-	TTasksGlobalStats m_globalStats;	// global stats for all tasks
-
 	size_t m_stNextSessionUniqueID;		// global counter for providing unique ids for tasks per session (launch of the program)
 
 protected:
Index: src/libchcore/TTaskManagerStatsSnapshot.cpp
===================================================================
diff -u
--- src/libchcore/TTaskManagerStatsSnapshot.cpp	(revision 0)
+++ src/libchcore/TTaskManagerStatsSnapshot.cpp	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -0,0 +1,74 @@
+// ============================================================================
+//  Copyright (C) 2001-2012 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  TTaskManagerStatsSnapshot.cpp
+/// @date  2012/2/26
+/// @brief Contains class responsible for holding task manager stats.
+// ============================================================================
+#include "stdafx.h"
+#include "TTaskManagerStatsSnapshot.h"
+
+BEGIN_CHCORE_NAMESPACE
+
+
+////////////////////////////////////////////////////////////////////////////////
+// class TTaskManagerStatsSnapshot
+
+TTaskManagerStatsSnapshot::TTaskManagerStatsSnapshot() :
+	m_stProcessedCount(0),
+	m_stTotalCount(0),
+	m_ullProcessedSize(0),
+	m_ullTotalSize(0),
+	m_dGlobalProgressInPercent(0.0),
+	m_stRunningTasks(0)
+{
+}
+
+TTaskManagerStatsSnapshot::TTaskManagerStatsSnapshot(const TTaskManagerStatsSnapshot& rSrc) :
+	m_stProcessedCount(rSrc.m_stProcessedCount),
+	m_stTotalCount(rSrc.m_stTotalCount),
+	m_ullProcessedSize(rSrc.m_ullProcessedSize),
+	m_ullTotalSize(rSrc.m_ullTotalSize),
+	m_dGlobalProgressInPercent(rSrc.m_dGlobalProgressInPercent),
+	m_stRunningTasks(rSrc.m_stRunningTasks)
+{
+}
+
+TTaskManagerStatsSnapshot& TTaskManagerStatsSnapshot::operator=(const TTaskManagerStatsSnapshot& rSrc)
+{
+	m_stProcessedCount = rSrc.m_stProcessedCount;
+	m_stTotalCount = rSrc.m_stTotalCount;
+	m_ullProcessedSize = rSrc.m_ullProcessedSize;
+	m_ullTotalSize = rSrc.m_ullTotalSize;
+	m_dGlobalProgressInPercent = rSrc.m_dGlobalProgressInPercent;
+	m_stRunningTasks = rSrc.m_stRunningTasks;
+
+	return *this;
+}
+
+void TTaskManagerStatsSnapshot::Clear()
+{
+	m_stProcessedCount = 0;
+	m_stTotalCount = 0;
+	m_ullProcessedSize = 0;
+	m_ullTotalSize = 0;
+	m_dGlobalProgressInPercent = 0.0;
+	m_stRunningTasks = 0;
+}
+
+END_CHCORE_NAMESPACE
Index: src/libchcore/TTaskManagerStatsSnapshot.h
===================================================================
diff -u
--- src/libchcore/TTaskManagerStatsSnapshot.h	(revision 0)
+++ src/libchcore/TTaskManagerStatsSnapshot.h	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -0,0 +1,72 @@
+// ============================================================================
+//  Copyright (C) 2001-2012 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  TTaskManagerStatsSnapshot.h
+/// @date  2012/2/26
+/// @brief Contains class responsible for holding task manager stats.
+// ============================================================================
+#ifndef __TTASKMANAGERSTATSSNAPSHOT_H__
+#define __TTASKMANAGERSTATSSNAPSHOT_H__
+
+#include "libchcore.h"
+
+BEGIN_CHCORE_NAMESPACE
+
+class LIBCHCORE_API TTaskManagerStatsSnapshot
+{
+public:
+	TTaskManagerStatsSnapshot();
+	TTaskManagerStatsSnapshot(const TTaskManagerStatsSnapshot& rSrc);
+
+	TTaskManagerStatsSnapshot& operator=(const TTaskManagerStatsSnapshot& rSrc);
+
+	void Clear();
+
+	size_t GetProcessedCount() const { return m_stProcessedCount; }
+	void SetProcessedCount(size_t stCount) { m_stProcessedCount = stCount; }
+
+	size_t GetTotalCount() const { return m_stTotalCount; }
+	void SetTotalCount(size_t stTotalCount) { m_stTotalCount = stTotalCount; }
+
+	unsigned long long GetProcessedSize() const { return m_ullProcessedSize; }
+	void SetProcessedSize(unsigned long long ullProcessedSize) { m_ullProcessedSize = ullProcessedSize; }
+
+	unsigned long long GetTotalSize() const { return m_ullTotalSize; }
+	void SetTotalSize(unsigned long long ullTotalSize) { m_ullTotalSize = ullTotalSize; }
+
+	double GetGlobalProgressInPercent() const { return m_dGlobalProgressInPercent; }
+	void SetGlobalProgressInPercent(double dPercent) { m_dGlobalProgressInPercent = dPercent; }
+
+	size_t GetRunningTasks() const { return m_stRunningTasks; }
+	void SetRunningTasks(size_t stRunningTasks) { m_stRunningTasks = stRunningTasks; }
+
+private:
+	size_t m_stProcessedCount;
+	size_t m_stTotalCount;
+
+	unsigned long long m_ullProcessedSize;
+	unsigned long long m_ullTotalSize;
+
+	double m_dGlobalProgressInPercent;
+
+	size_t m_stRunningTasks;
+};
+
+END_CHCORE_NAMESPACE
+
+#endif
Index: src/libchcore/TTaskStatsSnapshot.cpp
===================================================================
diff -u
--- src/libchcore/TTaskStatsSnapshot.cpp	(revision 0)
+++ src/libchcore/TTaskStatsSnapshot.cpp	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -0,0 +1,72 @@
+// ============================================================================
+//  Copyright (C) 2001-2012 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  TTaskStatsSnapshot.cpp
+/// @date  2012/02/26
+/// @brief Contains class responsible for holding task stats.
+// ============================================================================
+#include "stdafx.h"
+#include "TTaskStatsSnapshot.h"
+
+BEGIN_CHCORE_NAMESPACE
+
+////////////////////////////////////////////////////////////////////////////////
+// TTaskStatsSnapshot members
+
+TTaskStatsSnapshot::TTaskStatsSnapshot() :
+	m_tCurrentSubTaskStats(),
+	m_bTaskIsRunning(false),
+	m_eCurrentSubOperationType(eSubOperation_None),
+	m_timeElapsed(0),
+	m_dTaskProgress(0.0)
+{
+}
+
+TTaskStatsSnapshot::TTaskStatsSnapshot(const TTaskStatsSnapshot& rSrc) :
+	m_tCurrentSubTaskStats(rSrc.m_tCurrentSubTaskStats),
+	m_bTaskIsRunning(rSrc.m_bTaskIsRunning),
+	m_eCurrentSubOperationType(rSrc.m_eCurrentSubOperationType),
+	m_timeElapsed(rSrc.m_timeElapsed),
+	m_dTaskProgress(rSrc.m_dTaskProgress)
+{
+}
+
+TTaskStatsSnapshot& TTaskStatsSnapshot::operator=(const TTaskStatsSnapshot& rSrc)
+{
+	if(this != &rSrc)
+	{
+		m_tCurrentSubTaskStats = rSrc.m_tCurrentSubTaskStats;
+		m_bTaskIsRunning = rSrc.m_bTaskIsRunning;
+		m_eCurrentSubOperationType = rSrc.m_eCurrentSubOperationType;
+		m_timeElapsed = rSrc.m_timeElapsed;
+		m_dTaskProgress = rSrc.m_dTaskProgress;
+	}
+
+	return *this;
+}
+
+void TTaskStatsSnapshot::Clear()
+{
+	m_tCurrentSubTaskStats.Clear();
+	m_bTaskIsRunning = false;
+	m_eCurrentSubOperationType = eSubOperation_None;
+	m_timeElapsed = 0;
+	m_dTaskProgress = 0.0;
+}
+
+END_CHCORE_NAMESPACE
Index: src/libchcore/TTaskStatsSnapshot.h
===================================================================
diff -u
--- src/libchcore/TTaskStatsSnapshot.h	(revision 0)
+++ src/libchcore/TTaskStatsSnapshot.h	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -0,0 +1,70 @@
+// ============================================================================
+//  Copyright (C) 2001-2012 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  TTaskStatsSnapshot.h
+/// @date  2012/02/26
+/// @brief Contains class responsible for holding task stats.
+// ============================================================================
+#ifndef __TTASKSTATSSNAPSHOT_H__
+#define __TTASKSTATSSNAPSHOT_H__
+
+#include "libchcore.h"
+#include "TSubTaskStatsInfo.h"
+#include "ESubTaskTypes.h"
+#include "TSubTaskStatsSnapshot.h"
+
+BEGIN_CHCORE_NAMESPACE
+
+class LIBCHCORE_API TTaskStatsSnapshot
+{
+public:
+	TTaskStatsSnapshot();
+	TTaskStatsSnapshot(const TTaskStatsSnapshot& rSrc);
+
+	TTaskStatsSnapshot& operator=(const TTaskStatsSnapshot& rSrc);
+
+	void Clear();
+
+	const TSubTaskStatsSnapshot& GetCurrentSubTaskStats() const { return m_tCurrentSubTaskStats; }
+	TSubTaskStatsSnapshot& GetCurrentSubTaskStats() { return m_tCurrentSubTaskStats; }
+
+	bool IsTaskRunning() const { return m_bTaskIsRunning; }
+	void SetIsTaskIsRunning(bool bRunning) { m_bTaskIsRunning = bRunning; }
+
+	ESubOperationType GetCurrentSubOperationType() const { return m_eCurrentSubOperationType; }
+	void SetCurrentSubOperationType(ESubOperationType eSubTaskType) { m_eCurrentSubOperationType = eSubTaskType; }
+
+	time_t GetTimeElapsed() const { return m_timeElapsed; }
+	void SetTimeElapsed(time_t timeElapsed) { m_timeElapsed = timeElapsed; }
+
+	double GetTaskProgressInPercent() const { return m_dTaskProgress; }
+	void SetTaskProgressInPercent(double dProgress) { m_dTaskProgress = dProgress; }
+
+private:
+	TSubTaskStatsSnapshot m_tCurrentSubTaskStats;
+
+	double m_dTaskProgress;
+
+	bool m_bTaskIsRunning;
+	ESubOperationType m_eCurrentSubOperationType;
+	time_t m_timeElapsed;
+};
+
+END_CHCORE_NAMESPACE
+
+#endif
Index: src/libchcore/libchcore.vc90.vcproj
===================================================================
diff -u -r20aff533ab239b5b41263bb342879b4ea46fdbf6 -r12a1725bfd04b0f55fd0fda302975fdcd4174943
--- src/libchcore/libchcore.vc90.vcproj	(.../libchcore.vc90.vcproj)	(revision 20aff533ab239b5b41263bb342879b4ea46fdbf6)
+++ src/libchcore/libchcore.vc90.vcproj	(.../libchcore.vc90.vcproj)	(revision 12a1725bfd04b0f55fd0fda302975fdcd4174943)
@@ -339,118 +339,6 @@
 			<Filter
 				Name="Core"
 				>
-				<File
-					RelativePath=".\DataBuffer.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\DataBuffer.h"
-					>
-				</File>
-				<File
-					RelativePath=".\TAutoHandles.h"
-					>
-				</File>
-				<File
-					RelativePath=".\TBasePathData.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\TBasePathData.h"
-					>
-				</File>
-				<File
-					RelativePath=".\TFileFilter.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\TFileFilter.h"
-					>
-				</File>
-				<File
-					RelativePath=".\TFileFiltersArray.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\TFileFiltersArray.h"
-					>
-				</File>
-				<File
-					RelativePath=".\TFileInfo.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\TFileInfo.h"
-					>
-				</File>
-				<File
-					RelativePath=".\TFileInfoArray.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\TFileInfoArray.h"
-					>
-				</File>
-				<File
-					RelativePath=".\TLocalFilesystem.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\TLocalFilesystem.h"
-					>
-				</File>
-				<File
-					RelativePath=".\TSubTaskContext.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\TSubTaskContext.h"
-					>
-				</File>
-				<File
-					RelativePath=".\TTask.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\TTask.h"
-					>
-				</File>
-				<File
-					RelativePath=".\TTaskConfigTracker.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\TTaskConfigTracker.h"
-					>
-				</File>
-				<File
-					RelativePath=".\TTaskConfiguration.h"
-					>
-				</File>
-				<File
-					RelativePath=".\TTaskGlobalStats.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\TTaskGlobalStats.h"
-					>
-				</File>
-				<File
-					RelativePath=".\TTaskLocalStats.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\TTaskLocalStats.h"
-					>
-				</File>
-				<File
-					RelativePath=".\TTaskManager.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\TTaskManager.h"
-					>
-				</File>
 				<Filter
 					Name="SubTasks"
 					>
@@ -514,7 +402,147 @@
 						RelativePath=".\TSubTaskStatsInfo.h"
 						>
 					</File>
+					<File
+						RelativePath=".\TSubTaskStatsSnapshot.cpp"
+						>
+					</File>
+					<File
+						RelativePath=".\TSubTaskStatsSnapshot.h"
+						>
+					</File>
 				</Filter>
+				<Filter
+					Name="Task"
+					>
+					<File
+						RelativePath=".\TTask.cpp"
+						>
+					</File>
+					<File
+						RelativePath=".\TTask.h"
+						>
+					</File>
+					<File
+						RelativePath=".\TTaskConfigTracker.cpp"
+						>
+					</File>
+					<File
+						RelativePath=".\TTaskConfigTracker.h"
+						>
+					</File>
+					<File
+						RelativePath=".\TTaskConfiguration.h"
+						>
+					</File>
+					<File
+						RelativePath=".\TTaskLocalStats.cpp"
+						>
+					</File>
+					<File
+						RelativePath=".\TTaskLocalStats.h"
+						>
+					</File>
+					<File
+						RelativePath=".\TTaskStatsSnapshot.cpp"
+						>
+					</File>
+					<File
+						RelativePath=".\TTaskStatsSnapshot.h"
+						>
+					</File>
+				</Filter>
+				<Filter
+					Name="Task Manager"
+					>
+					<File
+						RelativePath=".\TTaskManager.cpp"
+						>
+					</File>
+					<File
+						RelativePath=".\TTaskManager.h"
+						>
+					</File>
+					<File
+						RelativePath=".\TTaskManagerStatsSnapshot.cpp"
+						>
+					</File>
+					<File
+						RelativePath=".\TTaskManagerStatsSnapshot.h"
+						>
+					</File>
+				</Filter>
+				<Filter
+					Name="Tools"
+					>
+					<File
+						RelativePath=".\DataBuffer.cpp"
+						>
+					</File>
+					<File
+						RelativePath=".\DataBuffer.h"
+						>
+					</File>
+					<File
+						RelativePath=".\TAutoHandles.h"
+						>
+					</File>
+					<File
+						RelativePath=".\TBasePathData.cpp"
+						>
+					</File>
+					<File
+						RelativePath=".\TBasePathData.h"
+						>
+					</File>
+					<File
+						RelativePath=".\TFileFilter.cpp"
+						>
+					</File>
+					<File
+						RelativePath=".\TFileFilter.h"
+						>
+					</File>
+					<File
+						RelativePath=".\TFileFiltersArray.cpp"
+						>
+					</File>
+					<File
+						RelativePath=".\TFileFiltersArray.h"
+						>
+					</File>
+					<File
+						RelativePath=".\TFileInfo.cpp"
+						>
+					</File>
+					<File
+						RelativePath=".\TFileInfo.h"
+						>
+					</File>
+					<File
+						RelativePath=".\TFileInfoArray.cpp"
+						>
+					</File>
+					<File
+						RelativePath=".\TFileInfoArray.h"
+						>
+					</File>
+					<File
+						RelativePath=".\TLocalFilesystem.cpp"
+						>
+					</File>
+					<File
+						RelativePath=".\TLocalFilesystem.h"
+						>
+					</File>
+					<File
+						RelativePath=".\TSubTaskContext.cpp"
+						>
+					</File>
+					<File
+						RelativePath=".\TSubTaskContext.h"
+						>
+					</File>
+				</Filter>
 			</Filter>
 			<Filter
 				Name="Base services"