Index: /trunk/doc/manual/en_US/user_VBoxManage.xml
===================================================================
--- /trunk/doc/manual/en_US/user_VBoxManage.xml	(revision 74002)
+++ /trunk/doc/manual/en_US/user_VBoxManage.xml	(revision 74003)
@@ -5152,5 +5152,6 @@
                          [--compact]
                          [--resize &lt;megabytes&gt;|--resizebyte &lt;bytes&gt;]
-                         [--move &lt;path&gt;</screen>
+                         [--move &lt;path&gt;]
+                         [--setlocation &lt;path&gt;]</screen>
 
       <note>
@@ -5277,4 +5278,19 @@
         </para>
       </listitem>
+
+     <listitem>
+       <para>
+         The <computeroutput>--setlocation &lt;path&gt;</computeroutput>
+         option can be used to set new location &lt;path&gt; of the
+         medium on the host file system if the medium had been moved
+         for any reasons. The path can be either relative to the
+         current directory or absolute.
+       </para>
+
+       <para>
+         Note, the new location is used as is, without any sanity checks,
+         so user is responsible to set correct path.
+       </para>
+     </listitem>
 
     </itemizedlist>
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp	(revision 74002)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp	(revision 74003)
@@ -493,4 +493,5 @@
     { "--resizebyte",   'R', RTGETOPT_REQ_UINT64 },
     { "--move",         'm', RTGETOPT_REQ_STRING },
+    { "--setlocation",  'l', RTGETOPT_REQ_STRING },
     { "--description",  'd', RTGETOPT_REQ_STRING }
 };
@@ -517,6 +518,7 @@
     bool fModifyResize = false;
     bool fModifyResizeMB = false;
-    bool fModifyLocation = false;
+    bool fMoveMedium = false;
     bool fModifyDescription = false;
+    bool fSetNewLocation = false;
     uint64_t cbResize = 0;
     const char *pszFilenameOrUuid = NULL;
@@ -615,5 +617,11 @@
                 /* Get a new location  */
                 pszNewLocation = RTPathAbsDup(ValueUnion.psz);
-                fModifyLocation = true;
+                fMoveMedium = true;
+                break;
+
+            case 'l':   // --setlocation
+                /* Get a new location  */
+                pszNewLocation = RTPathAbsDup(ValueUnion.psz);
+                fSetNewLocation = true;
                 break;
 
@@ -659,6 +667,8 @@
         && !fModifyCompact
         && !fModifyResize
-        && !fModifyLocation
-        && !fModifyDescription)
+        && !fMoveMedium
+        && !fSetNewLocation
+        && !fModifyDescription
+        )
         return errorSyntax(USAGE_MODIFYMEDIUM, "No operation specified");
 
@@ -766,5 +776,5 @@
     }
 
-    if (fModifyLocation)
+    if (fMoveMedium)
     {
         do
@@ -773,5 +783,5 @@
             Utf8Str strLocation(pszNewLocation);
             RTStrFree(pszNewLocation);
-            CHECK_ERROR(pMedium, SetLocation(Bstr(strLocation).raw(), pProgress.asOutParam()));
+            CHECK_ERROR(pMedium, MoveTo(Bstr(strLocation).raw(), pProgress.asOutParam()));
 
             if (SUCCEEDED(rc) && !pProgress.isNull())
@@ -784,14 +794,25 @@
             CHECK_ERROR_BREAK(pMedium, COMGETTER(Id)(uuid.asOutParam()));
 
-            RTPrintf("Move medium with UUID %s finished \n", Utf8Str(uuid).c_str());
+            RTPrintf("Move medium with UUID %s finished\n", Utf8Str(uuid).c_str());
         }
         while (0);
     }
 
+    if (fSetNewLocation)
+    {
+        Utf8Str strLocation(pszNewLocation);
+        RTStrFree(pszNewLocation);
+        CHECK_ERROR(pMedium, COMSETTER(Location)(Bstr(strLocation).raw()));
+
+        Bstr uuid;
+        CHECK_ERROR(pMedium, COMGETTER(Id)(uuid.asOutParam()));
+        RTPrintf("Set new location of medium with UUID %s finished\n", Utf8Str(uuid).c_str());
+    }
+
     if (fModifyDescription)
     {
         CHECK_ERROR(pMedium, COMSETTER(Description)(Bstr(pszNewLocation).raw()));
 
-        RTPrintf("Medium description has been changed. \n");
+        RTPrintf("Medium description has been changed.\n");
     }
 
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 74002)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 74003)
@@ -982,5 +982,6 @@
                      "                            [--compact]\n"
                      "                            [--resize <megabytes>|--resizebyte <bytes>]\n"
-                     "                            [--move <path]\n"
+                     "                            [--move <path>]\n"
+                     "                            [--setlocation <path>]\n"
                      "                            [--description <description string>]"
                      "\n", SEP);
Index: /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumItem.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumItem.cpp	(revision 74002)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumItem.cpp	(revision 74003)
@@ -88,5 +88,5 @@
     {
         /* Prepare move storage progress: */
-        CProgress comProgress = comMedium.SetLocation(strFileName);
+        CProgress comProgress = comMedium.MoveTo(strFileName);
 
         /* Show error message if necessary: */
Index: /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.cpp	(revision 74002)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.cpp	(revision 74003)
@@ -310,5 +310,5 @@
     {
         /* Prepare move storage progress: */
-        CProgress comProgress = comMedium.SetLocation(newData.m_options.m_strLocation);
+        CProgress comProgress = comMedium.MoveTo(newData.m_options.m_strLocation);
 
         /* Show error message if necessary: */
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 74002)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 74003)
@@ -15030,5 +15030,5 @@
   <interface
     name="IMedium" extends="$unknown"
-    uuid="c3a390cd-4efa-458d-2afb-d07eb4e105bb"
+    uuid="a570ac5b-d90d-42bb-b577-a3e2697044e4"
     wsmap="managed"
     reservedMethods="4" reservedAttributes="8"
@@ -15245,5 +15245,5 @@
     </attribute>
 
-    <attribute name="location" type="wstring" readonly="yes">
+    <attribute name="location" type="wstring">
       <desc>
         Location of the storage unit holding medium data.
@@ -16160,5 +16160,5 @@
     <!-- other methods -->
 
-    <method name="setLocation" wrap-hint-server="passcaller">
+    <method name="moveTo" wrap-hint-server="passcaller">
       <desc>
         Changes the location of this medium. Some medium types may support
Index: /trunk/src/VBox/Main/include/MediumImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/MediumImpl.h	(revision 74002)
+++ /trunk/src/VBox/Main/include/MediumImpl.h	(revision 74003)
@@ -239,4 +239,5 @@
     HRESULT getVariant(std::vector<MediumVariant_T> &aVariant);
     HRESULT getLocation(com::Utf8Str &aLocation);
+    HRESULT setLocation(const com::Utf8Str &aLocation);
     HRESULT getName(com::Utf8Str &aName);
     HRESULT getDeviceType(DeviceType_T *aDeviceType);
@@ -297,7 +298,7 @@
                         const std::vector<MediumVariant_T> &aVariant,
                         ComPtr<IProgress> &aProgress);
-    HRESULT setLocation(AutoCaller &autoCaller,
-                        const com::Utf8Str &aLocation,
-                        ComPtr<IProgress> &aProgress);
+    HRESULT moveTo(AutoCaller &autoCaller,
+                   const com::Utf8Str &aLocation,
+                   ComPtr<IProgress> &aProgress);
     HRESULT compact(ComPtr<IProgress> &aProgress);
     HRESULT resize(LONG64 aLogicalSize,
Index: /trunk/src/VBox/Main/src-server/MachineImplMoveVM.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/MachineImplMoveVM.cpp	(revision 74002)
+++ /trunk/src/VBox/Main/src-server/MachineImplMoveVM.cpp	(revision 74003)
@@ -1103,9 +1103,9 @@
             if (FAILED(rc)) throw rc;
 
-            /* Drop lock early because IMedium::SetLocation needs to get the VirtualBox one. */
+            /* Drop lock early because IMedium::MoveTo needs to get the VirtualBox one. */
             machineLock.release();
 
             ComPtr<IProgress> moveDiskProgress;
-            rc = pMedium->SetLocation(bstrLocation.raw(), moveDiskProgress.asOutParam());
+            rc = pMedium->MoveTo(bstrLocation.raw(), moveDiskProgress.asOutParam());
             if (SUCCEEDED(rc))
             {
Index: /trunk/src/VBox/Main/src-server/MediumImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/MediumImpl.cpp	(revision 74002)
+++ /trunk/src/VBox/Main/src-server/MediumImpl.cpp	(revision 74003)
@@ -2919,5 +2919,5 @@
 }
 
-HRESULT Medium::setLocation(AutoCaller &autoCaller, const com::Utf8Str &aLocation, ComPtr<IProgress> &aProgress)
+HRESULT Medium::moveTo(AutoCaller &autoCaller, const com::Utf8Str &aLocation, ComPtr<IProgress> &aProgress)
 {
     ComObjPtr<Medium> pParent;
@@ -2930,5 +2930,5 @@
     /// @todo NEWMEDIA for file names, add the default extension if no extension
     /// is present (using the information from the VD backend which also implies
-    /// that one more parameter should be passed to setLocation() requesting
+    /// that one more parameter should be passed to moveTo() requesting
     /// that functionality since it is only allowed when called from this method
 
@@ -3200,4 +3200,109 @@
 }
 
+HRESULT Medium::setLocation(const com::Utf8Str &aLocation)
+{
+    HRESULT rc = S_OK;
+
+    try
+    {
+        // locking: we need the tree lock first because we access parent pointers
+        // and we need to write-lock the media involved
+        AutoWriteLock treeLock(m->pVirtualBox->i_getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
+
+        AutoCaller autoCaller(this);
+        AssertComRCThrowRC(autoCaller.rc());
+
+        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+        Utf8Str destPath(aLocation);
+
+        // some check for file based medium
+        if (i_isMediumFormatFile())
+        {
+            /* Path must be absolute */
+            if (!RTPathStartsWithRoot(destPath.c_str()))
+            {
+                rc = setError(VBOX_E_FILE_ERROR,
+                              tr("The given path '%s' is not fully qualified"),
+                              destPath.c_str());
+                throw rc;
+            }
+
+            /* Simple check for existence */
+            if (!RTFileExists(destPath.c_str()))
+            {
+                rc = setError(VBOX_E_FILE_ERROR,
+                              tr("The given path '%s' is not an existing file. New location is invalid."),
+                              destPath.c_str());
+                throw rc;
+            }
+        }
+
+        /* Check VMs which have this medium attached to*/
+        std::vector<com::Guid> aMachineIds;
+        rc = getMachineIds(aMachineIds);
+
+        // switch locks only if there are machines with this medium attached
+        if (!aMachineIds.empty())
+        {
+            std::vector<com::Guid>::const_iterator currMachineID = aMachineIds.begin();
+            std::vector<com::Guid>::const_iterator lastMachineID = aMachineIds.end();
+
+            alock.release();
+            autoCaller.release();
+            treeLock.release();
+
+            while (currMachineID != lastMachineID)
+            {
+                Guid id(*currMachineID);
+                ComObjPtr<Machine> aMachine;
+                rc = m->pVirtualBox->i_findMachine(id, false, true, &aMachine);
+                if (SUCCEEDED(rc))
+                {
+                    ComObjPtr<SessionMachine> sm;
+                    ComPtr<IInternalSessionControl> ctl;
+
+                    bool ses = aMachine->i_isSessionOpenVM(sm, &ctl);
+                    if (ses)
+                    {
+                        treeLock.acquire();
+                        autoCaller.add();
+                        AssertComRCThrowRC(autoCaller.rc());
+                        alock.acquire();
+
+                        rc = setError(VERR_VM_UNEXPECTED_VM_STATE,
+                                      tr("At least the VM '%s' to whom this medium '%s' attached has currently an opened session. Stop all VMs before set location for this medium"),
+                                      id.toString().c_str(),
+                                      i_getLocationFull().c_str());
+                        throw rc;
+                    }
+                }
+                ++currMachineID;
+            }
+
+            treeLock.acquire();
+            autoCaller.add();
+            AssertComRCThrowRC(autoCaller.rc());
+            alock.acquire();
+        }
+
+        m->strLocationFull = destPath;
+
+        // save the settings
+        alock.release();
+        autoCaller.release();
+        treeLock.release();
+
+        i_markRegistriesModified();
+        m->pVirtualBox->i_saveModifiedRegistries();
+
+        MediumState_T mediumState;
+        refreshState(autoCaller, &mediumState);
+    }
+    catch (HRESULT aRC) { rc = aRC; }
+
+    return rc;
+}
+
 HRESULT Medium::compact(ComPtr<IProgress> &aProgress)
 {
@@ -8154,5 +8259,5 @@
 
         /* The object may request a specific UUID (through a special form of
-        * the setLocation() argument). Otherwise we have to generate it */
+        * the moveTo() argument). Otherwise we have to generate it */
         Guid id = m->id;
 
@@ -8332,5 +8437,5 @@
 
         /* The object may request a specific UUID (through a special form of
-         * the setLocation() argument). Otherwise we have to generate it */
+         * the moveTo() argument). Otherwise we have to generate it */
         Guid targetId = pTarget->m->id;
 
@@ -8880,5 +8985,5 @@
 
         /* The object may request a specific UUID (through a special form of
-         * the setLocation() argument). Otherwise we have to generate it */
+         * the moveTo() argument). Otherwise we have to generate it */
         Guid targetId = pTarget->m->id;
 
@@ -9166,5 +9271,5 @@
  * Implementation code for the "move" task.
  *
- * This only gets started from Medium::SetLocation() and always
+ * This only gets started from Medium::MoveTo() and always
  * runs asynchronously.
  *
@@ -9789,5 +9894,5 @@
 
         /* The object may request a specific UUID (through a special form of
-         * the setLocation() argument). Otherwise we have to generate it */
+         * the moveTo() argument). Otherwise we have to generate it */
         Guid targetId = m->id;
 
Index: /trunk/src/VBox/ValidationKit/testdriver/vbox.py
===================================================================
--- /trunk/src/VBox/ValidationKit/testdriver/vbox.py	(revision 74002)
+++ /trunk/src/VBox/ValidationKit/testdriver/vbox.py	(revision 74003)
@@ -783,4 +783,5 @@
         self.fImportedVBoxApi   = False;
         self.fpApiVer           = 3.2;
+        self.uRevision          = 0;
         self.oBuild             = None;
         self.oVBoxMgr           = None;
@@ -1318,4 +1319,11 @@
                 else:
                     self.fpApiVer += 1.1;
+
+            try:
+                self.uRevision = oVBox.revision;
+            except:
+                reporter.logXcpt('Failed to get VirtualBox revision, assuming 0');
+                self.uRevision = 0;
+            reporter.log("IVirtualBox.revision=%u" % (self.uRevision,));
 
             # Patch VBox manage to gloss over portability issues (error constants, etc).
Index: /trunk/src/VBox/ValidationKit/tests/api/tdMoveMedium1.py
===================================================================
--- /trunk/src/VBox/ValidationKit/tests/api/tdMoveMedium1.py	(revision 74002)
+++ /trunk/src/VBox/ValidationKit/tests/api/tdMoveMedium1.py	(revision 74003)
@@ -66,5 +66,5 @@
     #
 
-    def setLocation(self, sLocation, aoMediumAttachments):
+    def moveTo(self, sLocation, aoMediumAttachments):
         for oAttachment in aoMediumAttachments:
             try:
@@ -74,9 +74,17 @@
                 reporter.errorXcpt('failed to get the medium from the IMediumAttachment "%s"' % (oAttachment))
 
-            try:
-                oProgress = vboxwrappers.ProgressWrapper(oMedium.setLocation(sLocation), self.oTstDrv.oVBoxMgr, self.oTstDrv,
-                                                         'move "%s"' % (oMedium.name,))
-            except:
-                return reporter.errorXcpt('Medium::setLocation("%s") for medium "%s" failed' % (sLocation, oMedium.name,))
+            if self.oTstDrv.fpApiVer >= 5.3 and self.oTstDrv.uRevision > 124748:
+                try:
+                    oProgress = vboxwrappers.ProgressWrapper(oMedium.moveTo(sLocation), self.oTstDrv.oVBoxMgr, self.oTstDrv,
+                                                             'move "%s"' % (oMedium.name,));
+                except:
+                    return reporter.errorXcpt('Medium::moveTo("%s") for medium "%s" failed' % (sLocation, oMedium.name,));
+            else:
+                try:
+                    oProgress = vboxwrappers.ProgressWrapper(oMedium.setLocation(sLocation), self.oTstDrv.oVBoxMgr, self.oTstDrv,
+                                                             'move "%s"' % (oMedium.name,));
+                except:
+                    return reporter.errorXcpt('Medium::setLocation("%s") for medium "%s" failed' % (sLocation, oMedium.name,));
+
 
             oProgress.wait()
@@ -149,9 +157,9 @@
             aoMediumAttachments = oVM.getMediumAttachmentsOfController(sController)
             #case 1. Only path without file name, with trailing separator
-            fRc = self.setLocation(sNewLoc + os.sep, aoMediumAttachments) and fRc
+            fRc = self.moveTo(sNewLoc + os.sep, aoMediumAttachments) and fRc
             fRc = self.checkLocation(sNewLoc, aoMediumAttachments, asFiles) and fRc
 
             #case 2. Only path without file name, without trailing separator
-            fRc = self.setLocation(sOrigLoc, aoMediumAttachments) and fRc
+            fRc = self.moveTo(sOrigLoc, aoMediumAttachments) and fRc
             fRc = self.checkLocation(sOrigLoc, aoMediumAttachments, asFiles) and fRc
 
@@ -162,5 +170,5 @@
             #and the file name is processed as folder name (aka mv(1) logic).
             #Be discussed.
-            fRc = self.setLocation(os.path.join(sNewLoc, 'newName'), aoMediumAttachments) and fRc
+            fRc = self.moveTo(os.path.join(sNewLoc, 'newName'), aoMediumAttachments) and fRc
             asNewFiles = ['newName' + os.path.splitext(s)[1] for s in asFiles]
             fRc = self.checkLocation(os.path.join(sNewLoc, 'newName'), aoMediumAttachments, asFiles) and fRc
@@ -170,5 +178,5 @@
 
             #case 4. Only file name
-            fRc = self.setLocation('onlyMediumName', aoMediumAttachments) and fRc
+            fRc = self.moveTo('onlyMediumName', aoMediumAttachments) and fRc
             asNewFiles = ['onlyMediumName' + os.path.splitext(s)[1] for s in asFiles]
             if self.oTstDrv.fpApiVer >= 5.3:
@@ -183,5 +191,5 @@
                 aoMediumAttachments = oVM.getMediumAttachmentsOfController(sController)
                 asSnapFiles = [os.path.basename(o.medium.name) for o in aoMediumAttachments]
-                fRc = self.setLocation(sOrigLoc, aoMediumAttachments) and fRc
+                fRc = self.moveTo(sOrigLoc, aoMediumAttachments) and fRc
                 fRc = self.checkLocation(sOrigLoc, aoMediumAttachments, asSnapFiles) and fRc
 
Index: /trunk/src/VBox/ValidationKit/tests/api/tdMoveVM1.py
===================================================================
--- /trunk/src/VBox/ValidationKit/tests/api/tdMoveVM1.py	(revision 74002)
+++ /trunk/src/VBox/ValidationKit/tests/api/tdMoveVM1.py	(revision 74003)
@@ -287,5 +287,5 @@
         aoMediumAttachments = oMachine.getMediumAttachmentsOfController(sController)
         oSubTstDrvMoveMedium1Instance = SubTstDrvMoveMedium1(self.oTstDrv)
-        oSubTstDrvMoveMedium1Instance.setLocation(sOldLoc, aoMediumAttachments)
+        oSubTstDrvMoveMedium1Instance.moveTo(sOldLoc, aoMediumAttachments)
 
         del oSubTstDrvMoveMedium1Instance
