Index: /trunk/src/VBox/Main/include/GuestSessionImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/GuestSessionImpl.h	(revision 72000)
+++ /trunk/src/VBox/Main/include/GuestSessionImpl.h	(revision 72001)
@@ -27,4 +27,5 @@
 #include "GuestFileImpl.h"
 #include "GuestFsObjInfoImpl.h"
+#include "GuestSessionImplTasks.h"
 
 #include <deque>
@@ -261,4 +262,8 @@
      * @todo r=bird: Most of these are public for no real reason...
      * @{ */
+    HRESULT                 i_copyFromGuest(const GuestSessionFsSourceSet &SourceSet, const com::Utf8Str &strDestination,
+                                            ComPtr<IProgress> &pProgress);
+    HRESULT                 i_copyToGuest(const GuestSessionFsSourceSet &SourceSet, const com::Utf8Str &strDestination,
+                                          ComPtr<IProgress> &pProgress);
     int                     i_closeSession(uint32_t uFlags, uint32_t uTimeoutMS, int *pGuestRc);
     inline bool             i_directoryExists(uint32_t uDirID, ComObjPtr<GuestDirectory> *pDir);
Index: /trunk/src/VBox/Main/include/GuestSessionImplTasks.h
===================================================================
--- /trunk/src/VBox/Main/include/GuestSessionImplTasks.h	(revision 72000)
+++ /trunk/src/VBox/Main/include/GuestSessionImplTasks.h	(revision 72001)
@@ -35,16 +35,4 @@
 class GuestSessionTaskInternalOpen;
 
-/**
- * Enumeration which specifies the file system source type.
- */
-enum GuestSessionFsSourceType
-{
-    /** Invalid / uknown source type, don't use. */
-    GuestSessionFsSourceType_Unknown = 0,
-    /** The source is a directory. */
-    GuestSessionFsSourceType_Dir,
-    /** The source is a file. */
-    GuestSessionFsSourceType_File
-};
 
 /**
@@ -54,10 +42,10 @@
 struct GuestSessionFsSourceSpec
 {
-    Utf8Str                  strSource;
-    Utf8Str                  strFilter;
-    GuestSessionFsSourceType enmType;
-    PathStyle_T              enmPathStyle;
-    bool                     fDryRun;
-    bool                     fFollowSymlinks;
+    Utf8Str     strSource;
+    Utf8Str     strFilter;
+    FsObjType_T enmType;
+    PathStyle_T enmPathStyle;
+    bool        fDryRun;
+    bool        fFollowSymlinks;
     union
     {
Index: /trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp	(revision 72000)
+++ /trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp	(revision 72001)
@@ -722,4 +722,208 @@
     LogFlowFuncLeaveRC(vrc);
     return vrc;
+}
+
+/**
+ * Internal worker function for public APIs that handle copying elements from
+ * guest to the host.
+ *
+ * @return HRESULT
+ * @param  SourceSet            Source set specifying what to copy.
+ * @param  strDestination       Destination path on the host. Host path style.
+ * @param  pProgress            Progress object returned to the caller.
+ */
+HRESULT GuestSession::i_copyFromGuest(const GuestSessionFsSourceSet &SourceSet,
+                                      const com::Utf8Str &strDestination, ComPtr<IProgress> &pProgress)
+{
+    HRESULT hrc = i_isReadyExternal();
+    if (FAILED(hrc))
+        return hrc;
+
+    LogFlowThisFuncEnter();
+
+    /* Validate stuff. */
+    if (RT_UNLIKELY(SourceSet.size() == 0 || *(SourceSet[0].strSource.c_str()) == '\0')) /* At least one source must be present. */
+        return setError(E_INVALIDARG, tr("No source(s) specified"));
+    if (RT_UNLIKELY((strDestination.c_str()) == NULL || *(strDestination.c_str()) == '\0'))
+        return setError(E_INVALIDARG, tr("No destination specified"));
+
+    GuestSessionFsSourceSet::const_iterator itSource = SourceSet.begin();
+    while (itSource != SourceSet.end())
+    {
+        if (itSource->enmType == FsObjType_Directory)
+        {
+            if (itSource->Type.Dir.fCopyFlags)
+            {
+                if (!(itSource->Type.Dir.fCopyFlags & DirectoryCopyFlag_CopyIntoExisting))
+                    return setError(E_INVALIDARG, tr("Invalid / not (yet) implemented directory copy flags specified"));
+            }
+        }
+        else if (itSource->enmType == FsObjType_File)
+        {
+            if (itSource->Type.File.fCopyFlags)
+            {
+                if (   !(itSource->Type.File.fCopyFlags & FileCopyFlag_NoReplace)
+                    && !(itSource->Type.File.fCopyFlags & FileCopyFlag_FollowLinks)
+                    && !(itSource->Type.File.fCopyFlags & FileCopyFlag_Update))
+                {
+                    return setError(E_NOTIMPL, tr("Invalid / not (yet) implemented file copy flag(s) specified"));
+                }
+            }
+        }
+        else
+            return setError(E_NOTIMPL, tr("Source type %RU32 not implemented"), itSource->enmType);
+
+        itSource++;
+    }
+
+    try
+    {
+        GuestSessionTaskCopyFrom *pTask = NULL;
+        ComObjPtr<Progress> pProgressObj;
+        try
+        {
+            pTask = new GuestSessionTaskCopyFrom(this /* GuestSession */, SourceSet, strDestination);
+        }
+        catch(...)
+        {
+            hrc = setError(VBOX_E_IPRT_ERROR, tr("Failed to create SessionTaskCopyFrom object"));
+            throw;
+        }
+
+        hrc = pTask->Init(Utf8StrFmt(tr("Copying to \"%s\" on the host"), strDestination.c_str()));
+        if (FAILED(hrc))
+        {
+            delete pTask;
+            hrc = setError(VBOX_E_IPRT_ERROR,
+                           tr("Creating progress object for SessionTaskCopyFrom object failed"));
+            throw hrc;
+        }
+
+        hrc = pTask->createThreadWithType(RTTHREADTYPE_MAIN_HEAVY_WORKER);
+
+        if (SUCCEEDED(hrc))
+        {
+            /* Return progress to the caller. */
+            pProgressObj = pTask->GetProgressObject();
+            hrc = pProgressObj.queryInterfaceTo(pProgress.asOutParam());
+        }
+        else
+            hrc = setError(VBOX_E_IPRT_ERROR,
+                           tr("Starting thread for copying from guest to \"%s\" on the host failed"), strDestination.c_str());
+
+    }
+    catch(std::bad_alloc &)
+    {
+        hrc = E_OUTOFMEMORY;
+    }
+    catch(HRESULT eHR)
+    {
+        hrc = eHR;
+        LogFlowThisFunc(("Exception was caught in the function\n"));
+    }
+
+    return hrc;
+}
+
+/**
+ * Internal worker function for public APIs that handle copying elements from
+ * host to the guest.
+ *
+ * @return HRESULT
+ * @param  SourceSet            Source set specifying what to copy.
+ * @param  strDestination       Destination path on the guest. Guest path style.
+ * @param  pProgress            Progress object returned to the caller.
+ */
+HRESULT GuestSession::i_copyToGuest(const GuestSessionFsSourceSet &SourceSet,
+                                    const com::Utf8Str &strDestination, ComPtr<IProgress> &pProgress)
+{
+    HRESULT hrc = i_isReadyExternal();
+    if (FAILED(hrc))
+        return hrc;
+
+    LogFlowThisFuncEnter();
+
+    /* Validate stuff. */
+    if (RT_UNLIKELY(SourceSet.size() == 0 || *(SourceSet[0].strSource.c_str()) == '\0')) /* At least one source must be present. */
+        return setError(E_INVALIDARG, tr("No source(s) specified"));
+    if (RT_UNLIKELY((strDestination.c_str()) == NULL || *(strDestination.c_str()) == '\0'))
+        return setError(E_INVALIDARG, tr("No destination specified"));
+
+    GuestSessionFsSourceSet::const_iterator itSource = SourceSet.begin();
+    while (itSource != SourceSet.end())
+    {
+        if (itSource->enmType == FsObjType_Directory)
+        {
+            if (itSource->Type.Dir.fCopyFlags)
+            {
+                if (!(itSource->Type.Dir.fCopyFlags & DirectoryCopyFlag_CopyIntoExisting))
+                    return setError(E_INVALIDARG, tr("Invalid / not (yet) implemented directory copy flags specified"));
+            }
+        }
+        else if (itSource->enmType == FsObjType_File)
+        {
+            if (itSource->Type.File.fCopyFlags)
+            {
+                if (   !(itSource->Type.File.fCopyFlags & FileCopyFlag_NoReplace)
+                    && !(itSource->Type.File.fCopyFlags & FileCopyFlag_FollowLinks)
+                    && !(itSource->Type.File.fCopyFlags & FileCopyFlag_Update))
+                {
+                    return setError(E_NOTIMPL, tr("Invalid / not (yet) implemented file copy flag(s) specified"));
+                }
+            }
+        }
+        else
+            return setError(E_NOTIMPL, tr("Source type %RU32 not implemented"), itSource->enmType);
+
+        itSource++;
+    }
+
+    try
+    {
+        GuestSessionTaskCopyTo *pTask = NULL;
+        ComObjPtr<Progress> pProgressObj;
+        try
+        {
+            pTask = new GuestSessionTaskCopyTo(this /* GuestSession */, SourceSet, strDestination);
+        }
+        catch(...)
+        {
+            hrc = setError(VBOX_E_IPRT_ERROR, tr("Failed to create SessionTaskCopyTo object"));
+            throw;
+        }
+
+        hrc = pTask->Init(Utf8StrFmt(tr("Copying to \"%s\" on the guest"), strDestination.c_str()));
+        if (FAILED(hrc))
+        {
+            delete pTask;
+            hrc = setError(VBOX_E_IPRT_ERROR,
+                           tr("Creating progress object for SessionTaskCopyTo object failed"));
+            throw hrc;
+        }
+
+        hrc = pTask->createThreadWithType(RTTHREADTYPE_MAIN_HEAVY_WORKER);
+
+        if (SUCCEEDED(hrc))
+        {
+            /* Return progress to the caller. */
+            pProgress = pTask->GetProgressObject();
+            hrc = pProgressObj.queryInterfaceTo(pProgress.asOutParam());
+        }
+        else
+            hrc = setError(VBOX_E_IPRT_ERROR,
+                           tr("Starting thread for copying from host to \"%s\" on the guest failed"), strDestination.c_str());
+
+    }
+    catch(std::bad_alloc &)
+    {
+        hrc = E_OUTOFMEMORY;
+    }
+    catch(HRESULT eHR)
+    {
+        hrc = eHR;
+        LogFlowThisFunc(("Exception was caught in the function\n"));
+    }
+
+    return hrc;
 }
 
@@ -2595,5 +2799,5 @@
 }
 
-HRESULT GuestSession::fileCopyFromGuest(const com::Utf8Str &aSource, const com::Utf8Str &aDest,
+HRESULT GuestSession::fileCopyFromGuest(const com::Utf8Str &aSource, const com::Utf8Str &aDestination,
                                         const std::vector<FileCopyFlag_T> &aFlags,
                                         ComPtr<IProgress> &aProgress)
@@ -2602,9 +2806,4 @@
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
-    if (RT_UNLIKELY((aSource.c_str()) == NULL || *(aSource.c_str()) == '\0'))
-        return setError(E_INVALIDARG, tr("No source specified"));
-    if (RT_UNLIKELY((aDest.c_str()) == NULL || *(aDest.c_str()) == '\0'))
-        return setError(E_INVALIDARG, tr("No destination specified"));
-
     uint32_t fFlags = FileCopyFlag_None;
     if (aFlags.size())
@@ -2614,81 +2813,18 @@
     }
 
-    if (fFlags)
-    {
-        if (   !(fFlags & FileCopyFlag_NoReplace)
-            && !(fFlags & FileCopyFlag_FollowLinks)
-            && !(fFlags & FileCopyFlag_Update))
-        {
-            return setError(E_NOTIMPL, tr("Invalid / not (yet) implemented flag(s) specified"));
-        }
-    }
-
-    HRESULT hrc = i_isReadyExternal();
-    if (FAILED(hrc))
-        return hrc;
-
-    LogFlowThisFuncEnter();
-
-    try
-    {
-        GuestSessionTaskCopyFrom *pTask = NULL;
-        ComObjPtr<Progress> pProgress;
-        try
-        {
-            GuestSessionFsSourceSpec source;
-            source.strSource            = aSource;
-            source.enmType              = GuestSessionFsSourceType_File;
-            source.enmPathStyle         = i_getPathStyle();
-            source.Type.File.fCopyFlags = (FileCopyFlag_T)fFlags;
-
-            GuestSessionFsSourceSet vecSources;
-            vecSources.push_back(source);
-
-            pTask = new GuestSessionTaskCopyFrom(this /* GuestSession */, vecSources, aDest);
-        }
-        catch(...)
-        {
-            hrc = setError(VBOX_E_IPRT_ERROR, tr("Failed to create SessionTaskCopyFrom object"));
-            throw;
-        }
-
-
-        hrc = pTask->Init(Utf8StrFmt(tr("Copying \"%s\" from guest to \"%s\" on the host"), aSource.c_str(), aDest.c_str()));
-        if (FAILED(hrc))
-        {
-            delete pTask;
-            hrc = setError(VBOX_E_IPRT_ERROR,
-                           tr("Creating progress object for SessionTaskCopyFrom object failed"));
-            throw hrc;
-        }
-
-        hrc = pTask->createThreadWithType(RTTHREADTYPE_MAIN_HEAVY_WORKER);
-
-        if (SUCCEEDED(hrc))
-        {
-            /* Return progress to the caller. */
-            pProgress = pTask->GetProgressObject();
-            hrc = pProgress.queryInterfaceTo(aProgress.asOutParam());
-        }
-        else
-            hrc = setError(VBOX_E_IPRT_ERROR,
-                           tr("Starting thread for copying file \"%s\" from guest to \"%s\" on the host failed "),
-                           aSource.c_str(), aDest.c_str());
-
-    }
-    catch(std::bad_alloc &)
-    {
-        hrc = E_OUTOFMEMORY;
-    }
-    catch(HRESULT eHR)
-    {
-        hrc = eHR;
-        LogFlowThisFunc(("Exception was caught in the function \n"));
-    }
-
-    return hrc;
-}
-
-HRESULT GuestSession::fileCopyToGuest(const com::Utf8Str &aSource, const com::Utf8Str &aDest,
+    GuestSessionFsSourceSet SourceSet;
+
+    GuestSessionFsSourceSpec source;
+    source.strSource            = aSource;
+    source.enmType              = FsObjType_File;
+    source.enmPathStyle         = i_getPathStyle();
+    source.Type.File.fCopyFlags = (FileCopyFlag_T)fFlags;
+
+    SourceSet.push_back(source);
+
+    return i_copyFromGuest(SourceSet, aDestination, aProgress);
+}
+
+HRESULT GuestSession::fileCopyToGuest(const com::Utf8Str &aSource, const com::Utf8Str &aDestination,
                                       const std::vector<FileCopyFlag_T> &aFlags, ComPtr<IProgress> &aProgress)
 {
@@ -2696,9 +2832,4 @@
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
-    if (RT_UNLIKELY((aSource.c_str()) == NULL || *(aSource.c_str()) == '\0'))
-        return setError(E_INVALIDARG, tr("No source specified"));
-    if (RT_UNLIKELY((aDest.c_str()) == NULL || *(aDest.c_str()) == '\0'))
-        return setError(E_INVALIDARG, tr("No destination specified"));
-
     uint32_t fFlags = FileCopyFlag_None;
     if (aFlags.size())
@@ -2708,80 +2839,15 @@
     }
 
-    if (fFlags)
-    {
-        if (   !(fFlags & FileCopyFlag_NoReplace)
-            && !(fFlags & FileCopyFlag_FollowLinks)
-            && !(fFlags & FileCopyFlag_Update))
-        {
-            return setError(E_NOTIMPL, tr("Invalid / not (yet) implemented flag(s) specified"));
-        }
-    }
-
-    HRESULT hrc = i_isReadyExternal();
-    if (FAILED(hrc))
-        return hrc;
-
-    LogFlowThisFuncEnter();
-
-    try
-    {
-        GuestSessionTaskCopyTo *pTask = NULL;
-        ComObjPtr<Progress> pProgress;
-        try
-        {
-            GuestSessionFsSourceSpec source;
-            source.strSource            = aSource;
-            source.enmType              = GuestSessionFsSourceType_File;
-#if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS
-            source.enmPathStyle         = PathStyle_DOS;
-#else
-            source.enmPathStyle         = PathStyle_UNIX;
-#endif
-            source.Type.File.fCopyFlags = (FileCopyFlag_T)fFlags;
-
-            GuestSessionFsSourceSet vecSources;
-            vecSources.push_back(source);
-
-            pTask = new GuestSessionTaskCopyTo(this /* GuestSession */, vecSources, aDest);
-        }
-        catch(...)
-        {
-            hrc = setError(VBOX_E_IPRT_ERROR, tr("Failed to create SessionTaskCopyTo object"));
-            throw;
-        }
-
-        hrc = pTask->Init(Utf8StrFmt(tr("Copying \"%s\" from host to \"%s\" on the guest"), aSource.c_str(), aDest.c_str()));
-        if (FAILED(hrc))
-        {
-            delete pTask;
-            hrc = setError(VBOX_E_IPRT_ERROR,
-                           tr("Creating progress object for SessionTaskCopyTo object failed"));
-            throw hrc;
-        }
-
-        hrc = pTask->createThreadWithType(RTTHREADTYPE_MAIN_HEAVY_WORKER);
-
-        if (SUCCEEDED(hrc))
-        {
-            /* Return progress to the caller. */
-            pProgress = pTask->GetProgressObject();
-            hrc = pProgress.queryInterfaceTo(aProgress.asOutParam());
-        }
-        else
-            hrc = setError(VBOX_E_IPRT_ERROR,
-                           tr("Starting thread for copying file \"%s\" from host to \"%s\" on the guest failed "),
-                           aSource.c_str(), aDest.c_str());
-    }
-    catch(std::bad_alloc &)
-    {
-        hrc = E_OUTOFMEMORY;
-    }
-    catch(HRESULT eHR)
-    {
-        hrc = eHR;
-        LogFlowThisFunc(("Exception was caught in the function \n"));
-    }
-
-    return hrc;
+    GuestSessionFsSourceSet SourceSet;
+
+    GuestSessionFsSourceSpec source;
+    source.strSource            = aSource;
+    source.enmType              = FsObjType_File;
+    source.enmPathStyle         = i_getPathStyle();
+    source.Type.File.fCopyFlags = (FileCopyFlag_T)fFlags;
+
+    SourceSet.push_back(source);
+
+    return i_copyToGuest(SourceSet, aDestination, aProgress);
 }
 
@@ -2790,6 +2856,49 @@
                                     const com::Utf8Str &aDestination, ComPtr<IProgress> &aProgress)
 {
-    RT_NOREF(aSources, aFilters, aTypes, aFlags, aDestination, aProgress);
-    ReturnComNotImplemented();
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    const size_t cSources = aSources.size();
+    if (   aFilters.size() != cSources
+        || aTypes.size()   != cSources
+        || aFlags.size()   != cSources)
+    {
+        return setError(E_INVALIDARG, tr("Parameter array sizes don't match to the number of sources specified"));
+    }
+
+    GuestSessionFsSourceSet SourceSet;
+
+    std::vector<com::Utf8Str>::const_iterator itSource  = aSources.begin();
+    std::vector<com::Utf8Str>::const_iterator itFilter  = aFilters.begin();
+    std::vector<FsObjType_T>::const_iterator itType     = aTypes.begin();
+    std::vector<GuestCopyFlag_T>::const_iterator itFlag = aFlags.begin();
+
+    while (itSource != aSources.end())
+    {
+        GuestSessionFsSourceSpec source;
+        source.strSource    = *itSource;
+        source.strFilter    = *itFilter;
+        source.enmType      = *itType;
+        source.enmPathStyle = i_getPathStyle();
+
+        if (*itType == FsObjType_Directory)
+        {
+            source.Type.Dir.fCopyFlags = (DirectoryCopyFlag_T)*itFlag;
+            source.Type.Dir.fRecursive = true; /* Implicit. */
+        }
+        else
+        {
+            source.Type.File.fCopyFlags = (FileCopyFlag_T)*itFlag;
+        }
+
+        SourceSet.push_back(source);
+
+        ++itSource;
+        ++itFilter;
+        ++itType;
+        ++itFlag;
+    }
+
+    return i_copyFromGuest(SourceSet, aDestination, aProgress);
 }
 
@@ -2798,6 +2907,48 @@
                                   const com::Utf8Str &aDestination, ComPtr<IProgress> &aProgress)
 {
-    RT_NOREF(aSources, aFilters, aTypes, aFlags, aDestination, aProgress);
-    ReturnComNotImplemented();
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    const size_t cSources = aSources.size();
+    if (   aFilters.size() != cSources
+        || aTypes.size()   != cSources
+        || aFlags.size()   != cSources)
+    {
+        return setError(E_INVALIDARG, tr("Parameter array sizes don't match to the number of sources specified"));
+    }
+
+    GuestSessionFsSourceSet SourceSet;
+
+    std::vector<com::Utf8Str>::const_iterator itSource  = aSources.begin();
+    std::vector<com::Utf8Str>::const_iterator itFilter  = aFilters.begin();
+    std::vector<FsObjType_T>::const_iterator itType     = aTypes.begin();
+    std::vector<GuestCopyFlag_T>::const_iterator itFlag = aFlags.begin();
+
+    while (itSource != aSources.end())
+    {
+
+        GuestSessionFsSourceSpec source;
+        source.strSource    = *itSource;
+        source.strFilter    = *itFilter;
+        source.enmType      = *itType;
+        source.enmPathStyle = i_getPathStyle();
+
+        if (*itType == FsObjType_Directory)
+        {
+            source.Type.Dir.fCopyFlags = (DirectoryCopyFlag_T)*itFlag;
+            source.Type.Dir.fRecursive = true; /* Implicit. */
+        }
+        else
+            source.Type.File.fCopyFlags = (FileCopyFlag_T)*itFlag;
+
+        SourceSet.push_back(source);
+
+        ++itSource;
+        ++itFilter;
+        ++itType;
+        ++itFlag;
+    }
+
+    return i_copyToGuest(SourceSet, aDestination, aProgress);
 }
 
@@ -2815,10 +2966,4 @@
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
-    if (RT_UNLIKELY((aSource.c_str()) == NULL || *(aSource.c_str()) == '\0'))
-        return setError(E_INVALIDARG, tr("No source directory specified"));
-
-    if (RT_UNLIKELY((aDestination.c_str()) == NULL || *(aDestination.c_str()) == '\0'))
-        return setError(E_INVALIDARG, tr("No destination directory specified"));
-
     uint32_t fFlags = DirectoryCopyFlag_None;
     if (aFlags.size())
@@ -2828,73 +2973,16 @@
     }
 
-    if (fFlags)
-    {
-        if (!(fFlags & DirectoryCopyFlag_CopyIntoExisting))
-            return setError(E_INVALIDARG, tr("Invalid flags specified"));
-    }
-
-    HRESULT hrc = i_isReadyExternal();
-    if (FAILED(hrc))
-        return hrc;
-
-    LogFlowThisFuncEnter();
-
-    try
-    {
-        GuestSessionTaskCopyFrom *pTask = NULL;
-        ComObjPtr<Progress> pProgress;
-        try
-        {
-            GuestSessionFsSourceSpec source;
-            source.strSource           = aSource;
-            source.enmType             = GuestSessionFsSourceType_Dir;
-            source.enmPathStyle        = i_getPathStyle();
-            source.Type.Dir.fCopyFlags = (DirectoryCopyFlag_T)fFlags;
-
-            GuestSessionFsSourceSet vecSources;
-            vecSources.push_back(source);
-
-            pTask = new GuestSessionTaskCopyFrom(this /* GuestSession */, vecSources, aDestination);
-        }
-        catch(...)
-        {
-            hrc = setError(VBOX_E_IPRT_ERROR, tr("Failed to create SessionTaskCopyFrom object"));
-            throw;
-        }
-
-        hrc = pTask->Init(Utf8StrFmt(tr("Copying directory \"%s\" from guest to \"%s\" on the host"),
-                                     aSource.c_str(), aDestination.c_str()));
-        if (FAILED(hrc))
-        {
-            delete pTask;
-            hrc = setError(VBOX_E_IPRT_ERROR,
-                           tr("Creating progress object for SessionTaskCopyDirFrom object failed"));
-            throw hrc;
-        }
-
-        hrc = pTask->createThreadWithType(RTTHREADTYPE_MAIN_HEAVY_WORKER);
-
-        if (SUCCEEDED(hrc))
-        {
-            /* Return progress to the caller. */
-            pProgress = pTask->GetProgressObject();
-            hrc = pProgress.queryInterfaceTo(aProgress.asOutParam());
-        }
-        else
-            hrc = setError(VBOX_E_IPRT_ERROR,
-                           tr("Starting thread for copying directory \"%s\" from guest to \"%s\" on the host failed"),
-                           aSource.c_str(), aDestination.c_str());
-    }
-    catch(std::bad_alloc &)
-    {
-        hrc = E_OUTOFMEMORY;
-    }
-    catch(HRESULT eHR)
-    {
-        hrc = eHR;
-        LogFlowThisFunc(("Exception was caught in the function\n"));
-    }
-
-    return hrc;
+    GuestSessionFsSourceSet SourceSet;
+
+    GuestSessionFsSourceSpec source;
+    source.strSource            = aSource;
+    source.enmType              = FsObjType_Directory;
+    source.enmPathStyle         = i_getPathStyle();
+    source.Type.Dir.fCopyFlags  = (DirectoryCopyFlag_T)fFlags;
+    source.Type.Dir.fRecursive  = true; /* Implicit. */
+
+    SourceSet.push_back(source);
+
+    return i_copyFromGuest(SourceSet, aDestination, aProgress);
 }
 
@@ -2905,13 +2993,4 @@
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
-    if (RT_UNLIKELY((aSource.c_str()) == NULL || *(aSource.c_str()) == '\0'))
-        return setError(E_INVALIDARG, tr("No source directory specified"));
-
-    if (RT_UNLIKELY((aDestination.c_str()) == NULL || *(aDestination.c_str()) == '\0'))
-        return setError(E_INVALIDARG, tr("No destination directory specified"));
-
-    if (!RTPathExists(aSource.c_str()))
-        return setError(E_INVALIDARG, tr("Source directory \"%s\" does not exist"), aSource.c_str());
-
     uint32_t fFlags = DirectoryCopyFlag_None;
     if (aFlags.size())
@@ -2921,79 +3000,16 @@
     }
 
-    if (fFlags)
-    {
-        if (!(fFlags & DirectoryCopyFlag_CopyIntoExisting))
-            return setError(E_INVALIDARG, tr("Invalid flags specified"));
-    }
-
-    HRESULT hrc = i_isReadyExternal();
-    if (FAILED(hrc))
-        return hrc;
-
-    LogFlowThisFuncEnter();
-
-    try
-    {
-        GuestSessionTaskCopyTo *pTask = NULL;
-        ComObjPtr<Progress> pProgress;
-        try
-        {
-            GuestSessionFsSourceSpec source;
-            source.strSource           = aSource;
-            source.enmType             = GuestSessionFsSourceType_Dir;
-#if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS
-            source.enmPathStyle         = PathStyle_DOS;
-#else
-            source.enmPathStyle         = PathStyle_UNIX;
-#endif
-            source.fFollowSymlinks     = true;
-            source.Type.Dir.fRecursive = true;
-            source.Type.Dir.fCopyFlags = (DirectoryCopyFlag_T)fFlags;
-
-            GuestSessionFsSourceSet vecSources;
-            vecSources.push_back(source);
-
-            pTask = new GuestSessionTaskCopyTo(this /* GuestSession */, vecSources, aDestination);
-        }
-        catch(...)
-        {
-            hrc = setError(VBOX_E_IPRT_ERROR, tr("Failed to create SessionTaskCopyTo object"));
-            throw;
-        }
-
-        hrc = pTask->Init(Utf8StrFmt(tr("Copying directory \"%s\" from host to \"%s\" on the guest"),
-                                     aSource.c_str(), aDestination.c_str()));
-        if (FAILED(hrc))
-        {
-            delete pTask;
-            hrc = setError(VBOX_E_IPRT_ERROR,
-                           tr("Creating progress object for SessionTaskCopyDirTo object failed"));
-            throw hrc;
-        }
-
-        hrc = pTask->createThreadWithType(RTTHREADTYPE_MAIN_HEAVY_WORKER);
-
-        if (SUCCEEDED(hrc))
-        {
-            /* Return progress to the caller. */
-            pProgress = pTask->GetProgressObject();
-            hrc = pProgress.queryInterfaceTo(aProgress.asOutParam());
-        }
-        else
-            hrc = setError(VBOX_E_IPRT_ERROR,
-                           tr("Starting thread for copying directory \"%s\" from host to \"%s\" on the guest failed"),
-                           aSource.c_str(), aDestination.c_str());
-    }
-    catch(std::bad_alloc &)
-    {
-        hrc = E_OUTOFMEMORY;
-    }
-    catch(HRESULT eHR)
-    {
-        hrc = eHR;
-        LogFlowThisFunc(("Exception was caught in the function\n"));
-    }
-
-    return hrc;
+    GuestSessionFsSourceSet SourceSet;
+
+    GuestSessionFsSourceSpec source;
+    source.strSource           = aSource;
+    source.enmType             = FsObjType_Directory;
+    source.enmPathStyle        = i_getPathStyle();
+    source.Type.Dir.fCopyFlags = (DirectoryCopyFlag_T)fFlags;
+    source.Type.Dir.fRecursive = true; /* Implicit. */
+
+    SourceSet.push_back(source);
+
+    return i_copyToGuest(SourceSet, aDestination, aProgress);
 }
 
Index: /trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp	(revision 72000)
+++ /trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp	(revision 72001)
@@ -981,5 +981,5 @@
 
     /* If the source is a directory, make sure the path is properly terminated already. */
-    if (mSourceSpec.enmType == GuestSessionFsSourceType_Dir)
+    if (mSourceSpec.enmType == FsObjType_Directory)
     {
         if (   !mSrcRootAbs.endsWith("/")
@@ -1529,5 +1529,5 @@
         Utf8Str strDst = mDest;
 
-        if (itSrc->enmType == GuestSessionFsSourceType_Dir)
+        if (itSrc->enmType == FsObjType_Directory)
         {
             /* If the source does not end with a slash, copy over the entire directory
@@ -1554,5 +1554,5 @@
         if (srcObjData.mType == FsObjType_Directory)
         {
-            if (itSrc->enmType != GuestSessionFsSourceType_Dir)
+            if (itSrc->enmType != FsObjType_Directory)
             {
                 rc = VERR_NOT_A_FILE;
@@ -1562,5 +1562,5 @@
         else
         {
-            if (itSrc->enmType != GuestSessionFsSourceType_File)
+            if (itSrc->enmType != FsObjType_File)
             {
                 rc = VERR_NOT_A_DIRECTORY;
@@ -1572,5 +1572,5 @@
 
 #if 0
-        if (itSrc->enmType == GuestSessionFsSourceType_Dir)
+        if (itSrc->enmType == FsObjType_Directory)
         {
             bool fDstExists = RTDirExists(strDstDir.c_str());
@@ -1621,5 +1621,5 @@
             }
         }
-        else if (itSrc->enmType == GuestSessionFsSourceType_File)
+        else if (itSrc->enmType == FsObjType_File)
         {
 
@@ -1636,5 +1636,5 @@
             if (RT_SUCCESS(rc))
             {
-                if (itSrc->enmType == GuestSessionFsSourceType_Dir)
+                if (itSrc->enmType == FsObjType_Directory)
                 {
                     rc = pFsList->AddDirFromGuest(strSrc);
@@ -1704,5 +1704,5 @@
 
         /* Create the root directory. */
-        if (pList->mSourceSpec.enmType == GuestSessionFsSourceType_Dir)
+        if (pList->mSourceSpec.enmType == FsObjType_Directory)
         {
             rc = RTDirCreate(pList->mDstRootAbs.c_str(), fDirMode, 0 /* fCreate */);
@@ -1722,5 +1722,5 @@
             Utf8Str strSrcAbs = pList->mSrcRootAbs;
             Utf8Str strDstAbs = pList->mDstRootAbs;
-            if (pList->mSourceSpec.enmType == GuestSessionFsSourceType_Dir)
+            if (pList->mSourceSpec.enmType == FsObjType_Directory)
             {
                 strSrcAbs += pEntry->strPath;
@@ -1820,5 +1820,5 @@
         Utf8Str strDst = mDest;
 
-        if (itSrc->enmType == GuestSessionFsSourceType_Dir)
+        if (itSrc->enmType == FsObjType_Directory)
         {
             /* If the source does not end with a slash, copy over the entire directory
@@ -1842,5 +1842,5 @@
         if (RTFS_IS_DIRECTORY(srcFsObjInfo.Attr.fMode))
         {
-            if (itSrc->enmType != GuestSessionFsSourceType_Dir)
+            if (itSrc->enmType != FsObjType_Directory)
             {
                 rc = VERR_NOT_A_FILE;
@@ -1850,5 +1850,5 @@
         else
         {
-            if (itSrc->enmType == GuestSessionFsSourceType_Dir)
+            if (itSrc->enmType == FsObjType_Directory)
             {
                 rc = VERR_NOT_A_DIRECTORY;
@@ -1866,5 +1866,5 @@
             if (RT_SUCCESS(rc))
             {
-                if (itSrc->enmType == GuestSessionFsSourceType_Dir)
+                if (itSrc->enmType == FsObjType_Directory)
                 {
                     rc = pFsList->AddDirFromHost(strSrc);
@@ -1933,5 +1933,5 @@
 
         /* Create the root directory. */
-        if (pList->mSourceSpec.enmType == GuestSessionFsSourceType_Dir)
+        if (pList->mSourceSpec.enmType == FsObjType_Directory)
         {
             rc = directoryCreate(pList->mDstRootAbs.c_str(), DirectoryCreateFlag_None, fDirMode, fFollowSymlinks);
@@ -1951,5 +1951,5 @@
             Utf8Str strSrcAbs = pList->mSrcRootAbs;
             Utf8Str strDstAbs = pList->mDstRootAbs;
-            if (pList->mSourceSpec.enmType == GuestSessionFsSourceType_Dir)
+            if (pList->mSourceSpec.enmType == FsObjType_Directory)
             {
                 strSrcAbs += pEntry->strPath;
