Index: trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
===================================================================
--- trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp	(revision 35099)
+++ trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp	(revision 35100)
@@ -819,6 +819,33 @@
     if (!strcmp(a->argv[0], "install"))
     {
-        if (a->argc != 2)
-            return errorSyntax(USAGE_EXTPACK, "Incorrect number of parameters for \"extpack install\"");
+        const char *pszName  = NULL;
+        bool        fReplace = false;
+
+        static const RTGETOPTDEF s_aInstallOptions[] =
+        {
+            { "--replace",  'r', RTGETOPT_REQ_NOTHING },
+        };
+
+        RTGetOptInit(&GetState, a->argc, a->argv, s_aInstallOptions, RT_ELEMENTS(s_aInstallOptions), 1, 0 /*fFlags*/);
+        while ((ch = RTGetOpt(&GetState, &ValueUnion)))
+        {
+            switch (ch)
+            {
+                case 'f':
+                    fReplace = true;
+                    break;
+
+                case VINF_GETOPT_NOT_OPTION:
+                    if (pszName)
+                        return errorSyntax(USAGE_EXTPACK, "Too many extension pack names given to \"extpack uninstall\"");
+                    pszName = ValueUnion.psz;
+                    break;
+
+                default:
+                    return errorGetOpt(USAGE_EXTPACK, ch, &ValueUnion);
+            }
+        }
+        if (!pszName)
+            return errorSyntax(USAGE_EXTPACK, "No extension pack name was given to \"extpack install\"");
 
         char szPath[RTPATH_MAX];
@@ -832,5 +859,5 @@
         CHECK_ERROR2_RET(ptrExtPackMgr, OpenExtPackFile(bstrTarball.raw(), ptrExtPackFile.asOutParam()), RTEXITCODE_FAILURE);
         CHECK_ERROR2_RET(ptrExtPackFile, COMGETTER(Name)(bstrName.asOutParam()), RTEXITCODE_FAILURE);
-        CHECK_ERROR2_RET(ptrExtPackFile, Install(), RTEXITCODE_FAILURE);
+        CHECK_ERROR2_RET(ptrExtPackFile, Install(fReplace), RTEXITCODE_FAILURE);
         RTPrintf("Successfully installed \"%lS\".\n", bstrName.raw());
     }
@@ -845,6 +872,5 @@
         };
 
-        RTGetOptInit(&GetState, a->argc, a->argv, s_aUninstallOptions, RT_ELEMENTS(s_aUninstallOptions),
-                     1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+        RTGetOptInit(&GetState, a->argc, a->argv, s_aUninstallOptions, RT_ELEMENTS(s_aUninstallOptions), 1, 0);
         while ((ch = RTGetOpt(&GetState, &ValueUnion)))
         {
Index: trunk/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsExtension.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsExtension.cpp	(revision 35099)
+++ trunk/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsExtension.cpp	(revision 35100)
@@ -144,6 +144,6 @@
      */
     CExtPack extPackCur = manager.Find(strPackName);
-    bool fUninstallIt = extPackCur.isOk();
-    if (fUninstallIt)
+    bool fReplaceIt = extPackCur.isOk();
+    if (fReplaceIt)
     {
         QString strPackVersionCur = QString("%1r%2").arg(extPackCur.GetVersion()).arg(extPackCur.GetRevision());
@@ -172,30 +172,17 @@
 
     /*
-     * Perform uninstallation of any previous package.
+     * Install the selected package.
      *
      * Set the package name return value before doing this as the caller should
      * do a refresh even on failure.
      */
-    if (pstrExtPackName)
-        *pstrExtPackName = strPackName;
-    if (fUninstallIt)
-    {
-        /** @todo Refuse this if any VMs are running. */
-        manager.Uninstall(strPackName, false /*aForcedRemoval*/);
-        if (!extPackFile.isOk())
-        {
-            vboxProblem().cannotUninstallExtPack(strFilePath, manager, pParent);
-            return;
-        }
-    }
-
-    /*
-     * Install the selected package.
-     */
-    extPackFile.Install();
+    extPackFile.Install(fReplaceIt);
     if (extPackFile.isOk())
         vboxProblem().notifyAboutExtPackInstalled(strPackName, pParent);
     else
         vboxProblem().cannotInstallExtPack(strFilePath, extPackFile, pParent);
+
+    if (pstrExtPackName)
+        *pstrExtPackName = strPackName;
 }
 
Index: trunk/src/VBox/Main/ExtPackManagerImpl.cpp
===================================================================
--- trunk/src/VBox/Main/ExtPackManagerImpl.cpp	(revision 35099)
+++ trunk/src/VBox/Main/ExtPackManagerImpl.cpp	(revision 35100)
@@ -580,5 +580,5 @@
 }
 
-STDMETHODIMP ExtPackFile::Install(void)
+STDMETHODIMP ExtPackFile::Install(BOOL a_fReplace)
 {
     AutoCaller autoCaller(this);
@@ -587,5 +587,5 @@
     {
         if (m->fUsable)
-            hrc = m->ptrExtPackMgr->doInstall(this);
+            hrc = m->ptrExtPackMgr->doInstall(this, RT_BOOL(a_fReplace));
         else
             hrc = setError(E_FAIL, "%s", m->strWhyUnusable.c_str());
@@ -1062,5 +1062,12 @@
     if (m->fUsable)
     {
-        /** @todo not important, so it can wait. */
+        if (m->hMainMod == NIL_RTLDRMOD)
+            probeAndLoad();
+        else if (   !objinfoIsEqual(&ObjInfoDesc,    &m->ObjInfoDesc)
+                 || !objinfoIsEqual(&ObjInfoMainMod, &m->ObjInfoMainMod)
+                 || !objinfoIsEqual(&ObjInfoExtPack, &m->ObjInfoExtPack) )
+        {
+            /** @todo not important, so it can wait. */
+        }
     }
     /*
@@ -1918,5 +1925,5 @@
          */
         ExtPack *pExtPack;
-        hrc = refreshExtPack(strName.c_str(), false /*a_fUnsuableIsError*/, &pExtPack);
+        hrc = refreshExtPack(strName.c_str(), false /*a_fUnusableIsError*/, &pExtPack);
         if (SUCCEEDED(hrc))
         {
@@ -1949,5 +1956,5 @@
                     if (SUCCEEDED(hrc))
                     {
-                        hrc = refreshExtPack(strName.c_str(), false /*a_fUnsuableIsError*/, &pExtPack);
+                        hrc = refreshExtPack(strName.c_str(), false /*a_fUnusableIsError*/, &pExtPack);
                         if (SUCCEEDED(hrc))
                         {
@@ -1963,5 +1970,5 @@
                     {
                         ErrorInfoKeeper Eik;
-                        refreshExtPack(strName.c_str(), false /*a_fUnsuableIsError*/, NULL);
+                        refreshExtPack(strName.c_str(), false /*a_fUnusableIsError*/, NULL);
                     }
                 }
@@ -2291,5 +2298,5 @@
  *
  * @param   a_pszName           The extension to update..
- * @param   a_fUnsuableIsError  If @c true, report an unusable extension pack
+ * @param   a_fUnusableIsError  If @c true, report an unusable extension pack
  *                              as an error.
  * @param   a_ppExtPack         Where to store the pointer to the extension
@@ -2300,5 +2307,5 @@
  * @remarks Only called in VBoxSVC.
  */
-HRESULT ExtPackManager::refreshExtPack(const char *a_pszName, bool a_fUnsuableIsError, ExtPack **a_ppExtPack)
+HRESULT ExtPackManager::refreshExtPack(const char *a_pszName, bool a_fUnusableIsError, ExtPack **a_ppExtPack)
 {
     Assert(m->pVirtualBox != NULL); /* Only called from VBoxSVC. */
@@ -2397,5 +2404,5 @@
     if (   SUCCEEDED(hrc)
         && pExtPack
-        && a_fUnsuableIsError
+        && a_fUnusableIsError
         && !pExtPack->m->fUsable)
         hrc = setError(E_FAIL, "%s", pExtPack->m->strWhyUnusable.c_str());
@@ -2412,6 +2419,8 @@
  * @param   a_pExtPackFile  The extension pack file, caller checks that it's
  *                          usable.
- */
-HRESULT ExtPackManager::doInstall(ExtPackFile *a_pExtPackFile)
+ * @param   a_fReplace      Whether to replace any existing extpack or just
+ *                          fail.
+ */
+HRESULT ExtPackManager::doInstall(ExtPackFile *a_pExtPackFile, bool a_fReplace)
 {
     AssertReturn(m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON, E_UNEXPECTED);
@@ -2430,6 +2439,16 @@
          */
         ExtPack *pExtPack;
-        hrc = refreshExtPack(pStrName->c_str(), false /*a_fUnsuableIsError*/, &pExtPack);
-        if (SUCCEEDED(hrc) && !pExtPack)
+        hrc = refreshExtPack(pStrName->c_str(), false /*a_fUnusableIsError*/, &pExtPack);
+        if (SUCCEEDED(hrc))
+        {
+            if (pExtPack && a_fReplace)
+                hrc = pExtPack->callUninstallHookAndClose(m->pVirtualBox, false /*a_ForcedRemoval*/);
+            else if (pExtPack)
+                hrc = setError(E_FAIL,
+                               tr("Extension pack '%s' is already installed."
+                                  " In case of a reinstallation, please uninstall it first"),
+                               pStrName->c_str());
+        }
+        if (SUCCEEDED(hrc))
         {
             /*
@@ -2438,5 +2457,5 @@
              * even on failure, to be on the safe side).
              */
-/** @todo add a hash (SHA-256) of the tarball or maybe just the manifest. */
+            /** @todo add a hash (SHA-256) of the tarball or maybe just the manifest. */
             hrc = runSetUidToRootHelper("install",
                                         "--base-dir",   m->strBaseDir.c_str(),
@@ -2444,8 +2463,9 @@
                                         "--name",       pStrName->c_str(),
                                         "--tarball",    pStrTarball->c_str(),
+                                        pExtPack ? "--replace" : (const char *)NULL,
                                         (const char *)NULL);
             if (SUCCEEDED(hrc))
             {
-                hrc = refreshExtPack(pStrName->c_str(), true /*a_fUnsuableIsError*/, &pExtPack);
+                hrc = refreshExtPack(pStrName->c_str(), true /*a_fUnusableIsError*/, &pExtPack);
                 if (SUCCEEDED(hrc))
                 {
@@ -2457,12 +2477,7 @@
             {
                 ErrorInfoKeeper Eik;
-                refreshExtPack(pStrName->c_str(), false /*a_fUnsuableIsError*/, NULL);
+                refreshExtPack(pStrName->c_str(), false /*a_fUnusableIsError*/, NULL);
             }
         }
-        else if (SUCCEEDED(hrc))
-            hrc = setError(E_FAIL,
-                           tr("Extension pack '%s' is already installed."
-                              " In case of a reinstallation, please uninstall it first"),
-                           pStrName->c_str());
 
         /*
Index: trunk/src/VBox/Main/VBoxExtPackHelperApp.cpp
===================================================================
--- trunk/src/VBox/Main/VBoxExtPackHelperApp.cpp	(revision 35099)
+++ trunk/src/VBox/Main/VBoxExtPackHelperApp.cpp	(revision 35100)
@@ -195,4 +195,30 @@
                               fTemporary ? "temporary " : "", rc, pszDir);
     return RTEXITCODE_SUCCESS;
+}
+
+
+/**
+ * Common uninstall worker used by both uninstall and install --replace.
+ *
+ * @returns success or failure, message displayed on failure.
+ * @param   pszExtPackDir   The extension pack directory name.
+ */
+static RTEXITCODE CommonUninstallWorker(const char *pszExtPackDir)
+{
+    /* Rename the extension pack directory before deleting it to prevent new
+       VM processes from picking it up. */
+    char szExtPackUnInstDir[RTPATH_MAX];
+    int rc = RTStrCopy(szExtPackUnInstDir, sizeof(szExtPackUnInstDir), pszExtPackDir);
+    if (RT_SUCCESS(rc))
+        rc = RTStrCat(szExtPackUnInstDir, sizeof(szExtPackUnInstDir), "-_-uninst");
+    if (RT_FAILURE(rc))
+        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to construct temporary extension pack path: %Rrc", rc);
+
+    rc = RTDirRename(pszExtPackDir, szExtPackUnInstDir, RTPATHRENAME_FLAGS_NO_REPLACE);
+    if (RT_FAILURE(rc))
+        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to rename the extension pack directory: %Rrc", rc);
+
+    /* Recursively delete the directory content. */
+    return RemoveExtPackDir(szExtPackUnInstDir, false /*fTemporary*/);
 }
 
@@ -565,8 +591,9 @@
  * @param   pszName             The extension pack name.
  * @param   pszMangledName      The mangled extension pack name.
+ * @param   fReplace            Whether to replace any existing ext pack.
  */
 static RTEXITCODE DoInstall2(const char *pszBaseDir, const char *pszCertDir, const char *pszTarball,
                              RTFILE hTarballFile, RTFILE hTarballFileOpt,
-                             const char *pszName, const char *pszMangledName)
+                             const char *pszName, const char *pszMangledName, bool fReplace)
 {
     /*
@@ -612,17 +639,21 @@
 
     /*
-     * Check that they don't exist at this point in time.
-     */
-    rc = RTPathQueryInfoEx(szFinalPath, &ObjInfo, RTFSOBJATTRADD_NOTHING,  RTPATH_F_ON_LINK);
+     * Check that they don't exist at this point in time, unless fReplace=true.
+     */
+    rc = RTPathQueryInfoEx(szFinalPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
     if (RT_SUCCESS(rc) && RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode))
-        return RTMsgErrorExit(RTEXITCODE_FAILURE, "The extension pack is already installed. You must uninstall the old one first.");
-    if (RT_SUCCESS(rc))
+    {
+        if (!fReplace)
+            return RTMsgErrorExit(RTEXITCODE_FAILURE,
+                                  "The extension pack is already installed. You must uninstall the old one first.");
+    }
+    else if (RT_SUCCESS(rc))
         return RTMsgErrorExit(RTEXITCODE_FAILURE,
                               "Found non-directory file system object where the extension pack would be installed ('%s')",
                               szFinalPath);
-    if (rc != VERR_FILE_NOT_FOUND && rc != VERR_PATH_NOT_FOUND)
+    else if (rc != VERR_FILE_NOT_FOUND && rc != VERR_PATH_NOT_FOUND)
         return RTMsgErrorExit(RTEXITCODE_FAILURE, "Unexpected RTPathQueryInfoEx status code %Rrc for '%s'", rc, szFinalPath);
 
-    rc = RTPathQueryInfoEx(szTmpPath, &ObjInfo, RTFSOBJATTRADD_NOTHING,  RTPATH_F_ON_LINK);
+    rc = RTPathQueryInfoEx(szTmpPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
     if (rc != VERR_FILE_NOT_FOUND && rc != VERR_PATH_NOT_FOUND)
         return RTMsgErrorExit(RTEXITCODE_FAILURE, "Unexpected RTPathQueryInfoEx status code %Rrc for '%s'", rc, szFinalPath);
@@ -650,7 +681,16 @@
     {
         rc = RTDirRename(szTmpPath, szFinalPath, RTPATHRENAME_FLAGS_NO_REPLACE);
+        if (   RT_FAILURE(rc)
+            && fReplace
+            && RTDirExists(szFinalPath))
+        {
+            /* Automatic uninstall if --replace was given. */
+            rcExit = CommonUninstallWorker(szFinalPath);
+            if (rcExit == RTEXITCODE_SUCCESS)
+                rc = RTDirRename(szTmpPath, szFinalPath, RTPATHRENAME_FLAGS_NO_REPLACE);
+        }
         if (RT_SUCCESS(rc))
             RTMsgInfo("Successfully installed '%s' (%s)", pszName, pszTarball);
-        else
+        else if (rcExit == RTEXITCODE_SUCCESS)
             rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE,
                                     "Failed to rename the temporary directory to the final one: %Rrc ('%s' -> '%s')",
@@ -688,9 +728,10 @@
     static const RTGETOPTDEF s_aOptions[] =
     {
-        { "--base-dir",     'b',   RTGETOPT_REQ_STRING },
-        { "--cert-dir",     'c',   RTGETOPT_REQ_STRING },
-        { "--name",         'n',   RTGETOPT_REQ_STRING },
-        { "--tarball",      't',   RTGETOPT_REQ_STRING },
-        { "--tarball-fd",   'd',   RTGETOPT_REQ_UINT64 }
+        { "--base-dir",     'b',   RTGETOPT_REQ_STRING  },
+        { "--cert-dir",     'c',   RTGETOPT_REQ_STRING  },
+        { "--name",         'n',   RTGETOPT_REQ_STRING  },
+        { "--tarball",      't',   RTGETOPT_REQ_STRING  },
+        { "--tarball-fd",   'd',   RTGETOPT_REQ_UINT64  },
+        { "--replace",      'r',   RTGETOPT_REQ_NOTHING }
     };
     RTGETOPTSTATE   GetState;
@@ -704,4 +745,5 @@
     const char     *pszTarball      = NULL;
     RTFILE          hTarballFileOpt = NIL_RTFILE;
+    bool            fReplace        = false;
     RTGETOPTUNION   ValueUnion;
     int             ch;
@@ -753,4 +795,8 @@
             }
 
+            case 'r':
+                fReplace = true;
+                break;
+
             case 'h':
             case 'V':
@@ -783,5 +829,5 @@
     {
         rcExit = DoInstall2(pszBaseDir, pszCertDir, pszTarball, hTarballFile, hTarballFileOpt,
-                            pszName, pstrMangledName->c_str());
+                            pszName, pstrMangledName->c_str(), fReplace);
         RTFileClose(hTarballFile);
     }
@@ -880,19 +926,5 @@
     }
 
-    /* Rename the extension pack directory before deleting it to prevent new
-       VM processes from picking it up. */
-    char szExtPackUnInstDir[RTPATH_MAX];
-    rc = RTPathJoin(szExtPackUnInstDir, sizeof(szExtPackUnInstDir), pszBaseDir, strMangledName.c_str());
-    if (RT_SUCCESS(rc))
-        rc = RTStrCat(szExtPackUnInstDir, sizeof(szExtPackUnInstDir), "-_-uninst");
-    if (RT_FAILURE(rc))
-        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to construct temporary extension pack path: %Rrc", rc);
-
-    rc = RTDirRename(szExtPackDir, szExtPackUnInstDir, RTPATHRENAME_FLAGS_NO_REPLACE);
-    if (RT_FAILURE(rc))
-        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to rename the extension pack directory: %Rrc", rc);
-
-    /* Recursively delete the directory content. */
-    RTEXITCODE rcExit = RemoveExtPackDir(szExtPackUnInstDir, false /*fTemporary*/);
+    RTEXITCODE rcExit = CommonUninstallWorker(szExtPackDir);
     if (rcExit == RTEXITCODE_SUCCESS)
         RTMsgInfo("Successfully removed extension pack '%s'\n", pszName);
Index: trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 35099)
+++ trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 35100)
@@ -14476,5 +14476,5 @@
   <interface
     name="IExtPackFile" extends="IExtPackBase"
-    uuid="e57e5ab7-e0e8-4a55-9241-afa7ad219911"
+    uuid="64b65bda-eedf-442c-9fd2-d179a021031a"
     wsmap="suppress"
     >
@@ -14495,4 +14495,10 @@
         Install the extension pack.
       </desc>
+      <param name="replace" type="boolean" dir="in">
+        <desc>
+          Set this to automatically uninstall any existing extension pack with
+          the same name as the one being installed.
+        </desc>
+      </param>
     </method>
   </interface>
Index: trunk/src/VBox/Main/include/ExtPackManagerImpl.h
===================================================================
--- trunk/src/VBox/Main/include/ExtPackManagerImpl.h	(revision 35099)
+++ trunk/src/VBox/Main/include/ExtPackManagerImpl.h	(revision 35100)
@@ -70,5 +70,5 @@
      * @{ */
     STDMETHOD(COMGETTER(FilePath))(BSTR *a_pbstrPath);
-    STDMETHOD(Install)(void);
+    STDMETHOD(Install)(BOOL a_fReplace);
     /** @}  */
 
@@ -219,5 +219,5 @@
     /** @name Internal interfaces used by other Main classes.
      * @{ */
-    HRESULT     doInstall(ExtPackFile *a_pExtPackFile);
+    HRESULT     doInstall(ExtPackFile *a_pExtPackFile, bool a_fReplace);
     void        callAllVirtualBoxReadyHooks(void);
     void        callAllConsoleReadyHooks(IConsole *a_pConsole);
