Index: src/ch/ClipboardMonitor.cpp
===================================================================
diff -u -r1d7d79169d480a02e335b8b0a4919f9c78d58325 -r8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f
--- src/ch/ClipboardMonitor.cpp	(.../ClipboardMonitor.cpp)	(revision 1d7d79169d480a02e335b8b0a4919f9c78d58325)
+++ src/ch/ClipboardMonitor.cpp	(.../ClipboardMonitor.cpp)	(revision 8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f)
@@ -156,7 +156,7 @@
 				dlg.m_bdData.strText+=_T("...");
 
 			// show window
-			INT_PTR iResult=dlg.DoModal();
+			INT_PTR iResult = dlg.DoModal();
 
 			// set data to config
 			SetPropValue<PP_SHORTCUTS>(rConfig, dlg.m_bdData.cvShortcuts);
@@ -179,17 +179,6 @@
 				CTaskPtr spTask = pData->m_pTasks->CreateTask();
 				spTask->SetTaskDefinition(tTaskDefinition);
 
-				BUFFERSIZES bs;
-				bs.m_bOnlyDefault=GetPropValue<PP_BFUSEONLYDEFAULT>(rConfig);
-				bs.m_uiDefaultSize=GetPropValue<PP_BFDEFAULT>(rConfig);
-				bs.m_uiOneDiskSize=GetPropValue<PP_BFONEDISK>(rConfig);
-				bs.m_uiTwoDisksSize=GetPropValue<PP_BFTWODISKS>(rConfig);
-				bs.m_uiCDSize=GetPropValue<PP_BFCD>(rConfig);
-				bs.m_uiLANSize=GetPropValue<PP_BFLAN>(rConfig);
-
-				spTask->SetBufferSizes(&bs);
-				spTask->SetPriority(GetPropValue<PP_CMDEFAULTPRIORITY>(rConfig));
-
 				// add task to a list of tasks and start
 				pData->m_pTasks->Add(spTask);
 
Index: src/ch/MainWnd.cpp
===================================================================
diff -u -r1d7d79169d480a02e335b8b0a4919f9c78d58325 -r8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f
--- src/ch/MainWnd.cpp	(.../MainWnd.cpp)	(revision 1d7d79169d480a02e335b8b0a4919f9c78d58325)
+++ src/ch/MainWnd.cpp	(.../MainWnd.cpp)	(revision 8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f)
@@ -515,14 +515,23 @@
 	SetTaskPropValue<eTO_CreateDirectoriesRelativeToRoot>(tTaskDefinition.GetConfiguration(), bForceDirectories != FALSE);
 	SetTaskPropValue<eTO_IgnoreDirectories>(tTaskDefinition.GetConfiguration(), bIgnoreDirs != FALSE);
 
+	// buffer sizes
+	SetTaskPropValue<eTO_DefaultBufferSize>(tTaskDefinition.GetConfiguration(), bsSizes.m_uiDefaultSize);
+	SetTaskPropValue<eTO_OneDiskBufferSize>(tTaskDefinition.GetConfiguration(), bsSizes.m_uiOneDiskSize);
+	SetTaskPropValue<eTO_TwoDisksBufferSize>(tTaskDefinition.GetConfiguration(), bsSizes.m_uiTwoDisksSize);
+	SetTaskPropValue<eTO_CDBufferSize>(tTaskDefinition.GetConfiguration(), bsSizes.m_uiCDSize);
+	SetTaskPropValue<eTO_LANBufferSize>(tTaskDefinition.GetConfiguration(), bsSizes.m_uiLANSize);
+	SetTaskPropValue<eTO_UseOnlyDefaultBuffer>(tTaskDefinition.GetConfiguration(), bsSizes.m_bOnlyDefault);
+
+	// Task priority
+	SetTaskPropValue<eTO_ThreadPriority>(tTaskDefinition.GetConfiguration(), iPriority);
+
 	// create task with the above definition
 	CTaskPtr spTask = m_tasks.CreateTask();
 
 	spTask->SetTaskDefinition(tTaskDefinition);
 			
 	// set some stuff related with task
-	spTask->SetBufferSizes(&bsSizes);
-	spTask->SetPriority(iPriority);
 	spTask->SetFilters(&ffFilters);
 
 	m_tasks.Add(spTask);
@@ -592,12 +601,21 @@
 		SetTaskPropValue<eTO_CreateDirectoriesRelativeToRoot>(tTaskDefinition.GetConfiguration(), dlg.m_ccData.m_bForceDirectories);
 		SetTaskPropValue<eTO_IgnoreDirectories>(tTaskDefinition.GetConfiguration(), dlg.m_ccData.m_bIgnoreFolders);
 
+		// Buffer settings
+		SetTaskPropValue<eTO_DefaultBufferSize>(tTaskDefinition.GetConfiguration(), dlg.m_ccData.m_bsSizes.m_uiDefaultSize);
+		SetTaskPropValue<eTO_OneDiskBufferSize>(tTaskDefinition.GetConfiguration(), dlg.m_ccData.m_bsSizes.m_uiOneDiskSize);
+		SetTaskPropValue<eTO_TwoDisksBufferSize>(tTaskDefinition.GetConfiguration(), dlg.m_ccData.m_bsSizes.m_uiTwoDisksSize);
+		SetTaskPropValue<eTO_CDBufferSize>(tTaskDefinition.GetConfiguration(), dlg.m_ccData.m_bsSizes.m_uiCDSize);
+		SetTaskPropValue<eTO_LANBufferSize>(tTaskDefinition.GetConfiguration(), dlg.m_ccData.m_bsSizes.m_uiLANSize);
+		SetTaskPropValue<eTO_UseOnlyDefaultBuffer>(tTaskDefinition.GetConfiguration(), dlg.m_ccData.m_bsSizes.m_bOnlyDefault);
+
+		// Task priority
+		SetTaskPropValue<eTO_ThreadPriority>(tTaskDefinition.GetConfiguration(), dlg.m_ccData.m_iPriority);
+		
 		// new task
 		CTaskPtr spTask = m_tasks.CreateTask();
 		spTask->SetTaskDefinition(tTaskDefinition);
 		
-		spTask->SetBufferSizes(&dlg.m_ccData.m_bsSizes);
-		spTask->SetPriority(dlg.m_ccData.m_iPriority);
 		spTask->SetFilters(&dlg.m_ccData.m_afFilters);
 		
 		m_tasks.Add(spTask);
Index: src/ch/StatusDlg.cpp
===================================================================
diff -u -r0a673d59b6baab3d616ce2570e5bf63378fa7e3c -r8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f
--- src/ch/StatusDlg.cpp	(.../StatusDlg.cpp)	(revision 0a673d59b6baab3d616ce2570e5bf63378fa7e3c)
+++ src/ch/StatusDlg.cpp	(.../StatusDlg.cpp)	(revision 8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f)
@@ -319,7 +319,7 @@
 		// set progress
 		m_ctlCurrentProgress.SetPos(td.m_nPercent);
 
-		SetBufferSizesString(td.m_pbsSizes->m_auiSizes[td.m_iCurrentBufferIndex], td.m_iCurrentBufferIndex);
+		SetBufferSizesString(td.m_iCurrentBufferSize, td.m_iCurrentBufferIndex);
 
 		// data that can be changed only by user from outside the thread
 		// refresh only when there are new selected item
@@ -342,10 +342,10 @@
 		return;
 
 	CBufferSizeDlg dlg;
-	dlg.m_bsSizes = *spTask->GetBufferSizes();
+	spTask->GetBufferSizes(dlg.m_bsSizes);
 	dlg.m_iActiveIndex = spTask->GetCurrentBufferIndex();
 	if(dlg.DoModal() == IDOK)
-		spTask->SetBufferSizes(&dlg.m_bsSizes);
+		spTask->SetBufferSizes(dlg.m_bsSizes);
 }
 
 CTaskPtr CStatusDlg::GetSelectedItemPointer()
Index: src/ch/TConfig.cpp
===================================================================
diff -u -rca046f75806db6693a4b2dc6ddb255f76d0bbc3f -r8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f
--- src/ch/TConfig.cpp	(.../TConfig.cpp)	(revision ca046f75806db6693a4b2dc6ddb255f76d0bbc3f)
+++ src/ch/TConfig.cpp	(.../TConfig.cpp)	(revision 8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f)
@@ -87,7 +87,7 @@
 	boost::upgrade_lock<boost::shared_mutex> lock(rLock);
 
 	boost::optional<T> tValue = rTree.get_optional<T>(pszPropName);
-	if(tValue.is_initialized() && tValue.get() != tNewValue)
+	if(!tValue.is_initialized() || tValue.get() != tNewValue)
 	{
 		boost::upgrade_to_unique_lock<boost::shared_mutex> upgraded_lock(lock);
 		rTree.put<T>(pszPropName, tNewValue);
@@ -253,10 +253,10 @@
 
 TConfig& TConfig::SetValue(PCTSTR pszPropName, int iValue)
 {
-   if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, iValue))
-      SendNotification(pszPropName);
+	if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, iValue))
+		SendNotification(pszPropName);
 
-   return *this;
+	return *this;
 }
 
 unsigned int TConfig::GetUInt(PCTSTR pszPropName, unsigned int uiDefault) const
@@ -272,10 +272,10 @@
 
 TConfig& TConfig::SetValue(PCTSTR pszPropName, unsigned int uiValue)
 {
-   if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, uiValue))
-      SendNotification(pszPropName);
+	if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, uiValue))
+		SendNotification(pszPropName);
 
-   return *this;
+	return *this;
 }
 
 long long TConfig::GetLongLong(PCTSTR pszPropName, long long llDefault) const
@@ -291,10 +291,10 @@
 
 TConfig& TConfig::SetValue(PCTSTR pszPropName, long long llValue)
 {
-   if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, llValue))
-      SendNotification(pszPropName);
+	if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, llValue))
+		SendNotification(pszPropName);
 
-   return *this;
+	return *this;
 }
 
 unsigned long long TConfig::GetULongLong(PCTSTR pszPropName, unsigned long long ullDefault) const
@@ -310,10 +310,10 @@
 
 TConfig& TConfig::SetValue(PCTSTR pszPropName, unsigned long long ullValue)
 {
-   if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, ullValue))
-      SendNotification(pszPropName);
+	if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, ullValue))
+		SendNotification(pszPropName);
 
-   return *this;
+	return *this;
 }
 
 double TConfig::GetDouble(PCTSTR pszPropName, double dDefault) const
@@ -329,10 +329,10 @@
 
 TConfig& TConfig::SetValue(PCTSTR pszPropName, double dValue)
 {
-   if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, dValue))
-      SendNotification(pszPropName);
+	if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, dValue))
+		SendNotification(pszPropName);
 
-   return *this;
+	return *this;
 }
 
 CString TConfig::GetString(PCTSTR pszPropName, const CString& strDefault) const
@@ -344,20 +344,20 @@
 
 bool TConfig::GetValue(PCTSTR pszPropName, CString& rstrValue) const
 {
-   std::wstring wstrData;
-   bool bResult = ::GetValue<std::wstring>(m_propTree, pszPropName, wstrData, m_lock);
-   rstrValue = wstrData.c_str();
+	std::wstring wstrData;
+	bool bResult = ::GetValue<std::wstring>(m_propTree, pszPropName, wstrData, m_lock);
+	rstrValue = wstrData.c_str();
 
-   return bResult;
+	return bResult;
 }
 
 TConfig& TConfig::SetValue(PCTSTR pszPropName, const CString& strValue)
 {
-   std::wstring wstrData = strValue;
-   if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, wstrData))
-      SendNotification(pszPropName);
+	std::wstring wstrData = strValue;
+	if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, wstrData))
+		SendNotification(pszPropName);
 
-   return *this;
+	return *this;
 }
 
 bool TConfig::GetValue(PCTSTR pszPropName, std::vector<CString>& rvValues) const
@@ -404,7 +404,9 @@
 
 	boost::shared_lock<boost::shared_mutex> lock(m_lock);
 
-	rSubConfig.m_propTree = m_propTree.get_child(pszSubTreeName);
+	boost::optional<const boost::property_tree::wiptree&> optChildren = m_propTree.get_child_optional(pszSubTreeName);
+	if(optChildren.is_initialized())
+		rSubConfig.m_propTree = optChildren.get();
 }
 
 void TConfig::PutSubConfig(PCTSTR pszSubTreeName, const TConfig& rSubConfig)
Index: src/ch/TTaskConfigTracker.cpp
===================================================================
diff -u -rca046f75806db6693a4b2dc6ddb255f76d0bbc3f -r8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f
--- src/ch/TTaskConfigTracker.cpp	(.../TTaskConfigTracker.cpp)	(revision ca046f75806db6693a4b2dc6ddb255f76d0bbc3f)
+++ src/ch/TTaskConfigTracker.cpp	(.../TTaskConfigTracker.cpp)	(revision 8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f)
@@ -81,14 +81,14 @@
 	return bModified;
 }
 
-bool TTaskConfigTracker::IsModified(bool bResetModificationState, TOptionsSet setOptions)
+bool TTaskConfigTracker::IsModified(TOptionsSet setOptions, bool bResetModificationState)
 {
 	boost::upgrade_lock<boost::shared_mutex> lock(m_lock);
 
 	std::set<ETaskOptions> setCommon;
 	std::set_intersection(setOptions.Get().begin(), setOptions.Get().end(), m_setModified.begin(), m_setModified.end(), std::inserter(setCommon, setCommon.begin()));
 
-	bool bModified = setCommon.empty();
+	bool bModified = !setCommon.empty();
 	if(bModified && bResetModificationState)
 	{
 		boost::upgrade_to_unique_lock<boost::shared_mutex> upgraded_lock(lock);
@@ -127,7 +127,6 @@
 
 void TTaskConfigTracker::AddModified(const std::set<CString>& setModified)
 {
-	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 	BOOST_FOREACH(const CString& strVal, setModified)
 	{
 		AddModified(strVal);
Index: src/ch/TTaskConfigTracker.h
===================================================================
diff -u -rca046f75806db6693a4b2dc6ddb255f76d0bbc3f -r8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f
--- src/ch/TTaskConfigTracker.h	(.../TTaskConfigTracker.h)	(revision ca046f75806db6693a4b2dc6ddb255f76d0bbc3f)
+++ src/ch/TTaskConfigTracker.h	(.../TTaskConfigTracker.h)	(revision 8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f)
@@ -46,7 +46,7 @@
 	bool IsModified(ETaskOptions eOption) const;
 	bool IsModified(TOptionsSet setOptions) const;
 	bool IsModified(ETaskOptions eOption, bool bResetModificationState);
-	bool IsModified(bool bResetModificationState, TOptionsSet setOptions);
+	bool IsModified(TOptionsSet setOptions, bool bResetModificationState);
 
 	void AddModified(const CString& strModified);
 	void AddModified(ETaskOptions eModified);
Index: src/ch/task.cpp
===================================================================
diff -u -rca046f75806db6693a4b2dc6ddb255f76d0bbc3f -r8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f
--- src/ch/task.cpp	(.../task.cpp)	(revision ca046f75806db6693a4b2dc6ddb255f76d0bbc3f)
+++ src/ch/task.cpp	(.../task.cpp)	(revision 8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f)
@@ -49,16 +49,14 @@
 
 void TTasksGlobalStats::IncreaseGlobalTotalSize(unsigned long long ullModify)
 {
-	m_lock.lock();
+	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 	m_ullGlobalTotalSize += ullModify;
-	m_lock.unlock();
 }
 
 void TTasksGlobalStats::DecreaseGlobalTotalSize(unsigned long long ullModify)
 {
-	m_lock.lock();
+	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 	m_ullGlobalTotalSize -= ullModify;
-	m_lock.unlock();
 }
 
 unsigned long long TTasksGlobalStats::GetGlobalTotalSize() const
@@ -69,16 +67,14 @@
 
 void TTasksGlobalStats::IncreaseGlobalProcessedSize(unsigned long long ullModify)
 {
-	m_lock.lock();
+	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 	m_ullGlobalProcessedSize += ullModify;
-	m_lock.unlock();
 }
 
 void TTasksGlobalStats::DecreaseGlobalProcessedSize(unsigned long long ullModify)
 {
-	m_lock.lock();
+	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 	m_ullGlobalProcessedSize -= ullModify;
-	m_lock.unlock();
 }
 
 unsigned long long TTasksGlobalStats::GetGlobalProcessedSize() const
@@ -89,19 +85,16 @@
 
 void TTasksGlobalStats::IncreaseGlobalProgressData(unsigned long long ullTasksPosition, unsigned long long ullTasksSize)
 {
-	m_lock.lock();
+	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 	m_ullGlobalTotalSize += ullTasksSize;
 	m_ullGlobalProcessedSize += ullTasksPosition;
-	m_lock.unlock();
-
 }
 
 void TTasksGlobalStats::DecreaseGlobalProgressData(unsigned long long ullTasksPosition, unsigned long long ullTasksSize)
 {
-	m_lock.lock();
+	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 	m_ullGlobalTotalSize -= ullTasksSize;
 	m_ullGlobalProcessedSize -= ullTasksPosition;
-	m_lock.unlock();
 }
 
 int TTasksGlobalStats::GetProgressPercents() const
@@ -118,16 +111,14 @@
 
 void TTasksGlobalStats::IncreaseRunningTasks()
 {
-	m_lock.lock();
+	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 	++m_stRunningTasks;
-	m_lock.unlock();
 }
 
 void TTasksGlobalStats::DecreaseRunningTasks()
 {
-	m_lock.lock();
+	boost::unique_lock<boost::shared_mutex> lock(m_lock);
 	--m_stRunningTasks;
-	m_lock.unlock();
 }
 
 size_t TTasksGlobalStats::GetRunningTasksCount() const
@@ -426,7 +417,6 @@
 	m_log(),
 	m_piFeedbackHandler(piFeedbackHandler),
 	m_files(m_arrSourcePaths),
-	m_nPriority(THREAD_PRIORITY_NORMAL),
 	m_bForce(false),
 	m_bContinue(false),
 	m_bRareStateModified(false),
@@ -436,12 +426,6 @@
 	m_eCurrentState(eTaskState_None)
 {
 	BOOST_ASSERT(piFeedbackHandler);
-
-	m_bsSizes.m_uiDefaultSize=65536;
-	m_bsSizes.m_uiOneDiskSize=4194304;
-	m_bsSizes.m_uiTwoDisksSize=262144;
-	m_bsSizes.m_uiCDSize=262144;
-	m_bsSizes.m_uiLANSize=65536;
 }
 
 CTask::~CTask()
@@ -548,38 +532,37 @@
 	return m_eCurrentState;
 }
 
-// m_nBufferSize
-void CTask::SetBufferSizes(const BUFFERSIZES* bsSizes)
+void CTask::SetBufferSizes(const BUFFERSIZES& bsSizes)
 {
-	boost::unique_lock<boost::shared_mutex> lock(m_lock);
-	m_bsSizes = *bsSizes;
-	m_bOftenStateModified = true;
+	m_tTaskDefinition.GetConfiguration().DelayNotifications();
+	SetTaskPropValue<eTO_DefaultBufferSize>(m_tTaskDefinition.GetConfiguration(), bsSizes.m_uiDefaultSize);
+	SetTaskPropValue<eTO_OneDiskBufferSize>(m_tTaskDefinition.GetConfiguration(), bsSizes.m_uiOneDiskSize);
+	SetTaskPropValue<eTO_TwoDisksBufferSize>(m_tTaskDefinition.GetConfiguration(), bsSizes.m_uiTwoDisksSize);
+	SetTaskPropValue<eTO_CDBufferSize>(m_tTaskDefinition.GetConfiguration(), bsSizes.m_uiCDSize);
+	SetTaskPropValue<eTO_LANBufferSize>(m_tTaskDefinition.GetConfiguration(), bsSizes.m_uiLANSize);
+	SetTaskPropValue<eTO_UseOnlyDefaultBuffer>(m_tTaskDefinition.GetConfiguration(), bsSizes.m_bOnlyDefault);
+	m_tTaskDefinition.GetConfiguration().ResumeNotifications();
 }
 
-const BUFFERSIZES* CTask::GetBufferSizes()
+void CTask::GetBufferSizes(BUFFERSIZES& bsSizes)
 {
-	boost::shared_lock<boost::shared_mutex> lock(m_lock);
-	return &m_bsSizes;
+	bsSizes.m_uiDefaultSize = GetTaskPropValue<eTO_DefaultBufferSize>(m_tTaskDefinition.GetConfiguration());
+	bsSizes.m_uiOneDiskSize = GetTaskPropValue<eTO_OneDiskBufferSize>(m_tTaskDefinition.GetConfiguration());
+	bsSizes.m_uiTwoDisksSize = GetTaskPropValue<eTO_TwoDisksBufferSize>(m_tTaskDefinition.GetConfiguration());
+	bsSizes.m_uiCDSize = GetTaskPropValue<eTO_CDBufferSize>(m_tTaskDefinition.GetConfiguration());
+	bsSizes.m_uiLANSize = GetTaskPropValue<eTO_LANBufferSize>(m_tTaskDefinition.GetConfiguration());
+	bsSizes.m_bOnlyDefault = GetTaskPropValue<eTO_UseOnlyDefaultBuffer>(m_tTaskDefinition.GetConfiguration());
 }
 
 int CTask::GetCurrentBufferIndex()
 {
 	return m_files.GetBufferIndexAt(m_tTaskBasicProgressInfo.GetCurrentIndex(), m_tDestinationPath);
 }
 
-// m_pThread
-// m_nPriority
-int CTask::GetPriority()
-{
-	boost::shared_lock<boost::shared_mutex> lock(m_lock);
-
-	return m_nPriority;
-}
-
+// thread
 void CTask::SetPriority(int nPriority)
 {
-	boost::unique_lock<boost::shared_mutex> lock(m_lock);
-	SetPriorityNL(nPriority);
+	SetTaskPropValue<eTO_ThreadPriority>(m_tTaskDefinition.GetConfiguration(), nPriority);
 }
 
 void CTask::CalculateTotalSize()
@@ -654,9 +637,6 @@
 		THROW(_T("Wrong data read from stream"), 0, 0, 0);
 	}
 
-	ar2 >> m_bsSizes;
-	ar2 >> m_nPriority;
-
 	time_t timeElapsed = 0;
 	ar2 >> timeElapsed;
 	m_localStats.SetTimeElapsed(timeElapsed);
@@ -709,9 +689,6 @@
 
 		ar << iState;
 
-		ar << m_bsSizes;
-		ar << m_nPriority;
-
 		time_t timeElapsed = m_localStats.GetTimeElapsed();
 		ar << timeElapsed;
 
@@ -740,7 +717,7 @@
 	m_bRareStateModified = true;
 	m_bOftenStateModified = true;
 
-	m_workerThread.StartThread(DelegateThreadProc, this, m_nPriority);
+	m_workerThread.StartThread(DelegateThreadProc, this, GetTaskPropValue<eTO_ThreadPriority>(m_tTaskDefinition.GetConfiguration()));
 }
 
 void CTask::ResumeProcessing()
@@ -856,8 +833,7 @@
 		}
 	}
 
-	pData->m_pbsSizes=&m_bsSizes;
-	pData->m_nPriority=m_nPriority;
+	pData->m_nPriority = GetTaskPropValue<eTO_ThreadPriority>(m_tTaskDefinition.GetConfiguration());
 	pData->m_strDstPath = m_tTaskDefinition.GetDestinationPath();
 	pData->m_pafFilters=&m_afFilters;
 	pData->m_eTaskState = m_eCurrentState;
@@ -873,10 +849,33 @@
 	pData->m_bCreateEmptyFiles = GetTaskPropValue<eTO_CreateEmptyFiles>(m_tTaskDefinition.GetConfiguration());
 
 	if(m_files.GetSize() > 0)
-		pData->m_iCurrentBufferIndex=m_bsSizes.m_bOnlyDefault ? 0 : m_files.GetAt((stCurrentIndex < m_files.GetSize()) ? stCurrentIndex : 0)->GetBufferIndex(m_tDestinationPath);
+		pData->m_iCurrentBufferIndex = GetTaskPropValue<eTO_UseOnlyDefaultBuffer>(m_tTaskDefinition.GetConfiguration()) ? 0 : m_files.GetAt((stCurrentIndex < m_files.GetSize()) ? stCurrentIndex : 0)->GetBufferIndex(m_tDestinationPath);
 	else
-		pData->m_iCurrentBufferIndex=0;
+		pData->m_iCurrentBufferIndex = 0;
 
+	switch(pData->m_iCurrentBufferIndex)
+	{
+	case BI_DEFAULT:
+		pData->m_iCurrentBufferSize = GetTaskPropValue<eTO_DefaultBufferSize>(m_tTaskDefinition.GetConfiguration());
+		break;
+	case BI_ONEDISK:
+		pData->m_iCurrentBufferSize = GetTaskPropValue<eTO_OneDiskBufferSize>(m_tTaskDefinition.GetConfiguration());
+		break;
+	case BI_TWODISKS:
+		pData->m_iCurrentBufferSize = GetTaskPropValue<eTO_TwoDisksBufferSize>(m_tTaskDefinition.GetConfiguration());
+		break;
+	case BI_CD:
+		pData->m_iCurrentBufferSize = GetTaskPropValue<eTO_CDBufferSize>(m_tTaskDefinition.GetConfiguration());
+		break;
+	case BI_LAN:
+		pData->m_iCurrentBufferSize = GetTaskPropValue<eTO_LANBufferSize>(m_tTaskDefinition.GetConfiguration());
+		break;
+	default:
+		THROW(_T("Unhandled case"), 0, 0, 0);
+		//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();
 
@@ -1010,33 +1009,6 @@
 	return bResult != 0;
 }
 
-// m_nBufferSize
-void CTask::SetBufferSizesNL(const BUFFERSIZES* bsSizes)
-{
-	m_bsSizes = *bsSizes;
-	m_bOftenStateModified = true;
-}
-
-const BUFFERSIZES* CTask::GetBufferSizesNL()
-{
-	return &m_bsSizes;
-}
-
-// m_pThread
-// m_nPriority
-int CTask::GetPriorityNL()
-{
-	return m_nPriority;
-}
-
-void CTask::SetPriorityNL(int nPriority)
-{
-	m_workerThread.ChangePriority(nPriority);
-
-	m_nPriority = nPriority;
-	m_bOftenStateModified = true;
-}
-
 void CTask::CalculateTotalSizeNL()
 {
 	unsigned long long ullTotalSize = 0;
@@ -1920,7 +1892,7 @@
 			}
 
 			// recreate buffer if needed
-			if(m_cfgTracker.IsModified() && m_cfgTracker.IsModified(TOptionsSet() % eTO_DefaultBufferSize % eTO_OneDiskBufferSize % eTO_TwoDisksBufferSize % eTO_CDBufferSize % eTO_LANBufferSize % eTO_UseOnlyDefaultBuffer))
+			if(m_cfgTracker.IsModified() && m_cfgTracker.IsModified(TOptionsSet() % eTO_DefaultBufferSize % eTO_OneDiskBufferSize % eTO_TwoDisksBufferSize % eTO_CDBufferSize % eTO_LANBufferSize % eTO_UseOnlyDefaultBuffer, true))
 			{
 				BUFFERSIZES bs;
 				bs.m_bOnlyDefault = GetTaskPropValue<eTO_UseOnlyDefaultBuffer>(m_tTaskDefinition.GetConfiguration());
@@ -1949,11 +1921,11 @@
 				fmt.SetParam(_t("%dstfile"), pData->strDstFile);
 
 				m_log.logi(fmt);
-				pData->dbBuffer.Create(GetBufferSizes());
+				pData->dbBuffer.Create(&bs);
 			}
 
 			// establish count of data to read
-			if(GetBufferSizes()->m_bOnlyDefault)
+			if(GetTaskPropValue<eTO_UseOnlyDefaultBuffer>(m_tTaskDefinition.GetConfiguration()))
 				iBufferIndex = BI_DEFAULT;
 			else
 				iBufferIndex = pData->spSrcFile->GetBufferIndex(m_tDestinationPath);
@@ -2094,7 +2066,15 @@
 	// remove changes in buffer sizes to avoid re-creation later
 	m_cfgTracker.RemoveModificationSet(TOptionsSet() % eTO_DefaultBufferSize % eTO_OneDiskBufferSize % eTO_TwoDisksBufferSize % eTO_CDBufferSize % eTO_LANBufferSize % eTO_UseOnlyDefaultBuffer);
 
-	ccp.dbBuffer.Create(GetBufferSizes());
+	BUFFERSIZES bs;
+	bs.m_bOnlyDefault = GetTaskPropValue<eTO_UseOnlyDefaultBuffer>(m_tTaskDefinition.GetConfiguration());
+	bs.m_uiDefaultSize = GetTaskPropValue<eTO_DefaultBufferSize>(m_tTaskDefinition.GetConfiguration());
+	bs.m_uiOneDiskSize = GetTaskPropValue<eTO_OneDiskBufferSize>(m_tTaskDefinition.GetConfiguration());
+	bs.m_uiTwoDisksSize = GetTaskPropValue<eTO_TwoDisksBufferSize>(m_tTaskDefinition.GetConfiguration());
+	bs.m_uiCDSize = GetTaskPropValue<eTO_CDBufferSize>(m_tTaskDefinition.GetConfiguration());
+	bs.m_uiLANSize = GetTaskPropValue<eTO_LANBufferSize>(m_tTaskDefinition.GetConfiguration());
+
+	ccp.dbBuffer.Create(&bs);
 	ccp.pDestPath = &m_tDestinationPath;
 
 	// helpers
@@ -2372,6 +2352,7 @@
 
 		// enable configuration changes tracking
 		m_tTaskDefinition.GetConfiguration().ConnectToNotifier(TTaskConfigTracker::NotificationProc, &m_cfgTracker);
+		m_tTaskDefinition.GetConfiguration().ConnectToNotifier(CTask::OnCfgOptionChanged, this);
 
 		// set thread options
 		HANDLE hThread = GetCurrentThread();
@@ -2491,13 +2472,15 @@
 		m_localStats.MarkTaskAsNotRunning();
 
 		m_tTaskDefinition.GetConfiguration().DisconnectFromNotifier(TTaskConfigTracker::NotificationProc);
+		m_tTaskDefinition.GetConfiguration().DisconnectFromNotifier(CTask::OnCfgOptionChanged);
 
 		// and the real end
 		OnEndOperation();
 	}
 	catch(...)
 	{
 		m_tTaskDefinition.GetConfiguration().DisconnectFromNotifier(TTaskConfigTracker::NotificationProc);
+		m_tTaskDefinition.GetConfiguration().DisconnectFromNotifier(CTask::OnCfgOptionChanged);
 
 		// refresh time
 		m_localStats.DisableTimeTracking();
@@ -2596,6 +2579,18 @@
 	}
 }
 
+void CTask::OnCfgOptionChanged(const std::set<CString>& rsetChanges, void* pParam)
+{
+	CTask* pTask = (CTask*)pParam;
+	if(!pTask)
+		THROW(_T("Invalid pointer"), 0, 0, 0);
+
+	if(rsetChanges.find(TaskPropData<eTO_ThreadPriority>::GetPropertyName()) != rsetChanges.end())
+	{
+		pTask->m_workerThread.ChangePriority(GetTaskPropValue<eTO_ThreadPriority>(pTask->GetTaskDefinition().GetConfiguration()));
+	}
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // CTaskArray members
 CTaskArray::CTaskArray() :
@@ -2724,24 +2719,25 @@
 {
 	std::vector<CTaskPtr> vTasksToRemove;
 
-	m_lock.lock();
-	
-	size_t stIndex = m_vTasks.size();
-	while(stIndex--)
+	// separate scope for locking
 	{
-		CTaskPtr spTask = m_vTasks.at(stIndex);
-		
-		// delete only when the thread is finished
-		if((spTask->GetTaskState() == eTaskState_Finished || spTask->GetTaskState() == eTaskState_Cancelled))
+		boost::unique_lock<boost::shared_mutex> lock(m_lock);
+
+		size_t stIndex = m_vTasks.size();
+		while(stIndex--)
 		{
-			spTask->OnUnregisterTask();
+			CTaskPtr spTask = m_vTasks.at(stIndex);
 
-			vTasksToRemove.push_back(spTask);
-			m_vTasks.erase(m_vTasks.begin() + stIndex);
+			// delete only when the thread is finished
+			if((spTask->GetTaskState() == eTaskState_Finished || spTask->GetTaskState() == eTaskState_Cancelled))
+			{
+				spTask->OnUnregisterTask();
+
+				vTasksToRemove.push_back(spTask);
+				m_vTasks.erase(m_vTasks.begin() + stIndex);
+			}
 		}
 	}
-	
-	m_lock.unlock();
 
 	BOOST_FOREACH(CTaskPtr& spTask, vTasksToRemove)
 	{
Index: src/ch/task.h
===================================================================
diff -u -rca046f75806db6693a4b2dc6ddb255f76d0bbc3f -r8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f
--- src/ch/task.h	(.../task.h)	(revision ca046f75806db6693a4b2dc6ddb255f76d0bbc3f)
+++ src/ch/task.h	(.../task.h)	(revision 8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f)
@@ -53,6 +53,7 @@
 	CString m_strFullFilePath;
 	CString m_strFileName;
 
+	int m_iCurrentBufferSize;
 	int m_iCurrentBufferIndex;
 	size_t m_stIndex;
 	size_t m_stSize;
@@ -64,7 +65,6 @@
 	EOperationType m_eOperationType;
 	ESubOperationType m_eSubOperationType;
 
-	const BUFFERSIZES* m_pbsSizes;
 	int m_nPriority;
 
 	ull_t m_ullProcessedSize;
@@ -285,13 +285,11 @@
 	ETaskCurrentState GetTaskState() const;
 
 	// m_nBufferSize
-	void SetBufferSizes(const BUFFERSIZES* bsSizes);
-	const BUFFERSIZES* GetBufferSizes();
+	void SetBufferSizes(const BUFFERSIZES& bsSizes);
+	void GetBufferSizes(BUFFERSIZES& bsSizes);
 	int GetCurrentBufferIndex();
 
-	// m_pThread
-	// m_nPriority
-	int  GetPriority();
+	// thread
 	void SetPriority(int nPriority);
 
 	void Load(const CString& strPath);
@@ -372,14 +370,6 @@
 	void SetStatusNL(UINT nStatus, UINT nMask);
 	UINT GetStatusNL(UINT nMask = 0xffffffff);
 
-	// m_nBufferSize
-	void SetBufferSizesNL(const BUFFERSIZES* bsSizes);
-	const BUFFERSIZES* GetBufferSizesNL();
-
-	// m_nPriority
-	int  GetPriorityNL();
-	void SetPriorityNL(int nPriority);
-
 	void CalculateProcessedSize();
 	void CalculateProcessedSizeNL();
 
@@ -403,6 +393,8 @@
 
 	CString GetRelatedPathNL(EPathType ePathType);
 
+	static void OnCfgOptionChanged(const std::set<CString>& rsetChanges, void* pParam);
+
 private:
 	// task initial information (needed to start a task); might be a bit processed.
 	TTaskDefinition m_tTaskDefinition;
@@ -413,12 +405,8 @@
 	CDestPath m_tDestinationPath;
 
 	// task settings
-	int m_nPriority;                    // task priority (really processing thread priority)
-
 	CFiltersArray m_afFilters;          // filtering settings for files (will be filtered according to the rules inside when searching for files)
 
-	BUFFERSIZES m_bsSizes;              // sizes of buffers used to copy (derived from the global
-
 	// current task state (derivatives of the task initial information)
 	// changing slowly or only partially
 	CFileInfoArray m_files;             // list of files/directories found during operating on the task input data (filled by search for files)