Index: /trunk/src/VBox/Main/MachineImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/MachineImpl.cpp	(revision 31062)
+++ /trunk/src/VBox/Main/MachineImpl.cpp	(revision 31063)
@@ -11036,6 +11036,9 @@
         if (pMedium != NULL)
         {
-            bool fIsReadOnlyImage = (devType == DeviceType_DVD);
+            MediumType_T mediumType = pMedium->getType();
+            bool fIsReadOnlyImage =    devType == DeviceType_DVD
+                                    || mediumType == MediumType_Shareable;
             bool fIsVitalImage = (devType == DeviceType_HardDisk);
+
             mrc = pMedium->createMediumLockList(fIsVitalImage /* fFailIfInaccessible */,
                                                 !fIsReadOnlyImage /* fMediumLockWrite */,
Index: /trunk/src/VBox/Main/MediumImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/MediumImpl.cpp	(revision 31062)
+++ /trunk/src/VBox/Main/MediumImpl.cpp	(revision 31063)
@@ -47,5 +47,5 @@
 ////////////////////////////////////////////////////////////////////////////////
 
-/** Describes how a machine refers to this image. */
+/** Describes how a machine refers to this medium. */
 struct BackRef
 {
@@ -86,4 +86,5 @@
         : pVirtualBox(NULL),
           state(MediumState_NotCreated),
+          variant(MediumVariant_Standard),
           size(0),
           readers(0),
@@ -110,4 +111,5 @@
     Utf8Str strDescription;
     MediumState_T state;
+    MediumVariant_T variant;
     Utf8Str strLocation;
     Utf8Str strLocationFull;
@@ -792,5 +794,5 @@
 /**
  * Initializes the medium object by opening the storage unit at the specified
- * location. The enOpenMode parameter defines whether the image will be opened
+ * location. The enOpenMode parameter defines whether the medium will be opened
  * read/write or read-only.
  *
@@ -802,8 +804,8 @@
  * @param aVirtualBox   VirtualBox object.
  * @param aLocation     Storage unit location.
- * @param enOpenMode    Whether to open the image read/write or read-only.
+ * @param enOpenMode    Whether to open the medium read/write or read-only.
  * @param aDeviceType   Device type of medium.
- * @param aSetImageId   Whether to set the image UUID or not.
- * @param aImageId      New image UUID if @aSetId is true. Empty string means
+ * @param aSetImageId   Whether to set the medium UUID or not.
+ * @param aImageId      New medium UUID if @aSetId is true. Empty string means
  *                      create a new UUID, and a zero UUID is invalid.
  * @param aSetParentId  Whether to set the parent UUID or not.
@@ -886,5 +888,5 @@
 /**
  * Initializes the medium object by loading its data from the given settings
- * node. In this mode, the image will always be opened read/write.
+ * node. In this mode, the medium will always be opened read/write.
  *
  * @param aVirtualBox   VirtualBox object.
@@ -917,5 +919,5 @@
     if (aParent)
     {
-        // differencing image: add to parent
+        // differencing medium: add to parent
         AutoWriteLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
         m->pParent = aParent;
@@ -954,7 +956,6 @@
     }
 
-    /* optional, only for diffs, default is false;
-     * we can only auto-reset diff images, so they
-     * must not have a parent */
+    /* optional, only for diffs, default is false; we can only auto-reset
+     * diff media so they must have a parent */
     if (aParent != NULL)
         m->autoReset = data.fAutoReset;
@@ -1096,5 +1097,5 @@
  * Called either from FinalRelease() or by the parent when it gets destroyed.
  *
- * @note All children of this hard disk get uninitialized by calling their
+ * @note All children of this medium get uninitialized by calling their
  *       uninit() methods.
  *
@@ -1153,5 +1154,5 @@
  * parent. Used in uninit() and other places when reparenting is necessary.
  *
- * The caller must hold the hard disk tree lock!
+ * The caller must hold the medium tree lock!
  */
 void Medium::deparent()
@@ -1176,5 +1177,5 @@
  * parent. Used in uninit() and other places when reparenting is necessary.
  *
- * The caller must hold the hard disk tree lock!
+ * The caller must hold the medium tree lock!
  */
 void Medium::setParent(const ComObjPtr<Medium> &pParent)
@@ -1249,4 +1250,17 @@
 }
 
+STDMETHODIMP Medium::COMGETTER(Variant)(MediumVariant_T *aVariant)
+{
+    CheckComArgOutPointerValid(aVariant);
+
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+    *aVariant = m->variant;
+
+    return S_OK;
+}
+
 
 STDMETHODIMP Medium::COMGETTER(Location)(BSTR *aLocation)
@@ -1398,7 +1412,4 @@
     }
 
-    /** @todo implement this case later */
-    CheckComArgExpr(aType, aType != MediumType_Shareable);
-
     if (m->type == aType)
     {
@@ -1407,14 +1418,14 @@
     }
 
-    /* cannot change the type of a differencing hard disk */
+    /* cannot change the type of a differencing medium */
     if (m->pParent)
         return setError(E_FAIL,
-                        tr("Cannot change the type of hard disk '%s' because it is a differencing hard disk"),
+                        tr("Cannot change the type of medium '%s' because it is a differencing medium"),
                         m->strLocationFull.raw());
 
-    /* cannot change the type of a hard disk being in use by more than one VM */
+    /* cannot change the type of a medium being in use by more than one VM */
     if (m->backRefs.size() > 1)
         return setError(E_FAIL,
-                        tr("Cannot change the type of hard disk '%s' because it is attached to %d virtual machines"),
+                        tr("Cannot change the type of medium '%s' because it is attached to %d virtual machines"),
                         m->strLocationFull.raw(), m->backRefs.size());
 
@@ -1435,6 +1446,15 @@
             if (getChildren().size() != 0)
                 return setError(E_FAIL,
-                                tr("Cannot change type for hard disk '%s' since it has %d child hard disk(s)"),
+                                tr("Cannot change type for medium '%s' since it has %d child media"),
                                 m->strLocationFull.raw(), getChildren().size());
+            if (aType == MediumType_Shareable)
+            {
+                MediumVariant_T variant = getVariant();
+                if (!(variant & MediumVariant_Fixed))
+                    return setError(E_FAIL,
+                                    tr("Cannot change type for medium '%s' to 'Shareable' since it is a dynamic medium storage unit"),
+                                    m->strLocationFull.raw());
+
+            }
             break;
         }
@@ -1531,6 +1551,6 @@
 
     /* We assume that some backend may decide to return a meaningless value in
-     * response to VDGetSize() for differencing hard disks and therefore
-     * always ask the base hard disk ourselves. */
+     * response to VDGetSize() for differencing media and therefore always
+     * ask the base medium ourselves. */
 
     /* base() will do callers/locking */
@@ -1565,5 +1585,5 @@
     if (m->pParent.isNull())
         return setError(VBOX_E_NOT_SUPPORTED,
-                        tr("Hard disk '%s' is not differencing"),
+                        tr("Medium '%s' is not differencing"),
                         m->strLocationFull.raw());
 
@@ -2078,10 +2098,10 @@
             &&  !(m->formatObj->capabilities() & MediumFormatCapabilities_CreateDynamic))
             throw setError(VBOX_E_NOT_SUPPORTED,
-                           tr("Hard disk format '%s' does not support dynamic storage creation"),
+                           tr("Medium format '%s' does not support dynamic storage creation"),
                            m->strFormat.raw());
         if (    (aVariant & MediumVariant_Fixed)
             &&  !(m->formatObj->capabilities() & MediumFormatCapabilities_CreateDynamic))
             throw setError(VBOX_E_NOT_SUPPORTED,
-                           tr("Hard disk format '%s' does not support fixed storage creation"),
+                           tr("Medium format '%s' does not support fixed storage creation"),
                            m->strFormat.raw());
 
@@ -2093,6 +2113,6 @@
                              static_cast<IMedium*>(this),
                              (aVariant & MediumVariant_Fixed)
-                               ? BstrFmt(tr("Creating fixed hard disk storage unit '%s'"), m->strLocationFull.raw())
-                               : BstrFmt(tr("Creating dynamic hard disk storage unit '%s'"), m->strLocationFull.raw()),
+                               ? BstrFmt(tr("Creating fixed medium storage unit '%s'"), m->strLocationFull.raw())
+                               : BstrFmt(tr("Creating dynamic medium storage unit '%s'"), m->strLocationFull.raw()),
                              TRUE /* aCancelable */);
         if (FAILED(rc))
@@ -2165,5 +2185,9 @@
     if (m->type == MediumType_Writethrough)
         return setError(E_FAIL,
-                        tr("Hard disk '%s' is Writethrough"),
+                        tr("Medium type of '%s' is Writethrough"),
+                        m->strLocationFull.raw());
+    else if (m->type == MediumType_Shareable)
+        return setError(E_FAIL,
+                        tr("Medium type of '%s' is Shareable"),
                         m->strLocationFull.raw());
 
@@ -2252,5 +2276,5 @@
         // locking: we need the tree lock first because we access parent pointers
         AutoReadLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
-        // and we need to write-lock the images involved
+        // and we need to write-lock the media involved
         AutoMultiWriteLock3 alock(this, pTarget, pParent COMMA_LOCKVAL_SRC_POS);
 
@@ -2306,5 +2330,5 @@
         rc = pProgress->init(m->pVirtualBox,
                              static_cast <IMedium *>(this),
-                             BstrFmt(tr("Creating clone hard disk '%s'"), pTarget->m->strLocationFull.raw()),
+                             BstrFmt(tr("Creating clone medium '%s'"), pTarget->m->strLocationFull.raw()),
                              TRUE /* aCancelable */);
         if (FAILED(rc))
@@ -2385,5 +2409,5 @@
         rc = pProgress->init(m->pVirtualBox,
                              static_cast <IMedium *>(this),
-                             BstrFmt(tr("Compacting hard disk '%s'"), m->strLocationFull.raw()),
+                             BstrFmt(tr("Compacting medium '%s'"), m->strLocationFull.raw()),
                              TRUE /* aCancelable */);
         if (FAILED(rc))
@@ -2449,5 +2473,5 @@
         if (m->pParent.isNull())
             throw setError(VBOX_E_NOT_SUPPORTED,
-                           tr("Hard disk '%s' is not differencing"),
+                           tr("Medium type of '%s' is not differencing"),
                            m->strLocationFull.raw());
 
@@ -2480,5 +2504,5 @@
         rc = pProgress->init(m->pVirtualBox,
                              static_cast<IMedium*>(this),
-                             BstrFmt(tr("Resetting differencing hard disk '%s'"), m->strLocationFull.raw()),
+                             BstrFmt(tr("Resetting differencing medium '%s'"), m->strLocationFull.raw()),
                              FALSE /* aCancelable */);
         if (FAILED(rc))
@@ -2552,5 +2576,5 @@
 
 /**
- * Internal method to return the medium's GUID. Must have caller + locking!
+ * Internal method to return the medium's state. Must have caller + locking!
  * @return
  */
@@ -2558,4 +2582,13 @@
 {
     return m->state;
+}
+
+/**
+ * Internal method to return the medium's variant. Must have caller + locking!
+ * @return
+ */
+MediumState_T Medium::getVariant() const
+{
+    return m->variant;
 }
 
@@ -2607,5 +2640,5 @@
 /**
  * Adds the given machine and optionally the snapshot to the list of the objects
- * this image is attached to.
+ * this medium is attached to.
  *
  * @param aMachineId    Machine ID.
@@ -2638,5 +2671,5 @@
     if (m->numCreateDiffTasks > 0)
         return setError(E_FAIL,
-                        tr("Cannot attach hard disk '%s' {%RTuuid}: %u differencing child hard disk(s) are being created"),
+                        tr("Cannot attach medium '%s' {%RTuuid}: %u differencing child media are being created"),
                         m->strLocationFull.raw(),
                         m->id.raw(),
@@ -2699,5 +2732,5 @@
 /**
  * Removes the given machine and optionally the snapshot from the list of the
- * objects this image is attached to.
+ * objects this medium is attached to.
  *
  * @param aMachineId    Machine ID.
@@ -2838,5 +2871,5 @@
 /**
  * Checks if the given change of \a aOldPath to \a aNewPath affects the location
- * of this hard disk or any its child and updates the paths if necessary to
+ * of this medium or any its child and updates the paths if necessary to
  * reflect the new location.
  *
@@ -2871,11 +2904,11 @@
 
 /**
- * Returns the base hard disk of the hard disk chain this hard disk is part of.
- *
- * The base hard disk is found by walking up the parent-child relationship axis.
- * If the hard disk doesn't have a parent (i.e. it's a base hard disk), it
+ * Returns the base medium of the media chain this medium is part of.
+ *
+ * The base medium is found by walking up the parent-child relationship axis.
+ * If the medium doesn't have a parent (i.e. it's a base medium), it
  * returns itself in response to this method.
  *
- * @param aLevel    Where to store the number of ancestors of this hard disk
+ * @param aLevel    Where to store the number of ancestors of this medium
  *                  (zero for the base), may be @c NULL.
  *
@@ -2918,6 +2951,6 @@
 
 /**
- * Returns @c true if this hard disk cannot be modified because it has
- * dependants (children) or is part of the snapshot. Related to the hard disk
+ * Returns @c true if this medium cannot be modified because it has
+ * dependants (children) or is part of the snapshot. Related to the medium
  * type and posterity, not to the current media state.
  *
@@ -2961,6 +2994,6 @@
 
 /**
- * Saves hard disk data by appending a new <HardDisk> child node to the given
- * parent node which can be either <HardDisks> or <HardDisk>.
+ * Saves medium data by appending a new child node to the given
+ * parent XML settings node.
  *
  * @param data      Settings struct to be updated.
@@ -3006,5 +3039,5 @@
     }
 
-    /* only for base hard disks */
+    /* only for base media */
     if (m->pParent.isNull())
         data.hdType = m->type;
@@ -3025,5 +3058,5 @@
 
 /**
- * Compares the location of this hard disk to the given location.
+ * Compares the location of this medium to the given location.
  *
  * The comparison takes the location details into account. For example, if the
@@ -3064,5 +3097,5 @@
         if (RT_FAILURE(vrc))
             return setError(E_FAIL,
-                            tr("Invalid hard disk storage file location '%s' (%Rrc)"),
+                            tr("Invalid medium storage file location '%s' (%Rrc)"),
                             location.raw(),
                             vrc);
@@ -3083,5 +3116,5 @@
  * @param fFailIfInaccessible If true, this fails with an error if a medium is inaccessible. If false,
  *          inaccessible media are silently skipped and not locked (i.e. their state remains "Inaccessible");
- *          this is necessary for a VM's removable images on VM startup for which we do not want to fail.
+ *          this is necessary for a VM's removable media VM startup for which we do not want to fail.
  * @param fMediumLockWrite  Whether to associate a write lock with this medium.
  * @param pToBeParent       Medium which will become the parent of this medium.
@@ -3120,5 +3153,5 @@
         /* Accessibility check must be first, otherwise locking interferes
          * with getting the medium state. Lock lists are not created for
-         * fun, and thus getting the image status is no luxury. */
+         * fun, and thus getting the medium status is no luxury. */
         MediumState_T mediumState = pMedium->getState();
         if (mediumState == MediumState_Inaccessible)
@@ -3129,5 +3162,5 @@
             if (mediumState == MediumState_Inaccessible)
             {
-                // ignore inaccessible ISO images and silently return S_OK,
+                // ignore inaccessible ISO media and silently return S_OK,
                 // otherwise VM startup (esp. restore) may fail without good reason
                 if (!fFailIfInaccessible)
@@ -3168,5 +3201,5 @@
 
 /**
- * Returns a preferred format for differencing hard disks.
+ * Returns a preferred format for differencing media.
  */
 Bstr Medium::preferredDiffFormat()
@@ -3217,5 +3250,5 @@
  * Sets the value of m->strLocation and calculates the value of m->strLocationFull.
  *
- * Treats non-FS-path locations specially, and prepends the default hard disk
+ * Treats non-FS-path locations specially, and prepends the default medium
  * folder if the given location string does not contain any path information
  * at all.
@@ -3391,5 +3424,5 @@
 
 /**
- * Queries information from the image file.
+ * Queries information from the medium.
  *
  * As a result of this call, the accessibility state and data members such as
@@ -3492,6 +3525,6 @@
         try
         {
-            /** @todo This kind of opening of images is assuming that diff
-             * images can be opened as base images. Should be documented if
+            /** @todo This kind of opening of media is assuming that diff
+             * media can be opened as base media. Should be documented if
              * it must work for all medium format backends. */
             vrc = VDOpen(hdd,
@@ -3575,4 +3608,5 @@
             vrc = VDGetImageFlags(hdd, 0, &uImageFlags);
             ComAssertRCThrow(vrc, E_FAIL);
+            m->variant = (MediumVariant_T)uImageFlags;
 
             if (uImageFlags & VD_IMAGE_FLAGS_DIFF)
@@ -3585,9 +3619,9 @@
                 {
                     /* the parent must be known to us. Note that we freely
-                     * call locking methods of mVirtualBox and parent from the
-                     * write lock (breaking the {parent,child} lock order)
-                     * because there may be no concurrent access to the just
-                     * opened hard disk on ther threads yet (and init() will
-                     * fail if this method reporst MediumState_Inaccessible) */
+                     * call locking methods of mVirtualBox and parent, as all
+                     * relevant locks must be already held. There may be no
+                     * concurrent access to the just opened medium on other
+                     * threads yet (and init() will fail if this method reports
+                     * MediumState_Inaccessible) */
 
                     Guid id = parentId;
@@ -3599,5 +3633,5 @@
                     {
                         lastAccessError = Utf8StrFmt(
-                            tr("Parent hard disk with UUID {%RTuuid} of the hard disk '%s' is not found in the media registry ('%s')"),
+                            tr("Parent medium with UUID {%RTuuid} of the medium '%s' is not found in the media registry ('%s')"),
                             &parentId, location.c_str(),
                             m->pVirtualBox->settingsFilePath().c_str());
@@ -3624,5 +3658,5 @@
                     {
                         lastAccessError = Utf8StrFmt(
-                            tr("Hard disk '%s' is differencing but it is not associated with any parent hard disk in the media registry ('%s')"),
+                            tr("Medium type of '%s' is differencing but it is not associated with any parent medium in the media registry ('%s')"),
                             location.c_str(),
                             m->pVirtualBox->settingsFilePath().c_str());
@@ -3635,5 +3669,5 @@
                     {
                         lastAccessError = Utf8StrFmt(
-                            tr("Parent UUID {%RTuuid} of the hard disk '%s' does not match UUID {%RTuuid} of its parent hard disk stored in the media registry ('%s')"),
+                            tr("Parent UUID {%RTuuid} of the medium '%s' does not match UUID {%RTuuid} of its parent medium stored in the media registry ('%s')"),
                             &parentId, location.c_str(),
                             m->pParent->getId().raw(),
@@ -3846,5 +3880,5 @@
 
 /**
- * Deletes the hard disk storage unit.
+ * Deletes the medium storage unit.
  *
  * If @a aProgress is not NULL but the object it points to is @c null then a new
@@ -3895,5 +3929,5 @@
                                                    | MediumFormatCapabilities_CreateFixed)))
             throw setError(VBOX_E_NOT_SUPPORTED,
-                           tr("Hard disk format '%s' does not support storage deletion"),
+                           tr("Medium format '%s' does not support storage deletion"),
                            m->strFormat.raw());
 
@@ -3902,7 +3936,7 @@
          * it is really inaccessible, the delete operation will fail anyway.
          * Accepting Inaccessible state is especially important because all
-         * registered hard disks are initially Inaccessible upon VBoxSVC
-         * startup until COMGETTER(RefreshState) is called. Accept Deleting
-         * state because some callers need to put the image in this state early
+         * registered media are initially Inaccessible upon VBoxSVC startup
+         * until COMGETTER(RefreshState) is called. Accept Deleting state
+         * because some callers need to put the medium in this state early
          * to prevent races. */
         switch (m->state)
@@ -3932,5 +3966,5 @@
 #endif
             throw setError(VBOX_E_OBJECT_IN_USE,
-                           tr("Cannot delete storage: hard disk '%s' is still attached to the following %d virtual machine(s): %s"),
+                           tr("Cannot delete storage: medium '%s' is still attached to the following %d virtual machine(s): %s"),
                            m->strLocationFull.c_str(),
                            m->backRefs.size(),
@@ -3971,5 +4005,5 @@
         }
 
-        /* try to remove from the list of known hard disks before performing
+        /* try to remove from the list of known media before performing
          * actual deletion (we favor the consistency of the media registry
          * which would have been broken if unregisterWithVirtualBox() failed
@@ -3992,5 +4026,5 @@
                 rc = pProgress->init(m->pVirtualBox,
                                      static_cast<IMedium*>(this),
-                                     BstrFmt(tr("Deleting hard disk storage unit '%s'"), m->strLocationFull.raw()),
+                                     BstrFmt(tr("Deleting medium storage unit '%s'"), m->strLocationFull.raw()),
                                      FALSE /* aCancelable */);
                 if (FAILED(rc))
@@ -4109,6 +4143,6 @@
 
 /**
- * Creates a new differencing storage unit using the given target hard disk's
- * format and the location. Note that @c aTarget must be NotCreated.
+ * Creates a new differencing storage unit using the format of the given target
+ * medium and the location. Note that @c aTarget must be NotCreated.
  *
  * The @a aMediumLockList parameter contains the associated medium lock list,
@@ -4127,6 +4161,6 @@
  * NULL when @a aWait is @c false (this method will assert in this case).
  *
- * @param aTarget           Target hard disk.
- * @param aVariant          Precise image variant to create.
+ * @param aTarget           Target medium.
+ * @param aVariant          Precise medium variant to create.
  * @param aMediumLockList   List of media which should be locked.
  * @param aProgress         Where to find/store a Progress object to track
@@ -4170,5 +4204,6 @@
         AutoMultiWriteLock2 alock(this, aTarget COMMA_LOCKVAL_SRC_POS);
 
-        ComAssertThrow(m->type != MediumType_Writethrough, E_FAIL);
+        ComAssertThrow(   m->type != MediumType_Writethrough
+                       && m->type != MediumType_Shareable, E_FAIL);
         ComAssertThrow(m->state == MediumState_LockedRead, E_FAIL);
 
@@ -4176,5 +4211,5 @@
             throw aTarget->setStateError();
 
-        /* Check that the hard disk is not attached to the current state of
+        /* Check that the medium is not attached to the current state of
          * any VM referring to it. */
         for (BackRefList::const_iterator it = m->backRefs.begin();
@@ -4184,6 +4219,6 @@
             if (it->fInCurState)
             {
-                /* Note: when a VM snapshot is being taken, all normal hard
-                 * disks attached to the VM in the current state will be, as an
+                /* Note: when a VM snapshot is being taken, all normal media
+                 * attached to the VM in the current state will be, as an
                  * exception, also associated with the snapshot which is about
                  * to create (see SnapshotMachine::init()) before deassociating
@@ -4194,5 +4229,5 @@
                 if (it->llSnapshotIds.size() == 0)
                     throw setError(VBOX_E_INVALID_OBJECT_STATE,
-                                   tr("Hard disk '%s' is attached to a virtual machine with UUID {%RTuuid}. No differencing hard disks based on it may be created until it is detached"),
+                                   tr("Medium '%s' is attached to a virtual machine with UUID {%RTuuid}. No differencing media based on it may be created until it is detached"),
                                    m->strLocationFull.raw(), it->machineId.raw());
 
@@ -4212,5 +4247,5 @@
                 rc = pProgress->init(m->pVirtualBox,
                                      static_cast<IMedium*>(this),
-                                     BstrFmt(tr("Creating differencing hard disk storage unit '%s'"), aTarget->m->strLocationFull.raw()),
+                                     BstrFmt(tr("Creating differencing medium storage unit '%s'"), aTarget->m->strLocationFull.raw()),
                                      TRUE /* aCancelable */);
                 if (FAILED(rc))
@@ -4253,9 +4288,9 @@
 
 /**
- * Prepares this (source) hard disk, target hard disk and all intermediate hard
- * disks for the merge operation.
+ * Prepares this (source) medium, target medium and all intermediate media
+ * for the merge operation.
  *
  * This method is to be called prior to calling the #mergeTo() to perform
- * necessary consistency checks and place involved hard disks to appropriate
+ * necessary consistency checks and place involved media to appropriate
  * states. If #mergeTo() is not called or fails, the state modifications
  * performed by this method must be undone by #cancelMergeTo().
@@ -4263,5 +4298,5 @@
  * See #mergeTo() for more information about merging.
  *
- * @param pTarget       Target hard disk.
+ * @param pTarget       Target medium.
  * @param aMachineId    Allowed machine attachment. NULL means do not check.
  * @param aSnapshotId   Allowed snapshot attachment. NULL or empty UUID means
@@ -4277,5 +4312,5 @@
  *
  * @note Locks medium tree for reading. Locks this object, aTarget and all
- *       intermediate hard disks for writing.
+ *       intermediate media for writing.
  */
 HRESULT Medium::prepareMergeTo(const ComObjPtr<Medium> &pTarget,
@@ -4332,5 +4367,5 @@
                 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
                 throw setError(E_FAIL,
-                               tr("Hard disks '%s' and '%s' are unrelated"),
+                               tr("Media '%s' and '%s' are unrelated"),
                                m->strLocationFull.raw(), tgtLoc.raw());
             }
@@ -4382,5 +4417,5 @@
             }
             /* One backreference is only allowed if the machine ID is not empty
-             * and it matches the machine the image is attached to (including
+             * and it matches the machine the medium is attached to (including
              * the snapshot ID if not empty). */
             if (   m->backRefs.size() != 0
@@ -4546,8 +4581,8 @@
 
 /**
- * Merges this hard disk to the specified hard disk which must be either its
+ * Merges this medium to the specified medium which must be either its
  * direct ancestor or descendant.
  *
- * Given this hard disk is SOURCE and the specified hard disk is TARGET, we will
+ * Given this medium is SOURCE and the specified medium is TARGET, we will
  * get two varians of the merge operation:
  *
@@ -4563,14 +4598,14 @@
  *             LockWr    Del             Del       LockWr
  *
- * Each diagram shows the involved hard disks on the hard disk chain where
- * SOURCE and TARGET belong. Under each hard disk there is a state value which
- * the hard disk must have at a time of the mergeTo() call.
- *
- * The hard disks in the square braces may be absent (e.g. when the forward
- * operation takes place and SOURCE is the base hard disk, or when the backward
+ * Each diagram shows the involved media on the media chain where
+ * SOURCE and TARGET belong. Under each medium there is a state value which
+ * the medium must have at a time of the mergeTo() call.
+ *
+ * The media in the square braces may be absent (e.g. when the forward
+ * operation takes place and SOURCE is the base medium, or when the backward
  * merge operation takes place and TARGET is the last child in the chain) but if
  * they present they are involved too as shown.
  *
- * Nor the source hard disk neither intermediate hard disks may be attached to
+ * Neither the source medium nor intermediate media may be attached to
  * any VM directly or in the snapshot, otherwise this method will assert.
  *
@@ -4580,9 +4615,9 @@
  * If @a aWait is @c true then this method will perform the operation on the
  * calling thread and will not return to the caller until the operation is
- * completed. When this method succeeds, all intermediate hard disk objects in
- * the chain will be uninitialized, the state of the target hard disk (and all
- * involved extra hard disks) will be restored. @a aMediumLockList will not be
+ * completed. When this method succeeds, all intermediate medium objects in
+ * the chain will be uninitialized, the state of the target medium (and all
+ * involved extra media) will be restored. @a aMediumLockList will not be
  * deleted, whether the operation is successful or not. The caller has to do
- * this if appropriate. Note that this (source) hard disk is not uninitialized
+ * this if appropriate. Note that this (source) medium is not uninitialized
  * because of possible AutoCaller instances held by the caller of this method
  * on the current thread. It's therefore the responsibility of the caller to
@@ -4591,9 +4626,9 @@
  * If @a aWait is @c false then this method will create a thread to perform the
  * operation asynchronously and will return immediately. If the operation
- * succeeds, the thread will uninitialize the source hard disk object and all
- * intermediate hard disk objects in the chain, reset the state of the target
- * hard disk (and all involved extra hard disks) and delete @a aMediumLockList.
+ * succeeds, the thread will uninitialize the source medium object and all
+ * intermediate medium objects in the chain, reset the state of the target
+ * medium (and all involved extra media) and delete @a aMediumLockList.
  * If the operation fails, the thread will only reset the states of all
- * involved hard disks and delete @a aMediumLockList.
+ * involved media and delete @a aMediumLockList.
  *
  * When this method fails (regardless of the @a aWait mode), it is a caller's
@@ -4607,5 +4642,5 @@
  * NULL when @a aWait is @c false (this method will assert in this case).
  *
- * @param pTarget       Target hard disk.
+ * @param pTarget       Target medium.
  * @param fMergeForward Merge direction.
  * @param pParentForTarget New parent for target medium after merge.
@@ -4622,5 +4657,5 @@
  *                and this parameter is ignored.
  *
- * @note Locks the tree lock for writing. Locks the hard disks from the chain
+ * @note Locks the tree lock for writing. Locks the media from the chain
  *       for writing.
  */
@@ -4670,5 +4705,5 @@
                 rc = pProgress->init(m->pVirtualBox,
                                      static_cast<IMedium*>(this),
-                                     BstrFmt(tr("Merging hard disk '%s' to '%s'"),
+                                     BstrFmt(tr("Merging medium '%s' to '%s'"),
                                              getName().raw(),
                                              tgtName.raw()),
@@ -4716,5 +4751,5 @@
  * @param aMediumLockList Medium locking information.
  *
- * @note Locks the hard disks from the chain for writing.
+ * @note Locks the media from the chain for writing.
  */
 void Medium::cancelMergeTo(const MediaList &aChildrenToReparent,
@@ -4781,5 +4816,5 @@
         if (m->formatObj.isNull())
             return setError(E_INVALIDARG,
-                            tr("Invalid hard disk storage format '%ls'"),
+                            tr("Invalid medium storage format '%ls'"),
                             aFormat);
 
@@ -4824,5 +4859,5 @@
     if (getChildren().size() != 0)
         return setError(E_FAIL,
-                        tr("Cannot close medium '%s' because it has %d child hard disk(s)"),
+                        tr("Cannot close medium '%s' because it has %d child media"),
                         m->strLocationFull.raw(), getChildren().size());
 
@@ -5080,5 +5115,5 @@
                 AutoReadLock alock(pMedium COMMA_LOCKVAL_SRC_POS);
 
-                // open the image
+                // open the medium
                 vrc = VDOpen(hdd,
                              pMedium->m->strFormat.c_str(),
@@ -5178,4 +5213,5 @@
     /* these parameters we need after creation */
     uint64_t size = 0, logicalSize = 0;
+    MediumVariant_T variant = MediumVariant_Standard;
     bool fGenerateUuid = false;
 
@@ -5232,9 +5268,13 @@
             if (RT_FAILURE(vrc))
                 throw setError(E_FAIL,
-                            tr("Could not create the hard disk storage unit '%s'%s"),
+                            tr("Could not create the medium storage unit '%s'%s"),
                             location.raw(), vdError(vrc).raw());
 
             size = VDGetFileSize(hdd, 0);
             logicalSize = VDGetSize(hdd, 0) / _1M;
+            unsigned uImageFlags;
+            vrc = VDGetImageFlags(hdd, 0, &uImageFlags);
+            if (RT_SUCCESS(vrc))
+                variant = (MediumVariant_T)uImageFlags;
         }
         catch (HRESULT aRC) { rc = aRC; }
@@ -5270,4 +5310,5 @@
         m->size = size;
         m->logicalSize = logicalSize;
+        m->variant = variant;
     }
     else
@@ -5305,4 +5346,5 @@
 
     uint64_t size = 0, logicalSize = 0;
+    MediumVariant_T variant = MediumVariant_Standard;
     bool fGenerateUuid = false;
 
@@ -5343,5 +5385,5 @@
         try
         {
-            /* Open all hard disk images in the target chain but the last. */
+            /* Open all media in the target chain but the last. */
             MediumLockList::Base::const_iterator targetListBegin =
                 task.mpMediumLockList->GetBegin();
@@ -5357,5 +5399,5 @@
                 AutoReadLock alock(pMedium COMMA_LOCKVAL_SRC_POS);
 
-                /* Skip over the target diff image */
+                /* Skip over the target diff medium */
                 if (pMedium->m->state == MediumState_Creating)
                     continue;
@@ -5364,5 +5406,5 @@
                 Assert(pMedium->m->state == MediumState_LockedRead);
 
-                /* Open all images in appropriate mode. */
+                /* Open all media in appropriate mode. */
                 vrc = VDOpen(hdd,
                              pMedium->m->strFormat.c_str(),
@@ -5372,5 +5414,5 @@
                 if (RT_FAILURE(vrc))
                     throw setError(E_FAIL,
-                                   tr("Could not open the hard disk storage unit '%s'%s"),
+                                   tr("Could not open the medium storage unit '%s'%s"),
                                    pMedium->m->strLocationFull.raw(),
                                    vdError(vrc).raw());
@@ -5394,9 +5436,13 @@
             if (RT_FAILURE(vrc))
                 throw setError(E_FAIL,
-                                tr("Could not create the differencing hard disk storage unit '%s'%s"),
+                                tr("Could not create the differencing medium storage unit '%s'%s"),
                                 targetLocation.raw(), vdError(vrc).raw());
 
             size = VDGetFileSize(hdd, VD_LAST_IMAGE);
             logicalSize = VDGetSize(hdd, VD_LAST_IMAGE) / _1M;
+            unsigned uImageFlags;
+            vrc = VDGetImageFlags(hdd, 0, &uImageFlags);
+            if (RT_SUCCESS(vrc))
+                variant = (MediumVariant_T)uImageFlags;
         }
         catch (HRESULT aRC) { rc = aRC; }
@@ -5418,5 +5464,5 @@
         /** @todo r=klaus neither target nor base() are locked,
             * potential race! */
-        /* diffs for immutable hard disks are auto-reset by default */
+        /* diffs for immutable media are auto-reset by default */
         pTarget->m->autoReset = (getBase()->m->type == MediumType_Immutable);
 
@@ -5439,4 +5485,5 @@
         pTarget->m->size = size;
         pTarget->m->logicalSize = logicalSize;
+        pTarget->m->variant = variant;
     }
     else
@@ -5472,5 +5519,5 @@
 
     /* Note that in sync mode, it's the caller's responsibility to
-     * unlock the hard disk */
+     * unlock the medium. */
 
     return rc;
@@ -5509,5 +5556,5 @@
             unsigned uTargetIdx = VD_LAST_IMAGE;
             unsigned uSourceIdx = VD_LAST_IMAGE;
-            /* Open all hard disks in the chain. */
+            /* Open all media in the chain. */
             MediumLockList::Base::iterator lockListBegin =
                 task.mpMediumLockList->GetBegin();
@@ -5532,6 +5579,6 @@
                  * complex sanity (sane complexity)
                  *
-                 * The current image must be in the Deleting (image is merged)
-                 * or LockedRead (parent image) state if it is not the target.
+                 * The current medium must be in the Deleting (medium is merged)
+                 * or LockedRead (parent medium) state if it is not the target.
                  * If it is the target it must be in the LockedWrite state.
                  */
@@ -5543,5 +5590,5 @@
 
                 /*
-                 * Image must be the target, in the LockedRead state
+                 * Medium must be the target, in the LockedRead state
                  * or Deleting state where it is not allowed to be attached
                  * to a virtual machine.
@@ -5561,5 +5608,5 @@
                     uOpenFlags = VD_OPEN_FLAGS_READONLY;
 
-                /* Open the image */
+                /* Open the medium */
                 vrc = VDOpen(hdd,
                              pMedium->m->strFormat.c_str(),
@@ -5620,5 +5667,5 @@
         {
             throw setError(E_FAIL,
-                            tr("Could not merge the hard disk '%s' to '%s'%s"),
+                            tr("Could not merge the medium '%s' to '%s'%s"),
                             m->strLocationFull.raw(),
                             pTarget->m->strLocationFull.raw(),
@@ -5634,5 +5681,5 @@
     if (SUCCEEDED(rc))
     {
-        /* all hard disks but the target were successfully deleted by
+        /* all media but the target were successfully deleted by
          * VDMerge; reparent the last one and uninitialize deleted media. */
 
@@ -5642,5 +5689,5 @@
         {
             /* first, unregister the target since it may become a base
-             * hard disk which needs re-registration */
+             * medium which needs re-registration */
             rc2 = m->pVirtualBox->unregisterHardDisk(pTarget, NULL /*&fNeedsSaveSettings*/);
             AssertComRC(rc2);
@@ -5688,5 +5735,5 @@
         }
 
-        /* unregister and uninitialize all hard disks removed by the merge */
+        /* unregister and uninitialize all media removed by the merge */
         MediumLockList::Base::iterator lockListBegin =
             task.mpMediumLockList->GetBegin();
@@ -5702,5 +5749,5 @@
             const ComObjPtr<Medium> pMedium = mediumLock.GetMedium();
 
-            /* The target and all images not merged (readonly) are skipped */
+            /* The target and all media not merged (readonly) are skipped */
             if (   pMedium == pTarget
                 || pMedium->m->state == MediumState_LockedRead)
@@ -5714,11 +5761,11 @@
             AssertComRC(rc2);
 
-            /* now, uninitialize the deleted hard disk (note that
+            /* now, uninitialize the deleted medium (note that
              * due to the Deleting state, uninit() will not touch
              * the parent-child relationship so we need to
              * uninitialize each disk individually) */
 
-            /* note that the operation initiator hard disk (which is
-             * normally also the source hard disk) is a special case
+            /* note that the operation initiator medium (which is
+             * normally also the source medium) is a special case
              * -- there is one more caller added by Task to it which
              * we must release. Also, if we are in sync mode, the
@@ -5760,5 +5807,5 @@
         /* Here we come if either VDMerge() failed (in which case we
          * assume that it tried to do everything to make a further
-         * retry possible -- e.g. not deleted intermediate hard disks
+         * retry possible -- e.g. not deleted intermediate media
          * and so on) or VirtualBox::saveSettings() failed (where we
          * should have the original tree but with intermediate storage
@@ -5797,4 +5844,5 @@
 
     uint64_t size = 0, logicalSize = 0;
+    MediumVariant_T variant = MediumVariant_Standard;
     bool fGenerateUuid = false;
 
@@ -5825,5 +5873,5 @@
         try
         {
-            /* Open all hard disk images in the source chain. */
+            /* Open all media in the source chain. */
             MediumLockList::Base::const_iterator sourceListBegin =
                 task.mpSourceMediumLockList->GetBegin();
@@ -5841,5 +5889,5 @@
                 Assert(pMedium->m->state == MediumState_LockedRead);
 
-                /** Open all images in read-only mode. */
+                /** Open all media in read-only mode. */
                 vrc = VDOpen(hdd,
                              pMedium->m->strFormat.c_str(),
@@ -5849,5 +5897,5 @@
                 if (RT_FAILURE(vrc))
                     throw setError(E_FAIL,
-                                    tr("Could not open the hard disk storage unit '%s'%s"),
+                                    tr("Could not open the medium storage unit '%s'%s"),
                                     pMedium->m->strLocationFull.raw(),
                                     vdError(vrc).raw());
@@ -5876,5 +5924,5 @@
             try
             {
-                /* Open all hard disk images in the target chain. */
+                /* Open all media in the target chain. */
                 MediumLockList::Base::const_iterator targetListBegin =
                     task.mpTargetMediumLockList->GetBegin();
@@ -5899,5 +5947,5 @@
                             || pMedium->m->state == MediumState_LockedWrite);
 
-                    /* Open all images in appropriate mode. */
+                    /* Open all media in appropriate mode. */
                     vrc = VDOpen(targetHdd,
                                  pMedium->m->strFormat.c_str(),
@@ -5907,5 +5955,5 @@
                     if (RT_FAILURE(vrc))
                         throw setError(E_FAIL,
-                                       tr("Could not open the hard disk storage unit '%s'%s"),
+                                       tr("Could not open the medium storage unit '%s'%s"),
                                        pMedium->m->strLocationFull.raw(),
                                        vdError(vrc).raw());
@@ -5927,9 +5975,13 @@
                 if (RT_FAILURE(vrc))
                     throw setError(E_FAIL,
-                                    tr("Could not create the clone hard disk '%s'%s"),
+                                    tr("Could not create the clone medium '%s'%s"),
                                     targetLocation.raw(), vdError(vrc).raw());
 
                 size = VDGetFileSize(targetHdd, VD_LAST_IMAGE);
                 logicalSize = VDGetSize(targetHdd, VD_LAST_IMAGE) / _1M;
+                unsigned uImageFlags;
+                vrc = VDGetImageFlags(targetHdd, 0, &uImageFlags);
+                if (RT_SUCCESS(vrc))
+                    variant = (MediumVariant_T)uImageFlags;
             }
             catch (HRESULT aRC) { rc = aRC; }
@@ -5943,5 +5995,5 @@
     catch (HRESULT aRC) { rc = aRC; }
 
-    /* Only do the parent changes for newly created images. */
+    /* Only do the parent changes for newly created media. */
     if (SUCCEEDED(rc) && fCreatingTarget)
     {
@@ -5984,4 +6036,5 @@
             pTarget->m->size = size;
             pTarget->m->logicalSize = logicalSize;
+            pTarget->m->variant = variant;
         }
         else
@@ -6057,5 +6110,5 @@
             if (RT_FAILURE(vrc))
                 throw setError(E_FAIL,
-                                tr("Could not delete the hard disk storage unit '%s'%s"),
+                                tr("Could not delete the medium storage unit '%s'%s"),
                                 location.raw(), vdError(vrc).raw());
 
@@ -6094,4 +6147,5 @@
 
     uint64_t size = 0, logicalSize = 0;
+    MediumVariant_T variant = MediumVariant_Standard;
 
     try
@@ -6125,5 +6179,5 @@
         try
         {
-            /* Open all hard disk images in the target chain but the last. */
+            /* Open all media in the target chain but the last. */
             MediumLockList::Base::const_iterator targetListBegin =
                 task.mpMediumLockList->GetBegin();
@@ -6143,5 +6197,5 @@
                        || pMedium->m->state == MediumState_LockedRead);
 
-                /* Open all images in appropriate mode. */
+                /* Open all media in appropriate mode. */
                 vrc = VDOpen(hdd,
                              pMedium->m->strFormat.c_str(),
@@ -6151,9 +6205,9 @@
                 if (RT_FAILURE(vrc))
                     throw setError(E_FAIL,
-                                   tr("Could not open the hard disk storage unit '%s'%s"),
+                                   tr("Could not open the medium storage unit '%s'%s"),
                                    pMedium->m->strLocationFull.raw(),
                                    vdError(vrc).raw());
 
-                /* Done when we hit the image which should be reset */
+                /* Done when we hit the media which should be reset */
                 if (pMedium == this)
                     break;
@@ -6164,5 +6218,5 @@
             if (RT_FAILURE(vrc))
                 throw setError(E_FAIL,
-                               tr("Could not delete the hard disk storage unit '%s'%s"),
+                               tr("Could not delete the medium storage unit '%s'%s"),
                                location.raw(), vdError(vrc).raw());
 
@@ -6175,5 +6229,5 @@
             if (RT_FAILURE(vrc))
                 throw setError(E_FAIL,
-                                tr("Could not open the hard disk storage unit '%s'%s"),
+                                tr("Could not open the medium storage unit '%s'%s"),
                                 parentLocation.raw(), vdError(vrc).raw());
 
@@ -6181,5 +6235,5 @@
                                format.c_str(),
                                location.c_str(),
-                               /// @todo use the same image variant as before
+                               /// @todo use the same medium variant as before
                                VD_IMAGE_FLAGS_NONE,
                                NULL,
@@ -6191,9 +6245,13 @@
             if (RT_FAILURE(vrc))
                 throw setError(E_FAIL,
-                                tr("Could not create the differencing hard disk storage unit '%s'%s"),
+                                tr("Could not create the differencing medium storage unit '%s'%s"),
                                 location.raw(), vdError(vrc).raw());
 
             size = VDGetFileSize(hdd, VD_LAST_IMAGE);
             logicalSize = VDGetSize(hdd, VD_LAST_IMAGE) / _1M;
+            unsigned uImageFlags;
+            vrc = VDGetImageFlags(hdd, 0, &uImageFlags);
+            if (RT_SUCCESS(vrc))
+                variant = (MediumVariant_T)uImageFlags;
         }
         catch (HRESULT aRC) { rc = aRC; }
@@ -6207,4 +6265,5 @@
     m->size = size;
     m->logicalSize = logicalSize;
+    m->variant = variant;
 
     if (task.isAsync())
@@ -6216,5 +6275,5 @@
 
     /* Note that in sync mode, it's the caller's responsibility to
-     * unlock the hard disk */
+     * unlock the medium. */
 
     return rc;
@@ -6244,5 +6303,5 @@
         try
         {
-            /* Open all hard disk images in the chain. */
+            /* Open all media in the chain. */
             MediumLockList::Base::const_iterator mediumListBegin =
                 task.mpMediumLockList->GetBegin();
@@ -6266,5 +6325,5 @@
                     Assert(pMedium->m->state == MediumState_LockedRead);
 
-                /** Open all images but last in read-only mode. */
+                /** Open all media but last in read-only mode. */
                 vrc = VDOpen(hdd,
                              pMedium->m->strFormat.c_str(),
@@ -6274,5 +6333,5 @@
                 if (RT_FAILURE(vrc))
                     throw setError(E_FAIL,
-                                   tr("Could not open the hard disk storage unit '%s'%s"),
+                                   tr("Could not open the medium storage unit '%s'%s"),
                                    pMedium->m->strLocationFull.raw(),
                                    vdError(vrc).raw());
@@ -6291,13 +6350,13 @@
                 if (vrc == VERR_NOT_SUPPORTED)
                     throw setError(VBOX_E_NOT_SUPPORTED,
-                                   tr("Compacting is not yet supported for hard disk '%s'"),
+                                   tr("Compacting is not yet supported for medium '%s'"),
                                    location.raw());
                 else if (vrc == VERR_NOT_IMPLEMENTED)
                     throw setError(E_NOTIMPL,
-                                   tr("Compacting is not implemented, hard disk '%s'"),
+                                   tr("Compacting is not implemented, medium '%s'"),
                                    location.raw());
                 else
                     throw setError(E_FAIL,
-                                   tr("Could not compact hard disk '%s'%s"),
+                                   tr("Could not compact medium '%s'%s"),
                                    location.raw(),
                                    vdError(vrc).raw());
@@ -6311,5 +6370,5 @@
 
     /* Everything is explicitly unlocked when the task exits,
-     * as the task destruction also destroys the image chain. */
+     * as the task destruction also destroys the media chain. */
 
     return rc;
Index: /trunk/src/VBox/Main/SnapshotImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/SnapshotImpl.cpp	(revision 31062)
+++ /trunk/src/VBox/Main/SnapshotImpl.cpp	(revision 31063)
@@ -2067,5 +2067,8 @@
 
             MediumType_T type = pHD->getType();
-            if (type != MediumType_Writethrough) // writethrough images are unaffected by snapshots, so do nothing for them
+            // writethrough and shareable images are unaffected by snapshots,
+            // so do nothing for them
+            if (   type != MediumType_Writethrough
+                && type != MediumType_Shareable)
             {
                 // normal or immutable media need attention
@@ -2283,8 +2286,10 @@
 
             {
-                // writethrough images are unaffected by snapshots, skip them
+                // writethrough and shareable images are unaffected by
+                // snapshots, skip them
                 AutoReadLock medlock(pHD COMMA_LOCKVAL_SRC_POS);
                 MediumType_T type = pHD->getType();
-                if (type == MediumType_Writethrough)
+                if (   type == MediumType_Writethrough
+                    || type == MediumType_Shareable)
                     continue;
             }
@@ -2757,6 +2762,8 @@
     AutoWriteLock alock(aHD COMMA_LOCKVAL_SRC_POS);
 
-    // Medium must not be writethrough at this point
-    AssertReturn(aHD->getType() != MediumType_Writethrough, E_FAIL);
+    // Medium must not be writethrough/shareable at this point
+    MediumType_T type = aHD->getType();
+    AssertReturn(   type != MediumType_Writethrough
+                 && type != MediumType_Shareable, E_FAIL);
 
     aMediumLockList = NULL;
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 31062)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 31063)
@@ -8567,5 +8567,5 @@
   <interface
     name="IMedium" extends="$unknown"
-    uuid="1d578f43-5ef1-4415-b556-7592d3ccdc8f"
+    uuid="858ea9d3-9ade-4aa7-91b7-d8a40f8f9b16"
     wsmap="managed"
   >
@@ -8950,4 +8950,12 @@
           automatically; call <link to="#refreshState"/> for that.
         </note>
+      </desc>
+    </attribute>
+
+    <attribute name="variant" type="MediumVariant" readonly="yes">
+      <desc>
+        Returns the storage format variant information for this medium.
+        Before <link to="#refreshState"/> is called this method returns
+        an undefined value.
       </desc>
     </attribute>
Index: /trunk/src/VBox/Main/include/MediumImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/MediumImpl.h	(revision 31062)
+++ /trunk/src/VBox/Main/include/MediumImpl.h	(revision 31063)
@@ -97,4 +97,5 @@
     STDMETHOD(COMSETTER(Description))(IN_BSTR aDescription);
     STDMETHOD(COMGETTER(State))(MediumState_T *aState);
+    STDMETHOD(COMGETTER(Variant))(MediumVariant_T *aVariant);
     STDMETHOD(COMGETTER(Location))(BSTR *aLocation);
     STDMETHOD(COMSETTER(Location))(IN_BSTR aLocation);
@@ -155,4 +156,5 @@
     const Guid& getId() const;
     MediumState_T getState() const;
+    MediumVariant_T getVariant() const;
     const Utf8Str& getLocation() const;
     const Utf8Str& getLocationFull() const;
Index: /trunk/src/VBox/Main/xml/Settings.cpp
===================================================================
--- /trunk/src/VBox/Main/xml/Settings.cpp	(revision 31062)
+++ /trunk/src/VBox/Main/xml/Settings.cpp	(revision 31063)
@@ -923,9 +923,5 @@
                 med.hdType = MediumType_Writethrough;
             else if (strType == "SHAREABLE")
-            {
-                /// @todo remove check once the medium type is implemented
-                throw ConfigFileError(this, &elmMedium, N_("HardDisk/@type attribute of Shareable is not implemented yet"));
                 med.hdType = MediumType_Shareable;
-            }
             else
                 throw ConfigFileError(this, &elmMedium, N_("HardDisk/@type attribute must be one of Normal, Immutable or Writethrough"));
