Index: src/ch/ClipboardMonitor.cpp
===================================================================
diff -u -r9352ed0c4fe447a36bc728640c307be6d41455fd -rf703b71b8c856e2538283555e9fdbc84918677c3
--- src/ch/ClipboardMonitor.cpp	(.../ClipboardMonitor.cpp)	(revision 9352ed0c4fe447a36bc728640c307be6d41455fd)
+++ src/ch/ClipboardMonitor.cpp	(.../ClipboardMonitor.cpp)	(revision f703b71b8c856e2538283555e9fdbc84918677c3)
@@ -96,7 +96,7 @@
 	// bufor
 	TCHAR path[_MAX_PATH];
 	//	UINT i;	// counter
-	CTask *pTask;	// ptr to a task
+	CTaskPtr spTask;	// ptr to a task
 	CClipboardEntryPtr spEntry;
 
 	// register clipboard format
@@ -116,14 +116,14 @@
 
 			UINT nCount=DragQueryFile(static_cast<HDROP>(handle), 0xffffffff, NULL, 0);
 
-			pTask = pData->m_pTasks->CreateTask();
+			spTask = pData->m_pTasks->CreateTask();
 
 			for (UINT i=0;i<nCount;i++)
 			{
 				DragQueryFile(static_cast<HDROP>(handle), i, path, _MAX_PATH);
 				spEntry.reset(new CClipboardEntry);
 				spEntry->SetPath(path);
-				pTask->AddClipboardData(spEntry);
+				spTask->AddClipboardData(spEntry);
 			}
 
 			if (IsClipboardFormatAvailable(nFormat))
@@ -133,14 +133,14 @@
 
 				DWORD dwData=((DWORD*)addr)[0];
 				if (dwData & DROPEFFECT_COPY)
-					pTask->SetStatus(ST_COPY, ST_OPERATION_MASK);	// copy
+					spTask->SetStatus(ST_COPY, ST_OPERATION_MASK);	// copy
 				else if (dwData & DROPEFFECT_MOVE)
-					pTask->SetStatus(ST_MOVE, ST_OPERATION_MASK);	// move
+					spTask->SetStatus(ST_MOVE, ST_OPERATION_MASK);	// move
 
 				GlobalUnlock(handle);
 			}
 			else
-				pTask->SetStatus(ST_COPY, ST_OPERATION_MASK);	// default - copy
+				spTask->SetStatus(ST_COPY, ST_OPERATION_MASK);	// default - copy
 
 			EmptyClipboard();
 			CloseClipboard();
@@ -153,8 +153,8 @@
 			bs.m_uiCDSize=(UINT)rConfig.get_signed_num(PP_BFCD);
 			bs.m_uiLANSize=(UINT)rConfig.get_signed_num(PP_BFLAN);
 
-			pTask->SetBufferSizes(&bs);
-			pTask->SetPriority(boost::numeric_cast<int>(rConfig.get_signed_num(PP_CMDEFAULTPRIORITY)));
+			spTask->SetBufferSizes(&bs);
+			spTask->SetPriority(boost::numeric_cast<int>(rConfig.get_signed_num(PP_CMDEFAULTPRIORITY)));
 
 			// get dest folder
 			CFolderDialog dlg;
@@ -184,7 +184,7 @@
 
 			dlg.m_bdData.strInitialDir=(dlg.m_bdData.cvRecent.size() > 0) ? dlg.m_bdData.cvRecent.at(0) : _T("");
 
-			int iStatus=pTask->GetStatus(ST_OPERATION_MASK);
+			int iStatus=spTask->GetStatus(ST_OPERATION_MASK);
 			if (iStatus == ST_COPY)
 				dlg.m_bdData.strCaption=GetResManager().LoadString(IDS_TITLECOPY_STRING);
 			else if (iStatus == ST_MOVE)
@@ -194,11 +194,11 @@
 			dlg.m_bdData.strText=GetResManager().LoadString(IDS_MAINBROWSETEXT_STRING);
 
 			// set count of data to display
-			size_t stClipboardSize = pTask->GetClipboardDataSize();
+			size_t stClipboardSize = spTask->GetClipboardDataSize();
 			size_t stEntries = (stClipboardSize > 3) ? 2 : stClipboardSize;
 			for(size_t i = 0; i < stEntries; i++)
 			{
-				dlg.m_bdData.strText += pTask->GetClipboardData(i)->GetPath() + _T("\n");
+				dlg.m_bdData.strText += spTask->GetClipboardData(i)->GetPath() + _T("\n");
 			}
 
 			// add ...
@@ -228,30 +228,30 @@
 			rConfig.set_bool(PP_FDIGNORESHELLDIALOGS, dlg.m_bdData.bIgnoreDialogs);
 			rConfig.write(NULL);
 
-			if ( iResult != IDOK )
-				delete pTask;
+			if(iResult != IDOK)
+				spTask.reset();
 			else
 			{
 				// get dest path
 				CString strData;
 				dlg.GetPath(strData);
-				pTask->SetDestPath(strData);
+				spTask->SetDestPath(strData);
 
 				// get the relationship between src and dst paths
-				for (size_t stIndex = 0; stIndex < pTask->GetClipboard()->GetSize(); ++stIndex)
+				for (size_t stIndex = 0; stIndex < spTask->GetClipboard()->GetSize(); ++stIndex)
             {
-               pTask->GetClipboard()->GetAt(stIndex)->CalcBufferIndex(pTask->GetDestPath());
+               spTask->GetClipboard()->GetAt(stIndex)->CalcBufferIndex(spTask->GetDestPath());
             }
 
 				// add task to a list of tasks and start
-				pData->m_pTasks->Add(pTask);
+				pData->m_pTasks->Add(spTask);
 
-				// write pTask to a file
-				pTask->Store(true);
-				pTask->Store(false);
+				// write spTask to a file
+				spTask->Store(true);
+				spTask->Store(false);
 
 				// start processing
-				pTask->BeginProcessing();
+				spTask->BeginProcessing();
 			}
 		}
 
Index: src/ch/MainWnd.cpp
===================================================================
diff -u -r9352ed0c4fe447a36bc728640c307be6d41455fd -rf703b71b8c856e2538283555e9fdbc84918677c3
--- src/ch/MainWnd.cpp	(.../MainWnd.cpp)	(revision 9352ed0c4fe447a36bc728640c307be6d41455fd)
+++ src/ch/MainWnd.cpp	(.../MainWnd.cpp)	(revision f703b71b8c856e2538283555e9fdbc84918677c3)
@@ -333,10 +333,10 @@
 /////////////////////////////////////////////////////////////////////////////
 // CMainWnd/CTrayIcon menu message handlers
 
-void CMainWnd::ShowStatusWindow(const CTask *pSelect)
+void CMainWnd::ShowStatusWindow(const CTaskPtr& spSelect)
 {
 	m_pdlgStatus=new CStatusDlg(&m_tasks, this);	// self deleting
-	m_pdlgStatus->m_pInitialSelection=pSelect;
+	m_pdlgStatus->m_spInitialSelection = spSelect;
 	m_pdlgStatus->m_bLockInstance=true;
 	m_pdlgStatus->m_bAutoDelete=true;
 	m_pdlgStatus->Create();
@@ -402,19 +402,19 @@
 	case 8743:
 		{
 			// wait state handling section
-			CTask* pTask;
+			CTaskPtr spTask;
 			if (GetConfig().get_signed_num(PP_CMLIMITMAXOPERATIONS) == 0 || m_tasks.GetOperationsPending() < (UINT)GetConfig().get_signed_num(PP_CMLIMITMAXOPERATIONS))
 			{
 				for(size_t stIndex = 0; stIndex < m_tasks.GetSize(); ++stIndex)
 				{
-					pTask = m_tasks.GetAt(stIndex);
+					spTask = m_tasks.GetAt(stIndex);
 					// turn on some thread - find something with wait state
-					if (pTask->GetStatus(ST_WAITING_MASK) & ST_WAITING && (GetConfig().get_signed_num(PP_CMLIMITMAXOPERATIONS) == 0 || m_tasks.GetOperationsPending() < (UINT)GetConfig().get_signed_num(PP_CMLIMITMAXOPERATIONS)))
+					if(spTask->GetStatus(ST_WAITING_MASK) & ST_WAITING && (GetConfig().get_signed_num(PP_CMLIMITMAXOPERATIONS) == 0 || m_tasks.GetOperationsPending() < (UINT)GetConfig().get_signed_num(PP_CMLIMITMAXOPERATIONS)))
 					{
 						TRACE("Enabling task %ld\n", stIndex);
-						pTask->SetContinueFlag(true);
-						pTask->IncreaseOperationsPending();
-						pTask->SetStatus(0, ST_WAITING);		// turn off wait state
+						spTask->SetContinueFlag(true);
+						spTask->IncreaseOperationsPending();
+						spTask->SetStatus(0, ST_WAITING);		// turn off wait state
 					}
 				}
 			}
@@ -541,38 +541,38 @@
 	}
 
 	// create new task
-	CTask *pTask = m_tasks.CreateTask();
-	pTask->SetDestPath(strDstPath);
+	CTaskPtr spTask = m_tasks.CreateTask();
+	spTask->SetDestPath(strDstPath);
 	CClipboardEntryPtr spEntry;
 
 	// files
 	for (int i=0;i<astrFiles.GetSize();i++)
 	{
 		spEntry.reset(new CClipboardEntry);
 		spEntry->SetPath(astrFiles.GetAt(i));
-		spEntry->CalcBufferIndex(pTask->GetDestPath());
-		pTask->AddClipboardData(spEntry);
+		spEntry->CalcBufferIndex(spTask->GetDestPath());
+		spTask->AddClipboardData(spEntry);
 	}
 
-	pTask->SetStatus(bMove ? ST_MOVE : ST_COPY, ST_OPERATION_MASK);
+	spTask->SetStatus(bMove ? ST_MOVE : ST_COPY, ST_OPERATION_MASK);
 
 	// special status
-	pTask->SetStatus((bOnlyCreate ? ST_IGNORE_CONTENT : 0) | (bIgnoreDirs ? ST_IGNORE_DIRS : 0) | (bForceDirectories ? ST_FORCE_DIRS : 0), ST_SPECIAL_MASK);
+	spTask->SetStatus((bOnlyCreate ? ST_IGNORE_CONTENT : 0) | (bIgnoreDirs ? ST_IGNORE_DIRS : 0) | (bForceDirectories ? ST_FORCE_DIRS : 0), ST_SPECIAL_MASK);
 			
 	// set some stuff related with task
-	pTask->SetBufferSizes(&bsSizes);
-	pTask->SetPriority(iPriority);
-	pTask->SetFilters(&ffFilters);
-	pTask->SetCopies(ucCopies);
+	spTask->SetBufferSizes(&bsSizes);
+	spTask->SetPriority(iPriority);
+	spTask->SetFilters(&ffFilters);
+	spTask->SetCopies(ucCopies);
 
-	m_tasks.Add(pTask);
+	m_tasks.Add(spTask);
 
 	// save state of a task
-	pTask->Store(true);
-	pTask->Store(false);
+	spTask->Store(true);
+	spTask->Store(false);
 
 	// add to task list and start processing
-	pTask->BeginProcessing();
+	spTask->BeginProcessing();
 
 	return CWnd::OnCopyData(pWnd, pCopyDataStruct);
 }
@@ -626,35 +626,35 @@
 		}
 
 		// new task
-		CTask *pTask = m_tasks.CreateTask();
-		pTask->SetDestPath(dlg.m_ccData.m_strDestPath);
+		CTaskPtr spTask = m_tasks.CreateTask();
+		spTask->SetDestPath(dlg.m_ccData.m_strDestPath);
 		CClipboardEntryPtr spEntry;
 		for (int i=0;i<dlg.m_ccData.m_astrPaths.GetSize();i++)
 		{
 			spEntry.reset(new CClipboardEntry);
 			spEntry->SetPath(dlg.m_ccData.m_astrPaths.GetAt(i));
-			spEntry->CalcBufferIndex(pTask->GetDestPath());
-			pTask->AddClipboardData(spEntry);
+			spEntry->CalcBufferIndex(spTask->GetDestPath());
+			spTask->AddClipboardData(spEntry);
 		}
 		
-		pTask->SetStatus((dlg.m_ccData.m_iOperation == 1) ? ST_MOVE : ST_COPY, ST_OPERATION_MASK);
+		spTask->SetStatus((dlg.m_ccData.m_iOperation == 1) ? ST_MOVE : ST_COPY, ST_OPERATION_MASK);
 
 		// special status
-		pTask->SetStatus((dlg.m_ccData.m_bCreateStructure ? ST_IGNORE_CONTENT : 0) | (dlg.m_ccData.m_bIgnoreFolders ? ST_IGNORE_DIRS : 0)
+		spTask->SetStatus((dlg.m_ccData.m_bCreateStructure ? ST_IGNORE_CONTENT : 0) | (dlg.m_ccData.m_bIgnoreFolders ? ST_IGNORE_DIRS : 0)
 			| (dlg.m_ccData.m_bForceDirectories ? ST_FORCE_DIRS : 0), ST_SPECIAL_MASK);
 		
-		pTask->SetBufferSizes(&dlg.m_ccData.m_bsSizes);
-		pTask->SetPriority(dlg.m_ccData.m_iPriority);
-		pTask->SetFilters(&dlg.m_ccData.m_afFilters);
+		spTask->SetBufferSizes(&dlg.m_ccData.m_bsSizes);
+		spTask->SetPriority(dlg.m_ccData.m_iPriority);
+		spTask->SetFilters(&dlg.m_ccData.m_afFilters);
 		
-		m_tasks.Add(pTask);
+		m_tasks.Add(spTask);
 
 		// save
-		pTask->Store(true);
-		pTask->Store(false);
+		spTask->Store(true);
+		spTask->Store(false);
 		
 		// store and start
-		pTask->BeginProcessing();
+		spTask->BeginProcessing();
 	}
 }
 
@@ -664,7 +664,8 @@
 	{
 	case WM_MINIVIEWDBLCLK:
 		{
-			ShowStatusWindow((CTask*)lParam);
+         CTaskPtr spTask = m_tasks.GetTaskBySessionUniqueID(lParam);
+			ShowStatusWindow(spTask);
 			break;
 		}
 	case WM_SHOWMINIVIEW:
@@ -925,31 +926,13 @@
 	// kill thread that monitors clipboard
 	CClipboardMonitor::StopMonitor();
 
-	// kill all unfinished tasks - send kill request
-	for(size_t stIndex = 0; stIndex < m_tasks.GetSize(); ++stIndex)
-   {
-      m_tasks.GetAt(stIndex)->SetKillFlag();
-   }
+   m_tasks.StopAllTasks();
 
-	// wait for finishing
-	for(size_t stIndex = 0; stIndex < m_tasks.GetSize(); ++stIndex)
-	{
-		while(!m_tasks.GetAt(stIndex)->GetKilledFlag())
-			Sleep(10);
-		m_tasks.GetAt(stIndex)->CleanupAfterKill();
-	}
-
 	// save
 	m_tasks.SaveProgress();
 
 	// delete all tasks
-	size_t stSize = m_tasks.GetSize();
-	while(stSize--)
-	{
-		delete m_tasks.GetAt(stSize);
-	}
-
-	(static_cast< CArray<CTask*, CTask*>* >(&m_tasks))->RemoveAll();
+	m_tasks.RemoveAll();
 }
 
 void CMainWnd::OnAppExit()
Index: src/ch/MainWnd.h
===================================================================
diff -u -r59c39dd19e2c42f33189ee07274f0488d54d7ed0 -rf703b71b8c856e2538283555e9fdbc84918677c3
--- src/ch/MainWnd.h	(.../MainWnd.h)	(revision 59c39dd19e2c42f33189ee07274f0488d54d7ed0)
+++ src/ch/MainWnd.h	(.../MainWnd.h)	(revision f703b71b8c856e2538283555e9fdbc84918677c3)
@@ -66,7 +66,7 @@
 protected:
 	BOOL RegisterClass();
 	int ShowTrayIcon();
-	void ShowStatusWindow(const CTask* pSelect=NULL);
+	void ShowStatusWindow(const CTaskPtr& spSelect = CTaskPtr());
 	void PrepareToExit();
 	//{{AFX_MSG(CMainWnd)
 	afx_msg void OnPopupShowStatus();
Index: src/ch/MiniViewDlg.cpp
===================================================================
diff -u -r9352ed0c4fe447a36bc728640c307be6d41455fd -rf703b71b8c856e2538283555e9fdbc84918677c3
--- src/ch/MiniViewDlg.cpp	(.../MiniViewDlg.cpp)	(revision 9352ed0c4fe447a36bc728640c307be6d41455fd)
+++ src/ch/MiniViewDlg.cpp	(.../MiniViewDlg.cpp)	(revision f703b71b8c856e2538283555e9fdbc84918677c3)
@@ -179,16 +179,16 @@
 	int index=0;
 	_PROGRESSITEM_* pItem=NULL;
 
-	if (GetConfig().get_bool(PP_MVSHOWSINGLETASKS))
+	if(GetConfig().get_bool(PP_MVSHOWSINGLETASKS))
 	{
 		for(size_t stIndex = 0; stIndex < m_pTasks->GetSize(); ++stIndex)
 		{
-			CTask* pTask=m_pTasks->GetAt(stIndex);
-			pTask->GetMiniSnapshot(&dd);
+			CTaskPtr spTask = m_pTasks->GetAt(stIndex);
+			spTask->GetMiniSnapshot(&dd);
 
-			if ((dd.m_uiStatus & ST_STEP_MASK) != ST_FINISHED && (dd.m_uiStatus & ST_STEP_MASK) != ST_CANCELLED)
+			if((dd.m_uiStatus & ST_STEP_MASK) != ST_FINISHED && (dd.m_uiStatus & ST_STEP_MASK) != ST_CANCELLED)
 			{
-				pItem=m_ctlStatus.GetItemAddress(index++);
+				pItem = m_ctlStatus.GetItemAddress(index++);
 
 				// load
 				if ((dd.m_uiStatus & ST_WORKING_MASK) == ST_ERROR)
@@ -202,7 +202,7 @@
 				
 				pItem->m_strText=dd.m_fi.GetFileName();
 				pItem->m_uiPos=dd.m_nPercent;
-				pItem->m_pTask=pTask;
+				pItem->m_spTask = spTask;
 			}
 		}
 	}
@@ -245,7 +245,7 @@
 	pItem->m_crColor=GetSysColor(COLOR_HIGHLIGHT);
 	pItem->m_strText=GetResManager().LoadString(IDS_MINIVIEWALL_STRING);
 	pItem->m_uiPos=m_pTasks->GetPercent();
-	pItem->m_pTask=NULL;
+	pItem->m_spTask.reset();
 
 	// get rid of the rest
 	m_ctlStatus.SetSmoothProgress(GetConfig().get_bool(PP_MVUSESMOOTHPROGRESS));
@@ -406,9 +406,9 @@
 			if (iSel == LB_ERR || (size_t)iSel >= pDlg->m_ctlStatus.m_vItems.size())
 				return;
 
-			CTask* pTask;
-			if ( (pTask=pDlg->m_ctlStatus.m_vItems.at(iSel)->m_pTask) != NULL)
-				pTask->PauseProcessing();
+			CTaskPtr spTask = pDlg->m_ctlStatus.m_vItems.at(iSel)->m_spTask;
+			if(spTask)
+				spTask->PauseProcessing();
 			else
 				pDlg->m_pTasks->TasksPauseProcessing();
 
@@ -513,13 +513,13 @@
 			int iSel=pDlg->m_ctlStatus.GetCurSel();
 			if (iSel == LB_ERR || (size_t)iSel >= pDlg->m_ctlStatus.m_vItems.size())
 				return;
-			CTask* pTask;
-			if ( (pTask=pDlg->m_ctlStatus.m_vItems.at(iSel)->m_pTask) != NULL)
+			CTaskPtr spTask = pDlg->m_ctlStatus.m_vItems.at(iSel)->m_spTask;
+			if (spTask)
 			{
-				if (pTask->GetStatus(ST_WAITING_MASK) & ST_WAITING)
-					pTask->SetForceFlag(true);
+				if(spTask->GetStatus(ST_WAITING_MASK) & ST_WAITING)
+					spTask->SetForceFlag(true);
 				else
-					pTask->ResumeProcessing();
+					spTask->ResumeProcessing();
 			}
 			else
 				pDlg->m_pTasks->TasksResumeProcessing();
@@ -557,9 +557,9 @@
 		int iSel=pDlg->m_ctlStatus.GetCurSel();
 		if (iSel == LB_ERR || (size_t)iSel >= pDlg->m_ctlStatus.m_vItems.size())
 			return;
-		CTask* pTask;
-		if ( (pTask=pDlg->m_ctlStatus.m_vItems.at(iSel)->m_pTask) != NULL)
-			pTask->CancelProcessing();
+		CTaskPtr spTask = pDlg->m_ctlStatus.m_vItems.at(iSel)->m_spTask;
+		if(spTask)
+			spTask->CancelProcessing();
 		else
 			pDlg->m_pTasks->TasksCancelProcessing();
 		break;
@@ -611,9 +611,9 @@
 			int iSel=pDlg->m_ctlStatus.GetCurSel();
 			if (iSel == LB_ERR || (size_t)iSel >= pDlg->m_ctlStatus.m_vItems.size())
 				return;
-			CTask* pTask;
-			if ( (pTask=pDlg->m_ctlStatus.m_vItems.at(iSel)->m_pTask) != NULL)
-				pTask->RestartProcessing();
+         CTaskPtr spTask = pDlg->m_ctlStatus.m_vItems.at(iSel)->m_spTask;
+			if(spTask)
+				spTask->RestartProcessing();
 			else
 				pDlg->m_pTasks->TasksRestartProcessing();
 			break;
@@ -801,13 +801,13 @@
 
 void CMiniViewDlg::OnDblclkProgressList() 
 {
-	int iSel=m_ctlStatus.GetCurSel();
-	if (iSel == LB_ERR || (size_t)iSel >= m_ctlStatus.m_vItems.size())
+	int iSel = m_ctlStatus.GetCurSel();
+	if(iSel == LB_ERR || (size_t)iSel >= m_ctlStatus.m_vItems.size())
 		return;
-	CTask* pTask;
-	pTask=m_ctlStatus.m_vItems.at(iSel)->m_pTask;
 
-	GetParent()->PostMessage(WM_MINIVIEWDBLCLK, 0, (LPARAM)pTask);
+   CTaskPtr spTask = m_ctlStatus.m_vItems.at(iSel)->m_spTask;
+
+	GetParent()->PostMessage(WM_MINIVIEWDBLCLK, 0, (LPARAM)spTask->GetSessionUniqueID());
 }
 
 void CMiniViewDlg::OnLanguageChanged()
Index: src/ch/ProgressListBox.cpp
===================================================================
diff -u -r9352ed0c4fe447a36bc728640c307be6d41455fd -rf703b71b8c856e2538283555e9fdbc84918677c3
--- src/ch/ProgressListBox.cpp	(.../ProgressListBox.cpp)	(revision 9352ed0c4fe447a36bc728640c307be6d41455fd)
+++ src/ch/ProgressListBox.cpp	(.../ProgressListBox.cpp)	(revision f703b71b8c856e2538283555e9fdbc84918677c3)
@@ -17,6 +17,7 @@
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
 #include "stdafx.h"
+#include "task.h"
 #include "ProgressListBox.h"
 #include "MemDC.h"
 
Index: src/ch/ProgressListBox.h
===================================================================
diff -u -r449a5b399ab21ca0d06050b47b264f2f704af966 -rf703b71b8c856e2538283555e9fdbc84918677c3
--- src/ch/ProgressListBox.h	(.../ProgressListBox.h)	(revision 449a5b399ab21ca0d06050b47b264f2f704af966)
+++ src/ch/ProgressListBox.h	(.../ProgressListBox.h)	(revision f703b71b8c856e2538283555e9fdbc84918677c3)
@@ -19,8 +19,6 @@
 #ifndef __PROGRESSLISTBOX_H__
 #define __PROGRESSLISTBOX_H__
 
-class CTask;
-
 /////////////////////////////////////////////////////////////////////////////
 // CProgressListBox window
 struct _PROGRESSITEM_
@@ -32,7 +30,7 @@
 
 	COLORREF m_crColor;
 
-	CTask* m_pTask;
+	CTaskPtr m_spTask;
 };
 
 class CProgressListBox : public CListBox
Index: src/ch/ReplacePathsDlg.cpp
===================================================================
diff -u -r9352ed0c4fe447a36bc728640c307be6d41455fd -rf703b71b8c856e2538283555e9fdbc84918677c3
--- src/ch/ReplacePathsDlg.cpp	(.../ReplacePathsDlg.cpp)	(revision 9352ed0c4fe447a36bc728640c307be6d41455fd)
+++ src/ch/ReplacePathsDlg.cpp	(.../ReplacePathsDlg.cpp)	(revision f703b71b8c856e2538283555e9fdbc84918677c3)
@@ -18,10 +18,10 @@
 ***************************************************************************/
 #include "stdafx.h"
 #include "resource.h"
+#include "task.h"
 #include "ReplacePathsDlg.h"
 #include "dialogs.h"
 #include "ch.h"
-#include "task.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
@@ -82,9 +82,9 @@
 
 	InitializeResizableControls();
 
-	for(size_t stIndex = 0; stIndex < m_pTask->GetClipboardDataSize(); ++stIndex)
+	for(size_t stIndex = 0; stIndex < m_spTask->GetClipboardDataSize(); ++stIndex)
    {
-      m_ctlPathsList.AddString(m_pTask->GetClipboardData(stIndex)->GetPath());
+      m_ctlPathsList.AddString(m_spTask->GetClipboardData(stIndex)->GetPath());
    }
 	
 	return TRUE;
Index: src/ch/ReplacePathsDlg.h
===================================================================
diff -u -r9c71c0a84781c524c0091ee86914d5cc3bbf5190 -rf703b71b8c856e2538283555e9fdbc84918677c3
--- src/ch/ReplacePathsDlg.h	(.../ReplacePathsDlg.h)	(revision 9c71c0a84781c524c0091ee86914d5cc3bbf5190)
+++ src/ch/ReplacePathsDlg.h	(.../ReplacePathsDlg.h)	(revision f703b71b8c856e2538283555e9fdbc84918677c3)
@@ -30,7 +30,7 @@
 public:
 	CReplacePathsDlg();   // standard constructor
 
-	CTask* m_pTask;
+	CTaskPtr m_spTask;
 // Dialog Data
 	//{{AFX_DATA(CReplacePathsDlg)
 	enum { IDD = IDD_REPLACE_PATHS_DIALOG };
Index: src/ch/StatusDlg.cpp
===================================================================
diff -u -r9352ed0c4fe447a36bc728640c307be6d41455fd -rf703b71b8c856e2538283555e9fdbc84918677c3
--- src/ch/StatusDlg.cpp	(.../StatusDlg.cpp)	(revision 9352ed0c4fe447a36bc728640c307be6d41455fd)
+++ src/ch/StatusDlg.cpp	(.../StatusDlg.cpp)	(revision f703b71b8c856e2538283555e9fdbc84918677c3)
@@ -164,7 +164,7 @@
 	size_t stIndex = 0;
 	while(stIndex < m_pTasks->GetSize())
 	{
-		if(m_pTasks->GetAt(stIndex) == m_pInitialSelection)
+		if(m_pTasks->GetAt(stIndex) == m_spInitialSelection)
 		{
          m_ctlStatusList.SetItemState(boost::numeric_cast<int>(stIndex), LVIS_SELECTED, LVIS_SELECTED);
 			break;
@@ -224,21 +224,25 @@
 	CLanguageDialog::OnTimer(nIDEvent);
 }
 
-void CStatusDlg::AddTaskInfo(int nPos, CTask *pTask, DWORD dwCurrentTime)
+void CStatusDlg::AddTaskInfo(int nPos, const CTaskPtr& spTask, DWORD dwCurrentTime)
 {
+   _ASSERTE(spTask != NULL);
+   if(spTask == NULL)
+      return;
+
 	// index to string
 	_itot(nPos, m_szData, 10);
 
 	// get data snapshot from task
-	pTask->GetSnapshot(&td);
+	spTask->GetSnapshot(&td);
 
 	// index subitem
 	lvi.mask=LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
 	lvi.iItem=nPos;
 	lvi.iSubItem=0;
 	lvi.pszText=td.m_szStatusText;
 	lvi.cchTextMax=lstrlen(lvi.pszText);
-	lvi.lParam=reinterpret_cast<LPARAM>(pTask);
+	lvi.lParam = spTask->GetSessionUniqueID();
 	lvi.iImage=GetImageFromStatus(td.m_uiStatus);
 	if (nPos < m_ctlStatusList.GetItemCount())
 		m_ctlStatusList.SetItem(&lvi);
@@ -271,7 +275,7 @@
 	m_ctlStatusList.SetItem(&lvi);
 
 	// right side update
-	if (pTask == pSelectedItem && GetConfig().get_bool(PP_STATUSSHOWDETAILS))
+	if(spTask == m_spSelectedItem && GetConfig().get_bool(PP_STATUSSHOWDETAILS))
 	{
 		// data that can be changed by a thread
 		GetDlgItem(IDC_OPERATION_STATIC)->SetWindowText(td.m_szStatusText);	// operation
@@ -335,56 +339,42 @@
 
 		// data that can be changed only by user from outside the thread
 		// refresh only when there are new selected item
-//		if (pTask != m_pLastSelected)
+//		if (spTask != m_spLastSelected)
 		{
 			GetDlgItem(IDC_DESTINATION_STATIC)->SetWindowText(td.m_pdpDestPath->GetPath());
 			GetDlgItem(IDC_PRIORITY_STATIC)->SetWindowText(GetResManager().LoadString(IDS_PRIORITY0_STRING+PriorityToIndex(td.m_nPriority)));
 			GetDlgItem(IDC_ASSOCIATEDFILES__STATIC)->SetWindowText(*td.m_pstrUniqueName+_T(".atd (.atp, .log)"));
 		}
 
-		// refresh m_pLastSelected
-		m_pLastSelected=pTask;
+		// refresh m_spLastSelected
+		m_spLastSelected = spTask;
 	}
 }
 
 void CStatusDlg::OnSetBuffersizeButton()
 {
-	CTask* pTask;
-	if ( (pTask=GetSelectedItemPointer()) == NULL )
+	CTaskPtr spTask = GetSelectedItemPointer();
+	if(!spTask)
 		return;
 
 	CBufferSizeDlg dlg;
-	dlg.m_bsSizes=*pTask->GetBufferSizes();
-	dlg.m_iActiveIndex=pTask->GetCurrentBufferIndex();
-	if (dlg.DoModal() == IDOK)
-	{
-		// if the task has been deleted - skip
-		if ( pTask != GetSelectedItemPointer() )
-		{
-			TRACE("Task were finished and deleted when trying to change buffer sizes");
-			return;
-		}
-		
-		TRACE("bOnlyDefault=%d\n", dlg.m_bsSizes.m_bOnlyDefault);
-		pTask->SetBufferSizes(&dlg.m_bsSizes);
-	}
+	dlg.m_bsSizes = *spTask->GetBufferSizes();
+	dlg.m_iActiveIndex = spTask->GetCurrentBufferIndex();
+	if(dlg.DoModal() == IDOK)
+   	spTask->SetBufferSizes(&dlg.m_bsSizes);
 }
 
-CTask* CStatusDlg::GetSelectedItemPointer()
+CTaskPtr CStatusDlg::GetSelectedItemPointer()
 {
-//	TRACE("inside GetSelectedItemPointer()\n");
 	// returns ptr to a CTask for a given element in listview
-	if (m_ctlStatusList.GetSelectedCount() == 1)
+	if(m_ctlStatusList.GetSelectedCount() == 1)
 	{
-		POSITION pos=m_ctlStatusList.GetFirstSelectedItemPosition();
-		int nPos=m_ctlStatusList.GetNextSelectedItem(pos);
-		CTask* pSelectedItem=reinterpret_cast<CTask*>(m_ctlStatusList.GetItemData(nPos));
-//		if (AfxIsValidAddress(pSelectedItem, sizeof(CTask)))
-		return pSelectedItem;
+		POSITION pos = m_ctlStatusList.GetFirstSelectedItemPosition();
+		int nPos = m_ctlStatusList.GetNextSelectedItem(pos);
+		return m_pTasks->GetTaskBySessionUniqueID(m_ctlStatusList.GetItemData(nPos));
 	}
-//	TRACE("exiting GetSelectedItemPointer()\n");
 
-	return NULL;
+	return CTaskPtr();
 }
 
 void CStatusDlg::OnRollUnrollButton() 
@@ -437,18 +427,18 @@
 void CStatusDlg::ApplyButtonsState()
 {
 	// remember ptr to CTask
-	pSelectedItem=GetSelectedItemPointer();
+	m_spSelectedItem=GetSelectedItemPointer();
 	bool bShowLog=GetConfig().get_bool(PP_CMCREATELOG);
 
 	// set status of buttons pause/resume/cancel
-	if (pSelectedItem != NULL)
+	if (m_spSelectedItem != NULL)
 	{
 		GetDlgItem(IDC_RESTART_BUTTON)->EnableWindow(true);
 		GetDlgItem(IDC_SHOW_LOG_BUTTON)->EnableWindow(bShowLog);
 		GetDlgItem(IDC_DELETE_BUTTON)->EnableWindow(true);
 		
-		if (pSelectedItem->GetStatus(ST_STEP_MASK) == ST_FINISHED
-			|| pSelectedItem->GetStatus(ST_STEP_MASK) == ST_CANCELLED)
+		if (m_spSelectedItem->GetStatus(ST_STEP_MASK) == ST_FINISHED
+			|| m_spSelectedItem->GetStatus(ST_STEP_MASK) == ST_CANCELLED)
 		{
 			GetDlgItem(IDC_CANCEL_BUTTON)->EnableWindow(false);
 			GetDlgItem(IDC_PAUSE_BUTTON)->EnableWindow(false);
@@ -457,15 +447,15 @@
 		else
 		{
 			// pause/resume
-			if (pSelectedItem->GetStatus(ST_WORKING_MASK) & ST_PAUSED)
+			if (m_spSelectedItem->GetStatus(ST_WORKING_MASK) & ST_PAUSED)
 			{
 				GetDlgItem(IDC_PAUSE_BUTTON)->EnableWindow(false);
 				GetDlgItem(IDC_RESUME_BUTTON)->EnableWindow(true);
 			}
 			else
 			{
 				GetDlgItem(IDC_PAUSE_BUTTON)->EnableWindow(true);
-				if (pSelectedItem->GetStatus(ST_WAITING_MASK) & ST_WAITING)
+				if (m_spSelectedItem->GetStatus(ST_WAITING_MASK) & ST_WAITING)
 					GetDlgItem(IDC_RESUME_BUTTON)->EnableWindow(true);
 				else
 					GetDlgItem(IDC_RESUME_BUTTON)->EnableWindow(false);
@@ -514,37 +504,37 @@
 		if (LOWORD(wParam) >= ID_POPUP_TIME_CRITICAL && LOWORD(wParam) <= ID_POPUP_IDLE)
 		{
 			// processing priority
-			if ( (pSelectedItem=GetSelectedItemPointer()) == NULL )
+			if ( (m_spSelectedItem=GetSelectedItemPointer()) == NULL )
 				return ictranslate::CLanguageDialog::OnCommand(wParam, lParam);
 			
 			switch (LOWORD(wParam))
 			{
 			case ID_POPUP_TIME_CRITICAL:
-				pSelectedItem->SetPriority(THREAD_PRIORITY_TIME_CRITICAL);
+				m_spSelectedItem->SetPriority(THREAD_PRIORITY_TIME_CRITICAL);
 				GetDlgItem(IDC_PRIORITY_STATIC)->SetWindowText(GetResManager().LoadString(IDS_PRIORITY0_STRING+PriorityToIndex(THREAD_PRIORITY_TIME_CRITICAL)));
 				break;
 			case ID_POPUP_HIGHEST:
-				pSelectedItem->SetPriority(THREAD_PRIORITY_HIGHEST);
+				m_spSelectedItem->SetPriority(THREAD_PRIORITY_HIGHEST);
 				GetDlgItem(IDC_PRIORITY_STATIC)->SetWindowText(GetResManager().LoadString(IDS_PRIORITY0_STRING+PriorityToIndex(THREAD_PRIORITY_HIGHEST)));
 				break;
 			case ID_POPUP_ABOVE_NORMAL:
-				pSelectedItem->SetPriority(THREAD_PRIORITY_ABOVE_NORMAL);
+				m_spSelectedItem->SetPriority(THREAD_PRIORITY_ABOVE_NORMAL);
 				GetDlgItem(IDC_PRIORITY_STATIC)->SetWindowText(GetResManager().LoadString(IDS_PRIORITY0_STRING+PriorityToIndex(THREAD_PRIORITY_ABOVE_NORMAL)));
 				break;
 			case ID_POPUP_NORMAL:
-				pSelectedItem->SetPriority(THREAD_PRIORITY_NORMAL);
+				m_spSelectedItem->SetPriority(THREAD_PRIORITY_NORMAL);
 				GetDlgItem(IDC_PRIORITY_STATIC)->SetWindowText(GetResManager().LoadString(IDS_PRIORITY0_STRING+PriorityToIndex(THREAD_PRIORITY_NORMAL)));
 				break;
 			case ID_POPUP_BELOW_NORMAL:
-				pSelectedItem->SetPriority(THREAD_PRIORITY_BELOW_NORMAL);
+				m_spSelectedItem->SetPriority(THREAD_PRIORITY_BELOW_NORMAL);
 				GetDlgItem(IDC_PRIORITY_STATIC)->SetWindowText(GetResManager().LoadString(IDS_PRIORITY0_STRING+PriorityToIndex(THREAD_PRIORITY_BELOW_NORMAL)));
 				break;
 			case ID_POPUP_LOWEST:
-				pSelectedItem->SetPriority(THREAD_PRIORITY_LOWEST);
+				m_spSelectedItem->SetPriority(THREAD_PRIORITY_LOWEST);
 				GetDlgItem(IDC_PRIORITY_STATIC)->SetWindowText(GetResManager().LoadString(IDS_PRIORITY0_STRING+PriorityToIndex(THREAD_PRIORITY_LOWEST)));
 				break;
 			case ID_POPUP_IDLE:
-				pSelectedItem->SetPriority(THREAD_PRIORITY_IDLE);
+				m_spSelectedItem->SetPriority(THREAD_PRIORITY_IDLE);
 				GetDlgItem(IDC_PRIORITY_STATIC)->SetWindowText(GetResManager().LoadString(IDS_PRIORITY0_STRING+PriorityToIndex(THREAD_PRIORITY_IDLE)));
 				break;
 			}
@@ -555,83 +545,71 @@
 
 void CStatusDlg::OnPauseButton() 
 {
-	CTask* pTask;
-	if ( (pTask=GetSelectedItemPointer()) == NULL )
-		return;
+	CTaskPtr spTask = GetSelectedItemPointer();
+	if(spTask)
+   {
+      TRACE("PauseProcessing call...\n");
+      spTask->PauseProcessing();
 
-	TRACE("PauseProcessing call...\n");
-	pTask->PauseProcessing();
-
-	RefreshStatus();
+      RefreshStatus();
+   }
 }
 
 void CStatusDlg::OnResumeButton() 
 {
-	CTask* pTask;
-	if ( (pTask=GetSelectedItemPointer()) == NULL )
-		return;
+   CTaskPtr spTask = GetSelectedItemPointer();
+	if(spTask)
+   {
+      if(spTask->GetStatus(ST_WAITING_MASK) & ST_WAITING)
+         spTask->SetForceFlag();
+      else
+         spTask->ResumeProcessing();
 
-	TRACE("ResumeProcessing call ");
-	if (pTask->GetStatus(ST_WAITING_MASK) & ST_WAITING)
-	{
-		TRACE("by setting force flag\n");
-		pTask->SetForceFlag();
-	}
-	else
-	{
-		TRACE("by function ResumeProcessing\n");
-		pTask->ResumeProcessing();
-	}
-
-	RefreshStatus();
+      RefreshStatus();
+   }
 }
 
 void CStatusDlg::OnCancelButton() 
 {
-	CTask* pTask;
-	if ( (pTask=GetSelectedItemPointer()) != NULL )
-	{
-		TRACE("CancelProcessing call...\n");
-		pTask->CancelProcessing();
-	}
-	RefreshStatus();
+   CTaskPtr spTask = GetSelectedItemPointer();
+	if(spTask)
+   {
+      spTask->CancelProcessing();
+      RefreshStatus();
+   }
 }
 
 void CStatusDlg::OnRestartButton() 
 {
-	CTask* pTask;
-	if ( (pTask=GetSelectedItemPointer()) == NULL )
-		return;
-
-	TRACE("RestartProcessing call...\n");
-	pTask->RestartProcessing();
-	RefreshStatus();
+   CTaskPtr spTask = GetSelectedItemPointer();
+	if(spTask)
+   {
+      spTask->RestartProcessing();
+      RefreshStatus();
+   }
 }
 
 void CStatusDlg::OnDeleteButton() 
 {
-	CTask* pTask;
-	if ( (pTask=GetSelectedItemPointer()) == NULL )
-		return;
+   CTaskPtr spTask = GetSelectedItemPointer();
+	if(spTask)
+   {
+      UINT uiStatus = spTask->GetStatus(ST_STEP_MASK);
+      if((uiStatus & ST_STEP_MASK) != ST_FINISHED && (uiStatus & ST_STEP_MASK) != ST_CANCELLED)
+      {
+         // ask if cancel
+         if(MsgBox(IDS_CONFIRMCANCEL_STRING, MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
+         {
+            // cancel
+            spTask->CancelProcessing();
+         }
+         else
+            return;
+      }
 
-	UINT uiStatus=pTask->GetStatus(ST_STEP_MASK);
-	if ( (uiStatus & ST_STEP_MASK) != ST_FINISHED && (uiStatus & ST_STEP_MASK) != ST_CANCELLED )
-	{
-		// ask if cancel
-		if (MsgBox(IDS_CONFIRMCANCEL_STRING, MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
-		{
-			// cancel
-			if ( (pTask=GetSelectedItemPointer()) == NULL )
-				return;
-
-			pTask->CancelProcessing();
-		}
-		else
-			return;
-	}
-
-		m_pTasks->RemoveFinished(&pTask);
-	RefreshStatus();
+      m_pTasks->RemoveFinished(spTask);
+      RefreshStatus();
+   }
 }
 
 void CStatusDlg::OnPauseAllButton() 
@@ -678,11 +656,11 @@
 		break;
 	case VK_SPACE:
 		{
-			CTask* pTask;
-			if ( (pTask=GetSelectedItemPointer()) == NULL )
+         CTaskPtr spTask = GetSelectedItemPointer();
+			if (!spTask)
 				return;
 		
-			if (pTask->GetStatus(ST_WORKING_MASK) & ST_PAUSED)
+			if(spTask->GetStatus(ST_WORKING_MASK) & ST_PAUSED)
 				OnResumeButton();
 			else
 				OnPauseButton();
@@ -731,7 +709,7 @@
 void CStatusDlg::RefreshStatus()
 {
 	// remember address of a current selection
-	pSelectedItem=GetSelectedItemPointer();
+	m_spSelectedItem=GetSelectedItemPointer();
 
 	// current time
 	DWORD dwCurrentTime=GetTickCount();
@@ -787,7 +765,7 @@
 	if (m_ctlStatusList.GetSelectedCount() == 0)
 	{
 		EnableControls(false);
-		m_pLastSelected=NULL;
+		m_spLastSelected.reset();
 		m_i64LastProcessed=0;
 	}
 	else
@@ -834,24 +812,24 @@
 void CStatusDlg::OnPopupReplacePaths() 
 {
 	// check if there's a selection currently
-	if ( (pSelectedItem=GetSelectedItemPointer()) != NULL )
+	if ( (m_spSelectedItem=GetSelectedItemPointer()) != NULL )
 	{
-		if (pSelectedItem->GetStatus(ST_WORKING_MASK) & ST_PAUSED)
+		if (m_spSelectedItem->GetStatus(ST_WORKING_MASK) & ST_PAUSED)
 		{
 			bool bContinue=false;
-			if (pSelectedItem->GetStatus(ST_WORKING_MASK) == ST_ERROR)
+			if (m_spSelectedItem->GetStatus(ST_WORKING_MASK) == ST_ERROR)
 			{
-				pSelectedItem->PauseProcessing();
+				m_spSelectedItem->PauseProcessing();
 				bContinue=true;
 			}
 
 			// assuming here that there's selection and task is paused
 			CReplacePathsDlg dlg;
-			dlg.m_pTask=pSelectedItem;
+			dlg.m_spTask=m_spSelectedItem;
 			if (dlg.DoModal() == IDOK)
 			{
 				// change 'no case'
-				int iClipboard=pSelectedItem->ReplaceClipboardStrings(dlg.m_strSource, dlg.m_strDest);
+				int iClipboard=m_spSelectedItem->ReplaceClipboardStrings(dlg.m_strSource, dlg.m_strDest);
 
 				ictranslate::CFormat fmt(GetResManager().LoadString(IDS_REPLACEPATHSTEXT_STRING));
 				fmt.SetParam(_t("%count"), iClipboard);
@@ -860,7 +838,7 @@
 
 			// resume if earlier was an error
 			if (bContinue)
-				pSelectedItem->ResumeProcessing();
+				m_spSelectedItem->ResumeProcessing();
 		}
 		else
 			MsgBox(IDS_TASKNOTPAUSED_STRING);
@@ -872,16 +850,15 @@
 void CStatusDlg::OnShowLogButton() 
 {
 	// show log
-	CTask* pTask;
-	if ( (pTask=GetSelectedItemPointer()) == NULL || !GetConfig().get_bool(PP_CMCREATELOG))
+	CTaskPtr spTask = GetSelectedItemPointer();
+	if (!spTask || !GetConfig().get_bool(PP_CMCREATELOG))
 		return;
 
-	// call what's needed
-	unsigned long lResult=(unsigned long)(ShellExecute(this->m_hWnd, _T("open"), _T("notepad.exe"),
-			CString(pTask->GetTaskPath())+pTask->GetUniqueName()+_T(".log"), NULL, SW_SHOWNORMAL));
-	if (lResult < 32)
+	unsigned long lResult = (unsigned long)(ShellExecute(this->m_hWnd, _T("open"), _T("notepad.exe"),
+			CString(spTask->GetTaskPath()) + spTask->GetUniqueName() + _T(".log"), NULL, SW_SHOWNORMAL));
+	if(lResult < 32)
 	{
-		CString str=CString(pTask->GetTaskPath())+pTask->GetUniqueName()+_T(".log");
+		CString str = CString(spTask->GetTaskPath()) + spTask->GetUniqueName()+_T(".log");
 		ictranslate::CFormat fmt(GetResManager().LoadString(IDS_SHELLEXECUTEERROR_STRING));
 		fmt.SetParam(_t("%errno"), lResult);
 		fmt.SetParam(_t("%path"), str);
Index: src/ch/StatusDlg.h
===================================================================
diff -u -r11621f18af6a7b1d486a7d6a576b97d4d09e8e96 -rf703b71b8c856e2538283555e9fdbc84918677c3
--- src/ch/StatusDlg.h	(.../StatusDlg.h)	(revision 11621f18af6a7b1d486a7d6a576b97d4d09e8e96)
+++ src/ch/StatusDlg.h	(.../StatusDlg.h)	(revision f703b71b8c856e2538283555e9fdbc84918677c3)
@@ -41,15 +41,15 @@
 
 	void ApplyButtonsState();
 	void ApplyDisplayDetails(bool bInitial=false);
-	CTask* GetSelectedItemPointer();
+	CTaskPtr GetSelectedItemPointer();
 
-	void AddTaskInfo(int nPos, CTask *pTask, DWORD dwCurrentTime);
+	void AddTaskInfo(int nPos, const CTaskPtr& spTask, DWORD dwCurrentTime);
 	void EnableControls(bool bEnable=true);
 
 	CTaskArray* m_pTasks;
-	CTask* pSelectedItem;
-	const CTask *m_pLastSelected;
-	const CTask* m_pInitialSelection;
+	CTaskPtr m_spSelectedItem;
+	CTaskPtr m_spLastSelected;
+	CTaskPtr m_spInitialSelection;
 
 	TCHAR m_szData[_MAX_PATH];
 	TCHAR m_szTimeBuffer1[40];
Index: src/ch/task.cpp
===================================================================
diff -u -r678a716a4ed83d5790a407ce60dfcf7d8ca703fa -rf703b71b8c856e2538283555e9fdbc84918677c3
--- src/ch/task.cpp	(.../task.cpp)	(revision 678a716a4ed83d5790a407ce60dfcf7d8ca703fa)
+++ src/ch/task.cpp	(.../task.cpp)	(revision f703b71b8c856e2538283555e9fdbc84918677c3)
@@ -25,6 +25,7 @@
 #include <boost/serialization/serialization.hpp>
 #include <boost/archive/binary_oarchive.hpp>
 #include <boost/archive/binary_iarchive.hpp>
+#include <boost/make_shared.hpp>
 #include <fstream>
 
 // assume max sectors of 4kB (for rounding)
@@ -64,7 +65,7 @@
 
 ////////////////////////////////////////////////////////////////////////////
 // CTask members
-CTask::CTask(chcore::IFeedbackHandler* piFeedbackHandler, const TASK_CREATE_DATA *pCreateData) :
+CTask::CTask(chcore::IFeedbackHandler* piFeedbackHandler, const TASK_CREATE_DATA *pCreateData, size_t stSessionUniqueID) :
 	m_log(),
 	m_piFeedbackHandler(piFeedbackHandler),
 	m_files(m_clipboard),
@@ -91,7 +92,8 @@
 	m_bForce(false),
 	m_bContinue(false),
 	m_bSaved(false),
-	m_lOsError(0)
+	m_lOsError(0),
+   m_stSessionUniqueID(stSessionUniqueID)
 {
 	BOOST_ASSERT(piFeedbackHandler);
 
@@ -1126,12 +1128,12 @@
 ////////////////////////////////////////////////////////////////////////////////
 // CTaskArray members
 CTaskArray::CTaskArray() :
-CArray<CTask*, CTask*>(),
-m_uhRange(0),
-m_uhPosition(0),
-m_uiOperationsPending(0),
-m_lFinished(0),
-m_piFeedbackFactory(NULL)
+   m_uhRange(0),
+   m_uhPosition(0),
+   m_uiOperationsPending(0),
+   m_lFinished(0),
+   m_piFeedbackFactory(NULL),
+   m_stNextSessionUniqueID(0)
 {
 }
 
@@ -1152,76 +1154,75 @@
 	m_piFeedbackFactory = piFeedbackHandlerFactory;
 }
 
-CTask* CTaskArray::CreateTask()
+CTaskPtr CTaskArray::CreateTask()
 {
 	BOOST_ASSERT(m_piFeedbackFactory);
 	if(!m_piFeedbackFactory)
-		return NULL;
+		return CTaskPtr();
 
 	chcore::IFeedbackHandler* piHandler = m_piFeedbackFactory->Create();
 	if(!piHandler)
-		return NULL;
+		return CTaskPtr();
 
-	CTask* pTask = NULL;
-	try
-	{
-		pTask = new CTask(piHandler, &m_tcd);
-	}
-	catch(...)
-	{
-		//		piHandler->Delete();
-		throw;
-	}
-
-	return pTask;
+   CTaskPtr spTask = boost::make_shared<CTask>(piHandler, &m_tcd, m_stNextSessionUniqueID++);
+	return spTask;
 }
 
 size_t CTaskArray::GetSize()
 {
 	m_cs.Lock();
-	size_t stSize = m_nSize;
+	size_t stSize = m_vTasks.size();
 	m_cs.Unlock();
 
 	return stSize;
 }
 
-size_t CTaskArray::GetUpperBound( )
+CTaskPtr CTaskArray::GetAt(size_t nIndex)
 {
+	_ASSERTE(nIndex >= 0 && nIndex < (size_t)m_vTasks.size());
+   if(nIndex >= m_vTasks.size())
+      THROW(_t("Invalid argument"), 0, 0, 0);
+
 	m_cs.Lock();
-	size_t stUpper = m_nSize;
+	CTaskPtr spTask = m_vTasks.at(nIndex);
 	m_cs.Unlock();
 
-	return stUpper - 1;
+	return spTask;
 }
 
-void CTaskArray::SetSize(size_t nNewSize, int nGrowBy)
+CTaskPtr CTaskArray::GetTaskBySessionUniqueID(size_t stSessionUniqueID)
 {
-	m_cs.Lock();
-	(static_cast<CArray<CTask*, CTask*>*>(this))->SetSize(nNewSize, nGrowBy);
-	m_cs.Unlock();
-}
+   CTaskPtr spFoundTask;
 
-CTask* CTaskArray::GetAt(size_t nIndex)
-{
-	ASSERT(nIndex >= 0 && nIndex < (size_t)m_nSize);
-	m_cs.Lock();
-	CTask* pTask = m_pData[nIndex];
-	m_cs.Unlock();
+   m_cs.Lock();
+   BOOST_FOREACH(CTaskPtr& spTask, m_vTasks)
+   {
+      if(spTask->GetSessionUniqueID() == stSessionUniqueID)
+      {
+         spFoundTask = spTask;
+         break;
+      }
+   }
+   m_cs.Unlock();
 
-	return pTask;
+   return spFoundTask;
 }
 
-size_t CTaskArray::Add(CTask* newElement)
+size_t CTaskArray::Add(const CTaskPtr& spNewTask)
 {
-	if(!newElement)
+	if(!spNewTask)
 		THROW(_t("Invalid argument"), 0, 0, 0);
+
 	m_cs.Lock();
 	// here we know load succeeded
-	newElement->SetTaskPath(m_strTasksDir.c_str());
+	spNewTask->SetTaskPath(m_strTasksDir.c_str());
 
-	m_uhRange+=newElement->GetAllSize();
-	m_uhPosition+=newElement->GetProcessedSize();
-	size_t pos = (static_cast<CArray<CTask*, CTask*>*>(this))->Add(newElement);
+   m_vTasks.push_back(spNewTask);
+
+	m_uhRange += spNewTask->GetAllSize();
+	m_uhPosition += spNewTask->GetProcessedSize();
+
+	size_t pos = m_vTasks.size() - 1;
 	m_cs.Unlock();
 
 	return pos;
@@ -1230,135 +1231,143 @@
 void CTaskArray::RemoveAt(size_t stIndex, size_t stCount)
 {
 	m_cs.Lock();
-	for(size_t i = stIndex; i < stIndex + stCount; i++)
-	{
-		CTask* pTask = GetAt(i);
+   try
+   {
+      _ASSERTE(stIndex >= m_vTasks.size() || stIndex + stCount > m_vTasks.size());
+      if(stIndex >= m_vTasks.size() || stIndex + stCount > m_vTasks.size())
+         THROW(_t("Invalid argument"), 0, 0, 0);
 
-		// kill task if needed
-		pTask->KillThread();
+      for(std::vector<CTaskPtr>::iterator iterTask = m_vTasks.begin() + stIndex; iterTask != m_vTasks.begin() + stIndex + stCount; ++iterTask)
+	   {
+		   CTaskPtr& spTask = *iterTask;
 
-		m_uhRange -= pTask->GetAllSize();
-		m_uhPosition -= pTask->GetProcessedSize();
+		   // kill task if needed
+		   spTask->KillThread();
 
-		delete pTask;
-	}
+		   m_uhRange -= spTask->GetAllSize();
+		   m_uhPosition -= spTask->GetProcessedSize();
+	   }
 
-	// remove elements from array
-	(static_cast<CArray<CTask*, CTask*>*>(this))->RemoveAt(stIndex, stCount);
+	   // remove elements from array
+      m_vTasks.erase(m_vTasks.begin() + stIndex, m_vTasks.begin() + stIndex + stCount);
+   }
+   catch(...)
+   {
+      m_cs.Unlock();
+      throw;
+   }
 	m_cs.Unlock();
 }
 
 void CTaskArray::RemoveAll()
 {
-	m_cs.Lock();
-	CTask* pTask;
+   m_cs.Lock();
 
-	for(size_t stIndex = 0; stIndex < GetSize(); ++stIndex)
-   {
-      GetAt(stIndex)->SetKillFlag();		// send an info about finishing
-   }
+   StopAllTasks();
 
-	// wait for finishing and get rid of it
-	for(size_t stIndex = 0; stIndex < GetSize(); ++stIndex)
-	{
-		pTask=GetAt(stIndex);
+	m_vTasks.clear();
 
-		// wait
-		while(!pTask->GetKilledFlag())
-			Sleep(10);
-
-		pTask->CleanupAfterKill();
-
-		m_uhRange-=pTask->GetAllSize();
-		m_uhPosition-=pTask->GetProcessedSize();
-
-		// delete data
-		delete pTask;
-	}
-
-	(static_cast<CArray<CTask*, CTask*>*>(this))->RemoveAll();
-	m_cs.Unlock();
+   m_cs.Unlock();
 }
 
 void CTaskArray::RemoveAllFinished()
 {
 	m_cs.Lock();
-	size_t i = GetSize();
 
-	while(i--)
+   size_t stIndex = m_vTasks.size();
+	while(stIndex--)
 	{
-		CTask* pTask = GetAt(i);
+		CTaskPtr spTask = m_vTasks.at(stIndex);
 
 		// delete only when the thread is finished
-		if ( (pTask->GetStatus(ST_STEP_MASK) == ST_FINISHED || pTask->GetStatus(ST_STEP_MASK) == ST_CANCELLED)
-			&& pTask->GetKilledFlag())
+		if((spTask->GetStatus(ST_STEP_MASK) == ST_FINISHED || spTask->GetStatus(ST_STEP_MASK) == ST_CANCELLED)
+			&& spTask->GetKilledFlag())
 		{
-			m_uhRange-=pTask->GetAllSize();
-			m_uhPosition-=pTask->GetProcessedSize();
+			m_uhRange -= spTask->GetAllSize();
+			m_uhPosition -= spTask->GetProcessedSize();
 
 			// delete associated files
-			pTask->DeleteProgress(m_strTasksDir.c_str());
+			spTask->DeleteProgress(m_strTasksDir.c_str());
 
-			delete pTask;
-
-			static_cast<CArray<CTask*, CTask*>*>(this)->RemoveAt(i);
+			m_vTasks.erase(m_vTasks.begin() + stIndex);
 		}
 	}
 
 	m_cs.Unlock();
 }
 
-void CTaskArray::RemoveFinished(CTask** pSelTask)
+void CTaskArray::RemoveFinished(const CTaskPtr& spSelTask)
 {
 	m_cs.Lock();
-	for(size_t stIndex=0; stIndex < GetSize(); ++stIndex)
+	for(std::vector<CTaskPtr>::iterator iterTask = m_vTasks.begin(); iterTask != m_vTasks.end(); ++iterTask)
 	{
-		CTask* pTask = GetAt(stIndex);
+		CTaskPtr& spTask = *iterTask;
 
-		if (pTask == *pSelTask && (pTask->GetStatus(ST_STEP_MASK) == ST_FINISHED || pTask->GetStatus(ST_STEP_MASK) == ST_CANCELLED))
+		if(spTask == spSelTask && (spTask->GetStatus(ST_STEP_MASK) == ST_FINISHED || spTask->GetStatus(ST_STEP_MASK) == ST_CANCELLED))
 		{
 			// kill task if needed
-			pTask->KillThread();
+			spTask->KillThread();
 
-			m_uhRange-=pTask->GetAllSize();
-			m_uhPosition-=pTask->GetProcessedSize();
+			m_uhRange -= spTask->GetAllSize();
+			m_uhPosition -= spTask->GetProcessedSize();
 
 			// delete associated files
-			pTask->DeleteProgress(m_strTasksDir.c_str());
+			spTask->DeleteProgress(m_strTasksDir.c_str());
 
-			// delete data
-			delete pTask;
+			m_vTasks.erase(iterTask);
 
-			static_cast<CArray<CTask*, CTask*>*>(this)->RemoveAt(stIndex);
-
 			m_cs.Unlock();
 			return;
 		}
 	}
 	m_cs.Unlock();
 }
 
+void CTaskArray::StopAllTasks()
+{
+   m_cs.Lock();
+
+   // kill all unfinished tasks - send kill request
+   BOOST_FOREACH(CTaskPtr& spTask, m_vTasks)
+   {
+      spTask->SetKillFlag();
+   }
+
+   // wait for finishing
+   BOOST_FOREACH(CTaskPtr& spTask, m_vTasks)
+   {
+      while(!spTask->GetKilledFlag())
+         Sleep(10);
+      spTask->CleanupAfterKill();
+   }
+   m_cs.Unlock();
+}
+
 void CTaskArray::SaveData()
 {
 	m_cs.Lock();
-	for (int i=0;i<m_nSize;i++)
-		m_pData[i]->Store(true);
+	BOOST_FOREACH(CTaskPtr& spTask, m_vTasks)
+   {
+      spTask->Store(true);
+   }
 	m_cs.Unlock();
 }
 
 void CTaskArray::SaveProgress()
 {
 	m_cs.Lock();
-	for (int i=0;i<m_nSize;i++)
-		m_pData[i]->Store(false);
+   BOOST_FOREACH(CTaskPtr& spTask, m_vTasks)
+   {
+      spTask->Store(false);
+   }
 	m_cs.Unlock();
 }
 
 void CTaskArray::LoadDataProgress()
 {
 	m_cs.Lock();
 	CFileFind finder;
-	CTask* pTask;
+	CTaskPtr spTask;
 	CString strPath;
 
 	BOOL bWorking=finder.FindFile(CString(m_strTasksDir.c_str())+_T("*.atd"));
@@ -1367,28 +1376,26 @@
 		bWorking = finder.FindNextFile();
 
 		// load data
-		pTask = CreateTask();
-
+		spTask = CreateTask();
 		try
 		{
 			strPath = finder.GetFilePath();
 
-			pTask->Load(strPath, true);
+			spTask->Load(strPath, true);
 
 			strPath = strPath.Left(strPath.GetLength() - 4);
 			strPath += _T(".atp");
 
-			pTask->Load(strPath, false);
+			spTask->Load(strPath, false);
 
 			// add read task to array
-			Add(pTask);
+			Add(spTask);
 		}
 		catch(std::exception& e)
 		{
 			CString strFmt;
 			strFmt.Format(_T("Cannot load task data: %s (reason: %S)"), strPath, e.what());
 			LOG_ERROR(strFmt);
-			delete pTask;
 		}
 	}
 	finder.Close();
@@ -1398,16 +1405,18 @@
 
 void CTaskArray::TasksBeginProcessing()
 {
-	for(size_t stIndex = 0; stIndex < GetSize(); ++stIndex)
+	BOOST_FOREACH(CTaskPtr& spTask, m_vTasks)
    {
-      GetAt(stIndex)->BeginProcessing();
+      spTask->BeginProcessing();
    }
 }
 
 void CTaskArray::TasksPauseProcessing()
 {
-   for(size_t stIndex = 0; stIndex < GetSize(); ++stIndex)
-		GetAt(stIndex)->PauseProcessing();
+   BOOST_FOREACH(CTaskPtr& spTask, m_vTasks)
+   {
+      spTask->PauseProcessing();
+   }
 }
 
 void CTaskArray::TasksResumeProcessing()
@@ -1418,32 +1427,36 @@
 
 void CTaskArray::TasksRestartProcessing()
 {
-   for(size_t stIndex = 0; stIndex < GetSize(); ++stIndex)
-		GetAt(stIndex)->RestartProcessing();
+   BOOST_FOREACH(CTaskPtr& spTask, m_vTasks)
+   {
+      spTask->RestartProcessing();
+   }
 }
 
 bool CTaskArray::TasksRetryProcessing(bool bOnlyErrors/*=false*/, UINT uiInterval)
 {
 	bool bChanged=false;
-   for(size_t stIndex = 0; stIndex < GetSize(); ++stIndex)
+   BOOST_FOREACH(CTaskPtr& spTask, m_vTasks)
 	{
-		if (GetAt(stIndex)->RetryProcessing(bOnlyErrors, uiInterval))
-			bChanged=true;
+		if(spTask->RetryProcessing(bOnlyErrors, uiInterval))
+			bChanged = true;
 	}
 
 	return bChanged;
 }
 
 void CTaskArray::TasksCancelProcessing()
 {
-   for(size_t stIndex = 0; stIndex < GetSize(); ++stIndex)
-		GetAt(stIndex)->CancelProcessing();
+   BOOST_FOREACH(CTaskPtr& spTask, m_vTasks)
+   {
+      spTask->CancelProcessing();
+   }
 }
 
 ull_t CTaskArray::GetPosition()
 {
 	m_cs.Lock();
-	ull_t rv=m_uhPosition;
+	ull_t rv = m_uhPosition;
 	m_cs.Unlock();
 
 	return rv;
@@ -1492,9 +1505,9 @@
 		bFlag=false;
 	else
 	{
-      for(size_t stIndex = 0; stIndex < GetSize(); ++stIndex)
+      BOOST_FOREACH(CTaskPtr& spTask, m_vTasks)
 		{
-			uiStatus=GetAt(stIndex)->GetStatus();
+			uiStatus = spTask->GetStatus();
 			bFlag=((uiStatus & ST_STEP_MASK) == ST_FINISHED || (uiStatus & ST_STEP_MASK) == ST_CANCELLED
 				|| (uiStatus & ST_WORKING_MASK) == ST_PAUSED
 				|| ((uiStatus & ST_WORKING_MASK) == ST_ERROR && !GetConfig().get_bool(PP_CMAUTORETRYONERROR)));
Index: src/ch/task.h
===================================================================
diff -u -r678a716a4ed83d5790a407ce60dfcf7d8ca703fa -rf703b71b8c856e2538283555e9fdbc84918677c3
--- src/ch/task.h	(.../task.h)	(revision 678a716a4ed83d5790a407ce60dfcf7d8ca703fa)
+++ src/ch/task.h	(.../task.h)	(revision f703b71b8c856e2538283555e9fdbc84918677c3)
@@ -232,7 +232,7 @@
 class CTask
 {
 public:
-	CTask(chcore::IFeedbackHandler* piFeedbackHandler, const TASK_CREATE_DATA *pCreateData);
+	CTask(chcore::IFeedbackHandler* piFeedbackHandler, const TASK_CREATE_DATA *pCreateData, size_t stSessionUniqueID);
 	~CTask();
 
    int OnBeginTask();
@@ -363,6 +363,8 @@
 	void SetContinueFlag(bool bFlag=true);
 	bool GetContinueFlag();
 
+   size_t GetSessionUniqueID() const { return m_stSessionUniqueID; }
+
 protected:
 	static UINT ThrdProc(LPVOID pParam);
 	static void CheckForWaitState(CTask* pTask);
@@ -435,9 +437,13 @@
 	tstring_t m_strTaskBasePath;	// base path at which the files will be stored
 	bool m_bSaved;		// has the state been saved ('til next modification)
 
+   size_t m_stSessionUniqueID;
+
 	CCriticalSection* m_pcs;	// protects *m_pnTasksProcessed & *m_pnTasksAll from external array
 };
 
+typedef boost::shared_ptr<CTask> CTaskPtr;
+
 ///////////////////////////////////////////////////////////////////////////
 // CProcessingException
 
@@ -460,28 +466,29 @@
 ///////////////////////////////////////////////////////////////////////////
 // CTaskArray
 
-class CTaskArray : public CArray<CTask*, CTask*>
+class CTaskArray// : public CArray<CTask*, CTask*>
 {
 public:
 	CTaskArray();
 	~CTaskArray();
 
 	void Create(chcore::IFeedbackHandlerFactory* piFeedbackHandlerFactory);
 
-	CTask* CreateTask();
+	CTaskPtr CreateTask();
 
-	size_t GetSize( );
-	size_t GetUpperBound( );
-	void SetSize(size_t stNewSize, int nGrowBy = -1);
+	size_t GetSize();
 
-	CTask* GetAt(size_t stIndex);
-	size_t Add(CTask* newElement);
+	CTaskPtr GetAt(size_t stIndex);
+   CTaskPtr GetTaskBySessionUniqueID(size_t stSessionUniqueID);
+	size_t Add(const CTaskPtr& spNewTask);
 
 	void RemoveAt(size_t stIndex, size_t stCount = 1);
 	void RemoveAll();
 	void RemoveAllFinished();
-	void RemoveFinished(CTask** pSelTask);
+	void RemoveFinished(const CTaskPtr& spSelTask);
 
+   void StopAllTasks();
+
 	void SaveData();
 	void SaveProgress();
 	void LoadDataProgress();
@@ -515,6 +522,10 @@
 	CCriticalSection m_cs;
 	TASK_CREATE_DATA m_tcd;
 
+private:
+   std::vector<CTaskPtr> m_vTasks;
+   size_t m_stNextSessionUniqueID;
+
 protected:
 	chcore::IFeedbackHandlerFactory* m_piFeedbackFactory;
 };