Index: src/ch/TLocalFilesystem.cpp
===================================================================
diff -u -ra3800c2f65fa66354e072b34c9e9970af49236b6 -r886c32a98f09ae8dc24ceb6b27e5c8a75104954e
--- src/ch/TLocalFilesystem.cpp	(.../TLocalFilesystem.cpp)	(revision a3800c2f65fa66354e072b34c9e9970af49236b6)
+++ src/ch/TLocalFilesystem.cpp	(.../TLocalFilesystem.cpp)	(revision 886c32a98f09ae8dc24ceb6b27e5c8a75104954e)
@@ -26,44 +26,52 @@
 #include "FileInfo.h"
 #include "..\Common\FileSupport.h"
 #include "DataBuffer.h"
+#include <boost\algorithm\string\case_conv.hpp>
 
 void TLocalFilesystem::GetDriveData(const chcore::TSmartPath& spPath, int* piDrvNum, UINT* puiDrvType)
 {
-	TCHAR drv[_MAX_DRIVE + 1];
+	chcore::TSmartPath pathDrive = spPath.GetDrive();
 
-	_tsplitpath(spPath.ToString(), drv, NULL, NULL, NULL);
-	if(lstrlen(drv) != 0)
+	if(!spPath.IsNetworkPath())
 	{
-		// add '\\'
-		lstrcat(drv, _T("\\"));
-		_tcsupr(drv);
+		std::wstring wstrDrive = spPath.ToWString();
 
-		// disk number
-		if(piDrvNum)
-			*piDrvNum=drv[0]-_T('A');
+		if(wstrDrive.empty())
+		{
+			if(piDrvNum)
+				*piDrvNum = -1;
 
-		// disk type
-		if(puiDrvType)
+			if(puiDrvType)
+				*puiDrvType = DRIVE_UNKNOWN;
+		}
+		else
 		{
-			*puiDrvType=GetDriveType(drv);
-			if(*puiDrvType == DRIVE_NO_ROOT_DIR)
-				*puiDrvType=DRIVE_UNKNOWN;
+			// disk number
+			if(piDrvNum)
+			{
+				boost::to_upper(wstrDrive);
+				*piDrvNum = wstrDrive.at(0) - _T('A');
+			}
+
+			// disk type
+			if(puiDrvType)
+			{
+				pathDrive.AppendSeparatorIfDoesNotExist();
+
+				*puiDrvType = GetDriveType(pathDrive.ToString());
+				if(*puiDrvType == DRIVE_NO_ROOT_DIR)
+					*puiDrvType = DRIVE_UNKNOWN;
+			}
 		}
 	}
 	else
 	{
-		// there's no disk in a path
+		// network path
 		if(piDrvNum)
-			*piDrvNum=-1;
+			*piDrvNum = -1;
 
 		if(puiDrvType)
-		{
-			// check for unc path
-			if(_tcsncmp(spPath.ToString(), _T("\\\\"), 2) == 0)
-				*puiDrvType=DRIVE_REMOTE;
-			else
-				*puiDrvType=DRIVE_UNKNOWN;
-		}
+			*puiDrvType = DRIVE_REMOTE;
 	}
 }
 
@@ -112,9 +120,31 @@
 	return ::SetFileAttributes(PrependPathExtensionIfNeeded(pathFileDir).ToString(), dwAttributes) != FALSE;
 }
 
-bool TLocalFilesystem::CreateDirectory(const chcore::TSmartPath& pathDirectory)
+bool TLocalFilesystem::CreateDirectory(const chcore::TSmartPath& pathDirectory, bool bCreateFullPath)
 {
-	return ::CreateDirectory(PrependPathExtensionIfNeeded(pathDirectory).ToString(), NULL) != FALSE;
+	if(!bCreateFullPath)
+		return ::CreateDirectory(PrependPathExtensionIfNeeded(pathDirectory).ToString(), NULL) != FALSE;
+	else
+	{
+		std::vector<chcore::TSmartPath> vComponents;
+		pathDirectory.SplitPath(vComponents);
+
+		chcore::TSmartPath pathToTest;
+		BOOST_FOREACH(const chcore::TSmartPath& pathComponent, vComponents)
+		{
+			pathToTest += pathComponent;
+			// try to create subsequent paths
+			if(!pathToTest.IsDrive() && !pathToTest.IsServerName())
+			{
+				// try to create the specified path
+				BOOL bRes = ::CreateDirectory(PrependPathExtensionIfNeeded(pathToTest).ToString(), NULL);
+				if(!bRes && GetLastError() != ERROR_ALREADY_EXISTS)
+					return false;
+			}
+		}
+	}
+
+	return true;
 }
 
 bool TLocalFilesystem::RemoveDirectory(const chcore::TSmartPath& pathFile)
Index: src/ch/TLocalFilesystem.h
===================================================================
diff -u -ra3800c2f65fa66354e072b34c9e9970af49236b6 -r886c32a98f09ae8dc24ceb6b27e5c8a75104954e
--- src/ch/TLocalFilesystem.h	(.../TLocalFilesystem.h)	(revision a3800c2f65fa66354e072b34c9e9970af49236b6)
+++ src/ch/TLocalFilesystem.h	(.../TLocalFilesystem.h)	(revision 886c32a98f09ae8dc24ceb6b27e5c8a75104954e)
@@ -42,7 +42,7 @@
 	static bool SetFileDirectoryTime(const chcore::TSmartPath& pathFileDir, const FILETIME& ftCreationTime, const FILETIME& ftLastAccessTime, const FILETIME& ftLastWriteTime);
 	static bool SetAttributes(const chcore::TSmartPath& pathFileDir, DWORD dwAttributes);
 
-	static bool CreateDirectory(const chcore::TSmartPath& pathDirectory);
+	static bool CreateDirectory(const chcore::TSmartPath& pathDirectory, bool bCreateFullPath);
 	static bool RemoveDirectory(const chcore::TSmartPath& pathFile);
 	static bool DeleteFile(const chcore::TSmartPath& pathFile);
 
Index: src/ch/TSubTaskBase.cpp
===================================================================
diff -u -ra3800c2f65fa66354e072b34c9e9970af49236b6 -r886c32a98f09ae8dc24ceb6b27e5c8a75104954e
--- src/ch/TSubTaskBase.cpp	(.../TSubTaskBase.cpp)	(revision a3800c2f65fa66354e072b34c9e9970af49236b6)
+++ src/ch/TSubTaskBase.cpp	(.../TSubTaskBase.cpp)	(revision 886c32a98f09ae8dc24ceb6b27e5c8a75104954e)
@@ -80,7 +80,7 @@
 		chcore::TSmartPath pathCombined = pathDst + spFileInfo->GetFullFilePath().GetFileDir();
 
 		// force create directory
-		SHCreateDirectoryEx(NULL, pathCombined.ToString(), NULL);
+		TLocalFilesystem::CreateDirectory(pathCombined, true);
 
 		return pathCombined + spFileInfo->GetFullFilePath().GetFileName();
 	}
Index: src/ch/TSubTaskCopyMove.cpp
===================================================================
diff -u -r7749d67cd70821fef9cc51303d42625fbcc2aa9d -r886c32a98f09ae8dc24ceb6b27e5c8a75104954e
--- src/ch/TSubTaskCopyMove.cpp	(.../TSubTaskCopyMove.cpp)	(revision 7749d67cd70821fef9cc51303d42625fbcc2aa9d)
+++ src/ch/TSubTaskCopyMove.cpp	(.../TSubTaskCopyMove.cpp)	(revision 886c32a98f09ae8dc24ceb6b27e5c8a75104954e)
@@ -178,7 +178,7 @@
 			if(spFileInfo->IsDirectory())
 			{
 				bool bRetry = true;
-				if(bRetry && !TLocalFilesystem::CreateDirectory(ccp.pathDstFile) && (dwLastError=GetLastError()) != ERROR_ALREADY_EXISTS )
+				if(bRetry && !TLocalFilesystem::CreateDirectory(ccp.pathDstFile, false) && (dwLastError=GetLastError()) != ERROR_ALREADY_EXISTS )
 				{
 					// log
 					fmt.SetFormat(_T("Error %errno while calling CreateDirectory %path (ProcessFiles)"));
Index: src/libchcore/TPath.cpp
===================================================================
diff -u -re30c2b40bd1b533d8740edc88d80b2fb340f3466 -r886c32a98f09ae8dc24ceb6b27e5c8a75104954e
--- src/libchcore/TPath.cpp	(.../TPath.cpp)	(revision e30c2b40bd1b533d8740edc88d80b2fb340f3466)
+++ src/libchcore/TPath.cpp	(.../TPath.cpp)	(revision 886c32a98f09ae8dc24ceb6b27e5c8a75104954e)
@@ -18,8 +18,12 @@
 ***************************************************************************/
 #include "stdafx.h"
 #include <boost/serialization/serialization.hpp>
+#include <boost/bind.hpp>
 #include "TPath.h"
+#pragma warning(push)
+#pragma warning(disable: 4996)
 #include <boost/algorithm/string.hpp>
+#pragma warning(pop)
 #include "../libicpf/exception.h"
 #include <cctype>
 
@@ -34,8 +38,8 @@
 /// @brief     Constructs the TPath object.
 // ============================================================================
 TPath::TPath() :
-	m_strPath(),
-	m_lRefCount(1)
+m_strPath(),
+m_lRefCount(1)
 {
 }
 
@@ -46,8 +50,8 @@
 /// @brief     Constructs the TPath object.
 // ============================================================================
 TPath::TPath(const TPath& rSrc) :
-	m_strPath(rSrc.m_strPath),
-	m_lRefCount(1)
+m_strPath(rSrc.m_strPath),
+m_lRefCount(1)
 {
 }
 
@@ -121,7 +125,7 @@
 /// @brief     Constructs an empty path.
 // ============================================================================
 TSmartPath::TSmartPath() :
-	m_pPath(NULL)
+m_pPath(NULL)
 {
 }
 
@@ -133,7 +137,7 @@
 /// @param[in] spPath - reference to another path object.
 // ============================================================================
 TSmartPath::TSmartPath(const TSmartPath& spPath) :
-	m_pPath(spPath.m_pPath)
+m_pPath(spPath.m_pPath)
 {
 	if(m_pPath)
 		m_pPath->AddRef();
@@ -250,27 +254,40 @@
 // ============================================================================
 TSmartPath TSmartPath::operator+(const TSmartPath& rPath) const
 {
-	TSmartPath spNewPath(*this);
 	if(rPath.m_pPath && rPath.m_pPath->m_strPath.length() > 0)
 	{
-		spNewPath.PrepareToWrite();
-
-		// detect separators
-		bool bThisEndsWithSeparator = EndsWithSeparator();
-		bool bInStartsWithSeparator = rPath.StartsWithSeparator();
-
-		if(!bThisEndsWithSeparator && !bInStartsWithSeparator)
-			spNewPath.m_pPath->m_strPath += _T("\\") + rPath.m_pPath->m_strPath;
-		else if(bThisEndsWithSeparator ^ bInStartsWithSeparator)
-			spNewPath.m_pPath->m_strPath += rPath.m_pPath->m_strPath;
+		// if this path is empty, then return the input one
+		if(!m_pPath || rPath.m_pPath->m_strPath.length() == 0)
+			return rPath;
 		else
 		{
-			spNewPath.m_pPath->m_strPath.erase(m_pPath->m_strPath.length() - 1);
-			spNewPath.m_pPath->m_strPath += rPath.m_pPath->m_strPath;
+			TSmartPath spNewPath(*this);
+
+			// both paths contains something to be concatenated
+			spNewPath.PrepareToWrite();
+
+			// detect separators
+			bool bThisEndsWithSeparator = EndsWithSeparator();
+			bool bInStartsWithSeparator = rPath.StartsWithSeparator();
+
+			if(!bThisEndsWithSeparator && !bInStartsWithSeparator)
+				spNewPath.m_pPath->m_strPath += _T("\\") + rPath.m_pPath->m_strPath;
+			else if(bThisEndsWithSeparator ^ bInStartsWithSeparator)
+				spNewPath.m_pPath->m_strPath += rPath.m_pPath->m_strPath;
+			else
+			{
+				spNewPath.m_pPath->m_strPath.erase(m_pPath->m_strPath.length() - 1);
+				spNewPath.m_pPath->m_strPath += rPath.m_pPath->m_strPath;
+			}
+
+			return spNewPath;
 		}
 	}
-
-	return spNewPath;
+	else
+	{
+		// input path is empty, so return this path, whatever this is
+		return *this;
+	}
 }
 
 // ============================================================================
@@ -286,20 +303,27 @@
 	// if there is no path inside rPath, then there is no point in doing anything
 	if(rPath.m_pPath && rPath.m_pPath->m_strPath.length() > 0)
 	{
-		PrepareToWrite();
-		
-		// detect separators
-		bool bThisEndsWithSeparator = EndsWithSeparator();
-		bool bInStartsWithSeparator = rPath.StartsWithSeparator();
-
-		if(!bThisEndsWithSeparator && !bInStartsWithSeparator)
-			m_pPath->m_strPath += _T("\\") + rPath.m_pPath->m_strPath;
-		else if(bThisEndsWithSeparator ^ bInStartsWithSeparator)
-			m_pPath->m_strPath += rPath.m_pPath->m_strPath;
+		// if this path is empty, then optimize by just assigning the input path to this one
+		if(!m_pPath || m_pPath->m_strPath.length() == 0)
+			*this = rPath;
 		else
 		{
-			m_pPath->m_strPath.erase(m_pPath->m_strPath.length() - 1);
-			m_pPath->m_strPath += rPath.m_pPath->m_strPath;
+			// both paths are not empty - do regular concatenation
+			PrepareToWrite();
+
+			// detect separators
+			bool bThisEndsWithSeparator = EndsWithSeparator();
+			bool bInStartsWithSeparator = rPath.StartsWithSeparator();
+
+			if(!bThisEndsWithSeparator && !bInStartsWithSeparator)
+				m_pPath->m_strPath += _T("\\") + rPath.m_pPath->m_strPath;
+			else if(bThisEndsWithSeparator ^ bInStartsWithSeparator)
+				m_pPath->m_strPath += rPath.m_pPath->m_strPath;
+			else
+			{
+				m_pPath->m_strPath.erase(m_pPath->m_strPath.length() - 1);
+				m_pPath->m_strPath += rPath.m_pPath->m_strPath;
+			}
 		}
 	}
 
@@ -388,6 +412,45 @@
 }
 
 // ============================================================================
+/// TSmartPath::SplitPath
+/// @date 2011/04/05
+///
+/// @brief     Splits path to components.
+/// @param[in] vComponents - receives the split path.
+// ============================================================================
+void TSmartPath::SplitPath(std::vector<TSmartPath>& vComponents) const
+{
+	vComponents.clear();
+
+	if(IsNetworkPath())
+	{
+		// server name first
+		vComponents.push_back(GetServerName());
+
+		// now the split directories
+		std::vector<TSmartPath> vDirSplit;
+		TSmartPath spDir = GetFileDir();
+		spDir.SplitPath(vDirSplit);
+
+		vComponents.insert(vComponents.end(), vDirSplit.begin(), vDirSplit.end());
+
+		// and file name last
+		vComponents.push_back(GetFileName());
+	}
+	else
+	{
+		std::vector<std::wstring> vStrings;
+		boost::split(vStrings, m_pPath->m_strPath, boost::is_any_of(_T("\\/")));
+
+		BOOST_FOREACH(const std::wstring& pathComponent, vStrings)
+		{
+			if(!pathComponent.empty())
+				vComponents.push_back(PathFromWString(pathComponent));
+		}
+	}
+}
+
+// ============================================================================
 /// TSmartPath::IsChildOf
 /// @date 2009/11/29
 ///
@@ -488,63 +551,33 @@
 }
 
 // ============================================================================
-/// chcore::TSmartPath::HasLengthExtension
-/// @date 2010/10/16
+/// chcore::TSmartPath::IsNetworkPath
+/// @date 2010/10/17
 ///
-/// @brief     Checks if the path has prefix allowing handling of longer paths (\\?\)
-/// @return    True if prefix exists, false otherwise.
+/// @brief     Checks if the path is network one (\\server_name...)
+/// @return    True if it is, false otherwise.
 // ============================================================================
-bool TSmartPath::HasLengthExtension() const
+bool TSmartPath::IsNetworkPath() const
 {
-	return m_pPath && boost::starts_with(m_pPath->m_strPath, _T("\\\\?\\"));
-}
+	if(!m_pPath)
+		return false;
 
-// ============================================================================
-/// chcore::TSmartPath::AddLengthExtension
-/// @date 2010/10/16
-///
-/// @brief     Adds a length extension prefix if not exist.
-// ============================================================================
-void TSmartPath::AddLengthExtension()
-{
-	if(!HasLengthExtension())
-	{
-		PrepareToWrite();
-		m_pPath->m_strPath.insert(0, _T("\\\\?\\"));
-	}
+	return (m_pPath->m_strPath.length() > 2 && IsSeparator(m_pPath->m_strPath.at(0)) && IsSeparator(m_pPath->m_strPath.at(1)));		// "\\server_name"
 }
 
 // ============================================================================
-/// chcore::TSmartPath::DeleteLengthExtension
-/// @date 2010/10/16
+/// chcore::TSmartPath::IsDrive
+/// @date 2011/04/05
 ///
-/// @brief     Deletes length extension prefix from path if exists.
-// ============================================================================
-void TSmartPath::DeleteLengthExtension()
-{
-	if(HasLengthExtension())
-	{
-		PrepareToWrite();
-		m_pPath->m_strPath.erase(m_pPath->m_strPath.begin(), m_pPath->m_strPath.begin() + 4);
-	}
-}
-
-// ============================================================================
-/// chcore::TSmartPath::IsNetworkPath
-/// @date 2010/10/17
-///
-/// @brief     Checks if the path is network one (\\server_name...)
+/// @brief     Checks if this path contains only drive specification (i.e. c:)
 /// @return    True if it is, false otherwise.
 // ============================================================================
-bool TSmartPath::IsNetworkPath() const
+bool TSmartPath::IsDrive() const
 {
 	if(!m_pPath)
 		return false;
 
-	if(HasLengthExtension())
-		return (m_pPath->m_strPath.length() > 6 && IsSeparator(m_pPath->m_strPath.at(4)) && IsSeparator(m_pPath->m_strPath.at(5)));		// "\\?\\\server_name"
-	else
-		return (m_pPath->m_strPath.length() > 2 && IsSeparator(m_pPath->m_strPath.at(0)) && IsSeparator(m_pPath->m_strPath.at(1)));		// "\\server_name"
+	return (m_pPath->m_strPath.length() == 2 && m_pPath->m_strPath.at(1) == _T(':'));
 }
 
 // ============================================================================
@@ -558,10 +591,8 @@
 {
 	if(!m_pPath)
 		return false;
-	if(HasLengthExtension())
-		return (m_pPath->m_strPath.length() >= 6 && m_pPath->m_strPath.at(5) == _T(':'));
-	else
-		return (m_pPath->m_strPath.length() >= 2 && m_pPath->m_strPath.at(1) == _T(':'));
+
+	return (m_pPath->m_strPath.length() >= 2 && m_pPath->m_strPath.at(1) == _T(':'));
 }
 
 // ============================================================================
@@ -576,26 +607,36 @@
 	if(!m_pPath)
 		return TSmartPath();
 
-	if(HasLengthExtension())
+	if(m_pPath->m_strPath.length() >= 2 && m_pPath->m_strPath.at(1) == _T(':'))
 	{
-		if(m_pPath->m_strPath.length() >= 6 && m_pPath->m_strPath.at(5) == _T(':'))
-			return PathFromString(std::wstring(m_pPath->m_strPath.begin() + 4, m_pPath->m_strPath.begin() + 6));	// c: for c:\windows\test.cpp
+		if(m_pPath->m_strPath.length() == 2)
+			return *this;
+		else
+			return PathFromWString(std::wstring(m_pPath->m_strPath.begin(), m_pPath->m_strPath.begin() + 2));	// c: for c:\windows\test.cpp
 	}
-	else
-	{
-		if(m_pPath->m_strPath.length() >= 2 && m_pPath->m_strPath.at(1) == _T(':'))
-		{
-			if(m_pPath->m_strPath.length() == 2)
-				return *this;
-			else
-				return PathFromString(std::wstring(m_pPath->m_strPath.begin(), m_pPath->m_strPath.begin() + 2));	// c: for c:\windows\test.cpp
-		}
-	}
 
 	return TSmartPath();
 }
 
 // ============================================================================
+/// chcore::TSmartPath::IsServerName
+/// @date 2011/04/05
+///
+/// @brief     Checks if this path contains only the server specification (i.e. \\server - witn no ending backslash)
+/// @return    True is this path contains only server specification.
+// ============================================================================
+bool TSmartPath::IsServerName() const
+{
+	if(!m_pPath)
+		return false;
+
+	return (m_pPath->m_strPath.length() > 2 &&			// must have at least 3 characters...
+		IsSeparator(m_pPath->m_strPath.at(0)) && IsSeparator(m_pPath->m_strPath.at(1)) &&	// ... the first two of which are separators...
+		std::isalnum(m_pPath->m_strPath.at(2)) &&											// ... followed by at least one alphanumeric character...
+		m_pPath->m_strPath.find_first_of(_T("\\/"), 3) == std::wstring::npos);								// ... with no additional separators (so \\abc is true, \\abc\ is not).
+}
+
+// ============================================================================
 /// chcore::TSmartPath::HasServerName
 /// @date 2010/10/17
 ///
@@ -607,10 +648,7 @@
 	if(!m_pPath)
 		return false;
 
-	if(HasLengthExtension())
-		return (m_pPath->m_strPath.length() > 6 && IsSeparator(m_pPath->m_strPath.at(4)) && IsSeparator(m_pPath->m_strPath.at(5)) && std::isalnum(m_pPath->m_strPath.at(6)));
-	else
-		return (m_pPath->m_strPath.length() > 2 && IsSeparator(m_pPath->m_strPath.at(0)) && IsSeparator(m_pPath->m_strPath.at(1)) && std::isalnum(m_pPath->m_strPath.at(2)));
+	return (m_pPath->m_strPath.length() > 2 && IsSeparator(m_pPath->m_strPath.at(0)) && IsSeparator(m_pPath->m_strPath.at(1)) && std::isalnum(m_pPath->m_strPath.at(2)));
 }
 
 // ============================================================================
@@ -626,30 +664,15 @@
 		return TSmartPath();
 
 	std::wstring wstrPath;
-	if(HasLengthExtension())
+	if(m_pPath->m_strPath.length() > 2 && IsSeparator(m_pPath->m_strPath.at(0)) && IsSeparator(m_pPath->m_strPath.at(1)) && std::isalnum(m_pPath->m_strPath.at(2)))
 	{
-		if(m_pPath->m_strPath.length() > 6 && IsSeparator(m_pPath->m_strPath.at(4)) && IsSeparator(m_pPath->m_strPath.at(5)) && std::isalnum(m_pPath->m_strPath.at(6)))
-		{
-			size_t stEndPos = m_pPath->m_strPath.find_first_of(_T("\\/"), 6);
-			if(stEndPos == std::wstring::npos)
-				wstrPath.insert(wstrPath.end(), m_pPath->m_strPath.begin() + 4, m_pPath->m_strPath.end());
-			else
-				wstrPath.insert(wstrPath.end(), m_pPath->m_strPath.begin() + 4, m_pPath->m_strPath.begin() + stEndPos);
-			return PathFromString(wstrPath);
-		}
+		size_t stEndPos = m_pPath->m_strPath.find_first_of(_T("\\/"), 2);
+		if(stEndPos == std::wstring::npos)
+			wstrPath.insert(wstrPath.end(), m_pPath->m_strPath.begin(), m_pPath->m_strPath.end());
+		else
+			wstrPath.insert(wstrPath.end(), m_pPath->m_strPath.begin(), m_pPath->m_strPath.begin() + stEndPos);
+		return PathFromWString(wstrPath);
 	}
-	else
-	{
-		if(m_pPath->m_strPath.length() > 2 && IsSeparator(m_pPath->m_strPath.at(0)) && IsSeparator(m_pPath->m_strPath.at(1)) && std::isalnum(m_pPath->m_strPath.at(2)))
-		{
-			size_t stEndPos = m_pPath->m_strPath.find_first_of(_T("\\/"), 2);
-			if(stEndPos == std::wstring::npos)
-				wstrPath.insert(wstrPath.end(), m_pPath->m_strPath.begin(), m_pPath->m_strPath.end());
-			else
-				wstrPath.insert(wstrPath.end(), m_pPath->m_strPath.begin(), m_pPath->m_strPath.begin() + stEndPos);
-			return PathFromString(wstrPath);
-		}
-	}
 
 	return TSmartPath();
 }
@@ -666,16 +689,8 @@
 	if(!m_pPath)
 		return false;
 
-	if(HasLengthExtension())
-	{
-		size_t stIndex = m_pPath->m_strPath.find_last_of(_T("\\/"));
-		return (stIndex != std::wstring::npos && stIndex >= 4);
-	}
-	else
-	{
-		size_t stIndex = m_pPath->m_strPath.find_last_of(_T("\\/"));
-		return (stIndex != std::wstring::npos);
-	}
+	size_t stIndex = m_pPath->m_strPath.find_last_of(_T("\\/"));
+	return (stIndex != std::wstring::npos);
 }
 
 // ============================================================================
@@ -690,24 +705,12 @@
 	if(!m_pPath)
 		return TSmartPath();
 
-	if(HasLengthExtension())
+	size_t stIndex = m_pPath->m_strPath.find_last_of(_T("\\/"));
+	if(stIndex != std::wstring::npos)
 	{
-		size_t stIndex = m_pPath->m_strPath.find_last_of(_T("\\/"));
-		if(stIndex != std::wstring::npos && stIndex >= 4)
-		{
-			std::wstring wstrPath(m_pPath->m_strPath.begin(), m_pPath->m_strPath.begin() + stIndex + 1);
-			return PathFromString(wstrPath);
-		}
+		std::wstring wstrPath(m_pPath->m_strPath.begin(), m_pPath->m_strPath.begin() + stIndex + 1);
+		return PathFromWString(wstrPath);
 	}
-	else
-	{
-		size_t stIndex = m_pPath->m_strPath.find_last_of(_T("\\/"));
-		if(stIndex != std::wstring::npos)
-		{
-			std::wstring wstrPath(m_pPath->m_strPath.begin(), m_pPath->m_strPath.begin() + stIndex + 1);
-			return PathFromString(wstrPath);
-		}
-	}
 
 	return TSmartPath();
 }
@@ -725,20 +728,10 @@
 		return false;
 
 	size_t stStart = 0;
-	if(HasLengthExtension())
-	{
-		if(IsNetworkPath())
-			stStart = m_pPath->m_strPath.find_first_of(_T("/\\"), 6);
-		else
-			stStart = m_pPath->m_strPath.find_first_of(_T("/\\"), 4);
-	}
+	if(IsNetworkPath())
+		stStart = m_pPath->m_strPath.find_first_of(_T("/\\"), 2);
 	else
-	{
-		if(IsNetworkPath())
-			stStart = m_pPath->m_strPath.find_first_of(_T("/\\"), 2);
-		else
-			stStart = m_pPath->m_strPath.find_first_of(_T("/\\"));
-	}
+		stStart = m_pPath->m_strPath.find_first_of(_T("/\\"));
 
 	size_t stEnd = m_pPath->m_strPath.find_last_of(_T("/\\"));
 	return (stStart != std::wstring::npos && stEnd >= stStart);
@@ -757,26 +750,16 @@
 		return TSmartPath();
 
 	size_t stStart = 0;
-	if(HasLengthExtension())
-	{
-		if(IsNetworkPath())
-			stStart = m_pPath->m_strPath.find_first_of(_T("/\\"), 6);
-		else
-			stStart = m_pPath->m_strPath.find_first_of(_T("/\\"), 4);
-	}
+	if(IsNetworkPath())
+		stStart = m_pPath->m_strPath.find_first_of(_T("/\\"), 2);
 	else
-	{
-		if(IsNetworkPath())
-			stStart = m_pPath->m_strPath.find_first_of(_T("/\\"), 2);
-		else
-			stStart = m_pPath->m_strPath.find_first_of(_T("/\\"));
-	}
+		stStart = m_pPath->m_strPath.find_first_of(_T("/\\"));
 
 	size_t stEnd = m_pPath->m_strPath.find_last_of(_T("/\\"));
 	if(stStart != std::wstring::npos && stEnd >= stStart)
 	{
 		std::wstring wstrDir(m_pPath->m_strPath.begin() + stStart, m_pPath->m_strPath.begin() + stEnd + 1);
-		return PathFromString(wstrDir);
+		return PathFromWString(wstrDir);
 	}
 
 	return TSmartPath();
@@ -828,7 +811,7 @@
 		stEnd = m_pPath->m_strPath.length();
 
 	std::wstring wstrDir(m_pPath->m_strPath.begin() + stStart + 1, m_pPath->m_strPath.begin() + stEnd);
-	return PathFromString(wstrDir);
+	return PathFromWString(wstrDir);
 }
 
 // ============================================================================
@@ -863,7 +846,7 @@
 	size_t stIndex = m_pPath->m_strPath.find_last_of(_T("\\/."));
 
 	if(stIndex != std::wstring::npos && m_pPath->m_strPath.at(stIndex) == _T('.'))
-		return PathFromString(std::wstring(m_pPath->m_strPath.begin() + stIndex, m_pPath->m_strPath.end()));	// ".txt" for "c:\windows\test.txt"
+		return PathFromWString(std::wstring(m_pPath->m_strPath.begin() + stIndex, m_pPath->m_strPath.end()));	// ".txt" for "c:\windows\test.txt"
 
 	return TSmartPath();
 }
@@ -880,16 +863,8 @@
 	if(!m_pPath)
 		return false;
 
-	if(HasLengthExtension())
-	{
-		size_t stIndex = m_pPath->m_strPath.find_last_of(_T("\\/"));
-		return (stIndex != std::wstring::npos && stIndex >= 4 && stIndex != m_pPath->m_strPath.length() - 1);
-	}
-	else
-	{
-		size_t stIndex = m_pPath->m_strPath.find_last_of(_T("\\/"));
-		return (stIndex != std::wstring::npos && stIndex != m_pPath->m_strPath.length() - 1);
-	}
+	size_t stIndex = m_pPath->m_strPath.find_last_of(_T("\\/"));
+	return (stIndex != std::wstring::npos && stIndex != m_pPath->m_strPath.length() - 1);
 }
 
 // ============================================================================
@@ -904,18 +879,9 @@
 	if(!m_pPath)
 		return TSmartPath();
 
-	if(HasLengthExtension())
-	{
-		size_t stIndex = m_pPath->m_strPath.find_last_of(_T("\\/"));
-		if(stIndex != std::wstring::npos && stIndex >= 4)
-			return PathFromString(std::wstring(m_pPath->m_strPath.begin() + stIndex + 1, m_pPath->m_strPath.end()));	// "test.txt" for "c:\windows\test.txt"
-	}
-	else
-	{
-		size_t stIndex = m_pPath->m_strPath.find_last_of(_T("\\/"));
-		if(stIndex != std::wstring::npos)
-			return PathFromString(std::wstring(m_pPath->m_strPath.begin() + stIndex + 1, m_pPath->m_strPath.end()));	// "test.txt" for "c:\windows\test.txt"
-	}
+	size_t stIndex = m_pPath->m_strPath.find_last_of(_T("\\/"));
+	if(stIndex != std::wstring::npos)
+		return PathFromWString(std::wstring(m_pPath->m_strPath.begin() + stIndex + 1, m_pPath->m_strPath.end()));	// "test.txt" for "c:\windows\test.txt"
 
 	return TSmartPath();
 }
@@ -931,24 +897,12 @@
 	if(!m_pPath)
 		return;
 
-	if(HasLengthExtension())
+	size_t stIndex = m_pPath->m_strPath.find_last_of(_T("\\/"));
+	if(stIndex != std::wstring::npos)
 	{
-		size_t stIndex = m_pPath->m_strPath.find_last_of(_T("\\/"));
-		if(stIndex != std::wstring::npos && stIndex >= 4)
-		{
-			PrepareToWrite();
-			m_pPath->m_strPath.erase(m_pPath->m_strPath.begin() + stIndex + 1, m_pPath->m_strPath.end());	// "test.txt" for "c:\windows\test.txt"
-		}
+		PrepareToWrite();
+		m_pPath->m_strPath.erase(m_pPath->m_strPath.begin() + stIndex + 1, m_pPath->m_strPath.end());	// "test.txt" for "c:\windows\test.txt"
 	}
-	else
-	{
-		size_t stIndex = m_pPath->m_strPath.find_last_of(_T("\\/"));
-		if(stIndex != std::wstring::npos)
-		{
-			PrepareToWrite();
-			m_pPath->m_strPath.erase(m_pPath->m_strPath.begin() + stIndex + 1, m_pPath->m_strPath.end());	// "test.txt" for "c:\windows\test.txt"
-		}
-	}
 }
 
 // ============================================================================
@@ -1016,16 +970,8 @@
 		return false;
 
 	wchar_t wchLastChar = 0;
-	if(HasLengthExtension())
-	{
-		if(m_pPath->m_strPath.length() > 4)
-			wchLastChar = m_pPath->m_strPath.at(4);
-	}
-	else
-	{
-		if(m_pPath->m_strPath.length() > 0)
-			wchLastChar = m_pPath->m_strPath.at(0);
-	}
+	if(m_pPath->m_strPath.length() > 0)
+		wchLastChar = m_pPath->m_strPath.at(0);
 
 	return (wchLastChar == _T('\\') || wchLastChar == _T('/'));
 }
@@ -1041,10 +987,7 @@
 	if(!StartsWithSeparator())
 	{
 		PrepareToWrite();
-		if(HasLengthExtension())
-			m_pPath->m_strPath.insert(4, _T("\\"));
-		else
-			m_pPath->m_strPath.insert(0, _T("\\"));
+		m_pPath->m_strPath.insert(0, _T("\\"));
 	}
 }
 
@@ -1060,10 +1003,7 @@
 	{
 		PrepareToWrite();
 
-		if(HasLengthExtension())
-			m_pPath->m_strPath.erase(4);
-		else
-			m_pPath->m_strPath.erase(0);
+		m_pPath->m_strPath.erase(0);
 	}
 }
 
@@ -1078,18 +1018,42 @@
 	return !m_pPath || m_pPath->m_strPath.empty();
 }
 
+// ============================================================================
+/// chcore::TSmartPath::GetLength
+/// @date 2011/04/05
+///
+/// @brief     Retrieves path length in characters.
+/// @return    Path length.
+// ============================================================================
 size_t TSmartPath::GetLength() const
 {
 	if(!m_pPath)
 		return 0;
 	return m_pPath->m_strPath.length();
 }
 
+// ============================================================================
+/// chcore::TSmartPath::StoreInConfig
+/// @date 2011/04/05
+///
+/// @brief     Stores the path in configuration file.
+/// @param[in] rConfig - configuration object to store information in.
+/// @param[in] pszPropName - property name under which to store the path.
+// ============================================================================
 void TSmartPath::StoreInConfig(chcore::TConfig& rConfig, PCTSTR pszPropName) const
 {
 	rConfig.SetValue(pszPropName, m_pPath ? m_pPath->m_strPath : std::wstring());
 }
 
+// ============================================================================
+/// chcore::TSmartPath::ReadFromConfig
+/// @date 2011/04/05
+///
+/// @brief     Reads a path from configuration file.
+/// @param[in] rConfig - configuration object to read path from.
+/// @param[in] pszPropName - property name from under which to read the path.
+/// @return    True if path properly read, false otherwise.
+// ============================================================================
 bool TSmartPath::ReadFromConfig(const chcore::TConfig& rConfig, PCTSTR pszPropName)
 {
 	std::wstring wstrPath;
@@ -1155,14 +1119,14 @@
 }
 
 // ============================================================================
-/// chcore::PathFromString
+/// chcore::PathFromWString
 /// @date 2010/10/12
 ///
 /// @brief     Creates a path object from string.
 /// @param[in] pszPath - string containing path.
 /// @return    New path object.
 // ============================================================================
-TSmartPath PathFromString(const std::wstring& strPath)
+TSmartPath PathFromWString(const std::wstring& strPath)
 {
 	TSmartPath spPath;
 	spPath.FromString(strPath);
@@ -1176,7 +1140,7 @@
 /// @brief     Constructs an empty path container object.
 // ============================================================================
 TPathContainer::TPathContainer() :
-	m_vPaths()
+m_vPaths()
 {
 }
 
@@ -1188,7 +1152,7 @@
 /// @param[in] rSrcContainer - path container to copy paths from.
 // ============================================================================
 TPathContainer::TPathContainer(const TPathContainer& rSrcContainer) :
-	m_vPaths(rSrcContainer.m_vPaths)
+m_vPaths(rSrcContainer.m_vPaths)
 {
 }
 
@@ -1274,7 +1238,7 @@
 {
 	if(stIndex > m_vPaths.size())
 		THROW_CORE_EXCEPTION(eBoundsExceeded);
-	
+
 	m_vPaths[stIndex] = spPath;
 }
 
@@ -1350,7 +1314,7 @@
 	{
 		BOOST_FOREACH(const std::wstring& wstrPath, vPaths)
 		{
-			m_vPaths.push_back(PathFromString(wstrPath));
+			m_vPaths.push_back(PathFromWString(wstrPath));
 		}
 		return true;
 	}
Index: src/libchcore/TPath.h
===================================================================
diff -u -re30c2b40bd1b533d8740edc88d80b2fb340f3466 -r886c32a98f09ae8dc24ceb6b27e5c8a75104954e
--- src/libchcore/TPath.h	(.../TPath.h)	(revision e30c2b40bd1b533d8740edc88d80b2fb340f3466)
+++ src/libchcore/TPath.h	(.../TPath.h)	(revision 886c32a98f09ae8dc24ceb6b27e5c8a75104954e)
@@ -80,6 +80,8 @@
 	// other operations
 	void Clear() throw();
 
+	void SplitPath(std::vector<TSmartPath>& vComponents) const;
+
 	bool Compare(const TSmartPath& rPath, bool bCaseSensitive = DefaultCaseSensitivity) const;
 	bool IsChildOf(const TSmartPath& rPath, bool bCaseSensitive = DefaultCaseSensitivity) const;
 
@@ -88,15 +90,13 @@
 	void AppendIfNotExists(const wchar_t* pszPostfix, bool bCaseSensitive = DefaultCaseSensitivity);
 	void CutIfExists(const wchar_t* pszPostfix, bool bCaseSensitive = DefaultCaseSensitivity);
 
-	bool HasLengthExtension() const;	// checks if path is prefixed with "\\?\"
-	void AddLengthExtension();
-	void DeleteLengthExtension();
-
 	bool IsNetworkPath() const;
 
+	bool IsDrive() const;
 	bool HasDrive() const;
 	TSmartPath GetDrive() const;		// c: for c:\windows\test.txt
 
+	bool IsServerName() const;
 	bool HasServerName() const;
 	TSmartPath GetServerName() const;
 
@@ -162,7 +162,7 @@
 };
 
 LIBCHCORE_API TSmartPath PathFromString(const wchar_t* pszPath);
-LIBCHCORE_API TSmartPath PathFromString(const std::wstring& strPath);
+LIBCHCORE_API TSmartPath PathFromWString(const std::wstring& strPath);
 
 class LIBCHCORE_API TPathContainer
 {