Index: src/libchcore/TFilesystemFeedbackWrapper.cpp
===================================================================
diff -u -r09d769045d1d5c45d8df16d209c754b872348c26 -r25722a1d39e5d4bb49c5a60cbee3dda6c02cb193
--- src/libchcore/TFilesystemFeedbackWrapper.cpp	(.../TFilesystemFeedbackWrapper.cpp)	(revision 09d769045d1d5c45d8df16d209c754b872348c26)
+++ src/libchcore/TFilesystemFeedbackWrapper.cpp	(.../TFilesystemFeedbackWrapper.cpp)	(revision 25722a1d39e5d4bb49c5a60cbee3dda6c02cb193)
@@ -23,15 +23,16 @@
 
 namespace chcore
 {
-	TFilesystemFeedbackWrapper::TFilesystemFeedbackWrapper(const IFilesystemPtr& spFilesystem, icpf::log_file& rLog) :
+	TFilesystemFeedbackWrapper::TFilesystemFeedbackWrapper(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemPtr& spFilesystem, icpf::log_file& rLog) :
+		m_spFeedbackHandler(spFeedbackHandler),
 		m_spFilesystem(spFilesystem),
 		m_rLog(rLog)
 	{
 		if (!spFilesystem)
 			THROW_CORE_EXCEPTION_MSG(eErr_InvalidArgument, L"Filesystem not provided");
 	}
 
-	TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::CreateDirectoryFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TSmartPath& pathDirectory)
+	TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::CreateDirectoryFB(const TSmartPath& pathDirectory)
 	{
 		bool bRetry = false;
 		do
@@ -59,7 +60,7 @@
 			strFormat.Replace(_T("%path"), pathDirectory.ToString());
 			m_rLog.loge(strFormat.c_str());
 
-			EFeedbackResult frResult = spFeedbackHandler->FileError(pathDirectory.ToWString(), TString(), EFileError::eCreateError, dwLastError);
+			EFeedbackResult frResult = m_spFeedbackHandler->FileError(pathDirectory.ToWString(), TString(), EFileError::eCreateError, dwLastError);
 			switch (frResult)
 			{
 			case EFeedbackResult::eResult_Cancel:
@@ -85,7 +86,7 @@
 		return TSubTaskBase::eSubResult_Continue;
 	}
 
-	TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::CheckForFreeSpaceFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TSmartPath& pathFirstSrc, const TSmartPath& pathDestination, unsigned long long ullNeededSize)
+	TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::CheckForFreeSpaceFB(const TSmartPath& pathFirstSrc, const TSmartPath& pathDestination, unsigned long long ullNeededSize)
 	{
 		unsigned long long ullAvailableSize = 0;
 		bool bRetry = false;
@@ -117,7 +118,7 @@
 				strFormat.Replace(_T("%path"), pathDestination.ToString());
 				m_rLog.loge(strFormat.c_str());
 
-				EFeedbackResult frResult = spFeedbackHandler->FileError(pathDestination.ToWString(), TString(), EFileError::eCheckForFreeSpace, dwLastError);
+				EFeedbackResult frResult = m_spFeedbackHandler->FileError(pathDestination.ToWString(), TString(), EFileError::eCheckForFreeSpace, dwLastError);
 				switch (frResult)
 				{
 				case EFeedbackResult::eResult_Cancel:
@@ -146,7 +147,7 @@
 				strFormat.Replace(_t("%availablesize"), boost::lexical_cast<std::wstring>(ullAvailableSize).c_str());
 				m_rLog.logw(strFormat.c_str());
 
-				EFeedbackResult frResult = spFeedbackHandler->NotEnoughSpace(pathFirstSrc.ToWString(), pathDestination.ToWString(), ullNeededSize);
+				EFeedbackResult frResult = m_spFeedbackHandler->NotEnoughSpace(pathFirstSrc.ToWString(), pathDestination.ToWString(), ullNeededSize);
 				switch (frResult)
 				{
 				case EFeedbackResult::eResult_Cancel:
@@ -172,4 +173,240 @@
 		return TSubTaskBase::eSubResult_Continue;
 	}
 
+	TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::RemoveDirectoryFB(const TFileInfoPtr& spFileInfo, bool bProtectReadOnlyFiles)
+	{
+		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 (!bProtectReadOnlyFiles)
+					m_spFilesystem->SetAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY);
+			}
+			catch (const TFileException&)
+			{
+			}
+
+			DWORD dwLastError = ERROR_SUCCESS;
+			try
+			{
+				m_spFilesystem->RemoveDirectory(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());
+			m_rLog.loge(strFormat.c_str());
+
+			EFeedbackResult frResult = m_spFeedbackHandler->FileError(spFileInfo->GetFullFilePath().ToWString(), TString(), EFileError::eDeleteError, dwLastError);
+			switch (frResult)
+			{
+			case EFeedbackResult::eResult_Cancel:
+				m_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;
+	}
+
+	TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::DeleteFileFB(const TFileInfoPtr& spFileInfo, bool bProtectReadOnlyFiles)
+	{
+		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 (!bProtectReadOnlyFiles)
+					m_spFilesystem->SetAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY);
+			}
+			catch (const TFileException&)
+			{
+			}
+
+			DWORD dwLastError = ERROR_SUCCESS;
+			try
+			{
+				m_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());
+			m_rLog.loge(strFormat.c_str());
+
+			EFeedbackResult frResult = m_spFeedbackHandler->FileError(spFileInfo->GetFullFilePath().ToWString(), TString(), EFileError::eDeleteError, dwLastError);
+			switch (frResult)
+			{
+			case EFeedbackResult::eResult_Cancel:
+				m_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;
+	}
+
+	TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::FastMoveFB(const TFileInfoPtr& spFileInfo, const TSmartPath& pathDestination, const TBasePathDataPtr& spBasePath, bool& bSkip)
+	{
+		bool bRetry = false;
+		do
+		{
+			bRetry = false;
+
+			TSmartPath pathSrc = spBasePath->GetSrcPath();
+
+			DWORD dwLastError = ERROR_SUCCESS;
+			try
+			{
+				m_spFilesystem->FastMove(pathSrc, pathDestination);
+				spBasePath->SetSkipFurtherProcessing(true);		// mark that this path should not be processed any further
+				return TSubTaskBase::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 || dwLastError == ERROR_NOT_SAME_DEVICE)
+			{
+				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());
+				m_rLog.loge(strFormat.c_str());
+
+				EFeedbackResult frResult = m_spFeedbackHandler->FileError(pathSrc.ToWString(), pathDestination.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 TSubTaskBase::eSubResult_Continue;
+	}
+
+	TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::GetFileInfoFB(const TSmartPath& pathCurrent, TFileInfoPtr& spFileInfo, const TBasePathDataPtr& spBasePath, bool& bSkip)
+	{
+		bool bRetry = false;
+		do
+		{
+			bRetry = false;
+
+			// read attributes of src file/folder
+			DWORD dwLastError = ERROR_SUCCESS;
+			try
+			{
+				m_spFilesystem->GetFileInfo(pathCurrent, spFileInfo, spBasePath);
+				return TSubTaskBase::eSubResult_Continue;
+			}
+			catch (const TFileException& e)
+			{
+				dwLastError = e.GetNativeError();
+			}
+
+			EFeedbackResult frResult = m_spFeedbackHandler->FileError(pathCurrent.ToWString(), TString(), 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 TSubTaskBase::eSubResult_Continue;
+	}
+
 }
Index: src/libchcore/TFilesystemFeedbackWrapper.h
===================================================================
diff -u -r09d769045d1d5c45d8df16d209c754b872348c26 -r25722a1d39e5d4bb49c5a60cbee3dda6c02cb193
--- src/libchcore/TFilesystemFeedbackWrapper.h	(.../TFilesystemFeedbackWrapper.h)	(revision 09d769045d1d5c45d8df16d209c754b872348c26)
+++ src/libchcore/TFilesystemFeedbackWrapper.h	(.../TFilesystemFeedbackWrapper.h)	(revision 25722a1d39e5d4bb49c5a60cbee3dda6c02cb193)
@@ -29,12 +29,22 @@
 	class TFilesystemFeedbackWrapper
 	{
 	public:
-		TFilesystemFeedbackWrapper(const IFilesystemPtr& spFilesystem, icpf::log_file& rLog);
+		TFilesystemFeedbackWrapper(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemPtr& spFilesystem, icpf::log_file& rLog);
 
-		TSubTaskBase::ESubOperationResult CreateDirectoryFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TSmartPath& pathDirectory);
-		TSubTaskBase::ESubOperationResult CheckForFreeSpaceFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TSmartPath& pathFirstSrc, const TSmartPath& pathDestination, unsigned long long ullNeededSize);
+		TSubTaskBase::ESubOperationResult CreateDirectoryFB(const TSmartPath& pathDirectory);
+		TSubTaskBase::ESubOperationResult CheckForFreeSpaceFB(const TSmartPath& pathFirstSrc, const TSmartPath& pathDestination, unsigned long long ullNeededSize);
 
+		TSubTaskBase::ESubOperationResult RemoveDirectoryFB(const TFileInfoPtr& spFileInfo, bool bProtectReadOnlyFiles);
+		TSubTaskBase::ESubOperationResult DeleteFileFB(const TFileInfoPtr& spFileInfo, bool bProtectReadOnlyFiles);
+
+		TSubTaskBase::ESubOperationResult FastMoveFB(const TFileInfoPtr& spFileInfo, const TSmartPath& pathDestination,
+			const TBasePathDataPtr& spBasePath, bool& bSkip);
+
+		TSubTaskBase::ESubOperationResult GetFileInfoFB(const TSmartPath& pathCurrent,
+			TFileInfoPtr& spFileInfo, const TBasePathDataPtr& spBasePath, bool& bSkip);
+
 	private:
+		IFeedbackHandlerPtr m_spFeedbackHandler;
 		IFilesystemPtr m_spFilesystem;
 		icpf::log_file& m_rLog;
 	};
Index: src/libchcore/TSubTaskCopyMove.cpp
===================================================================
diff -u -r6eefe6212611518e13af7771d406612c0a7a2bed -r25722a1d39e5d4bb49c5a60cbee3dda6c02cb193
--- src/libchcore/TSubTaskCopyMove.cpp	(.../TSubTaskCopyMove.cpp)	(revision 6eefe6212611518e13af7771d406612c0a7a2bed)
+++ src/libchcore/TSubTaskCopyMove.cpp	(.../TSubTaskCopyMove.cpp)	(revision 25722a1d39e5d4bb49c5a60cbee3dda6c02cb193)
@@ -91,7 +91,7 @@
 		IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem();
 		TBasePathDataContainerPtr spSrcPaths = GetContext().GetBasePaths();
 
-		TFilesystemFeedbackWrapper tFilesystemFBWrapper(spFilesystem, rLog);
+		TFilesystemFeedbackWrapper tFilesystemFBWrapper(spFeedbackHandler, spFilesystem, rLog);
 
 		// log
 		rLog.logi(_T("Processing files/folders (ProcessFiles)"));
@@ -110,7 +110,7 @@
 		// now it's time to check if there is enough space on destination device
 		unsigned long long ullNeededSize = rFilesCache.CalculateTotalSize() - rFilesCache.CalculatePartialSize(m_tSubTaskStats.GetCurrentIndex());
 		TSmartPath pathSingleSrc = spSrcPaths->GetAt(0)->GetSrcPath();
-		TSubTaskBase::ESubOperationResult eResult = tFilesystemFBWrapper.CheckForFreeSpaceFB(spFeedbackHandler, pathSingleSrc, pathDestination, ullNeededSize);
+		TSubTaskBase::ESubOperationResult eResult = tFilesystemFBWrapper.CheckForFreeSpaceFB(pathSingleSrc, pathDestination, ullNeededSize);
 		if(eResult != TSubTaskBase::eSubResult_Continue)
 			return eResult;
 
@@ -176,7 +176,7 @@
 			// if folder - create it
 			if(spFileInfo->IsDirectory())
 			{
-				eResult = tFilesystemFBWrapper.CreateDirectoryFB(spFeedbackHandler, ccp.pathDstFile);
+				eResult = tFilesystemFBWrapper.CreateDirectoryFB(ccp.pathDstFile);
 				if(eResult != TSubTaskBase::eSubResult_Continue)
 					return eResult;
 
Index: src/libchcore/TSubTaskDelete.cpp
===================================================================
diff -u -rd468098a278a0d16c5b700236ea276b9c9677c9f -r25722a1d39e5d4bb49c5a60cbee3dda6c02cb193
--- src/libchcore/TSubTaskDelete.cpp	(.../TSubTaskDelete.cpp)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
+++ src/libchcore/TSubTaskDelete.cpp	(.../TSubTaskDelete.cpp)	(revision 25722a1d39e5d4bb49c5a60cbee3dda6c02cb193)
@@ -39,6 +39,7 @@
 #include <boost/make_shared.hpp>
 #include "TBufferSizes.h"
 #include "TFileException.h"
+#include "TFilesystemFeedbackWrapper.h"
 
 namespace chcore
 {
@@ -67,6 +68,8 @@
 		TWorkerThreadController& rThreadController = GetContext().GetThreadController();
 		IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem();
 
+		TFilesystemFeedbackWrapper tFilesystemFBWrapper(spFeedbackHandler, spFilesystem, rLog);
+
 		// log
 		rLog.logi(_T("Deleting files (DeleteFiles)..."));
 
@@ -111,10 +114,11 @@
 
 			ESubOperationResult eResult = TSubTaskBase::eSubResult_Continue;
 			// delete data
+			bool bProtectReadOnlyFiles = GetTaskPropValue<eTO_ProtectReadOnlyFiles>(GetContext().GetConfig());
 			if (spFileInfo->IsDirectory())
-				eResult = RemoveDirectoryFB(spFeedbackHandler, spFileInfo);
+				eResult = tFilesystemFBWrapper.RemoveDirectoryFB(spFileInfo, bProtectReadOnlyFiles);
 			else
-				eResult = DeleteFileFB(spFeedbackHandler, spFileInfo);
+				eResult = tFilesystemFBWrapper.DeleteFileFB(spFileInfo, bProtectReadOnlyFiles);
 
 			++fcIndex;
 		}
@@ -129,144 +133,6 @@
 		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);
-			}
-			catch (const TFileException&)
-			{
-			}
-
-			DWORD dwLastError = ERROR_SUCCESS;
-			try
-			{
-				spFilesystem->RemoveDirectory(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;
-	}
-
-	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();
-
-		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;
-	}
-
 	void TSubTaskDelete::GetStatsSnapshot(TSubTaskStatsSnapshotPtr& spStats) const
 	{
 		m_tSubTaskStats.GetSnapshot(spStats);
Index: src/libchcore/TSubTaskDelete.h
===================================================================
diff -u -rd468098a278a0d16c5b700236ea276b9c9677c9f -r25722a1d39e5d4bb49c5a60cbee3dda6c02cb193
--- src/libchcore/TSubTaskDelete.h	(.../TSubTaskDelete.h)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
+++ src/libchcore/TSubTaskDelete.h	(.../TSubTaskDelete.h)	(revision 25722a1d39e5d4bb49c5a60cbee3dda6c02cb193)
@@ -49,10 +49,6 @@
 		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 -rcde3645c5041aedd6703b81b6fed42134c615917 -r25722a1d39e5d4bb49c5a60cbee3dda6c02cb193
--- src/libchcore/TSubTaskFastMove.cpp	(.../TSubTaskFastMove.cpp)	(revision cde3645c5041aedd6703b81b6fed42134c615917)
+++ src/libchcore/TSubTaskFastMove.cpp	(.../TSubTaskFastMove.cpp)	(revision 25722a1d39e5d4bb49c5a60cbee3dda6c02cb193)
@@ -40,6 +40,7 @@
 #include "TFeedbackHandlerWrapper.h"
 #include "TBufferSizes.h"
 #include "TFileException.h"
+#include "TFilesystemFeedbackWrapper.h"
 
 namespace chcore
 {
@@ -72,6 +73,8 @@
 		const TFileFiltersArray& rafFilters = GetContext().GetFilters();
 		IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem();
 
+		TFilesystemFeedbackWrapper tFilesystemFBWrapper(spFeedbackHandler, spFilesystem, rLog);
+
 		rLog.logi(_T("Performing initial fast-move operation..."));
 
 		// new stats
@@ -115,7 +118,7 @@
 			TFileInfoPtr spFileInfo(boost::make_shared<TFileInfo>());
 
 			bool bSkip = false;
-			ESubOperationResult eResult = GetFileInfoFB(spFeedbackHandler, pathCurrent, spFileInfo, spBasePath, bSkip);
+			ESubOperationResult eResult = tFilesystemFBWrapper.GetFileInfoFB(pathCurrent, spFileInfo, spBasePath, bSkip);
 			if (eResult != TSubTaskBase::eSubResult_Continue)
 				return eResult;
 			else if (bSkip)
@@ -129,7 +132,7 @@
 			}
 
 			// try to fast move
-			eResult = FastMoveFB(spFeedbackHandler, spFileInfo, pathDestination, spBasePath, bSkip);
+			eResult = tFilesystemFBWrapper.FastMoveFB(spFileInfo, CalculateDestinationPath(spFileInfo, pathDestination, 0), spBasePath, bSkip);
 			if (eResult != TSubTaskBase::eSubResult_Continue)
 				return eResult;
 			//else if (bSkip)
@@ -154,124 +157,6 @@
 		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 || dwLastError == ERROR_NOT_SAME_DEVICE)
-			{
-				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 -rd468098a278a0d16c5b700236ea276b9c9677c9f -r25722a1d39e5d4bb49c5a60cbee3dda6c02cb193
--- src/libchcore/TSubTaskFastMove.h	(.../TSubTaskFastMove.h)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
+++ src/libchcore/TSubTaskFastMove.h	(.../TSubTaskFastMove.h)	(revision 25722a1d39e5d4bb49c5a60cbee3dda6c02cb193)
@@ -55,8 +55,6 @@
 
 	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 -rd468098a278a0d16c5b700236ea276b9c9677c9f -r25722a1d39e5d4bb49c5a60cbee3dda6c02cb193
--- src/libchcore/TSubTaskScanDirectory.cpp	(.../TSubTaskScanDirectory.cpp)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
+++ src/libchcore/TSubTaskScanDirectory.cpp	(.../TSubTaskScanDirectory.cpp)	(revision 25722a1d39e5d4bb49c5a60cbee3dda6c02cb193)
@@ -39,6 +39,7 @@
 #include "TFeedbackHandlerWrapper.h"
 #include "TBufferSizes.h"
 #include "TFileException.h"
+#include "TFilesystemFeedbackWrapper.h"
 
 namespace chcore
 {
@@ -71,7 +72,10 @@
 		TBasePathDataContainerPtr spBasePaths = GetContext().GetBasePaths();
 		const TConfig& rConfig = GetContext().GetConfig();
 		const TFileFiltersArray& rafFilters = GetContext().GetFilters();
+		IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem();
 
+		TFilesystemFeedbackWrapper tFilesystemFBWrapper(spFeedbackHandler, spFilesystem, rLog);
+
 		rLog.logi(_T("Searching for files..."));
 
 		// reset progress
@@ -116,7 +120,7 @@
 
 			// try to get some info about the input path; let user know if the path does not exist.
 			bool bSkip = false;
-			ESubOperationResult eResult = GetFileInfoFB(spFeedbackHandler, pathCurrent, spFileInfo, spBasePath, bSkip);
+			ESubOperationResult eResult = tFilesystemFBWrapper.GetFileInfoFB(pathCurrent, spFileInfo, spBasePath, bSkip);
 			if (eResult != TSubTaskBase::eSubResult_Continue)
 				return eResult;
 			else if (bSkip)
@@ -185,57 +189,6 @@
 		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 -rd468098a278a0d16c5b700236ea276b9c9677c9f -r25722a1d39e5d4bb49c5a60cbee3dda6c02cb193
--- src/libchcore/TSubTaskScanDirectory.h	(.../TSubTaskScanDirectory.h)	(revision d468098a278a0d16c5b700236ea276b9c9677c9f)
+++ src/libchcore/TSubTaskScanDirectory.h	(.../TSubTaskScanDirectory.h)	(revision 25722a1d39e5d4bb49c5a60cbee3dda6c02cb193)
@@ -56,8 +56,6 @@
 		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)