Index: src/ch/ClipboardMonitor.cpp
===================================================================
diff -u -r8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f -r3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529
--- src/ch/ClipboardMonitor.cpp	(.../ClipboardMonitor.cpp)	(revision 8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f)
+++ src/ch/ClipboardMonitor.cpp	(.../ClipboardMonitor.cpp)	(revision 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529)
@@ -174,7 +174,7 @@
 				// get dest path
 				CString strData;
 				dlg.GetPath(strData);
-				tTaskDefinition.SetDestinationPath(strData);
+				tTaskDefinition.SetDestinationPath((PCTSTR)strData);
 
 				CTaskPtr spTask = pData->m_pTasks->CreateTask();
 				spTask->SetTaskDefinition(tTaskDefinition);
Fisheye: Tag 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529 refers to a dead (removed) revision in file `src/ch/DestPath.cpp'.
Fisheye: No comparison available.  Pass `N' to diff?
Fisheye: Tag 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529 refers to a dead (removed) revision in file `src/ch/DestPath.h'.
Fisheye: No comparison available.  Pass `N' to diff?
Index: src/ch/FileInfo.cpp
===================================================================
diff -u -rca1933ef07e18d939449e4878eca5cc81cc73f3f -r3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529
--- src/ch/FileInfo.cpp	(.../FileInfo.cpp)	(revision ca1933ef07e18d939449e4878eca5cc81cc73f3f)
+++ src/ch/FileInfo.cpp	(.../FileInfo.cpp)	(revision 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529)
@@ -40,6 +40,46 @@
 #define new DEBUG_NEW
 #endif
 
+void GetDriveData(LPCTSTR lpszPath, int* piDrvNum, UINT* puiDrvType)
+{
+	TCHAR drv[_MAX_DRIVE+1];
+
+	_tsplitpath(lpszPath, drv, NULL, NULL, NULL);
+	if(lstrlen(drv) != 0)
+	{
+		// add '\\'
+		lstrcat(drv, _T("\\"));
+		_tcsupr(drv);
+
+		// disk number
+		if(piDrvNum)
+			*piDrvNum=drv[0]-_T('A');
+
+		// disk type
+		if(puiDrvType)
+		{
+			*puiDrvType=GetDriveType(drv);
+			if(*puiDrvType == DRIVE_NO_ROOT_DIR)
+				*puiDrvType=DRIVE_UNKNOWN;
+		}
+	}
+	else
+	{
+		// there's no disk in a path
+		if(piDrvNum)
+			*piDrvNum=-1;
+
+		if(puiDrvType)
+		{
+			// check for unc path
+			if(_tcsncmp(lpszPath, _T("\\\\"), 2) == 0)
+				*puiDrvType=DRIVE_REMOTE;
+			else
+				*puiDrvType=DRIVE_UNKNOWN;
+		}
+	}
+}
+
 //////////////////////////////////////////////////////////////////////////////
 // CClipboardEntry
 
@@ -81,23 +121,26 @@
 	return m_iDriveNumber;
 }
 
-int CClipboardEntry::GetBufferIndex(const CDestPath& dpDestPath)
+int CClipboardEntry::GetBufferIndex(const chcore::TSmartPath& dpDestPath)
 {
 	if(m_iBufferIndex == -1)
 	{
+		int iDriveNumber = 0;
 		UINT uiDriveType = 0;
-		GetDriveData(m_strPath, NULL, &uiDriveType);
+		int iDstDriveNumber = 0;
+		UINT uiDstDriveType = 0;
+		GetDriveData(m_strPath, &iDriveNumber, &uiDriveType);
+		GetDriveData(dpDestPath, &iDstDriveNumber, &uiDstDriveType);
 
 		// what kind of buffer
-		if(uiDriveType == DRIVE_REMOTE || dpDestPath.GetDriveType() == DRIVE_REMOTE)
+		if(uiDriveType == DRIVE_REMOTE || uiDstDriveType == DRIVE_REMOTE)
 			m_iBufferIndex = BI_LAN;
-		else if(uiDriveType == DRIVE_CDROM || dpDestPath.GetDriveType() == DRIVE_CDROM)
+		else if(uiDriveType == DRIVE_CDROM || uiDstDriveType == DRIVE_CDROM)
 			m_iBufferIndex = BI_CD;
-		else if(uiDriveType == DRIVE_FIXED && dpDestPath.GetDriveType() == DRIVE_FIXED)
+		else if(uiDriveType == DRIVE_FIXED && uiDstDriveType == DRIVE_FIXED)
 		{
-			int iDriveNumber = GetDriveNumber();
 			// two hdd's - is this the same physical disk ?
-			if(iDriveNumber == dpDestPath.GetDriveNumber() || IsSamePhysicalDisk(iDriveNumber, dpDestPath.GetDriveNumber()))
+			if(iDriveNumber == iDstDriveNumber || IsSamePhysicalDisk(iDriveNumber, iDstDriveNumber))
 				m_iBufferIndex = BI_ONEDISK;
 			else
 				m_iBufferIndex = BI_TWODISKS;
@@ -132,18 +175,18 @@
 }
 
 CClipboardArray::CClipboardArray(const CClipboardArray& rSrc) :
-   m_vEntries(rSrc.m_vEntries)
+	m_vEntries(rSrc.m_vEntries)
 {
 }
 
 CClipboardArray& CClipboardArray::operator=(const CClipboardArray& rSrc)
 {
-   if(this != &rSrc)
-   {
-      m_vEntries = rSrc.m_vEntries;
-   }
+	if(this != &rSrc)
+	{
+		m_vEntries = rSrc.m_vEntries;
+	}
 
-   return *this;
+	return *this;
 }
 
 CClipboardEntryPtr CClipboardArray::GetAt(size_t stPos) const
@@ -227,42 +270,32 @@
 // Construction/Destruction
 //////////////////////////////////////////////////////////////////////
 // finds another name for a copy of src file(folder) in dest location
-void FindFreeSubstituteName(CString strSrcPath, CString strDstPath, CString* pstrResult)
+void FindFreeSubstituteName(chcore::TSmartPath pathSrcPath, chcore::TSmartPath pathDstPath, CString* pstrResult)
 {
 	// get the name from srcpath
-	if (strSrcPath.Right(1) == _T("\\"))
-		strSrcPath=strSrcPath.Left(strSrcPath.GetLength()-1);
+	pathSrcPath.CutIfExists(_T("\\"), false);
+	pathDstPath.AppendIfNotExists(_T("\\"), false);
 
-	int iBarPos=strSrcPath.ReverseFind(_T('\\'));
-	CString strFolderName;
-	if (iBarPos != -1)
-		strFolderName=strSrcPath.Mid(iBarPos+1);
-	else
-		strFolderName=strSrcPath;	// it shouldn't happen at all
+	chcore::TSmartPath spLastComponent = pathSrcPath.GetLastComponent(_T("\\"), false);
 
-	if (strDstPath.Right(1) != _T("\\"))
-		strDstPath+=_T("\\");
-
 	// set the dest path
 	CString strCheckPath;
 	ictranslate::CFormat fmt(GetResManager().LoadString(IDS_FIRSTCOPY_STRING));
-	fmt.SetParam(_t("%name"), strFolderName);
-	strCheckPath = fmt;
-	if (strCheckPath.GetLength() > _MAX_PATH)
-		strCheckPath=strCheckPath.Left(_MAX_PATH);	// max - 260 chars
+	fmt.SetParam(_t("%name"), (PCTSTR)spLastComponent);
+	chcore::TSmartPath pathCheckPath((PCTSTR)fmt);
 
 	// when adding to strDstPath check if the path already exists - if so - try again
 	int iCounter=1;
 	CString strFmt = GetResManager().LoadString(IDS_NEXTCOPY_STRING);
-	while (CFileInfo::Exist(strDstPath+strCheckPath))
+	while(CFileInfo::Exist(pathDstPath + pathCheckPath))
 	{
 		fmt.SetFormat(strFmt);
-		fmt.SetParam(_t("%name"), strFolderName);
+		fmt.SetParam(_t("%name"), (PCTSTR)spLastComponent);
 		fmt.SetParam(_t("%count"), ++iCounter);
-		strCheckPath = fmt;
+		pathCheckPath = (PCTSTR)fmt;
 	}
 
-	*pstrResult=strCheckPath;
+	*pstrResult = pathCheckPath;
 }
 
 ////////////////////////////////////////////////////////////////////////////
@@ -296,25 +329,26 @@
 {
 }
 
-bool CFileInfo::Exist(CString strPath)
+bool CFileInfo::Exist(chcore::TSmartPath pathToCheck)
 {
 	WIN32_FIND_DATA fd;
 	
 	// search by exact name
-	HANDLE hFind = FindFirstFile(strPath, &fd);
-	if (hFind != INVALID_HANDLE_VALUE)
+	HANDLE hFind = FindFirstFile(pathToCheck, &fd);
+	if(hFind != INVALID_HANDLE_VALUE)
 		return true;
 
 	// another try (add '\\' if needed and '*' for marking that we look for ie. c:\*
 	// instead of c:\, which would never be found prev. way)
-	if (strPath.Right(1) != _T("\\"))
-		strPath+=_T("\\*");
-	else
-		strPath+=_T("*");
+	pathToCheck.AppendIfNotExists(_T("\\"), false);
+	pathToCheck.AppendIfNotExists(_T("*"), false);
 
-	hFind = FindFirstFile(strPath, &fd);
-	if (hFind != INVALID_HANDLE_VALUE)
+	hFind = FindFirstFile(pathToCheck, &fd);
+	if(hFind != INVALID_HANDLE_VALUE)
+	{
+		::FindClose(hFind);
 		return true;
+	}
 	else
 		return false;
 }
@@ -483,26 +517,25 @@
 		&& rInfo.m_ftLastWrite.dwHighDateTime == m_ftLastWrite.dwHighDateTime && rInfo.m_ftLastWrite.dwLowDateTime == m_ftLastWrite.dwLowDateTime && rInfo.m_uhFileSize == m_uhFileSize);
 }
 
-CString CFileInfo::GetDestinationPath(CString strPath, int iFlags) const
+chcore::TSmartPath CFileInfo::GetDestinationPath(chcore::TSmartPath pathDst, int iFlags) const
 {
 	// add '\\'
-	if (strPath.Right(1) != _T("\\"))
-		strPath+=_T("\\");
+	pathDst.AppendIfNotExists(_T("\\"), false);
 
 	// iFlags: bit 0-ignore folders; bit 1-force creating directories
 	if (iFlags & 0x02)
 	{
 		// force create directories
 		TCHAR dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
 		_tsplitpath(GetFullFilePath(), NULL, dir, fname, ext);
-		
+
 		CString str=dir;
 		str.TrimLeft(_T("\\"));
 
 		// force create directory
-		SHCreateDirectoryEx(NULL, strPath+str, NULL);
+		SHCreateDirectoryEx(NULL, pathDst + str, NULL);
 
-		return strPath+str+fname+CString(ext);
+		return pathDst + chcore::TSmartPath((PCTSTR)str) + chcore::TSmartPath(fname) + chcore::TSmartPath(ext);
 	}
 	else
 	{
@@ -512,15 +545,15 @@
 			if(!m_pClipboard->GetAt(m_stSrcIndex)->IsDestinationPathSet())
 			{
 				CString strNewPath;
-				FindFreeSubstituteName(GetFullFilePath(), strPath, &strNewPath);
+				FindFreeSubstituteName(chcore::TSmartPath((PCTSTR)GetFullFilePath()), pathDst, &strNewPath);
 				m_pClipboard->GetAt(m_stSrcIndex)->SetDestinationPath(strNewPath);
 			}
-			
-			CString strResultPath = strPath+m_pClipboard->GetAt(m_stSrcIndex)->GetDestinationPath()+m_strFilePath;
-			return strResultPath;
+
+			CString strResultPath = pathDst + m_pClipboard->GetAt(m_stSrcIndex)->GetDestinationPath() + m_strFilePath;
+			return chcore::TSmartPath((PCTSTR)strResultPath);
 		}
 		else
-			return strPath+GetFileName();
+			return pathDst + chcore::TSmartPath(GetFileName());
 	}
 }
 
@@ -540,7 +573,7 @@
 	return strPath;
 }
 
-int CFileInfo::GetBufferIndex(const CDestPath& dpDestPath) const
+int CFileInfo::GetBufferIndex(const chcore::TSmartPath& dpDestPath) const
 {
 	if(m_stSrcIndex != std::numeric_limits<size_t>::max())
 		return m_pClipboard->GetAt(m_stSrcIndex)->GetBufferIndex(dpDestPath);
@@ -613,7 +646,7 @@
 	return ullSize;
 }
 
-int CFileInfoArray::GetBufferIndexAt(size_t stIndex, const CDestPath& rDestPath) const
+int CFileInfoArray::GetBufferIndexAt(size_t stIndex, const chcore::TSmartPath& dpDestPath) const
 {
 	boost::shared_lock<boost::shared_mutex> lock(m_lock);
 	if(stIndex >= m_vFiles.size())
@@ -624,7 +657,7 @@
 		if(!spFileInfo)
 			THROW(_T("Invalid pointer"), 0, 0, 0);
 
-		return spFileInfo->GetBufferIndex(rDestPath);
+		return spFileInfo->GetBufferIndex(dpDestPath);
 	}
 }
 
Index: src/ch/FileInfo.h
===================================================================
diff -u -r73b2826b21fdda4cbae36e8a1a7b7d5454ee519c -r3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529
--- src/ch/FileInfo.h	(.../FileInfo.h)	(revision 73b2826b21fdda4cbae36e8a1a7b7d5454ee519c)
+++ src/ch/FileInfo.h	(.../FileInfo.h)	(revision 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529)
@@ -22,10 +22,10 @@
 #ifndef __FILEINFO_H__
 #define __FILEINFO_H__
 
-#include "DestPath.h"
+#include "../libchcore/TPath.h"
 
-void FindFreeSubstituteName(CString strSrcPath, CString strDstPath, CString* pstrResult);
-extern void GetDriveData(LPCTSTR lpszPath, int *piDrvNum, UINT *puiDrvType);
+void FindFreeSubstituteName(chcore::TSmartPath pathSrcPath, chcore::TSmartPath pathDstPath, CString* pstrResult);
+void GetDriveData(LPCTSTR lpszPath, int *piDrvNum, UINT *puiDrvType);
 
 // CFileInfo flags
 // flag stating that file has been processed (used to determine if file can be deleted at the end of copying)
@@ -49,7 +49,7 @@
 
 	int GetDriveNumber();
 
-	int GetBufferIndex(const CDestPath& dpDestPath);
+	int GetBufferIndex(const chcore::TSmartPath& dpDestPath);
 
 	template<class Archive>
 	void Serialize(Archive& ar, unsigned int /*uiVersion*/, bool bData)
@@ -160,7 +160,7 @@
 	~CFileInfo();
 
 	// static member
-	static bool Exist(CString strPath);	// check for file or folder existence
+	static bool Exist(chcore::TSmartPath strPath);	// check for file or folder existence
 
 	void Create(const WIN32_FIND_DATA* pwfd, LPCTSTR pszFilePath, size_t stSrcIndex);
 	bool Create(CString strFilePath, size_t stSrcIndex);
@@ -203,14 +203,14 @@
 
 	// operations
 	void SetClipboard(const CClipboardArray *pClipboard) { m_pClipboard = pClipboard; };
-	CString GetDestinationPath(CString strPath, int iFlags) const;
+	chcore::TSmartPath GetDestinationPath(chcore::TSmartPath strPath, int iFlags) const;
 
 	void SetSrcIndex(size_t stIndex) { m_stSrcIndex = stIndex; };
 	size_t GetSrcIndex() const { return m_stSrcIndex; };
 
 	bool GetMove() const { if (m_stSrcIndex != std::numeric_limits<size_t>::max()) return m_pClipboard->GetAt(m_stSrcIndex)->GetMove(); else return true; };
 
-	int GetBufferIndex(const CDestPath& dpDestPath) const;
+	int GetBufferIndex(const chcore::TSmartPath& dpDestPath) const;
 
 	// operators
 	bool operator==(const CFileInfo& rInfo);
@@ -278,7 +278,7 @@
 	unsigned long long CalculateTotalSize();
 
 	/// Retrieves buffer index for an item at a specified index
-	int GetBufferIndexAt(size_t stIndex, const CDestPath& rDestPath) const;
+	int GetBufferIndexAt(size_t stIndex, const chcore::TSmartPath& dpDestPath) const;
 
 	/// Stores infos about elements in the archive
 	template<class Archive>
Index: src/ch/MainWnd.cpp
===================================================================
diff -u -r8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f -r3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529
--- src/ch/MainWnd.cpp	(.../MainWnd.cpp)	(revision 8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f)
+++ src/ch/MainWnd.cpp	(.../MainWnd.cpp)	(revision 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529)
@@ -497,7 +497,7 @@
 
 	// create new task
 	TTaskDefinition tTaskDefinition;
-	tTaskDefinition.SetDestinationPath(strDstPath);
+	tTaskDefinition.SetDestinationPath((PCTSTR)strDstPath);
 
 	// files
 	for(int i = 0; i < astrFiles.GetSize(); i++)
@@ -589,7 +589,7 @@
 			tTaskDefinition.AddSourcePath(dlg.m_ccData.m_astrPaths.GetAt(iIndex));
 		}
 
-		tTaskDefinition.SetDestinationPath(dlg.m_ccData.m_strDestPath);
+		tTaskDefinition.SetDestinationPath((PCTSTR)dlg.m_ccData.m_strDestPath);
 
 		tTaskDefinition.SetOperationType((dlg.m_ccData.m_iOperation == 1) ? eOperation_Move : eOperation_Copy);
 
Index: src/ch/StatusDlg.cpp
===================================================================
diff -u -r8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f -r3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529
--- src/ch/StatusDlg.cpp	(.../StatusDlg.cpp)	(revision 8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f)
+++ src/ch/StatusDlg.cpp	(.../StatusDlg.cpp)	(revision 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529)
@@ -258,7 +258,7 @@
 
 	// insert 'file' subitem
 	lvi.iSubItem=2;
-	strTemp=td.m_strDstPath;
+	strTemp = (CString)td.m_pathDstPath;
 	lvi.pszText=strTemp.GetBuffer(0);
 	strTemp.ReleaseBuffer();
 	lvi.cchTextMax=lstrlen(lvi.pszText);
@@ -325,7 +325,7 @@
 		// refresh only when there are new selected item
 //		if (spTask != m_spLastSelected)
 		{
-			GetDlgItem(IDC_DESTINATION_STATIC)->SetWindowText(td.m_strDstPath);
+			GetDlgItem(IDC_DESTINATION_STATIC)->SetWindowText(td.m_pathDstPath);
 			GetDlgItem(IDC_PRIORITY_STATIC)->SetWindowText(GetResManager().LoadString(IDS_PRIORITY0_STRING+PriorityToIndex(td.m_nPriority)));
 			GetDlgItem(IDC_ASSOCIATEDFILES__STATIC)->SetWindowText(td.m_strUniqueName);
 		}
Index: src/ch/TConfig.cpp
===================================================================
diff -u -r8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f -r3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529
--- src/ch/TConfig.cpp	(.../TConfig.cpp)	(revision 8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f)
+++ src/ch/TConfig.cpp	(.../TConfig.cpp)	(revision 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529)
@@ -360,6 +360,31 @@
 	return *this;
 }
 
+chcore::TSmartPath TConfig::GetPath(PCTSTR pszPropName, const chcore::TSmartPath& pathDefault) const
+{
+	boost::shared_lock<boost::shared_mutex> lock(m_lock);
+	std::wstring wstrData = m_propTree.get<std::wstring>(pszPropName, std::wstring(pathDefault));
+	return chcore::TSmartPath(wstrData);
+}
+
+bool TConfig::GetValue(PCTSTR pszPropName, chcore::TSmartPath& rpathValue) const
+{
+	std::wstring wstrData;
+	bool bResult = ::GetValue<std::wstring>(m_propTree, pszPropName, wstrData, m_lock);
+	rpathValue = wstrData.c_str();
+
+	return bResult;
+}
+
+TConfig& TConfig::SetValue(PCTSTR pszPropName, const chcore::TSmartPath& pathValue)
+{
+	std::wstring wstrData = pathValue;
+	if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, wstrData))
+		SendNotification(pszPropName);
+
+	return *this;
+}
+
 bool TConfig::GetValue(PCTSTR pszPropName, std::vector<CString>& rvValues) const
 {
 	boost::shared_lock<boost::shared_mutex> lock(m_lock);
Index: src/ch/TConfig.h
===================================================================
diff -u -rca046f75806db6693a4b2dc6ddb255f76d0bbc3f -r3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529
--- src/ch/TConfig.h	(.../TConfig.h)	(revision ca046f75806db6693a4b2dc6ddb255f76d0bbc3f)
+++ src/ch/TConfig.h	(.../TConfig.h)	(revision 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529)
@@ -23,6 +23,8 @@
 #ifndef __TCONFIG_H__
 #define __TCONFIG_H__
 
+#include "../libchcore/TPath.h"
+
 #pragma warning(push)
 #pragma warning(disable: 4100 4702)
 #include <boost/property_tree/ptree.hpp>
@@ -99,6 +101,10 @@
 	bool GetValue(PCTSTR pszPropName, CString& rstrValue) const;
 	TConfig& SetValue(PCTSTR pszPropName, const CString& strValue);
 
+	chcore::TSmartPath GetPath(PCTSTR pszPropName, const chcore::TSmartPath& pathDefault) const;
+	bool GetValue(PCTSTR pszPropName, chcore::TSmartPath& rpathValue) const;
+	TConfig& SetValue(PCTSTR pszPropName, const chcore::TSmartPath& strValue);
+
 	bool GetValue(PCTSTR pszPropName, std::vector<CString>& rvValues) const;
 	void SetValue(PCTSTR pszPropName, const std::vector<CString>& rvValues);
 
Index: src/ch/TSubTaskContext.cpp
===================================================================
diff -u -rb7709acbab26fdb108b77d3e08d3872f54248af2 -r3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529
--- src/ch/TSubTaskContext.cpp	(.../TSubTaskContext.cpp)	(revision b7709acbab26fdb108b77d3e08d3872f54248af2)
+++ src/ch/TSubTaskContext.cpp	(.../TSubTaskContext.cpp)	(revision 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529)
@@ -23,11 +23,9 @@
 #include "stdafx.h"
 #include "TSubTaskContext.h"
 
-TSubTaskContext::TSubTaskContext(CClipboardArray& rSourcePaths, const CDestPath& rDestinationPath, TTaskConfiguration& rConfig) :
-	m_rSourcePaths(rSourcePaths),
-	m_rPathDestination(rDestinationPath),
-	m_rConfig(rConfig),
-	m_tFiles(rSourcePaths)
+TSubTaskContext::TSubTaskContext(TTaskDefinition& rTaskDefinition, CFileInfoArray& rFilesCache) :
+	m_rTaskDefinition(rTaskDefinition),
+	m_rFilesCache(rFilesCache)
 {
 }
 
Index: src/ch/TSubTaskContext.h
===================================================================
diff -u -rb7709acbab26fdb108b77d3e08d3872f54248af2 -r3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529
--- src/ch/TSubTaskContext.h	(.../TSubTaskContext.h)	(revision b7709acbab26fdb108b77d3e08d3872f54248af2)
+++ src/ch/TSubTaskContext.h	(.../TSubTaskContext.h)	(revision 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529)
@@ -25,29 +25,22 @@
 
 #include "FileInfo.h"
 
-class CClipboardArray;
-class CDestPath;
-class TTaskConfiguration;
+class TTaskDefinition;
 
 ///////////////////////////////////////////////////////////////////////////
 // TSubTaskContext
 
 class TSubTaskContext
 {
 public:
-	TSubTaskContext(CClipboardArray& rSourcePaths, const CDestPath& rDestinationPath, TTaskConfiguration& rConfig);
+	TSubTaskContext(TTaskDefinition& rTaskDefinition, CFileInfoArray& rFilesCache);
 	~TSubTaskContext();
 
 private:
-	// input data
-	CClipboardArray& m_rSourcePaths;			///< Contains source paths to be processed
-	const CDestPath& m_rPathDestination;			///< Contains destination path for the data to be processed to
+	TTaskDefinition& m_rTaskDefinition;
 
-	// configuration data
-	TTaskConfiguration& m_rConfig;
-
 	// data on which to operate
-	CFileInfoArray m_tFiles;
+	CFileInfoArray& m_rFilesCache;
 };
 
 
Index: src/ch/TTaskDefinition.cpp
===================================================================
diff -u -rca046f75806db6693a4b2dc6ddb255f76d0bbc3f -r3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529
--- src/ch/TTaskDefinition.cpp	(.../TTaskDefinition.cpp)	(revision ca046f75806db6693a4b2dc6ddb255f76d0bbc3f)
+++ src/ch/TTaskDefinition.cpp	(.../TTaskDefinition.cpp)	(revision 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529)
@@ -39,7 +39,7 @@
 TTaskDefinition::TTaskDefinition(const TTaskDefinition& rSrc) :
 	m_strTaskUniqueID(rSrc.m_strTaskUniqueID),
 	m_vSourcePaths(rSrc.m_vSourcePaths),
-	m_strDestinationPath(rSrc.m_strDestinationPath),
+	m_pathDestinationPath(rSrc.m_pathDestinationPath),
 	m_tOperationPlan(rSrc.m_tOperationPlan),
 	m_tConfiguration(rSrc.m_tConfiguration),
 	m_bModified(rSrc.m_bModified)
@@ -56,7 +56,7 @@
 	{
 		m_strTaskUniqueID = rSrc.m_strTaskUniqueID;
 		m_vSourcePaths = rSrc.m_vSourcePaths;
-		m_strDestinationPath = rSrc.m_strDestinationPath;
+		m_pathDestinationPath = rSrc.m_pathDestinationPath;
 		m_tOperationPlan = rSrc.m_tOperationPlan;
 		m_tConfiguration = rSrc.m_tConfiguration;
 		m_bModified = rSrc.m_bModified;
@@ -101,17 +101,16 @@
 }
 
 // Destination path
-void TTaskDefinition::SetDestinationPath(const CString& strPath)
+void TTaskDefinition::SetDestinationPath(const chcore::TSmartPath& pathDestination)
 {
-	m_strDestinationPath = strPath;
-	if(m_strDestinationPath.Right(1) != _T("\\"))
-		m_strDestinationPath += _T("\\");
+	m_pathDestinationPath = pathDestination;
+	m_pathDestinationPath.AppendIfNotExists(_T("\\"), false);
 	m_bModified = true;
 }
 
-CString TTaskDefinition::GetDestinationPath() const
+chcore::TSmartPath TTaskDefinition::GetDestinationPath() const
 {
-	return m_strDestinationPath;
+	return m_pathDestinationPath;
 }
 
 // Operation type
@@ -158,7 +157,7 @@
 	// clear everything
 	m_strTaskUniqueID.Empty();
 	m_vSourcePaths.clear();
-	m_strDestinationPath.Empty();
+	m_pathDestinationPath.Clear();
 
 	m_tConfiguration.Clear();
 
@@ -177,17 +176,16 @@
 
 	// basic information
 	if(!tTaskInfo.GetValue(_T("TaskDefinition.SourcePaths"), m_vSourcePaths) || m_vSourcePaths.empty())
-       THROW(_T("Missing source paths"), 0, 0, 0);
+		THROW(_T("Missing source paths"), 0, 0, 0);
 
-	if(!tTaskInfo.GetValue(_T("TaskDefinition.DestinationPath"), m_strDestinationPath) || m_strDestinationPath.IsEmpty())
-       THROW(_T("Missing destination path"), 0, 0, 0);
+	if(!tTaskInfo.GetValue(_T("TaskDefinition.DestinationPath"), m_pathDestinationPath) || m_pathDestinationPath.IsEmpty())
+		THROW(_T("Missing destination path"), 0, 0, 0);
 
-	if(m_strDestinationPath.Right(1) != _T("\\"))
-		m_strDestinationPath += _T("\\");
+	m_pathDestinationPath.AppendIfNotExists(_T("\\"), false);
 
 	int iOperation = eOperation_None;
 	if(!tTaskInfo.GetValue(_T("TaskDefinition.OperationType"), iOperation))
-       THROW(_T("Missing operation type"), 0, 0, 0);
+		THROW(_T("Missing operation type"), 0, 0, 0);
 
 	m_tOperationPlan.SetOperationType((EOperationType)iOperation);
 
@@ -208,7 +206,7 @@
 
 		// basic information
 		tTaskInfo.SetValue(_T("TaskDefinition.SourcePaths.Path"), m_vSourcePaths);
-		tTaskInfo.SetValue(_T("TaskDefinition.DestinationPath"), m_strDestinationPath);
+		tTaskInfo.SetValue(_T("TaskDefinition.DestinationPath"), m_pathDestinationPath);
 
 		int iOperation = m_tOperationPlan.GetOperationType();
 		tTaskInfo.SetValue(_T("TaskDefinition.OperationType"), iOperation);
Index: src/ch/TTaskDefinition.h
===================================================================
diff -u -r1d7d79169d480a02e335b8b0a4919f9c78d58325 -r3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529
--- src/ch/TTaskDefinition.h	(.../TTaskDefinition.h)	(revision 1d7d79169d480a02e335b8b0a4919f9c78d58325)
+++ src/ch/TTaskDefinition.h	(.../TTaskDefinition.h)	(revision 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529)
@@ -51,8 +51,8 @@
 	void ClearSourcePaths();
 
 	// Destination path
-	void SetDestinationPath(const CString& strPath);
-	CString GetDestinationPath() const;
+	void SetDestinationPath(const chcore::TSmartPath& pathDestination);
+	chcore::TSmartPath GetDestinationPath() const;
 
 	// Operation type
 	void SetOperationType(EOperationType eOperation);
@@ -73,7 +73,7 @@
 
 	// basic information
 	std::vector<CString> m_vSourcePaths;
-	CString m_strDestinationPath;
+	chcore::TSmartPath m_pathDestinationPath;
 
 	TOperationPlan m_tOperationPlan;			///< Describes the operation along with sub-operations to be performed on the task input data
 
Index: src/ch/ch.vc90.vcproj
===================================================================
diff -u -rca046f75806db6693a4b2dc6ddb255f76d0bbc3f -r3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529
--- src/ch/ch.vc90.vcproj	(.../ch.vc90.vcproj)	(revision ca046f75806db6693a4b2dc6ddb255f76d0bbc3f)
+++ src/ch/ch.vc90.vcproj	(.../ch.vc90.vcproj)	(revision 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="windows-1250"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="9.00"
+	Version="9,00"
 	Name="ch"
 	ProjectGUID="{4B215B9A-58CA-4987-AC95-7DFC3043E100}"
 	RootNamespace="ch"
@@ -415,14 +415,6 @@
 					>
 				</File>
 				<File
-					RelativePath="DestPath.cpp"
-					>
-				</File>
-				<File
-					RelativePath="DestPath.h"
-					>
-				</File>
-				<File
 					RelativePath="Device IO.h"
 					>
 				</File>
Index: src/ch/task.cpp
===================================================================
diff -u -r8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f -r3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529
--- src/ch/task.cpp	(.../task.cpp)	(revision 8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f)
+++ src/ch/task.cpp	(.../task.cpp)	(revision 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529)
@@ -29,6 +29,7 @@
 #include "FeedbackHandler.h"
 
 #include "TTaskConfiguration.h"
+#include "TSubTaskContext.h"
 
 // assume max sectors of 4kB (for rounding)
 #define MAXSECTORSIZE			4096
@@ -449,7 +450,6 @@
 
 		m_arrSourcePaths.Add(spEntry);
 	}
-	m_tDestinationPath.SetPath(m_tTaskDefinition.GetDestinationPath());
 }
 
 void CTask::OnRegisterTask(TTasksGlobalStats& rtGlobalStats)
@@ -556,7 +556,7 @@
 
 int CTask::GetCurrentBufferIndex()
 {
-	return m_files.GetBufferIndexAt(m_tTaskBasicProgressInfo.GetCurrentIndex(), m_tDestinationPath);
+	return m_files.GetBufferIndexAt(m_tTaskBasicProgressInfo.GetCurrentIndex(), m_tTaskDefinition.GetDestinationPath());
 }
 
 // thread
@@ -834,7 +834,7 @@
 	}
 
 	pData->m_nPriority = GetTaskPropValue<eTO_ThreadPriority>(m_tTaskDefinition.GetConfiguration());
-	pData->m_strDstPath = m_tTaskDefinition.GetDestinationPath();
+	pData->m_pathDstPath = m_tTaskDefinition.GetDestinationPath();
 	pData->m_pafFilters=&m_afFilters;
 	pData->m_eTaskState = m_eCurrentState;
 	pData->m_stIndex = stCurrentIndex;
@@ -849,7 +849,7 @@
 	pData->m_bCreateEmptyFiles = GetTaskPropValue<eTO_CreateEmptyFiles>(m_tTaskDefinition.GetConfiguration());
 
 	if(m_files.GetSize() > 0)
-		pData->m_iCurrentBufferIndex = GetTaskPropValue<eTO_UseOnlyDefaultBuffer>(m_tTaskDefinition.GetConfiguration()) ? 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_tTaskDefinition.GetDestinationPath());
 	else
 		pData->m_iCurrentBufferIndex = 0;
 
@@ -1052,7 +1052,9 @@
 	m_files.Clear();
 
 	// enter some data to m_files
-	int iDestDrvNumber = m_tDestinationPath.GetDriveNumber();
+	int iDestDrvNumber = 0;
+	GetDriveData(m_tTaskDefinition.GetDestinationPath(), &iDestDrvNumber, NULL);
+
 	bool bIgnoreDirs = GetTaskPropValue<eTO_IgnoreDirectories>(m_tTaskDefinition.GetConfiguration());
 	bool bForceDirectories = GetTaskPropValue<eTO_CreateDirectoriesRelativeToRoot>(m_tTaskDefinition.GetConfiguration());
 	bool bMove = m_tTaskDefinition.GetOperationType() == eOperation_Move;
@@ -1123,10 +1125,10 @@
 		if(!m_arrSourcePaths.GetAt(stIndex)->IsDestinationPathSet())
 		{
 			// generate something - if dest folder == src folder - search for copy
-			if(m_tTaskDefinition.GetDestinationPath() == spFileInfo->GetFileRoot())
+			if((CString)m_tTaskDefinition.GetDestinationPath() == spFileInfo->GetFileRoot())
 			{
 				CString strSubst;
-				FindFreeSubstituteName(spFileInfo->GetFullFilePath(), m_tTaskDefinition.GetDestinationPath(), &strSubst);
+				FindFreeSubstituteName(chcore::TSmartPath((PCTSTR)spFileInfo->GetFullFilePath()), m_tTaskDefinition.GetDestinationPath(), &strSubst);
 				m_arrSourcePaths.GetAt(stIndex)->SetDestinationPath(strSubst);
 			}
 			else
@@ -1928,7 +1930,7 @@
 			if(GetTaskPropValue<eTO_UseOnlyDefaultBuffer>(m_tTaskDefinition.GetConfiguration()))
 				iBufferIndex = BI_DEFAULT;
 			else
-				iBufferIndex = pData->spSrcFile->GetBufferIndex(m_tDestinationPath);
+				iBufferIndex = pData->spSrcFile->GetBufferIndex(m_tTaskDefinition.GetDestinationPath());
 
 			ulToRead = bNoBuffer ? ROUNDUP(pData->dbBuffer.GetSizes()->m_auiSizes[iBufferIndex], MAXSECTORSIZE) : pData->dbBuffer.GetSizes()->m_auiSizes[iBufferIndex];
 
@@ -2075,7 +2077,6 @@
 	bs.m_uiLANSize = GetTaskPropValue<eTO_LANBufferSize>(m_tTaskDefinition.GetConfiguration());
 
 	ccp.dbBuffer.Create(&bs);
-	ccp.pDestPath = &m_tDestinationPath;
 
 	// helpers
 	DWORD dwLastError = 0;
@@ -2093,7 +2094,7 @@
 	fmt.SetParam(_t("%lansize"), pbs->m_uiLANSize);
 	fmt.SetParam(_t("%filecount"), stSize);
 	fmt.SetParam(_t("%ignorefolders"), bIgnoreFolders);
-	fmt.SetParam(_t("%dstpath"), m_tDestinationPath.GetPath());
+	fmt.SetParam(_t("%dstpath"), (PCTSTR)m_tTaskDefinition.GetDestinationPath());
 	fmt.SetParam(_t("%currindex"), m_tTaskBasicProgressInfo.GetCurrentIndex());
 
 	m_log.logi(fmt);
@@ -2112,11 +2113,14 @@
 		CFileInfoPtr spFileInfo = m_files.GetAt(m_tTaskBasicProgressInfo.GetCurrentIndex());
 
 		// set dest path with filename
-		ccp.strDstFile = spFileInfo->GetDestinationPath(m_tDestinationPath.GetPath(), ((int)bForceDirectories) << 1 | (int)bIgnoreFolders);
+		ccp.strDstFile = spFileInfo->GetDestinationPath((PCTSTR)m_tTaskDefinition.GetDestinationPath(), ((int)bForceDirectories) << 1 | (int)bIgnoreFolders);
 
 		// are the files/folders lie on the same partition ?
+		int iDstDriveNumber = 0;
 		bool bMove = m_tTaskDefinition.GetOperationType() == eOperation_Move;
-		if(bMove && m_tDestinationPath.GetDriveNumber() != -1 && m_tDestinationPath.GetDriveNumber() == spFileInfo->GetDriveNumber() && spFileInfo->GetMove())
+		if(bMove)
+			GetDriveData(m_tTaskDefinition.GetDestinationPath(), &iDstDriveNumber, NULL);
+		if(bMove && iDstDriveNumber != -1 && iDstDriveNumber == spFileInfo->GetDriveNumber() && spFileInfo->GetMove())
 		{
 			bool bRetry = true;
 			if(bRetry && !MoveFile(spFileInfo->GetFullFilePath(), ccp.strDstFile))
Index: src/ch/task.h
===================================================================
diff -u -r8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f -r3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529
--- src/ch/task.h	(.../task.h)	(revision 8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f)
+++ src/ch/task.h	(.../task.h)	(revision 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529)
@@ -25,7 +25,6 @@
 #include "DataBuffer.h"
 #include "../libchcore/FeedbackHandlerBase.h"
 #include "FileFilter.h"
-#include "DestPath.h"
 #include "TTaskDefinition.h"
 #include "TTaskConfigTracker.h"
 
@@ -58,7 +57,7 @@
 	size_t m_stIndex;
 	size_t m_stSize;
 
-	CString m_strDstPath;
+	chcore::TSmartPath m_pathDstPath;
 	CFiltersArray* m_pafFilters;
 
 	ETaskCurrentState m_eTaskState;
@@ -92,7 +91,6 @@
 {
 	CFileInfoPtr spSrcFile;		// CFileInfo - src file
 	CString strDstFile;			// dest path with filename
-	const CDestPath* pDestPath;
 
 	CDataBuffer dbBuffer;		// buffer handling
 	bool bOnlyCreate;			// flag from configuration - skips real copying - only create
@@ -402,7 +400,6 @@
 	TTaskConfigTracker m_cfgTracker;
 
 	CClipboardArray m_arrSourcePaths;
-	CDestPath m_tDestinationPath;
 
 	// task settings
 	CFiltersArray m_afFilters;          // filtering settings for files (will be filtered according to the rules inside when searching for files)
Index: src/libchcore/TPath.cpp
===================================================================
diff -u -r39db7f4bffdd185122d8dab0772bd6fc49a0b675 -r3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529
--- src/libchcore/TPath.cpp	(.../TPath.cpp)	(revision 39db7f4bffdd185122d8dab0772bd6fc49a0b675)
+++ src/libchcore/TPath.cpp	(.../TPath.cpp)	(revision 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529)
@@ -35,6 +35,18 @@
 }
 
 // ============================================================================
+/// TPath::TPath
+/// @date 2009/11/29
+///
+/// @brief     Constructs the TPath object.
+// ============================================================================
+TPath::TPath(const TPath& rSrc) :
+	m_strPath(rSrc.m_strPath),
+	m_lRefCount(1)
+{
+}
+
+// ============================================================================
 /// TPath::~TPath
 /// @date 2009/11/29
 ///
@@ -74,6 +86,18 @@
 }
 
 // ============================================================================
+/// TPath::New
+/// @date 2010/10/07
+///
+/// @brief     Clones this object.
+/// @return    Pointer to the newly allocated object.
+// ============================================================================
+TPath* TPath::Clone()
+{
+	return new TPath(*this);
+}
+
+// ============================================================================
 /// TPath::Delete
 /// @date 2009/11/29
 ///
@@ -104,8 +128,9 @@
 /// @param[in] strPath - string containing a path.
 // ============================================================================
 TSmartPath::TSmartPath(const tstring_t& strPath) :
-	m_pPath(TPath::New())
+	m_pPath(NULL)
 {
+	m_pPath = TPath::New();
 	if(m_pPath)
 		m_pPath->m_strPath = strPath;
 }
@@ -118,8 +143,9 @@
 /// @param[in] pszPath - string with path.
 // ============================================================================
 TSmartPath::TSmartPath(const tchar_t* pszPath) :
-	m_pPath(TPath::New())
+	m_pPath(NULL)
 {
+	m_pPath = TPath::New();
 	if(m_pPath)
 		m_pPath->m_strPath = pszPath;
 }
@@ -134,6 +160,8 @@
 TSmartPath::TSmartPath(const TSmartPath& spPath) :
 	m_pPath(spPath.m_pPath)
 {
+	if(m_pPath)
+		m_pPath->AddRef();
 }
 
 // ============================================================================
@@ -173,15 +201,7 @@
 // ============================================================================
 TSmartPath& TSmartPath::operator=(const tstring_t& strPath)
 {
-	// can we get exclusive access to the member?
-	// if not, clear this object
-	if(m_pPath && m_pPath->IsShared())
-		Clear();
-
-	// create new internal path if does not exist
-	if(!m_pPath)
-		m_pPath = TPath::New();
-
+	PrepareToWrite();
 	m_pPath->m_strPath = strPath;
 
 	return *this;
@@ -197,15 +217,7 @@
 // ============================================================================
 TSmartPath& TSmartPath::operator=(const tchar_t* pszPath)
 {
-	// can we get exclusive access to the member?
-	// if not, clear this object
-	if(m_pPath && m_pPath->IsShared())
-		Clear();
-
-	// create new internal path if does not exist
-	if(!m_pPath)
-		m_pPath = TPath::New();
-
+	PrepareToWrite();
 	m_pPath->m_strPath = pszPath;
 
 	return *this;
@@ -315,27 +327,21 @@
 	// if there is no path inside rPath, then there is no point in doing anything
 	if(rPath.m_pPath)
 	{
-		// can we use this object exclusively?
-		if(m_pPath && m_pPath->IsShared())
-			Clear();
-
-		if(!m_pPath)
-			m_pPath = TPath::New();
-
+		PrepareToWrite();
 		m_pPath->m_strPath += rPath.m_pPath->m_strPath;
 	}
 
 	return *this;
 }
 
 // ============================================================================
-/// TSmartPath::operator tstring_t
+/// TSmartPath::operator const tstring_t
 /// @date 2009/11/29
 ///
-/// @brief     
-/// @return    
+/// @brief     Casts this path object to string
+/// @return    String with path.
 // ============================================================================
-TSmartPath::operator tstring_t() const
+TSmartPath::operator const tstring_t() const
 {
 	tstring_t strPath;
 	if(m_pPath)
@@ -387,6 +393,106 @@
 }
 
 // ============================================================================
+/// TSmartPath::AppendIfNotExists
+/// @date 2009/11/29
+///
+/// @brief     Appends a specified suffix if not present.
+/// @param[in] pszPostfix - string to check against.
+// ============================================================================
+void TSmartPath::AppendIfNotExists(const wchar_t* pszPostfix, bool bCaseSensitive)
+{
+	BOOST_ASSERT(pszPostfix);
+	if(!pszPostfix)
+		return;
+
+	bool bEndsWith = false;
+	if(bCaseSensitive)
+		bEndsWith = m_pPath && boost::ends_with(m_pPath->m_strPath, pszPostfix);
+	else
+		bEndsWith = m_pPath && boost::iends_with(m_pPath->m_strPath, pszPostfix);
+
+	if(!bEndsWith)
+	{
+		PrepareToWrite();
+		m_pPath->m_strPath += pszPostfix;
+	}
+}
+
+// ============================================================================
+/// TSmartPath::CutIfExists
+/// @date 2010/10/07
+///
+/// @brief     Cuts a specified suffix if present.
+/// @param[in] pszPostfix - string to check against.
+// ============================================================================
+void TSmartPath::CutIfExists(const wchar_t* pszPostfix, bool bCaseSensitive)
+{
+	BOOST_ASSERT(pszPostfix);
+	if(!pszPostfix)
+		return;
+
+	bool bEndsWith = false;
+	if(bCaseSensitive)
+		bEndsWith = m_pPath && boost::ends_with(m_pPath->m_strPath, pszPostfix);
+	else
+		bEndsWith = m_pPath && boost::iends_with(m_pPath->m_strPath, pszPostfix);
+
+	if(bEndsWith)
+	{
+		PrepareToWrite();
+		m_pPath->m_strPath.erase(m_pPath->m_strPath.end() - _tcslen(pszPostfix), m_pPath->m_strPath.end());
+	}
+}
+
+TSmartPath TSmartPath::GetLastComponent(const wchar_t* pszSeparator, bool bCaseSensitive)
+{
+	if(!m_pPath)
+		return TSmartPath();
+
+	boost::iterator_range<std::wstring::iterator> rangeIter;
+	if(bCaseSensitive)
+		rangeIter = boost::find_last(m_pPath->m_strPath, pszSeparator);
+	else
+		rangeIter = boost::ifind_last(m_pPath->m_strPath, pszSeparator);
+
+	std::wstring wstrData;
+	wstrData.insert(wstrData.end(), rangeIter.end(), m_pPath->m_strPath.end());
+
+	return TSmartPath(wstrData);
+}
+
+// ============================================================================
+/// TSmartPath::IsEmpty
+/// @date 2010/10/07
+///
+/// @brief     Prepares the path to be written to.
+// ============================================================================
+bool TSmartPath::IsEmpty() const
+{
+	return !m_pPath || m_pPath->m_strPath.empty();
+}
+
+// ============================================================================
+/// TSmartPath::AppendIfNotExists
+/// @date 2009/11/29
+///
+/// @brief     Prepares the path to be written to.
+// ============================================================================
+void TSmartPath::PrepareToWrite()
+{
+	if(m_pPath && m_pPath->IsShared())
+	{
+		TPath* pPath = m_pPath->Clone();
+		Clear();
+		m_pPath = pPath;
+	}
+
+	// create new internal path if does not exist
+	if(!m_pPath)
+		m_pPath = TPath::New();
+}
+
+// ============================================================================
 /// TPathContainer::TPathContainer
 /// @date 2009/11/30
 ///
Index: src/libchcore/TPath.h
===================================================================
diff -u -r39db7f4bffdd185122d8dab0772bd6fc49a0b675 -r3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529
--- src/libchcore/TPath.h	(.../TPath.h)	(revision 39db7f4bffdd185122d8dab0772bd6fc49a0b675)
+++ src/libchcore/TPath.h	(.../TPath.h)	(revision 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529)
@@ -27,6 +27,7 @@
 {
 public:
 	TPath();
+	TPath(const TPath& rSrc);
 	~TPath();
 
 	long AddRef() { return ++m_lRefCount; }
@@ -35,6 +36,7 @@
 
 protected:
 	static TPath* New();
+	TPath* Clone();
 	static void Delete(TPath* pPath);
 
 protected:
@@ -67,12 +69,30 @@
 	TSmartPath operator+(const TSmartPath& rPath) const;
 	TSmartPath& operator+=(const TSmartPath& rPath);
 
-	operator tstring_t() const;
+	operator const tstring_t() const;
 
+	operator const wchar_t*() const
+	{
+		if(m_pPath)
+			return m_pPath->m_strPath.c_str();
+
+		return NULL;
+	}
+
 	bool Compare(const TSmartPath& rPath, bool bCaseSensitive) const;
 	bool IsChildOf(const TSmartPath& rPath, bool bCaseSensitive) const;
 
+	void AppendIfNotExists(const wchar_t* pszPostfix, bool bCaseSensitive);
+	void CutIfExists(const wchar_t* pszPostfix, bool bCaseSensitive);
+
+	TSmartPath GetLastComponent(const wchar_t* pszSeparator, bool bCaseSensitive);
+
+	bool IsEmpty() const;
+
 protected:
+	void PrepareToWrite();
+
+protected:
 	TPath* m_pPath;
 };