Index: /trunk/src/VBox/Main/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Main/Makefile.kmk	(revision 55643)
+++ /trunk/src/VBox/Main/Makefile.kmk	(revision 55644)
@@ -741,9 +741,4 @@
 	src-client/EmulatedUSBImpl.cpp \
 	src-client/GuestImpl.cpp \
-	src-client/GuestDirectoryImpl.cpp \
-	src-client/GuestFileImpl.cpp \
-	src-client/GuestFsObjInfoImpl.cpp \
-	src-client/GuestProcessImpl.cpp \
-	src-client/GuestSessionImpl.cpp \
 	src-client/GuestCtrlImpl.cpp \
 	src-client/KeyboardImpl.cpp \
@@ -774,5 +769,10 @@
  VBoxC_SOURCES += \
 	src-client/GuestSessionImplTasks.cpp \
-	src-client/GuestCtrlPrivate.cpp
+	src-client/GuestCtrlPrivate.cpp \
+	src-client/GuestDirectoryImpl.cpp \
+	src-client/GuestFileImpl.cpp \
+	src-client/GuestFsObjInfoImpl.cpp \
+	src-client/GuestProcessImpl.cpp \
+	src-client/GuestSessionImpl.cpp
 endif
 ifdef VBOX_WITH_DRAG_AND_DROP
Index: /trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h
===================================================================
--- /trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h	(revision 55643)
+++ /trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h	(revision 55644)
@@ -1,5 +1,4 @@
 /* $Id$ */
 /** @file
- *
  * Internal helpers/structures for guest control functionality.
  */
Index: /trunk/src/VBox/Main/include/GuestImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/GuestImpl.h	(revision 55643)
+++ /trunk/src/VBox/Main/include/GuestImpl.h	(revision 55644)
@@ -27,10 +27,13 @@
 
 #include "AdditionsFacilityImpl.h"
-#include "GuestCtrlImplPrivate.h"
+#ifdef VBOX_WITH_GUEST_CONTROL
+# include "GuestCtrlImplPrivate.h"
+# include "GuestSessionImpl.h"
+#endif
 #ifdef VBOX_WITH_DRAG_AND_DROP
 # include "GuestDnDSourceImpl.h"
 # include "GuestDnDTargetImpl.h"
 #endif
-#include "GuestSessionImpl.h"
+#include "EventImpl.h"
 #include "HGCM.h"
 
@@ -72,6 +75,6 @@
     /** Static callback for handling guest control notifications. */
     static DECLCALLBACK(int) i_notifyCtrlDispatcher(void *pvExtension, uint32_t u32Function, void *pvData, uint32_t cbData);
+#endif
     static DECLCALLBACK(void) i_staticUpdateStats(RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick);
-#endif
     /** @}  */
 
@@ -96,8 +99,8 @@
         return setErrorInternal(aResultCode, getStaticClassIID(), getStaticComponentName(), aText, false, true);
     }
-#ifdef VBOX_WITH_GUEST_CONTROL
-    int         i_dispatchToSession(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
     uint32_t    i_getAdditionsVersion(void) { return mData.mAdditionsVersionFull; }
     VBOXOSTYPE  i_getGuestOSType(void) { return mData.mOSType; }
+#ifdef VBOX_WITH_GUEST_CONTROL
+    int         i_dispatchToSession(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
     int         i_sessionRemove(GuestSession *pSession);
     int         i_sessionCreate(const GuestSessionStartupInfo &ssInfo, const GuestCredentials &guestCreds,
@@ -174,6 +177,8 @@
     typedef std::map< AdditionsFacilityType_T, ComObjPtr<AdditionsFacility> >::const_iterator FacilityMapIterConst;
 
+#ifdef VBOX_WITH_GUEST_CONTROL
     /** Map for keeping the guest sessions. The primary key marks the guest session ID. */
     typedef std::map <uint32_t, ComObjPtr<GuestSession> > GuestSessions;
+#endif
 
     struct Data
@@ -192,6 +197,8 @@
         uint32_t                    mAdditionsFeatures;
         Utf8Str                     mInterfaceVersion;
+#ifdef VBOX_WITH_GUEST_CONTROL
         GuestSessions               mGuestSessions;
         uint32_t                    mNextSessionID;
+#endif
     } mData;
 
@@ -208,5 +215,4 @@
     const ComObjPtr<Console>        mParent;
 
-#ifdef VBOX_WITH_GUEST_CONTROL
     /**
      * This can safely be used without holding any locks.
@@ -215,4 +221,5 @@
      */
     const ComObjPtr<EventSource>    mEventSource;
+#ifdef VBOX_WITH_GUEST_CONTROL
     /** General extension callback for guest control. */
     HGCMSVCEXTHANDLE                mhExtCtrl;
Index: /trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp	(revision 55643)
+++ /trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp	(revision 55644)
@@ -17,6 +17,8 @@
 
 #include "GuestImpl.h"
-#include "GuestSessionImpl.h"
-#include "GuestCtrlImplPrivate.h"
+#ifdef VBOX_WITH_GUEST_CONTROL
+# include "GuestSessionImpl.h"
+# include "GuestCtrlImplPrivate.h"
+#endif
 
 #include "Global.h"
@@ -49,9 +51,9 @@
 #include <VBox/log.h>
 
+#ifdef VBOX_WITH_GUEST_CONTROL
 
 // public methods only for internal purposes
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef VBOX_WITH_GUEST_CONTROL
 /**
  * Static callback function for receiving updates on guest control commands
@@ -112,5 +114,364 @@
     return rc;
 }
+
+// private methods
+/////////////////////////////////////////////////////////////////////////////
+
+int Guest::i_dispatchToSession(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)
+{
+    LogFlowFunc(("pCtxCb=%p, pSvcCb=%p\n", pCtxCb, pSvcCb));
+
+    AssertPtrReturn(pCtxCb, VERR_INVALID_POINTER);
+    AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER);
+
+    LogFlowFunc(("uFunction=%RU32, uContextID=%RU32, uProtocol=%RU32\n",
+                  pCtxCb->uFunction, pCtxCb->uContextID, pCtxCb->uProtocol));
+
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    uint32_t uSessionID = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pCtxCb->uContextID);
+#ifdef DEBUG
+    LogFlowFunc(("uSessionID=%RU32 (%zu total)\n",
+                 uSessionID, mData.mGuestSessions.size()));
+#endif
+    GuestSessions::const_iterator itSession
+        = mData.mGuestSessions.find(uSessionID);
+
+    int rc;
+    if (itSession != mData.mGuestSessions.end())
+    {
+        ComObjPtr<GuestSession> pSession(itSession->second);
+        Assert(!pSession.isNull());
+
+        alock.release();
+
+        bool fDispatch = true;
+#ifdef DEBUG
+        /*
+         * Pre-check: If we got a status message with an error and VERR_TOO_MUCH_DATA
+         *            it means that that guest could not handle the entire message
+         *            because of its exceeding size. This should not happen on daily
+         *            use but testcases might try this. It then makes no sense to dispatch
+         *            this further because we don't have a valid context ID.
+         */
+        if (   pCtxCb->uFunction == GUEST_EXEC_STATUS
+            && pSvcCb->mParms    >= 5)
+        {
+            CALLBACKDATA_PROC_STATUS dataCb;
+            /* pSvcCb->mpaParms[0] always contains the context ID. */
+            pSvcCb->mpaParms[1].getUInt32(&dataCb.uPID);
+            pSvcCb->mpaParms[2].getUInt32(&dataCb.uStatus);
+            pSvcCb->mpaParms[3].getUInt32(&dataCb.uFlags);
+            pSvcCb->mpaParms[4].getPointer(&dataCb.pvData, &dataCb.cbData);
+
+            if (   (         dataCb.uStatus == PROC_STS_ERROR)
+                   /** @todo Note: Due to legacy reasons we cannot change uFlags to
+                    *              int32_t, so just cast it for now. */
+                && ((int32_t)dataCb.uFlags  == VERR_TOO_MUCH_DATA))
+            {
+                LogFlowFunc(("Requested command with too much data, skipping dispatching ...\n"));
+
+                Assert(dataCb.uPID == 0);
+                fDispatch = false;
+            }
+        }
+#endif
+        if (fDispatch)
+        {
+            switch (pCtxCb->uFunction)
+            {
+                case GUEST_DISCONNECTED:
+                    rc = pSession->i_dispatchToThis(pCtxCb, pSvcCb);
+                    break;
+
+                case GUEST_EXEC_STATUS:
+                case GUEST_EXEC_OUTPUT:
+                case GUEST_EXEC_INPUT_STATUS:
+                case GUEST_EXEC_IO_NOTIFY:
+                    rc = pSession->i_dispatchToProcess(pCtxCb, pSvcCb);
+                    break;
+
+                case GUEST_FILE_NOTIFY:
+                    rc = pSession->i_dispatchToFile(pCtxCb, pSvcCb);
+                    break;
+
+                case GUEST_SESSION_NOTIFY:
+                    rc = pSession->i_dispatchToThis(pCtxCb, pSvcCb);
+                    break;
+
+                default:
+                    /*
+                     * Try processing generic messages which might
+                     * (or might not) supported by certain objects.
+                     * If the message either is not found or supported
+                     * by the approprirate object, try handling it
+                     * in this session object.
+                     */
+                    rc = pSession->i_dispatchToObject(pCtxCb, pSvcCb);
+                    if (   rc == VERR_NOT_FOUND
+                        || rc == VERR_NOT_SUPPORTED)
+                    {
+                        alock.acquire();
+
+                        rc = pSession->dispatchGeneric(pCtxCb, pSvcCb);
+                    }
+#ifndef DEBUG_andy
+                    if (rc == VERR_NOT_IMPLEMENTED)
+                        AssertMsgFailed(("Received not handled function %RU32\n", pCtxCb->uFunction));
+#endif
+                    break;
+            }
+        }
+        else
+            rc = VERR_NOT_FOUND;
+    }
+    else
+        rc = VERR_NOT_FOUND;
+
+    LogFlowFuncLeaveRC(rc);
+    return rc;
+}
+
+int Guest::i_sessionRemove(GuestSession *pSession)
+{
+    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
+
+    LogFlowThisFuncEnter();
+
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    int rc = VERR_NOT_FOUND;
+
+    LogFlowThisFunc(("Removing session (ID=%RU32) ...\n", pSession->i_getId()));
+
+    GuestSessions::iterator itSessions = mData.mGuestSessions.begin();
+    while (itSessions != mData.mGuestSessions.end())
+    {
+        if (pSession == itSessions->second)
+        {
+#ifdef DEBUG_andy
+            ULONG cRefs = pSession->AddRef();
+            Assert(cRefs >= 2);
+            LogFlowThisFunc(("pCurSession=%p, cRefs=%RU32\n", pSession, cRefs - 2));
+            pSession->Release();
+#endif
+            /* Make sure to consume the pointer before the one of the
+             * iterator gets released. */
+            ComObjPtr<GuestSession> pCurSession = pSession;
+
+            LogFlowThisFunc(("Removing session (pSession=%p, ID=%RU32) (now total %ld sessions)\n",
+                             pSession, pSession->i_getId(), mData.mGuestSessions.size() - 1));
+
+            rc = pSession->i_onRemove();
+            mData.mGuestSessions.erase(itSessions);
+
+            alock.release(); /* Release lock before firing off event. */
+
+            fireGuestSessionRegisteredEvent(mEventSource, pCurSession,
+                                            false /* Unregistered */);
+            pCurSession.setNull();
+            break;
+        }
+
+        itSessions++;
+    }
+
+    LogFlowFuncLeaveRC(rc);
+    return rc;
+}
+
+int Guest::i_sessionCreate(const GuestSessionStartupInfo &ssInfo,
+                           const GuestCredentials &guestCreds, ComObjPtr<GuestSession> &pGuestSession)
+{
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    int rc = VERR_MAX_PROCS_REACHED;
+    if (mData.mGuestSessions.size() >= VBOX_GUESTCTRL_MAX_SESSIONS)
+        return rc;
+
+    try
+    {
+        /* Create a new session ID and assign it. */
+        uint32_t uNewSessionID = VBOX_GUESTCTRL_SESSION_ID_BASE;
+        uint32_t uTries = 0;
+
+        for (;;)
+        {
+            /* Is the context ID already used? */
+            if (!i_sessionExists(uNewSessionID))
+            {
+                rc = VINF_SUCCESS;
+                break;
+            }
+            uNewSessionID++;
+            if (uNewSessionID >= VBOX_GUESTCTRL_MAX_SESSIONS)
+                uNewSessionID = VBOX_GUESTCTRL_SESSION_ID_BASE;
+
+            if (++uTries == VBOX_GUESTCTRL_MAX_SESSIONS)
+                break; /* Don't try too hard. */
+        }
+        if (RT_FAILURE(rc)) throw rc;
+
+        /* Create the session object. */
+        HRESULT hr = pGuestSession.createObject();
+        if (FAILED(hr)) throw VERR_COM_UNEXPECTED;
+
+        /** @todo Use an overloaded copy operator. Later. */
+        GuestSessionStartupInfo startupInfo;
+        startupInfo.mID = uNewSessionID; /* Assign new session ID. */
+        startupInfo.mName = ssInfo.mName;
+        startupInfo.mOpenFlags = ssInfo.mOpenFlags;
+        startupInfo.mOpenTimeoutMS = ssInfo.mOpenTimeoutMS;
+
+        GuestCredentials guestCredentials;
+        if (!guestCreds.mUser.isEmpty())
+        {
+            /** @todo Use an overloaded copy operator. Later. */
+            guestCredentials.mUser = guestCreds.mUser;
+            guestCredentials.mPassword = guestCreds.mPassword;
+            guestCredentials.mDomain = guestCreds.mDomain;
+        }
+        else
+        {
+            /* Internal (annonymous) session. */
+            startupInfo.mIsInternal = true;
+        }
+
+        rc = pGuestSession->init(this, startupInfo, guestCredentials);
+        if (RT_FAILURE(rc)) throw rc;
+
+        /*
+         * Add session object to our session map. This is necessary
+         * before calling openSession because the guest calls back
+         * with the creation result of this session.
+         */
+        mData.mGuestSessions[uNewSessionID] = pGuestSession;
+
+        alock.release(); /* Release lock before firing off event. */
+
+        fireGuestSessionRegisteredEvent(mEventSource, pGuestSession,
+                                        true /* Registered */);
+    }
+    catch (int rc2)
+    {
+        rc = rc2;
+    }
+
+    LogFlowFuncLeaveRC(rc);
+    return rc;
+}
+
+inline bool Guest::i_sessionExists(uint32_t uSessionID)
+{
+    GuestSessions::const_iterator itSessions = mData.mGuestSessions.find(uSessionID);
+    return (itSessions == mData.mGuestSessions.end()) ? false : true;
+}
+
 #endif /* VBOX_WITH_GUEST_CONTROL */
+
+
+// implementation of public methods
+/////////////////////////////////////////////////////////////////////////////
+HRESULT Guest::createSession(const com::Utf8Str &aUser, const com::Utf8Str &aPassword, const com::Utf8Str &aDomain,
+                             const com::Utf8Str &aSessionName, ComPtr<IGuestSession> &aGuestSession)
+
+{
+#ifndef VBOX_WITH_GUEST_CONTROL
+    ReturnComNotImplemented();
+#else /* VBOX_WITH_GUEST_CONTROL */
+
+    LogFlowFuncEnter();
+
+    /* Do not allow anonymous sessions (with system rights) with public API. */
+    if (RT_UNLIKELY(!aUser.length()))
+        return setError(E_INVALIDARG, tr("No user name specified"));
+
+    GuestSessionStartupInfo startupInfo;
+    startupInfo.mName = aSessionName;
+
+    GuestCredentials guestCreds;
+    guestCreds.mUser = aUser;
+    guestCreds.mPassword = aPassword;
+    guestCreds.mDomain = aDomain;
+
+    ComObjPtr<GuestSession> pSession;
+    int rc = i_sessionCreate(startupInfo, guestCreds, pSession);
+    if (RT_SUCCESS(rc))
+    {
+        /* Return guest session to the caller. */
+        HRESULT hr2 = pSession.queryInterfaceTo(aGuestSession.asOutParam());
+        if (FAILED(hr2))
+            rc = VERR_COM_OBJECT_NOT_FOUND;
+    }
+
+    if (RT_SUCCESS(rc))
+        /* Start (fork) the session asynchronously
+         * on the guest. */
+        rc = pSession->i_startSessionAsync();
+
+    HRESULT hr = S_OK;
+
+    if (RT_FAILURE(rc))
+    {
+        switch (rc)
+        {
+            case VERR_MAX_PROCS_REACHED:
+                hr = setError(VBOX_E_IPRT_ERROR, tr("Maximum number of concurrent guest sessions (%ld) reached"),
+                              VBOX_GUESTCTRL_MAX_SESSIONS);
+                break;
+
+            /** @todo Add more errors here. */
+
+            default:
+                hr = setError(VBOX_E_IPRT_ERROR, tr("Could not create guest session: %Rrc"), rc);
+                break;
+        }
+    }
+
+    LogFlowThisFunc(("Returning rc=%Rhrc\n", hr));
+    return hr;
+#endif /* VBOX_WITH_GUEST_CONTROL */
+}
+
+HRESULT Guest::findSession(const com::Utf8Str &aSessionName, std::vector<ComPtr<IGuestSession> > &aSessions)
+{
+#ifndef VBOX_WITH_GUEST_CONTROL
+    ReturnComNotImplemented();
+#else /* VBOX_WITH_GUEST_CONTROL */
+
+    LogFlowFuncEnter();
+
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    Utf8Str strName(aSessionName);
+    std::list < ComObjPtr<GuestSession> > listSessions;
+
+    GuestSessions::const_iterator itSessions = mData.mGuestSessions.begin();
+    while (itSessions != mData.mGuestSessions.end())
+    {
+        if (strName.contains(itSessions->second->i_getName())) /** @todo Use a (simple) pattern match (IPRT?). */
+            listSessions.push_back(itSessions->second);
+        itSessions++;
+    }
+
+    LogFlowFunc(("Sessions with \"%s\" = %RU32\n",
+                 aSessionName.c_str(), listSessions.size()));
+
+    aSessions.resize(listSessions.size());
+    if (listSessions.size())
+    {
+        size_t i = 0;
+        for (std::list < ComObjPtr<GuestSession> >::const_iterator it = listSessions.begin(); it != listSessions.end(); ++it, ++i)
+            (*it).queryInterfaceTo(aSessions[i].asOutParam());
+
+        return S_OK;
+
+    }
+
+    return setErrorNoLog(VBOX_E_OBJECT_NOT_FOUND,
+                         tr("Could not find sessions with name '%s'"),
+                         aSessionName.c_str());
+#endif /* VBOX_WITH_GUEST_CONTROL */
+}
 
 HRESULT Guest::updateGuestAdditions(const com::Utf8Str &aSource, const std::vector<com::Utf8Str> &aArguments,
@@ -217,359 +578,2 @@
 }
 
-// private methods
-/////////////////////////////////////////////////////////////////////////////
-
-int Guest::i_dispatchToSession(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)
-{
-    LogFlowFunc(("pCtxCb=%p, pSvcCb=%p\n", pCtxCb, pSvcCb));
-
-    AssertPtrReturn(pCtxCb, VERR_INVALID_POINTER);
-    AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER);
-
-    LogFlowFunc(("uFunction=%RU32, uContextID=%RU32, uProtocol=%RU32\n",
-                  pCtxCb->uFunction, pCtxCb->uContextID, pCtxCb->uProtocol));
-
-    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    uint32_t uSessionID = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pCtxCb->uContextID);
-#ifdef DEBUG
-    LogFlowFunc(("uSessionID=%RU32 (%zu total)\n",
-                 uSessionID, mData.mGuestSessions.size()));
-#endif
-    GuestSessions::const_iterator itSession
-        = mData.mGuestSessions.find(uSessionID);
-
-    int rc;
-    if (itSession != mData.mGuestSessions.end())
-    {
-        ComObjPtr<GuestSession> pSession(itSession->second);
-        Assert(!pSession.isNull());
-
-        alock.release();
-
-        bool fDispatch = true;
-#ifdef DEBUG
-        /*
-         * Pre-check: If we got a status message with an error and VERR_TOO_MUCH_DATA
-         *            it means that that guest could not handle the entire message
-         *            because of its exceeding size. This should not happen on daily
-         *            use but testcases might try this. It then makes no sense to dispatch
-         *            this further because we don't have a valid context ID.
-         */
-        if (   pCtxCb->uFunction == GUEST_EXEC_STATUS
-            && pSvcCb->mParms    >= 5)
-        {
-            CALLBACKDATA_PROC_STATUS dataCb;
-            /* pSvcCb->mpaParms[0] always contains the context ID. */
-            pSvcCb->mpaParms[1].getUInt32(&dataCb.uPID);
-            pSvcCb->mpaParms[2].getUInt32(&dataCb.uStatus);
-            pSvcCb->mpaParms[3].getUInt32(&dataCb.uFlags);
-            pSvcCb->mpaParms[4].getPointer(&dataCb.pvData, &dataCb.cbData);
-
-            if (   (         dataCb.uStatus == PROC_STS_ERROR)
-                   /** @todo Note: Due to legacy reasons we cannot change uFlags to
-                    *              int32_t, so just cast it for now. */
-                && ((int32_t)dataCb.uFlags  == VERR_TOO_MUCH_DATA))
-            {
-                LogFlowFunc(("Requested command with too much data, skipping dispatching ...\n"));
-
-                Assert(dataCb.uPID == 0);
-                fDispatch = false;
-            }
-        }
-#endif
-        if (fDispatch)
-        {
-            switch (pCtxCb->uFunction)
-            {
-                case GUEST_DISCONNECTED:
-                    rc = pSession->i_dispatchToThis(pCtxCb, pSvcCb);
-                    break;
-
-                case GUEST_EXEC_STATUS:
-                case GUEST_EXEC_OUTPUT:
-                case GUEST_EXEC_INPUT_STATUS:
-                case GUEST_EXEC_IO_NOTIFY:
-                    rc = pSession->i_dispatchToProcess(pCtxCb, pSvcCb);
-                    break;
-
-                case GUEST_FILE_NOTIFY:
-                    rc = pSession->i_dispatchToFile(pCtxCb, pSvcCb);
-                    break;
-
-                case GUEST_SESSION_NOTIFY:
-                    rc = pSession->i_dispatchToThis(pCtxCb, pSvcCb);
-                    break;
-
-                default:
-                    /*
-                     * Try processing generic messages which might
-                     * (or might not) supported by certain objects.
-                     * If the message either is not found or supported
-                     * by the approprirate object, try handling it
-                     * in this session object.
-                     */
-                    rc = pSession->i_dispatchToObject(pCtxCb, pSvcCb);
-                    if (   rc == VERR_NOT_FOUND
-                        || rc == VERR_NOT_SUPPORTED)
-                    {
-                        alock.acquire();
-
-                        rc = pSession->dispatchGeneric(pCtxCb, pSvcCb);
-                    }
-#ifndef DEBUG_andy
-                    if (rc == VERR_NOT_IMPLEMENTED)
-                        AssertMsgFailed(("Received not handled function %RU32\n", pCtxCb->uFunction));
-#endif
-                    break;
-            }
-        }
-        else
-            rc = VERR_NOT_FOUND;
-    }
-    else
-        rc = VERR_NOT_FOUND;
-
-    LogFlowFuncLeaveRC(rc);
-    return rc;
-}
-
-int Guest::i_sessionRemove(GuestSession *pSession)
-{
-    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
-
-    LogFlowThisFuncEnter();
-
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    int rc = VERR_NOT_FOUND;
-
-    LogFlowThisFunc(("Removing session (ID=%RU32) ...\n", pSession->i_getId()));
-
-    GuestSessions::iterator itSessions = mData.mGuestSessions.begin();
-    while (itSessions != mData.mGuestSessions.end())
-    {
-        if (pSession == itSessions->second)
-        {
-#ifdef DEBUG_andy
-            ULONG cRefs = pSession->AddRef();
-            Assert(cRefs >= 2);
-            LogFlowThisFunc(("pCurSession=%p, cRefs=%RU32\n", pSession, cRefs - 2));
-            pSession->Release();
-#endif
-            /* Make sure to consume the pointer before the one of the
-             * iterator gets released. */
-            ComObjPtr<GuestSession> pCurSession = pSession;
-
-            LogFlowThisFunc(("Removing session (pSession=%p, ID=%RU32) (now total %ld sessions)\n",
-                             pSession, pSession->i_getId(), mData.mGuestSessions.size() - 1));
-
-            rc = pSession->i_onRemove();
-            mData.mGuestSessions.erase(itSessions);
-
-            alock.release(); /* Release lock before firing off event. */
-
-            fireGuestSessionRegisteredEvent(mEventSource, pCurSession,
-                                            false /* Unregistered */);
-            pCurSession.setNull();
-            break;
-        }
-
-        itSessions++;
-    }
-
-    LogFlowFuncLeaveRC(rc);
-    return rc;
-}
-
-int Guest::i_sessionCreate(const GuestSessionStartupInfo &ssInfo,
-                           const GuestCredentials &guestCreds, ComObjPtr<GuestSession> &pGuestSession)
-{
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    int rc = VERR_MAX_PROCS_REACHED;
-    if (mData.mGuestSessions.size() >= VBOX_GUESTCTRL_MAX_SESSIONS)
-        return rc;
-
-    try
-    {
-        /* Create a new session ID and assign it. */
-        uint32_t uNewSessionID = VBOX_GUESTCTRL_SESSION_ID_BASE;
-        uint32_t uTries = 0;
-
-        for (;;)
-        {
-            /* Is the context ID already used? */
-            if (!i_sessionExists(uNewSessionID))
-            {
-                rc = VINF_SUCCESS;
-                break;
-            }
-            uNewSessionID++;
-            if (uNewSessionID >= VBOX_GUESTCTRL_MAX_SESSIONS)
-                uNewSessionID = VBOX_GUESTCTRL_SESSION_ID_BASE;
-
-            if (++uTries == VBOX_GUESTCTRL_MAX_SESSIONS)
-                break; /* Don't try too hard. */
-        }
-        if (RT_FAILURE(rc)) throw rc;
-
-        /* Create the session object. */
-        HRESULT hr = pGuestSession.createObject();
-        if (FAILED(hr)) throw VERR_COM_UNEXPECTED;
-
-        /** @todo Use an overloaded copy operator. Later. */
-        GuestSessionStartupInfo startupInfo;
-        startupInfo.mID = uNewSessionID; /* Assign new session ID. */
-        startupInfo.mName = ssInfo.mName;
-        startupInfo.mOpenFlags = ssInfo.mOpenFlags;
-        startupInfo.mOpenTimeoutMS = ssInfo.mOpenTimeoutMS;
-
-        GuestCredentials guestCredentials;
-        if (!guestCreds.mUser.isEmpty())
-        {
-            /** @todo Use an overloaded copy operator. Later. */
-            guestCredentials.mUser = guestCreds.mUser;
-            guestCredentials.mPassword = guestCreds.mPassword;
-            guestCredentials.mDomain = guestCreds.mDomain;
-        }
-        else
-        {
-            /* Internal (annonymous) session. */
-            startupInfo.mIsInternal = true;
-        }
-
-        rc = pGuestSession->init(this, startupInfo, guestCredentials);
-        if (RT_FAILURE(rc)) throw rc;
-
-        /*
-         * Add session object to our session map. This is necessary
-         * before calling openSession because the guest calls back
-         * with the creation result of this session.
-         */
-        mData.mGuestSessions[uNewSessionID] = pGuestSession;
-
-        alock.release(); /* Release lock before firing off event. */
-
-        fireGuestSessionRegisteredEvent(mEventSource, pGuestSession,
-                                        true /* Registered */);
-    }
-    catch (int rc2)
-    {
-        rc = rc2;
-    }
-
-    LogFlowFuncLeaveRC(rc);
-    return rc;
-}
-
-inline bool Guest::i_sessionExists(uint32_t uSessionID)
-{
-    GuestSessions::const_iterator itSessions = mData.mGuestSessions.find(uSessionID);
-    return (itSessions == mData.mGuestSessions.end()) ? false : true;
-}
-
-// implementation of public methods
-/////////////////////////////////////////////////////////////////////////////
-HRESULT Guest::createSession(const com::Utf8Str &aUser, const com::Utf8Str &aPassword, const com::Utf8Str &aDomain,
-                             const com::Utf8Str &aSessionName, ComPtr<IGuestSession> &aGuestSession)
-
-{
-#ifndef VBOX_WITH_GUEST_CONTROL
-    ReturnComNotImplemented();
-#else /* VBOX_WITH_GUEST_CONTROL */
-
-    LogFlowFuncEnter();
-
-    /* Do not allow anonymous sessions (with system rights) with public API. */
-    if (RT_UNLIKELY(!aUser.length()))
-        return setError(E_INVALIDARG, tr("No user name specified"));
-
-    GuestSessionStartupInfo startupInfo;
-    startupInfo.mName = aSessionName;
-
-    GuestCredentials guestCreds;
-    guestCreds.mUser = aUser;
-    guestCreds.mPassword = aPassword;
-    guestCreds.mDomain = aDomain;
-
-    ComObjPtr<GuestSession> pSession;
-    int rc = i_sessionCreate(startupInfo, guestCreds, pSession);
-    if (RT_SUCCESS(rc))
-    {
-        /* Return guest session to the caller. */
-        HRESULT hr2 = pSession.queryInterfaceTo(aGuestSession.asOutParam());
-        if (FAILED(hr2))
-            rc = VERR_COM_OBJECT_NOT_FOUND;
-    }
-
-    if (RT_SUCCESS(rc))
-        /* Start (fork) the session asynchronously
-         * on the guest. */
-        rc = pSession->i_startSessionAsync();
-
-    HRESULT hr = S_OK;
-
-    if (RT_FAILURE(rc))
-    {
-        switch (rc)
-        {
-            case VERR_MAX_PROCS_REACHED:
-                hr = setError(VBOX_E_IPRT_ERROR, tr("Maximum number of concurrent guest sessions (%ld) reached"),
-                              VBOX_GUESTCTRL_MAX_SESSIONS);
-                break;
-
-            /** @todo Add more errors here. */
-
-            default:
-                hr = setError(VBOX_E_IPRT_ERROR, tr("Could not create guest session: %Rrc"), rc);
-                break;
-        }
-    }
-
-    LogFlowThisFunc(("Returning rc=%Rhrc\n", hr));
-    return hr;
-#endif /* VBOX_WITH_GUEST_CONTROL */
-}
-
-HRESULT Guest::findSession(const com::Utf8Str &aSessionName, std::vector<ComPtr<IGuestSession> > &aSessions)
-{
-#ifndef VBOX_WITH_GUEST_CONTROL
-    ReturnComNotImplemented();
-#else /* VBOX_WITH_GUEST_CONTROL */
-
-    LogFlowFuncEnter();
-
-    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    Utf8Str strName(aSessionName);
-    std::list < ComObjPtr<GuestSession> > listSessions;
-
-    GuestSessions::const_iterator itSessions = mData.mGuestSessions.begin();
-    while (itSessions != mData.mGuestSessions.end())
-    {
-        if (strName.contains(itSessions->second->i_getName())) /** @todo Use a (simple) pattern match (IPRT?). */
-            listSessions.push_back(itSessions->second);
-        itSessions++;
-    }
-
-    LogFlowFunc(("Sessions with \"%s\" = %RU32\n",
-                 aSessionName.c_str(), listSessions.size()));
-
-    aSessions.resize(listSessions.size());
-    if (listSessions.size())
-    {
-        size_t i = 0;
-        for (std::list < ComObjPtr<GuestSession> >::const_iterator it = listSessions.begin(); it != listSessions.end(); ++it, ++i)
-            (*it).queryInterfaceTo(aSessions[i].asOutParam());
-
-        return S_OK;
-
-    }
-
-    return setErrorNoLog(VBOX_E_OBJECT_NOT_FOUND,
-                         tr("Could not find sessions with name '%s'"),
-                         aSessionName.c_str());
-#endif /* VBOX_WITH_GUEST_CONTROL */
-}
-
Index: /trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp	(revision 55643)
+++ /trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp	(revision 55644)
@@ -19,4 +19,7 @@
  *   Header Files                                                             *
  ******************************************************************************/
+#ifndef VBOX_WITH_GUEST_CONTROL
+# error "VBOX_WITH_GUEST_CONTROL must defined in this file"
+#endif
 #include "GuestCtrlImplPrivate.h"
 #include "GuestSessionImpl.h"
Index: /trunk/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp	(revision 55643)
+++ /trunk/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp	(revision 55644)
@@ -23,8 +23,10 @@
 #include "GuestDnDSourceImpl.h"
 #include "GuestDnDPrivate.h"
+#include "ConsoleImpl.h"
 
 #include "Global.h"
 #include "AutoCaller.h"
 
+#include <iprt/asm.h>
 #include <iprt/dir.h>
 #include <iprt/file.h>
Index: /trunk/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp	(revision 55643)
+++ /trunk/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp	(revision 55644)
@@ -22,4 +22,5 @@
 #include "GuestImpl.h"
 #include "GuestDnDTargetImpl.h"
+#include "ConsoleImpl.h"
 
 #include "Global.h"
@@ -28,4 +29,5 @@
 #include <algorithm>        /* For std::find(). */
 
+#include <iprt/asm.h>
 #include <iprt/file.h>
 #include <iprt/dir.h>
Index: /trunk/src/VBox/Main/src-client/GuestImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/GuestImpl.cpp	(revision 55643)
+++ /trunk/src/VBox/Main/src-client/GuestImpl.cpp	(revision 55644)
@@ -17,6 +17,7 @@
 
 #include "GuestImpl.h"
-#include "GuestSessionImpl.h"
-
+#ifdef VBOX_WITH_GUEST_CONTROL
+# include "GuestSessionImpl.h"
+#endif
 #include "Global.h"
 #include "ConsoleImpl.h"
@@ -109,11 +110,7 @@
     AssertMsgRC(vrc, ("Failed to create guest statistics update timer (%Rrc)\n", vrc));
 
-#ifdef VBOX_WITH_GUEST_CONTROL
     hr = unconst(mEventSource).createObject();
     if (SUCCEEDED(hr))
         hr = mEventSource->init();
-#else
-    hr = S_OK;
-#endif
 
 #ifdef VBOX_WITH_DRAG_AND_DROP
@@ -185,7 +182,5 @@
 #endif
 
-#ifdef VBOX_WITH_GUEST_CONTROL
     unconst(mEventSource).setNull();
-#endif
     unconst(mParent) = NULL;
 
@@ -517,7 +512,4 @@
 HRESULT Guest::getEventSource(ComPtr<IEventSource> &aEventSource)
 {
-#ifndef VBOX_WITH_GUEST_CONTROL
-    ReturnComNotImplemented();
-#else
     LogFlowThisFuncEnter();
 
@@ -527,5 +519,4 @@
     LogFlowFuncLeaveRC(S_OK);
     return S_OK;
-#endif /* VBOX_WITH_GUEST_CONTROL */
 }
 
@@ -544,4 +535,5 @@
 HRESULT Guest::getSessions(std::vector<ComPtr<IGuestSession> > &aSessions)
 {
+#ifdef VBOX_WITH_GUEST_CONTROL
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -552,4 +544,7 @@
 
     return S_OK;
+#else
+    ReturnComNotImplemented();
+#endif
 }
 
@@ -997,9 +992,9 @@
  * @param   aDomain             Domain of guest user account. Optional.
  * @param   enmState            New state to indicate.
- * @param   puDetails           Pointer to state details. Optional.
+ * @param   pbDetails           Pointer to state details. Optional.
  * @param   cbDetails           Size (in bytes) of state details. Pass 0 if not used.
  */
 void Guest::i_onUserStateChange(Bstr aUser, Bstr aDomain, VBoxGuestUserState enmState,
-                                const uint8_t *puDetails, uint32_t cbDetails)
+                                const uint8_t *pbDetails, uint32_t cbDetails)
 {
     LogFlowThisFunc(("\n"));
Index: /trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp	(revision 55643)
+++ /trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp	(revision 55644)
@@ -21,4 +21,7 @@
 *******************************************************************************/
 #include "GuestImpl.h"
+#ifndef VBOX_WITH_GUEST_CONTROL
+# error "VBOX_WITH_GUEST_CONTROL must defined in this file"
+#endif
 #include "GuestSessionImpl.h"
 #include "GuestCtrlImplPrivate.h"
