Index: src/libchcore/TOverlappedReaderFB.cpp
===================================================================
diff -u -ra1f5b3d99f2f175b102d81379698ea1f08e42cce -r8aa9ecb7ccb06d721b9717a4bb664651b0b8b10e
--- src/libchcore/TOverlappedReaderFB.cpp	(.../TOverlappedReaderFB.cpp)	(revision a1f5b3d99f2f175b102d81379698ea1f08e42cce)
+++ src/libchcore/TOverlappedReaderFB.cpp	(.../TOverlappedReaderFB.cpp)	(revision 8aa9ecb7ccb06d721b9717a4bb664651b0b8b10e)
@@ -19,6 +19,7 @@
 #include "stdafx.h"
 #include "TOverlappedReaderFB.h"
 #include "TCoreException.h"
+#include "TFileInfo.h"
 
 namespace chcore
 {
@@ -43,6 +44,29 @@
 	{
 	}
 
+	TSubTaskBase::ESubOperationResult TOverlappedReaderFB::Start()
+	{
+		// update the source file size (it might differ from the time this file was originally scanned).
+		// NOTE: this kind of update could be also done when copying chunks of data beyond the original end-of-file,
+		//       but it would require frequent total size updates and thus - serializations).
+		// NOTE2: the by-chunk corrections of stats are still applied when copying to ensure even further size
+		//        matching; this update however still allows for better serialization management.
+		file_size_t fsOldSize = m_spSrcFileInfo->GetLength64();
+		file_size_t fsNewSize = 0;
+
+		TSubTaskBase::ESubOperationResult eResult = m_spSrcFile->GetFileSize(fsNewSize);
+		if(eResult != TSubTaskBase::eSubResult_Continue)
+			return eResult;
+
+		if(fsNewSize != fsOldSize)
+		{
+			m_spStats->AdjustTotalSize(fsOldSize, fsNewSize);
+			m_spSrcFileInfo->SetLength64(fsNewSize);
+		}
+
+		return eResult;
+	}
+
 	void TOverlappedReaderFB::SetReleaseMode()
 	{
 		m_spReader->ReleaseBuffers();
Index: src/libchcore/TOverlappedReaderFB.h
===================================================================
diff -u -rc0d9a798f9fbbeda239b84721ed864f9727e1ddc -r8aa9ecb7ccb06d721b9717a4bb664651b0b8b10e
--- src/libchcore/TOverlappedReaderFB.h	(.../TOverlappedReaderFB.h)	(revision c0d9a798f9fbbeda239b84721ed864f9727e1ddc)
+++ src/libchcore/TOverlappedReaderFB.h	(.../TOverlappedReaderFB.h)	(revision 8aa9ecb7ccb06d721b9717a4bb664651b0b8b10e)
@@ -35,6 +35,8 @@
 			unsigned long long ullFilePos, DWORD dwChunkSize);
 		~TOverlappedReaderFB();
 
+		TSubTaskBase::ESubOperationResult Start();
+
 		TOverlappedReaderPtr GetReader() const { return m_spReader; }
 		void SetReleaseMode();
 
Index: src/libchcore/TOverlappedReaderWriterFB.cpp
===================================================================
diff -u -ra1f5b3d99f2f175b102d81379698ea1f08e42cce -r8aa9ecb7ccb06d721b9717a4bb664651b0b8b10e
--- src/libchcore/TOverlappedReaderWriterFB.cpp	(.../TOverlappedReaderWriterFB.cpp)	(revision a1f5b3d99f2f175b102d81379698ea1f08e42cce)
+++ src/libchcore/TOverlappedReaderWriterFB.cpp	(.../TOverlappedReaderWriterFB.cpp)	(revision 8aa9ecb7ccb06d721b9717a4bb664651b0b8b10e)
@@ -104,8 +104,16 @@
 		return eResult;
 	}
 
-	TSubTaskBase::ESubOperationResult TOverlappedReaderWriterFB::Start(HANDLE hKill)
+	TSubTaskBase::ESubOperationResult TOverlappedReaderWriterFB::Start(HANDLE hKill, bool bCreateOnly)
 	{
+		TSubTaskBase::ESubOperationResult eResult = m_spReader->Start();
+		if(eResult != TSubTaskBase::eSubResult_Continue)
+			return eResult;
+
+		eResult = m_spWriter->Start(bCreateOnly);
+		if(eResult != TSubTaskBase::eSubResult_Continue)
+			return eResult;
+
 		// read data from file to buffer
 		// NOTE: order is critical here:
 		// - write finished is first, so that all the data that were already queued to be written, will be written and accounted for (in stats)
@@ -127,7 +135,6 @@
 			m_spReader->GetReader()->GetEventReadPossibleHandle()
 		};
 
-		TSubTaskBase::ESubOperationResult eResult = TSubTaskBase::eSubResult_Continue;
 		bool bStopProcessing = false;
 		while(!bStopProcessing && eResult == TSubTaskBase::eSubResult_Continue)
 		{
Index: src/libchcore/TOverlappedReaderWriterFB.h
===================================================================
diff -u -rc0d9a798f9fbbeda239b84721ed864f9727e1ddc -r8aa9ecb7ccb06d721b9717a4bb664651b0b8b10e
--- src/libchcore/TOverlappedReaderWriterFB.h	(.../TOverlappedReaderWriterFB.h)	(revision c0d9a798f9fbbeda239b84721ed864f9727e1ddc)
+++ src/libchcore/TOverlappedReaderWriterFB.h	(.../TOverlappedReaderWriterFB.h)	(revision 8aa9ecb7ccb06d721b9717a4bb664651b0b8b10e)
@@ -40,7 +40,7 @@
 
 		TOverlappedReaderWriterFB& operator=(const TOverlappedReaderWriterFB&) = delete;
 
-		TSubTaskBase::ESubOperationResult Start(HANDLE hKill);
+		TSubTaskBase::ESubOperationResult Start(HANDLE hKill, bool bCreateOnly);
 
 		// reader/writer
 		TOverlappedReaderFBPtr GetReader() const { return m_spReader; }
Index: src/libchcore/TOverlappedWriterFB.cpp
===================================================================
diff -u -ra1f5b3d99f2f175b102d81379698ea1f08e42cce -r8aa9ecb7ccb06d721b9717a4bb664651b0b8b10e
--- src/libchcore/TOverlappedWriterFB.cpp	(.../TOverlappedWriterFB.cpp)	(revision a1f5b3d99f2f175b102d81379698ea1f08e42cce)
+++ src/libchcore/TOverlappedWriterFB.cpp	(.../TOverlappedWriterFB.cpp)	(revision 8aa9ecb7ccb06d721b9717a4bb664651b0b8b10e)
@@ -199,4 +199,87 @@
 
 		return eResult;
 	}
+
+	TSubTaskBase::ESubOperationResult TOverlappedWriterFB::Start(bool bOnlyCreate)
+	{
+		// open destination file, handle the failures and possibly existence of the destination file
+		unsigned long long ullProcessedSize = m_spStats->GetCurrentItemProcessedSize();
+		unsigned long long ullSeekTo = ullProcessedSize;
+
+		bool bDstFileFreshlyCreated = false;
+		TSubTaskBase::ESubOperationResult eResult = m_spDstFile->IsFreshlyCreated(bDstFileFreshlyCreated);
+		if(eResult != TSubTaskBase::eSubResult_Continue)
+			return eResult;
+
+		file_size_t fsDstFileSize = 0;
+		eResult = m_spDstFile->GetFileSize(fsDstFileSize);
+		if(eResult != TSubTaskBase::eSubResult_Continue)
+			return eResult;
+
+		// try to resume if possible
+		bool bCanSilentResume = false;
+		if(m_spStats->CanCurrentItemSilentResume())
+		{
+			if(fsDstFileSize == ullProcessedSize && fsDstFileSize <= m_spSrcFileInfo->GetLength64())
+			{
+				ullSeekTo = fsDstFileSize;
+				bCanSilentResume = true;
+			}
+		}
+
+		if(!bCanSilentResume && !bDstFileFreshlyCreated && fsDstFileSize > 0)
+		{
+			bool bShouldAppend = false;
+			eResult = m_spDstFile->HandleFileAlreadyExistsFB(m_spSrcFileInfo, bShouldAppend);
+			if(eResult != TSubTaskBase::eSubResult_Continue)
+				return eResult;
+
+			if(bShouldAppend)
+				ullSeekTo = std::min(fsDstFileSize, m_spSrcFileInfo->GetLength64());
+			else
+				ullSeekTo = 0;
+		}
+
+		if(bOnlyCreate)
+		{
+			// we don't copy contents, but need to increase processed size
+			m_spStats->AdjustProcessedSize(m_spStats->GetCurrentItemProcessedSize(), m_spSrcFileInfo->GetLength64());
+
+			return TSubTaskBase::eSubResult_Continue;
+		}
+
+		// ullSeekTo contains the seek position in destination file; in case the destination is already
+		// larger than source file all we can do is to perform truncation of destination file to the size of
+		// source file.
+		// NOTE: the truncation that will be the result of the following assignment might cause the end of destination file
+		// to be overwritten by the end of source file.
+		ullSeekTo = std::min(ullSeekTo, m_spSrcFileInfo->GetLength64());
+
+		// seek to the position where copying will start
+		file_size_t fsMoveTo = m_spDstFile->GetSeekPositionForResume(ullSeekTo);
+
+		// sanity check
+		if(bDstFileFreshlyCreated && ullSeekTo != 0)
+			throw TCoreException(eErr_InternalProblem, L"Destination file was freshly created, but seek position is not 0", LOCATION);
+		if(fsMoveTo > ullSeekTo)
+			throw TCoreException(eErr_InternalProblem, L"File position to move to is placed after the end of file", LOCATION);
+
+		// adjust the stats for the difference between what was already processed and what will now be considered processed
+		m_spStats->AdjustProcessedSize(ullProcessedSize, fsMoveTo);
+
+		// if the destination file already exists - truncate it to the current file position
+		if(!bDstFileFreshlyCreated)
+		{
+			// if destination file was opened (as opposed to newly created)
+			eResult = m_spDstFile->TruncateFileFB(fsMoveTo);
+			if(eResult != TSubTaskBase::eSubResult_Continue)
+				return eResult;
+		}
+
+		// at this point user already decided that he want to write data into destination file;
+		// so if we're to resume copying after this point, we don't have to ask user for overwriting existing file
+		m_spStats->SetCurrentItemSilentResume(true);
+
+		return eResult;
+	}
 }
Index: src/libchcore/TOverlappedWriterFB.h
===================================================================
diff -u -ra1f5b3d99f2f175b102d81379698ea1f08e42cce -r8aa9ecb7ccb06d721b9717a4bb664651b0b8b10e
--- src/libchcore/TOverlappedWriterFB.h	(.../TOverlappedWriterFB.h)	(revision a1f5b3d99f2f175b102d81379698ea1f08e42cce)
+++ src/libchcore/TOverlappedWriterFB.h	(.../TOverlappedWriterFB.h)	(revision 8aa9ecb7ccb06d721b9717a4bb664651b0b8b10e)
@@ -33,6 +33,8 @@
 			unsigned long long ullFilePos, const TBufferListPtr& spEmptyBuffers);
 		~TOverlappedWriterFB();
 
+		TSubTaskBase::ESubOperationResult Start(bool bOnlyCreate);
+
 		TOverlappedWriterPtr GetWriter() const { return m_spWriter; }
 
 		void SetReleaseMode() { m_bReleaseMode = true; }
Index: src/libchcore/TSubTaskCopyMove.cpp
===================================================================
diff -u -ra1f5b3d99f2f175b102d81379698ea1f08e42cce -r8aa9ecb7ccb06d721b9717a4bb664651b0b8b10e
--- src/libchcore/TSubTaskCopyMove.cpp	(.../TSubTaskCopyMove.cpp)	(revision a1f5b3d99f2f175b102d81379698ea1f08e42cce)
+++ src/libchcore/TSubTaskCopyMove.cpp	(.../TSubTaskCopyMove.cpp)	(revision 8aa9ecb7ccb06d721b9717a4bb664651b0b8b10e)
@@ -358,15 +358,9 @@
 		TFilesystemFileFeedbackWrapperPtr spSrcFileWrapper(std::make_shared<TFilesystemFileFeedbackWrapper>(fileSrc, spFeedbackHandler, GetContext().GetLogFileData(), rThreadController, spFilesystem));
 		TFilesystemFileFeedbackWrapperPtr spDstFileWrapper(std::make_shared<TFilesystemFileFeedbackWrapper>(fileDst, spFeedbackHandler, GetContext().GetLogFileData(), rThreadController, spFilesystem));
 
-		TSubTaskBase::ESubOperationResult eResult = OpenSrcAndDstFilesFB(*spSrcFileWrapper, *spDstFileWrapper, pData);
-		if(eResult != TSubTaskBase::eSubResult_Continue)
-			return eResult;
-
 		// recreate buffer if needed
 		AdjustBufferIfNeeded(pData->spMemoryPool, pData->tBufferSizes);
 
-		//ATLTRACE(_T("CustomCopyFile: %s\n"), pData->spSrcFile->GetFullFilePath().ToString());
-
 		// establish count of data to read
 		TBufferSizes::EBufferType eBufferIndex = GetBufferIndex(pData->tBufferSizes, pData->spSrcFile);
 		m_spSubTaskStats->SetCurrentBufferIndex(eBufferIndex);
@@ -381,7 +375,7 @@
 		TOverlappedReaderWriterFB tReaderWriter(spSrcFileWrapper, pData->spSrcFile, spDstFileWrapper, m_spSubTaskStats, m_spLog->GetLogFileData(),
 			pData->spMemoryPool, ullNextReadPos, dwCurrentBufferSize);
 
-		eResult = tReaderWriter.Start(rThreadController.GetKillThreadHandle());
+		ESubOperationResult eResult = tReaderWriter.Start(rThreadController.GetKillThreadHandle(), pData->bOnlyCreate);
 
 		return eResult;
 	}
@@ -391,110 +385,6 @@
 		m_spSubTaskStats->AdjustProcessedSize(m_spSubTaskStats->GetCurrentItemProcessedSize(), spSrcFileInfo->GetLength64());
 	}
 
-	TSubTaskCopyMove::ESubOperationResult TSubTaskCopyMove::OpenSrcAndDstFilesFB(TFilesystemFileFeedbackWrapper& rSrcFile, TFilesystemFileFeedbackWrapper& rDstFile,
-		CUSTOM_COPY_PARAMS* pData)
-	{
-		IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem();
-
-		// update the source file size (it might differ from the time this file was originally scanned).
-		// NOTE: this kind of update could be also done when copying chunks of data beyond the original end-of-file,
-		//       but it would require frequent total size updates and thus - serializations).
-		// NOTE2: the by-chunk corrections of stats are still applied when copying to ensure even further size
-		//        matching; this update however still allows for better serialization management.
-		file_size_t fsOldSize = pData->spSrcFile->GetLength64();
-		file_size_t fsNewSize = 0;
-		
-		ESubOperationResult eResult = rSrcFile.GetFileSize(fsNewSize);
-		if(eResult != eSubResult_Continue)
-			return eResult;
-
-		if(fsNewSize != fsOldSize)
-		{
-			m_spSubTaskStats->AdjustTotalSize(fsOldSize, fsNewSize);
-			pData->spSrcFile->SetLength64(fsNewSize);
-		}
-
-		// open destination file, handle the failures and possibly existence of the destination file
-		unsigned long long ullProcessedSize = m_spSubTaskStats->GetCurrentItemProcessedSize();
-		unsigned long long ullSeekTo = ullProcessedSize;
-
-		bool bDstFileFreshlyCreated = false;
-		eResult = rDstFile.IsFreshlyCreated(bDstFileFreshlyCreated);
-		if(eResult != eSubResult_Continue)
-			return eResult;
-
-		file_size_t fsDstFileSize = 0;
-		eResult = rDstFile.GetFileSize(fsDstFileSize);
-		if(eResult != eSubResult_Continue)
-			return eResult;
-
-		// try to resume if possible
-		bool bCanSilentResume = false;
-		if (m_spSubTaskStats->CanCurrentItemSilentResume())
-		{
-			if(fsDstFileSize == ullProcessedSize && fsDstFileSize <= fsNewSize)
-			{
-				ullSeekTo = fsDstFileSize;
-				bCanSilentResume = true;
-			}
-		}
-
-		if(!bCanSilentResume && !bDstFileFreshlyCreated && fsDstFileSize > 0)
-		{
-			bool bShouldAppend = false;
-			eResult = rDstFile.HandleFileAlreadyExistsFB(pData->spSrcFile, bShouldAppend);
-			if(eResult != eSubResult_Continue)
-				return eResult;
-
-			if(bShouldAppend)
-				ullSeekTo = std::min(fsDstFileSize, fsNewSize);
-			else
-				ullSeekTo = 0;
-		}
-
-		if(pData->bOnlyCreate)
-		{
-			// we don't copy contents, but need to increase processed size
-			AdjustProcessedSizeForSkip(pData->spSrcFile);
-
-			return eSubResult_Continue;
-		}
-
-		// ullSeekTo contains the seek position in destination file; in case the destination is already
-		// larger than source file all we can do is to perform truncation of destination file to the size of
-		// source file.
-		// NOTE: the truncation that will be the result of the following assignment might cause the end of destination file
-		// to be overwritten by the end of source file.
-		ullSeekTo = std::min(ullSeekTo, fsNewSize);
-
-		// seek to the position where copying will start
-		file_size_t fsMoveTo = rDstFile.GetSeekPositionForResume(ullSeekTo);
-
-		// sanity check
-		if (bDstFileFreshlyCreated && ullSeekTo != 0)
-			throw TCoreException(eErr_InternalProblem, L"Destination file was freshly created, but seek position is not 0", LOCATION);
-		if(fsMoveTo > ullSeekTo)
-			throw TCoreException(eErr_InternalProblem, L"File position to move to is placed after the end of file", LOCATION);
-
-		// adjust the stats for the difference between what was already processed and what will now be considered processed
-		m_spSubTaskStats->AdjustProcessedSize(ullProcessedSize, fsMoveTo);
-
-		// if the destination file already exists - truncate it to the current file position
-		if(!bDstFileFreshlyCreated)
-		{
-			// if destination file was opened (as opposed to newly created)
-			eResult = rDstFile.TruncateFileFB(fsMoveTo);
-			if(eResult != TSubTaskBase::eSubResult_Continue)
-				return eResult;
-		}
-
-		// at this point user already decided that he want to write data into destination file;
-		// so if we're to resume copying after this point, we don't have to ask user for overwriting existing file
-		m_spSubTaskStats->SetCurrentItemSilentResume(true);
-
-		return eResult;
-	}
-
 	bool TSubTaskCopyMove::AdjustBufferIfNeeded(const TOverlappedMemoryPoolPtr& spBuffer, TBufferSizes& rBufferSizes, bool bForce)
 	{
 		const TConfig& rConfig = GetContext().GetConfig();
Index: src/libchcore/TSubTaskCopyMove.h
===================================================================
diff -u -rc0d9a798f9fbbeda239b84721ed864f9727e1ddc -r8aa9ecb7ccb06d721b9717a4bb664651b0b8b10e
--- src/libchcore/TSubTaskCopyMove.h	(.../TSubTaskCopyMove.h)	(revision c0d9a798f9fbbeda239b84721ed864f9727e1ddc)
+++ src/libchcore/TSubTaskCopyMove.h	(.../TSubTaskCopyMove.h)	(revision 8aa9ecb7ccb06d721b9717a4bb664651b0b8b10e)
@@ -26,7 +26,6 @@
 #include "libchcore.h"
 #include "TSubTaskBase.h"
 #include "TBufferSizes.h"
-#include "IFilesystemFile.h"
 #include "../liblogger/TLogger.h"
 #include "TOverlappedMemoryPool.h"
 
@@ -64,9 +63,6 @@
 
 		ESubOperationResult CustomCopyFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, CUSTOM_COPY_PARAMS* pData);
 
-		ESubOperationResult OpenSrcAndDstFilesFB(TFilesystemFileFeedbackWrapper& rSrcFile, TFilesystemFileFeedbackWrapper& rDstFile,
-			CUSTOM_COPY_PARAMS* pData);
-
 		void AdjustProcessedSizeForSkip(const TFileInfoPtr& spSrcFileInfo);
 
 	private: