Index: /trunk/doc/manual/user_ChangeLogImpl.xml
===================================================================
--- /trunk/doc/manual/user_ChangeLogImpl.xml	(revision 37823)
+++ /trunk/doc/manual/user_ChangeLogImpl.xml	(revision 37824)
@@ -36,9 +36,15 @@
       <listitem>
         <para>Guest Additions: modules and features now are represented as facilities
-          to have a common interface for frontends.</para>
-      </listitem>
-
-      <listitem>
-        <para>New Networking Mode: <emphasis>UDP Tunnel</emphasis>. Allows to
+          to have a common interface for frontends</para>
+      </listitem>
+
+      <listitem>
+        <para>Networking: new network attachment mode "Generic Driver", which
+          offers an open plugin architecture for arbitrary and separately
+          distributable virtual network implementations</para>
+      </listitem>
+
+      <listitem>
+        <para>New Networking Mode <emphasis>UDP Tunnel</emphasis>: allows to
         interconnect VMs running on different hosts easily and transparently,
         see <xref linkend="networkingmodes" /></para>
@@ -87,6 +93,11 @@
 
       <listitem>
+        <para>GUI: decrease time before showing the VM configuration
+          dialog</para>
+      </listitem>
+
+      <listitem>
         <para>VBoxManage: changed syntax of the <emphasis>guestcontrol</emphasis>
-          command group, fixed various bugs</para>
+          command group, fixed various bugs, removed obsolete options</para>
       </listitem>
 
@@ -102,11 +113,45 @@
 
       <listitem>
+        <para>Settings: provide better diagnostics if a single medium is used
+          twice in a VM config</para>
+      </listitem>
+
+      <listitem>
+        <para>Settings: provide better diagnostics for errors in medium
+          create/merge/clone operations, and fix memory leaks in error
+          cases</para>
+      </listitem>
+
+      <listitem>
+        <para>Storage: ATA/SATA drives can be marked as non-rotational, i.e.
+          the guest OS will detect them as a SSD if supported, which can
+          improve performance</para>
+      </listitem>
+
+      <listitem>
         <para>Storage: virtual CD/DVD images will be detached if the guest
-          ejects the medium</para>
+          ejects the medium, unless the drive is marked to handle ejects only
+          on a temporary basis</para>
+      </listitem>
+
+      <listitem>
+        <para>Storage: the medium UUID can be changed again when attaching
+          a medium for the first time, which allows using images which are
+          exact duplicates including the UUID</para>
       </listitem>
 
       <listitem>
         <para>Storage: fixed possible data corruption under certain circumstances
-          whith VHD and Parallels images (bug #9150)</para>
+          with VHD and Parallels images (bug #9150)</para>
+      </listitem>
+
+      <listitem>
+        <para>Storage: fixed unnecessary expansion when cloning differential
+          images in VDI format</para>
+      </listitem>
+
+      <listitem>
+        <para>Storage: fixed detection code to handle empty files for VDI and
+          VMDK format</para>
       </listitem>
 
@@ -129,4 +174,9 @@
       <listitem>
         <para>NAT: reduced memory footprint</para>
+      </listitem>
+
+      <listitem>
+        <para>Networking: workaround for a bug in wireshark when operating
+          directly on a capture file created by VirtualBox</para>
       </listitem>
 
@@ -152,4 +202,14 @@
         <para>Sources: fixed USB 2.0 support using extension packs for non-official
           builds</para>
+      </listitem>
+
+      <listitem>
+        <para>Webservice: fixed timeout handling with HTTP 1.1 keepalive, and
+          be more robust when connections fail</para>
+      </listitem>
+
+      <listitem>
+        <para>VBoxSVC: fixed regression when several clients trigger autostart
+          simultaneously</para>
       </listitem>
 
@@ -175,4 +235,14 @@
         <para>Guest Additions: fixed high CPU usage while executing guest programs
           from the host</para>
+      </listitem>
+
+      <listitem>
+        <para>Main: fixed incorrect handling of the medium location for media
+          which are not file based (e.g. iSCSI), which resulted in confusing
+          location values in many places</para>
+      </listitem>
+
+      <listitem>
+        <para>JAX-WS client bindings: fixed resource leak</para>
       </listitem>
 
Index: /trunk/include/VBox/settings.h
===================================================================
--- /trunk/include/VBox/settings.h	(revision 37823)
+++ /trunk/include/VBox/settings.h	(revision 37824)
@@ -807,4 +807,5 @@
           fPassThrough(false),
           fTempEject(false),
+          fNonRotational(false),
           lPort(0),
           lDevice(0)
@@ -821,4 +822,7 @@
     // VM config or not:
     bool                fTempEject;
+
+    // Whether the medium is non-rotational:
+    bool                fNonRotational;
 
     int32_t             lPort;
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 37823)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 37824)
@@ -467,4 +467,5 @@
                      "                            [--passthrough on|off]\n"
                      "                            [--tempeject on|off]\n"
+                     "                            [--nonrotational on|off]\n"
                      "                            [--bandwidthgroup <name>]\n"
                      "                            [--forceunmount]\n"
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp	(revision 37823)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp	(revision 37824)
@@ -53,4 +53,5 @@
     { "--passthrough",      'h', RTGETOPT_REQ_STRING },
     { "--tempeject",        'e', RTGETOPT_REQ_STRING },
+    { "--nonrotational",    'n', RTGETOPT_REQ_STRING },
     { "--bandwidthgroup",   'b', RTGETOPT_REQ_STRING },
     { "--forceunmount",     'f', RTGETOPT_REQ_NOTHING },
@@ -86,4 +87,5 @@
     const char *pszPassThrough = NULL;
     const char *pszTempEject = NULL;
+    const char *pszNonRotational = NULL;
     const char *pszBandwidthGroup = NULL;
     Bstr bstrNewUuid;
@@ -178,4 +180,13 @@
             }
 
+            case 'n':   // nonrotational <on|off>
+            {
+                if (ValueUnion.psz)
+                    pszNonRotational = ValueUnion.psz;
+                else
+                    rc = E_FAIL;
+                break;
+            }
+
             case 'b':   // bandwidthgroup <name>
             {
@@ -410,5 +421,5 @@
                 if (ctlType == StorageControllerType_I82078)        // floppy controller
                     devTypeRequested = DeviceType_Floppy;
-                else if (pszMedium)
+                else
                 {
                     /*
@@ -428,17 +439,21 @@
                         mediumAttachment->COMGETTER(Type)(&deviceType);
 
-                        ComPtr<IMedium> pExistingMedium;
-                        rc = findMedium(a, pszMedium, deviceType, true /* fSilent */,
-                                        pExistingMedium);
-                        if (SUCCEEDED(rc) && pExistingMedium)
+                        if (pszMedium)
                         {
-                            if (    (deviceType == DeviceType_DVD)
-                                 || (deviceType == DeviceType_HardDisk)
-                               )
-                                devTypeRequested = deviceType;
+                            ComPtr<IMedium> pExistingMedium;
+                            rc = findMedium(a, pszMedium, deviceType, true /* fSilent */,
+                                            pExistingMedium);
+                            if (SUCCEEDED(rc) && pExistingMedium)
+                            {
+                                if (    (deviceType == DeviceType_DVD)
+                                     || (deviceType == DeviceType_HardDisk)
+                                   )
+                                    devTypeRequested = deviceType;
+                            }
                         }
+                        else
+                            devTypeRequested = deviceType;
                     }
                 }
-                /* for all other cases lets ask the user what type of drive it is */
             }
 
@@ -573,16 +588,25 @@
             else
             {
-                Bstr bstrMedium(pszMedium);
-                if (bstrMedium.isEmpty())
-                    throw Utf8Str("Missing --medium argument");
-
-                rc = findOrOpenMedium(a, pszMedium, devTypeRequested,
-                                      pMedium2Mount, fSetNewUuid, NULL);
-                if (FAILED(rc) || !pMedium2Mount)
-                    throw Utf8StrFmt("Invalid UUID or filename \"%s\"", pszMedium);
+                if (!pszMedium)
+                {
+                    ComPtr<IMediumAttachment> mediumAttachment;
+                    rc = machine->GetMediumAttachment(Bstr(pszCtl).raw(), port,
+                                                      device,
+                                                      mediumAttachment.asOutParam());
+                    if (FAILED(rc))
+                        throw Utf8Str("Missing --medium argument");
+                }
+                else
+                {
+                    Bstr bstrMedium(pszMedium);
+                    rc = findOrOpenMedium(a, pszMedium, devTypeRequested,
+                                          pMedium2Mount, fSetNewUuid, NULL);
+                    if (FAILED(rc) || !pMedium2Mount)
+                        throw Utf8StrFmt("Invalid UUID or filename \"%s\"", pszMedium);
+                }
             }
 
             // set medium/parent medium UUID, if so desired
-            if (fSetNewUuid || fSetNewParentUuid)
+            if (pMedium2Mount && (fSetNewUuid || fSetNewParentUuid))
             {
                 CHECK_ERROR(pMedium2Mount, SetIDs(fSetNewUuid, bstrNewUuid.raw(),
@@ -605,24 +629,35 @@
             }
 
-            switch (devTypeRequested)
-            {
-                case DeviceType_DVD:
-                case DeviceType_Floppy:
-                {
-                    if (!fRunTime)
+            if (pszMedium)
+            {
+                switch (devTypeRequested)
+                {
+                    case DeviceType_DVD:
+                    case DeviceType_Floppy:
                     {
-                        ComPtr<IMediumAttachment> mediumAttachment;
-                        // check if there is a dvd/floppy drive at the given location, if not attach one first
-                        rc = machine->GetMediumAttachment(Bstr(pszCtl).raw(),
-                                                          port,
-                                                          device,
-                                                          mediumAttachment.asOutParam());
-                        if (SUCCEEDED(rc))
+                        if (!fRunTime)
                         {
-                            DeviceType_T deviceType;
-                            mediumAttachment->COMGETTER(Type)(&deviceType);
-                            if (deviceType != devTypeRequested)
+                            ComPtr<IMediumAttachment> mediumAttachment;
+                            // check if there is a dvd/floppy drive at the given location, if not attach one first
+                            rc = machine->GetMediumAttachment(Bstr(pszCtl).raw(),
+                                                              port,
+                                                              device,
+                                                              mediumAttachment.asOutParam());
+                            if (SUCCEEDED(rc))
                             {
-                                machine->DetachDevice(Bstr(pszCtl).raw(), port, device);
+                                DeviceType_T deviceType;
+                                mediumAttachment->COMGETTER(Type)(&deviceType);
+                                if (deviceType != devTypeRequested)
+                                {
+                                    machine->DetachDevice(Bstr(pszCtl).raw(), port, device);
+                                    rc = machine->AttachDevice(Bstr(pszCtl).raw(),
+                                                               port,
+                                                               device,
+                                                               devTypeRequested,    // DeviceType_DVD or DeviceType_Floppy
+                                                               NULL);
+                                }
+                            }
+                            else
+                            {
                                 rc = machine->AttachDevice(Bstr(pszCtl).raw(),
                                                            port,
@@ -632,36 +667,28 @@
                             }
                         }
-                        else
+
+                        if (pMedium2Mount)
                         {
-                            rc = machine->AttachDevice(Bstr(pszCtl).raw(),
-                                                       port,
-                                                       device,
-                                                       devTypeRequested,    // DeviceType_DVD or DeviceType_Floppy
-                                                       NULL);
+                            CHECK_ERROR(machine, MountMedium(Bstr(pszCtl).raw(),
+                                                             port,
+                                                             device,
+                                                             pMedium2Mount,
+                                                             fForceUnmount));
                         }
+                    } // end DeviceType_DVD or DeviceType_Floppy:
+                    break;
+
+                    case DeviceType_HardDisk:
+                    {
+                        // if there is anything attached at the given location, remove it
+                        machine->DetachDevice(Bstr(pszCtl).raw(), port, device);
+                        CHECK_ERROR(machine, AttachDevice(Bstr(pszCtl).raw(),
+                                                          port,
+                                                          device,
+                                                          DeviceType_HardDisk,
+                                                          pMedium2Mount));
                     }
-
-                    if (pMedium2Mount)
-                    {
-                        CHECK_ERROR(machine, MountMedium(Bstr(pszCtl).raw(),
-                                                         port,
-                                                         device,
-                                                         pMedium2Mount,
-                                                         fForceUnmount));
-                    }
-                } // end DeviceType_DVD or DeviceType_Floppy:
-                break;
-
-                case DeviceType_HardDisk:
-                {
-                    // if there is anything attached at the given location, remove it
-                    machine->DetachDevice(Bstr(pszCtl).raw(), port, device);
-                    CHECK_ERROR(machine, AttachDevice(Bstr(pszCtl).raw(),
-                                                      port,
-                                                      device,
-                                                      DeviceType_HardDisk,
-                                                      pMedium2Mount));
-                }
-                break;
+                    break;
+                }
             }
         }
@@ -714,4 +741,30 @@
                 else
                     throw Utf8StrFmt("Invalid --tempeject argument '%s'", pszTempEject);
+            }
+            else
+                throw Utf8StrFmt("Couldn't find the controller attachment for the controller '%s'\n", pszCtl);
+        }
+
+        if (   pszNonRotational
+            && (SUCCEEDED(rc)))
+        {
+            ComPtr<IMediumAttachment> mattach;
+            CHECK_ERROR(machine, GetMediumAttachment(Bstr(pszCtl).raw(), port,
+                                                     device, mattach.asOutParam()));
+
+            if (SUCCEEDED(rc))
+            {
+                if (!RTStrICmp(pszNonRotational, "on"))
+                {
+                    CHECK_ERROR(machine, NonRotationalDevice(Bstr(pszCtl).raw(),
+                                                             port, device, TRUE));
+                }
+                else if (!RTStrICmp(pszNonRotational, "off"))
+                {
+                    CHECK_ERROR(machine, NonRotationalDevice(Bstr(pszCtl).raw(),
+                                                             port, device, FALSE));
+                }
+                else
+                    throw Utf8StrFmt("Invalid --nonrotational argument '%s'", pszNonRotational);
             }
             else
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.cpp	(revision 37823)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.cpp	(revision 37824)
@@ -552,4 +552,5 @@
     , mAttIsPassthrough (false)
     , mAttIsTempEject (false)
+    , mAttIsNonRotational (false)
 {
     /* Check for proper parent type */
@@ -610,4 +611,9 @@
 }
 
+bool AttachmentItem::attIsNonRotational() const
+{
+    return mAttIsNonRotational;
+}
+
 void AttachmentItem::setAttSlot (const StorageSlot &aAttSlot)
 {
@@ -635,4 +641,9 @@
 {
     mAttIsTempEject = aIsAttTempEject;
+}
+
+void AttachmentItem::setAttIsNonRotational (bool aIsAttNonRotational)
+{
+    mAttIsNonRotational = aIsAttNonRotational;
 }
 
@@ -1096,4 +1107,11 @@
             return false;
         }
+        case R_AttIsNonRotational:
+        {
+            if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
+                if (item->rtti() == AbstractItem::Type_AttachmentItem)
+                    return static_cast <AttachmentItem*> (item)->attIsNonRotational();
+            return false;
+        }
         case R_AttSize:
         {
@@ -1311,4 +1329,15 @@
                 {
                     static_cast <AttachmentItem*> (item)->setAttIsTempEject (aValue.toBool());
+                    emit dataChanged (aIndex, aIndex);
+                    return true;
+                }
+            return false;
+        }
+        case R_AttIsNonRotational:
+        {
+            if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
+                if (item->rtti() == AbstractItem::Type_AttachmentItem)
+                {
+                    static_cast <AttachmentItem*> (item)->setAttIsNonRotational (aValue.toBool());
                     emit dataChanged (aIndex, aIndex);
                     return true;
@@ -1801,4 +1830,5 @@
     connect (mCbPassthrough, SIGNAL (stateChanged (int)), this, SLOT (setInformation()));
     connect (mCbTempEject, SIGNAL (stateChanged (int)), this, SLOT (setInformation()));
+    connect (mCbNonRotational, SIGNAL (stateChanged (int)), this, SLOT (setInformation()));
 
     /* Applying language settings */
@@ -1865,4 +1895,5 @@
                     storageAttachmentData.m_fAttachmentPassthrough = attachment.GetPassthrough();
                     storageAttachmentData.m_fAttachmentTempEject = attachment.GetTemporaryEject();
+                    storageAttachmentData.m_fAttachmentNonRotational = attachment.GetNonRotational();
                     CMedium comMedium(attachment.GetMedium());
                     VBoxMedium vboxMedium;
@@ -1925,4 +1956,5 @@
             mStorageModel->setData(attachmentIndex, attachmentData.m_fAttachmentPassthrough, StorageModel::R_AttIsPassthrough);
             mStorageModel->setData(attachmentIndex, attachmentData.m_fAttachmentTempEject, StorageModel::R_AttIsTempEject);
+            mStorageModel->setData(attachmentIndex, attachmentData.m_fAttachmentNonRotational, StorageModel::R_AttIsNonRotational);
         }
     }
@@ -1977,4 +2009,5 @@
             attachmentData.m_fAttachmentPassthrough = mStorageModel->data(attachmentIndex, StorageModel::R_AttIsPassthrough).toBool();
             attachmentData.m_fAttachmentTempEject = mStorageModel->data(attachmentIndex, StorageModel::R_AttIsTempEject).toBool();
+            attachmentData.m_fAttachmentNonRotational = mStorageModel->data(attachmentIndex, StorageModel::R_AttIsNonRotational).toBool();
             attachmentData.m_strAttachmentMediumId = mStorageModel->data(attachmentIndex, StorageModel::R_AttMediumId).toString();
 
@@ -2417,4 +2450,8 @@
                 mCbTempEject->setChecked (!isHostDrive && mStorageModel->data (index, StorageModel::R_AttIsTempEject).toBool());
 
+                /* Getting NonRotational state */
+                mCbNonRotational->setVisible (device == KDeviceType_HardDisk);
+                mCbNonRotational->setChecked (mStorageModel->data (index, StorageModel::R_AttIsNonRotational).toBool());
+
                 /* Update optional widgets visibility */
                 updateAdditionalObjects (device);
@@ -2489,4 +2526,8 @@
                 if (!mStorageModel->data (index, StorageModel::R_AttIsHostDrive).toBool())
                     mStorageModel->setData (index, mCbTempEject->isChecked(), StorageModel::R_AttIsTempEject);
+            }
+            else if (sdr == mCbNonRotational)
+            {
+                mStorageModel->setData (index, mCbNonRotational->isChecked(), StorageModel::R_AttIsNonRotational);
             }
             break;
@@ -3397,4 +3438,5 @@
         bool fAttachmentPassthrough = attachmentData.m_fAttachmentPassthrough;
         bool fAttachmentTempEject = attachmentData.m_fAttachmentTempEject;
+        bool fAttachmentNonRotational = attachmentData.m_fAttachmentNonRotational;
         /* Get GUI medium object: */
         VBoxMedium vboxMedium = vboxGlobal().findMedium(strAttachmentMediumId);
@@ -3426,4 +3468,10 @@
                     }
                 }
+                else if (attachmentDeviceType == KDeviceType_HardDisk)
+                {
+                    m_machine.NonRotationalDevice(strControllerName, iAttachmentPort, iAttachmentDevice, fAttachmentNonRotational);
+                    /* Check that machine is OK: */
+                    fSuccess = m_machine.isOk();
+                }
             }
             else
@@ -3461,4 +3509,5 @@
         bool fAttachmentPassthrough = attachmentData.m_fAttachmentPassthrough;
         bool fAttachmentTempEject = attachmentData.m_fAttachmentTempEject;
+        bool fAttachmentNonRotational = attachmentData.m_fAttachmentNonRotational;
         KDeviceType attachmentDeviceType = attachmentData.m_attachmentType;
 
@@ -3497,4 +3546,13 @@
                     }
                 }
+                if (fSuccess)
+                {
+                    if (attachmentDeviceType == KDeviceType_DVD)
+                    {
+                        m_machine.NonRotationalDevice(strControllerName, iAttachmentPort, iAttachmentDevice, fAttachmentNonRotational);
+                        /* Check that machine is OK: */
+                        fSuccess = m_machine.isOk();
+                    }
+                }
             }
             else
@@ -3571,4 +3629,5 @@
     mCbPassthrough->setEnabled(isMachineOffline());
     mCbTempEject->setEnabled(isMachineInValidMode());
+    mCbNonRotational->setEnabled(isMachineOffline());
     mLsInformation->setEnabled(isMachineInValidMode());
     mLbHDFormat->setEnabled(isMachineInValidMode());
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.h	(revision 37823)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.h	(revision 37824)
@@ -357,4 +357,5 @@
     bool attIsPassthrough() const;
     bool attIsTempEject() const;
+    bool attIsNonRotational() const;
 
     void setAttSlot (const StorageSlot &aAttSlot);
@@ -363,4 +364,5 @@
     void setAttIsPassthrough (bool aPassthrough);
     void setAttIsTempEject (bool aTempEject);
+    void setAttIsNonRotational (bool aNonRotational);
 
     QString attSize() const;
@@ -394,4 +396,5 @@
     bool mAttIsPassthrough;
     bool mAttIsTempEject;
+    bool mAttIsNonRotational;
 
     QString mAttName;
@@ -448,4 +451,5 @@
         R_AttIsPassthrough,
         R_AttIsTempEject,
+        R_AttIsNonRotational,
         R_AttSize,
         R_AttLogicalSize,
@@ -562,5 +566,6 @@
         , m_strAttachmentMediumId(QString())
         , m_fAttachmentPassthrough(false)
-        , m_fAttachmentTempEject(false) {}
+        , m_fAttachmentTempEject(false)
+        , m_fAttachmentNonRotational(false) {}
     /* Functions: */
     bool equal(const UIDataSettingsMachineStorageAttachment &other) const
@@ -571,5 +576,6 @@
                (m_strAttachmentMediumId == other.m_strAttachmentMediumId) &&
                (m_fAttachmentPassthrough == other.m_fAttachmentPassthrough) &&
-               (m_fAttachmentTempEject == other.m_fAttachmentTempEject);
+               (m_fAttachmentTempEject == other.m_fAttachmentTempEject) &&
+               (m_fAttachmentNonRotational == other.m_fAttachmentNonRotational);
     }
     /* Operators: */
@@ -583,4 +589,5 @@
     bool m_fAttachmentPassthrough;
     bool m_fAttachmentTempEject;
+    bool m_fAttachmentNonRotational;
 };
 typedef UISettingsCache<UIDataSettingsMachineStorageAttachment> UICacheSettingsMachineStorageAttachment;
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.ui
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.ui	(revision 37823)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.ui	(revision 37824)
@@ -339,4 +339,20 @@
          </widget>
         </item>
+        <item row="2" column="2" >
+         <widget class="QCheckBox" name="mCbNonRotational" >
+          <property name="sizePolicy" >
+           <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="whatsThis" >
+           <string>When checked, this marks the medium as non-rotational storage (SSD).</string>
+          </property>
+          <property name="text" >
+           <string>&amp;Solid-state drive</string>
+          </property>
+         </widget>
+        </item>
         <item row="3" column="0" colspan="3" >
          <widget class="QILabelSeparator" native="1" name="mLsInformation" >
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 37823)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 37824)
@@ -4691,4 +4691,43 @@
     </method>
 
+    <method name="nonRotationalDevice">
+      <desc>
+        Sets a flag in the device information which indicates that the medium
+        is not based on rotational technology, i.e. that the access times are
+        more or less independent of the position on the medium. This may or may
+        not be supported by a particular drive, and is silently ignored in the
+        latter case. At the moment only hard disks (which is a misnomer in this
+        context) accept this setting. Changing the setting while the VM is
+        running is forbidden. The device must already exist; see
+        <link to="IMachine::attachDevice"/> for how to attach a new device.
+
+        The @a controllerPort and @a device parameters specify the device slot and
+        have have the same meaning as with <link to="IMachine::attachDevice" />.
+
+        <result name="E_INVALIDARG">
+          SATA device, SATA port, IDE port or IDE slot out of range.
+        </result>
+        <result name="VBOX_E_INVALID_OBJECT_STATE">
+          Attempt to modify an unregistered virtual machine.
+        </result>
+        <result name="VBOX_E_INVALID_VM_STATE">
+          Invalid machine state.
+        </result>
+
+      </desc>
+      <param name="name" type="wstring" dir="in">
+        <desc>Name of the storage controller.</desc>
+      </param>
+      <param name="controllerPort" type="long" dir="in">
+        <desc>Storage controller port.</desc>
+      </param>
+      <param name="device" type="long" dir="in">
+        <desc>Device slot in the given port.</desc>
+      </param>
+      <param name="nonRotational" type="boolean" dir="in">
+        <desc>New value for the non-rotational device flag.</desc>
+      </param>
+    </method>
+
     <method name="setBandwidthGroupForDevice">
       <desc>
@@ -9840,4 +9879,8 @@
       <desc>Signals that the removable medium has been ejected. This is not
         necessarily equivalent to having a @c null medium association.</desc>
+    </attribute>
+
+    <attribute name="nonRotational" type="boolean" readonly="yes">
+      <desc>Whether the associated medium is non-rotational.</desc>
     </attribute>
 
Index: /trunk/src/VBox/Main/include/MachineImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/MachineImpl.h	(revision 37823)
+++ /trunk/src/VBox/Main/include/MachineImpl.h	(revision 37824)
@@ -478,4 +478,5 @@
     STDMETHOD(PassthroughDevice)(IN_BSTR aControllerName, LONG aControllerPort, LONG aDevice, BOOL aPassthrough);
     STDMETHOD(TemporaryEjectDevice)(IN_BSTR aControllerName, LONG aControllerPort, LONG aDevice, BOOL aTempEject);
+    STDMETHOD(NonRotationalDevice)(IN_BSTR aControllerName, LONG aControllerPort, LONG aDevice, BOOL aNonRotational);
     STDMETHOD(SetBandwidthGroupForDevice)(IN_BSTR aControllerName, LONG aControllerPort,
                                           LONG aDevice, IBandwidthGroup *aBandwidthGroup);
Index: /trunk/src/VBox/Main/include/MediumAttachmentImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/MediumAttachmentImpl.h	(revision 37823)
+++ /trunk/src/VBox/Main/include/MediumAttachmentImpl.h	(revision 37824)
@@ -50,4 +50,5 @@
                  bool fPassthrough,
                  bool fTempEject,
+                 bool fNonRotational,
                  const Utf8Str &strBandwidthGroup);
     void uninit();
@@ -65,4 +66,5 @@
     STDMETHOD(COMGETTER(TemporaryEject))(BOOL *aTemporaryEject);
     STDMETHOD(COMGETTER(IsEjected))(BOOL *aIsEjected);
+    STDMETHOD(COMGETTER(NonRotational))(BOOL *aNonRotational);
     STDMETHOD(COMGETTER(BandwidthGroup))(IBandwidthGroup **aBwGroup);
 
@@ -83,4 +85,5 @@
     bool getPassthrough() const;
     bool getTempEject() const;
+    bool getNonRotational() const;
     const Utf8Str& getBandwidthGroup() const;
 
@@ -95,4 +98,7 @@
     /** Must be called from under this object's write lock. */
     void updateTempEject(bool aTempEject);
+
+    /** Must be called from under this object's write lock. */
+    void updateNonRotational(bool aNonRotational);
 
     /** Must be called from under this object's write lock. */
Index: /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 37823)
+++ /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 37824)
@@ -316,4 +316,6 @@
 #endif
 
+static const char *const g_apszIDEDrives[4] =
+    { "PrimaryMaster", "PrimarySlave", "SecondaryMaster", "SecondarySlave" };
 
 class ConfigError : public RTCError
@@ -1571,6 +1573,4 @@
                         for (uint32_t j = 0; j < 4; ++j)
                         {
-                            static const char * const s_apszConfig[4] =
-                            { "PrimaryMaster", "PrimarySlave", "SecondaryMaster", "SecondarySlave" };
                             static const char * const s_apszBiosConfig[4] =
                             { "SataPrimaryMasterLUN", "SataPrimarySlaveLUN", "SataSecondaryMasterLUN", "SataSecondarySlaveLUN" };
@@ -1578,5 +1578,5 @@
                             LONG lPortNumber = -1;
                             hrc = ctrls[i]->GetIDEEmulationPort(j, &lPortNumber);           H();
-                            InsertConfigInteger(pCfg, s_apszConfig[j], lPortNumber);
+                            InsertConfigInteger(pCfg, g_apszIDEDrives[j], lPortNumber);
                             if (pBiosCfg)
                                 InsertConfigInteger(pBiosCfg, s_apszBiosConfig[j], lPortNumber);
@@ -2861,8 +2861,9 @@
         DeviceType_T lType;
         hrc = pMediumAtt->COMGETTER(Type)(&lType);                                          H();
+        BOOL fNonRotational;
+        hrc = pMediumAtt->COMGETTER(NonRotational)(&fNonRotational);                        H();
 
         unsigned uLUN;
         PCFGMNODE pLunL0 = NULL;
-        PCFGMNODE pCfg = NULL;
         hrc = Console::convertBusPortDeviceToLun(enmBus, lPort, lDev, uLUN);                H();
 
@@ -2912,4 +2913,31 @@
         InsertConfigNode(pCtlInst, Utf8StrFmt("LUN#%u", uLUN).c_str(), &pLunL0);
 
+        PCFGMNODE pCfg = CFGMR3GetChild(pCtlInst, "Config");
+        if (pCfg)
+        {
+            if (!strcmp(pcszDevice, "piix3ide"))
+            {
+                PCFGMNODE pDrive = CFGMR3GetChild(pCfg, g_apszIDEDrives[uLUN]);
+                if (!pDrive)
+                    InsertConfigNode(pCfg, g_apszIDEDrives[uLUN], &pDrive);
+                PCFGMNODE pNonRot = CFGMR3GetChild(pCtlInst, "NonRotationalMedium");
+                if (pNonRot)
+                    CFGMR3RemoveNode(pNonRot);
+                InsertConfigInteger(pDrive, "NonRotationalMedium", !!fNonRotational);
+            }
+            else if (!strcmp(pcszDevice, "ahci"))
+            {
+                Utf8Str strPort = Utf8StrFmt("Port%u", uLUN);
+                PCFGMNODE pDrive = CFGMR3GetChild(pCfg, strPort.c_str());
+                if (!pDrive)
+                    InsertConfigNode(pCfg, strPort.c_str(), &pDrive);
+                PCFGMNODE pNonRot = CFGMR3GetChild(pCtlInst, "NonRotationalMedium");
+                if (pNonRot)
+                    CFGMR3RemoveNode(pNonRot);
+                InsertConfigInteger(pDrive, "NonRotationalMedium", !!fNonRotational);
+            }
+        }
+        /** @todo add SCSI/SAS support once the SSD support is there */
+
         Utf8Str devicePath = Utf8StrFmt("%s/%u/LUN#%u", pcszDevice, uInstance, uLUN);
         mapMediumAttachments[devicePath] = pMediumAtt;
@@ -2919,5 +2947,6 @@
         {
             InsertConfigString(pLunL0, "Driver", "SCSI");
-            InsertConfigNode(pLunL0, "Config", &pCfg);
+            PCFGMNODE pL1Cfg = NULL;
+            InsertConfigNode(pLunL0, "Config", &pL1Cfg);
 
             InsertConfigNode(pLunL0, "AttachedDriver", &pLunL0);
Index: /trunk/src/VBox/Main/src-server/MachineImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 37823)
+++ /trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 37824)
@@ -3804,4 +3804,5 @@
                           false /* fPassthrough */,
                           false /* fTempEject */,
+                          false /* fNonRotational */,
                           Utf8Str::Empty);
     if (FAILED(rc)) return rc;
@@ -3994,7 +3995,54 @@
     if (pAttach->getType() != DeviceType_DVD)
         return setError(E_INVALIDARG,
-                        tr("Setting passthrough rejected as the device attached to device slot %d on port %d of controller '%ls' is not a DVD"),
+                        tr("Setting temporary eject flag rejected as the device attached to device slot %d on port %d of controller '%ls' is not a DVD"),
                         aDevice, aControllerPort, aControllerName);
     pAttach->updateTempEject(!!aTemporaryEject);
+
+    return S_OK;
+}
+
+STDMETHODIMP Machine::NonRotationalDevice(IN_BSTR aControllerName, LONG aControllerPort,
+                                          LONG aDevice, BOOL aNonRotational)
+{
+    CheckComArgStrNotEmptyOrNull(aControllerName);
+
+    LogFlowThisFunc(("aControllerName=\"%ls\" aControllerPort=%ld aDevice=%ld aNonRotational=%d\n",
+                     aControllerName, aControllerPort, aDevice, aNonRotational));
+
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    HRESULT rc = checkStateDependency(MutableStateDep);
+    if (FAILED(rc)) return rc;
+
+    AssertReturn(mData->mMachineState != MachineState_Saved, E_FAIL);
+
+    if (Global::IsOnlineOrTransient(mData->mMachineState))
+        return setError(VBOX_E_INVALID_VM_STATE,
+                        tr("Invalid machine state: %s"),
+                        Global::stringifyMachineState(mData->mMachineState));
+
+    MediumAttachment *pAttach = findAttachment(mMediaData->mAttachments,
+                                               aControllerName,
+                                               aControllerPort,
+                                               aDevice);
+    if (!pAttach)
+        return setError(VBOX_E_OBJECT_NOT_FOUND,
+                        tr("No storage device attached to device slot %d on port %d of controller '%ls'"),
+                        aDevice, aControllerPort, aControllerName);
+
+
+    setModified(IsModified_Storage);
+    mMediaData.backup();
+
+    AutoWriteLock attLock(pAttach COMMA_LOCKVAL_SRC_POS);
+
+    if (pAttach->getType() != DeviceType_HardDisk)
+        return setError(E_INVALIDARG,
+                        tr("Setting the non-rotational medium flag rejected as the device attached to device slot %d on port %d of controller '%ls' is not a hard disk"),
+                        aDevice, aControllerPort, aControllerName);
+    pAttach->updateNonRotational(!!aNonRotational);
 
     return S_OK;
@@ -8098,4 +8146,5 @@
                                dev.fPassThrough,
                                dev.fTempEject,
+                               dev.fNonRotational,
                                pBwGroup.isNull() ? Utf8Str::Empty : pBwGroup->getName());
         if (FAILED(rc)) break;
@@ -9045,4 +9094,5 @@
             dev.fPassThrough = pAttach->getPassthrough();
             dev.fTempEject = pAttach->getTempEject();
+            dev.fNonRotational = pAttach->getNonRotational();
         }
 
@@ -9368,4 +9418,5 @@
                                   false /* aPassthrough */,
                                   false /* aTempEject */,
+                                  false /* aNonRotational */,
                                   pAtt->getBandwidthGroup());
             if (FAILED(rc)) throw rc;
Index: /trunk/src/VBox/Main/src-server/MediumAttachmentImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/MediumAttachmentImpl.cpp	(revision 37823)
+++ /trunk/src/VBox/Main/src-server/MediumAttachmentImpl.cpp	(revision 37824)
@@ -41,4 +41,5 @@
           fPassthrough(false),
           fTempEject(false),
+          fNonRotational(false),
           fImplicit(false)
     { }
@@ -58,4 +59,5 @@
     bool                fPassthrough;
     bool                fTempEject;
+    bool                fNonRotational;
     bool                fImplicit;
 };
@@ -117,8 +119,9 @@
                                bool aPassthrough,
                                bool aTempEject,
+                               bool aNonRotational,
                                const Utf8Str &strBandwidthGroup)
 {
     LogFlowThisFuncEnter();
-    LogFlowThisFunc(("aParent=%p aMedium=%p aControllerName=%ls aPort=%d aDevice=%d aType=%d aImplicit=%d aPassthrough=%d aTempEject=%d\n", aParent, aMedium, aControllerName.raw(), aPort, aDevice, aType, aImplicit, aPassthrough, aTempEject));
+    LogFlowThisFunc(("aParent=%p aMedium=%p aControllerName=%ls aPort=%d aDevice=%d aType=%d aImplicit=%d aPassthrough=%d aTempEject=%d aNonRotational=%d strBandwithGroup=%s\n", aParent, aMedium, aControllerName.raw(), aPort, aDevice, aType, aImplicit, aPassthrough, aTempEject, aNonRotational, strBandwidthGroup.c_str()));
 
     if (aType == DeviceType_HardDisk)
@@ -143,4 +146,5 @@
     m->bd->fPassthrough = aPassthrough;
     m->bd->fTempEject = aTempEject;
+    m->bd->fNonRotational = aNonRotational;
     m->bd->fImplicit = aImplicit;
 
@@ -319,4 +323,21 @@
 }
 
+STDMETHODIMP MediumAttachment::COMGETTER(NonRotational)(BOOL *aNonRotational)
+{
+    LogFlowThisFuncEnter();
+
+    CheckComArgOutPointerValid(aNonRotational);
+
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
+
+    *aNonRotational = m->bd->fNonRotational;
+
+    LogFlowThisFuncLeave();
+    return S_OK;
+}
+
 STDMETHODIMP MediumAttachment::COMGETTER(BandwidthGroup) (IBandwidthGroup **aBwGroup)
 {
@@ -429,4 +450,10 @@
 }
 
+bool MediumAttachment::getNonRotational() const
+{
+    AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
+    return m->bd->fNonRotational;
+}
+
 const Utf8Str& MediumAttachment::getBandwidthGroup() const
 {
@@ -481,4 +508,13 @@
 }
 
+/** Must be called from under this object's write lock. */
+void MediumAttachment::updateNonRotational(bool aNonRotational)
+{
+    Assert(isWriteLockOnCurrentThread());
+
+    m->bd.backup();
+    m->bd->fNonRotational = aNonRotational;
+}
+
 void MediumAttachment::updateBandwidthGroup(const Utf8Str &aBandwidthGroup)
 {
Index: /trunk/src/VBox/Main/xml/Settings.cpp
===================================================================
--- /trunk/src/VBox/Main/xml/Settings.cpp	(revision 37823)
+++ /trunk/src/VBox/Main/xml/Settings.cpp	(revision 37824)
@@ -1692,4 +1692,5 @@
                   && (fPassThrough              == a.fPassThrough)
                   && (fTempEject                == a.fTempEject)
+                  && (fNonRotational            == a.fNonRotational)
                   && (lPort                     == a.lPort)
                   && (lDevice                   == a.lDevice)
@@ -2984,5 +2985,8 @@
 
             if (strTemp == "HardDisk")
+            {
                 att.deviceType = DeviceType_HardDisk;
+                pelmAttached->getAttributeValue("nonrotational", att.fNonRotational);
+            }
             else if (m->sv >= SettingsVersion_v1_9)
             {
@@ -4229,4 +4233,6 @@
                 case DeviceType_HardDisk:
                     pcszType = "HardDisk";
+                    if (att.fNonRotational)
+                        pelmDevice->setAttribute("nonrotational", att.fNonRotational);
                 break;
 
