Index: src/libchcore/IFilesystem.h
===================================================================
diff -u -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/IFilesystem.h	(.../IFilesystem.h)	(revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b)
+++ src/libchcore/IFilesystem.h	(.../IFilesystem.h)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -57,7 +57,7 @@
 	virtual bool FastMove(const TSmartPath& pathSource, const TSmartPath& pathDestination) = 0;
 
 	virtual IFilesystemFindPtr CreateFinderObject(const TSmartPath& pathDir, const TSmartPath& pathMask) = 0;
-	virtual IFilesystemFilePtr CreateFileObject() = 0;
+	virtual IFilesystemFilePtr CreateFileObject(const TSmartPath& pathFile) = 0;
 
 	virtual EPathsRelation GetPathsRelation(const TSmartPath& pathFirst, const TSmartPath& pathSecond) = 0;
 
Index: src/libchcore/IFilesystemFile.cpp
===================================================================
diff -u -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/IFilesystemFile.cpp	(.../IFilesystemFile.cpp)	(revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b)
+++ src/libchcore/IFilesystemFile.cpp	(.../IFilesystemFile.cpp)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -19,10 +19,9 @@
 #include "stdafx.h"
 #include "IFilesystemFile.h"
 
-BEGIN_CHCORE_NAMESPACE
-
-IFilesystemFile::~IFilesystemFile()
+namespace chcore
 {
+	IFilesystemFile::~IFilesystemFile()
+	{
+	}
 }
-
-END_CHCORE_NAMESPACE
Index: src/libchcore/IFilesystemFile.h
===================================================================
diff -u -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/IFilesystemFile.h	(.../IFilesystemFile.h)	(revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b)
+++ src/libchcore/IFilesystemFile.h	(.../IFilesystemFile.h)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -23,35 +23,35 @@
 #include "TPath.h"
 #include "TOverlappedDataBuffer.h"
 
-BEGIN_CHCORE_NAMESPACE
-
-class LIBCHCORE_API IFilesystemFile
+namespace chcore
 {
-public:
-	static const unsigned int MaxSectorSize = 4096;
+	class LIBCHCORE_API IFilesystemFile
+	{
+	public:
+		static const unsigned int MaxSectorSize = 4096;
 
-public:
-	virtual ~IFilesystemFile();
+	public:
+		virtual ~IFilesystemFile();
 
-	virtual bool OpenExistingForReading(const TSmartPath& pathFile, bool bNoBuffering) = 0;
-	virtual bool CreateNewForWriting(const TSmartPath& pathFile, bool bNoBuffering) = 0;
-	virtual bool OpenExistingForWriting(const TSmartPath& pathFile, bool bNoBuffering) = 0;
+		virtual bool OpenExistingForReading(bool bNoBuffering) = 0;
+		virtual bool CreateNewForWriting(bool bNoBuffering) = 0;
+		virtual bool OpenExistingForWriting(bool bNoBuffering) = 0;
 
-	virtual bool SetFilePointer(long long llNewPos, DWORD dwMoveMethod) = 0;
-	virtual bool SetEndOfFile() = 0;
+		virtual bool Truncate(long long ullNewSize) = 0;
 
-	virtual bool ReadFile(TOverlappedDataBuffer& rBuffer) = 0;
-	virtual bool WriteFile(TOverlappedDataBuffer& rBuffer) = 0;
-	virtual bool FinalizeFile(TOverlappedDataBuffer& rBuffer) = 0;
+		virtual bool ReadFile(TOverlappedDataBuffer& rBuffer) = 0;
+		virtual bool WriteFile(TOverlappedDataBuffer& rBuffer) = 0;
+		virtual bool FinalizeFile(TOverlappedDataBuffer& rBuffer) = 0;
 
-	virtual bool IsOpen() const = 0;
-	virtual unsigned long long GetFileSize() const = 0;
+		virtual bool IsOpen() const = 0;
+		virtual unsigned long long GetFileSize() const = 0;
 
-	virtual void Close() = 0;
-};
+		virtual void Close() = 0;
 
-typedef std::shared_ptr<IFilesystemFile> IFilesystemFilePtr;
+		virtual TSmartPath GetFilePath() const = 0;
+	};
 
-END_CHCORE_NAMESPACE
+	typedef std::shared_ptr<IFilesystemFile> IFilesystemFilePtr;
+}
 
 #endif
Index: src/libchcore/TFakeFileDescription.cpp
===================================================================
diff -u -r5efb534fc5440a7ab779d2514a00486ecb58e845 -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/TFakeFileDescription.cpp	(.../TFakeFileDescription.cpp)	(revision 5efb534fc5440a7ab779d2514a00486ecb58e845)
+++ src/libchcore/TFakeFileDescription.cpp	(.../TFakeFileDescription.cpp)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -19,8 +19,39 @@
 #include "stdafx.h"
 #include "TFakeFileDescription.h"
 
-BEGIN_CHCORE_NAMESPACE
+namespace chcore
+{
+	TFakeFileDescription::TFakeFileDescription()
+	{
+	}
 
+	TFakeFileDescription::TFakeFileDescription(TFileInfo fileInfo, TSparseRangeMap sparseRangeMap) :
+		m_fiData(fileInfo),
+		m_mapDamagedRanges(sparseRangeMap)
+	{
+	}
 
+	TFakeFileDescription::~TFakeFileDescription()
+	{
+	}
 
-END_CHCORE_NAMESPACE
+	TFileInfo& TFakeFileDescription::GetFileInfo()
+	{
+		return m_fiData;
+	}
+
+	const TFileInfo& TFakeFileDescription::GetFileInfo() const
+	{
+		return m_fiData;
+	}
+
+	TSparseRangeMap& TFakeFileDescription::GetDamageMap()
+	{
+		return m_mapDamagedRanges;
+	}
+
+	const TSparseRangeMap& TFakeFileDescription::GetDamageMap() const
+	{
+		return m_mapDamagedRanges;
+	}
+}
Index: src/libchcore/TFakeFileDescription.h
===================================================================
diff -u -r5efb534fc5440a7ab779d2514a00486ecb58e845 -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/TFakeFileDescription.h	(.../TFakeFileDescription.h)	(revision 5efb534fc5440a7ab779d2514a00486ecb58e845)
+++ src/libchcore/TFakeFileDescription.h	(.../TFakeFileDescription.h)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -21,19 +21,29 @@
 
 #include "libchcore.h"
 #include "TFileInfo.h"
+#include "TSparseRangeMap.h"
 
-BEGIN_CHCORE_NAMESPACE
-
-class LIBCHCORE_API TFakeFileDescription
+namespace chcore
 {
-public:
-	TFakeFileDescription();
-	~TFakeFileDescription();
+	class LIBCHCORE_API TFakeFileDescription
+	{
+	public:
+		TFakeFileDescription();
+		TFakeFileDescription(TFileInfo fileInfo, TSparseRangeMap sparseRangeMap);
+		~TFakeFileDescription();
 
-private:
-	TFileInfo m_fiData;
-};
+		TFileInfo& GetFileInfo();
+		const TFileInfo& GetFileInfo() const;
 
-END_CHCORE_NAMESPACE
+		TSparseRangeMap& GetDamageMap();
+		const TSparseRangeMap& GetDamageMap() const;
 
+	private:
+		TFileInfo m_fiData;
+		TSparseRangeMap m_mapDamagedRanges;
+	};
+
+	typedef std::shared_ptr<TFakeFileDescription> TFakeFileDescriptionPtr;
+}
+
 #endif
Index: src/libchcore/TFakeFilesystem.cpp
===================================================================
diff -u -r5efb534fc5440a7ab779d2514a00486ecb58e845 -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/TFakeFilesystem.cpp	(.../TFakeFilesystem.cpp)	(revision 5efb534fc5440a7ab779d2514a00486ecb58e845)
+++ src/libchcore/TFakeFilesystem.cpp	(.../TFakeFilesystem.cpp)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -18,15 +18,346 @@
 // ============================================================================
 #include "stdafx.h"
 #include "TFakeFilesystem.h"
+#include "RoundingFunctions.h"
+#include "TCoreException.h"
+#include "ErrorCodes.h"
+#include "TFakeFilesystemFile.h"
+#include "TFakeFilesystemFind.h"
+#include "TPathContainer.h"
 
-BEGIN_CHCORE_NAMESPACE
-
-TFakeFilesystem::TFakeFilesystem()
+namespace chcore
 {
-}
+	TFakeFilesystem::TFakeFilesystem()
+	{
+	}
 
-TFakeFilesystem::~TFakeFilesystem()
-{
-}
+	TFakeFilesystem::~TFakeFilesystem()
+	{
+	}
 
-END_CHCORE_NAMESPACE
+	bool TFakeFilesystem::PathExist(const TSmartPath& strPath)
+	{
+		for (const TFakeFileDescriptionPtr& spDesc : m_listFilesystemContent)
+		{
+			if (spDesc->GetFileInfo().GetFullFilePath() == strPath)
+				return true;
+		}
+
+		return false;
+	}
+
+	bool TFakeFilesystem::GetDynamicFreeSpace(const TSmartPath& path, unsigned long long& rullFree)
+	{
+		// get total size of volume
+		file_size_t fsSize = std::numeric_limits<file_size_t>::max();
+		wchar_t wchDrive = path.GetDriveLetter();
+		auto iterFind = m_mapVolumeInfo.find(wchDrive);
+		if (iterFind != m_mapVolumeInfo.end())
+			fsSize = iterFind->second.GetTotalSize();
+
+		// decrease by file sizes
+		for (const TFakeFileDescriptionPtr& spDesc : m_listFilesystemContent)
+		{
+			file_size_t fsFileSize(RoundUp(spDesc->GetFileInfo().GetLength64(), (file_size_t)IFilesystemFile::MaxSectorSize));
+			if (fsFileSize > fsSize)
+				return false;
+			fsSize -= RoundUp(spDesc->GetFileInfo().GetLength64(), (file_size_t)IFilesystemFile::MaxSectorSize);
+		}
+
+		rullFree = fsSize;
+		return false;
+	}
+
+	IFilesystem::EPathsRelation TFakeFilesystem::GetPathsRelation(const TSmartPath& pathFirst, const TSmartPath& pathSecond)
+	{
+		UINT uiFirstDriveType = DRIVE_FIXED;
+		UINT uiSecondDriveType = DRIVE_FIXED;
+
+		auto iterFirst = m_mapVolumeInfo.find(pathFirst.GetDriveLetter());
+		auto iterSecond = m_mapVolumeInfo.find(pathSecond.GetDriveLetter());
+		if (iterFirst != m_mapVolumeInfo.end())
+			uiFirstDriveType = iterFirst->second.GetDriveType();
+		if (iterSecond != m_mapVolumeInfo.end())
+			uiSecondDriveType = iterSecond->second.GetDriveType();
+
+		// what kind of relation...
+		EPathsRelation eRelation = eRelation_Other;
+		if (uiFirstDriveType == DRIVE_REMOTE || uiSecondDriveType == DRIVE_REMOTE)
+			eRelation = eRelation_Network;
+		else if (uiFirstDriveType == DRIVE_CDROM || uiSecondDriveType == DRIVE_CDROM)
+			eRelation = eRelation_CDRom;
+		else if (uiFirstDriveType == DRIVE_FIXED && uiSecondDriveType == DRIVE_FIXED)
+		{
+			// two hdd's - is this the same physical disk ?
+			wchar_t wchFirstDrive = pathFirst.GetDriveLetter();
+			wchar_t wchSecondDrive = pathSecond.GetDriveLetter();
+
+			if (wchFirstDrive == L'\0' || wchSecondDrive == L'\0')
+				THROW_CORE_EXCEPTION(eErr_FixedDriveWithoutDriveLetter);
+
+			if (wchFirstDrive == wchSecondDrive)
+				eRelation = eRelation_SinglePhysicalDisk;
+			else
+			{
+				DWORD dwFirstPhysicalDisk = 0;
+				DWORD dwSecondPhysicalDisk = 1;
+
+				if (iterFirst != m_mapVolumeInfo.end())
+					dwFirstPhysicalDisk = iterFirst->second.GetPhysicalDriveNumber();
+				if (iterSecond != m_mapVolumeInfo.end())
+					dwSecondPhysicalDisk = iterSecond->second.GetPhysicalDriveNumber();
+
+				if (dwFirstPhysicalDisk == std::numeric_limits<DWORD>::max() || dwSecondPhysicalDisk == std::numeric_limits<DWORD>::max())
+				{
+					// NOTE: disabled throwing an exception here - when testing, it came out that some DRIVE_FIXED
+					//       volumes might have problems handling this detection (TrueCrypt volumes for example).
+					//       So for now we report it as two different physical disks.
+					//THROW(_T("Problem with physical disk detection"), 0, 0, 0);
+					eRelation = eRelation_TwoPhysicalDisks;
+				}
+
+				if (dwFirstPhysicalDisk == dwSecondPhysicalDisk)
+					eRelation = eRelation_SinglePhysicalDisk;
+				else
+					eRelation = eRelation_TwoPhysicalDisks;
+			}
+		}
+
+		return eRelation;
+	}
+
+	IFilesystemFilePtr TFakeFilesystem::CreateFileObject(const TSmartPath& spFilename)
+	{
+		IFilesystemFilePtr spFile = std::make_shared<TFakeFilesystemFile>(spFilename, this);
+		return spFile;
+	}
+
+	IFilesystemFindPtr TFakeFilesystem::CreateFinderObject(const TSmartPath& pathDir, const TSmartPath& pathMask)
+	{
+		// check if directory exists
+		TFakeFileDescriptionPtr spFileDesc = FindFileByLocation(pathDir);
+		if (!spFileDesc)
+			return nullptr;
+
+		IFilesystemFindPtr spFind = std::make_shared<TFakeFilesystemFind>(pathDir, pathMask, this);
+		return spFind;
+	}
+
+	bool TFakeFilesystem::FastMove(const TSmartPath& pathSource, const TSmartPath& pathDestination)
+	{
+		TFakeFileDescriptionPtr spFileDesc = FindFileByLocation(pathSource);
+		if (!spFileDesc)
+			return false;
+
+		// check parent of pathDestination
+		TSmartPath pathParent = pathDestination.GetParent();
+		if (pathParent.IsEmpty())
+			return false;
+
+		TFakeFileDescriptionPtr spParentDesc = FindFileByLocation(pathParent);
+		if (!spParentDesc)
+			return false;
+
+		spFileDesc->GetFileInfo().SetFilePath(pathDestination);
+		return true;
+	}
+
+	bool TFakeFilesystem::GetFileInfo(const TSmartPath& pathFile, TFileInfoPtr& rFileInfo, const TBasePathDataPtr& spBasePathData)
+	{
+		TFakeFileDescriptionPtr spFileDesc = FindFileByLocation(pathFile);
+		if (!spFileDesc)
+		{
+			FILETIME fi = { 0, 0 };
+			rFileInfo->Init(TSmartPath(), (DWORD)-1, 0, fi, fi, fi, 0);
+			return false;
+		}
+
+		// copy data from W32_F_D
+		rFileInfo->Init(spBasePathData, pathFile, spFileDesc->GetFileInfo().GetAttributes(),
+			spFileDesc->GetFileInfo().GetLength64(),
+			spFileDesc->GetFileInfo().GetCreationTime().GetAsFiletime(),
+			spFileDesc->GetFileInfo().GetLastAccessTime().GetAsFiletime(),
+			spFileDesc->GetFileInfo().GetLastWriteTime().GetAsFiletime(),
+			0);
+
+		return true;
+	}
+
+	bool TFakeFilesystem::DeleteFile(const TSmartPath& pathFile)
+	{
+		// check parent of pathDestination
+		TSmartPath pathParent = pathFile.GetParent();
+		if (pathParent.IsEmpty())
+			return false;
+
+		TFakeFileDescriptionPtr spParentDesc = FindFileByLocation(pathParent);
+		if (!spParentDesc)
+			return false;
+
+		// similar to FindFileByLocation(), but operating on iterators
+		for (auto iterList = m_listFilesystemContent.begin(); iterList != m_listFilesystemContent.end(); ++iterList)
+		{
+			TFakeFileDescriptionPtr spDesc = (*iterList);
+			if (spDesc->GetFileInfo().GetFullFilePath() == pathFile)
+			{
+				if (spDesc->GetFileInfo().IsDirectory())
+					return false;
+
+				m_listFilesystemContent.erase(iterList);
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	bool TFakeFilesystem::RemoveDirectory(const TSmartPath& pathFile)
+	{
+		// check parent of pathDestination
+		TSmartPath pathParent = pathFile.GetParent();
+		if (pathParent.IsEmpty())
+			return false;
+
+		TFakeFileDescriptionPtr spParentDesc = FindFileByLocation(pathParent);
+		if (!spParentDesc)
+			return false;
+
+		for (auto iterList = m_listFilesystemContent.begin(); iterList != m_listFilesystemContent.end(); ++iterList)
+		{
+			TFakeFileDescriptionPtr spDesc = (*iterList);
+			if (spDesc->GetFileInfo().GetFullFilePath() == pathFile)
+			{
+				if (!spDesc->GetFileInfo().IsDirectory())
+					return false;
+
+				m_listFilesystemContent.erase(iterList);
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	bool TFakeFilesystem::CreateDirectory(const TSmartPath& pathDirectory, bool bCreateFullPath)
+	{
+		// check parent of pathDestination
+		TFakeFileDescriptionPtr spDesc = FindFileByLocation(pathDirectory);
+		if (spDesc)
+			return true;
+
+		if(!bCreateFullPath)
+		{
+			TSmartPath pathParent = pathDirectory.GetParent();
+			if (pathParent.IsEmpty())
+				return false;
+
+			TFakeFileDescriptionPtr spParentDesc = FindFileByLocation(pathParent);
+			if (!spParentDesc)
+				return false;
+
+			CreateFakeDirectory(pathDirectory);
+		}
+		else
+			CreateFSObjectByLocation(pathDirectory);
+
+		return true;
+	}
+
+	bool TFakeFilesystem::SetAttributes(const TSmartPath& pathFileDir, DWORD dwAttributes)
+	{
+		TFakeFileDescriptionPtr spFileDesc = FindFileByLocation(pathFileDir);
+		if (!spFileDesc)
+			return false;
+
+		if (spFileDesc->GetFileInfo().IsDirectory() && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
+			return false;
+		if (!spFileDesc->GetFileInfo().IsDirectory() && (dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
+			return false;
+
+		spFileDesc->GetFileInfo().SetAttributes(dwAttributes);
+		return true;
+	}
+
+	bool TFakeFilesystem::SetFileDirectoryTime(const TSmartPath& pathFileDir, const TFileTime& ftCreationTime, const TFileTime& ftLastAccessTime, const TFileTime& ftLastWriteTime)
+	{
+		TFakeFileDescriptionPtr spFileDesc = FindFileByLocation(pathFileDir);
+		if (!spFileDesc)
+			return false;
+
+		spFileDesc->GetFileInfo().SetFileTimes(ftCreationTime, ftLastAccessTime, ftLastWriteTime);
+		return true;
+	}
+
+	void TFakeFilesystem::SetVolumeInfo(wchar_t wchVolumeLetter, file_size_t fsSize, UINT uiDriveType, DWORD dwPhysicalDiskNumber)
+	{
+		if (wchVolumeLetter >= L'a' && wchVolumeLetter <= L'z')
+			wchVolumeLetter = wchVolumeLetter - 'a' + 'A';
+		else if (wchVolumeLetter < L'A' || wchVolumeLetter > L'Z')
+			THROW_CORE_EXCEPTION(eErr_InvalidArgument);
+
+		auto iterMap = m_mapVolumeInfo.find(wchVolumeLetter);
+		if (iterMap == m_mapVolumeInfo.end())
+			m_mapVolumeInfo.emplace(std::make_pair(wchVolumeLetter, TFakeVolumeInfo(fsSize, uiDriveType, dwPhysicalDiskNumber)));
+		else
+		{
+			iterMap->second.SetDriveType(uiDriveType);
+			iterMap->second.SetTotalSize(fsSize);
+		}
+	}
+
+	TFakeFileDescriptionPtr TFakeFilesystem::FindFileByLocation(const TSmartPath& rPath)
+	{
+		for (TFakeFileDescriptionPtr spFile : m_listFilesystemContent)
+		{
+			if (spFile->GetFileInfo().GetFullFilePath() == rPath)
+				return spFile;
+		}
+
+		return nullptr;
+	}
+
+	TFakeFileDescriptionPtr TFakeFilesystem::CreateFSObjectByLocation(const TSmartPath& pathFSObject)
+	{
+		TPathContainer pathParts;
+		pathFSObject.SplitPath(pathParts);
+
+		TSmartPath pathPartial;
+		TFakeFileDescriptionPtr spFileDesc;
+		for (size_t stIndex = 0; stIndex != pathParts.GetCount(); ++stIndex)
+		{
+			if (stIndex == 0 && (!pathParts.GetAt(stIndex).IsDrive() && !pathParts.GetAt(stIndex).IsServerName()))
+				THROW_CORE_EXCEPTION(eErr_InvalidArgument);
+
+			pathPartial += pathParts.GetAt(stIndex);
+
+			spFileDesc = FindFileByLocation(pathPartial);
+			if (!spFileDesc)
+				CreateFakeDirectory(pathPartial);
+		}
+
+		return spFileDesc;
+	}
+
+	FILETIME TFakeFilesystem::GetCurrentFileTime()
+	{
+		SYSTEMTIME st;
+		GetSystemTime(&st);
+
+		FILETIME ft;
+		SystemTimeToFileTime(&st, &ft);
+
+		return ft;
+	}
+
+	TFakeFileDescriptionPtr TFakeFilesystem::CreateFakeDirectory(const TSmartPath& pathDir)
+	{
+		FILETIME ftCurrent = GetCurrentFileTime();
+		TFakeFileDescriptionPtr spDesc = std::make_shared<TFakeFileDescription>(
+			TFileInfo(nullptr, pathDir, FILE_ATTRIBUTE_DIRECTORY, 0, ftCurrent, ftCurrent, ftCurrent, 0),
+			TSparseRangeMap()
+			);
+
+		m_listFilesystemContent.emplace_back(std::move(spDesc));
+		return spDesc;
+	}
+}
Index: src/libchcore/TFakeFilesystem.h
===================================================================
diff -u -r5efb534fc5440a7ab779d2514a00486ecb58e845 -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/TFakeFilesystem.h	(.../TFakeFilesystem.h)	(revision 5efb534fc5440a7ab779d2514a00486ecb58e845)
+++ src/libchcore/TFakeFilesystem.h	(.../TFakeFilesystem.h)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -20,19 +20,52 @@
 #define __TFAKEFILESYSTEM_H__
 
 #include "libchcore.h"
+#include "TFakeFileDescription.h"
+#include "IFilesystem.h"
+#include "TFakeVolumeInfo.h"
 
-BEGIN_CHCORE_NAMESPACE
-
-class LIBCHCORE_API TFakeFilesystem
+namespace chcore
 {
-public:
-	TFakeFilesystem();
-	~TFakeFilesystem();
+	class LIBCHCORE_API TFakeFilesystem : public IFilesystem
+	{
+	public:
+		TFakeFilesystem();
+		~TFakeFilesystem();
 
-private:
+		// interface implementation
+		virtual bool PathExist(const TSmartPath& strPath) override;
+		virtual bool SetFileDirectoryTime(const TSmartPath& pathFileDir, const TFileTime& ftCreationTime, const TFileTime& ftLastAccessTime, const TFileTime& ftLastWriteTime) override;
+		virtual bool SetAttributes(const TSmartPath& pathFileDir, DWORD dwAttributes) override;
+		virtual bool CreateDirectory(const TSmartPath& pathDirectory, bool bCreateFullPath) override;
+		virtual bool RemoveDirectory(const TSmartPath& pathFile) override;
+		virtual bool DeleteFile(const TSmartPath& pathFile) override;
+		virtual bool GetFileInfo(const TSmartPath& pathFile, TFileInfoPtr& rFileInfo, const TBasePathDataPtr& spBasePathData = TBasePathDataPtr()) override;
+		virtual bool FastMove(const TSmartPath& pathSource, const TSmartPath& pathDestination) override;
+		virtual IFilesystemFindPtr CreateFinderObject(const TSmartPath& pathDir, const TSmartPath& pathMask) override;
+		virtual IFilesystemFilePtr CreateFileObject(const TSmartPath& spFilename) override;
+		virtual EPathsRelation GetPathsRelation(const TSmartPath& pathFirst, const TSmartPath& pathSecond) override;
+		virtual bool GetDynamicFreeSpace(const TSmartPath& path, unsigned long long& rullFree) override;
 
-};
+		// fake handling api
+		void SetVolumeInfo(wchar_t wchVolumeLetter, file_size_t fsSize, UINT uiDriveType, DWORD dwPhysicalDiskNumber);
+		void AddFSObjectDescription(const TFakeFileDescriptionPtr& spFileDesc);
 
-END_CHCORE_NAMESPACE
+	private:
+		TFakeFileDescriptionPtr FindFileByLocation(const TSmartPath& rPath);
+		TFakeFileDescriptionPtr CreateFSObjectByLocation(const TSmartPath& pathFSObject);
+		static FILETIME GetCurrentFileTime();
+		TFakeFileDescriptionPtr CreateFakeDirectory(const TSmartPath& pathDir);
 
+	private:
+#pragma warning(push)
+#pragma warning(disable: 4251)
+		std::list<TFakeFileDescriptionPtr> m_listFilesystemContent;
+		std::map<wchar_t, TFakeVolumeInfo> m_mapVolumeInfo;
+#pragma warning(pop)
+
+		friend class TFakeFilesystemFile;
+		friend class TFakeFilesystemFind;
+	};
+}
+
 #endif
Index: src/libchcore/TFakeFilesystemFile.cpp
===================================================================
diff -u -r5efb534fc5440a7ab779d2514a00486ecb58e845 -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/TFakeFilesystemFile.cpp	(.../TFakeFilesystemFile.cpp)	(revision 5efb534fc5440a7ab779d2514a00486ecb58e845)
+++ src/libchcore/TFakeFilesystemFile.cpp	(.../TFakeFilesystemFile.cpp)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -18,15 +18,275 @@
 // ============================================================================
 #include "stdafx.h"
 #include "TFakeFilesystemFile.h"
+#include "TCoreException.h"
+#include "ErrorCodes.h"
+#include "TFakeFilesystem.h"
+#include <boost/numeric/conversion/cast.hpp>
 
-BEGIN_CHCORE_NAMESPACE
-
-TFakeFilesystemFile::TFakeFilesystemFile()
+namespace
 {
+	struct APCINFO
+	{
+		OVERLAPPED* pOverlapped;
+		DWORD dwError;
+		DWORD dwNumberOfBytesTransfered;
+	};
+
+	enum EStatus : DWORD
+	{
+		STATUS_OK = 0,
+		STATUS_END_OF_FILE = 0xc0000011
+	};
 }
 
-TFakeFilesystemFile::~TFakeFilesystemFile()
+namespace chcore
 {
-}
+	VOID CALLBACK ReadCompleted(ULONG_PTR dwParam)
+	{
+		APCINFO* pApcInfo = (APCINFO*)dwParam;
+		OverlappedReadCompleted(pApcInfo->dwError, pApcInfo->dwNumberOfBytesTransfered, pApcInfo->pOverlapped);
 
-END_CHCORE_NAMESPACE
+		delete pApcInfo;
+	}
+
+	VOID CALLBACK WriteCompleted(ULONG_PTR dwParam)
+	{
+		APCINFO* pApcInfo = (APCINFO*)dwParam;
+		OverlappedWriteCompleted(pApcInfo->dwError, pApcInfo->dwNumberOfBytesTransfered, pApcInfo->pOverlapped);
+
+		delete pApcInfo;
+	}
+
+	TFakeFilesystemFile::TFakeFilesystemFile(const TSmartPath& pathFile, TFakeFilesystem* pFilesystem) :
+		m_pathFile(pathFile),
+		m_pFilesystem(pFilesystem),
+		m_bIsOpen(false),
+		m_bNoBuffering(false),
+		m_bModeReading(true)
+	{
+		if (!pFilesystem || pathFile.IsEmpty())
+			THROW_CORE_EXCEPTION(eErr_InvalidArgument);
+	}
+
+	TFakeFilesystemFile::~TFakeFilesystemFile()
+	{
+	}
+
+	void TFakeFilesystemFile::Close()
+	{
+		m_bIsOpen = false;
+	}
+
+	TSmartPath TFakeFilesystemFile::GetFilePath() const
+	{
+		return m_pathFile;
+	}
+
+	unsigned long long TFakeFilesystemFile::GetFileSize() const
+	{
+		TFakeFileDescriptionPtr spFileDesc = m_pFilesystem->FindFileByLocation(m_pathFile);
+		if (!spFileDesc)
+			return 0;
+
+		return spFileDesc->GetFileInfo().GetLength64();
+	}
+
+	bool TFakeFilesystemFile::IsOpen() const
+	{
+		return m_bIsOpen;
+	}
+
+	bool TFakeFilesystemFile::FinalizeFile(TOverlappedDataBuffer& /*rBuffer*/)
+	{
+		// does nothing
+		return true;
+	}
+
+	bool TFakeFilesystemFile::WriteFile(TOverlappedDataBuffer& rBuffer)
+	{
+		if (!IsOpen())
+			THROW_CORE_EXCEPTION(eErr_InternalProblem);
+
+		// file should have been created already by create for write functions
+		TFakeFileDescriptionPtr spFileDesc = m_pFilesystem->FindFileByLocation(m_pathFile);
+		if (!spFileDesc)
+			return false;
+
+		APCINFO* pInfo = new APCINFO;
+		unsigned long long ullNewSize = 0;
+		unsigned long long ullGrow = 0;
+		if (rBuffer.GetFilePosition() >= spFileDesc->GetFileInfo().GetLength64())
+		{
+			ullNewSize = rBuffer.GetFilePosition() + rBuffer.GetRealDataSize();
+			ullGrow = ullNewSize - spFileDesc->GetFileInfo().GetLength64();
+		}
+		else
+		{
+			ullNewSize = std::max(rBuffer.GetFilePosition() + rBuffer.GetRealDataSize(), spFileDesc->GetFileInfo().GetLength64());
+			ullGrow = ullNewSize - spFileDesc->GetFileInfo().GetLength64();
+		}
+
+		spFileDesc->GetFileInfo().SetLength64(ullNewSize);
+
+		rBuffer.SetStatusCode(STATUS_OK);
+		rBuffer.SetBytesTransferred(rBuffer.GetRealDataSize());
+		pInfo->dwError = ERROR_SUCCESS;
+		pInfo->dwNumberOfBytesTransfered = rBuffer.GetRealDataSize();
+		pInfo->pOverlapped = &rBuffer;
+
+		if (QueueUserAPC(WriteCompleted, GetCurrentThread(), (ULONG_PTR)pInfo) == 0)
+			THROW_CORE_EXCEPTION(eErr_InternalProblem);
+
+		return true;
+	}
+
+	bool TFakeFilesystemFile::ReadFile(TOverlappedDataBuffer& rBuffer)
+	{
+		if (!IsOpen())
+			THROW_CORE_EXCEPTION(eErr_InternalProblem);
+
+		// check if we're reading the undamaged data
+		TFakeFileDescriptionPtr spFileDesc = m_pFilesystem->FindFileByLocation(m_pathFile);
+		if (!spFileDesc)
+			return false;
+
+		const TSparseRangeMap& rmapDamage = spFileDesc->GetDamageMap();
+		if (rmapDamage.OverlapsRange(rBuffer.GetFilePosition(), rBuffer.GetRequestedDataSize()))
+		{
+			APCINFO* pInfo = new APCINFO;
+			pInfo->dwError = ERROR_READ_FAULT;
+			pInfo->dwNumberOfBytesTransfered = 0;
+			pInfo->pOverlapped = &rBuffer;
+
+			if (QueueUserAPC(ReadCompleted, GetCurrentThread(), (ULONG_PTR)pInfo) == 0)
+				THROW_CORE_EXCEPTION(eErr_InternalProblem);
+		}
+		else
+		{
+			APCINFO* pInfo = new APCINFO;
+
+			if (rBuffer.GetFilePosition() >= spFileDesc->GetFileInfo().GetLength64())
+			{
+				rBuffer.SetStatusCode(STATUS_END_OF_FILE);
+				rBuffer.SetBytesTransferred(0);
+				pInfo->dwError = ERROR_HANDLE_EOF;
+				pInfo->dwNumberOfBytesTransfered = 0;
+				pInfo->pOverlapped = &rBuffer;
+			}
+			else if (rBuffer.GetFilePosition() + rBuffer.GetRequestedDataSize() > spFileDesc->GetFileInfo().GetLength64())
+			{
+				file_size_t fsRemaining = spFileDesc->GetFileInfo().GetLength64() - rBuffer.GetFilePosition();
+
+				rBuffer.SetStatusCode(STATUS_OK);
+				rBuffer.SetBytesTransferred(fsRemaining);
+				pInfo->dwError = ERROR_SUCCESS;
+				pInfo->dwNumberOfBytesTransfered = boost::numeric_cast<DWORD>(fsRemaining);
+				pInfo->pOverlapped = &rBuffer;
+			}
+			else
+			{
+				rBuffer.SetStatusCode(STATUS_OK);
+				rBuffer.SetBytesTransferred(rBuffer.GetRequestedDataSize());
+				pInfo->dwError = ERROR_SUCCESS;
+				pInfo->dwNumberOfBytesTransfered = rBuffer.GetRequestedDataSize();
+				pInfo->pOverlapped = &rBuffer;
+			}
+
+			GenerateBufferContent(rBuffer);
+
+			if (QueueUserAPC(ReadCompleted, GetCurrentThread(), (ULONG_PTR)pInfo) == 0)
+				THROW_CORE_EXCEPTION(eErr_InternalProblem);
+		}
+
+		return true;
+	}
+
+	bool TFakeFilesystemFile::Truncate(long long llNewSize)
+	{
+		if (!IsOpen())
+			THROW_CORE_EXCEPTION(eErr_InternalProblem);
+
+		// check if we're reading the undamaged data
+		TFakeFileDescriptionPtr spFileDesc = m_pFilesystem->FindFileByLocation(m_pathFile);
+		if (!spFileDesc)
+			return false;
+
+		spFileDesc->GetFileInfo().SetLength64(llNewSize);
+		return true;
+	}
+
+	bool TFakeFilesystemFile::OpenExistingForWriting(bool bNoBuffering)
+	{
+		TFakeFileDescriptionPtr spFileDesc = m_pFilesystem->FindFileByLocation(m_pathFile);
+		if (!spFileDesc)
+			return false;
+
+		Close();
+
+		m_bIsOpen = true;
+		m_bNoBuffering = bNoBuffering;
+		m_bModeReading = false;
+
+		return true;
+	}
+
+	bool TFakeFilesystemFile::CreateNewForWriting(bool bNoBuffering)
+	{
+		TFakeFileDescriptionPtr spFileDesc = m_pFilesystem->FindFileByLocation(m_pathFile);
+		if(!spFileDesc)
+		{
+			TFakeFileDescriptionPtr parentDesc = m_pFilesystem->FindFileByLocation(m_pathFile.GetParent());
+			if (!parentDesc)
+				return false;
+
+			FILETIME ftCurrent = m_pFilesystem->GetCurrentFileTime();
+			TFakeFileDescriptionPtr spNewFile(std::make_shared<TFakeFileDescription>(
+				TFileInfo(nullptr, m_pathFile, FILE_ATTRIBUTE_NORMAL, 0, ftCurrent, ftCurrent, ftCurrent, 0),
+				TSparseRangeMap()
+				));
+
+			m_pFilesystem->m_listFilesystemContent.push_back(spNewFile);
+		}
+
+		Close();
+
+		m_bIsOpen = true;
+		m_bNoBuffering = bNoBuffering;
+		m_bModeReading = false;
+
+		return true;
+	}
+
+	bool TFakeFilesystemFile::OpenExistingForReading(bool bNoBuffering)
+	{
+		TFakeFileDescriptionPtr spFileDesc = m_pFilesystem->FindFileByLocation(m_pathFile);
+		if (!spFileDesc)
+			return false;
+
+		Close();
+
+		m_bIsOpen = true;
+		m_bNoBuffering = bNoBuffering;
+		m_bModeReading = true;
+
+		return true;
+	}
+
+	void TFakeFilesystemFile::GenerateBufferContent(TOverlappedDataBuffer &rBuffer)
+	{
+		if(rBuffer.GetBytesTransferred() > 0)
+		{
+			ZeroMemory(rBuffer.GetBufferPtr(), rBuffer.GetBufferSize());
+
+			size_t stCount = rBuffer.GetBytesTransferred() / sizeof(file_size_t);
+			if (stCount > 0)
+			{
+				file_size_t* pBuffer = (file_size_t*)rBuffer.GetBufferPtr();
+				for (size_t stIndex = 0; stIndex != stCount; ++stIndex)
+				{
+					pBuffer[stIndex] = rBuffer.GetFilePosition() + stIndex * sizeof(file_size_t);
+				}
+			}
+		}
+	}
+}
Index: src/libchcore/TFakeFilesystemFile.h
===================================================================
diff -u -r5efb534fc5440a7ab779d2514a00486ecb58e845 -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/TFakeFilesystemFile.h	(.../TFakeFilesystemFile.h)	(revision 5efb534fc5440a7ab779d2514a00486ecb58e845)
+++ src/libchcore/TFakeFilesystemFile.h	(.../TFakeFilesystemFile.h)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -20,19 +20,45 @@
 #define __TFAKEFILESYSTEMFILE_H__
 
 #include "libchcore.h"
+#include "IFilesystemFile.h"
+#include "TFakeFileDescription.h"
 
-BEGIN_CHCORE_NAMESPACE
-
-class LIBCHCORE_API TFakeFilesystemFile
+namespace chcore
 {
-public:
-	TFakeFilesystemFile();
-	~TFakeFilesystemFile();
+	class TFakeFilesystem;
 
-private:
-	
-};
+	class LIBCHCORE_API TFakeFilesystemFile : public IFilesystemFile
+	{
+	public:
+		TFakeFilesystemFile(const TSmartPath& pathFile, TFakeFilesystem* pFilesystem);
+		~TFakeFilesystemFile();
 
-END_CHCORE_NAMESPACE
+		virtual bool OpenExistingForReading(bool bNoBuffering) override;
+		virtual bool CreateNewForWriting(bool bNoBuffering) override;
+		virtual bool OpenExistingForWriting(bool bNoBuffering) override;
+		virtual bool Truncate(long long ullNewSize) override;
+		virtual bool ReadFile(TOverlappedDataBuffer& rBuffer) override;
 
+		void GenerateBufferContent(TOverlappedDataBuffer &rBuffer);
+
+		virtual bool WriteFile(TOverlappedDataBuffer& rBuffer) override;
+		virtual bool FinalizeFile(TOverlappedDataBuffer& rBuffer) override;
+		virtual bool IsOpen() const override;
+		virtual unsigned long long GetFileSize() const override;
+		virtual void Close() override;
+
+		virtual TSmartPath GetFilePath() const override;
+
+	private:
+#pragma warning(push)
+#pragma warning(disable: 4251)
+		TSmartPath m_pathFile;
+#pragma warning(pop)
+		bool m_bIsOpen;
+		bool m_bNoBuffering;
+		bool m_bModeReading;
+		TFakeFilesystem* m_pFilesystem;
+	};
+}
+
 #endif
Index: src/libchcore/TFakeFilesystemFind.cpp
===================================================================
diff -u -r5efb534fc5440a7ab779d2514a00486ecb58e845 -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/TFakeFilesystemFind.cpp	(.../TFakeFilesystemFind.cpp)	(revision 5efb534fc5440a7ab779d2514a00486ecb58e845)
+++ src/libchcore/TFakeFilesystemFind.cpp	(.../TFakeFilesystemFind.cpp)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -18,15 +18,65 @@
 // ============================================================================
 #include "stdafx.h"
 #include "TFakeFilesystemFind.h"
+#include "TFakeFilesystem.h"
+#include "TCoreException.h"
+#include "ErrorCodes.h"
+#include "TStringPattern.h"
 
-BEGIN_CHCORE_NAMESPACE
-
-TFakeFilesystemFind::TFakeFilesystemFind()
+namespace chcore
 {
-}
+	TFakeFilesystemFind::TFakeFilesystemFind(const TSmartPath& pathDir, const TSmartPath& pathMask, TFakeFilesystem* pFakeFilesystem) :
+		m_pathDir(pathDir),
+		m_pathMask(pathMask),
+		m_pFilesystem(pFakeFilesystem)
+	{
+		if (!pFakeFilesystem)
+			THROW_CORE_EXCEPTION(eErr_InvalidArgument);
+	}
 
-TFakeFilesystemFind::~TFakeFilesystemFind()
-{
-}
+	TFakeFilesystemFind::~TFakeFilesystemFind()
+	{
+	}
 
-END_CHCORE_NAMESPACE
+	bool TFakeFilesystemFind::FindNext(TFileInfoPtr& rspFileInfo)
+	{
+		if (!m_bScanned)
+		{
+			Prescan();
+			m_bScanned = true;
+		}
+
+		if (m_iterCurrent == m_vItems.end())
+			return false;
+
+		*rspFileInfo = *m_iterCurrent++;
+		return true;
+	}
+
+	void TFakeFilesystemFind::Close()
+	{
+		m_vItems.clear();
+		m_iterCurrent = m_vItems.end();
+		m_bScanned = false;
+	}
+
+	void TFakeFilesystemFind::Prescan()
+	{
+		m_vItems.clear();
+		m_iterCurrent = m_vItems.end();
+
+		for (TFakeFileDescriptionPtr spFileInfoDesc : m_pFilesystem->m_listFilesystemContent)
+		{
+			if (spFileInfoDesc->GetFileInfo().GetFullFilePath().StartsWith(m_pathDir))
+			{
+				TStringPattern pattern(m_pathMask.ToString());
+				if (pattern.Matches(spFileInfoDesc->GetFileInfo().GetFullFilePath().ToWString()))
+				{
+					m_vItems.push_back(spFileInfoDesc->GetFileInfo());
+				}
+			}
+		}
+
+		m_iterCurrent = m_vItems.begin();
+	}
+}
Index: src/libchcore/TFakeFilesystemFind.h
===================================================================
diff -u -r5efb534fc5440a7ab779d2514a00486ecb58e845 -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/TFakeFilesystemFind.h	(.../TFakeFilesystemFind.h)	(revision 5efb534fc5440a7ab779d2514a00486ecb58e845)
+++ src/libchcore/TFakeFilesystemFind.h	(.../TFakeFilesystemFind.h)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -20,19 +20,37 @@
 #define __TFAKEFILESYSTEMFIND_H__
 
 #include "libchcore.h"
+#include "IFilesystemFind.h"
+#include "TPath.h"
 
-BEGIN_CHCORE_NAMESPACE
-
-class LIBCHCORE_API TFakeFilesystemFind
+namespace chcore
 {
-public:
-	TFakeFilesystemFind();
-	~TFakeFilesystemFind();
+	class TFakeFilesystem;
 
-private:
+	class LIBCHCORE_API TFakeFilesystemFind : public IFilesystemFind
+	{
+	public:
+		TFakeFilesystemFind(const TSmartPath& pathDir, const TSmartPath& pathMask, TFakeFilesystem* pFakeFilesystem);
+		~TFakeFilesystemFind();
 
-};
+		virtual bool FindNext(TFileInfoPtr& rspFileInfo) override;
+		virtual void Close() override;
 
-END_CHCORE_NAMESPACE
+	private:
+		void Prescan();
 
+	private:
+		TSmartPath m_pathDir;
+		TSmartPath m_pathMask;
+		TFakeFilesystem* m_pFilesystem;
+
+#pragma warning(push)
+#pragma warning(disable: 4251)
+		bool m_bScanned = false;
+		std::vector<TFileInfo> m_vItems;
+		std::vector<TFileInfo>::iterator m_iterCurrent;
+#pragma warning(pop)
+	};
+}
+
 #endif
Index: src/libchcore/TFakeVolumeInfo.cpp
===================================================================
diff -u
--- src/libchcore/TFakeVolumeInfo.cpp	(revision 0)
+++ src/libchcore/TFakeVolumeInfo.cpp	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -0,0 +1,65 @@
+// ============================================================================
+//  Copyright (C) 2001-2015 by Jozef Starosczyk
+//  ixen@copyhandler.com
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU Library General Public License
+//  (version 2) as published by the Free Software Foundation;
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU Library General Public
+//  License along with this program; if not, write to the
+//  Free Software Foundation, Inc.,
+//  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// ============================================================================
+#include "stdafx.h"
+#include "TFakeVolumeInfo.h"
+
+BEGIN_CHCORE_NAMESPACE
+
+TFakeVolumeInfo::TFakeVolumeInfo(file_size_t fsTotalSize, UINT uiDriveType, DWORD dwPhysicalDriveNumber) :
+	m_fsTotalSize(fsTotalSize),
+	m_uiDriveType(uiDriveType),
+	m_dwPhysicalDriveNumber(dwPhysicalDriveNumber)
+{
+}
+
+TFakeVolumeInfo::~TFakeVolumeInfo()
+{
+}
+
+void TFakeVolumeInfo::SetTotalSize(file_size_t fsTotalSize)
+{
+	m_fsTotalSize = fsTotalSize;
+}
+
+file_size_t TFakeVolumeInfo::GetTotalSize() const
+{
+	return m_fsTotalSize;
+}
+
+void TFakeVolumeInfo::SetDriveType(UINT uiDriveType)
+{
+	m_uiDriveType = uiDriveType;
+}
+
+UINT TFakeVolumeInfo::GetDriveType() const
+{
+	return m_uiDriveType;
+}
+
+void TFakeVolumeInfo::SetPhysicalDriveNumber(DWORD dwDriveNumber)
+{
+	m_dwPhysicalDriveNumber = dwDriveNumber;
+}
+
+DWORD TFakeVolumeInfo::GetPhysicalDriveNumber() const
+{
+	return m_dwPhysicalDriveNumber;
+}
+
+END_CHCORE_NAMESPACE
Index: src/libchcore/TFakeVolumeInfo.h
===================================================================
diff -u
--- src/libchcore/TFakeVolumeInfo.h	(revision 0)
+++ src/libchcore/TFakeVolumeInfo.h	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -0,0 +1,50 @@
+// ============================================================================
+//  Copyright (C) 2001-2015 by Jozef Starosczyk
+//  ixen@copyhandler.com
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU Library General Public License
+//  (version 2) as published by the Free Software Foundation;
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU Library General Public
+//  License along with this program; if not, write to the
+//  Free Software Foundation, Inc.,
+//  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// ============================================================================
+#ifndef __TFAKEVOLUMEINFO_H__
+#define __TFAKEVOLUMEINFO_H__
+
+#include "libchcore.h"
+#include "CommonDataTypes.h"
+
+BEGIN_CHCORE_NAMESPACE
+
+class LIBCHCORE_API TFakeVolumeInfo
+{
+public:
+	TFakeVolumeInfo(file_size_t fsTotalSize, UINT uiDriveType, DWORD dwPhysicalDriveNumber);
+	~TFakeVolumeInfo();
+
+	void SetTotalSize(file_size_t fsTotalSize);
+	file_size_t GetTotalSize() const;
+
+	void SetDriveType(UINT uiDriveType);
+	UINT GetDriveType() const;
+
+	void SetPhysicalDriveNumber(DWORD dwDriveNumber);
+	DWORD GetPhysicalDriveNumber() const;
+
+private:
+	file_size_t m_fsTotalSize;
+	UINT m_uiDriveType;
+	DWORD m_dwPhysicalDriveNumber;
+};
+
+END_CHCORE_NAMESPACE
+
+#endif
Index: src/libchcore/TFileInfo.cpp
===================================================================
diff -u -r95a466ca0a4f95851dcacf2b80e2084e0168b7e4 -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/TFileInfo.cpp	(.../TFileInfo.cpp)	(revision 95a466ca0a4f95851dcacf2b80e2084e0168b7e4)
+++ src/libchcore/TFileInfo.cpp	(.../TFileInfo.cpp)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -25,303 +25,329 @@
 #include "ISerializerRowData.h"
 #include "ISerializerContainer.h"
 
-BEGIN_CHCORE_NAMESPACE
+namespace chcore
+{
+	//////////////////////////////////////////////////////////////////////
+	// Construction/Destruction
+	//////////////////////////////////////////////////////////////////////
 
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
+	TFileInfo::TFileInfo() :
+		m_pathFile(m_setModifications),
+		m_spBasePathData(m_setModifications),
+		m_dwAttributes(m_setModifications, 0),
+		m_uhFileSize(m_setModifications, 0),
+		m_ftCreation(m_setModifications),
+		m_ftLastAccess(m_setModifications),
+		m_ftLastWrite(m_setModifications),
+		m_uiFlags(m_setModifications, 0),
+		m_oidObjectID(0)
+	{
+		m_setModifications[eMod_Added] = true;
+	}
 
-TFileInfo::TFileInfo() :
-	m_pathFile(m_setModifications),
-	m_spBasePathData(m_setModifications),
-	m_dwAttributes(m_setModifications, 0),
-	m_uhFileSize(m_setModifications, 0),
-	m_ftCreation(m_setModifications),
-	m_ftLastAccess(m_setModifications),
-	m_ftLastWrite(m_setModifications),
-	m_uiFlags(m_setModifications, 0),
-	m_oidObjectID(0)
-{
-	m_setModifications[eMod_Added] = true;
-}
+	TFileInfo::TFileInfo(const TFileInfo& rSrc) :
+		m_pathFile(m_setModifications, rSrc.m_pathFile),
+		m_spBasePathData(m_setModifications, rSrc.m_spBasePathData),
+		m_dwAttributes(m_setModifications, rSrc.m_dwAttributes),
+		m_uhFileSize(m_setModifications, rSrc.m_uhFileSize),
+		m_ftCreation(m_setModifications, rSrc.m_ftCreation),
+		m_ftLastAccess(m_setModifications, rSrc.m_ftLastAccess),
+		m_ftLastWrite(m_setModifications, rSrc.m_ftLastWrite),
+		m_uiFlags(m_setModifications, rSrc.m_uiFlags),
+		m_oidObjectID(rSrc.m_oidObjectID)
+	{
+		m_setModifications = rSrc.m_setModifications;
+	}
 
-TFileInfo::TFileInfo(const TFileInfo& rSrc) :
-	m_pathFile(m_setModifications, rSrc.m_pathFile),
-	m_spBasePathData(m_setModifications, rSrc.m_spBasePathData),
-	m_dwAttributes(m_setModifications, rSrc.m_dwAttributes),
-	m_uhFileSize(m_setModifications, rSrc.m_uhFileSize),
-	m_ftCreation(m_setModifications, rSrc.m_ftCreation),
-	m_ftLastAccess(m_setModifications, rSrc.m_ftLastAccess),
-	m_ftLastWrite(m_setModifications, rSrc.m_ftLastWrite),
-	m_uiFlags(m_setModifications, rSrc.m_uiFlags),
-	m_oidObjectID(rSrc.m_oidObjectID)
-{
-	m_setModifications = rSrc.m_setModifications;
-}
+	TFileInfo::TFileInfo(const TBasePathDataPtr& spBasePathData, const TSmartPath& rpathFile, DWORD dwAttributes, ULONGLONG uhFileSize, FILETIME ftCreation, FILETIME ftLastAccess, FILETIME ftLastWrite, uint_t uiFlags) :
+		m_pathFile(m_setModifications, rpathFile),
+		m_spBasePathData(m_setModifications, spBasePathData),
+		m_dwAttributes(m_setModifications, dwAttributes),
+		m_uhFileSize(m_setModifications, uhFileSize),
+		m_ftCreation(m_setModifications, ftCreation),
+		m_ftLastAccess(m_setModifications, ftLastAccess),
+		m_ftLastWrite(m_setModifications, ftLastWrite),
+		m_uiFlags(m_setModifications, uiFlags),
+		m_oidObjectID(0)
+	{
+		if (m_spBasePathData.Get())
+			m_pathFile.Modify().MakeRelativePath(m_spBasePathData.Get()->GetSrcPath());
+	}
 
-TFileInfo::~TFileInfo()
-{
-}
+	TFileInfo::~TFileInfo()
+	{
+	}
 
-TFileInfo& TFileInfo::operator=(const TFileInfo& rSrc)
-{
-	if(this != & rSrc)
+	TFileInfo& TFileInfo::operator=(const TFileInfo& rSrc)
 	{
-		m_pathFile = rSrc.m_pathFile;
-		m_spBasePathData = rSrc.m_spBasePathData;
-		m_dwAttributes = rSrc.m_dwAttributes;
-		m_uhFileSize = rSrc.m_uhFileSize;
-		m_ftCreation = rSrc.m_ftCreation;
-		m_ftLastAccess = rSrc.m_ftLastAccess;
-		m_ftLastWrite = rSrc.m_ftLastWrite;
-		m_uiFlags = rSrc.m_uiFlags;
-		m_oidObjectID = rSrc.m_oidObjectID;
-		m_setModifications = rSrc.m_setModifications;
+		if (this != &rSrc)
+		{
+			m_pathFile = rSrc.m_pathFile;
+			m_spBasePathData = rSrc.m_spBasePathData;
+			m_dwAttributes = rSrc.m_dwAttributes;
+			m_uhFileSize = rSrc.m_uhFileSize;
+			m_ftCreation = rSrc.m_ftCreation;
+			m_ftLastAccess = rSrc.m_ftLastAccess;
+			m_ftLastWrite = rSrc.m_ftLastWrite;
+			m_uiFlags = rSrc.m_uiFlags;
+			m_oidObjectID = rSrc.m_oidObjectID;
+			m_setModifications = rSrc.m_setModifications;
+		}
+
+		return *this;
 	}
 
-	return *this;
-}
+	void TFileInfo::Init(const TBasePathDataPtr& spBasePathData, const TSmartPath& rpathFile,
+		DWORD dwAttributes, ULONGLONG uhFileSize, FILETIME ftCreation, FILETIME ftLastAccess, FILETIME ftLastWrite,
+		uint_t uiFlags)
+	{
+		m_pathFile = rpathFile;
+		m_spBasePathData = spBasePathData;
+		m_dwAttributes = dwAttributes;
+		m_uhFileSize = uhFileSize;
+		m_ftCreation = ftCreation;
+		m_ftLastAccess = ftLastAccess;
+		m_ftLastWrite = ftLastWrite;
+		m_uiFlags = uiFlags;
 
-void TFileInfo::Init(const TBasePathDataPtr& spBasePathData, const TSmartPath& rpathFile,
-					DWORD dwAttributes, ULONGLONG uhFileSize, FILETIME ftCreation, FILETIME ftLastAccess, FILETIME ftLastWrite,
-					uint_t uiFlags)
-{
-	m_pathFile = rpathFile;
-	m_spBasePathData = spBasePathData;
-	m_dwAttributes = dwAttributes;
-	m_uhFileSize = uhFileSize;
-	m_ftCreation = ftCreation;
-	m_ftLastAccess = ftLastAccess;
-	m_ftLastWrite = ftLastWrite;
-	m_uiFlags = uiFlags;
+		if (m_spBasePathData.Get())
+			m_pathFile.Modify().MakeRelativePath(m_spBasePathData.Get()->GetSrcPath());
+	}
 
-	if(m_spBasePathData.Get())
-		m_pathFile.Modify().MakeRelativePath(m_spBasePathData.Get()->GetSrcPath());
-}
+	void TFileInfo::Init(const TSmartPath& rpathFile, DWORD dwAttributes, ULONGLONG uhFileSize, FILETIME ftCreation, FILETIME ftLastAccess, FILETIME ftLastWrite,
+		uint_t uiFlags)
+	{
+		m_pathFile = rpathFile;
+		m_spBasePathData.Modify().reset();
+		m_dwAttributes = dwAttributes;
+		m_uhFileSize = uhFileSize;
+		m_ftCreation = ftCreation;
+		m_ftLastAccess = ftLastAccess;
+		m_ftLastWrite = ftLastWrite;
+		m_uiFlags = uiFlags;
+	}
 
-void TFileInfo::Init(const TSmartPath& rpathFile, DWORD dwAttributes, ULONGLONG uhFileSize, FILETIME ftCreation, FILETIME ftLastAccess, FILETIME ftLastWrite,
-					 uint_t uiFlags)
-{
-	m_pathFile = rpathFile;
-	m_spBasePathData.Modify().reset();
-	m_dwAttributes = dwAttributes;
-	m_uhFileSize = uhFileSize;
-	m_ftCreation = ftCreation;
-	m_ftLastAccess = ftLastAccess;
-	m_ftLastWrite = ftLastWrite;
-	m_uiFlags = uiFlags;
-}
+	void TFileInfo::SetParentObject(const TBasePathDataPtr& spBasePathData)
+	{
+		// cannot set parent object if there is already one specified
+		if (m_spBasePathData.Get())
+			THROW_CORE_EXCEPTION(eErr_InvalidArgument);
 
-void TFileInfo::SetParentObject(const TBasePathDataPtr& spBasePathData)
-{
-	// cannot set parent object if there is already one specified
-	if(m_spBasePathData.Get())
-		THROW_CORE_EXCEPTION(eErr_InvalidArgument);
+		m_spBasePathData = spBasePathData;
+		if (m_spBasePathData.Get())
+			m_pathFile.Modify().MakeRelativePath(m_spBasePathData.Get()->GetSrcPath());
+	}
 
-	m_spBasePathData = spBasePathData;
-	if(m_spBasePathData.Get())
-		m_pathFile.Modify().MakeRelativePath(m_spBasePathData.Get()->GetSrcPath());
-}
+	bool TFileInfo::operator==(const TFileInfo& rInfo) const
+	{
+		return (rInfo.m_dwAttributes == m_dwAttributes &&
+			rInfo.m_ftCreation.Get() == m_ftCreation.Get() &&
+			rInfo.m_ftLastWrite.Get() == m_ftLastWrite.Get() &&
+			rInfo.m_uhFileSize == m_uhFileSize);
+	}
 
-bool TFileInfo::operator==(const TFileInfo& rInfo) const
-{
-	return (rInfo.m_dwAttributes == m_dwAttributes &&
-		rInfo.m_ftCreation.Get() == m_ftCreation.Get() &&
-		rInfo.m_ftLastWrite.Get() == m_ftLastWrite.Get() &&
-		rInfo.m_uhFileSize == m_uhFileSize);
-}
+	TSmartPath TFileInfo::GetFullFilePath() const
+	{
+		if (m_spBasePathData.Get())
+		{
+			TSmartPath pathCombined = m_spBasePathData.Get()->GetSrcPath();
+			pathCombined += m_pathFile;
+			return pathCombined;
+		}
+		else
+			return m_pathFile;
+	}
 
-TSmartPath TFileInfo::GetFullFilePath() const
-{
-	if(m_spBasePathData.Get())
+	object_id_t TFileInfo::GetSrcObjectID() const
 	{
-		TSmartPath pathCombined = m_spBasePathData.Get()->GetSrcPath();
-		pathCombined += m_pathFile;
-		return pathCombined;
+		if (m_spBasePathData.Get())
+			return m_spBasePathData.Get()->GetObjectID();
+		return (object_id_t)-1;
 	}
-	else
-		return m_pathFile;
-}
 
-object_id_t TFileInfo::GetSrcObjectID() const
-{
-	if(m_spBasePathData.Get())
-		return m_spBasePathData.Get()->GetObjectID();
-	return (object_id_t)-1;
-}
+	TBasePathDataPtr TFileInfo::GetBasePathData() const
+	{
+		return m_spBasePathData;
+	}
 
-TBasePathDataPtr TFileInfo::GetBasePathData() const
-{
-	return m_spBasePathData;
-}
+	void TFileInfo::MarkAsProcessed(bool bProcessed)
+	{
+		if (bProcessed)
+			m_uiFlags.Modify() |= eFlag_Processed;
+		else
+			m_uiFlags.Modify() &= ~eFlag_Processed;
+	}
 
-void TFileInfo::MarkAsProcessed(bool bProcessed)
-{
-	if(bProcessed)
-		m_uiFlags.Modify() |= eFlag_Processed;
-	else
-		m_uiFlags.Modify() &= ~eFlag_Processed;
-}
+	bool TFileInfo::IsProcessed() const
+	{
+		return m_uiFlags & eFlag_Processed;
+	}
 
-bool TFileInfo::IsProcessed() const
-{
-	return m_uiFlags & eFlag_Processed;
-}
+	ULONGLONG TFileInfo::GetLength64() const
+	{
+		return m_uhFileSize;
+	}
 
-ULONGLONG TFileInfo::GetLength64() const
-{
-	return m_uhFileSize;
-}
+	void TFileInfo::SetLength64(ULONGLONG uhSize)
+	{
+		m_uhFileSize = uhSize;
+	}
 
-void TFileInfo::SetLength64(ULONGLONG uhSize)
-{
-	m_uhFileSize=uhSize;
-}
+	void TFileInfo::SetFileTimes(const TFileTime& rCreation, const TFileTime& rLastAccess, const TFileTime& rLastWrite)
+	{
+		m_ftCreation = rCreation;
+		m_ftLastAccess = rLastAccess;
+		m_ftLastWrite = rLastWrite;
+	}
 
-const TSmartPath& TFileInfo::GetFilePath() const
-{
-	return m_pathFile;
-}
+	const TSmartPath& TFileInfo::GetFilePath() const
+	{
+		return m_pathFile;
+	}
 
-void TFileInfo::SetFilePath(const TSmartPath& tPath)
-{
-	m_pathFile = tPath;
-}
+	void TFileInfo::SetFilePath(const TSmartPath& tPath)
+	{
+		m_pathFile = tPath;
+	}
 
-const TFileTime& TFileInfo::GetCreationTime() const
-{
-	return m_ftCreation;
-}
+	const TFileTime& TFileInfo::GetCreationTime() const
+	{
+		return m_ftCreation;
+	}
 
-const TFileTime& TFileInfo::GetLastAccessTime() const
-{
-	return m_ftLastAccess;
-}
+	const TFileTime& TFileInfo::GetLastAccessTime() const
+	{
+		return m_ftLastAccess;
+	}
 
-const TFileTime& TFileInfo::GetLastWriteTime() const
-{
-	return m_ftLastWrite;
-}
+	const TFileTime& TFileInfo::GetLastWriteTime() const
+	{
+		return m_ftLastWrite;
+	}
 
-DWORD TFileInfo::GetAttributes() const
-{
-	return m_dwAttributes;
-}
+	DWORD TFileInfo::GetAttributes() const
+	{
+		return m_dwAttributes;
+	}
 
-bool TFileInfo::IsDirectory() const
-{
-	return (m_dwAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
-}
+	void TFileInfo::SetAttributes(DWORD dwAttributes)
+	{
+		m_dwAttributes = dwAttributes;
+	}
 
-bool TFileInfo::IsArchived() const
-{
-	return (m_dwAttributes & FILE_ATTRIBUTE_ARCHIVE) != 0;
-}
+	bool TFileInfo::IsDirectory() const
+	{
+		return (m_dwAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
+	}
 
-bool TFileInfo::IsReadOnly() const
-{
-	return (m_dwAttributes & FILE_ATTRIBUTE_READONLY) != 0;
-}
+	bool TFileInfo::IsArchived() const
+	{
+		return (m_dwAttributes & FILE_ATTRIBUTE_ARCHIVE) != 0;
+	}
 
-bool TFileInfo::IsCompressed() const
-{
-	return (m_dwAttributes & FILE_ATTRIBUTE_COMPRESSED) != 0;
-}
+	bool TFileInfo::IsReadOnly() const
+	{
+		return (m_dwAttributes & FILE_ATTRIBUTE_READONLY) != 0;
+	}
 
-bool TFileInfo::IsSystem() const
-{
-	return (m_dwAttributes & FILE_ATTRIBUTE_SYSTEM) != 0;
-}
+	bool TFileInfo::IsCompressed() const
+	{
+		return (m_dwAttributes & FILE_ATTRIBUTE_COMPRESSED) != 0;
+	}
 
-bool TFileInfo::IsHidden() const
-{
-	return (m_dwAttributes & FILE_ATTRIBUTE_HIDDEN) != 0;
-}
+	bool TFileInfo::IsSystem() const
+	{
+		return (m_dwAttributes & FILE_ATTRIBUTE_SYSTEM) != 0;
+	}
 
-bool TFileInfo::IsTemporary() const
-{
-	return (m_dwAttributes & FILE_ATTRIBUTE_TEMPORARY) != 0;
-}
+	bool TFileInfo::IsHidden() const
+	{
+		return (m_dwAttributes & FILE_ATTRIBUTE_HIDDEN) != 0;
+	}
 
-bool TFileInfo::IsNormal() const
-{
-	return m_dwAttributes == 0;
-}
+	bool TFileInfo::IsTemporary() const
+	{
+		return (m_dwAttributes & FILE_ATTRIBUTE_TEMPORARY) != 0;
+	}
 
-void TFileInfo::Store(const ISerializerContainerPtr& spContainer) const
-{
-	if(m_setModifications.any())
+	bool TFileInfo::IsNormal() const
 	{
-		ISerializerRowData& rRow = spContainer->GetRow(m_oidObjectID, m_setModifications[eMod_Added]);
+		return m_dwAttributes == 0;
+	}
 
-		if(m_setModifications[eMod_Path])
-			rRow.SetValue(_T("rel_path"), m_pathFile);
-		if(m_setModifications[eMod_BasePath])
-			rRow.SetValue(_T("base_path_id"), m_spBasePathData.Get()->GetObjectID());
-		if(m_setModifications[eMod_Attributes])
-			rRow.SetValue(_T("attr"), m_dwAttributes);
-		if(m_setModifications[eMod_FileSize])
-			rRow.SetValue(_T("size"), m_uhFileSize);
-		if(m_setModifications[eMod_TimeCreated])
-			rRow.SetValue(_T("time_created"), m_ftCreation.Get().ToUInt64());
-		if(m_setModifications[eMod_TimeLastWrite])
-			rRow.SetValue(_T("time_last_write"), m_ftLastWrite.Get().ToUInt64());
-		if(m_setModifications[eMod_TimeLastAccess])
-			rRow.SetValue(_T("time_last_access"), m_ftLastAccess.Get().ToUInt64());
-		if(m_setModifications[eMod_Flags])
-			rRow.SetValue(_T("flags"), m_uiFlags);
+	void TFileInfo::Store(const ISerializerContainerPtr& spContainer) const
+	{
+		if (m_setModifications.any())
+		{
+			ISerializerRowData& rRow = spContainer->GetRow(m_oidObjectID, m_setModifications[eMod_Added]);
 
-		m_setModifications.reset();
+			if (m_setModifications[eMod_Path])
+				rRow.SetValue(_T("rel_path"), m_pathFile);
+			if (m_setModifications[eMod_BasePath])
+				rRow.SetValue(_T("base_path_id"), m_spBasePathData.Get()->GetObjectID());
+			if (m_setModifications[eMod_Attributes])
+				rRow.SetValue(_T("attr"), m_dwAttributes);
+			if (m_setModifications[eMod_FileSize])
+				rRow.SetValue(_T("size"), m_uhFileSize);
+			if (m_setModifications[eMod_TimeCreated])
+				rRow.SetValue(_T("time_created"), m_ftCreation.Get().ToUInt64());
+			if (m_setModifications[eMod_TimeLastWrite])
+				rRow.SetValue(_T("time_last_write"), m_ftLastWrite.Get().ToUInt64());
+			if (m_setModifications[eMod_TimeLastAccess])
+				rRow.SetValue(_T("time_last_access"), m_ftLastAccess.Get().ToUInt64());
+			if (m_setModifications[eMod_Flags])
+				rRow.SetValue(_T("flags"), m_uiFlags);
+
+			m_setModifications.reset();
+		}
 	}
-}
 
-void TFileInfo::InitColumns(IColumnsDefinition& rColumns)
-{
-	rColumns.AddColumn(_T("id"), ColumnType<object_id_t>::value);
-	rColumns.AddColumn(_T("rel_path"), IColumnsDefinition::eType_path);
-	rColumns.AddColumn(_T("base_path_id"), ColumnType<object_id_t>::value);
-	rColumns.AddColumn(_T("attr"), IColumnsDefinition::eType_ulong);
-	rColumns.AddColumn(_T("size"), IColumnsDefinition::eType_ulonglong);
-	rColumns.AddColumn(_T("time_created"), IColumnsDefinition::eType_ulonglong);
-	rColumns.AddColumn(_T("time_last_write"), IColumnsDefinition::eType_ulonglong);
-	rColumns.AddColumn(_T("time_last_access"), IColumnsDefinition::eType_ulonglong);
-	rColumns.AddColumn(_T("flags"), IColumnsDefinition::eType_uint);
-}
+	void TFileInfo::InitColumns(IColumnsDefinition& rColumns)
+	{
+		rColumns.AddColumn(_T("id"), ColumnType<object_id_t>::value);
+		rColumns.AddColumn(_T("rel_path"), IColumnsDefinition::eType_path);
+		rColumns.AddColumn(_T("base_path_id"), ColumnType<object_id_t>::value);
+		rColumns.AddColumn(_T("attr"), IColumnsDefinition::eType_ulong);
+		rColumns.AddColumn(_T("size"), IColumnsDefinition::eType_ulonglong);
+		rColumns.AddColumn(_T("time_created"), IColumnsDefinition::eType_ulonglong);
+		rColumns.AddColumn(_T("time_last_write"), IColumnsDefinition::eType_ulonglong);
+		rColumns.AddColumn(_T("time_last_access"), IColumnsDefinition::eType_ulonglong);
+		rColumns.AddColumn(_T("flags"), IColumnsDefinition::eType_uint);
+	}
 
-void TFileInfo::Load(const ISerializerRowReaderPtr& spRowReader, const TBasePathDataContainerPtr& spSrcContainer)
-{
-	size_t stBaseObjectID = 0;
-	unsigned long long ullTime = 0;
-	spRowReader->GetValue(_T("id"), m_oidObjectID);
-	spRowReader->GetValue(_T("rel_path"), m_pathFile.Modify());
-	spRowReader->GetValue(_T("base_path_id"), stBaseObjectID);
-	spRowReader->GetValue(_T("attr"), m_dwAttributes.Modify());
-	spRowReader->GetValue(_T("size"), m_uhFileSize.Modify());
+	void TFileInfo::Load(const ISerializerRowReaderPtr& spRowReader, const TBasePathDataContainerPtr& spSrcContainer)
+	{
+		size_t stBaseObjectID = 0;
+		unsigned long long ullTime = 0;
+		spRowReader->GetValue(_T("id"), m_oidObjectID);
+		spRowReader->GetValue(_T("rel_path"), m_pathFile.Modify());
+		spRowReader->GetValue(_T("base_path_id"), stBaseObjectID);
+		spRowReader->GetValue(_T("attr"), m_dwAttributes.Modify());
+		spRowReader->GetValue(_T("size"), m_uhFileSize.Modify());
 
-	spRowReader->GetValue(_T("time_created"), ullTime);
-	m_ftCreation.Modify().FromUInt64(ullTime);
+		spRowReader->GetValue(_T("time_created"), ullTime);
+		m_ftCreation.Modify().FromUInt64(ullTime);
 
-	spRowReader->GetValue(_T("time_last_write"), ullTime);
-	m_ftLastWrite.Modify().FromUInt64(ullTime);
+		spRowReader->GetValue(_T("time_last_write"), ullTime);
+		m_ftLastWrite.Modify().FromUInt64(ullTime);
 
-	spRowReader->GetValue(_T("time_last_access"), ullTime);
-	m_ftLastAccess.Modify().FromUInt64(ullTime);
+		spRowReader->GetValue(_T("time_last_access"), ullTime);
+		m_ftLastAccess.Modify().FromUInt64(ullTime);
 
-	spRowReader->GetValue(_T("flags"), m_uiFlags.Modify());
+		spRowReader->GetValue(_T("flags"), m_uiFlags.Modify());
 
-	m_spBasePathData = spSrcContainer->FindByID(stBaseObjectID);
+		m_spBasePathData = spSrcContainer->FindByID(stBaseObjectID);
 
-	m_setModifications.reset();
-}
+		m_setModifications.reset();
+	}
 
-object_id_t TFileInfo::GetObjectID() const
-{
-	return m_oidObjectID;
-}
+	object_id_t TFileInfo::GetObjectID() const
+	{
+		return m_oidObjectID;
+	}
 
-void TFileInfo::SetObjectID(object_id_t oidObjectID)
-{
-	m_oidObjectID = oidObjectID;
+	void TFileInfo::SetObjectID(object_id_t oidObjectID)
+	{
+		m_oidObjectID = oidObjectID;
+	}
 }
-
-END_CHCORE_NAMESPACE
Index: src/libchcore/TFileInfo.h
===================================================================
diff -u -ra44714d5c7ec0f50a376f4d0ea919ee5a224f834 -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/TFileInfo.h	(.../TFileInfo.h)	(revision a44714d5c7ec0f50a376f4d0ea919ee5a224f834)
+++ src/libchcore/TFileInfo.h	(.../TFileInfo.h)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -29,117 +29,119 @@
 #include "TSharedModificationTracker.h"
 #include "TFileTime.h"
 
-BEGIN_CHCORE_NAMESPACE
-
-// CFileInfo flags
-
-class LIBCHCORE_API TFileInfo
+namespace chcore
 {
-public:
-	enum EFlags
+	class LIBCHCORE_API TFileInfo
 	{
-		// flag stating that file has been processed (used to determine if file can be deleted at the end of copying)
-		eFlag_Processed = 1,
-	};
+	public:
+		enum EFlags
+		{
+			// flag stating that file has been processed (used to determine if file can be deleted at the end of copying)
+			eFlag_Processed = 1,
+		};
 
-public:
-	TFileInfo();
-	TFileInfo(const TFileInfo& rSrc);
-	~TFileInfo();
+	public:
+		TFileInfo();
+		TFileInfo(const TFileInfo& rSrc);
+		TFileInfo(const TBasePathDataPtr& spBasePathData, const TSmartPath& rpathFile,
+			DWORD dwAttributes, ULONGLONG uhFileSize, FILETIME ftCreation, FILETIME ftLastAccess, FILETIME ftLastWrite,
+			uint_t uiFlags);
+		~TFileInfo();
 
-	TFileInfo& operator=(const TFileInfo& rSrc);
+		TFileInfo& operator=(const TFileInfo& rSrc);
 
-	// operators
-	bool operator==(const TFileInfo& rInfo) const;
+		// operators
+		bool operator==(const TFileInfo& rInfo) const;
 
-	// with base path
-	void Init(const TBasePathDataPtr& spBasePathData, const TSmartPath& rpathFile,
-		DWORD dwAttributes, ULONGLONG uhFileSize, FILETIME ftCreation, FILETIME ftLastAccess, FILETIME ftLastWrite,
-		uint_t uiFlags);
+		// with base path
+		void Init(const TBasePathDataPtr& spBasePathData, const TSmartPath& rpathFile,
+			DWORD dwAttributes, ULONGLONG uhFileSize, FILETIME ftCreation, FILETIME ftLastAccess, FILETIME ftLastWrite,
+			uint_t uiFlags);
 
-	// without base path
-	void Init(const TSmartPath& rpathFile, DWORD dwAttributes, ULONGLONG uhFileSize, FILETIME ftCreation,
-		FILETIME ftLastAccess, FILETIME ftLastWrite, uint_t uiFlags);
+		// without base path
+		void Init(const TSmartPath& rpathFile, DWORD dwAttributes, ULONGLONG uhFileSize, FILETIME ftCreation,
+			FILETIME ftLastAccess, FILETIME ftLastWrite, uint_t uiFlags);
 
-	// unique object id
-	object_id_t GetObjectID() const;
-	void SetObjectID(object_id_t oidObjectID);
+		// unique object id
+		object_id_t GetObjectID() const;
+		void SetObjectID(object_id_t oidObjectID);
 
-	// parent object
-	TBasePathDataPtr GetBasePathData() const;
-	void SetParentObject(const TBasePathDataPtr& spBasePathData);
-	object_id_t GetSrcObjectID() const;
+		// parent object
+		TBasePathDataPtr GetBasePathData() const;
+		void SetParentObject(const TBasePathDataPtr& spBasePathData);
+		object_id_t GetSrcObjectID() const;
 
-	// file path
-	const TSmartPath& GetFilePath() const;	// returns path with m_pathFile (probably not full)
-	TSmartPath GetFullFilePath() const;		// returns full path
-	void SetFilePath(const TSmartPath& tPath);
+		// file path
+		const TSmartPath& GetFilePath() const;	// returns path with m_pathFile (probably not full)
+		TSmartPath GetFullFilePath() const;		// returns full path
+		void SetFilePath(const TSmartPath& tPath);
 
-	// file size
-	ULONGLONG GetLength64() const;
-	void SetLength64(ULONGLONG uhSize);
+		// file size
+		ULONGLONG GetLength64() const;
+		void SetLength64(ULONGLONG uhSize);
 
-	// file times
-	const TFileTime& GetCreationTime() const;
-	const TFileTime& GetLastAccessTime() const;
-	const TFileTime& GetLastWriteTime() const;
+		// file times
+		void SetFileTimes(const TFileTime& rCreation, const TFileTime& rLastAccess, const TFileTime& rLastWrite);
+		const TFileTime& GetCreationTime() const;
+		const TFileTime& GetLastAccessTime() const;
+		const TFileTime& GetLastWriteTime() const;
 
-	// attributes
-	DWORD GetAttributes() const;
-	bool IsDirectory() const;
-	bool IsArchived() const;
-	bool IsReadOnly() const;
-	bool IsCompressed() const;
-	bool IsSystem() const;
-	bool IsHidden() const;
-	bool IsTemporary() const;
-	bool IsNormal() const;
+		// attributes
+		DWORD GetAttributes() const;
+		void SetAttributes(DWORD dwAttributes);
+		bool IsDirectory() const;
+		bool IsArchived() const;
+		bool IsReadOnly() const;
+		bool IsCompressed() const;
+		bool IsSystem() const;
+		bool IsHidden() const;
+		bool IsTemporary() const;
+		bool IsNormal() const;
 
-	void MarkAsProcessed(bool bProcessed);
-	bool IsProcessed() const;
+		void MarkAsProcessed(bool bProcessed);
+		bool IsProcessed() const;
 
-	void Store(const ISerializerContainerPtr& spContainer) const;
-	static void InitColumns(IColumnsDefinition& rColumns);
-	void Load(const ISerializerRowReaderPtr& spRowReader, const TBasePathDataContainerPtr& spSrcContainer);
+		void Store(const ISerializerContainerPtr& spContainer) const;
+		static void InitColumns(IColumnsDefinition& rColumns);
+		void Load(const ISerializerRowReaderPtr& spRowReader, const TBasePathDataContainerPtr& spSrcContainer);
 
-private:
-	enum EModifications
-	{
-		eMod_None = 0,
-		eMod_Added,
-		eMod_Path,
-		eMod_BasePath,
-		eMod_Attributes,
-		eMod_FileSize,
-		eMod_TimeCreated,
-		eMod_TimeLastAccess,
-		eMod_TimeLastWrite,
-		eMod_Flags,
+	private:
+		enum EModifications
+		{
+			eMod_None = 0,
+			eMod_Added,
+			eMod_Path,
+			eMod_BasePath,
+			eMod_Attributes,
+			eMod_FileSize,
+			eMod_TimeCreated,
+			eMod_TimeLastAccess,
+			eMod_TimeLastWrite,
+			eMod_Flags,
 
-		// do not use - must be the last value in this enum
-		eMod_Last
-	};
+			// do not use - must be the last value in this enum
+			eMod_Last
+		};
 
 #pragma warning(push)
 #pragma warning(disable: 4251)
-	typedef std::bitset<eMod_Last> Bitset;
-	mutable Bitset m_setModifications;
+		typedef std::bitset<eMod_Last> Bitset;
+		mutable Bitset m_setModifications;
 
-	object_id_t m_oidObjectID;
+		object_id_t m_oidObjectID;
 
-	TSharedModificationTracker<TSmartPath, Bitset, eMod_Path> m_pathFile;
-	TSharedModificationTracker<TBasePathDataPtr, Bitset, eMod_BasePath> m_spBasePathData;
-	TSharedModificationTracker<DWORD, Bitset, eMod_Attributes> m_dwAttributes;	// attributes
-	TSharedModificationTracker<ULONGLONG, Bitset, eMod_FileSize> m_uhFileSize;
-	TSharedModificationTracker<TFileTime, Bitset, eMod_TimeCreated> m_ftCreation;
-	TSharedModificationTracker<TFileTime, Bitset, eMod_TimeLastAccess> m_ftLastAccess;
-	TSharedModificationTracker<TFileTime, Bitset, eMod_TimeLastWrite> m_ftLastWrite;
-	TSharedModificationTracker<uint_t, Bitset, eMod_Flags> m_uiFlags;
+		TSharedModificationTracker<TSmartPath, Bitset, eMod_Path> m_pathFile;
+		TSharedModificationTracker<TBasePathDataPtr, Bitset, eMod_BasePath> m_spBasePathData;
+		TSharedModificationTracker<DWORD, Bitset, eMod_Attributes> m_dwAttributes;	// attributes
+		TSharedModificationTracker<ULONGLONG, Bitset, eMod_FileSize> m_uhFileSize;
+		TSharedModificationTracker<TFileTime, Bitset, eMod_TimeCreated> m_ftCreation;
+		TSharedModificationTracker<TFileTime, Bitset, eMod_TimeLastAccess> m_ftLastAccess;
+		TSharedModificationTracker<TFileTime, Bitset, eMod_TimeLastWrite> m_ftLastWrite;
+		TSharedModificationTracker<uint_t, Bitset, eMod_Flags> m_uiFlags;
 #pragma warning(pop)
-};
+	};
 
-typedef boost::shared_ptr<TFileInfo> TFileInfoPtr;
+	typedef boost::shared_ptr<TFileInfo> TFileInfoPtr;
+}
 
-END_CHCORE_NAMESPACE
-
 #endif
Index: src/libchcore/TLocalFilesystem.cpp
===================================================================
diff -u -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/TLocalFilesystem.cpp	(.../TLocalFilesystem.cpp)	(revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b)
+++ src/libchcore/TLocalFilesystem.cpp	(.../TLocalFilesystem.cpp)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -203,9 +203,9 @@
 	return std::shared_ptr<TLocalFilesystemFind>(new TLocalFilesystemFind(pathDir, pathMask));
 }
 
-IFilesystemFilePtr TLocalFilesystem::CreateFileObject()
+IFilesystemFilePtr TLocalFilesystem::CreateFileObject(const TSmartPath& pathFile)
 {
-	return std::shared_ptr<TLocalFilesystemFile>(new TLocalFilesystemFile());
+	return std::shared_ptr<TLocalFilesystemFile>(new TLocalFilesystemFile(pathFile));
 }
 
 TSmartPath TLocalFilesystem::PrependPathExtensionIfNeeded(const TSmartPath& pathInput)
Index: src/libchcore/TLocalFilesystem.h
===================================================================
diff -u -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/TLocalFilesystem.h	(.../TLocalFilesystem.h)	(revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b)
+++ src/libchcore/TLocalFilesystem.h	(.../TLocalFilesystem.h)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -57,7 +57,7 @@
 	virtual bool FastMove(const TSmartPath& pathSource, const TSmartPath& pathDestination) override;
 
 	virtual IFilesystemFindPtr CreateFinderObject(const TSmartPath& pathDir, const TSmartPath& pathMask) override;
-	virtual IFilesystemFilePtr CreateFileObject() override;
+	virtual IFilesystemFilePtr CreateFileObject(const TSmartPath& pathFile) override;
 
 	virtual EPathsRelation GetPathsRelation(const TSmartPath& pathFirst, const TSmartPath& pathSecond) override;
 
Index: src/libchcore/TLocalFilesystemFile.cpp
===================================================================
diff -u -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/TLocalFilesystemFile.cpp	(.../TLocalFilesystemFile.cpp)	(revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b)
+++ src/libchcore/TLocalFilesystemFile.cpp	(.../TLocalFilesystemFile.cpp)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -26,196 +26,191 @@
 #include "RoundingFunctions.h"
 #include "TLocalFilesystem.h"
 
-BEGIN_CHCORE_NAMESPACE
-
-// compile-time check - ensure the buffer granularity used for transfers are bigger than expected sector size
-static_assert(TLocalFilesystemFile::MaxSectorSize <= TBufferSizes::BufferGranularity, "Buffer granularity must be equal to or bigger than the max sector size");
-
-TLocalFilesystemFile::TLocalFilesystemFile() :
-	m_hFile(INVALID_HANDLE_VALUE),
-	m_pathFile(),
-	m_bNoBuffering(false)
+namespace chcore
 {
-}
+	// compile-time check - ensure the buffer granularity used for transfers are bigger than expected sector size
+	static_assert(TLocalFilesystemFile::MaxSectorSize <= TBufferSizes::BufferGranularity, "Buffer granularity must be equal to or bigger than the max sector size");
 
-TLocalFilesystemFile::~TLocalFilesystemFile()
-{
-	Close();
-}
+	TLocalFilesystemFile::TLocalFilesystemFile(const TSmartPath& pathFile) :
+		m_pathFile(TLocalFilesystem::PrependPathExtensionIfNeeded(pathFile)),
+		m_hFile(INVALID_HANDLE_VALUE),
+		m_bNoBuffering(false)
+	{
+		if (pathFile.IsEmpty())
+			THROW_CORE_EXCEPTION(eErr_InvalidArgument);
+	}
 
-DWORD TLocalFilesystemFile::GetFlagsAndAttributes(bool bNoBuffering) const
-{
-	return FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED | FILE_FLAG_SEQUENTIAL_SCAN | (bNoBuffering ? FILE_FLAG_NO_BUFFERING /*| FILE_FLAG_WRITE_THROUGH*/ : 0);
-}
+	TLocalFilesystemFile::~TLocalFilesystemFile()
+	{
+		Close();
+	}
 
-bool TLocalFilesystemFile::OpenExistingForReading(const TSmartPath& pathFile, bool bNoBuffering)
-{
-	Close();
+	DWORD TLocalFilesystemFile::GetFlagsAndAttributes(bool bNoBuffering) const
+	{
+		return FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED | FILE_FLAG_SEQUENTIAL_SCAN | (bNoBuffering ? FILE_FLAG_NO_BUFFERING /*| FILE_FLAG_WRITE_THROUGH*/ : 0);
+	}
 
-	m_pathFile = TLocalFilesystem::PrependPathExtensionIfNeeded(pathFile);
-	m_hFile = ::CreateFile(m_pathFile.ToString(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, GetFlagsAndAttributes(bNoBuffering), NULL);
-	if (m_hFile == INVALID_HANDLE_VALUE)
-		return false;
+	bool TLocalFilesystemFile::OpenExistingForReading(bool bNoBuffering)
+	{
+		Close();
 
-	m_bNoBuffering = bNoBuffering;
-	return true;
-}
+		m_hFile = ::CreateFile(m_pathFile.ToString(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, GetFlagsAndAttributes(bNoBuffering), NULL);
+		if (m_hFile == INVALID_HANDLE_VALUE)
+			return false;
 
-bool TLocalFilesystemFile::CreateNewForWriting(const TSmartPath& pathFile, bool bNoBuffering)
-{
-	Close();
+		m_bNoBuffering = bNoBuffering;
+		return true;
+	}
 
-	m_pathFile = TLocalFilesystem::PrependPathExtensionIfNeeded(pathFile);
-	m_hFile = ::CreateFile(m_pathFile.ToString(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, GetFlagsAndAttributes(bNoBuffering), NULL);
-	if (m_hFile == INVALID_HANDLE_VALUE)
-		return false;
+	bool TLocalFilesystemFile::CreateNewForWriting(bool bNoBuffering)
+	{
+		Close();
 
-	m_bNoBuffering = bNoBuffering;
-	return true;
-}
+		m_hFile = ::CreateFile(m_pathFile.ToString(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, GetFlagsAndAttributes(bNoBuffering), NULL);
+		if (m_hFile == INVALID_HANDLE_VALUE)
+			return false;
 
-bool TLocalFilesystemFile::OpenExistingForWriting(const TSmartPath& pathFile, bool bNoBuffering)
-{
-	Close();
+		m_bNoBuffering = bNoBuffering;
+		return true;
+	}
 
-	m_pathFile = TLocalFilesystem::PrependPathExtensionIfNeeded(pathFile);
-	m_hFile = CreateFile(m_pathFile.ToString(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, GetFlagsAndAttributes(bNoBuffering), NULL);
-	if (m_hFile == INVALID_HANDLE_VALUE)
-		return false;
+	bool TLocalFilesystemFile::OpenExistingForWriting(bool bNoBuffering)
+	{
+		Close();
 
-	m_bNoBuffering = bNoBuffering;
-	return true;
-}
+		m_hFile = CreateFile(m_pathFile.ToString(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, GetFlagsAndAttributes(bNoBuffering), NULL);
+		if (m_hFile == INVALID_HANDLE_VALUE)
+			return false;
 
-bool TLocalFilesystemFile::SetFilePointer(long long llNewPos, DWORD dwMoveMethod)
-{
-	if (!IsOpen())
-		return false;
+		m_bNoBuffering = bNoBuffering;
+		return true;
+	}
 
-	LARGE_INTEGER li = { 0, 0 };
-	LARGE_INTEGER liNew = { 0, 0 };
+	bool TLocalFilesystemFile::Truncate(long long llNewSize)
+	{
+		if (!IsOpen())
+			return false;
 
-	li.QuadPart = llNewPos;
+		LARGE_INTEGER li = { 0, 0 };
+		LARGE_INTEGER liNew = { 0, 0 };
 
-	return SetFilePointerEx(m_hFile, li, &liNew, dwMoveMethod) != FALSE;
-}
+		li.QuadPart = llNewSize;
 
-bool TLocalFilesystemFile::SetEndOfFile()
-{
-	if (!IsOpen())
-		return false;
+		if (!SetFilePointerEx(m_hFile, li, &liNew, FILE_BEGIN))
+			return false;
 
-	return ::SetEndOfFile(m_hFile) != FALSE;
-}
+		return ::SetEndOfFile(m_hFile) != FALSE;
+	}
 
-bool TLocalFilesystemFile::ReadFile(TOverlappedDataBuffer& rBuffer)
-{
-	if (!IsOpen())
-		THROW_CORE_EXCEPTION(eErr_InternalProblem);
-
-	ATLTRACE(_T("Reading %lu bytes\n"), rBuffer.GetRequestedDataSize());
-	if (!::ReadFileEx(m_hFile, rBuffer.GetBufferPtr(), rBuffer.GetRequestedDataSize(), &rBuffer, OverlappedReadCompleted))
+	bool TLocalFilesystemFile::ReadFile(TOverlappedDataBuffer& rBuffer)
 	{
-		DWORD dwLastError = GetLastError();
-		switch (dwLastError)
-		{
-		case ERROR_IO_PENDING:
-			return true;
+		if (!IsOpen())
+			THROW_CORE_EXCEPTION(eErr_InternalProblem);
 
-		case ERROR_HANDLE_EOF:
+		ATLTRACE(_T("Reading %lu bytes\n"), rBuffer.GetRequestedDataSize());
+		if (!::ReadFileEx(m_hFile, rBuffer.GetBufferPtr(), rBuffer.GetRequestedDataSize(), &rBuffer, OverlappedReadCompleted))
 		{
-			rBuffer.SetBytesTransferred(0);
-			rBuffer.SetStatusCode(0);
-			rBuffer.SetErrorCode(ERROR_SUCCESS);
-			rBuffer.SetLastPart(true);
+			DWORD dwLastError = GetLastError();
+			switch (dwLastError)
+			{
+			case ERROR_IO_PENDING:
+				return true;
 
-			rBuffer.RequeueAsFull();	// basically the same as OverlappedReadCompleted
+			case ERROR_HANDLE_EOF:
+			{
+				rBuffer.SetBytesTransferred(0);
+				rBuffer.SetStatusCode(0);
+				rBuffer.SetErrorCode(ERROR_SUCCESS);
+				rBuffer.SetLastPart(true);
 
-			return true;
-		}
-		}
+				rBuffer.RequeueAsFull();	// basically the same as OverlappedReadCompleted
 
-		return false;
+				return true;
+			}
+			}
+
+			return false;
+		}
+		return true;
 	}
-	return true;
-}
 
-bool TLocalFilesystemFile::WriteFile(TOverlappedDataBuffer& rBuffer)
-{
-	if (!IsOpen())
-		THROW_CORE_EXCEPTION(eErr_InternalProblem);
+	bool TLocalFilesystemFile::WriteFile(TOverlappedDataBuffer& rBuffer)
+	{
+		if (!IsOpen())
+			THROW_CORE_EXCEPTION(eErr_InternalProblem);
 
-	DWORD dwToWrite = boost::numeric_cast<DWORD>(rBuffer.GetRealDataSize());
+		DWORD dwToWrite = boost::numeric_cast<DWORD>(rBuffer.GetRealDataSize());
 
-	if (m_bNoBuffering && rBuffer.IsLastPart())
-		dwToWrite = RoundUp<DWORD>(dwToWrite, MaxSectorSize);
+		if (m_bNoBuffering && rBuffer.IsLastPart())
+			dwToWrite = RoundUp<DWORD>(dwToWrite, MaxSectorSize);
 
-	ATLTRACE(_T("Writing %lu bytes\n"), dwToWrite);
-	if (!::WriteFileEx(m_hFile, rBuffer.GetBufferPtr(), dwToWrite, &rBuffer, OverlappedWriteCompleted))
-	{
-		if (GetLastError() == ERROR_IO_PENDING)
-			return true;
-		return false;
+		ATLTRACE(_T("Writing %lu bytes\n"), dwToWrite);
+		if (!::WriteFileEx(m_hFile, rBuffer.GetBufferPtr(), dwToWrite, &rBuffer, OverlappedWriteCompleted))
+		{
+			if (GetLastError() == ERROR_IO_PENDING)
+				return true;
+			return false;
+		}
+
+		return true;
 	}
 
-	return true;
-}
-
-bool TLocalFilesystemFile::FinalizeFile(TOverlappedDataBuffer& rBuffer)
-{
-	if (!IsOpen())
-		THROW_CORE_EXCEPTION(eErr_InternalProblem);
-
-	if (m_bNoBuffering && rBuffer.IsLastPart())
+	bool TLocalFilesystemFile::FinalizeFile(TOverlappedDataBuffer& rBuffer)
 	{
-		DWORD dwToWrite = boost::numeric_cast<DWORD>(rBuffer.GetRealDataSize());
-		DWORD dwReallyWritten = RoundUp<DWORD>(dwToWrite, MaxSectorSize);
+		if (!IsOpen())
+			THROW_CORE_EXCEPTION(eErr_InternalProblem);
 
-		ATLTRACE(_T("Finalize file - size diff: written: %I64u, required: %I64u\n"), dwReallyWritten, dwToWrite);
-
-		if (dwToWrite != dwReallyWritten)
+		if (m_bNoBuffering && rBuffer.IsLastPart())
 		{
-			unsigned long long ullNewFileSize = rBuffer.GetFilePosition() + dwToWrite;	// new size
+			DWORD dwToWrite = boost::numeric_cast<DWORD>(rBuffer.GetRealDataSize());
+			DWORD dwReallyWritten = RoundUp<DWORD>(dwToWrite, MaxSectorSize);
 
-			if (!OpenExistingForWriting(m_pathFile, false))
-				return false;
+			ATLTRACE(_T("Finalize file - size diff: written: %I64u, required: %I64u\n"), dwReallyWritten, dwToWrite);
 
-			//seek
-			ATLTRACE(_T("Truncating file to %I64u bytes\n"), ullNewFileSize);
-			if (!SetFilePointer(ullNewFileSize, FILE_BEGIN))
-				return false;
+			if (dwToWrite != dwReallyWritten)
+			{
+				unsigned long long ullNewFileSize = rBuffer.GetFilePosition() + dwToWrite;	// new size
 
-			//set eof
-			if (!SetEndOfFile())
-				return false;
+				if (!OpenExistingForWriting(false))
+					return false;
+
+				//seek
+				ATLTRACE(_T("Truncating file to %I64u bytes\n"), ullNewFileSize);
+				if (!Truncate(ullNewFileSize))
+					return false;
+			}
 		}
+
+		return true;
 	}
 
-	return true;
-}
+	void TLocalFilesystemFile::Close()
+	{
+		if (m_hFile != INVALID_HANDLE_VALUE)
+			::CloseHandle(m_hFile);
+		m_hFile = INVALID_HANDLE_VALUE;
+	}
 
-void TLocalFilesystemFile::Close()
-{
-	if (m_hFile != INVALID_HANDLE_VALUE)
-		::CloseHandle(m_hFile);
-	m_hFile = INVALID_HANDLE_VALUE;
-}
+	unsigned long long TLocalFilesystemFile::GetFileSize() const
+	{
+		if (!IsOpen())
+			return 0;
 
-unsigned long long TLocalFilesystemFile::GetFileSize() const
-{
-	if (!IsOpen())
-		return 0;
+		BY_HANDLE_FILE_INFORMATION bhfi;
 
-	BY_HANDLE_FILE_INFORMATION bhfi;
+		if (!::GetFileInformationByHandle(m_hFile, &bhfi))
+			return 0;
 
-	if (!::GetFileInformationByHandle(m_hFile, &bhfi))
-		return 0;
+		ULARGE_INTEGER uli;
+		uli.HighPart = bhfi.nFileSizeHigh;
+		uli.LowPart = bhfi.nFileSizeLow;
 
-	ULARGE_INTEGER uli;
-	uli.HighPart = bhfi.nFileSizeHigh;
-	uli.LowPart = bhfi.nFileSizeLow;
+		return uli.QuadPart;
+	}
 
-	return uli.QuadPart;
-}
+	TSmartPath TLocalFilesystemFile::GetFilePath() const
+	{
+		return m_pathFile;
+	}
 
-END_CHCORE_NAMESPACE
+}
Index: src/libchcore/TLocalFilesystemFile.h
===================================================================
diff -u -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/TLocalFilesystemFile.h	(.../TLocalFilesystemFile.h)	(revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b)
+++ src/libchcore/TLocalFilesystemFile.h	(.../TLocalFilesystemFile.h)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -24,41 +24,40 @@
 #include "TOverlappedDataBuffer.h"
 #include "IFilesystemFile.h"
 
-BEGIN_CHCORE_NAMESPACE
-
-class LIBCHCORE_API TLocalFilesystemFile : public IFilesystemFile
+namespace chcore
 {
-public:
-	virtual ~TLocalFilesystemFile();
+	class LIBCHCORE_API TLocalFilesystemFile : public IFilesystemFile
+	{
+	public:
+		virtual ~TLocalFilesystemFile();
 
-	virtual bool OpenExistingForReading(const TSmartPath& pathFile, bool bNoBuffering) override;
-	virtual bool CreateNewForWriting(const TSmartPath& pathFile, bool bNoBuffering) override;
-	virtual bool OpenExistingForWriting(const TSmartPath& pathFile, bool bNoBuffering) override;
+		virtual bool OpenExistingForReading(bool bNoBuffering) override;
+		virtual bool CreateNewForWriting(bool bNoBuffering) override;
+		virtual bool OpenExistingForWriting(bool bNoBuffering) override;
 
-	virtual bool SetFilePointer(long long llNewPos, DWORD dwMoveMethod) override;
-	virtual bool SetEndOfFile() override;
+		virtual bool Truncate(long long llNewSize) override;
 
-	virtual bool ReadFile(TOverlappedDataBuffer& rBuffer) override;
-	virtual bool WriteFile(TOverlappedDataBuffer& rBuffer) override;
-	virtual bool FinalizeFile(TOverlappedDataBuffer& rBuffer) override;
+		virtual bool ReadFile(TOverlappedDataBuffer& rBuffer) override;
+		virtual bool WriteFile(TOverlappedDataBuffer& rBuffer) override;
+		virtual bool FinalizeFile(TOverlappedDataBuffer& rBuffer) override;
 
-	virtual bool IsOpen() const  override { return m_hFile != INVALID_HANDLE_VALUE; }
-	virtual unsigned long long GetFileSize() const override;
+		virtual bool IsOpen() const  override { return m_hFile != INVALID_HANDLE_VALUE; }
+		virtual unsigned long long GetFileSize() const override;
+		virtual TSmartPath GetFilePath() const override;
 
-	virtual void Close() override;
+		virtual void Close() override;
 
-private:
-	TLocalFilesystemFile();
-	DWORD GetFlagsAndAttributes(bool bNoBuffering) const;
+	private:
+		TLocalFilesystemFile(const TSmartPath& pathFile);
+		DWORD GetFlagsAndAttributes(bool bNoBuffering) const;
 
-private:
-	TSmartPath m_pathFile;
-	HANDLE m_hFile;
-	bool m_bNoBuffering;
+	private:
+		TSmartPath m_pathFile;
+		HANDLE m_hFile;
+		bool m_bNoBuffering;
 
-	friend class TLocalFilesystem;
-};
+		friend class TLocalFilesystem;
+	};
+}
 
-END_CHCORE_NAMESPACE
-
 #endif
Index: src/libchcore/TPath.cpp
===================================================================
diff -u -r11b0a299be97bc3afaa633d6522c17b214ba3b79 -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/TPath.cpp	(.../TPath.cpp)	(revision 11b0a299be97bc3afaa633d6522c17b214ba3b79)
+++ src/libchcore/TPath.cpp	(.../TPath.cpp)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -31,878 +31,904 @@
 #include "TPathContainer.h"
 #include "TStringArray.h"
 
-BEGIN_CHCORE_NAMESPACE
-
+namespace chcore
+{
 #define DEFAULT_PATH_SEPARATOR _T("\\")
 
-// ============================================================================
-/// TSmartPath::TSmartPath
-/// @date 2009/11/29
-///
-/// @brief     Constructs an empty path.
-// ============================================================================
-TSmartPath::TSmartPath() :
-	m_strPath()
-{
-}
+	// ============================================================================
+	/// TSmartPath::TSmartPath
+	/// @date 2009/11/29
+	///
+	/// @brief     Constructs an empty path.
+	// ============================================================================
+	TSmartPath::TSmartPath() :
+		m_strPath()
+	{
+	}
 
-// ============================================================================
-/// TSmartPath::TSmartPath
-/// @date 2009/11/29
-///
-/// @brief     Constructs path object from another path object.
-/// @param[in] spPath - reference to another path object.
-// ============================================================================
-TSmartPath::TSmartPath(const TSmartPath& spPath) :
-	m_strPath(spPath.m_strPath)
-{
-}
+	// ============================================================================
+	/// TSmartPath::TSmartPath
+	/// @date 2009/11/29
+	///
+	/// @brief     Constructs path object from another path object.
+	/// @param[in] spPath - reference to another path object.
+	// ============================================================================
+	TSmartPath::TSmartPath(const TSmartPath& spPath) :
+		m_strPath(spPath.m_strPath)
+	{
+	}
 
-// ============================================================================
-/// TSmartPath::~TSmartPath
-/// @date 2009/11/29
-///
-/// @brief     
-/// @return    
-// ============================================================================
-TSmartPath::~TSmartPath()
-{
-	Clear();
-}
+	// ============================================================================
+	/// TSmartPath::~TSmartPath
+	/// @date 2009/11/29
+	///
+	/// @brief     
+	/// @return    
+	// ============================================================================
+	TSmartPath::~TSmartPath()
+	{
+		Clear();
+	}
 
-// ============================================================================
-/// TSmartPath::Clear
-/// @date 2009/11/29
-///
-/// @brief     Clears this object.
-// ============================================================================
-void TSmartPath::Clear() throw()
-{
-	m_strPath.Clear();
-}
+	// ============================================================================
+	/// TSmartPath::Clear
+	/// @date 2009/11/29
+	///
+	/// @brief     Clears this object.
+	// ============================================================================
+	void TSmartPath::Clear() throw()
+	{
+		m_strPath.Clear();
+	}
 
 
-TSmartPath TSmartPath::AppendCopy(const TSmartPath& pathToAppend, bool bEnsurePathSeparatorExists) const
-{
-	TSmartPath pathNew(*this);
-	pathNew.Append(pathToAppend, bEnsurePathSeparatorExists);
+	TSmartPath TSmartPath::AppendCopy(const TSmartPath& pathToAppend, bool bEnsurePathSeparatorExists) const
+	{
+		TSmartPath pathNew(*this);
+		pathNew.Append(pathToAppend, bEnsurePathSeparatorExists);
 
-	return pathNew;
-}
+		return pathNew;
+	}
 
-TSmartPath& TSmartPath::Append(const TSmartPath& pathToAppend, bool bEnsurePathSeparatorExists)
-{
-	// if there is no path inside rPath, then there is no point in doing anything
-	if(!pathToAppend.m_strPath.IsEmpty())
+	TSmartPath& TSmartPath::Append(const TSmartPath& pathToAppend, bool bEnsurePathSeparatorExists)
 	{
-		// if this path is empty, then optimize by just assigning the input path to this one
-		if(m_strPath.IsEmpty())
-			*this = pathToAppend;
-		else
+		// if there is no path inside rPath, then there is no point in doing anything
+		if (!pathToAppend.m_strPath.IsEmpty())
 		{
-			if(bEnsurePathSeparatorExists)
+			// if this path is empty, then optimize by just assigning the input path to this one
+			if (m_strPath.IsEmpty())
+				*this = pathToAppend;
+			else
 			{
-				// detect separators
-				bool bThisEndsWithSeparator = EndsWithSeparator();
-				bool bInStartsWithSeparator = pathToAppend.StartsWithSeparator();
+				if (bEnsurePathSeparatorExists)
+				{
+					// detect separators
+					bool bThisEndsWithSeparator = EndsWithSeparator();
+					bool bInStartsWithSeparator = pathToAppend.StartsWithSeparator();
 
-				if(!bThisEndsWithSeparator && !bInStartsWithSeparator)
-					m_strPath += _T("\\") + pathToAppend.m_strPath;
-				else if(bThisEndsWithSeparator ^ bInStartsWithSeparator)
-					m_strPath += pathToAppend.m_strPath;
+					if (!bThisEndsWithSeparator && !bInStartsWithSeparator)
+						m_strPath += _T("\\") + pathToAppend.m_strPath;
+					else if (bThisEndsWithSeparator ^ bInStartsWithSeparator)
+						m_strPath += pathToAppend.m_strPath;
+					else
+					{
+						m_strPath.Delete(m_strPath.GetLength() - 1, 1);
+						m_strPath += pathToAppend.m_strPath;
+					}
+				}
 				else
-				{
-					m_strPath.Delete(m_strPath.GetLength() - 1, 1);
 					m_strPath += pathToAppend.m_strPath;
-				}
 			}
-			else
-				m_strPath += pathToAppend.m_strPath;
 		}
+
+		return *this;
 	}
 
-	return *this;
-}
+	// ============================================================================
+	/// TSmartPath::operator=
+	/// @date 2009/11/29
+	///
+	/// @brief     Assigns a path from other path object.
+	/// @param[in] spPath - path object from which we want to get path.
+	/// @return    Reference to this object.
+	// ============================================================================
+	TSmartPath& TSmartPath::operator=(const TSmartPath& spPath)
+	{
+		if (this != &spPath)
+		{
+			Clear();
+			m_strPath = spPath.m_strPath;
+		}
 
-// ============================================================================
-/// TSmartPath::operator=
-/// @date 2009/11/29
-///
-/// @brief     Assigns a path from other path object.
-/// @param[in] spPath - path object from which we want to get path.
-/// @return    Reference to this object.
-// ============================================================================
-TSmartPath& TSmartPath::operator=(const TSmartPath& spPath)
-{
-	if(this != &spPath)
+		return *this;
+	}
+
+	// ============================================================================
+	/// TSmartPath::operator==
+	/// @date 2009/11/29
+	///
+	/// @brief     Compares paths (case sensitive).
+	/// @param[in] rPath - path to compare this object to.
+	/// @return    True if equal, false otherwise.
+	// ============================================================================
+	bool TSmartPath::operator==(const TSmartPath& rPath) const
 	{
-		Clear();
-		m_strPath = spPath.m_strPath;
+		return Compare(rPath) == 0;
 	}
 
-	return *this;
-}
 
-// ============================================================================
-/// TSmartPath::operator==
-/// @date 2009/11/29
-///
-/// @brief     Compares paths (case sensitive).
-/// @param[in] rPath - path to compare this object to.
-/// @return    True if equal, false otherwise.
-// ============================================================================
-bool TSmartPath::operator==(const TSmartPath& rPath) const
-{
-	return Compare(rPath) == 0;
-}
+	bool TSmartPath::operator!=(const TSmartPath& rPath) const
+	{
+		return Compare(rPath) != 0;
+	}
 
+	// ============================================================================
+	/// TSmartPath::operator<
+	/// @date 2009/11/29
+	///
+	/// @brief     Compares paths (case sensitive).
+	/// @param[in] rPath - input path to compare.
+	/// @return    True if this object is less than rPath, false otherwise.
+	// ============================================================================
+	bool TSmartPath::operator<(const TSmartPath& rPath) const
+	{
+		return Compare(rPath) < 0;
+	}
 
-bool TSmartPath::operator!=(const TSmartPath& rPath) const
-{
-	return Compare(rPath) != 0;
-}
+	// ============================================================================
+	/// TSmartPath::operator>
+	/// @date 2009/11/29
+	///
+	/// @brief     Compares paths (case sensitive).
+	/// @param[in] rPath - input path to compare.
+	/// @return    True if this object is less than rPath, false otherwise.
+	// ============================================================================
+	bool TSmartPath::operator>(const TSmartPath& rPath) const
+	{
+		return Compare(rPath) > 0;
+	}
 
-// ============================================================================
-/// TSmartPath::operator<
-/// @date 2009/11/29
-///
-/// @brief     Compares paths (case sensitive).
-/// @param[in] rPath - input path to compare.
-/// @return    True if this object is less than rPath, false otherwise.
-// ============================================================================
-bool TSmartPath::operator<(const TSmartPath& rPath) const
-{
-	return Compare(rPath) < 0;
-}
+	// ============================================================================
+	/// TSmartPath::operator+
+	/// @date 2009/11/29
+	///
+	/// @brief     Concatenates two paths, returns the result.
+	/// @param[in] rPath - path to concatenate.
+	/// @return    New path object with the results of concatenation.
+	// ============================================================================
+	TSmartPath TSmartPath::operator+(const TSmartPath& rPath) const
+	{
+		return AppendCopy(rPath, true);
+	}
 
-// ============================================================================
-/// TSmartPath::operator>
-/// @date 2009/11/29
-///
-/// @brief     Compares paths (case sensitive).
-/// @param[in] rPath - input path to compare.
-/// @return    True if this object is less than rPath, false otherwise.
-// ============================================================================
-bool TSmartPath::operator>(const TSmartPath& rPath) const
-{
-	return Compare(rPath) > 0;
-}
+	// ============================================================================
+	/// TSmartPath::operator+=
+	/// @date 2009/11/29
+	///
+	/// @brief     Concatenates provided path to our own.
+	/// @param[in] rPath - path to concatenate.
+	/// @return    Reference to this object.
+	// ============================================================================
+	TSmartPath& TSmartPath::operator+=(const TSmartPath& rPath)
+	{
+		return Append(rPath, true);
+	}
 
-// ============================================================================
-/// TSmartPath::operator+
-/// @date 2009/11/29
-///
-/// @brief     Concatenates two paths, returns the result.
-/// @param[in] rPath - path to concatenate.
-/// @return    New path object with the results of concatenation.
-// ============================================================================
-TSmartPath TSmartPath::operator+(const TSmartPath& rPath) const
-{
-	return AppendCopy(rPath, true);
-}
+	// ============================================================================
+	/// TSmartPath::FromString
+	/// @date 2010/10/12
+	///
+	/// @brief     Initializes this path object with path contained in string.
+	/// @param[in] pszPath - string containing path.
+	// ============================================================================
+	void TSmartPath::FromString(const wchar_t* pszPath)
+	{
+		if (!pszPath)
+			THROW_CORE_EXCEPTION(eErr_InvalidArgument);
 
-// ============================================================================
-/// TSmartPath::operator+=
-/// @date 2009/11/29
-///
-/// @brief     Concatenates provided path to our own.
-/// @param[in] rPath - path to concatenate.
-/// @return    Reference to this object.
-// ============================================================================
-TSmartPath& TSmartPath::operator+=(const TSmartPath& rPath)
-{
-	return Append(rPath, true);
-}
+		m_strPath = pszPath;
+	}
 
-// ============================================================================
-/// TSmartPath::FromString
-/// @date 2010/10/12
-///
-/// @brief     Initializes this path object with path contained in string.
-/// @param[in] pszPath - string containing path.
-// ============================================================================
-void TSmartPath::FromString(const wchar_t* pszPath)
-{
-	if(!pszPath)
-		THROW_CORE_EXCEPTION(eErr_InvalidArgument);
+	// ============================================================================
+	/// TSmartPath::FromString
+	/// @date 2010/10/12
+	///
+	/// @brief     Initializes this path object with path contained in string.
+	/// @param[in] strPath - string containing path.
+	// ============================================================================
+	void TSmartPath::FromString(const TString& strPath)
+	{
+		m_strPath = strPath;
+	}
 
-	m_strPath = pszPath;
-}
+	// ============================================================================
+	/// TSmartPath::ToString
+	/// @date 2010/10/12
+	///
+	/// @brief     Retrieves the pointer to a string containing path.
+	/// @return    Pointer to the string containing path.
+	// ============================================================================
+	const wchar_t* TSmartPath::ToString() const
+	{
+		return m_strPath.c_str();
+	}
 
-// ============================================================================
-/// TSmartPath::FromString
-/// @date 2010/10/12
-///
-/// @brief     Initializes this path object with path contained in string.
-/// @param[in] strPath - string containing path.
-// ============================================================================
-void TSmartPath::FromString(const TString& strPath)
-{
-	m_strPath = strPath;
-}
+	// ============================================================================
+	/// TSmartPath::ToString
+	/// @date 2010/10/12
+	///
+	/// @brief     Retrieves the string containing path.
+	/// @return    String containing path.
+	// ============================================================================
+	TString TSmartPath::ToWString() const
+	{
+		return m_strPath;
+	}
 
-// ============================================================================
-/// TSmartPath::ToString
-/// @date 2010/10/12
-///
-/// @brief     Retrieves the pointer to a string containing path.
-/// @return    Pointer to the string containing path.
-// ============================================================================
-const wchar_t* TSmartPath::ToString() const
-{
-	return m_strPath.c_str();
-}
+	// ============================================================================
+	/// TSmartPath::Compare
+	/// @date 2009/11/29
+	///
+	/// @brief     Compares paths.
+	/// @param[in] rPath - path to compare to.
+	/// @return    Result of the comparison.
+	// ============================================================================
+	int TSmartPath::Compare(const TSmartPath& rPath, bool bCaseSensitive) const
+	{
+		if (bCaseSensitive)
+			return m_strPath.Compare(rPath.m_strPath);
+		else
+			return m_strPath.CompareNoCase(rPath.m_strPath);
+	}
 
-// ============================================================================
-/// TSmartPath::ToString
-/// @date 2010/10/12
-///
-/// @brief     Retrieves the string containing path.
-/// @return    String containing path.
-// ============================================================================
-TString TSmartPath::ToWString() const
-{
-	return m_strPath;
-}
+	// ============================================================================
+	/// TSmartPath::SplitPath
+	/// @date 2011/04/05
+	///
+	/// @brief     Splits path to components.
+	/// @param[in] vComponents - receives the split path.
+	// ============================================================================
+	void TSmartPath::SplitPath(TPathContainer& vComponents) const
+	{
+		vComponents.Clear();
 
-// ============================================================================
-/// TSmartPath::Compare
-/// @date 2009/11/29
-///
-/// @brief     Compares paths.
-/// @param[in] rPath - path to compare to.
-/// @return    Result of the comparison.
-// ============================================================================
-int TSmartPath::Compare(const TSmartPath& rPath, bool bCaseSensitive) const
-{
-	if(bCaseSensitive)
-		return m_strPath.Compare(rPath.m_strPath);
-	else
-		return m_strPath.CompareNoCase(rPath.m_strPath);
-}
+		if (IsNetworkPath())
+		{
+			// server name first
+			vComponents.Add(GetServerName());
 
-// ============================================================================
-/// TSmartPath::SplitPath
-/// @date 2011/04/05
-///
-/// @brief     Splits path to components.
-/// @param[in] vComponents - receives the split path.
-// ============================================================================
-void TSmartPath::SplitPath(TPathContainer& vComponents) const
-{
-	vComponents.Clear();
+			// now the split directories
+			TPathContainer vDirSplit;
+			TSmartPath spDir = GetFileDir();
+			spDir.SplitPath(vDirSplit);
 
-	if(IsNetworkPath())
-	{
-		// server name first
-		vComponents.Add(GetServerName());
+			vComponents.Append(vDirSplit);
 
-		// now the split directories
-		TPathContainer vDirSplit;
-		TSmartPath spDir = GetFileDir();
-		spDir.SplitPath(vDirSplit);
+			// and file name last
+			vComponents.Add(GetFileName());
+		}
+		else
+		{
+			TStringArray vStrings;
+			m_strPath.Split(_T("\\/"), vStrings);
 
-		vComponents.Append(vDirSplit);
+			for (size_t stIndex = 0; stIndex < vStrings.GetCount(); ++stIndex)
+			{
+				const TString& strComponent = vStrings.GetAt(stIndex);
+				if (!strComponent.IsEmpty())
+					vComponents.Add(PathFromWString(strComponent));
+			}
+		}
+	}
 
-		// and file name last
-		vComponents.Add(GetFileName());
+	// ============================================================================
+	/// TSmartPath::IsChildOf
+	/// @date 2009/11/29
+	///
+	/// @brief     Checks if this path starts with the path specified as parameter.
+	/// @param[in] rPath - path to check this one against.
+	/// @return    True if this path starts with the provided one, false otherwise.
+	// ============================================================================
+	bool TSmartPath::IsChildOf(const TSmartPath& rPath, bool bCaseSensitive) const
+	{
+		if (bCaseSensitive)
+			return m_strPath.StartsWith(rPath.m_strPath.c_str());
+		else
+			return m_strPath.StartsWithNoCase(rPath.m_strPath.c_str());
 	}
-	else
+
+	// ============================================================================
+	/// TSmartPath::MakeRelativePath
+	/// @date 2010/10/12
+	///
+	/// @brief     Converts this path to be relative to the reference, base path.
+	/// @param[in] rReferenceBasePath - Path which will be base path to this relative path.
+	/// @param[in] bCaseSensitive - Compare path with case sensitivity on/off.
+	/// @return    True if conversion to relative path succeeded, false otherwise.
+	// ============================================================================
+	bool TSmartPath::MakeRelativePath(const TSmartPath& rReferenceBasePath, bool bCaseSensitive)
 	{
-		TStringArray vStrings;
-		m_strPath.Split(_T("\\/"), vStrings);
+		bool bStartsWith = false;
+		if (bCaseSensitive)
+			bStartsWith = m_strPath.StartsWith(rReferenceBasePath.m_strPath.c_str());
+		else
+			bStartsWith = m_strPath.StartsWithNoCase(rReferenceBasePath.m_strPath.c_str());
 
-		for(size_t stIndex = 0; stIndex < vStrings.GetCount(); ++stIndex)
+		if (bStartsWith)
 		{
-			const TString& strComponent = vStrings.GetAt(stIndex);
-			if(!strComponent.IsEmpty())
-				vComponents.Add(PathFromWString(strComponent));
+			m_strPath.Delete(0, rReferenceBasePath.m_strPath.GetLength());
+			return true;
 		}
+		else
+			return false;
 	}
-}
 
-// ============================================================================
-/// TSmartPath::IsChildOf
-/// @date 2009/11/29
-///
-/// @brief     Checks if this path starts with the path specified as parameter.
-/// @param[in] rPath - path to check this one against.
-/// @return    True if this path starts with the provided one, false otherwise.
-// ============================================================================
-bool TSmartPath::IsChildOf(const TSmartPath& rPath, bool bCaseSensitive) const
-{
-	if(bCaseSensitive)
-		return m_strPath.StartsWith(rPath.m_strPath.c_str());
-	else
-		return m_strPath.StartsWithNoCase(rPath.m_strPath.c_str());
-}
+	bool TSmartPath::MakeAbsolutePath(const TSmartPath& rReferenceBasePath)
+	{
+		if (!IsRelativePath())
+			return false;
 
-// ============================================================================
-/// TSmartPath::MakeRelativePath
-/// @date 2010/10/12
-///
-/// @brief     Converts this path to be relative to the reference, base path.
-/// @param[in] rReferenceBasePath - Path which will be base path to this relative path.
-/// @param[in] bCaseSensitive - Compare path with case sensitivity on/off.
-/// @return    True if conversion to relative path succeeded, false otherwise.
-// ============================================================================
-bool TSmartPath::MakeRelativePath(const TSmartPath& rReferenceBasePath, bool bCaseSensitive)
-{
-	bool bStartsWith = false;
-	if(bCaseSensitive)
-		bStartsWith = m_strPath.StartsWith(rReferenceBasePath.m_strPath.c_str());
-	else
-		bStartsWith = m_strPath.StartsWithNoCase(rReferenceBasePath.m_strPath.c_str());
+		bool bHasSeparator = rReferenceBasePath.EndsWithSeparator();
+		if (!bHasSeparator)
+			PrependSeparatorIfDoesNotExist();
+		else
+			StripSeparatorAtFront();
 
-	if(bStartsWith)
-	{
-		m_strPath.Delete(0, rReferenceBasePath.m_strPath.GetLength());
+		m_strPath = rReferenceBasePath.ToString() + m_strPath;
+
 		return true;
 	}
-	else
-		return false;
-}
 
-bool TSmartPath::MakeAbsolutePath(const TSmartPath& rReferenceBasePath)
-{
-	if(!IsRelativePath())
-		return false;
+	// ============================================================================
+	/// 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 bHasSeparator = rReferenceBasePath.EndsWithSeparator();
-	if(!bHasSeparator)
-		PrependSeparatorIfDoesNotExist();
-	else
-		StripSeparatorAtFront();
+		bool bEndsWith = false;
+		if (bCaseSensitive)
+			bEndsWith = m_strPath.EndsWith(pszPostfix);
+		else
+			bEndsWith = m_strPath.EndsWithNoCase(pszPostfix);
 
-	m_strPath = rReferenceBasePath.ToString() + m_strPath;
+		if (!bEndsWith)
+			m_strPath += pszPostfix;
+	}
 
-	return true;
-}
+	// ============================================================================
+	/// 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;
 
-// ============================================================================
-/// 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_strPath.EndsWith(pszPostfix);
+		else
+			bEndsWith = m_strPath.EndsWithNoCase(pszPostfix);
 
-	bool bEndsWith = false;
-	if(bCaseSensitive)
-		bEndsWith = m_strPath.EndsWith(pszPostfix);
-	else
-		bEndsWith = m_strPath.EndsWithNoCase(pszPostfix);
+		if (bEndsWith)
+			m_strPath.Delete(m_strPath.GetLength() - _tcslen(pszPostfix), m_strPath.GetLength() - _tcslen(pszPostfix));
+	}
 
-	if(!bEndsWith)
-		m_strPath += pszPostfix;
-}
+	// ============================================================================
+	/// TSmartPath::IsNetworkPath
+	/// @date 2010/10/17
+	///
+	/// @brief     Checks if the path is network one (\\server_name...)
+	/// @return    True if it is, false otherwise.
+	// ============================================================================
+	bool TSmartPath::IsNetworkPath() const
+	{
+		return (m_strPath.GetLength() > 2 && IsSeparator(m_strPath.GetAt(0)) && IsSeparator(m_strPath.GetAt(1)));		// "\\server_name"
+	}
 
-// ============================================================================
-/// 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;
+	// ============================================================================
+	/// TSmartPath::IsDrive
+	/// @date 2011/04/05
+	///
+	/// @brief     Checks if this path contains only drive specification (i.e. c:)
+	/// @return    True if it is, false otherwise.
+	// ============================================================================
+	bool TSmartPath::IsDrive() const
+	{
+		return (m_strPath.GetLength() == 2 && m_strPath.GetAt(1) == _T(':'));
+	}
 
-	bool bEndsWith = false;
-	if(bCaseSensitive)
-		bEndsWith = m_strPath.EndsWith(pszPostfix);
-	else
-		bEndsWith = m_strPath.EndsWithNoCase(pszPostfix);
+	// ============================================================================
+	/// TSmartPath::HasDrive
+	/// @date 2010/10/16
+	///
+	/// @brief     Checks if path has a drive component.
+	/// @return    True if it has, false otherwise.
+	// ============================================================================
+	bool TSmartPath::HasDrive() const
+	{
+		return (m_strPath.GetLength() >= 2 && m_strPath.GetAt(1) == _T(':'));
+	}
 
-	if(bEndsWith)
-		m_strPath.Delete(m_strPath.GetLength() - _tcslen(pszPostfix), m_strPath.GetLength() - _tcslen(pszPostfix));
-}
+	// ============================================================================
+	/// TSmartPath::GetDrive
+	/// @date 2010/10/16
+	///
+	/// @brief     Retrieves drive from path.
+	/// @return    Path with drive, empty if drive does not exist.
+	// ============================================================================
+	TSmartPath TSmartPath::GetDrive() const
+	{
+		if (m_strPath.GetLength() >= 2 && m_strPath.GetAt(1) == _T(':'))
+		{
+			if (m_strPath.GetLength() == 2)
+				return *this;
+			else
+				return PathFromWString(m_strPath.Left(2));	// c: for c:\windows\test.cpp
+		}
 
-// ============================================================================
-/// TSmartPath::IsNetworkPath
-/// @date 2010/10/17
-///
-/// @brief     Checks if the path is network one (\\server_name...)
-/// @return    True if it is, false otherwise.
-// ============================================================================
-bool TSmartPath::IsNetworkPath() const
-{
-	return (m_strPath.GetLength() > 2 && IsSeparator(m_strPath.GetAt(0)) && IsSeparator(m_strPath.GetAt(1)));		// "\\server_name"
-}
+		return TSmartPath();
+	}
 
-// ============================================================================
-/// TSmartPath::IsDrive
-/// @date 2011/04/05
-///
-/// @brief     Checks if this path contains only drive specification (i.e. c:)
-/// @return    True if it is, false otherwise.
-// ============================================================================
-bool TSmartPath::IsDrive() const
-{
-	return (m_strPath.GetLength() == 2 && m_strPath.GetAt(1) == _T(':'));
-}
+	// ============================================================================
+	/// TSmartPath::GetDriveLetter
+	/// @date 2011/07/17
+	///
+	/// @brief     Retrieves drive letter from path.
+	/// @return    Drive letter or zero in case path does not have drive.
+	// ============================================================================
+	wchar_t TSmartPath::GetDriveLetter() const
+	{
+		if (m_strPath.GetLength() >= 2 && m_strPath.GetAt(1) == _T(':'))
+		{
+			wchar_t wchDrive = m_strPath.GetAt(0);
+			if (wchDrive >= L'a' && wchDrive <= L'z')
+				wchDrive = L'A' + wchDrive - L'a';
+			return wchDrive;
+		}
 
-// ============================================================================
-/// TSmartPath::HasDrive
-/// @date 2010/10/16
-///
-/// @brief     Checks if path has a drive component.
-/// @return    True if it has, false otherwise.
-// ============================================================================
-bool TSmartPath::HasDrive() const
-{
-	return (m_strPath.GetLength() >= 2 && m_strPath.GetAt(1) == _T(':'));
-}
+		return L'\0';
+	}
 
-// ============================================================================
-/// TSmartPath::GetDrive
-/// @date 2010/10/16
-///
-/// @brief     Retrieves drive from path.
-/// @return    Path with drive, empty if drive does not exist.
-// ============================================================================
-TSmartPath TSmartPath::GetDrive() const
-{
-	if(m_strPath.GetLength() >= 2 && m_strPath.GetAt(1) == _T(':'))
+	// ============================================================================
+	/// 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_strPath.GetLength() == 2)
-			return *this;
-		else
-			return PathFromWString(m_strPath.Left(2));	// c: for c:\windows\test.cpp
+		return (m_strPath.GetLength() > 2 &&			// must have at least 3 characters...
+			IsSeparator(m_strPath.GetAt(0)) && IsSeparator(m_strPath.GetAt(1)) &&	// ... the first two of which are separators...
+			std::isalnum(m_strPath.GetAt(2)) &&											// ... followed by at least one alphanumeric character...
+			m_strPath.FindFirstOf(_T("\\/"), 3) == TString::npos);								// ... with no additional separators (so \\abc is true, \\abc\ is not).
 	}
 
-	return TSmartPath();
-}
+	// ============================================================================
+	/// TSmartPath::HasServerName
+	/// @date 2010/10/17
+	///
+	/// @brief     
+	/// @return    
+	// ============================================================================
+	bool TSmartPath::HasServerName() const
+	{
+		return (m_strPath.GetLength() > 2 && IsSeparator(m_strPath.GetAt(0)) && IsSeparator(m_strPath.GetAt(1)) && std::isalnum(m_strPath.GetAt(2)));
+	}
 
-// ============================================================================
-/// TSmartPath::GetDriveLetter
-/// @date 2011/07/17
-///
-/// @brief     Retrieves drive letter from path.
-/// @return    Drive letter or zero in case path does not have drive.
-// ============================================================================
-wchar_t TSmartPath::GetDriveLetter() const
-{
-	if(m_strPath.GetLength() >= 2 && m_strPath.GetAt(1) == _T(':'))
+	// ============================================================================
+	/// TSmartPath::GetServerName
+	/// @date 2010/10/17
+	///
+	/// @brief     Retrieves server name from path (if network path).
+	/// @return    Path containing server name (with prepended \\)
+	// ============================================================================
+	TSmartPath TSmartPath::GetServerName() const
 	{
-		wchar_t wchDrive = m_strPath.GetAt(0);
-		if(wchDrive >= L'a' && wchDrive <= L'z')
-			wchDrive = L'A' + wchDrive - L'a';
-		return wchDrive;
+		TString wstrPath;
+		if (m_strPath.GetLength() > 2 && IsSeparator(m_strPath.GetAt(0)) && IsSeparator(m_strPath.GetAt(1)) && std::isalnum(m_strPath.GetAt(2)))
+		{
+			size_t stEndPos = m_strPath.FindFirstOf(_T("\\/"), 2);
+			if (stEndPos == TString::npos)
+				wstrPath = m_strPath;
+			else
+				wstrPath = m_strPath.Left(stEndPos);
+			return PathFromWString(wstrPath);
+		}
+
+		return TSmartPath();
 	}
 
-	return L'\0';
-}
+	// ============================================================================
+	/// TSmartPath::HasFileRoot
+	/// @date 2010/10/17
+	///
+	/// @brief     Checks if this path has a file root part.
+	/// @return    True if it has, false otherwise.
+	// ============================================================================
+	bool TSmartPath::HasFileRoot() const
+	{
+		size_t stIndex = m_strPath.FindLastOf(_T("\\/"));
+		return (stIndex != TString::npos);
+	}
 
-// ============================================================================
-/// 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
-{
-	return (m_strPath.GetLength() > 2 &&			// must have at least 3 characters...
-		IsSeparator(m_strPath.GetAt(0)) && IsSeparator(m_strPath.GetAt(1)) &&	// ... the first two of which are separators...
-		std::isalnum(m_strPath.GetAt(2)) &&											// ... followed by at least one alphanumeric character...
-		m_strPath.FindFirstOf(_T("\\/"), 3) == TString::npos);								// ... with no additional separators (so \\abc is true, \\abc\ is not).
-}
+	// ============================================================================
+	/// TSmartPath::GetFileRoot
+	/// @date 2010/10/17
+	///
+	/// @brief     Retrieves the root of the file.
+	/// @return    File root as path, empty path if does not exist.
+	// ============================================================================
+	TSmartPath TSmartPath::GetFileRoot() const
+	{
+		size_t stIndex = m_strPath.FindLastOf(_T("\\/"));
+		if (stIndex != TString::npos)
+			return PathFromWString(m_strPath.Left(stIndex + 1));
 
-// ============================================================================
-/// TSmartPath::HasServerName
-/// @date 2010/10/17
-///
-/// @brief     
-/// @return    
-// ============================================================================
-bool TSmartPath::HasServerName() const
-{
-	return (m_strPath.GetLength() > 2 && IsSeparator(m_strPath.GetAt(0)) && IsSeparator(m_strPath.GetAt(1)) && std::isalnum(m_strPath.GetAt(2)));
-}
+		return TSmartPath();
+	}
 
-// ============================================================================
-/// TSmartPath::GetServerName
-/// @date 2010/10/17
-///
-/// @brief     Retrieves server name from path (if network path).
-/// @return    Path containing server name (with prepended \\)
-// ============================================================================
-TSmartPath TSmartPath::GetServerName() const
-{
-	TString wstrPath;
-	if(m_strPath.GetLength() > 2 && IsSeparator(m_strPath.GetAt(0)) && IsSeparator(m_strPath.GetAt(1)) && std::isalnum(m_strPath.GetAt(2)))
+	// ============================================================================
+	/// TSmartPath::HasFileDir
+	/// @date 2010/10/16
+	///
+	/// @brief     Checks if path contains directory specification.
+	/// @return	   True if it contains one, false otherwise.
+	// ============================================================================
+	bool TSmartPath::HasFileDir() const
 	{
-		size_t stEndPos = m_strPath.FindFirstOf(_T("\\/"), 2);
-		if(stEndPos == TString::npos)
-			wstrPath = m_strPath;
+		size_t stStart = 0;
+		if (IsNetworkPath())
+			stStart = m_strPath.FindFirstOf(_T("/\\"), 2);
 		else
-			wstrPath = m_strPath.Left(stEndPos);
-		return PathFromWString(wstrPath);
+			stStart = m_strPath.FindFirstOf(_T("/\\"));
+
+		size_t stEnd = m_strPath.FindLastOf(_T("/\\"));
+		return (stStart != TString::npos && stEnd >= stStart);
 	}
 
-	return TSmartPath();
-}
+	// ============================================================================
+	/// TSmartPath::GetFileDir
+	/// @date 2010/10/16
+	///
+	/// @brief     Retrieves the directory specification from path.
+	/// @return    Directory specification, empty path if not found.
+	// ============================================================================
+	TSmartPath TSmartPath::GetFileDir() const
+	{
+		size_t stStart = 0;
+		if (IsNetworkPath())
+			stStart = m_strPath.FindFirstOf(_T("/\\"), 2);
+		else if (HasDrive())
+			stStart = m_strPath.FindFirstOf(_T("/\\"));
+		else
+			stStart = 0;
 
-// ============================================================================
-/// TSmartPath::HasFileRoot
-/// @date 2010/10/17
-///
-/// @brief     Checks if this path has a file root part.
-/// @return    True if it has, false otherwise.
-// ============================================================================
-bool TSmartPath::HasFileRoot() const
-{
-	size_t stIndex = m_strPath.FindLastOf(_T("\\/"));
-	return (stIndex != TString::npos);
-}
+		size_t stEnd = m_strPath.FindLastOf(_T("/\\"));
+		if (stStart != TString::npos && stEnd >= stStart)
+			return PathFromWString(m_strPath.MidRange(stStart, stEnd + 1));
 
-// ============================================================================
-/// TSmartPath::GetFileRoot
-/// @date 2010/10/17
-///
-/// @brief     Retrieves the root of the file.
-/// @return    File root as path, empty path if does not exist.
-// ============================================================================
-TSmartPath TSmartPath::GetFileRoot() const
-{
-	size_t stIndex = m_strPath.FindLastOf(_T("\\/"));
-	if(stIndex != TString::npos)
-		return PathFromWString(m_strPath.Left(stIndex + 1));
+		return TSmartPath();
+	}
 
-	return TSmartPath();
-}
+	// ============================================================================
+	/// TSmartPath::HasFileTitle
+	/// @date 2010/10/16
+	///
+	/// @brief     Checks if the path has file title part.
+	/// @return    True if it has one, false otherwise.
+	// ============================================================================
+	bool TSmartPath::HasFileTitle() const
+	{
+		size_t stStart = m_strPath.FindLastOf(_T("/\\"));
+		size_t stEnd = m_strPath.FindLastOf(_T("."));
+		if ((stStart == TString::npos && stEnd == TString::npos))
+			return !IsEmpty();
+		if (stStart == TString::npos)	// if does not exist, start from beginning
+			stStart = 0;
+		if (stEnd == TString::npos || stEnd < stStart)		// if does not exist or we have ".\\", use up to the end
+			stEnd = m_strPath.GetLength();
 
-// ============================================================================
-/// TSmartPath::HasFileDir
-/// @date 2010/10/16
-///
-/// @brief     Checks if path contains directory specification.
-/// @return	   True if it contains one, false otherwise.
-// ============================================================================
-bool TSmartPath::HasFileDir() const
-{
-	size_t stStart = 0;
-	if(IsNetworkPath())
-		stStart = m_strPath.FindFirstOf(_T("/\\"), 2);
-	else
-		stStart = m_strPath.FindFirstOf(_T("/\\"));
+		return stEnd > stStart + 1;
+	}
 
-	size_t stEnd = m_strPath.FindLastOf(_T("/\\"));
-	return (stStart != TString::npos && stEnd >= stStart);
-}
+	// ============================================================================
+	/// TSmartPath::GetFileTitle
+	/// @date 2010/10/16
+	///
+	/// @brief     Retrieves file title from path.
+	/// @return    File title. Empty if does not exist.
+	// ============================================================================
+	TSmartPath TSmartPath::GetFileTitle() const
+	{
+		size_t stStart = m_strPath.FindLastOf(_T("/\\"));
+		size_t stEnd = m_strPath.FindLastOf(_T("."));
+		if ((stStart == TString::npos && stEnd == TString::npos))
+			return *this;
+		if (stStart == TString::npos)	// if does not exist, start from beginning
+			stStart = 0;
+		else
+			++stStart;
+		if (stEnd == TString::npos || stEnd < stStart)		// if does not exist or we have ".\\", use up to the end
+			stEnd = m_strPath.GetLength();
 
-// ============================================================================
-/// TSmartPath::GetFileDir
-/// @date 2010/10/16
-///
-/// @brief     Retrieves the directory specification from path.
-/// @return    Directory specification, empty path if not found.
-// ============================================================================
-TSmartPath TSmartPath::GetFileDir() const
-{
-	size_t stStart = 0;
-	if(IsNetworkPath())
-		stStart = m_strPath.FindFirstOf(_T("/\\"), 2);
-	else if(HasDrive())
-		stStart = m_strPath.FindFirstOf(_T("/\\"));
-	else
-		stStart = 0;
+		return PathFromWString(m_strPath.MidRange(stStart, stEnd));
+	}
 
-	size_t stEnd = m_strPath.FindLastOf(_T("/\\"));
-	if(stStart != TString::npos && stEnd >= stStart)
-		return PathFromWString(m_strPath.MidRange(stStart, stEnd + 1));
+	// ============================================================================
+	/// TSmartPath::HasExtension
+	/// @date 2010/10/16
+	///
+	/// @brief     Checks if this path has a file extension.
+	/// @return    True if it has, false otherwise.
+	// ============================================================================
+	bool TSmartPath::HasExtension() const
+	{
+		size_t stIndex = m_strPath.FindLastOf(_T("\\/."));
 
-	return TSmartPath();
-}
+		return stIndex != TString::npos && (m_strPath.GetAt(stIndex) == _T('.'));
+	}
 
-// ============================================================================
-/// TSmartPath::HasFileTitle
-/// @date 2010/10/16
-///
-/// @brief     Checks if the path has file title part.
-/// @return    True if it has one, false otherwise.
-// ============================================================================
-bool TSmartPath::HasFileTitle() const
-{
-	size_t stStart = m_strPath.FindLastOf(_T("/\\"));
-	size_t stEnd = m_strPath.FindLastOf(_T("."));
-	if((stStart == TString::npos && stEnd == TString::npos))
-		return !IsEmpty();
-	if(stStart == TString::npos)	// if does not exist, start from beginning
-		stStart = 0;
-	if(stEnd == TString::npos || stEnd < stStart)		// if does not exist or we have ".\\", use up to the end
-		stEnd = m_strPath.GetLength();
+	// ============================================================================
+	/// TSmartPath::GetExtension
+	/// @date 2010/10/16
+	///
+	/// @brief     Retrieves file extension from this path.
+	/// @return    Extension part or empty if does not exist.
+	// ============================================================================
+	TSmartPath TSmartPath::GetExtension() const
+	{
+		size_t stIndex = m_strPath.FindLastOf(_T("\\/."));
 
-	return stEnd > stStart + 1;
-}
+		if (stIndex != TString::npos && m_strPath.GetAt(stIndex) == _T('.'))
+			return PathFromWString(m_strPath.MidRange(stIndex, m_strPath.GetLength()));	// ".txt" for "c:\windows\test.txt"
 
-// ============================================================================
-/// TSmartPath::GetFileTitle
-/// @date 2010/10/16
-///
-/// @brief     Retrieves file title from path.
-/// @return    File title. Empty if does not exist.
-// ============================================================================
-TSmartPath TSmartPath::GetFileTitle() const
-{
-	size_t stStart = m_strPath.FindLastOf(_T("/\\"));
-	size_t stEnd = m_strPath.FindLastOf(_T("."));
-	if((stStart == TString::npos && stEnd == TString::npos))
-		return *this;
-	if(stStart == TString::npos)	// if does not exist, start from beginning
-		stStart = 0;
-	else
-		++stStart;
-	if(stEnd == TString::npos || stEnd < stStart)		// if does not exist or we have ".\\", use up to the end
-		stEnd = m_strPath.GetLength();
+		return TSmartPath();
+	}
 
-	return PathFromWString(m_strPath.MidRange(stStart, stEnd));
-}
+	// ============================================================================
+	/// TSmartPath::HasFileName
+	/// @date 2010/10/16
+	///
+	/// @brief     Checks if this path contains filename part.
+	/// @return    True if filename exists, false otherwise.
+	// ============================================================================
+	bool TSmartPath::HasFileName() const
+	{
+		size_t stIndex = m_strPath.FindLastOf(_T("\\/"));
+		if (stIndex == TString::npos)	// no path separator?
+			return true;
+		else
+			return (stIndex != TString::npos && stIndex != m_strPath.GetLength() - 1);
+	}
 
-// ============================================================================
-/// TSmartPath::HasExtension
-/// @date 2010/10/16
-///
-/// @brief     Checks if this path has a file extension.
-/// @return    True if it has, false otherwise.
-// ============================================================================
-bool TSmartPath::HasExtension() const
-{
-	size_t stIndex = m_strPath.FindLastOf(_T("\\/."));
+	// ============================================================================
+	/// TSmartPath::GetFileName
+	/// @date 2010/10/16
+	///
+	/// @brief     Retrieves filename part of this path.
+	/// @return    Filename, or empty if does not exist.
+	// ============================================================================
+	TSmartPath TSmartPath::GetFileName() const
+	{
+		size_t stIndex = m_strPath.FindLastOf(_T("\\/"));
+		if (stIndex != TString::npos)
+			return PathFromWString(m_strPath.MidRange(stIndex + 1, m_strPath.GetLength()));	// "test.txt" for "c:\windows\test.txt"
+		else
+			return *this;
+	}
 
-	return stIndex != TString::npos && (m_strPath.GetAt(stIndex) == _T('.'));
-}
+	// ============================================================================
+	/// TSmartPath::DeleteFileName
+	/// @date 2010/10/17
+	///
+	/// @brief     Deletes the filename part of this path if exists.
+	// ============================================================================
+	void TSmartPath::DeleteFileName()
+	{
+		size_t stIndex = m_strPath.FindLastOf(_T("\\/"));
+		if (stIndex != TString::npos)
+			m_strPath.Delete(stIndex + 1, m_strPath.GetLength() - stIndex - 1);	// "test.txt" for "c:\windows\test.txt"
+		else
+		{
+			// no path separator inside - everything in this path is a filename
+			Clear();
+		}
+	}
 
-// ============================================================================
-/// TSmartPath::GetExtension
-/// @date 2010/10/16
-///
-/// @brief     Retrieves file extension from this path.
-/// @return    Extension part or empty if does not exist.
-// ============================================================================
-TSmartPath TSmartPath::GetExtension() const
-{
-	size_t stIndex = m_strPath.FindLastOf(_T("\\/."));
+	TSmartPath TSmartPath::GetParent() const
+	{
+		if (IsServerName() || IsDrive())
+			return TSmartPath();
 
-	if(stIndex != TString::npos && m_strPath.GetAt(stIndex) == _T('.'))
-		return PathFromWString(m_strPath.MidRange(stIndex, m_strPath.GetLength()));	// ".txt" for "c:\windows\test.txt"
+		TSmartPath pathResult(*this);
 
-	return TSmartPath();
-}
+		if (pathResult.EndsWithSeparator())
+		{
+			pathResult.StripSeparatorAtEnd();
+			if (pathResult.IsDrive() || pathResult.IsServerName())
+				return pathResult;
+		}
 
-// ============================================================================
-/// TSmartPath::HasFileName
-/// @date 2010/10/16
-///
-/// @brief     Checks if this path contains filename part.
-/// @return    True if filename exists, false otherwise.
-// ============================================================================
-bool TSmartPath::HasFileName() const
-{
-	size_t stIndex = m_strPath.FindLastOf(_T("\\/"));
-	if(stIndex == TString::npos)	// no path separator?
-		return true;
-	else
-		return (stIndex != TString::npos && stIndex != m_strPath.GetLength() - 1);
-}
+		pathResult.DeleteFileName();
 
-// ============================================================================
-/// TSmartPath::GetFileName
-/// @date 2010/10/16
-///
-/// @brief     Retrieves filename part of this path.
-/// @return    Filename, or empty if does not exist.
-// ============================================================================
-TSmartPath TSmartPath::GetFileName() const
-{
-	size_t stIndex = m_strPath.FindLastOf(_T("\\/"));
-	if(stIndex != TString::npos)
-		return PathFromWString(m_strPath.MidRange(stIndex + 1, m_strPath.GetLength()));	// "test.txt" for "c:\windows\test.txt"
-	else
-		return *this;
-}
+		return pathResult;
+	}
 
-// ============================================================================
-/// TSmartPath::DeleteFileName
-/// @date 2010/10/17
-///
-/// @brief     Deletes the filename part of this path if exists.
-// ============================================================================
-void TSmartPath::DeleteFileName()
-{
-	size_t stIndex = m_strPath.FindLastOf(_T("\\/"));
-	if(stIndex != TString::npos)
-		m_strPath.Delete(stIndex + 1, m_strPath.GetLength() - stIndex - 1);	// "test.txt" for "c:\windows\test.txt"
-	else
+	// ============================================================================
+	/// TSmartPath::EndsWithSeparator
+	/// @date 2010/10/16
+	///
+	/// @brief     Checks if path end with a path separator (/ or \)
+	/// @return    True if path ends with separator, false otherwise.
+	// ============================================================================
+	bool TSmartPath::EndsWithSeparator() const
 	{
-		// no path separator inside - everything in this path is a filename
-		Clear();
+		size_t stThisSize = m_strPath.GetLength();
+		if (stThisSize > 0)
+		{
+			wchar_t wchLastChar = m_strPath.GetAt(stThisSize - 1);
+			return (wchLastChar == _T('\\') || wchLastChar == _T('/'));
+		}
+
+		return false;
 	}
-}
 
-// ============================================================================
-/// TSmartPath::EndsWithSeparator
-/// @date 2010/10/16
-///
-/// @brief     Checks if path end with a path separator (/ or \)
-/// @return    True if path ends with separator, false otherwise.
-// ============================================================================
-bool TSmartPath::EndsWithSeparator() const
-{
-	size_t stThisSize = m_strPath.GetLength();
-	if(stThisSize > 0)
+	// ============================================================================
+	/// TSmartPath::AppendSeparatorIfDoesNotExist
+	/// @date 2010/10/16
+	///
+	/// @brief     Appends separator to this path if does not exist already.
+	// ============================================================================
+	void TSmartPath::AppendSeparatorIfDoesNotExist()
 	{
-		wchar_t wchLastChar = m_strPath.GetAt(stThisSize - 1);
-		return (wchLastChar == _T('\\') || wchLastChar == _T('/'));
+		if (!EndsWithSeparator())
+			m_strPath += _T("\\");
 	}
 
-	return false;
-}
+	// ============================================================================
+	/// TSmartPath::StripSeparatorAtEnd
+	/// @date 2010/10/17
+	///
+	/// @brief     Strips separator at the end of path if exists.
+	// ============================================================================
+	void TSmartPath::StripSeparatorAtEnd()
+	{
+		if (EndsWithSeparator())
+			m_strPath.Delete(m_strPath.GetLength() - 1, 1);
+	}
 
-// ============================================================================
-/// TSmartPath::AppendSeparatorIfDoesNotExist
-/// @date 2010/10/16
-///
-/// @brief     Appends separator to this path if does not exist already.
-// ============================================================================
-void TSmartPath::AppendSeparatorIfDoesNotExist()
-{
-	if(!EndsWithSeparator())
-		m_strPath += _T("\\");
-}
+	// ============================================================================
+	/// TSmartPath::StartsWithSeparator
+	/// @date 2010/10/16
+	///
+	/// @brief     Checks if path starts with a separator.
+	/// @return    True if path starts with separator, false otherwise.
+	// ============================================================================
+	bool TSmartPath::StartsWithSeparator() const
+	{
+		wchar_t wchLastChar = 0;
+		if (m_strPath.GetLength() > 0)
+			wchLastChar = m_strPath.GetAt(0);
 
-// ============================================================================
-/// TSmartPath::StripSeparatorAtEnd
-/// @date 2010/10/17
-///
-/// @brief     Strips separator at the end of path if exists.
-// ============================================================================
-void TSmartPath::StripSeparatorAtEnd()
-{
-	if(EndsWithSeparator())
-		m_strPath.Delete(m_strPath.GetLength() - 1, 1);
-}
+		return (wchLastChar == _T('\\') || wchLastChar == _T('/'));
+	}
 
-// ============================================================================
-/// TSmartPath::StartsWithSeparator
-/// @date 2010/10/16
-///
-/// @brief     Checks if path starts with a separator.
-/// @return    True if path starts with separator, false otherwise.
-// ============================================================================
-bool TSmartPath::StartsWithSeparator() const
-{
-	wchar_t wchLastChar = 0;
-	if(m_strPath.GetLength() > 0)
-		wchLastChar = m_strPath.GetAt(0);
+	// ============================================================================
+	/// TSmartPath::PrependSeparatorIfDoesNotExist
+	/// @date 2010/10/17
+	///
+	/// @brief     Prepends a separator to this path if not exist already.
+	// ============================================================================
+	void TSmartPath::PrependSeparatorIfDoesNotExist()
+	{
+		if (!StartsWithSeparator())
+			m_strPath = _T("\\") + m_strPath;
+	}
 
-	return (wchLastChar == _T('\\') || wchLastChar == _T('/'));
-}
+	// ============================================================================
+	/// TSmartPath::StripSeparatorAtFront
+	/// @date 2010/10/17
+	///
+	/// @brief     Strips separator at the front of this path (if exists).
+	// ============================================================================
+	void TSmartPath::StripSeparatorAtFront()
+	{
+		if (StartsWithSeparator())
+			m_strPath.Delete(0, 1);
+	}
 
-// ============================================================================
-/// TSmartPath::PrependSeparatorIfDoesNotExist
-/// @date 2010/10/17
-///
-/// @brief     Prepends a separator to this path if not exist already.
-// ============================================================================
-void TSmartPath::PrependSeparatorIfDoesNotExist()
-{
-	if(!StartsWithSeparator())
-		m_strPath = _T("\\") + m_strPath;
-}
+	// ============================================================================
+	/// TSmartPath::IsEmpty
+	/// @date 2010/10/07
+	///
+	/// @brief     Prepares the path to be written to.
+	// ============================================================================
+	bool TSmartPath::IsEmpty() const
+	{
+		return m_strPath.IsEmpty();
+	}
 
-// ============================================================================
-/// TSmartPath::StripSeparatorAtFront
-/// @date 2010/10/17
-///
-/// @brief     Strips separator at the front of this path (if exists).
-// ============================================================================
-void TSmartPath::StripSeparatorAtFront()
-{
-	if(StartsWithSeparator())
-		m_strPath.Delete(0, 1);
-}
+	// ============================================================================
+	/// TSmartPath::GetLength
+	/// @date 2011/04/05
+	///
+	/// @brief     Retrieves path length in characters.
+	/// @return    Path length.
+	// ============================================================================
+	size_t TSmartPath::GetLength() const
+	{
+		return m_strPath.GetLength();
+	}
 
-// ============================================================================
-/// TSmartPath::IsEmpty
-/// @date 2010/10/07
-///
-/// @brief     Prepares the path to be written to.
-// ============================================================================
-bool TSmartPath::IsEmpty() const
-{
-	return m_strPath.IsEmpty();
-}
+	// ============================================================================
+	/// TSmartPath::IsSeparator
+	/// @date 2010/10/17
+	///
+	/// @brief     Checks if the character is a separator.
+	/// @param[in] wchSeparator - Character to be checked.
+	/// @return    True if it is a separator, false otherwise.
+	// ============================================================================
+	bool TSmartPath::IsSeparator(wchar_t wchSeparator)
+	{
+		return (wchSeparator == _T('\\') || wchSeparator == _T('/'));
+	}
 
-// ============================================================================
-/// TSmartPath::GetLength
-/// @date 2011/04/05
-///
-/// @brief     Retrieves path length in characters.
-/// @return    Path length.
-// ============================================================================
-size_t TSmartPath::GetLength() const
-{
-	return m_strPath.GetLength();
-}
+	bool TSmartPath::IsRelativePath() const
+	{
+		return !HasDrive() && !HasServerName();
+	}
 
-// ============================================================================
-/// TSmartPath::IsSeparator
-/// @date 2010/10/17
-///
-/// @brief     Checks if the character is a separator.
-/// @param[in] wchSeparator - Character to be checked.
-/// @return    True if it is a separator, false otherwise.
-// ============================================================================
-bool TSmartPath::IsSeparator(wchar_t wchSeparator)
-{
-	return (wchSeparator == _T('\\') || wchSeparator == _T('/'));
-}
+	bool TSmartPath::StartsWith(const TSmartPath& rPath, bool bCaseSensitive)
+	{
+		if(bCaseSensitive)
+			return m_strPath.StartsWith(rPath.m_strPath.c_str());
 
-bool TSmartPath::IsRelativePath() const
-{
-	return !HasDrive() && !HasServerName();
-}
+		return m_strPath.StartsWithNoCase(rPath.m_strPath.c_str());
+	}
 
-// ============================================================================
-/// PathFromString
-/// @date 2010/10/12
-///
-/// @brief     Creates a path object from string.
-/// @param[in] pszPath - string containing path.
-/// @return    New path object.
-// ============================================================================
-TSmartPath PathFromString(const wchar_t* pszPath)
-{
-	if(!pszPath)
-		THROW(_T("Invalid pointer"), 0, 0, 0);
+	// ============================================================================
+	/// PathFromString
+	/// @date 2010/10/12
+	///
+	/// @brief     Creates a path object from string.
+	/// @param[in] pszPath - string containing path.
+	/// @return    New path object.
+	// ============================================================================
+	TSmartPath PathFromString(const wchar_t* pszPath)
+	{
+		if (!pszPath)
+			THROW(_T("Invalid pointer"), 0, 0, 0);
 
-	TSmartPath spPath;
-	spPath.FromString(pszPath);
-	return spPath;
-}
+		TSmartPath spPath;
+		spPath.FromString(pszPath);
+		return spPath;
+	}
 
-// ============================================================================
-/// PathFromWString
-/// @date 2010/10/12
-///
-/// @brief     Creates a path object from string.
-/// @param[in] pszPath - string containing path.
-/// @return    New path object.
-// ============================================================================
-TSmartPath PathFromWString(const TString& strPath)
-{
-	TSmartPath spPath;
-	spPath.FromString(strPath);
-	return spPath;
+	// ============================================================================
+	/// PathFromWString
+	/// @date 2010/10/12
+	///
+	/// @brief     Creates a path object from string.
+	/// @param[in] pszPath - string containing path.
+	/// @return    New path object.
+	// ============================================================================
+	TSmartPath PathFromWString(const TString& strPath)
+	{
+		TSmartPath spPath;
+		spPath.FromString(strPath);
+		return spPath;
+	}
 }
-
-END_CHCORE_NAMESPACE
Index: src/libchcore/TPath.h
===================================================================
diff -u -r7b830c34855c8aaa81aac2c6e0ca0fa6bae95e66 -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/TPath.h	(.../TPath.h)	(revision 7b830c34855c8aaa81aac2c6e0ca0fa6bae95e66)
+++ src/libchcore/TPath.h	(.../TPath.h)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -100,8 +100,10 @@
 
 	bool HasFileName() const;				// test.txt for c:\windows\test.txt
 	TSmartPath GetFileName() const;			// test.txt for c:\windows\test.txt
-	void DeleteFileName();			// test.txt for c:\windows\test.txt
+	void DeleteFileName();					// c:\windows\ for c:\windows\test.txt
 
+	TSmartPath GetParent() const;
+
 	bool EndsWithSeparator() const;
 	void AppendSeparatorIfDoesNotExist();
 	void StripSeparatorAtEnd();
@@ -110,6 +112,8 @@
 	void PrependSeparatorIfDoesNotExist();
 	void StripSeparatorAtFront();
 
+	bool StartsWith(const TSmartPath& rPath, bool bCaseSensitive = DefaultCaseSensitivity);
+
 	bool IsEmpty() const;
 	size_t GetLength() const;
 
Index: src/libchcore/TSubTaskCopyMove.cpp
===================================================================
diff -u -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/TSubTaskCopyMove.cpp	(.../TSubTaskCopyMove.cpp)	(revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b)
+++ src/libchcore/TSubTaskCopyMove.cpp	(.../TSubTaskCopyMove.cpp)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -272,8 +272,8 @@
 	const TConfig& rConfig = GetContext().GetConfig();
 	IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem();
 
-	IFilesystemFilePtr fileSrc = spFilesystem->CreateFileObject();
-	IFilesystemFilePtr fileDst = spFilesystem->CreateFileObject();
+	IFilesystemFilePtr fileSrc = spFilesystem->CreateFileObject(pData->spSrcFile->GetFullFilePath());
+	IFilesystemFilePtr fileDst = spFilesystem->CreateFileObject(pData->pathDstFile);
 
 	TString strFormat;
 	TSubTaskBase::ESubOperationResult eResult = TSubTaskBase::eSubResult_Continue;
@@ -315,7 +315,9 @@
 		pData->dbBuffer.GetEventReadPossibleHandle()
 	};
 
+	// #bug: always starting at the beginning of file instead of the position that OpenSrcAndDstFilesFB set the files to
 	unsigned long long ullNextReadPos = 0;
+
 	bool bStopProcessing = false;
 	while(!bStopProcessing)
 	{
@@ -524,7 +526,7 @@
 	bSkip = false;
 
 	// first open the source file and handle any failures
-	TSubTaskCopyMove::ESubOperationResult eResult = OpenSourceFileFB(spFeedbackHandler, spFileSrc, pData->spSrcFile->GetFullFilePath(), bNoBuffer);
+	TSubTaskCopyMove::ESubOperationResult eResult = OpenSourceFileFB(spFeedbackHandler, spFileSrc, bNoBuffer);
 	if(eResult != TSubTaskBase::eSubResult_Continue)
 		return eResult;
 	else if(!spFileSrc->IsOpen())
@@ -578,7 +580,7 @@
 	{
 		// open destination file for case, when we start operation on this file (i.e. it is not resume of the
 		// old operation)
-		eResult = OpenDestinationFileFB(spFeedbackHandler, spFileDst, pData->pathDstFile, bNoBuffer, pData->spSrcFile, ullSeekTo, bDstFileFreshlyCreated);
+		eResult = OpenDestinationFileFB(spFeedbackHandler, spFileDst, bNoBuffer, pData->spSrcFile, ullSeekTo, bDstFileFreshlyCreated);
 		if(eResult != TSubTaskBase::eSubResult_Continue)
 			return eResult;
 		else if(!spFileDst->IsOpen())
@@ -596,7 +598,7 @@
 	else
 	{
 		// we are resuming previous operation
-		eResult = OpenExistingDestinationFileFB(spFeedbackHandler, spFileDst, pData->pathDstFile, bNoBuffer);
+		eResult = OpenExistingDestinationFileFB(spFeedbackHandler, spFileDst, bNoBuffer);
 		if(eResult != TSubTaskBase::eSubResult_Continue)
 			return eResult;
 		else if(!spFileDst->IsOpen())
@@ -624,40 +626,9 @@
 	}
 
 	// seek to the position where copying will start
-	if(ullSeekTo != 0)		// src and dst files exists, requested resume at the specified index
+	ULONGLONG ullMove = (bNoBuffer ? RoundDown<unsigned long long>(ullSeekTo, IFilesystemFile::MaxSectorSize) : ullSeekTo);;
+	if(ullMove != 0)		// src and dst files exists, requested resume at the specified index
 	{
-		// try to move file pointers to the end
-		ULONGLONG ullMove = (bNoBuffer ? RoundDown<unsigned long long>(ullSeekTo, IFilesystemFile::MaxSectorSize) : ullSeekTo);
-
-		eResult = SetFilePointerFB(spFeedbackHandler, spFileSrc, ullMove, pData->spSrcFile->GetFullFilePath(), bSkip);
-		if(eResult != TSubTaskBase::eSubResult_Continue)
-			return eResult;
-		else if(bSkip)
-		{
-			unsigned long long ullDiff = pData->spSrcFile->GetLength64() - ullProcessedSize;
-
-			m_tSubTaskStats.IncreaseProcessedSize(ullDiff);
-			m_tSubTaskStats.IncreaseCurrentItemProcessedSize(ullDiff);
-
-			pData->bProcessed = false;
-			return TSubTaskBase::eSubResult_Continue;
-		}
-
-		eResult = SetFilePointerFB(spFeedbackHandler, spFileDst, ullMove, pData->pathDstFile, bSkip);
-		if(eResult != TSubTaskBase::eSubResult_Continue)
-			return eResult;
-		else if(bSkip)
-		{
-			// with either first or second seek we got 'skip' answer...
-			unsigned long long ullDiff = pData->spSrcFile->GetLength64() - ullProcessedSize;
-
-			m_tSubTaskStats.IncreaseProcessedSize(ullDiff);
-			m_tSubTaskStats.IncreaseCurrentItemProcessedSize(ullDiff);
-
-			pData->bProcessed = false;
-			return TSubTaskBase::eSubResult_Continue;
-		}
-
 		// adjust the stats for the difference between what was already processed and what will now be considered processed
 		if (ullMove > ullProcessedSize)
 		{
@@ -677,7 +648,7 @@
 	if(!bDstFileFreshlyCreated)
 	{
 		// if destination file was opened (as opposed to newly created)
-		eResult = SetEndOfFileFB(spFeedbackHandler, spFileDst, pData->pathDstFile, bSkip);
+		eResult = TruncateFileFB(spFeedbackHandler, spFileDst, ullMove, pData->pathDstFile, bSkip);
 		if(eResult != TSubTaskBase::eSubResult_Continue)
 			return eResult;
 		else if(bSkip)
@@ -725,28 +696,23 @@
 	return false;	// buffer did not need adjusting
 }
 
-TSubTaskBase::ESubOperationResult TSubTaskCopyMove::OpenSourceFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFileSrc,
-	const TSmartPath& spPathToOpen, bool bNoBuffering)
+TSubTaskBase::ESubOperationResult TSubTaskCopyMove::OpenSourceFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileSrc, bool bNoBuffering)
 {
 	icpf::log_file& rLog = GetContext().GetLog();
 
-	BOOST_ASSERT(!spPathToOpen.IsEmpty());
-	if(spPathToOpen.IsEmpty())
-		THROW_CORE_EXCEPTION(eErr_InvalidArgument);
-
 	bool bRetry = false;
 
-	spFileSrc->Close();
+	fileSrc->Close();
 
 	do
 	{
 		bRetry = false;
 
-		if(!spFileSrc->OpenExistingForReading(spPathToOpen, bNoBuffering))
+		if(!fileSrc->OpenExistingForReading(bNoBuffering))
 		{
 			DWORD dwLastError = GetLastError();
 
-			EFeedbackResult frResult = spFeedbackHandler->FileError(spPathToOpen.ToWString(), TString(), EFileError::eCreateError, dwLastError);
+			EFeedbackResult frResult = spFeedbackHandler->FileError(fileSrc->GetFilePath().ToWString(), TString(), EFileError::eCreateError, dwLastError);
 			switch(frResult)
 			{
 			case EFeedbackResult::eResult_Skip:
@@ -757,7 +723,7 @@
 					// log
 					TString strFormat = _T("Cancel request [error %errno] while opening source file %path (OpenSourceFileFB)");
 					strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
-					strFormat.Replace(_T("%path"), spPathToOpen.ToString());
+					strFormat.Replace(_T("%path"), fileSrc->GetFilePath().ToString());
 					rLog.loge(strFormat.c_str());
 
 					return TSubTaskBase::eSubResult_CancelRequest;
@@ -771,7 +737,7 @@
 					// log
 					TString strFormat = _T("Retrying [error %errno] to open source file %path (OpenSourceFileFB)");
 					strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
-					strFormat.Replace(_T("%path"), spPathToOpen.ToString());
+					strFormat.Replace(_T("%path"), fileSrc->GetFilePath().ToString());
 					rLog.loge(strFormat.c_str());
 
 					bRetry = true;
@@ -789,8 +755,7 @@
 	return TSubTaskBase::eSubResult_Continue;
 }
 
-TSubTaskBase::ESubOperationResult TSubTaskCopyMove::OpenDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFileDst,
-	const TSmartPath& pathDstFile, bool bNoBuffering, const TFileInfoPtr& spSrcFileInfo, unsigned long long& ullSeekTo, bool& bFreshlyCreated)
+TSubTaskBase::ESubOperationResult TSubTaskCopyMove::OpenDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileDst, bool bNoBuffering, const TFileInfoPtr& spSrcFileInfo, unsigned long long& ullSeekTo, bool& bFreshlyCreated)
 {
 	icpf::log_file& rLog = GetContext().GetLog();
 	IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem();
@@ -800,23 +765,23 @@
 	ullSeekTo = 0;
 	bFreshlyCreated = true;
 
-	spFileDst->Close();
+	fileDst->Close();
 	do
 	{
 		bRetry = false;
 
-		if(!spFileDst->CreateNewForWriting(pathDstFile, bNoBuffering))
+		if(!fileDst->CreateNewForWriting(bNoBuffering))
 		{
 			DWORD dwLastError = GetLastError();
 			if(dwLastError == ERROR_FILE_EXISTS)
 			{
 				bFreshlyCreated = false;
 
 				// pass it to the specialized method
-				TSubTaskBase::ESubOperationResult eResult = OpenExistingDestinationFileFB(spFeedbackHandler, spFileDst, pathDstFile, bNoBuffering);
+				TSubTaskBase::ESubOperationResult eResult = OpenExistingDestinationFileFB(spFeedbackHandler, fileDst, bNoBuffering);
 				if(eResult != TSubTaskBase::eSubResult_Continue)
 					return eResult;
-				else if(!spFileDst->IsOpen())
+				else if(!fileDst->IsOpen())
 					return TSubTaskBase::eSubResult_Continue;
 
 				// read info about the existing destination file,
@@ -825,7 +790,7 @@
 				//       reading parameters using opened handle; need to be tested in the future
 				TFileInfoPtr spDstFileInfo(boost::make_shared<TFileInfo>());
 
-				if(!spFilesystem->GetFileInfo(pathDstFile, spDstFileInfo))
+				if(!spFilesystem->GetFileInfo(fileDst->GetFilePath(), spDstFileInfo))
 					THROW_CORE_EXCEPTION_WIN32(eErr_CannotGetFileInfo, GetLastError());
 
 				// src and dst files are the same
@@ -847,7 +812,7 @@
 					{
 						// log
 						TString strFormat = _T("Cancel request while checking result of dialog before opening source file %path (CustomCopyFileFB)");
-						strFormat.Replace(_T("%path"), pathDstFile.ToString());
+						strFormat.Replace(_T("%path"), fileDst->GetFilePath().ToString());
 						rLog.logi(strFormat.c_str());
 
 						return TSubTaskBase::eSubResult_CancelRequest;
@@ -862,15 +827,15 @@
 			}
 			else
 			{
-				EFeedbackResult frResult = spFeedbackHandler->FileError(pathDstFile.ToWString(), TString(), EFileError::eCreateError, dwLastError);
+				EFeedbackResult frResult = spFeedbackHandler->FileError(fileDst->GetFilePath().ToWString(), TString(), EFileError::eCreateError, dwLastError);
 				switch(frResult)
 				{
 				case EFeedbackResult::eResult_Retry:
 					{
 						// log
 						TString strFormat = _T("Retrying [error %errno] to open destination file %path (CustomCopyFileFB)");
 						strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
-						strFormat.Replace(_T("%path"), pathDstFile.ToString());
+						strFormat.Replace(_T("%path"), fileDst->GetFilePath().ToString());
 						rLog.loge(strFormat.c_str());
 
 						bRetry = true;
@@ -882,7 +847,7 @@
 						// log
 						TString strFormat = _T("Cancel request [error %errno] while opening destination file %path (CustomCopyFileFB)");
 						strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
-						strFormat.Replace(_T("%path"), pathDstFile.ToString());
+						strFormat.Replace(_T("%path"), fileDst->GetFilePath().ToString());
 						rLog.loge(strFormat.c_str());
 
 						return TSubTaskBase::eSubResult_CancelRequest;
@@ -906,32 +871,31 @@
 	return TSubTaskBase::eSubResult_Continue;
 }
 
-TSubTaskBase::ESubOperationResult TSubTaskCopyMove::OpenExistingDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFileDst,
-	const TSmartPath& pathDstFile, bool bNoBuffering)
+TSubTaskBase::ESubOperationResult TSubTaskCopyMove::OpenExistingDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileDst, bool bNoBuffering)
 {
 	icpf::log_file& rLog = GetContext().GetLog();
 
 	bool bRetry = false;
 
-	spFileDst->Close();
+	fileDst->Close();
 
 	do
 	{
 		bRetry = false;
 
-		if(!spFileDst->OpenExistingForWriting(pathDstFile, bNoBuffering))
+		if(!fileDst->OpenExistingForWriting(bNoBuffering))
 		{
 			DWORD dwLastError = GetLastError();
 
-			EFeedbackResult frResult = spFeedbackHandler->FileError(pathDstFile.ToWString(), TString(), EFileError::eCreateError, dwLastError);
+			EFeedbackResult frResult = spFeedbackHandler->FileError(fileDst->GetFilePath().ToWString(), TString(), EFileError::eCreateError, dwLastError);
 			switch (frResult)
 			{
 			case EFeedbackResult::eResult_Retry:
 				{
 					// log
 					TString strFormat = _T("Retrying [error %errno] to open destination file %path (CustomCopyFileFB)");
 					strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
-					strFormat.Replace(_t("%path"), pathDstFile.ToString());
+					strFormat.Replace(_t("%path"), fileDst->GetFilePath().ToString());
 					rLog.loge(strFormat.c_str());
 
 					bRetry = true;
@@ -943,7 +907,7 @@
 					// log
 					TString strFormat = _T("Cancel request [error %errno] while opening destination file %path (CustomCopyFileFB)");
 					strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
-					strFormat.Replace(_T("%path"), pathDstFile.ToString());
+					strFormat.Replace(_T("%path"), fileDst->GetFilePath().ToString());
 					rLog.loge(strFormat.c_str());
 
 					return TSubTaskBase::eSubResult_CancelRequest;
@@ -966,57 +930,7 @@
 	return TSubTaskBase::eSubResult_Continue;
 }
 
-TSubTaskBase::ESubOperationResult TSubTaskCopyMove::SetFilePointerFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFile,
-	long long llDistance, const TSmartPath& pathFile, bool& bSkip)
-{
-	icpf::log_file& rLog = GetContext().GetLog();
-
-	bSkip = false;
-	bool bRetry = false;
-	do
-	{
-		bRetry = false;
-
-		if(!spFile->SetFilePointer(llDistance, FILE_BEGIN))
-		{
-			DWORD dwLastError = GetLastError();
-
-			// log
-			TString strFormat = _T("Error %errno while moving file pointer of %path to %pos");
-			strFormat.Replace(_t("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
-			strFormat.Replace(_t("%path"), pathFile.ToString());
-			strFormat.Replace(_t("%pos"), boost::lexical_cast<std::wstring>(llDistance).c_str());
-			rLog.loge(strFormat.c_str());
-
-			EFeedbackResult frResult = spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eSeekError, dwLastError);
-			switch(frResult)
-			{
-			case EFeedbackResult::eResult_Cancel:
-				return TSubTaskBase::eSubResult_CancelRequest;
-
-			case EFeedbackResult::eResult_Retry:
-				bRetry = true;
-				break;
-
-			case EFeedbackResult::eResult_Pause:
-				return TSubTaskBase::eSubResult_PauseRequest;
-
-			case EFeedbackResult::eResult_Skip:
-				bSkip = true;
-				return TSubTaskBase::eSubResult_Continue;
-
-			default:
-				BOOST_ASSERT(FALSE);		// unknown result
-				THROW_CORE_EXCEPTION(eErr_UnhandledCase);
-			}
-		}
-	}
-	while(bRetry);
-
-	return TSubTaskBase::eSubResult_Continue;
-}
-
-TSubTaskBase::ESubOperationResult TSubTaskCopyMove::SetEndOfFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFile,
+TSubTaskBase::ESubOperationResult TSubTaskCopyMove::TruncateFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFile, long long llNewSize, 
 	const TSmartPath& pathFile, bool& bSkip)
 {
 	icpf::log_file& rLog = GetContext().GetLog();
@@ -1026,12 +940,12 @@
 	bool bRetry = false;
 	do
 	{
-		if(!spFile->SetEndOfFile())
+		if(!spFile->Truncate(llNewSize))
 		{
 			// log
 			DWORD dwLastError = GetLastError();
 
-			TString strFormat = _T("Error %errno while setting size of file %path to 0");
+			TString strFormat = _T("Error %errno while truncating file %path to 0");
 			strFormat.Replace(_t("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
 			strFormat.Replace(_t("%path"), pathFile.ToString());
 			rLog.loge(strFormat.c_str());
Index: src/libchcore/TSubTaskCopyMove.h
===================================================================
diff -u -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/TSubTaskCopyMove.h	(.../TSubTaskCopyMove.h)	(revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b)
+++ src/libchcore/TSubTaskCopyMove.h	(.../TSubTaskCopyMove.h)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -67,17 +67,12 @@
 	ESubOperationResult OpenSrcAndDstFilesFB(const IFeedbackHandlerPtr& spFeedbackHandler, CUSTOM_COPY_PARAMS* pData,
 		const IFilesystemFilePtr& spFileSrc, const IFilesystemFilePtr& spFileDst, bool bNoBuffer, bool& bSkip);
 
-	ESubOperationResult OpenSourceFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileSrc,
-		const TSmartPath& spPathToOpen, bool bNoBuffering);
-	ESubOperationResult OpenDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileDst,
-		const TSmartPath& pathDstFile, bool bNoBuffering, const TFileInfoPtr& spSrcFileInfo,
+	ESubOperationResult OpenSourceFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileSrc, bool bNoBuffering);
+	ESubOperationResult OpenDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileDst, bool bNoBuffering, const TFileInfoPtr& spSrcFileInfo,
 		unsigned long long& ullSeekTo, bool& bFreshlyCreated);
-	ESubOperationResult OpenExistingDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileDst,
-		const TSmartPath& pathDstFilePath, bool bNoBuffering);
+	ESubOperationResult OpenExistingDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileDst, bool bNoBuffering);
 
-	ESubOperationResult SetFilePointerFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& file,
-		long long llDistance, const TSmartPath& pathFile, bool& bSkip);
-	ESubOperationResult SetEndOfFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& file,
+	ESubOperationResult TruncateFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& file, long long llNewSize,
 		const TSmartPath& pathFile, bool& bSkip);
 
 	ESubOperationResult ReadFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& file,
Index: src/libchcore/Tests/TestsTSmartPath.cpp
===================================================================
diff -u -ra44714d5c7ec0f50a376f4d0ea919ee5a224f834 -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/Tests/TestsTSmartPath.cpp	(.../TestsTSmartPath.cpp)	(revision a44714d5c7ec0f50a376f4d0ea919ee5a224f834)
+++ src/libchcore/Tests/TestsTSmartPath.cpp	(.../TestsTSmartPath.cpp)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -1106,3 +1106,148 @@
 	path.FromString(_T("some path"));
 	EXPECT_EQ(9, path.GetLength());
 }
+
+///////////////////////////////////////////////////////////////////////////////
+TEST(TSmartPathTests, GetParent_FilePath)
+{
+	TSmartPath path;
+	path.FromString(L"c:\\windows\\test.txt");
+
+	EXPECT_STREQ(L"c:\\windows\\", path.GetParent().ToString());
+}
+
+TEST(TSmartPathTests, GetParent_DirPath)
+{
+	TSmartPath path;
+	path.FromString(L"c:\\windows\\");
+
+	EXPECT_STREQ(L"c:\\", path.GetParent().ToString());
+}
+
+TEST(TSmartPathTests, GetParent_NetFilePath)
+{
+	TSmartPath path;
+	path.FromString(L"\\\\SomeServer\\windows\\test.txt");
+
+	EXPECT_STREQ(L"\\\\SomeServer\\windows\\", path.GetParent().ToString());
+}
+
+TEST(TSmartPathTests, GetParent_NetDirPath)
+{
+	TSmartPath path;
+	path.FromString(L"\\\\SomeServer\\windows\\");
+
+	EXPECT_STREQ(L"\\\\SomeServer\\", path.GetParent().ToString());
+}
+
+TEST(TSmartPathTests, GetParent_ServerNameRootDir)
+{
+	TSmartPath path;
+	path.FromString(L"\\\\SomeServer\\");
+
+	EXPECT_STREQ(L"\\\\SomeServer", path.GetParent().ToString());
+}
+
+TEST(TSmartPathTests, GetParent_DiskRootDir)
+{
+	TSmartPath path;
+	path.FromString(L"c:\\");
+
+	EXPECT_STREQ(L"c:", path.GetParent().ToString());
+}
+
+TEST(TSmartPathTests, GetParent_ServerName)
+{
+	TSmartPath path;
+	path.FromString(L"\\\\SomeServer");
+
+	EXPECT_STREQ(L"", path.GetParent().ToString());
+}
+
+TEST(TSmartPathTests, GetParent_Disk)
+{
+	TSmartPath path;
+	path.FromString(L"c:");
+
+	EXPECT_STREQ(L"", path.GetParent().ToString());
+}
+
+TEST(TSmartPathTests, StartsWith_SameCase_Positive)
+{
+	TSmartPath path;
+	path.FromString(L"c:\\windows\\file.txt");
+
+	EXPECT_TRUE(path.StartsWith(PathFromString(L"c:\\windows")));
+}
+
+TEST(TSmartPathTests, StartsWith_NoCase_SameCase_Positive)
+{
+	TSmartPath path;
+	path.FromString(L"c:\\windows\\file.txt");
+
+	EXPECT_TRUE(path.StartsWith(PathFromString(L"c:\\windows"), false));
+}
+
+TEST(TSmartPathTests, StartsWith_NoCase_DiffCase_Positive)
+{
+	TSmartPath path;
+	path.FromString(L"c:\\windows\\file.txt");
+
+	EXPECT_TRUE(path.StartsWith(PathFromString(L"c:\\Windows"), false));
+}
+
+TEST(TSmartPathTests, StartsWith_CaseSensitive_SameCase_Positive)
+{
+	TSmartPath path;
+	path.FromString(L"c:\\windows\\file.txt");
+
+	EXPECT_TRUE(path.StartsWith(PathFromString(L"c:\\windows"), true));
+}
+
+TEST(TSmartPathTests, StartsWith_CaseSensitive_DiffCase_Positive)
+{
+	TSmartPath path;
+	path.FromString(L"c:\\windows\\file.txt");
+
+	EXPECT_FALSE(path.StartsWith(PathFromString(L"c:\\Windows"), true));
+}
+
+TEST(TSmartPathTests, StartsWith_SameCase_Negative)
+{
+	TSmartPath path;
+	path.FromString(L"c:\\windows\\file.txt");
+
+	EXPECT_FALSE(path.StartsWith(PathFromString(L"\\windows")));
+}
+
+TEST(TSmartPathTests, StartsWith_NoCase_SameCase_Negative)
+{
+	TSmartPath path;
+	path.FromString(L"c:\\windows\\file.txt");
+
+	EXPECT_FALSE(path.StartsWith(PathFromString(L"\\windows"), false));
+}
+
+TEST(TSmartPathTests, StartsWith_NoCase_DiffCase_Negative)
+{
+	TSmartPath path;
+	path.FromString(L"c:\\windows\\file.txt");
+
+	EXPECT_FALSE(path.StartsWith(PathFromString(L"\\Windows"), false));
+}
+
+TEST(TSmartPathTests, StartsWith_CaseSensitive_SameCase_Negative)
+{
+	TSmartPath path;
+	path.FromString(L"c:\\windows\\file.txt");
+
+	EXPECT_FALSE(path.StartsWith(PathFromString(L"\\windows"), true));
+}
+
+TEST(TSmartPathTests, StartsWith_CaseSensitive_DiffCase_Negative)
+{
+	TSmartPath path;
+	path.FromString(L"c:\\windows\\file.txt");
+
+	EXPECT_FALSE(path.StartsWith(PathFromString(L"\\Windows"), true));
+}
Index: src/libchcore/libchcore.vc140.vcxproj
===================================================================
diff -u -r5efb534fc5440a7ab779d2514a00486ecb58e845 -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/libchcore.vc140.vcxproj	(.../libchcore.vc140.vcxproj)	(revision 5efb534fc5440a7ab779d2514a00486ecb58e845)
+++ src/libchcore/libchcore.vc140.vcxproj	(.../libchcore.vc140.vcxproj)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -523,6 +523,7 @@
     <ClInclude Include="TFakeFilesystem.h" />
     <ClInclude Include="TFakeFilesystemFile.h" />
     <ClInclude Include="TFakeFilesystemFind.h" />
+    <ClInclude Include="TFakeVolumeInfo.h" />
     <ClInclude Include="TFeedbackHandlerBase.h" />
     <ClInclude Include="TFeedbackHandlerWrapper.h" />
     <ClInclude Include="TFileAlreadyExistsFilter.h" />
@@ -753,6 +754,7 @@
     <ClCompile Include="TFakeFilesystem.cpp" />
     <ClCompile Include="TFakeFilesystemFile.cpp" />
     <ClCompile Include="TFakeFilesystemFind.cpp" />
+    <ClCompile Include="TFakeVolumeInfo.cpp" />
     <ClCompile Include="TFeedbackHandlerBase.cpp" />
     <ClCompile Include="TFeedbackHandlerWrapper.cpp" />
     <ClCompile Include="TFileAlreadyExistsFilter.cpp" />
Index: src/libchcore/libchcore.vc140.vcxproj.filters
===================================================================
diff -u -r5efb534fc5440a7ab779d2514a00486ecb58e845 -r27c262eb9cae55720e10f4886af6b5a82cb94fe9
--- src/libchcore/libchcore.vc140.vcxproj.filters	(.../libchcore.vc140.vcxproj.filters)	(revision 5efb534fc5440a7ab779d2514a00486ecb58e845)
+++ src/libchcore/libchcore.vc140.vcxproj.filters	(.../libchcore.vc140.vcxproj.filters)	(revision 27c262eb9cae55720e10f4886af6b5a82cb94fe9)
@@ -437,6 +437,9 @@
     <ClInclude Include="TSparseRangeMap.h">
       <Filter>Source Files\Tools</Filter>
     </ClInclude>
+    <ClInclude Include="TFakeVolumeInfo.h">
+      <Filter>Source Files\Filesystems\Fake</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="TSubTaskArray.cpp">
@@ -811,5 +814,8 @@
     <ClCompile Include="Tests\TestsTSparseRangeMap.cpp">
       <Filter>Tests</Filter>
     </ClCompile>
+    <ClCompile Include="TFakeVolumeInfo.cpp">
+      <Filter>Source Files\Filesystems\Fake</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>
\ No newline at end of file