Index: src/libchcore/EFileError.h
===================================================================
diff -u -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 -rd468098a278a0d16c5b700236ea276b9c9677c9f
--- src/libchcore/EFileError.h	(.../EFileError.h)	(revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3)
+++ src/libchcore/EFileError.h	(.../EFileError.h)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
@@ -32,7 +32,8 @@
 		eWriteError,		///< Problem occurred when tried to write data to a file
 		eFinalizeError,		///< Problem occurred when tried to finalize file
 		eFastMoveError,		///< Problem occurred when tried to perform fast move operation (that does not involve copying contents)
-		eCreateError		///< Problem occurred when tried to create the fs object
+		eCreateError,		///< Problem occurred when tried to create the fs object
+		eCheckForFreeSpace	///< Problem occurred when tried to create the fs object
 	};
 }
 
Index: src/libchcore/ErrorCodes.h
===================================================================
diff -u -r27a43e40952cf2f3e0bb0e608a8f3142042ceb46 -rd468098a278a0d16c5b700236ea276b9c9677c9f
--- src/libchcore/ErrorCodes.h	(.../ErrorCodes.h)	(revision 27a43e40952cf2f3e0bb0e608a8f3142042ceb46)
+++ src/libchcore/ErrorCodes.h	(.../ErrorCodes.h)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
@@ -83,6 +83,12 @@
 		eErr_FileNotOpen = 3007,
 		eErr_SeekFailed = 3008,
 		eErr_CannotTruncate = 3009,
+		eErr_CannotSetFileTimes = 3010,
+		eErr_CannotSetFileAttributes = 3011,
+		eErr_CannotCreateDirectory = 3012,
+		eErr_CannotRemoveDirectory = 3013,
+		eErr_CannotFastMove = 3014,
+		eErr_CannotGetFreeSpace = 3015,
 
 		// Task handling errors (4000+)
 		eErr_MissingTaskSerializationPath = 4000,
Index: src/libchcore/IFilesystem.h
===================================================================
diff -u -r479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc -rd468098a278a0d16c5b700236ea276b9c9677c9f
--- src/libchcore/IFilesystem.h	(.../IFilesystem.h)	(revision 479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc)
+++ src/libchcore/IFilesystem.h	(.../IFilesystem.h)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
@@ -46,22 +46,22 @@
 
 		virtual bool PathExist(const TSmartPath& strPath) = 0;
 
-		virtual bool SetFileDirectoryTime(const TSmartPath& pathFileDir, const TFileTime& ftCreationTime, const TFileTime& ftLastAccessTime, const TFileTime& ftLastWriteTime) = 0;
-		virtual bool SetAttributes(const TSmartPath& pathFileDir, DWORD dwAttributes) = 0;
+		virtual void SetFileDirectoryTime(const TSmartPath& pathFileDir, const TFileTime& ftCreationTime, const TFileTime& ftLastAccessTime, const TFileTime& ftLastWriteTime) = 0;
+		virtual void SetAttributes(const TSmartPath& pathFileDir, DWORD dwAttributes) = 0;
 
-		virtual bool CreateDirectory(const TSmartPath& pathDirectory, bool bCreateFullPath) = 0;
-		virtual bool RemoveDirectory(const TSmartPath& pathFile) = 0;
-		virtual bool DeleteFile(const TSmartPath& pathFile) = 0;
+		virtual void CreateDirectory(const TSmartPath& pathDirectory, bool bCreateFullPath) = 0;
+		virtual void RemoveDirectory(const TSmartPath& pathFile) = 0;
+		virtual void DeleteFile(const TSmartPath& pathFile) = 0;
 
-		virtual bool GetFileInfo(const TSmartPath& pathFile, TFileInfoPtr& rFileInfo, const TBasePathDataPtr& spBasePathData = TBasePathDataPtr()) = 0;
-		virtual bool FastMove(const TSmartPath& pathSource, const TSmartPath& pathDestination) = 0;
+		virtual void GetFileInfo(const TSmartPath& pathFile, TFileInfoPtr& rFileInfo, const TBasePathDataPtr& spBasePathData = TBasePathDataPtr()) = 0;
+		virtual void FastMove(const TSmartPath& pathSource, const TSmartPath& pathDestination) = 0;
 
 		virtual IFilesystemFindPtr CreateFinderObject(const TSmartPath& pathDir, const TSmartPath& pathMask) = 0;
 		virtual IFilesystemFilePtr CreateFileObject(const TSmartPath& pathFile, bool bNoBuffering) = 0;
 
 		virtual EPathsRelation GetPathsRelation(const TSmartPath& pathFirst, const TSmartPath& pathSecond) = 0;
 
-		virtual bool GetDynamicFreeSpace(const TSmartPath& path, unsigned long long& rullFree) = 0;
+		virtual void GetDynamicFreeSpace(const TSmartPath& path, unsigned long long& rullFree) = 0;
 	};
 
 	typedef std::shared_ptr<IFilesystem> IFilesystemPtr;
Index: src/libchcore/TFakeFilesystem.cpp
===================================================================
diff -u -r479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc -rd468098a278a0d16c5b700236ea276b9c9677c9f
--- src/libchcore/TFakeFilesystem.cpp	(.../TFakeFilesystem.cpp)	(revision 479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc)
+++ src/libchcore/TFakeFilesystem.cpp	(.../TFakeFilesystem.cpp)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
@@ -24,6 +24,7 @@
 #include "TFakeFilesystemFile.h"
 #include "TFakeFilesystemFind.h"
 #include "TPathContainer.h"
+#include "TFileException.h"
 
 namespace chcore
 {
@@ -46,7 +47,7 @@
 		return false;
 	}
 
-	bool TFakeFilesystem::GetDynamicFreeSpace(const TSmartPath& path, unsigned long long& rullFree)
+	void 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();
@@ -60,12 +61,15 @@
 		{
 			file_size_t fsFileSize(RoundUp(spDesc->GetFileInfo().GetLength64(), (file_size_t)IFilesystemFile::MaxSectorSize));
 			if (fsFileSize > fsSize)
-				return false;
+			{
+				rullFree = 0;
+				return;
+			}
+
 			fsSize -= RoundUp(spDesc->GetFileInfo().GetLength64(), (file_size_t)IFilesystemFile::MaxSectorSize);
 		}
 
 		rullFree = fsSize;
-		return false;
 	}
 
 	IFilesystem::EPathsRelation TFakeFilesystem::GetPathsRelation(const TSmartPath& pathFirst, const TSmartPath& pathSecond)
@@ -143,34 +147,29 @@
 		return spFind;
 	}
 
-	bool TFakeFilesystem::FastMove(const TSmartPath& pathSource, const TSmartPath& pathDestination)
+	void TFakeFilesystem::FastMove(const TSmartPath& pathSource, const TSmartPath& pathDestination)
 	{
 		TFakeFileDescriptionPtr spFileDesc = FindFileByLocation(pathSource);
 		if (!spFileDesc)
-			return false;
+			THROW_FILE_EXCEPTION(eErr_CannotFastMove, ERROR_FILE_INVALID, pathSource, L"Cannot fast move non-existent file");
 
 		// check parent of pathDestination
 		TSmartPath pathParent = pathDestination.GetParent();
 		if (pathParent.IsEmpty())
-			return false;
+			THROW_FILE_EXCEPTION(eErr_CannotFastMove, ERROR_FILE_INVALID, pathSource, L"Cannot get path of the parent");
 
 		TFakeFileDescriptionPtr spParentDesc = FindFileByLocation(pathParent);
 		if (!spParentDesc)
-			return false;
+			THROW_FILE_EXCEPTION(eErr_CannotFastMove, ERROR_FILE_INVALID, pathSource, L"Cannot get parent object");
 
 		spFileDesc->GetFileInfo().SetFilePath(pathDestination);
-		return true;
 	}
 
-	bool TFakeFilesystem::GetFileInfo(const TSmartPath& pathFile, TFileInfoPtr& rFileInfo, const TBasePathDataPtr& spBasePathData)
+	void 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;
-		}
+			THROW_FILE_EXCEPTION(eErr_CannotGetFileInfo, ERROR_FILE_INVALID, pathFile, L"Cannot get file info from non-existent file");
 
 		// copy data from W32_F_D
 		rFileInfo->Init(spBasePathData, pathFile, spFileDesc->GetFileInfo().GetAttributes(),
@@ -179,20 +178,18 @@
 			spFileDesc->GetFileInfo().GetLastAccessTime().GetAsFiletime(),
 			spFileDesc->GetFileInfo().GetLastWriteTime().GetAsFiletime(),
 			0);
-
-		return true;
 	}
 
-	bool TFakeFilesystem::DeleteFile(const TSmartPath& pathFile)
+	void TFakeFilesystem::DeleteFile(const TSmartPath& pathFile)
 	{
 		// check parent of pathDestination
 		TSmartPath pathParent = pathFile.GetParent();
 		if (pathParent.IsEmpty())
-			return false;
+			THROW_FILE_EXCEPTION(eErr_CannotDeleteFile, ERROR_FILE_INVALID, pathFile, L"Cannot get parent directory");
 
 		TFakeFileDescriptionPtr spParentDesc = FindFileByLocation(pathParent);
 		if (!spParentDesc)
-			return false;
+			THROW_FILE_EXCEPTION(eErr_CannotDeleteFile, ERROR_FILE_INVALID, pathFile, L"Cannot delete file from non-existent directory");
 
 		// similar to FindFileByLocation(), but operating on iterators
 		for (auto iterList = m_listFilesystemContent.begin(); iterList != m_listFilesystemContent.end(); ++iterList)
@@ -201,91 +198,87 @@
 			if (spDesc->GetFileInfo().GetFullFilePath() == pathFile)
 			{
 				if (spDesc->GetFileInfo().IsDirectory())
-					return false;
+					THROW_FILE_EXCEPTION(eErr_CannotRemoveDirectory, ERROR_FILE_INVALID, pathFile, L"Cannot remove directory by trying to delete a file");
 
 				m_listFilesystemContent.erase(iterList);
-				return true;
+				return;
 			}
 		}
 
-		return false;
+		THROW_FILE_EXCEPTION(eErr_CannotDeleteFile, ERROR_FILE_INVALID, pathFile, L"Cannot delete non-existent file");
 	}
 
-	bool TFakeFilesystem::RemoveDirectory(const TSmartPath& pathFile)
+	void TFakeFilesystem::RemoveDirectory(const TSmartPath& pathFile)
 	{
 		// check parent of pathDestination
 		TSmartPath pathParent = pathFile.GetParent();
 		if (pathParent.IsEmpty())
-			return false;
+			THROW_FILE_EXCEPTION(eErr_CannotRemoveDirectory, ERROR_FILE_INVALID, pathFile, L"Cannot get parent directory");
 
 		TFakeFileDescriptionPtr spParentDesc = FindFileByLocation(pathParent);
 		if (!spParentDesc)
-			return false;
+			THROW_FILE_EXCEPTION(eErr_CannotRemoveDirectory, ERROR_FILE_INVALID, pathFile, L"Cannot delete directory from non-existent parent");
 
 		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;
+					THROW_FILE_EXCEPTION(eErr_CannotDeleteFile, ERROR_FILE_INVALID, pathFile, L"Cannot remove file by trying to delete a directory");
 
 				m_listFilesystemContent.erase(iterList);
-				return true;
+				return;
 			}
 		}
 
-		return false;
+		THROW_FILE_EXCEPTION(eErr_CannotRemoveDirectory, ERROR_FILE_INVALID, pathFile, L"Cannot delete non-existent directory");
 	}
 
-	bool TFakeFilesystem::CreateDirectory(const TSmartPath& pathDirectory, bool bCreateFullPath)
+	void TFakeFilesystem::CreateDirectory(const TSmartPath& pathDirectory, bool bCreateFullPath)
 	{
 		// check parent of pathDestination
 		TFakeFileDescriptionPtr spDesc = FindFileByLocation(pathDirectory);
 		if (spDesc)
-			return true;
+			THROW_FILE_EXCEPTION(eErr_CannotCreateDirectory, ERROR_ALREADY_EXISTS, pathDirectory, L"Cannot create directory - it already exists");
 
 		if(!bCreateFullPath)
 		{
 			TSmartPath pathParent = pathDirectory.GetParent();
 			if (pathParent.IsEmpty())
-				return false;
+				THROW_FILE_EXCEPTION(eErr_CannotCreateDirectory, ERROR_FILE_INVALID, pathDirectory, L"Cannot retrieve parent");
 
 			TFakeFileDescriptionPtr spParentDesc = FindFileByLocation(pathParent);
 			if (!spParentDesc)
-				return false;
+				THROW_FILE_EXCEPTION(eErr_CannotCreateDirectory, ERROR_FILE_INVALID, pathDirectory, L"Cannot retrieve parent");
 
 			CreateFakeDirectory(pathDirectory);
 		}
 		else
 			CreateFSObjectByLocation(pathDirectory);
-
-		return true;
 	}
 
-	bool TFakeFilesystem::SetAttributes(const TSmartPath& pathFileDir, DWORD dwAttributes)
+	void TFakeFilesystem::SetAttributes(const TSmartPath& pathFileDir, DWORD dwAttributes)
 	{
 		TFakeFileDescriptionPtr spFileDesc = FindFileByLocation(pathFileDir);
 		if (!spFileDesc)
-			return false;
+			THROW_FILE_EXCEPTION(eErr_CannotSetFileAttributes, ERROR_FILE_INVALID, pathFileDir, L"Cannot locate file");
 
 		if (spFileDesc->GetFileInfo().IsDirectory() && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
-			return false;
+			THROW_FILE_EXCEPTION(eErr_CannotSetFileAttributes, ERROR_FILE_INVALID, pathFileDir, L"Cannot set invalid attribute");
 		if (!spFileDesc->GetFileInfo().IsDirectory() && (dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
-			return false;
+			THROW_FILE_EXCEPTION(eErr_CannotSetFileAttributes, ERROR_FILE_INVALID, pathFileDir, L"Cannot set invalid attribute");
 
 		spFileDesc->GetFileInfo().SetAttributes(dwAttributes);
-		return true;
 	}
 
-	bool TFakeFilesystem::SetFileDirectoryTime(const TSmartPath& pathFileDir, const TFileTime& ftCreationTime, const TFileTime& ftLastAccessTime, const TFileTime& ftLastWriteTime)
+	void TFakeFilesystem::SetFileDirectoryTime(const TSmartPath& pathFileDir, const TFileTime& ftCreationTime, const TFileTime& ftLastAccessTime, const TFileTime& ftLastWriteTime)
 	{
 		TFakeFileDescriptionPtr spFileDesc = FindFileByLocation(pathFileDir);
 		if (!spFileDesc)
-			return false;
+			THROW_FILE_EXCEPTION(eErr_CannotSetFileTimes, ERROR_FILE_INVALID, pathFileDir, L"Cannot locate file");
 
 		spFileDesc->GetFileInfo().SetFileTimes(ftCreationTime, ftLastAccessTime, ftLastWriteTime);
-		return true;
 	}
 
 	void TFakeFilesystem::SetVolumeInfo(wchar_t wchVolumeLetter, file_size_t fsSize, UINT uiDriveType, DWORD dwPhysicalDiskNumber)
Index: src/libchcore/TFakeFilesystem.h
===================================================================
diff -u -r479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc -rd468098a278a0d16c5b700236ea276b9c9677c9f
--- src/libchcore/TFakeFilesystem.h	(.../TFakeFilesystem.h)	(revision 479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc)
+++ src/libchcore/TFakeFilesystem.h	(.../TFakeFilesystem.h)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
@@ -34,17 +34,17 @@
 
 		// 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 void SetFileDirectoryTime(const TSmartPath& pathFileDir, const TFileTime& ftCreationTime, const TFileTime& ftLastAccessTime, const TFileTime& ftLastWriteTime) override;
+		virtual void SetAttributes(const TSmartPath& pathFileDir, DWORD dwAttributes) override;
+		virtual void CreateDirectory(const TSmartPath& pathDirectory, bool bCreateFullPath) override;
+		virtual void RemoveDirectory(const TSmartPath& pathFile) override;
+		virtual void DeleteFile(const TSmartPath& pathFile) override;
+		virtual void GetFileInfo(const TSmartPath& pathFile, TFileInfoPtr& rFileInfo, const TBasePathDataPtr& spBasePathData = TBasePathDataPtr()) override;
+		virtual void FastMove(const TSmartPath& pathSource, const TSmartPath& pathDestination) override;
 		virtual IFilesystemFindPtr CreateFinderObject(const TSmartPath& pathDir, const TSmartPath& pathMask) override;
 		virtual IFilesystemFilePtr CreateFileObject(const TSmartPath& spFilename, bool bNoBuffering) override;
 		virtual EPathsRelation GetPathsRelation(const TSmartPath& pathFirst, const TSmartPath& pathSecond) override;
-		virtual bool GetDynamicFreeSpace(const TSmartPath& path, unsigned long long& rullFree) override;
+		virtual void 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);
Index: src/libchcore/TLocalFilesystem.cpp
===================================================================
diff -u -r479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc -rd468098a278a0d16c5b700236ea276b9c9677c9f
--- src/libchcore/TLocalFilesystem.cpp	(.../TLocalFilesystem.cpp)	(revision 479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc)
+++ src/libchcore/TLocalFilesystem.cpp	(.../TLocalFilesystem.cpp)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
@@ -44,6 +44,7 @@
 #include "TLocalFilesystemFile.h"
 #include <memory>
 #include "TLocalFilesystemFind.h"
+#include "TFileException.h"
 
 namespace chcore
 {
@@ -103,29 +104,41 @@
 			return false;
 	}
 
-	bool TLocalFilesystem::SetFileDirectoryTime(const TSmartPath& pathFileDir, const TFileTime& ftCreationTime, const TFileTime& ftLastAccessTime, const TFileTime& ftLastWriteTime)
+	void TLocalFilesystem::SetFileDirectoryTime(const TSmartPath& pathFileDir, const TFileTime& ftCreationTime, const TFileTime& ftLastAccessTime, const TFileTime& ftLastWriteTime)
 	{
 		TAutoFileHandle hFile = CreateFile(PrependPathExtensionIfNeeded(pathFileDir).ToString(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL);
 		if (hFile == INVALID_HANDLE_VALUE)
-			return false;
+		{
+			DWORD dwLastError = GetLastError();
+			THROW_FILE_EXCEPTION(eErr_CannotOpenFile, dwLastError, pathFileDir, L"Cannot open file for setting file/directory times");
+		}
 
-		BOOL bResult = SetFileTime(hFile, &ftCreationTime.GetAsFiletime(), &ftLastAccessTime.GetAsFiletime(), &ftLastWriteTime.GetAsFiletime());
-
-		if (!hFile.Close())
-			return false;
-
-		return bResult != FALSE;
+		if (!SetFileTime(hFile, &ftCreationTime.GetAsFiletime(), &ftLastAccessTime.GetAsFiletime(), &ftLastWriteTime.GetAsFiletime()))
+		{
+			DWORD dwLastError = GetLastError();
+			THROW_FILE_EXCEPTION(eErr_CannotSetFileTimes, dwLastError, pathFileDir, L"Cannot set file/directory times");
+		}
 	}
 
-	bool TLocalFilesystem::SetAttributes(const TSmartPath& pathFileDir, DWORD dwAttributes)
+	void TLocalFilesystem::SetAttributes(const TSmartPath& pathFileDir, DWORD dwAttributes)
 	{
-		return ::SetFileAttributes(PrependPathExtensionIfNeeded(pathFileDir).ToString(), dwAttributes) != FALSE;
+		if (!::SetFileAttributes(PrependPathExtensionIfNeeded(pathFileDir).ToString(), dwAttributes))
+		{
+			DWORD dwLastError = GetLastError();
+			THROW_FILE_EXCEPTION(eErr_CannotSetFileAttributes, dwLastError, pathFileDir, L"Cannot set file/directory attributes");
+		}
 	}
 
-	bool TLocalFilesystem::CreateDirectory(const TSmartPath& pathDirectory, bool bCreateFullPath)
+	void TLocalFilesystem::CreateDirectory(const TSmartPath& pathDirectory, bool bCreateFullPath)
 	{
 		if (!bCreateFullPath)
-			return ::CreateDirectory(PrependPathExtensionIfNeeded(pathDirectory).ToString(), NULL) != FALSE;
+		{
+			if (!::CreateDirectory(PrependPathExtensionIfNeeded(pathDirectory).ToString(), NULL))
+			{
+				DWORD dwLastError = GetLastError();
+				THROW_FILE_EXCEPTION(eErr_CannotCreateDirectory, dwLastError, pathDirectory, L"Cannot create directory");
+			}
+		}
 		else
 		{
 			TPathContainer vComponents;
@@ -142,60 +155,72 @@
 				{
 					// try to create the specified path
 					BOOL bRes = ::CreateDirectory(PrependPathExtensionIfNeeded(pathToTest).ToString(), NULL);
-					if (!bRes && GetLastError() != ERROR_ALREADY_EXISTS)
-						return false;
+					if (!bRes)
+					{
+						DWORD dwLastError = GetLastError();
+						if (dwLastError != ERROR_ALREADY_EXISTS)
+							THROW_FILE_EXCEPTION(eErr_CannotCreateDirectory, dwLastError, pathToTest, L"Cannot create directory");
+					}
 				}
 			}
 		}
-
-		return true;
 	}
 
-	bool TLocalFilesystem::RemoveDirectory(const TSmartPath& pathFile)
+	void TLocalFilesystem::RemoveDirectory(const TSmartPath& pathDirectory)
 	{
-		return ::RemoveDirectory(PrependPathExtensionIfNeeded(pathFile).ToString()) != FALSE;
+		if (!::RemoveDirectory(PrependPathExtensionIfNeeded(pathDirectory).ToString()))
+		{
+			DWORD dwLastError = GetLastError();
+			THROW_FILE_EXCEPTION(eErr_CannotRemoveDirectory, dwLastError, pathDirectory, L"Cannot delete directory");
+		}
 	}
 
-	bool TLocalFilesystem::DeleteFile(const TSmartPath& pathFile)
+	void TLocalFilesystem::DeleteFile(const TSmartPath& pathFile)
 	{
-		return ::DeleteFile(PrependPathExtensionIfNeeded(pathFile).ToString()) != FALSE;
+		if (!::DeleteFile(PrependPathExtensionIfNeeded(pathFile).ToString()))
+		{
+			DWORD dwLastError = GetLastError();
+			THROW_FILE_EXCEPTION(eErr_CannotDeleteFile, dwLastError, pathFile, L"Cannot delete file");
+		}
 	}
 
-	bool TLocalFilesystem::GetFileInfo(const TSmartPath& pathFile, TFileInfoPtr& rFileInfo, const TBasePathDataPtr& spBasePathData)
+	void TLocalFilesystem::GetFileInfo(const TSmartPath& pathFile, TFileInfoPtr& spFileInfo, const TBasePathDataPtr& spBasePathData)
 	{
-		if (!rFileInfo)
+		if (!spFileInfo)
 			THROW_CORE_EXCEPTION(eErr_InvalidArgument);
 
 		WIN32_FIND_DATA wfd;
 		HANDLE hFind = FindFirstFile(PrependPathExtensionIfNeeded(pathFile).ToString(), &wfd);
-
 		if (hFind != INVALID_HANDLE_VALUE)
 		{
 			FindClose(hFind);
 
-			// new instance of path to accomodate the corrected path (i.e. input path might have lower case names, but we'd like to
-			// preserve the original case contained in the filesystem)
+			// new instance of path to accommodate the corrected path (i.e. input path might have lower case names, but we'd like to
+			// preserve the original case contained in the file system)
 			TSmartPath pathNew(pathFile);
 			pathNew.DeleteFileName();
 
 			// copy data from W32_F_D
-			rFileInfo->Init(spBasePathData, pathNew + PathFromString(wfd.cFileName),
+			spFileInfo->Init(spBasePathData, pathNew + PathFromString(wfd.cFileName),
 				wfd.dwFileAttributes, (((ULONGLONG)wfd.nFileSizeHigh) << 32) + wfd.nFileSizeLow, wfd.ftCreationTime,
 				wfd.ftLastAccessTime, wfd.ftLastWriteTime, 0);
-
-			return true;
 		}
 		else
 		{
-			FILETIME fi = { 0, 0 };
-			rFileInfo->Init(TSmartPath(), (DWORD)-1, 0, fi, fi, fi, 0);
-			return false;
+			DWORD dwLastError = GetLastError();
+			THROW_FILE_EXCEPTION(eErr_CannotGetFileInfo, dwLastError, pathFile, L"Cannot retrieve file information");
 		}
 	}
 
-	bool TLocalFilesystem::FastMove(const TSmartPath& pathSource, const TSmartPath& pathDestination)
+	void TLocalFilesystem::FastMove(const TSmartPath& pathSource, const TSmartPath& pathDestination)
 	{
-		return ::MoveFile(PrependPathExtensionIfNeeded(pathSource).ToString(), PrependPathExtensionIfNeeded(pathDestination).ToString()) != FALSE;
+		if (!::MoveFile(PrependPathExtensionIfNeeded(pathSource).ToString(), PrependPathExtensionIfNeeded(pathDestination).ToString()))
+		{
+			DWORD dwLastError = GetLastError();
+			// there is also the destination path that is important; tracking that would require adding a new exception class
+			// complicating the solution. For now it's not necessary to have that information in the exception.
+			THROW_FILE_EXCEPTION(eErr_CannotFastMove, dwLastError, pathSource, L"Cannot fast move file/directory");
+		}
 	}
 
 	IFilesystemFindPtr TLocalFilesystem::CreateFinderObject(const TSmartPath& pathDir, const TSmartPath& pathMask)
@@ -312,17 +337,17 @@
 		return pDiskExtent->DiskNumber;
 	}
 
-	bool TLocalFilesystem::GetDynamicFreeSpace(const TSmartPath& path, unsigned long long& rullFree)
+	void TLocalFilesystem::GetDynamicFreeSpace(const TSmartPath& path, unsigned long long& rullFree)
 	{
 		rullFree = 0;
 
 		ULARGE_INTEGER ui64Available, ui64Total;
 		if (GetDiskFreeSpaceEx(path.ToString(), &ui64Available, &ui64Total, NULL))
-		{
 			rullFree = ui64Available.QuadPart;
-			return true;
-		}
 		else
-			return false;
+		{
+			DWORD dwLastError = GetLastError();
+			THROW_FILE_EXCEPTION(eErr_CannotGetFreeSpace, dwLastError, path, L"Failed to retrieve free space information");
+		}
 	}
 }
Index: src/libchcore/TLocalFilesystem.h
===================================================================
diff -u -r479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc -rd468098a278a0d16c5b700236ea276b9c9677c9f
--- src/libchcore/TLocalFilesystem.h	(.../TLocalFilesystem.h)	(revision 479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc)
+++ src/libchcore/TLocalFilesystem.h	(.../TLocalFilesystem.h)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
@@ -46,22 +46,22 @@
 
 		virtual bool PathExist(const TSmartPath& strPath) override;	// check for file or folder existence
 
-		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 void SetFileDirectoryTime(const TSmartPath& pathFileDir, const TFileTime& ftCreationTime, const TFileTime& ftLastAccessTime, const TFileTime& ftLastWriteTime) override;
+		virtual void 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 void CreateDirectory(const TSmartPath& pathDirectory, bool bCreateFullPath) override;
+		virtual void RemoveDirectory(const TSmartPath& pathFile) override;
+		virtual void 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 void GetFileInfo(const TSmartPath& pathFile, TFileInfoPtr& rFileInfo, const TBasePathDataPtr& spBasePathData = TBasePathDataPtr()) override;
+		virtual void FastMove(const TSmartPath& pathSource, const TSmartPath& pathDestination) override;
 
 		virtual IFilesystemFindPtr CreateFinderObject(const TSmartPath& pathDir, const TSmartPath& pathMask) override;
 		virtual IFilesystemFilePtr CreateFileObject(const TSmartPath& pathFile, bool bNoBuffering) override;
 
 		virtual EPathsRelation GetPathsRelation(const TSmartPath& pathFirst, const TSmartPath& pathSecond) override;
 
-		virtual bool GetDynamicFreeSpace(const TSmartPath& path, unsigned long long& rullFree) override;
+		virtual void GetDynamicFreeSpace(const TSmartPath& path, unsigned long long& rullFree) override;
 
 	private:
 		static TSmartPath PrependPathExtensionIfNeeded(const TSmartPath& pathInput);
Index: src/libchcore/TLocalFilesystemFile.cpp
===================================================================
diff -u -r27a43e40952cf2f3e0bb0e608a8f3142042ceb46 -rd468098a278a0d16c5b700236ea276b9c9677c9f
--- src/libchcore/TLocalFilesystemFile.cpp	(.../TLocalFilesystemFile.cpp)	(revision 27a43e40952cf2f3e0bb0e608a8f3142042ceb46)
+++ src/libchcore/TLocalFilesystemFile.cpp	(.../TLocalFilesystemFile.cpp)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
@@ -169,6 +169,7 @@
 					rBuffer.SetLastPart(true);
 
 					rBuffer.RequeueAsFull();	// basically the same as OverlappedReadCompleted
+					break;
 				}
 
 			default:
@@ -246,5 +247,4 @@
 	{
 		return m_pathFile;
 	}
-
 }
Index: src/libchcore/TSubTaskCopyMove.cpp
===================================================================
diff -u -r27a43e40952cf2f3e0bb0e608a8f3142042ceb46 -rd468098a278a0d16c5b700236ea276b9c9677c9f
--- src/libchcore/TSubTaskCopyMove.cpp	(.../TSubTaskCopyMove.cpp)	(revision 27a43e40952cf2f3e0bb0e608a8f3142042ceb46)
+++ src/libchcore/TSubTaskCopyMove.cpp	(.../TSubTaskCopyMove.cpp)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
@@ -803,10 +803,8 @@
 				//       by using spDstFileInfo->Create() (which uses FindFirstFile()) or by
 				//       reading parameters using opened handle; need to be tested in the future
 				TFileInfoPtr spDstFileInfo(boost::make_shared<TFileInfo>());
+				spFilesystem->GetFileInfo(fileDst->GetFilePath(), spDstFileInfo);
 
-				if(!spFilesystem->GetFileInfo(fileDst->GetFilePath(), spDstFileInfo))
-					THROW_CORE_EXCEPTION_WIN32(eErr_CannotGetFileInfo, GetLastError());
-
 				// src and dst files are the same
 				EFeedbackResult frResult = spFeedbackHandler->FileAlreadyExists(spSrcFileInfo, spDstFileInfo);
 				switch(frResult)
@@ -1165,33 +1163,33 @@
 
 		bSkip = false;
 
-		// log
-		TString strFormat = _T("Error %errno while trying to write %count bytes to destination file %path (CustomCopyFileFB)");
-		strFormat.Replace(_t("%errno"), boost::lexical_cast<std::wstring>(rBuffer.GetErrorCode()).c_str());
-		strFormat.Replace(_t("%count"), boost::lexical_cast<std::wstring>(rBuffer.GetBytesTransferred()).c_str());
-		strFormat.Replace(_t("%path"), pathFile.ToString());
-		rLog.loge(strFormat.c_str());
+// log
+TString strFormat = _T("Error %errno while trying to write %count bytes to destination file %path (CustomCopyFileFB)");
+strFormat.Replace(_t("%errno"), boost::lexical_cast<std::wstring>(rBuffer.GetErrorCode()).c_str());
+strFormat.Replace(_t("%count"), boost::lexical_cast<std::wstring>(rBuffer.GetBytesTransferred()).c_str());
+strFormat.Replace(_t("%path"), pathFile.ToString());
+rLog.loge(strFormat.c_str());
 
-		EFeedbackResult frResult = spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eWriteError, dwLastError);
-		switch(frResult)
-		{
-		case EFeedbackResult::eResult_Cancel:
-			return TSubTaskBase::eSubResult_CancelRequest;
+EFeedbackResult frResult = spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eWriteError, dwLastError);
+switch (frResult)
+{
+case EFeedbackResult::eResult_Cancel:
+	return TSubTaskBase::eSubResult_CancelRequest;
 
-		case EFeedbackResult::eResult_Retry:
-			return TSubTaskBase::eSubResult_Retry;
+case EFeedbackResult::eResult_Retry:
+	return TSubTaskBase::eSubResult_Retry;
 
-		case EFeedbackResult::eResult_Pause:
-			return TSubTaskBase::eSubResult_PauseRequest;
+case EFeedbackResult::eResult_Pause:
+	return TSubTaskBase::eSubResult_PauseRequest;
 
-		case EFeedbackResult::eResult_Skip:
-			bSkip = true;
-			return TSubTaskBase::eSubResult_Continue;
+case EFeedbackResult::eResult_Skip:
+	bSkip = true;
+	return TSubTaskBase::eSubResult_Continue;
 
-		default:
-			BOOST_ASSERT(FALSE);		// unknown result
-			THROW_CORE_EXCEPTION(eErr_UnhandledCase);
-		}
+default:
+	BOOST_ASSERT(FALSE);		// unknown result
+	THROW_CORE_EXCEPTION(eErr_UnhandledCase);
+}
 	}
 
 	TSubTaskBase::ESubOperationResult TSubTaskCopyMove::FinalizeFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFile,
@@ -1244,8 +1242,7 @@
 				BOOST_ASSERT(FALSE);		// unknown result
 				THROW_CORE_EXCEPTION(eErr_UnhandledCase);
 			}
-		}
-		while (bRetry);
+		} while (bRetry);
 
 		return TSubTaskBase::eSubResult_Continue;
 	}
@@ -1255,10 +1252,25 @@
 		icpf::log_file& rLog = GetContext().GetLog();
 		IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem();
 
-		bool bRetry = true;
-		DWORD dwLastError = ERROR_SUCCESS;
-		while(bRetry && !spFilesystem->CreateDirectory(pathDirectory, false) && (dwLastError = GetLastError()) != ERROR_ALREADY_EXISTS)
+		bool bRetry = false;
+		do
 		{
+			bRetry = false;
+
+			DWORD dwLastError = ERROR_SUCCESS;
+			try
+			{
+				spFilesystem->CreateDirectory(pathDirectory, false);
+				return TSubTaskBase::eSubResult_Continue;
+			}
+			catch (const TFileException& e)
+			{
+				dwLastError = e.GetNativeError();
+			}
+
+			if (dwLastError == ERROR_ALREADY_EXISTS)
+				return TSubTaskBase::eSubResult_Continue;
+
 			// log
 			TString strFormat;
 			strFormat = _T("Error %errno while calling CreateDirectory %path (ProcessFiles)");
@@ -1273,21 +1285,21 @@
 				return TSubTaskBase::eSubResult_CancelRequest;
 
 			case EFeedbackResult::eResult_Retry:
-				bRetry = false;
+				bRetry = true;
 				break;
 
 			case EFeedbackResult::eResult_Pause:
 				return TSubTaskBase::eSubResult_PauseRequest;
 
 			case EFeedbackResult::eResult_Skip:
-				bRetry = false;
 				break;		// just do nothing
 
 			default:
 				BOOST_ASSERT(FALSE);		// unknown result
 				THROW_CORE_EXCEPTION(eErr_UnhandledCase);
 			}
 		}
+		while (bRetry);
 
 		return TSubTaskBase::eSubResult_Continue;
 	}
@@ -1313,9 +1325,50 @@
 			ullNeededSize = rFilesCache.CalculateTotalSize() - rFilesCache.CalculatePartialSize(m_tSubTaskStats.GetCurrentIndex());
 
 			// get free space
-			bool bResult = spFilesystem->GetDynamicFreeSpace(pathDestination, ullAvailableSize);
-			if(bResult && ullNeededSize > ullAvailableSize)
+			DWORD dwLastError = ERROR_SUCCESS;
+			bool bCheckFailed = false;
+			try
 			{
+				spFilesystem->GetDynamicFreeSpace(pathDestination, ullAvailableSize);
+			}
+			catch (const TFileException& e)
+			{
+				dwLastError = e.GetNativeError();
+				bCheckFailed = true;
+			}
+
+			if(bCheckFailed)
+			{
+				TString strFormat;
+				strFormat = _T("Error %errno while checking free space at %path");
+				strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
+				strFormat.Replace(_T("%path"), pathDestination.ToString());
+				rLog.loge(strFormat.c_str());
+
+				EFeedbackResult frResult = spFeedbackHandler->FileError(pathDestination.ToWString(), TString(), EFileError::eCheckForFreeSpace, dwLastError);
+				switch (frResult)
+				{
+				case EFeedbackResult::eResult_Cancel:
+					return TSubTaskBase::eSubResult_CancelRequest;
+
+				case EFeedbackResult::eResult_Retry:
+					bRetry = true;
+					continue;
+
+				case EFeedbackResult::eResult_Pause:
+					return TSubTaskBase::eSubResult_PauseRequest;
+
+				case EFeedbackResult::eResult_Skip:
+					return TSubTaskBase::eSubResult_Continue;
+
+				default:
+					BOOST_ASSERT(FALSE);		// unknown result
+					THROW_CORE_EXCEPTION(eErr_UnhandledCase);
+				}
+			}
+
+			if(ullNeededSize > ullAvailableSize)
+			{
 				TString strFormat = _T("Not enough free space on disk - needed %needsize bytes for data, available: %availablesize bytes.");
 				strFormat.Replace(_t("%needsize"), boost::lexical_cast<std::wstring>(ullNeededSize).c_str());
 				strFormat.Replace(_t("%availablesize"), boost::lexical_cast<std::wstring>(ullAvailableSize).c_str());
Index: src/libchcore/TSubTaskDelete.cpp
===================================================================
diff -u -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 -rd468098a278a0d16c5b700236ea276b9c9677c9f
--- src/libchcore/TSubTaskDelete.cpp	(.../TSubTaskDelete.cpp)	(revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3)
+++ src/libchcore/TSubTaskDelete.cpp	(.../TSubTaskDelete.cpp)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
@@ -38,6 +38,7 @@
 #include "TFeedbackHandlerWrapper.h"
 #include <boost/make_shared.hpp>
 #include "TBufferSizes.h"
+#include "TFileException.h"
 
 namespace chcore
 {
@@ -64,7 +65,6 @@
 		icpf::log_file& rLog = GetContext().GetLog();
 		TFileInfoArray& rFilesCache = GetContext().GetFilesCache();
 		TWorkerThreadController& rThreadController = GetContext().GetThreadController();
-		const TConfig& rConfig = GetContext().GetConfig();
 		IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem();
 
 		// log
@@ -79,7 +79,6 @@
 		m_tSubTaskStats.SetCurrentPath(TString());
 
 		// current processed path
-		BOOL bSuccess;
 		TFileInfoPtr spFileInfo;
 		TString strFormat;
 
@@ -110,63 +109,161 @@
 				continue;
 			}
 
+			ESubOperationResult eResult = TSubTaskBase::eSubResult_Continue;
 			// delete data
 			if (spFileInfo->IsDirectory())
+				eResult = RemoveDirectoryFB(spFeedbackHandler, spFileInfo);
+			else
+				eResult = DeleteFileFB(spFeedbackHandler, spFileInfo);
+
+			++fcIndex;
+		}
+
+		m_tSubTaskStats.SetCurrentIndex(fcIndex);
+		m_tSubTaskStats.SetProcessedCount(fcIndex);
+		m_tSubTaskStats.SetCurrentPath(TString());
+
+		// log
+		rLog.logi(_T("Deleting files finished"));
+
+		return TSubTaskBase::eSubResult_Continue;
+	}
+
+	TSubTaskBase::ESubOperationResult TSubTaskDelete::RemoveDirectoryFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TFileInfoPtr& spFileInfo)
+	{
+		const TConfig& rConfig = GetContext().GetConfig();
+		IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem();
+		icpf::log_file& rLog = GetContext().GetLog();
+
+		bool bRetry = false;
+		do
+		{
+			bRetry = false;
+
+			// #bug - changing read-only attribute should only be done when user explicitly requests it (via feedback response)
+			// for now it is ignored
+			try
 			{
 				if (!GetTaskPropValue<eTO_ProtectReadOnlyFiles>(rConfig))
 					spFilesystem->SetAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY);
-				bSuccess = spFilesystem->RemoveDirectory(spFileInfo->GetFullFilePath());
 			}
-			else
+			catch (const TFileException&)
 			{
-				// set files attributes to normal - it'd slow processing a bit, but it's better.
-				if (!GetTaskPropValue<eTO_ProtectReadOnlyFiles>(rConfig))
-					spFilesystem->SetAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL);
-				bSuccess = spFilesystem->DeleteFile(spFileInfo->GetFullFilePath());
 			}
 
-			// operation failed
-			DWORD dwLastError = GetLastError();
-			if (!bSuccess && dwLastError != ERROR_PATH_NOT_FOUND && dwLastError != ERROR_FILE_NOT_FOUND)
+			DWORD dwLastError = ERROR_SUCCESS;
+			try
 			{
-				// log
-				strFormat = _T("Error #%errno while deleting file/folder %path");
-				strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
-				strFormat.Replace(_T("%path"), spFileInfo->GetFullFilePath().ToString());
-				rLog.loge(strFormat.c_str());
+				spFilesystem->RemoveDirectory(spFileInfo->GetFullFilePath());
+				return TSubTaskBase::eSubResult_Continue;
+			}
+			catch (const TFileException& e)
+			{
+				dwLastError = e.GetNativeError();
+			}
 
-				EFeedbackResult frResult = spFeedbackHandler->FileError(spFileInfo->GetFullFilePath().ToWString(), TString(), EFileError::eDeleteError, dwLastError);
-				switch (frResult)
-				{
-				case EFeedbackResult::eResult_Cancel:
-					rLog.logi(_T("Cancel request while deleting file."));
-					return TSubTaskBase::eSubResult_CancelRequest;
+			if (dwLastError == ERROR_PATH_NOT_FOUND || dwLastError == ERROR_FILE_NOT_FOUND)
+				return TSubTaskBase::eSubResult_Continue;
 
-				case EFeedbackResult::eResult_Retry:
-					continue;	// no fcIndex bump, since we are trying again
+			// log
+			TString strFormat = _T("Error #%errno while deleting file/folder %path");
+			strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
+			strFormat.Replace(_T("%path"), spFileInfo->GetFullFilePath().ToString());
+			rLog.loge(strFormat.c_str());
 
-				case EFeedbackResult::eResult_Pause:
-					return TSubTaskBase::eSubResult_PauseRequest;
+			EFeedbackResult frResult = spFeedbackHandler->FileError(spFileInfo->GetFullFilePath().ToWString(), TString(), EFileError::eDeleteError, dwLastError);
+			switch (frResult)
+			{
+			case EFeedbackResult::eResult_Cancel:
+				rLog.logi(_T("Cancel request while deleting file."));
+				return TSubTaskBase::eSubResult_CancelRequest;
 
-				case EFeedbackResult::eResult_Skip:
-					break;		// just do nothing
+			case EFeedbackResult::eResult_Retry:
+				bRetry = true;
+				continue;	// no fcIndex bump, since we are trying again
 
-				default:
-					BOOST_ASSERT(FALSE);		// unknown result
-					THROW_CORE_EXCEPTION(eErr_UnhandledCase);
-				}
+			case EFeedbackResult::eResult_Pause:
+				return TSubTaskBase::eSubResult_PauseRequest;
+
+			case EFeedbackResult::eResult_Skip:
+				break;		// just do nothing
+
+			default:
+				BOOST_ASSERT(FALSE);		// unknown result
+				THROW_CORE_EXCEPTION(eErr_UnhandledCase);
 			}
+		}
+		while (bRetry);
 
-			++fcIndex;
-		}//while
+		return TSubTaskBase::eSubResult_Continue;
+	}
 
-		m_tSubTaskStats.SetCurrentIndex(fcIndex);
-		m_tSubTaskStats.SetProcessedCount(fcIndex);
-		m_tSubTaskStats.SetCurrentPath(TString());
+	TSubTaskBase::ESubOperationResult TSubTaskDelete::DeleteFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TFileInfoPtr& spFileInfo)
+	{
+		const TConfig& rConfig = GetContext().GetConfig();
+		IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem();
+		icpf::log_file& rLog = GetContext().GetLog();
 
-		// log
-		rLog.logi(_T("Deleting files finished"));
+		bool bRetry = false;
+		do
+		{
+			bRetry = false;
 
+			// #bug - changing read-only attribute should only be done when user explicitly requests it (via feedback response)
+			// for now it is ignored
+			try
+			{
+				if (!GetTaskPropValue<eTO_ProtectReadOnlyFiles>(rConfig))
+					spFilesystem->SetAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY);
+			}
+			catch (const TFileException&)
+			{
+			}
+
+			DWORD dwLastError = ERROR_SUCCESS;
+			try
+			{
+				spFilesystem->DeleteFile(spFileInfo->GetFullFilePath());
+				return TSubTaskBase::eSubResult_Continue;
+			}
+			catch (const TFileException& e)
+			{
+				dwLastError = e.GetNativeError();
+			}
+
+			if (dwLastError == ERROR_PATH_NOT_FOUND || dwLastError == ERROR_FILE_NOT_FOUND)
+				return TSubTaskBase::eSubResult_Continue;
+
+			// log
+			TString strFormat = _T("Error #%errno while deleting file/folder %path");
+			strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
+			strFormat.Replace(_T("%path"), spFileInfo->GetFullFilePath().ToString());
+			rLog.loge(strFormat.c_str());
+
+			EFeedbackResult frResult = spFeedbackHandler->FileError(spFileInfo->GetFullFilePath().ToWString(), TString(), EFileError::eDeleteError, dwLastError);
+			switch (frResult)
+			{
+			case EFeedbackResult::eResult_Cancel:
+				rLog.logi(_T("Cancel request while deleting file."));
+				return TSubTaskBase::eSubResult_CancelRequest;
+
+			case EFeedbackResult::eResult_Retry:
+				bRetry = true;
+				continue;	// no fcIndex bump, since we are trying again
+
+			case EFeedbackResult::eResult_Pause:
+				return TSubTaskBase::eSubResult_PauseRequest;
+
+			case EFeedbackResult::eResult_Skip:
+				break;		// just do nothing
+
+			default:
+				BOOST_ASSERT(FALSE);		// unknown result
+				THROW_CORE_EXCEPTION(eErr_UnhandledCase);
+			}
+		}
+		while (bRetry);
+
 		return TSubTaskBase::eSubResult_Continue;
 	}
 
Index: src/libchcore/TSubTaskDelete.h
===================================================================
diff -u -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 -rd468098a278a0d16c5b700236ea276b9c9677c9f
--- src/libchcore/TSubTaskDelete.h	(.../TSubTaskDelete.h)	(revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3)
+++ src/libchcore/TSubTaskDelete.h	(.../TSubTaskDelete.h)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
@@ -49,6 +49,10 @@
 		virtual void GetStatsSnapshot(TSubTaskStatsSnapshotPtr& spStats) const;
 
 	private:
+		TSubTaskBase::ESubOperationResult RemoveDirectoryFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TFileInfoPtr& spFileInfo);
+		TSubTaskBase::ESubOperationResult DeleteFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TFileInfoPtr& spFileInfo);
+
+	private:
 #pragma warning(push)
 #pragma warning(disable: 4251)
 		TSubTaskStatsInfo m_tSubTaskStats;
Index: src/libchcore/TSubTaskFastMove.cpp
===================================================================
diff -u -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 -rd468098a278a0d16c5b700236ea276b9c9677c9f
--- src/libchcore/TSubTaskFastMove.cpp	(.../TSubTaskFastMove.cpp)	(revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3)
+++ src/libchcore/TSubTaskFastMove.cpp	(.../TSubTaskFastMove.cpp)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
@@ -39,6 +39,7 @@
 #include "TScopedRunningTimeTracker.h"
 #include "TFeedbackHandlerWrapper.h"
 #include "TBufferSizes.h"
+#include "TFileException.h"
 
 namespace chcore
 {
@@ -91,8 +92,6 @@
 
 		// add everything
 		TString strFormat;
-		bool bRetry = true;
-		bool bSkipInputPath = false;
 
 		file_count_t fcSize = spBasePaths->GetCount();
 		file_count_t fcIndex = m_tSubTaskStats.GetCurrentIndex();
@@ -114,42 +113,12 @@
 				continue;
 
 			TFileInfoPtr spFileInfo(boost::make_shared<TFileInfo>());
-			bSkipInputPath = false;
-			// try to get some info about the input path; let user know if the path does not exist.
-			do
-			{
-				bRetry = false;
 
-				// read attributes of src file/folder
-				bool bExists = spFilesystem->GetFileInfo(pathCurrent, spFileInfo, spBasePath);
-				if (!bExists)
-				{
-					EFeedbackResult frResult = spFeedbackHandler->FileError(pathCurrent.ToWString(), TString(), EFileError::eFastMoveError, ERROR_FILE_NOT_FOUND);
-					switch (frResult)
-					{
-					case EFeedbackResult::eResult_Cancel:
-						return eSubResult_CancelRequest;
-
-					case EFeedbackResult::eResult_Retry:
-						bRetry = true;
-						break;
-
-					case EFeedbackResult::eResult_Pause:
-						return eSubResult_PauseRequest;
-
-					case EFeedbackResult::eResult_Skip:
-						bSkipInputPath = true;
-						break;		// just do nothing
-
-					default:
-						BOOST_ASSERT(FALSE);		// unknown result
-						THROW_CORE_EXCEPTION(eErr_UnhandledCase);
-					}
-				}
-			} while (bRetry);
-
-			// if we have chosen to skip the input path then there's nothing to do
-			if (bSkipInputPath)
+			bool bSkip = false;
+			ESubOperationResult eResult = GetFileInfoFB(spFeedbackHandler, pathCurrent, spFileInfo, spBasePath, bSkip);
+			if (eResult != TSubTaskBase::eSubResult_Continue)
+				return eResult;
+			else if (bSkip)
 				continue;
 
 			// does it match the input filter?
@@ -160,64 +129,17 @@
 			}
 
 			// try to fast move
-			bRetry = true;
-			bool bResult = true;
-			do
-			{
-				TSmartPath pathDestinationPath = CalculateDestinationPath(spFileInfo, pathDestination, 0);
-				TSmartPath pathSrc = spBasePath->GetSrcPath();
-				bResult = spFilesystem->FastMove(pathSrc, pathDestinationPath);
-				if (!bResult)
-				{
-					DWORD dwLastError = GetLastError();
+			eResult = FastMoveFB(spFeedbackHandler, spFileInfo, pathDestination, spBasePath, bSkip);
+			if (eResult != TSubTaskBase::eSubResult_Continue)
+				return eResult;
+			//else if (bSkip)
+			//	continue;
 
-					// check if this is one of the errors, that will just cause fast move to skip
-					if (dwLastError == ERROR_ACCESS_DENIED || dwLastError == ERROR_ALREADY_EXISTS)
-					{
-						bRetry = false;
-						bResult = true;
-					}
-					else
-					{
-						//log
-						strFormat = _T("Error %errno while calling fast move %srcpath -> %dstpath (TSubTaskFastMove)");
-						strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
-						strFormat.Replace(_T("%srcpath"), spFileInfo->GetFullFilePath().ToString());
-						strFormat.Replace(_T("%dstpath"), pathDestination.ToString());
-						rLog.loge(strFormat.c_str());
-
-						EFeedbackResult frResult = spFeedbackHandler->FileError(pathSrc.ToWString(), pathDestinationPath.ToWString(), EFileError::eFastMoveError, dwLastError);
-						switch (frResult)
-						{
-						case EFeedbackResult::eResult_Cancel:
-							return TSubTaskBase::eSubResult_CancelRequest;
-
-						case EFeedbackResult::eResult_Retry:
-							continue;
-
-						case EFeedbackResult::eResult_Pause:
-							return TSubTaskBase::eSubResult_PauseRequest;
-
-						case EFeedbackResult::eResult_Skip:
-							//bSkipInputPath = true;		// not needed, since we will break the loop anyway and there is no other processing for this path either
-							bRetry = false;
-							break;		// just do nothing
-
-						default:
-							BOOST_ASSERT(FALSE);		// unknown result
-							THROW_CORE_EXCEPTION(eErr_UnhandledCase);
-						}
-					}
-				}
-				else
-					spBasePath->SetSkipFurtherProcessing(true);		// mark that this path should not be processed any further
-			} while (!bResult && bRetry);
-
 			// check for kill need
 			if (rThreadController.KillRequested())
 			{
 				// log
-				rLog.logi(_T("Kill request while adding data to files array (RecurseDirectories)"));
+				rLog.logi(_T("Kill request while fast moving items"));
 				return eSubResult_KillRequest;
 			}
 		}
@@ -232,6 +154,124 @@
 		return eSubResult_Continue;
 	}
 
+	TSubTaskBase::ESubOperationResult TSubTaskFastMove::FastMoveFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TFileInfoPtr& spFileInfo, const TSmartPath& pathDestination,
+		const TBasePathDataPtr& spBasePath, bool& bSkip)
+	{
+		IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem();
+		icpf::log_file& rLog = GetContext().GetLog();
+
+		bool bRetry = false;
+		do
+		{
+			bRetry = false;
+
+			TSmartPath pathDestinationPath = CalculateDestinationPath(spFileInfo, pathDestination, 0);
+			TSmartPath pathSrc = spBasePath->GetSrcPath();
+
+			DWORD dwLastError = ERROR_SUCCESS;
+			try
+			{
+				spFilesystem->FastMove(pathSrc, pathDestinationPath);
+				spBasePath->SetSkipFurtherProcessing(true);		// mark that this path should not be processed any further
+				return eSubResult_Continue;
+			}
+			catch (const TFileException& e)
+			{
+				dwLastError = e.GetNativeError();
+			}
+
+			// check if this is one of the errors, that will just cause fast move to skip
+			if (dwLastError == ERROR_ACCESS_DENIED || dwLastError == ERROR_ALREADY_EXISTS)
+			{
+				bSkip = true;
+				break;
+			}
+			else
+			{
+				//log
+				TString strFormat = _T("Error %errno while calling fast move %srcpath -> %dstpath (TSubTaskFastMove)");
+				strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
+				strFormat.Replace(_T("%srcpath"), spFileInfo->GetFullFilePath().ToString());
+				strFormat.Replace(_T("%dstpath"), pathDestination.ToString());
+				rLog.loge(strFormat.c_str());
+
+				EFeedbackResult frResult = spFeedbackHandler->FileError(pathSrc.ToWString(), pathDestinationPath.ToWString(), EFileError::eFastMoveError, 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;
+					break;		// just do nothing
+
+				default:
+					BOOST_ASSERT(FALSE);		// unknown result
+					THROW_CORE_EXCEPTION(eErr_UnhandledCase);
+				}
+			}
+		}
+		while (bRetry);
+
+		return eSubResult_Continue;
+	}
+
+	TSubTaskBase::ESubOperationResult TSubTaskFastMove::GetFileInfoFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TSmartPath& pathCurrent,
+		TFileInfoPtr& spFileInfo, const TBasePathDataPtr& spBasePath, bool& bSkip)
+	{
+		const IFilesystemPtr& spFilesystem = GetContext().GetLocalFilesystem();
+
+		bool bRetry = false;
+		do
+		{
+			bRetry = false;
+
+			// read attributes of src file/folder
+			DWORD dwLastError = ERROR_SUCCESS;
+			try
+			{
+				spFilesystem->GetFileInfo(pathCurrent, spFileInfo, spBasePath);
+				return eSubResult_Continue;
+			}
+			catch (const TFileException& e)
+			{
+				dwLastError = e.GetNativeError();
+			}
+
+			EFeedbackResult frResult = spFeedbackHandler->FileError(pathCurrent.ToWString(), TString(), EFileError::eFastMoveError, dwLastError);
+			switch (frResult)
+			{
+			case EFeedbackResult::eResult_Cancel:
+				return eSubResult_CancelRequest;
+
+			case EFeedbackResult::eResult_Retry:
+				bRetry = true;
+				break;
+
+			case EFeedbackResult::eResult_Pause:
+				return eSubResult_PauseRequest;
+
+			case EFeedbackResult::eResult_Skip:
+				bSkip = true;
+				break;		// just do nothing
+
+			default:
+				BOOST_ASSERT(FALSE);		// unknown result
+				THROW_CORE_EXCEPTION(eErr_UnhandledCase);
+			}
+		}
+		while (bRetry);
+
+		return eSubResult_Continue;
+	}
+
 	void TSubTaskFastMove::GetStatsSnapshot(TSubTaskStatsSnapshotPtr& spStats) const
 	{
 		m_tSubTaskStats.GetSnapshot(spStats);
Index: src/libchcore/TSubTaskFastMove.h
===================================================================
diff -u -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 -rd468098a278a0d16c5b700236ea276b9c9677c9f
--- src/libchcore/TSubTaskFastMove.h	(.../TSubTaskFastMove.h)	(revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3)
+++ src/libchcore/TSubTaskFastMove.h	(.../TSubTaskFastMove.h)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
@@ -55,6 +55,8 @@
 
 	private:
 		int ScanDirectory(TSmartPath pathDirName, size_t stSrcIndex, bool bRecurse, bool bIncludeDirs, TFileFiltersArray& afFilters);
+		TSubTaskBase::ESubOperationResult GetFileInfoFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TSmartPath& pathCurrent, TFileInfoPtr& spFileInfo, const TBasePathDataPtr& spBasePath, bool& bSkip);
+		TSubTaskBase::ESubOperationResult FastMoveFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TFileInfoPtr& spFileInfo, const TSmartPath& pathDestination, const TBasePathDataPtr& spBasePath, bool& bSkip);
 
 	private:
 #pragma warning(push)
Index: src/libchcore/TSubTaskScanDirectory.cpp
===================================================================
diff -u -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 -rd468098a278a0d16c5b700236ea276b9c9677c9f
--- src/libchcore/TSubTaskScanDirectory.cpp	(.../TSubTaskScanDirectory.cpp)	(revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3)
+++ src/libchcore/TSubTaskScanDirectory.cpp	(.../TSubTaskScanDirectory.cpp)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
@@ -38,6 +38,7 @@
 #include "TScopedRunningTimeTracker.h"
 #include "TFeedbackHandlerWrapper.h"
 #include "TBufferSizes.h"
+#include "TFileException.h"
 
 namespace chcore
 {
@@ -70,7 +71,6 @@
 		TBasePathDataContainerPtr spBasePaths = GetContext().GetBasePaths();
 		const TConfig& rConfig = GetContext().GetConfig();
 		const TFileFiltersArray& rafFilters = GetContext().GetFilters();
-		const IFilesystemPtr& spFilesystem = GetContext().GetLocalFilesystem();
 
 		rLog.logi(_T("Searching for files..."));
 
@@ -93,8 +93,6 @@
 
 		// add everything
 		TString strFormat;
-		bool bRetry = true;
-		bool bSkipInputPath = false;
 
 		file_count_t fcSize = spBasePaths->GetCount();
 		// NOTE: in theory, we should resume the scanning, but in practice we are always restarting scanning if interrupted.
@@ -110,50 +108,18 @@
 			m_tSubTaskStats.SetProcessedCount(fcIndex);
 			m_tSubTaskStats.SetCurrentPath(pathCurrent.ToString());
 
-			bSkipInputPath = false;
 			TFileInfoPtr spFileInfo(boost::make_shared<TFileInfo>());
 
 			// check if we want to process this path at all (might be already fast moved)
 			if (spBasePath->GetSkipFurtherProcessing())
 				continue;
 
 			// try to get some info about the input path; let user know if the path does not exist.
-			do
-			{
-				bRetry = false;
-
-				// read attributes of src file/folder
-				bool bExists = spFilesystem->GetFileInfo(pathCurrent, spFileInfo, spBasePath);
-				if (!bExists)
-				{
-					EFeedbackResult frResult = spFeedbackHandler->FileError(pathCurrent.ToWString(), TString(), EFileError::eFastMoveError, ERROR_FILE_NOT_FOUND);
-					switch (frResult)
-					{
-					case EFeedbackResult::eResult_Cancel:
-						rFilesCache.Clear();
-						return eSubResult_CancelRequest;
-
-					case EFeedbackResult::eResult_Retry:
-						bRetry = true;
-						break;
-
-					case EFeedbackResult::eResult_Pause:
-						rFilesCache.Clear();
-						return eSubResult_PauseRequest;
-
-					case EFeedbackResult::eResult_Skip:
-						bSkipInputPath = true;
-						break;		// just do nothing
-
-					default:
-						BOOST_ASSERT(FALSE);		// unknown result
-						THROW_CORE_EXCEPTION(eErr_UnhandledCase);
-					}
-				}
-			} while (bRetry);
-
-			// if we have chosen to skip the input path then there's nothing to do
-			if (bSkipInputPath)
+			bool bSkip = false;
+			ESubOperationResult eResult = GetFileInfoFB(spFeedbackHandler, pathCurrent, spFileInfo, spBasePath, bSkip);
+			if (eResult != TSubTaskBase::eSubResult_Continue)
+				return eResult;
+			else if (bSkip)
 				continue;
 
 			// log
@@ -219,6 +185,57 @@
 		return eSubResult_Continue;
 	}
 
+	TSubTaskBase::ESubOperationResult TSubTaskScanDirectories::GetFileInfoFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TSmartPath& pathCurrent, TFileInfoPtr& spFileInfo, const TBasePathDataPtr& spBasePath, bool& bSkip)
+	{
+		TFileInfoArray& rFilesCache = GetContext().GetFilesCache();
+		const IFilesystemPtr& spFilesystem = GetContext().GetLocalFilesystem();
+
+		bool bRetry = false;
+		do
+		{
+			bRetry = false;
+
+			// read attributes of src file/folder
+			DWORD dwLastError = ERROR_SUCCESS;
+			try
+			{
+				spFilesystem->GetFileInfo(pathCurrent, spFileInfo, spBasePath);
+				return eSubResult_Continue;
+			}
+			catch (const TFileException& e)
+			{
+				dwLastError = e.GetNativeError();
+			}
+
+			EFeedbackResult frResult = spFeedbackHandler->FileError(pathCurrent.ToWString(), TString(), EFileError::eFastMoveError, dwLastError);
+			switch (frResult)
+			{
+			case EFeedbackResult::eResult_Cancel:
+				rFilesCache.Clear();
+				return eSubResult_CancelRequest;
+
+			case EFeedbackResult::eResult_Retry:
+				bRetry = true;
+				break;
+
+			case EFeedbackResult::eResult_Pause:
+				rFilesCache.Clear();
+				return eSubResult_PauseRequest;
+
+			case EFeedbackResult::eResult_Skip:
+				bSkip = true;
+				break;		// just do nothing
+
+			default:
+				BOOST_ASSERT(FALSE);		// unknown result
+				THROW_CORE_EXCEPTION(eErr_UnhandledCase);
+			}
+		}
+		while (bRetry);
+
+		return eSubResult_Continue;
+	}
+
 	void TSubTaskScanDirectories::GetStatsSnapshot(TSubTaskStatsSnapshotPtr& spStats) const
 	{
 		m_tSubTaskStats.GetSnapshot(spStats);
Index: src/libchcore/TSubTaskScanDirectory.h
===================================================================
diff -u -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 -rd468098a278a0d16c5b700236ea276b9c9677c9f
--- src/libchcore/TSubTaskScanDirectory.h	(.../TSubTaskScanDirectory.h)	(revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3)
+++ src/libchcore/TSubTaskScanDirectory.h	(.../TSubTaskScanDirectory.h)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
@@ -56,6 +56,8 @@
 		int ScanDirectory(TSmartPath pathDirName, const TBasePathDataPtr& spBasePathData,
 			bool bRecurse, bool bIncludeDirs, const TFileFiltersArray& afFilters);
 
+		ESubOperationResult GetFileInfoFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TSmartPath& pathCurrent, TFileInfoPtr& spFileInfo, const TBasePathDataPtr& spBasePath, bool& bSkip);
+
 	private:
 #pragma warning(push)
 #pragma warning(disable: 4251)