Index: /trunk/src/VBox/Main/include/ApplianceImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/ApplianceImpl.h	(revision 46517)
+++ /trunk/src/VBox/Main/include/ApplianceImpl.h	(revision 46518)
@@ -27,6 +27,10 @@
  * private classes. */
 #include <iprt/tar.h>
+#include <iprt/circbuf.h>
+#include <VBox/vd.h>
+#include <iprt/sha.h>
 
 #include "ovfreader.h"
+#include <set>
 
 /* VBox forward declarations */
@@ -38,4 +42,6 @@
 typedef struct VDINTERFACEIO *PVDINTERFACEIO;
 typedef struct SHASTORAGE    *PSHASTORAGE;
+
+typedef enum applianceIOName { applianceIOTar, applianceIOFile } APPLIANCEIONAME;
 
 namespace ovf
@@ -139,4 +145,14 @@
     static DECLCALLBACK(int) taskThreadImportOrExport(RTTHREAD aThread, void *pvUser);
 
+    HRESULT initSetOfSupportedStandardsURI();
+
+    Utf8Str typeOfVirtualDiskFormatFromURI(Utf8Str type) const;
+
+    std::set<Utf8Str> URIFromTypeOfVirtualDiskFormat(Utf8Str type);
+
+    HRESULT initApplianceIONameMap();
+
+    Utf8Str applianceIOName(APPLIANCEIONAME type) const;
+
     /*******************************************************************************
      * Read stuff
@@ -178,4 +194,5 @@
                             PVDINTERFACEIO pCallbacks,
                             PSHASTORAGE pStorage);
+
     void importMachineGeneric(const ovf::VirtualSystem &vsysThis,
                               ComObjPtr<VirtualSystemDescription> &vsdescThis,
@@ -219,4 +236,7 @@
                                      XMLStack &stack);
 
+    HRESULT preCheckImageAvailability(PSHASTORAGE pSHAStorage,
+                                      RTCString &availableImage);
+
     friend class Machine;
 };
Index: /trunk/src/VBox/Main/include/ApplianceImplPrivate.h
===================================================================
--- /trunk/src/VBox/Main/include/ApplianceImplPrivate.h	(revision 46517)
+++ /trunk/src/VBox/Main/include/ApplianceImplPrivate.h	(revision 46518)
@@ -22,4 +22,5 @@
 
 #include "ovfreader.h"
+#include <map>
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -230,4 +231,5 @@
 bool checkComplianceDigestAndOVFVersion(bool digestType, ovf::OVFVersion_T ovfVersion);
 
+
 typedef struct SHASTORAGE
 {
Index: /trunk/src/VBox/Main/include/ovfreader.h
===================================================================
--- /trunk/src/VBox/Main/include/ovfreader.h	(revision 46517)
+++ /trunk/src/VBox/Main/include/ovfreader.h	(revision 46518)
@@ -26,4 +26,22 @@
 namespace ovf
 {
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Errors
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Thrown by OVFReader for any kind of error that is not an XML error but
+ * still makes the OVF impossible to parse. Based on xml::LogicError so
+ * that one catch() for all xml::LogicError can handle all possible errors.
+ */
+
+class OVFLogicError : public xml::LogicError
+{
+public:
+    OVFLogicError(const char *aFormat, ...);
+};
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -173,4 +191,6 @@
 const char* const OVF20_URI_string = "http://schemas.dmtf.org/ovf/envelope/2";
 
+const char* const DTMF_SPECS_URI = "http://schemas.dmtf.org/wbem/cim-html/2/";
+
 ////////////////////////////////////////////////////////////////////////////////
 //
@@ -206,4 +226,13 @@
     }
 };
+
+
+struct FileReference
+{
+    RTCString strHref;       // value from /References/File/@href (filename)
+    RTCString strDiskId;     // value from /References/File/@id ()
+};
+
+typedef std::map<uint32_t, FileReference> FileReferenceMap;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -261,6 +290,22 @@
 };
 
-struct VirtualHardwareItem
-{
+
+enum StorageAccessType_T
+{   StorageAccessType_Unknown = 0,
+    StorageAccessType_Readable = 1,
+    StorageAccessType_Writeable = 2,
+    StorageAccessType_ReadWrite = 3
+};
+
+enum ComplianceType_T
+{   ComplianceType_No = 0,
+    ComplianceType_Soft = 1,
+    ComplianceType_Medium = 2,
+    ComplianceType_Strong = 3
+};
+
+class VirtualHardwareItem
+{
+public:
     RTCString strDescription;
     RTCString strCaption;
@@ -310,5 +355,131 @@
           ulBusNumber(0),
           ulLineNumber(0)
-    {};
+    {
+        itemName = "Item";
+    };
+
+    void fillItem(const xml::ElementNode *item);
+
+    void setDefaultFlag()
+    {
+        fDefault = true;
+    }
+
+    bool isThereDefaultValues() const
+    {
+        return fDefault;
+    }
+
+    void checkConsistencyAndCompliance() throw (OVFLogicError)
+    {
+        _checkConsistencyAndCompliance();
+    }
+
+protected:
+    virtual void _checkConsistencyAndCompliance() throw (OVFLogicError);
+    virtual const RTCString& getItemName() 
+    {
+        return _getItemName();
+    }
+
+private:
+    RTCString itemName;
+    bool fDefault;//true means that some fields were absent in the XML and some default values were assigned to.
+
+    virtual const RTCString& _getItemName() 
+    {
+        return itemName;
+    }
+};
+
+class StorageItem: public VirtualHardwareItem
+{
+    //see DMTF Schema Documentation http://schemas.dmtf.org/wbem/cim-html/2/
+    StorageAccessType_T accessType;
+    RTCString strHostExtentName;
+    int16_t hostExtentNameFormat;
+    int16_t hostExtentNameNamespace;
+    int64_t hostExtentStartingAddress;
+    int64_t hostResourceBlockSize;
+    int64_t limit;
+    RTCString strOtherHostExtentNameFormat;
+    RTCString strOtherHostExtentNameNamespace;
+    int64_t reservation;
+    int64_t virtualQuantity;
+    RTCString strVirtualQuantityUnits;
+    int64_t virtualResourceBlockSize;
+
+public:
+    StorageItem(): VirtualHardwareItem(),
+        accessType(StorageAccessType_Unknown),
+        hostExtentNameFormat(-1),
+        hostExtentNameNamespace(-1),
+        hostExtentStartingAddress(-1),
+        hostResourceBlockSize(-1),
+        limit(-1),
+        reservation(-1),
+        virtualQuantity(-1),
+        virtualResourceBlockSize(-1)
+    {
+        itemName = "StorageItem";
+    };
+
+    void fillItem(const xml::ElementNode *item);
+
+protected:
+    virtual void _checkConsistencyAndCompliance() throw (OVFLogicError);
+private:
+    RTCString itemName;
+
+    virtual const RTCString& _getItemName() 
+    {
+        return itemName;
+    }
+};
+
+
+class EthernetPortItem: public VirtualHardwareItem
+{
+    //see DMTF Schema Documentation http://schemas.dmtf.org/wbem/cim-html/2/
+    uint16_t DefaultPortVID;
+    uint16_t DefaultPriority;
+    uint16_t DesiredVLANEndpointMode;
+    uint32_t GroupID;
+    uint32_t ManagerID;
+    RTCString strNetworkPortProfileID;
+    uint16_t NetworkPortProfileIDType;
+    RTCString strOtherEndpointMode;
+    RTCString strOtherNetworkPortProfileIDTypeInfo;
+    RTCString strPortCorrelationID;
+    uint16_t PortVID;
+    bool Promiscuous;
+    uint64_t ReceiveBandwidthLimit;
+    uint16_t ReceiveBandwidthReservation;
+    bool SourceMACFilteringEnabled;
+    uint32_t VSITypeID;
+    uint8_t VSITypeIDVersion;
+    uint16_t AllowedPriorities[256];
+    RTCString strAllowedToReceiveMACAddresses;
+    uint16_t AllowedToReceiveVLANs[256];
+    RTCString strAllowedToTransmitMACAddresses;
+    uint16_t AllowedToTransmitVLANs[256];
+
+public:
+    EthernetPortItem(): VirtualHardwareItem()
+    {
+        itemName = "EthernetPortItem";
+    };
+
+    void fillItem(const xml::ElementNode *item);
+
+protected:
+    virtual void _checkConsistencyAndCompliance() throw (OVFLogicError);
+private:
+    RTCString itemName;
+
+    virtual const RTCString& _getItemName() 
+    {
+        return itemName;
+    }
 };
 
@@ -484,22 +655,4 @@
 };
 
-////////////////////////////////////////////////////////////////////////////////
-//
-// Errors
-//
-////////////////////////////////////////////////////////////////////////////////
-
-/**
- * Thrown by OVFReader for any kind of error that is not an XML error but
- * still makes the OVF impossible to parse. Based on xml::LogicError so
- * that one catch() for all xml::LogicError can handle all possible errors.
- */
-
-class OVFLogicError : public xml::LogicError
-{
-public:
-    OVFLogicError(const char *aFormat, ...);
-};
-
 } // end namespace ovf
 
Index: /trunk/src/VBox/Main/src-server/ApplianceImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/ApplianceImpl.cpp	(revision 46517)
+++ /trunk/src/VBox/Main/src-server/ApplianceImpl.cpp	(revision 46518)
@@ -19,6 +19,6 @@
 #include <iprt/path.h>
 #include <iprt/cpp/utils.h>
-
 #include <VBox/com/array.h>
+#include <map>
 
 #include "ApplianceImpl.h"
@@ -29,5 +29,6 @@
 #include "ProgressImpl.h"
 #include "MachineImpl.h"
-
+#include "MediumFormatImpl.h"
+#include "SystemPropertiesImpl.h"
 #include "AutoCaller.h"
 #include "Logging.h"
@@ -42,4 +43,18 @@
 //
 ////////////////////////////////////////////////////////////////////////////////
+
+static const char* const strISOURI = "http://www.ecma-international.org/publications/standards/Ecma-119.htm";
+static const char* const strVMDKStreamURI = "http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized";
+static const char* const strVMDKSparseURI = "http://www.vmware.com/specifications/vmdk.html#sparse";
+static const char* const strVMDKCompressedURI = "http://www.vmware.com/specifications/vmdk.html#compressed";
+static const char* const strVMDKCompressedURI2 = "http://www.vmware.com/interfaces/specifications/vmdk.html#compressed";
+static const char* const strVHDURI = "http://go.microsoft.com/fwlink/?LinkId=137171";
+
+static std::map<Utf8Str, Utf8Str> supportedStandardsURI;
+
+static const char* const applianceIOTarName = "Appliance::IOTar";
+static const char* const applianceIOFileName = "Appliance::IOFile";
+
+static std::map<APPLIANCEIONAME, Utf8Str> applianceIONameMap;
 
 static const struct
@@ -304,4 +319,5 @@
 }
 
+
 ////////////////////////////////////////////////////////////////////////////////
 //
@@ -355,4 +371,5 @@
 HRESULT Appliance::init(VirtualBox *aVirtualBox)
 {
+    HRESULT rc = S_OK;
     /* Enclose the state transition NotReady->InInit->Ready */
     AutoInitSpan autoInitSpan(this);
@@ -365,8 +382,12 @@
     m = new Data;
 
+    initApplianceIONameMap();
+
+    rc = initSetOfSupportedStandardsURI();
+
     /* Confirm a successful initialization */
     autoInitSpan.setSucceeded();
 
-    return S_OK;
+    return rc;
 }
 
@@ -604,4 +625,110 @@
 ////////////////////////////////////////////////////////////////////////////////
 
+HRESULT Appliance::initSetOfSupportedStandardsURI()
+{
+    HRESULT rc = S_OK;
+    if (!supportedStandardsURI.empty())
+        return rc;
+
+    /* Get the system properties. */
+    SystemProperties *pSysProps = mVirtualBox->getSystemProperties();
+    {
+        ComObjPtr<MediumFormat> trgFormat = pSysProps->mediumFormatFromExtension("iso");
+        if (trgFormat.isNull())
+            return setError(E_FAIL, tr("Can't find appropriate medium format for ISO type of a virtual disk."));
+
+        Bstr bstrFormatName;
+        rc = trgFormat->COMGETTER(Name)(bstrFormatName.asOutParam());
+        if (FAILED(rc)) return rc;
+
+        Utf8Str strTrgFormat = Utf8Str(bstrFormatName);
+
+        supportedStandardsURI.insert(std::make_pair(Utf8Str(strISOURI), strTrgFormat));
+    }
+
+    {
+        ComObjPtr<MediumFormat> trgFormat = pSysProps->mediumFormatFromExtension("vmdk");
+        if (trgFormat.isNull())
+            return setError(E_FAIL, tr("Can't find appropriate medium format for VMDK type of a virtual disk."));
+
+        Bstr bstrFormatName;
+        rc = trgFormat->COMGETTER(Name)(bstrFormatName.asOutParam());
+        if (FAILED(rc)) return rc;
+
+        Utf8Str strTrgFormat = Utf8Str(bstrFormatName);
+
+        supportedStandardsURI.insert(std::make_pair(Utf8Str(strVMDKStreamURI), strTrgFormat));
+        supportedStandardsURI.insert(std::make_pair(Utf8Str(strVMDKSparseURI), strTrgFormat));
+        supportedStandardsURI.insert(std::make_pair(Utf8Str(strVMDKCompressedURI), strTrgFormat));
+        supportedStandardsURI.insert(std::make_pair(Utf8Str(strVMDKCompressedURI2), strTrgFormat));
+    }
+
+    {
+        ComObjPtr<MediumFormat> trgFormat = pSysProps->mediumFormatFromExtension("vhd");
+        if (trgFormat.isNull())
+            return setError(E_FAIL, tr("Can't find appropriate medium format for VHD type of a virtual disk."));
+
+        Bstr bstrFormatName;
+        rc = trgFormat->COMGETTER(Name)(bstrFormatName.asOutParam());
+        if (FAILED(rc)) return rc;
+
+        Utf8Str strTrgFormat = Utf8Str(bstrFormatName);
+
+        supportedStandardsURI.insert(std::make_pair(Utf8Str(strVHDURI), strTrgFormat));
+    }
+
+    return rc;
+}
+
+Utf8Str Appliance::typeOfVirtualDiskFormatFromURI(Utf8Str uri) const
+{
+    Utf8Str type;
+    std::map<Utf8Str, Utf8Str>::const_iterator cit = supportedStandardsURI.find(uri);
+    if (cit != supportedStandardsURI.end())
+    {
+        type = cit->second;
+    }
+
+    return type;
+}
+
+std::set<Utf8Str> Appliance::URIFromTypeOfVirtualDiskFormat(Utf8Str type)
+{
+    std::set<Utf8Str> uri;
+    std::map<Utf8Str, Utf8Str>::const_iterator cit = supportedStandardsURI.begin();
+    while(cit != supportedStandardsURI.end())
+    {
+        if (cit->second.compare(type,Utf8Str::CaseInsensitive) == 0)
+            uri.insert(cit->first);
+        ++cit;
+    }
+
+    return uri;
+}
+
+HRESULT Appliance::initApplianceIONameMap()
+{
+    HRESULT rc = S_OK;
+    if (!applianceIONameMap.empty())
+        return rc;
+
+        applianceIONameMap.insert(std::make_pair(applianceIOTar, applianceIOTarName));
+        applianceIONameMap.insert(std::make_pair(applianceIOFile, applianceIOFileName));
+
+    return rc;
+}
+
+Utf8Str Appliance::applianceIOName(APPLIANCEIONAME type) const
+{
+    Utf8Str name;
+    std::map<APPLIANCEIONAME, Utf8Str>::const_iterator cit = applianceIONameMap.find(type);
+    if (cit != applianceIONameMap.end())
+    {
+        name = cit->second;
+    }
+
+    return name;
+}
+
 /**
  * Returns true if the appliance is in "idle" state. This should always be the
Index: /trunk/src/VBox/Main/src-server/ApplianceImplExport.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/ApplianceImplExport.cpp	(revision 46517)
+++ /trunk/src/VBox/Main/src-server/ApplianceImplExport.cpp	(revision 46518)
@@ -1230,4 +1230,8 @@
             uint64_t uTemp;
 
+            ovf::VirtualHardwareItem vhi;
+            ovf::StorageItem si;
+            ovf::EthernetPortItem epi;
+
             switch (desc.type)
             {
@@ -1518,5 +1522,5 @@
                             <rasd:ResourceType>10</rasd:ResourceType>
                         </Item> */
-                    if (uLoop == 1)
+                    if (uLoop == 2)
                     {
                         lAutomaticAllocation = 1;
@@ -1587,6 +1591,35 @@
             {
                 xml::ElementNode *pItem;
-
-                pItem = pelmVirtualHardwareSection->createChild("Item");
+                xml::ElementNode *pItemHelper;
+                RTCString itemElement;
+                RTCString itemElementHelper;
+
+                if (enFormat == ovf::OVFVersion_2_0)
+                {
+                    if(uLoop == 2)
+                    {
+                        if (desc.type == VirtualSystemDescriptionType_NetworkAdapter)
+                        {
+                            itemElement = "epasd:";
+                            pItem = pelmVirtualHardwareSection->createChild("EthernetPortItem");
+                        }
+                        else if (desc.type == VirtualSystemDescriptionType_CDROM ||
+                                 desc.type == VirtualSystemDescriptionType_HardDiskImage)
+                        {
+                            itemElement = "sasd:";
+                            pItem = pelmVirtualHardwareSection->createChild("StorageItem");
+                        }
+                    }
+                    else
+                    {
+                        itemElement = "rasd:";
+                        pItem = pelmVirtualHardwareSection->createChild("Item");
+                    }
+                }
+                else
+                {
+                    itemElement = "rasd:";
+                    pItem = pelmVirtualHardwareSection->createChild("Item");
+                }
 
                 // NOTE: DO NOT CHANGE THE ORDER of these items! The OVF standards prescribes that
@@ -1595,55 +1628,135 @@
 
                 if (lAddress != -1)
-                    pItem->createChild("rasd:Address")->addContent(Utf8StrFmt("%d", lAddress));
+                {
+                    //pItem->createChild("rasd:Address")->addContent(Utf8StrFmt("%d", lAddress));
+                    itemElementHelper = itemElement;
+                    pItemHelper = pItem->createChild(itemElementHelper.append("Address").c_str());
+                    pItemHelper->addContent(Utf8StrFmt("%d", lAddress));
+                }
 
                 if (lAddressOnParent != -1)
-                    pItem->createChild("rasd:AddressOnParent")->addContent(Utf8StrFmt("%d", lAddressOnParent));
+                {
+                    //pItem->createChild("rasd:AddressOnParent")->addContent(Utf8StrFmt("%d", lAddressOnParent));
+                    itemElementHelper = itemElement;
+                    pItemHelper = pItem->createChild(itemElementHelper.append("AddressOnParent").c_str());
+                    pItemHelper->addContent(Utf8StrFmt("%d", lAddressOnParent));
+                }
 
                 if (!strAllocationUnits.isEmpty())
-                    pItem->createChild("rasd:AllocationUnits")->addContent(strAllocationUnits);
+                {
+                    //pItem->createChild("rasd:AllocationUnits")->addContent(strAllocationUnits);
+                    itemElementHelper = itemElement;
+                    pItemHelper = pItem->createChild(itemElementHelper.append("AllocationUnits").c_str());
+                    pItemHelper->addContent(strAllocationUnits);
+                }
 
                 if (lAutomaticAllocation != -1)
-                    pItem->createChild("rasd:AutomaticAllocation")->addContent( (lAutomaticAllocation) ? "true" : "false" );
+                {
+                    //pItem->createChild("rasd:AutomaticAllocation")->addContent( (lAutomaticAllocation) ? "true" : "false" );
+                    itemElementHelper = itemElement;
+                    pItemHelper = pItem->createChild(itemElementHelper.append("AutomaticAllocation").c_str());
+                    pItemHelper->addContent((lAutomaticAllocation) ? "true" : "false" );
+                }
 
                 if (lBusNumber != -1)
-                    if (enFormat == ovf::OVFVersion_0_9) // BusNumber is invalid OVF 1.0 so only write it in 0.9 mode for OVFTool y
-                        pItem->createChild("rasd:BusNumber")->addContent(Utf8StrFmt("%d", lBusNumber));
+                {
+                    if (enFormat == ovf::OVFVersion_0_9)
+                    {
+                        // BusNumber is invalid OVF 1.0 so only write it in 0.9 mode for OVFTool
+                        //pItem->createChild("rasd:BusNumber")->addContent(Utf8StrFmt("%d", lBusNumber));
+                        itemElementHelper = itemElement;
+                        pItemHelper = pItem->createChild(itemElementHelper.append("BusNumber").c_str());
+                        pItemHelper->addContent(Utf8StrFmt("%d", lBusNumber));
+                    }
+                }
 
                 if (!strCaption.isEmpty())
-                    pItem->createChild("rasd:Caption")->addContent(strCaption);
+                {
+                    //pItem->createChild("rasd:Caption")->addContent(strCaption);
+                    itemElementHelper = itemElement;
+                    pItemHelper = pItem->createChild(itemElementHelper.append("Caption").c_str());
+                    pItemHelper->addContent(strCaption);
+                }
 
                 if (!strConnection.isEmpty())
-                    pItem->createChild("rasd:Connection")->addContent(strConnection);
+                {
+                    //pItem->createChild("rasd:Connection")->addContent(strConnection);
+                    itemElementHelper = itemElement;
+                    pItemHelper = pItem->createChild(itemElementHelper.append("Connection").c_str());
+                    pItemHelper->addContent(strConnection);
+                }
 
                 if (!strDescription.isEmpty())
-                    pItem->createChild("rasd:Description")->addContent(strDescription);
+                {
+                    //pItem->createChild("rasd:Description")->addContent(strDescription);
+                    itemElementHelper = itemElement;
+                    pItemHelper = pItem->createChild(itemElementHelper.append("Description").c_str());
+                    pItemHelper->addContent(strDescription);
+                }
 
                 if (!strCaption.isEmpty())
-                    if (enFormat == ovf::OVFVersion_1_0)
-                        pItem->createChild("rasd:ElementName")->addContent(strCaption);
+                {
+                        if (enFormat == ovf::OVFVersion_1_0)
+                        {
+                            //pItem->createChild("rasd:ElementName")->addContent(strCaption);
+                            itemElementHelper = itemElement;
+                            pItemHelper = pItem->createChild(itemElementHelper.append("ElementName").c_str());
+                            pItemHelper->addContent(strCaption);
+                        }
+                }
 
                 if (!strHostResource.isEmpty())
-                    pItem->createChild("rasd:HostResource")->addContent(strHostResource);
-
-                // <rasd:InstanceID>1</rasd:InstanceID>
-                xml::ElementNode *pelmInstanceID;
-                if (enFormat == ovf::OVFVersion_0_9)
-                    pelmInstanceID = pItem->createChild("rasd:InstanceId");
-                else
-                    pelmInstanceID = pItem->createChild("rasd:InstanceID");      // capitalization changed...
-                pelmInstanceID->addContent(Utf8StrFmt("%d", ulInstanceID++));
+                {
+                    //pItem->createChild("rasd:HostResource")->addContent(strHostResource);
+                    itemElementHelper = itemElement;
+                    pItemHelper = pItem->createChild(itemElementHelper.append("HostResource").c_str());
+                    pItemHelper->addContent(strHostResource);
+                }
+
+                {
+                    // <rasd:InstanceID>1</rasd:InstanceID>
+                    itemElementHelper = itemElement;
+                    if (enFormat == ovf::OVFVersion_0_9)
+                        //pelmInstanceID = pItem->createChild("rasd:InstanceId");
+                        pItemHelper = pItem->createChild(itemElementHelper.append("InstanceId").c_str());
+                    else
+                        //pelmInstanceID = pItem->createChild("rasd:InstanceID");      // capitalization changed...
+                        pItemHelper = pItem->createChild(itemElementHelper.append("InstanceID").c_str());
+
+                    pItemHelper->addContent(Utf8StrFmt("%d", ulInstanceID++));
+                }
 
                 if (ulParent)
-                    pItem->createChild("rasd:Parent")->addContent(Utf8StrFmt("%d", ulParent));
+                {
+                    //pItem->createChild("rasd:Parent")->addContent(Utf8StrFmt("%d", ulParent));
+                    itemElementHelper = itemElement;
+                    pItemHelper = pItem->createChild(itemElementHelper.append("Parent").c_str());
+                    pItemHelper->addContent(Utf8StrFmt("%d", ulParent));
+                }
 
                 if (!strResourceSubType.isEmpty())
-                    pItem->createChild("rasd:ResourceSubType")->addContent(strResourceSubType);
-
-                // <rasd:ResourceType>3</rasd:ResourceType>
-                pItem->createChild("rasd:ResourceType")->addContent(Utf8StrFmt("%d", type));
+                {
+                    //pItem->createChild("rasd:ResourceSubType")->addContent(strResourceSubType);
+                    itemElementHelper = itemElement;
+                    pItemHelper = pItem->createChild(itemElementHelper.append("ResourceSubType").c_str());
+                    pItemHelper->addContent(strResourceSubType);
+                }
+
+                {
+                    // <rasd:ResourceType>3</rasd:ResourceType>
+                    //pItem->createChild("rasd:ResourceType")->addContent(Utf8StrFmt("%d", type));
+                    itemElementHelper = itemElement;
+                    pItemHelper = pItem->createChild(itemElementHelper.append("ResourceType").c_str());
+                    pItemHelper->addContent(Utf8StrFmt("%d", type));
+                }
 
                 // <rasd:VirtualQuantity>1</rasd:VirtualQuantity>
                 if (lVirtualQuantity != -1)
-                    pItem->createChild("rasd:VirtualQuantity")->addContent(Utf8StrFmt("%d", lVirtualQuantity));
+                {
+                    //pItem->createChild("rasd:VirtualQuantity")->addContent(Utf8StrFmt("%d", lVirtualQuantity));
+                    itemElementHelper = itemElement;
+                    pItemHelper = pItem->createChild(itemElementHelper.append("VirtualQuantity").c_str());
+                    pItemHelper->addContent(Utf8StrFmt("%d", lVirtualQuantity));
+                }
             }
         }
@@ -1757,5 +1870,9 @@
         storage.fCreateDigest = m->fManifest;
         storage.fSha256 = m->fSha256;
-        int vrc = VDInterfaceAdd(&pFileIo->Core, "Appliance::IOFile",
+
+
+        Utf8Str name = applianceIOName(applianceIOFile);
+
+        int vrc = VDInterfaceAdd(&pFileIo->Core, name.c_str(),
                                  VDINTERFACETYPE_IO, 0, sizeof(VDINTERFACEIO),
                                  &storage.pVDImageIfaces);
@@ -1811,7 +1928,11 @@
         storage.fCreateDigest = m->fManifest;
         storage.fSha256 = m->fSha256;
-        vrc = VDInterfaceAdd(&pTarIo->Core, "Appliance::IOTar",
+
+        Utf8Str name = applianceIOName(applianceIOTar);
+
+        vrc = VDInterfaceAdd(&pTarIo->Core, name.c_str(),
                              VDINTERFACETYPE_IO, tar, sizeof(VDINTERFACEIO),
                              &storage.pVDImageIfaces);
+        
         if (RT_FAILURE(vrc))
         {
@@ -1858,6 +1979,8 @@
             // Now fully build a valid ovf document in memory
             buildXML(writeLock, doc, stack, pTask->locInfo.strPath, pTask->enFormat);
+            /* Extract the OVA file name */
+            Utf8Str strOvaFile = pTask->locInfo.strPath;
             /* Extract the path */
-            Utf8Str strOvfFile = Utf8Str(pTask->locInfo.strPath).stripExt().append(".ovf");
+            Utf8Str strOvfFile = strOvaFile.stripExt().append(".ovf");
             // Create a memory buffer containing the XML. */
             void *pvBuf = 0;
@@ -1951,9 +2074,4 @@
             try
             {
-                ComObjPtr<Progress> pProgress2;
-                pProgress2.createObject();
-                rc = pProgress2->init(mVirtualBox, static_cast<IAppliance*>(this), BstrFmt(tr("Creating medium '%s'"), strTargetFilePath.c_str()).raw(), TRUE);
-                if (FAILED(rc)) throw rc;
-
                 // advance to the next operation
                 pTask->pProgress->SetNextOperation(BstrFmt(tr("Exporting to disk image '%s'"), RTPathFilename(strTargetFilePath.c_str())).raw(),
@@ -1963,6 +2081,11 @@
                 if (pDiskEntry->type == VirtualSystemDescriptionType_HardDiskImage)
                 {
-                    rc = pSourceDisk->exportFile(strTargetFilePath.c_str(),
-                                                 format,
+                    ComObjPtr<Progress> pProgress2;
+                    pProgress2.createObject();
+                    rc = pProgress2->init(mVirtualBox, static_cast<IAppliance*>(this), BstrFmt(tr("Creating medium '%s'"), strTargetFilePath.c_str()).raw(), TRUE);
+                    if (FAILED(rc)) throw rc;
+
+                    rc = pSourceDisk->exportFile(strTargetFilePath.c_str(), 
+                                                 format, 
                                                  MediumVariant_VmdkStreamOptimized,
                                                  pIfIo,
@@ -1970,20 +2093,59 @@
                                                  pProgress2);
                     if (FAILED(rc)) throw rc;
+
+                    ComPtr<IProgress> pProgress3(pProgress2);
+                    // now wait for the background disk operation to complete; this throws HRESULTs on error
+                    waitForAsyncProgress(pTask->pProgress, pProgress3);
                 }
                 else
                 {
                     //copy/clone CD/DVD image
-                    rc = pSourceDisk->exportFile(strTargetFilePath.c_str(),
-                                                 formatTemp,
-                                                 MediumVariant_Standard,
-                                                 pIfIo,
-                                                 pStorage,
-                                                 pProgress2);
-                    if (FAILED(rc)) throw rc;
+                    /* Read the ISO file into a memory buffer */
+                    {
+                        void *pvTmpBuf = 0;
+                        size_t cbSize = 0;
+
+                        if (RTFileExists(strSrcFilePath.c_str()))
+                        {
+                            // open ISO file and read one into memory buffer
+                            RTFILE pFile = NULL;
+                            vrc = RTFileOpen(&pFile, strSrcFilePath.c_str(), RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE);
+                            if (RT_SUCCESS(vrc) && pFile != NULL)
+                            {
+                                uint64_t cbFile = 0;
+
+                                vrc = RTFileGetSize(pFile, &cbFile);
+
+                                if (RT_SUCCESS(vrc))
+                                   pvTmpBuf = RTMemAllocZ(cbFile);
+                                else
+                                    throw setError(VBOX_E_FILE_ERROR,
+                                            tr("Could not get size of the ISO file '%s' "),
+                                            RTPathFilename(strSrcFilePath.c_str()));
+
+                                vrc = RTFileRead(pFile, pvTmpBuf, cbFile, &cbSize);
+
+                                if (RT_FAILURE(vrc))
+                                {
+                                    if (pvTmpBuf)
+                                        RTMemFree(pvTmpBuf);
+                                    throw setError(VBOX_E_FILE_ERROR,
+                                           tr("Could not read the ISO file '%s' (%Rrc)"),
+                                           RTPathFilename(strSrcFilePath.c_str()), vrc);
+                                }
+                            }
+
+                            RTFileClose(pFile);
+                        }
+
+                        /* Write the ISO file to disk. */
+                        vrc = ShaWriteBuf(strTargetFilePath.c_str(), pvTmpBuf, cbSize, pIfIo, pStorage);
+                        RTMemFree(pvTmpBuf);
+                        if (RT_FAILURE(vrc))
+                            throw setError(VBOX_E_FILE_ERROR,
+                                           tr("Could not create ISO file '%s' (%Rrc)"),
+                                           strTargetFilePath.c_str(), vrc);
+                    }
                 }
-
-                ComPtr<IProgress> pProgress3(pProgress2);
-                // now wait for the background disk operation to complete; this throws HRESULTs on error
-                waitForAsyncProgress(pTask->pProgress, pProgress3);
             }
             catch (HRESULT rc3)
Index: /trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp	(revision 46517)
+++ /trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp	(revision 46518)
@@ -36,5 +36,4 @@
  *   Structures and Typedefs                                                  *
  ******************************************************************************/
-
 typedef struct FILESTORAGEINTERNAL
 {
@@ -282,5 +281,5 @@
     int rc = VINF_SUCCESS;
 
-    if (   fOpen & RTFILE_O_READ
+    if (fOpen & RTFILE_O_READ
         && !(fOpen & RTFILE_O_WRITE))
     {
@@ -298,4 +297,5 @@
          */
         bool fFound = false;
+
         for (;;)
         {
@@ -312,5 +312,7 @@
                     rc = RTTarSeekNextFile(tar);
                     if (RT_FAILURE(rc))
+                    {
                         break;
+                    }
                 }
             }
Index: /trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp	(revision 46517)
+++ /trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp	(revision 46518)
@@ -47,4 +47,6 @@
 #include <VBox/version.h>
 #include <VBox/settings.h>
+
+#include <set>
 
 using namespace std;
@@ -611,22 +613,50 @@
                     }
 
+                    /* 
+                     * Figure out from URI which format the image of disk has.
+                     * URI must have inside section <Disk>                   .
+                     * But there aren't strong requirements about correspondence one URI for one disk virtual format. 
+                     * So possibly, we aren't able to recognize some URIs.
+                     */
+                    Utf8Str vdf = typeOfVirtualDiskFormatFromURI(di.strFormat);
+
+                    /* 
+                     * fallback, if we can't determine virtual disk format using URI from the attribute ovf:format
+                     * in the corresponding section <Disk> in the OVF file.
+                     */
+                    if (vdf.isEmpty())
+                    {
+                        /* Figure out from extension which format the image of disk has. */
+                        {
+                            char *pszExt = RTPathExt(di.strHref.c_str());
+                            /* Get the system properties. */
+                            SystemProperties *pSysProps = mVirtualBox->getSystemProperties();
+                            ComObjPtr<MediumFormat> trgFormat = pSysProps->mediumFormatFromExtension(&pszExt[1]);
+                            if (trgFormat.isNull())
+                            {
+                                throw setError(E_FAIL,
+                                       tr("Internal inconsistency looking up medium format for the disk image '%s'"),
+                                       di.strHref.c_str());
+                            }
+
+                            Bstr bstrFormatName;
+                            rc = trgFormat->COMGETTER(Name)(bstrFormatName.asOutParam());
+                            if (FAILED(rc))
+                                throw rc;
+
+                            vdf = Utf8Str(bstrFormatName);
+                        }
+                    }
+
                     // @todo:
                     //  - figure out all possible vmdk formats we also support
                     //  - figure out if there is a url specifier for vhd already
                     //  - we need a url specifier for the vdi format
-                    if (!di.strFormat.compare("http://www.vmware.com/specifications/vmdk.html#sparse", 
-                                                Utf8Str::CaseInsensitive)
-                        || !di.strFormat.compare("http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized",
-                                Utf8Str::CaseInsensitive)
-                        || !di.strFormat.compare("http://www.vmware.com/specifications/vmdk.html#compressed",
-                                Utf8Str::CaseInsensitive)
-                        || !di.strFormat.compare("http://www.vmware.com/interfaces/specifications/vmdk.html#compressed",
-                                Utf8Str::CaseInsensitive)
-                    )
+
+                    if (vdf.compare("VMDK", Utf8Str::CaseInsensitive) == 0)
                     {
                         /* If the href is empty use the VM name as filename */
                         Utf8Str strFilename = di.strHref;
                         if (!strFilename.length())
-                            //strFilename = Utf8StrFmt("%s.vmdk", nameVBox.c_str());
                             strFilename = Utf8StrFmt("%s.vmdk", hd.strDiskId.c_str());
 
@@ -640,5 +670,6 @@
                         if (!(pController = pNewDesc->findControllerFromID(hd.idController)))
                             throw setError(E_FAIL,
-                                           tr("Cannot find hard disk controller with OVF instance ID %RI32 to which disk \"%s\" should be attached"),
+                                           tr("Cannot find hard disk controller with OVF instance ID %RI32 "
+                                              "to which disk \"%s\" should be attached"),
                                            hd.idController,
                                            di.strHref.c_str());
@@ -654,7 +685,6 @@
                                            di.ulSuggestedSizeMB,
                                            strExtraConfig);
-                    }//url specifier for ISO
-                    else if (!di.strFormat.compare("http://www.ecma-international.org/publications/standards/Ecma-119.htm",
-                            Utf8Str::CaseInsensitive))
+                    }
+                    else if (vdf.compare("RAW", Utf8Str::CaseInsensitive) == 0)
                     {
                         /* If the href is empty use the VM name as filename */
@@ -673,5 +703,6 @@
                         if (!(pController = pNewDesc->findControllerFromID(hd.idController)))
                             throw setError(E_FAIL,
-                                           tr("Cannot find disk controller with OVF instance ID %RI32 to which disk \"%s\" sh     ould be attached"),
+                                           tr("Cannot find disk controller with OVF instance ID %RI32 "
+                                              "to which disk \"%s\" should be attached"),
                                            hd.idController,
                                            di.strHref.c_str());
@@ -690,5 +721,7 @@
                     else
                         throw setError(VBOX_E_FILE_ERROR,
-                                       tr("Unsupported format for virtual disk image in OVF: \"%s\"", di.strFormat.c_str()));
+                                       tr("Unsupported format for virtual disk image %s in OVF: \"%s\""),
+                                          di.strHref.c_str(),
+                                          di.strFormat.c_str());
                 }
             }
@@ -764,4 +797,23 @@
 ////////////////////////////////////////////////////////////////////////////////
 
+HRESULT Appliance::preCheckImageAvailability(PSHASTORAGE pSHAStorage,
+                                               RTCString &availableImage)
+{
+    HRESULT rc = S_OK;
+    RTTAR tar = (RTTAR)pSHAStorage->pVDImageIfaces->pvUser;
+    char *pszFilename = 0;
+
+    int vrc = RTTarCurrentFile(tar, &pszFilename);
+
+    if (RT_FAILURE(vrc))
+    {
+        throw setError(VBOX_E_FILE_ERROR,
+               tr("Could not open the current file in the archive (%Rrc)"), vrc);
+    }
+
+    availableImage = pszFilename;
+
+    return rc;
+}
 
 /*******************************************************************************
@@ -929,4 +981,6 @@
                     }
 
+                    RTFileClose(pFile);
+
                     RTDIGESTTYPE digestType = RTDIGESTTYPE_UNKNOWN;
                     vrc = RTManifestVerifyDigestType(pBuf, cbRead, digestType);
@@ -948,5 +1002,7 @@
                     }
 
-                    vrc = VDInterfaceAdd(&pFileIo->Core, "Appliance::IOFile",
+                    Utf8Str name = applianceIOName(applianceIOFile);
+
+                    vrc = VDInterfaceAdd(&pFileIo->Core, name.c_str(),
                                              VDINTERFACETYPE_IO, 0, sizeof(VDINTERFACEIO),
                                              &storage.pVDImageIfaces);
@@ -1101,5 +1157,7 @@
                 }
 
-                vrc = VDInterfaceAdd(&pTarIo->Core, "Appliance::IOTar",
+                Utf8Str name = applianceIOName(applianceIOTar);
+
+                vrc = VDInterfaceAdd(&pTarIo->Core, name.c_str(),
                                      VDINTERFACETYPE_IO, tar, sizeof(VDINTERFACEIO),
                                      &storage.pVDImageIfaces);
@@ -1479,5 +1537,7 @@
             storage.fCreateDigest = true;
 
-            int vrc = VDInterfaceAdd(&pFileIo->Core, "Appliance::IOFile",
+            Utf8Str name = applianceIOName(applianceIOFile);
+
+            int vrc = VDInterfaceAdd(&pFileIo->Core, name.c_str(),
                                      VDINTERFACETYPE_IO, 0, sizeof(VDINTERFACEIO),
                                      &storage.pVDImageIfaces);
@@ -1553,5 +1613,8 @@
         SHASTORAGE storage;
         RT_ZERO(storage);
-        vrc = VDInterfaceAdd(&pTarIo->Core, "Appliance::IOTar",
+
+        Utf8Str name = applianceIOName(applianceIOTar);
+
+        vrc = VDInterfaceAdd(&pTarIo->Core, name.c_str(),
                              VDINTERFACETYPE_IO, tar, sizeof(VDINTERFACEIO),
                              &storage.pVDImageIfaces);
@@ -2050,4 +2113,6 @@
     {
         Utf8Str strTrgFormat = "VMDK";
+        ULONG lCabs = 0;
+
         if (RTPathHaveExt(strTargetPath.c_str()))
         {
@@ -2060,5 +2125,5 @@
                                strTargetPath.c_str());
             /* Check the capabilities. We need create capabilities. */
-            ULONG lCabs = 0;
+            lCabs = 0;
             com::SafeArray <MediumFormatCapabilities_T> mediumFormatCap;
             rc = trgFormat->COMGETTER(Capabilities)(ComSafeArrayAsOutParam(mediumFormatCap));
@@ -2088,13 +2153,4 @@
         if (strTrgFormat.compare("RAW", Utf8Str::CaseInsensitive) == 0)
         {
-            /* copy ISO image to the destination folder*/
-            vrc = RTFileCopy(strSrcFilePath.c_str(), strTargetPath.c_str());
-
-            if (RT_FAILURE(vrc))
-                throw setError(VBOX_E_FILE_ERROR,
-                               tr("Could not copy image %s to the destination folder '%s'"),
-                               strSrcFilePath.c_str(),
-                               strTargetPath.c_str());
-
             void *pvTmpBuf = 0;
             size_t cbSize = 0;
@@ -2102,4 +2158,5 @@
             /* Read the ISO file into a memory buffer */
             vrc = ShaReadBuf(strSrcFilePath.c_str(), &pvTmpBuf, &cbSize, pCallbacks, pStorage);
+
             if ( RT_FAILURE(vrc) || !pvTmpBuf)
                 throw setError(VBOX_E_FILE_ERROR,
@@ -2107,4 +2164,40 @@
                                RTPathFilename(strSrcFilePath.c_str()), vrc);
 
+            if (RTFileExists(strTargetPath.c_str()) == false)
+            {
+
+                /* ensure the directory exists */
+                if (lCabs & MediumFormatCapabilities_File)
+                {
+                    rc = VirtualBox::ensureFilePathExists(strTargetPath, true);
+                    if (FAILED(rc))
+                        throw rc;
+                }
+
+                // create a new file and copy raw data into one from buffer pvTmpBuf
+                RTFILE pFile = NULL;
+                vrc = RTFileOpen(&pFile, strTargetPath.c_str(), RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
+                if (RT_SUCCESS(vrc) && pFile != NULL)
+                {
+                    size_t cbWritten = 0;
+
+                    vrc = RTFileWrite(pFile, pvTmpBuf, cbSize, &cbWritten);
+
+                    if (RT_FAILURE(vrc))
+                    {
+                        Utf8Str path(strTargetPath);
+                        path = path.stripFilename();
+                        if (pvTmpBuf)
+                            RTMemFree(pvTmpBuf);
+                        throw setError(VBOX_E_FILE_ERROR,
+                                       tr("Could not write the ISO file '%s' into the folder %s (%Rrc)"),
+                                       strSrcFilePath.stripPath().c_str(), 
+                                       path.c_str(),
+                                       vrc);
+                    }
+                }
+
+                RTFileClose(pFile);
+            }
             /* Advance to the next operation. */
             stack.pProgress->SetNextOperation(BstrFmt(tr("Importing virtual disk image '%s'"),
@@ -2146,20 +2239,10 @@
                 Utf8Str strSrcFormat = "VDI";
 
-                if ( !di.strFormat.compare("http://www.vmware.com/specifications/vmdk.html#sparse",
-                        Utf8Str::CaseInsensitive)
-                    || !di.strFormat.compare("http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized",
-                            Utf8Str::CaseInsensitive)
-                    || !di.strFormat.compare("http://www.vmware.com/specifications/vmdk.html#compressed",
-                            Utf8Str::CaseInsensitive)
-                    || !di.strFormat.compare("http://www.vmware.com/interfaces/specifications/vmdk.html#compressed",
-                            Utf8Str::CaseInsensitive)
-                   )
+                std::set<Utf8Str> listURIs = Appliance::URIFromTypeOfVirtualDiskFormat("VMDK");
+                std::set<Utf8Str>::const_iterator itr = listURIs.find(di.strFormat);
+
+                if (itr != listURIs.end())
                 {
                     strSrcFormat = "VMDK";
-                }
-                else if (!di.strFormat.compare("http://go.microsoft.com/fwlink/?LinkId=137171",
-                                     Utf8Str::CaseInsensitive))
-                {
-                    strSrcFormat = "VHD";
                 }
 
@@ -2624,31 +2707,195 @@
             stack.fSessionOpen = true;
 
-            /* Iterate over all given disk images */
-            list<VirtualSystemDescriptionEntry*>::const_iterator itHD;
-            for (itHD = avsdeHDs.begin();
-                 itHD != avsdeHDs.end();
-                 ++itHD)
-            {
-                VirtualSystemDescriptionEntry *vsdeHD = *itHD;
-
-                // vsdeHD->strRef contains the disk identifier (e.g. "vmdisk1"), which should exist
-                // in the virtual system's disks map under that ID and also in the global images map
-                ovf::VirtualDisksMap::const_iterator itVirtualDisk = vsysThis.mapVirtualDisks.find(vsdeHD->strRef);
-                // and find the disk from the OVF's disk list
-                ovf::DiskImagesMap::const_iterator itDiskImage = stack.mapDisks.find(vsdeHD->strRef);
-                if (    (itVirtualDisk == vsysThis.mapVirtualDisks.end())
-                     || (itDiskImage == stack.mapDisks.end())
-                   )
-                    throw setError(E_FAIL,
-                                   tr("Internal inconsistency looking up disk image '%s'"),
-                                   vsdeHD->strRef.c_str());
-
-                const ovf::DiskImage &ovfDiskImage = itDiskImage->second;
-                const ovf::VirtualDisk &ovfVdisk = itVirtualDisk->second;
+            ovf::DiskImagesMap::const_iterator oit = stack.mapDisks.begin();
+            std::set<RTCString>  disksResolvedNames;
+
+            while(oit != stack.mapDisks.end())
+            {
+                if (RTPathHaveExt(oit->second.strHref.c_str()))
+                {
+                    /* Figure out which format the user have. */
+                    char *pszExt = RTPathExt(oit->second.strHref.c_str());
+                    /* Get the system properties. */
+                    SystemProperties *pSysProps = mVirtualBox->getSystemProperties();
+                    ComObjPtr<MediumFormat> trgFormat = pSysProps->mediumFormatFromExtension(&pszExt[1]);
+                    if (trgFormat.isNull())
+                    {
+                        ++oit;
+                        continue;
+                    }
+                }
+
+                ovf::DiskImage diCurrent = oit->second;
+                ovf::VirtualDisksMap::const_iterator itVDisk = vsysThis.mapVirtualDisks.begin();
+                bool fFoundInCurrentPosition = false;
+
+                VirtualSystemDescriptionEntry *vsdeTargetHD = 0;
+
+                /* 
+                 * 
+                 * Iterate over all given disk images of the virtual system
+                 * disks description. We need to find the target disk path,
+                 * which could be changed by the user. 
+                 *
+                 */
+                {
+                    list<VirtualSystemDescriptionEntry*>::const_iterator itHD;
+                    for (itHD = avsdeHDs.begin();
+                         itHD != avsdeHDs.end();
+                         ++itHD)
+                    {
+                        VirtualSystemDescriptionEntry *vsdeHD = *itHD;
+                        if (vsdeHD->strRef == diCurrent.strDiskId)
+                        {
+                            vsdeTargetHD = vsdeHD;
+                            break;
+                        }
+                    }
+                    if (!vsdeTargetHD)
+                        throw setError(E_FAIL,
+                                       tr("Internal inconsistency looking up disk image '%s'"),
+                                       diCurrent.strHref.c_str());
+
+                    //diCurrent.strDiskId contains the disk identifier (e.g. "vmdisk1"), which should exist
+                    //in the virtual system's disks map under that ID and also in the global images map
+                    itVDisk = vsysThis.mapVirtualDisks.find(diCurrent.strDiskId);
+                    if (itVDisk == vsysThis.mapVirtualDisks.end())
+                        throw setError(E_FAIL,
+                                       tr("Internal inconsistency looking up disk image '%s'"),
+                                       diCurrent.strHref.c_str());
+                }
+
+                /*
+                 *
+                 * preliminary check availability of the image
+                 * This step is useful if image is placed in the OVA (TAR) package
+                 *
+                 */
+
+                Utf8Str name = applianceIOName(applianceIOTar);
+
+                if (strncmp(pStorage->pVDImageIfaces->pszInterfaceName, name.c_str(), name.length()) == 0)
+                {
+                    RTCString availableImage(diCurrent.strHref);
+
+                    rc = preCheckImageAvailability(pStorage,
+                                                   availableImage
+                                                  );
+
+                    if (SUCCEEDED(rc))
+                    {
+                        /* current opened file isn't the same as passed one */
+                        if(availableImage.compare(diCurrent.strHref, Utf8Str::CaseInsensitive) != 0)
+                        {
+
+                            if (RTPathHaveExt(availableImage.c_str()))
+                            {
+                                /* Figure out which format the user have. */
+                                char *pszExt = RTPathExt(availableImage.c_str());
+                                /* Get the system properties. */
+                                SystemProperties *pSysProps = mVirtualBox->getSystemProperties();
+                                ComObjPtr<MediumFormat> trgFormat = pSysProps->mediumFormatFromExtension(&pszExt[1]);
+                                if (trgFormat.isNull())
+                                {
+                                    ++oit;
+                                    continue;
+                                }
+                            }
+
+                            /* 
+                             * 
+                             * availableImage contains the disk file reference (e.g. "disk1.vmdk"), which should exist
+                             * in the global images map.
+                             * And find the disk from the OVF's disk list
+                             *
+                             */
+                            {
+                                ovf::DiskImagesMap::const_iterator itDiskImage = stack.mapDisks.begin();
+                                while (++itDiskImage != stack.mapDisks.end())
+                                {
+                                    if (itDiskImage->second.strHref.compare(availableImage, Utf8Str::CaseInsensitive) == 0)
+                                        break;
+                                }
+                                if (itDiskImage == stack.mapDisks.end())
+                                {
+                                    throw setError(E_FAIL,
+                                                   tr("Internal inconsistency looking up disk image '%s'"),
+                                                   availableImage.c_str());
+                                }
+
+                                /* replace with a new found disk image */
+                                diCurrent = *(&itDiskImage->second);
+                            }
+
+                            /* 
+                             *  
+                             * Again iterate over all given disk images of the virtual system
+                             * disks description using the found disk image 
+                             *  
+                             */
+                            {
+                                list<VirtualSystemDescriptionEntry*>::const_iterator itHD;
+                                for (itHD = avsdeHDs.begin();
+                                     itHD != avsdeHDs.end();
+                                     ++itHD)
+                                {
+                                    VirtualSystemDescriptionEntry *vsdeHD = *itHD;
+                                    if (vsdeHD->strRef == diCurrent.strDiskId)
+                                    {
+                                        vsdeTargetHD = vsdeHD;
+                                        break;
+                                    }
+                                }
+                                if (!vsdeTargetHD)
+                                    throw setError(E_FAIL,
+                                                   tr("Internal inconsistency looking up disk image '%s'"),
+                                                   diCurrent.strHref.c_str());
+
+                                itVDisk = vsysThis.mapVirtualDisks.find(diCurrent.strDiskId);
+                                if (itVDisk == vsysThis.mapVirtualDisks.end())
+                                    throw setError(E_FAIL,
+                                                   tr("Internal inconsistency looking up disk image '%s'"),
+                                                   diCurrent.strHref.c_str());
+                            }
+                        }
+                        else
+                        {
+                            fFoundInCurrentPosition = true;
+                            ++oit;
+                        }
+                    }
+                    else
+                    {
+                        ++oit;
+                        continue;
+                    }
+                }
+                else
+                {
+                    /* just continue with normal files*/
+                    fFoundInCurrentPosition = true;
+                    ++oit;
+                }
+
+                /* It means that we possibly have imported the storage earlier on the previous loop steps*/
+                if (!fFoundInCurrentPosition)
+                {
+                    std::set<RTCString>::const_iterator h = disksResolvedNames.find(diCurrent.strHref);
+                    if (h != disksResolvedNames.end())
+                    {
+                        /* Yes, disk name was found, we can skip it*/
+                        continue;
+                    }
+                }
+
+                const ovf::VirtualDisk &ovfVdisk = itVDisk->second;
+
+                /* very important to store disk name for the next checks */
+                disksResolvedNames.insert(diCurrent.strHref);
 
                 ComObjPtr<Medium> pTargetHD;
 
-                importOneDiskImage(ovfDiskImage,
-                                   vsdeHD->strVboxCurrent,
+                importOneDiskImage(diCurrent,
+                                   vsdeTargetHD->strVboxCurrent,
                                    pTargetHD,
                                    stack,
@@ -2674,38 +2921,37 @@
                                             mhda.lDevice);
 
-                Log(("Attaching disk %s to port %d on device %d\n", vsdeHD->strVboxCurrent.c_str(), mhda.lControllerPort, mhda.lDevice));
-
-                int ifISO = 0;
-                ifISO = ovfDiskImage.strFormat.compare("http://www.ecma-international.org/publications/standards/Ecma-119.htm",
-                                                       Utf8Str::CaseInsensitive);
-                if ( ifISO != 0)
+                Log(("Attaching disk %s to port %d on device %d\n", 
+                vsdeTargetHD->strVboxCurrent.c_str(), mhda.lControllerPort, mhda.lDevice));
+
+                Utf8Str vdf = typeOfVirtualDiskFormatFromURI(diCurrent.strFormat);
+
+                if (vdf.compare("RAW", Utf8Str::CaseInsensitive) == 0)
                 {
-                    rc = sMachine->AttachDevice(mhda.controllerType.raw(),    // wstring name
-                                                mhda.lControllerPort,          // long controllerPort
-                                                mhda.lDevice,           // long device
-                                                DeviceType_HardDisk,    // DeviceType_T type
-                                                pTargetHD);
-
+                    ComPtr<IMedium> dvdImage(pTargetHD);
+
+                    rc = mVirtualBox->OpenMedium(Bstr(vsdeTargetHD->strVboxCurrent).raw(),
+                                                 DeviceType_DVD,
+                                                 AccessMode_ReadWrite,
+                                                 false,
+                                                 dvdImage.asOutParam());
+
+                    if (FAILED(rc)) throw rc;
+
+                    rc = sMachine->AttachDevice(mhda.controllerType.raw(),// wstring name
+                                                mhda.lControllerPort,     // long controllerPort
+                                                mhda.lDevice,             // long device
+                                                DeviceType_DVD,           // DeviceType_T type
+                                                dvdImage);
                     if (FAILED(rc)) throw rc;
                 }
                 else
                 {
-                    ComPtr<IMedium> dvdImage(pTargetHD);
-
-                    rc = mVirtualBox->OpenMedium(Bstr(vsdeHD->strVboxCurrent).raw(),
-                                                 DeviceType_DVD,
-                                                 AccessMode_ReadWrite,
-                                                 false,
-                                                 dvdImage.asOutParam());
+                    rc = sMachine->AttachDevice(mhda.controllerType.raw(),// wstring name
+                                                mhda.lControllerPort,     // long controllerPort
+                                                mhda.lDevice,             // long device
+                                                DeviceType_HardDisk,      // DeviceType_T type
+                                                pTargetHD);
 
                     if (FAILED(rc)) throw rc;
-
-                    rc = sMachine->AttachDevice(mhda.controllerType.raw(),    // wstring name
-                                                mhda.lControllerPort,          // long controllerPort
-                                                mhda.lDevice,           // long device
-                                                DeviceType_DVD,    // DeviceType_T type
-                                                dvdImage);
-                    if (FAILED(rc)) throw rc;
-
                 }
 
@@ -2714,5 +2960,5 @@
                 rc = sMachine->SaveSettings();
                 if (FAILED(rc)) throw rc;
-            } // end for (itHD = avsdeHDs.begin();
+            } // end while(oit != stack.mapDisks.end())
 
             // only now that we're done with all disks, close the session
@@ -2929,68 +3175,110 @@
         fRepairDuplicate = false;
 
-    // for each storage controller...
-    for (settings::StorageControllersList::iterator sit = config.storageMachine.llStorageControllers.begin();
-         sit != config.storageMachine.llStorageControllers.end();
-         ++sit)
-    {
-        settings::StorageController &sc = *sit;
-
-        // find the OVF virtual system description entry for this storage controller
-        switch (sc.storageBus)
-        {
-            case StorageBus_SATA:
-                break;
-            case StorageBus_SCSI:
-                break;
-            case StorageBus_IDE:
-                break;
-            case StorageBus_SAS:
-                break;
-        }
-
-        // for each medium attachment to this controller...
-        for (settings::AttachedDevicesList::iterator dit = sc.llAttachedDevices.begin();
-             dit != sc.llAttachedDevices.end();
-             ++dit)
-        {
-            settings::AttachedDevice &d = *dit;
-
-            if (d.uuid.isZero())
-                // empty DVD and floppy media
+    // there must be an image in the OVF disk structs with the same UUID
+
+    ovf::DiskImagesMap::const_iterator oit = stack.mapDisks.begin();
+    std::set<RTCString>  disksResolvedNames;
+
+    while(oit != stack.mapDisks.end())
+    {
+        if (RTPathHaveExt(oit->first.c_str()))
+        {
+            /* Figure out which format the user have. */
+            char *pszExt = RTPathExt(oit->second.strHref.c_str());
+            /* Get the system properties. */
+            SystemProperties *pSysProps = mVirtualBox->getSystemProperties();
+            ComObjPtr<MediumFormat> trgFormat = pSysProps->mediumFormatFromExtension(&pszExt[1]);
+            if (trgFormat.isNull())
+            {
+                ++oit;
                 continue;
-
-            // When repairing a broken VirtualBox xml config section (written
-            // by VirtualBox versions earlier than 3.2.10) assume the disks
-            // show up in the same order as in the OVF description.
-            if (fRepairDuplicate)
-            {
-                VirtualSystemDescriptionEntry *vsdeHD = *avsdeHDsIt;
-                ovf::DiskImagesMap::const_iterator itDiskImage = stack.mapDisks.find(vsdeHD->strRef);
-                if (itDiskImage != stack.mapDisks.end())
+            }
+        }
+
+        ovf::DiskImage diCurrent = oit->second;
+        bool fFoundInCurrentPosition = false;
+
+        VirtualSystemDescriptionEntry *vsdeTargetHD = 0;
+
+        {
+            /* Iterate over all given disk images of the virtual system
+             * disks description. We need to find the target disk path,
+             * which could be changed by the user. */
+            list<VirtualSystemDescriptionEntry*>::const_iterator itHD;
+            for (itHD = avsdeHDs.begin();
+                 itHD != avsdeHDs.end();
+                 ++itHD)
+            {
+                VirtualSystemDescriptionEntry *vsdeHD = *itHD;
+                if (vsdeHD->strRef == oit->first)
                 {
-                    const ovf::DiskImage &di = itDiskImage->second;
-                    d.uuid = Guid(di.uuidVbox);
+                    vsdeTargetHD = vsdeHD;
+                    break;
                 }
-                ++avsdeHDsIt;
-            }
-
-            // convert the Guid to string
-            Utf8Str strUuid = d.uuid.toString();
-
-            // there must be an image in the OVF disk structs with the same UUID
-            bool fFound = false;
-            for (ovf::DiskImagesMap::const_iterator oit = stack.mapDisks.begin();
-                 oit != stack.mapDisks.end();
-                 ++oit)
-            {
-                const ovf::DiskImage &di = oit->second;
-
-                if (di.uuidVbox == strUuid)
+            }
+            if (!vsdeTargetHD)
+                throw setError(E_FAIL,
+                               tr("Internal inconsistency looking up disk image '%s'"),
+                               oit->first.c_str());
+        }
+
+        /*
+         *
+         * preliminary check availability of the image
+         * This step is useful if image is placed in the OVA (TAR) package
+         *
+         */
+
+        Utf8Str name = applianceIOName(applianceIOTar);
+
+        if (strncmp(pStorage->pVDImageIfaces->pszInterfaceName, name.c_str(), name.length()) == 0)
+        {
+            RTCString availableImage(diCurrent.strHref);
+
+            rc = preCheckImageAvailability(pStorage,
+                                           availableImage
+                                          );
+
+            if (SUCCEEDED(rc))
+            {
+                /* current opened file isn't the same as passed one */
+                if(availableImage.compare(diCurrent.strHref, Utf8Str::CaseInsensitive) != 0)
                 {
-                    VirtualSystemDescriptionEntry *vsdeTargetHD = 0;
-
-                    /* Iterate over all given disk images of the virtual system
-                     * disks description. We need to find the target disk path,
-                     * which could be changed by the user. */
+                    if (RTPathHaveExt(availableImage.c_str()))
+                    {
+                        /* Figure out which format the user have. */
+                        char *pszExt = RTPathExt(availableImage.c_str());
+                        /* Get the system properties. */
+                        SystemProperties *pSysProps = mVirtualBox->getSystemProperties();
+                        ComObjPtr<MediumFormat> trgFormat = pSysProps->mediumFormatFromExtension(&pszExt[1]);
+                        if (trgFormat.isNull())
+                        {
+                            ++oit;
+                            continue;
+                        }
+                    }
+
+                    // availableImage contains the disk identifier (e.g. "vmdisk1"), which should exist
+                    // in the virtual system's disks map under that ID and also in the global images map
+                    // and find the disk from the OVF's disk list
+                    ovf::DiskImagesMap::const_iterator itDiskImage = stack.mapDisks.begin();
+                    while (++itDiskImage != stack.mapDisks.end())
+                    {
+                        if(itDiskImage->second.strHref.compare(availableImage, Utf8Str::CaseInsensitive) == 0 )
+                            break;
+                    }
+                    if (itDiskImage == stack.mapDisks.end())
+                    {
+                        throw setError(E_FAIL,
+                                       tr("Internal inconsistency looking up disk image '%s'"),
+                                       availableImage.c_str());
+                    }
+
+                    /* replace with a new found disk image */
+                    diCurrent = *(&itDiskImage->second);
+
+                    /* Again iterate over all given disk images of the virtual system
+                     * disks description using the found disk image
+                     */
                     list<VirtualSystemDescriptionEntry*>::const_iterator itHD;
                     for (itHD = avsdeHDs.begin();
@@ -2999,5 +3287,5 @@
                     {
                         VirtualSystemDescriptionEntry *vsdeHD = *itHD;
-                        if (vsdeHD->strRef == oit->first)
+                        if (vsdeHD->strRef == diCurrent.strDiskId)
                         {
                             vsdeTargetHD = vsdeHD;
@@ -3008,62 +3296,152 @@
                         throw setError(E_FAIL,
                                        tr("Internal inconsistency looking up disk image '%s'"),
-                                       oit->first.c_str());
-
-                    /*
-                     *
-                     * step 3: import disk
-                     *
-                     */
-                    ComObjPtr<Medium> pTargetHD;
-                    importOneDiskImage(di,
-                                       vsdeTargetHD->strVboxCurrent,
-                                       pTargetHD,
-                                       stack,
-                                       pCallbacks,
-                                       pStorage);
-
-                    Bstr hdId;
-                    int ifISO = 0;
-                    ifISO = di.strFormat.compare("http://www.ecma-international.org/publications/standards/Ecma-119.htm",
-                                                           Utf8Str::CaseInsensitive);
-                    if ( ifISO == 0)
+                                       diCurrent.strHref.c_str());
+                }
+                else
+                {
+                    fFoundInCurrentPosition = true;
+                    ++oit;
+                }
+            }
+            else
+            {
+                ++oit;
+                continue;
+            }
+        }
+        else
+        {
+            /* just continue with normal files*/
+            fFoundInCurrentPosition = true;
+            ++oit;
+        }
+
+        /* It means that we possibly have imported the storage earlier on the previous loop steps*/
+        if (!fFoundInCurrentPosition)
+        {
+            std::set<RTCString>::const_iterator h = disksResolvedNames.find(diCurrent.strHref);
+            if (h != disksResolvedNames.end())
+            {
+                /* Yes, disk name was found, we can skip it*/
+                continue;
+            }
+        }
+
+        /* Important! to store disk name for the next checks */
+        disksResolvedNames.insert(diCurrent.strHref);
+
+        // there must be an image in the OVF disk structs with the same UUID
+        bool fFound = false;
+        Utf8Str strUuid;
+
+        // for each storage controller...
+        for (settings::StorageControllersList::iterator sit = config.storageMachine.llStorageControllers.begin();
+             sit != config.storageMachine.llStorageControllers.end();
+             ++sit)
+        {
+            settings::StorageController &sc = *sit;
+
+            // find the OVF virtual system description entry for this storage controller
+            switch (sc.storageBus)
+            {
+                case StorageBus_SATA:
+                    break;
+                case StorageBus_SCSI:
+                    break;
+                case StorageBus_IDE:
+                    break;
+                case StorageBus_SAS:
+                    break;
+            }
+
+            // for each medium attachment to this controller...
+            for (settings::AttachedDevicesList::iterator dit = sc.llAttachedDevices.begin();
+                 dit != sc.llAttachedDevices.end();
+                 ++dit)
+            {
+                settings::AttachedDevice &d = *dit;
+
+                if (d.uuid.isZero())
+                    // empty DVD and floppy media
+                    continue;
+
+                // When repairing a broken VirtualBox xml config section (written
+                // by VirtualBox versions earlier than 3.2.10) assume the disks
+                // show up in the same order as in the OVF description.
+                if (fRepairDuplicate)
+                {
+                    VirtualSystemDescriptionEntry *vsdeHD = *avsdeHDsIt;
+                    ovf::DiskImagesMap::const_iterator itDiskImage = stack.mapDisks.find(vsdeHD->strRef);
+                    if (itDiskImage != stack.mapDisks.end())
                     {
-                        ComPtr<IMedium> dvdImage(pTargetHD);
-
-                        rc = mVirtualBox->OpenMedium(Bstr(vsdeTargetHD->strVboxCurrent).raw(),
-                                                     DeviceType_DVD,
-                                                     AccessMode_ReadWrite,
-                                                     false,
-                                                     dvdImage.asOutParam());
-
-                        if (FAILED(rc)) throw rc;
-
-                        // ... and replace the old UUID in the machine config with the one of
-                        // the imported disk that was just created
-                        rc = dvdImage->COMGETTER(Id)(hdId.asOutParam());
-                        if (FAILED(rc)) throw rc;
+                        const ovf::DiskImage &di = itDiskImage->second;
+                        d.uuid = Guid(di.uuidVbox);
                     }
-                    else
-                    {
-                        // ... and replace the old UUID in the machine config with the one of
-                        // the imported disk that was just created
-                        rc = pTargetHD->COMGETTER(Id)(hdId.asOutParam());
-                        if (FAILED(rc)) throw rc;
-                    }
-
-                    d.uuid = hdId;
-
-                    fFound = true;
-                    break;
+                    ++avsdeHDsIt;
                 }
-            }
+
+                // convert the Guid to string
+                strUuid = d.uuid.toString();
+
+                if (diCurrent.uuidVbox != strUuid)
+                {
+                    continue;
+                }
+                /*
+                 *
+                 * step 3: import disk
+                 *
+                 */
+                ComObjPtr<Medium> pTargetHD;
+                importOneDiskImage(diCurrent,
+                                   vsdeTargetHD->strVboxCurrent,
+                                   pTargetHD,
+                                   stack,
+                                   pCallbacks,
+                                   pStorage);
+
+                Bstr hdId;
+
+                Utf8Str vdf = typeOfVirtualDiskFormatFromURI(diCurrent.strFormat);
+
+                if (vdf.compare("RAW", Utf8Str::CaseInsensitive) == 0)
+                {
+                    ComPtr<IMedium> dvdImage(pTargetHD);
+
+                    rc = mVirtualBox->OpenMedium(Bstr(vsdeTargetHD->strVboxCurrent).raw(),
+                                                 DeviceType_DVD,
+                                                 AccessMode_ReadWrite,
+                                                 false,
+                                                 dvdImage.asOutParam());
+
+                    if (FAILED(rc)) throw rc;
+
+                    // ... and replace the old UUID in the machine config with the one of
+                    // the imported disk that was just created
+                    rc = dvdImage->COMGETTER(Id)(hdId.asOutParam());
+                    if (FAILED(rc)) throw rc;
+                }
+                else
+                {
+                    // ... and replace the old UUID in the machine config with the one of
+                    // the imported disk that was just created
+                    rc = pTargetHD->COMGETTER(Id)(hdId.asOutParam());
+                    if (FAILED(rc)) throw rc;
+                }
+
+                d.uuid = hdId;
+                fFound = true;
+                break;
+            } // for (settings::AttachedDevicesList::const_iterator dit = sc.llAttachedDevices.begin();
+        } // for (settings::StorageControllersList::const_iterator sit = config.storageMachine.llStorageControllers.begin();
 
             // no disk with such a UUID found:
-            if (!fFound)
-                throw setError(E_FAIL,
-                               tr("<vbox:Machine> element in OVF contains a medium attachment for the disk image %s but the OVF describes no such image"),
-                               strUuid.c_str());
-        } // for (settings::AttachedDevicesList::const_iterator dit = sc.llAttachedDevices.begin();
-    } // for (settings::StorageControllersList::const_iterator sit = config.storageMachine.llStorageControllers.begin();
+        if (!fFound)
+            throw setError(E_FAIL,
+                           tr("<vbox:Machine> element in OVF contains a medium attachment for the disk image %s "
+                              "but the OVF describes no such image"),
+                           strUuid.c_str());
+
+    }// while(oit != stack.mapDisks.end())
 
     /*
@@ -3080,6 +3458,6 @@
     // instance that we created from the vbox:Machine
     rc = pNewMachine->init(mVirtualBox,
-                           stack.strNameVBox,       // name from OVF preparations; can be suffixed to avoid duplicates, or changed by user
-                           config);                 // the whole machine config
+                           stack.strNameVBox,// name from OVF preparations; can be suffixed to avoid duplicates, or changed by user
+                           config);          // the whole machine config
     if (FAILED(rc)) throw rc;
 
@@ -3225,2 +3603,3 @@
 }
 
+
Index: /trunk/src/VBox/Main/xml/ovfreader.cpp
===================================================================
--- /trunk/src/VBox/Main/xml/ovfreader.cpp	(revision 46517)
+++ /trunk/src/VBox/Main/xml/ovfreader.cpp	(revision 46518)
@@ -91,17 +91,4 @@
     }
 
-//    if ((pTypeAttr = pRootElem->findAttribute("version")))
-//    {
-//        pcszTypeAttr = pTypeAttr->getValue();
-//        m_envelopeData.version = pcszTypeAttr;
-//    }
-//    else
-//    {
-//        throw OVFLogicError(N_("Error reading \"%s\": missing or invalid attribute '%s' in 'Envelope' element, line %d"),
-//                           m_strPath.c_str(),
-//                            "version",
-//                            pRootElem->getLineNumber());
-//    }
-
     if ((pTypeAttr = pRootElem->findAttribute("xml:lang")))
     {
@@ -255,4 +242,5 @@
                    )
                 {
+
                     // copy remaining values from file node then
                     const char *pcszBadInFile = NULL;
@@ -432,92 +420,78 @@
             }
 
-            xml::NodesLoop loopVirtualHardwareItems(*pelmThis, "Item");      // all "Item" child elements
-            const xml::ElementNode *pelmItem;
-            while ((pelmItem = loopVirtualHardwareItems.forAllNodes()))
             {
-                VirtualHardwareItem i;
-
-                i.ulLineNumber = pelmItem->getLineNumber();
-
-                xml::NodesLoop loopItemChildren(*pelmItem);      // all child elements
-                const xml::ElementNode *pelmItemChild;
-                while ((pelmItemChild = loopItemChildren.forAllNodes()))
+                xml::NodesLoop loopVirtualHardwareItems(*pelmThis, "Item");      // all "Item" child elements
+                const xml::ElementNode *pelmItem;
+                while ((pelmItem = loopVirtualHardwareItems.forAllNodes()))
                 {
-                    const char *pcszItemChildName = pelmItemChild->getName();
-                    if (!strcmp(pcszItemChildName, "Description"))
-                        i.strDescription = pelmItemChild->getValue();
-                    else if (!strcmp(pcszItemChildName, "Caption"))
-                        i.strCaption = pelmItemChild->getValue();
-                    else if (!strcmp(pcszItemChildName, "ElementName"))
-                        i.strElementName = pelmItemChild->getValue();
-                    else if (    (!strcmp(pcszItemChildName, "InstanceID"))
-                              || (!strcmp(pcszItemChildName, "InstanceId"))
-                            )
-                        pelmItemChild->copyValue(i.ulInstanceID);
-                    else if (!strcmp(pcszItemChildName, "HostResource"))
-                        i.strHostResource = pelmItemChild->getValue();
-                    else if (!strcmp(pcszItemChildName, "ResourceType"))
+                    VirtualHardwareItem i;
+
+                    i.ulLineNumber = pelmItem->getLineNumber();
+                    i.fillItem(pelmItem);
+                    try{
+                        i.checkConsistencyAndCompliance();
+                    }
+                    catch (OVFLogicError &e)
                     {
-                        uint32_t ulType;
-                        pelmItemChild->copyValue(ulType);
-                        i.resourceType = (ResourceType_T)ulType;
-                        i.fResourceRequired = true;
-                        const char *pcszAttValue;
-                        if (pelmItem->getAttributeValue("required", pcszAttValue))
-                        {
-                            if (!strcmp(pcszAttValue, "false"))
-                                i.fResourceRequired = false;
-                        }
-                    }
-                    else if (!strcmp(pcszItemChildName, "OtherResourceType"))
-                        i.strOtherResourceType = pelmItemChild->getValue();
-                    else if (!strcmp(pcszItemChildName, "ResourceSubType"))
-                        i.strResourceSubType = pelmItemChild->getValue();
-                    else if (!strcmp(pcszItemChildName, "AutomaticAllocation"))
-                        i.fAutomaticAllocation = (!strcmp(pelmItemChild->getValue(), "true")) ? true : false;
-                    else if (!strcmp(pcszItemChildName, "AutomaticDeallocation"))
-                        i.fAutomaticDeallocation = (!strcmp(pelmItemChild->getValue(), "true")) ? true : false;
-                    else if (!strcmp(pcszItemChildName, "Parent"))
-                        pelmItemChild->copyValue(i.ulParent);
-                    else if (!strcmp(pcszItemChildName, "Connection"))
-                        i.strConnection = pelmItemChild->getValue();
-                    else if (!strcmp(pcszItemChildName, "Address"))
+                        throw OVFLogicError(N_("Error reading \"%s\": \"%s\""),
+                                            m_strPath.c_str(),
+                                            e.what());
+                    }
+
+                    // store!
+                    vsys.mapHardwareItems[i.ulInstanceID] = i;
+                }
+            }
+
+            {
+                xml::NodesLoop loopVirtualHardwareItems(*pelmThis, "StorageItem");// all "StorageItem" child elements
+                const xml::ElementNode *pelmItem;
+                while ((pelmItem = loopVirtualHardwareItems.forAllNodes()))
+                {
+                    StorageItem i;
+
+                    i.ulLineNumber = pelmItem->getLineNumber();
+                    i.fillItem(pelmItem);
+
+                    try
                     {
-                        i.strAddress = pelmItemChild->getValue();
-                        pelmItemChild->copyValue(i.lAddress);
-                    }
-                    else if (!strcmp(pcszItemChildName, "AddressOnParent"))
-                        i.strAddressOnParent = pelmItemChild->getValue();
-                    else if (!strcmp(pcszItemChildName, "AllocationUnits"))
-                        i.strAllocationUnits = pelmItemChild->getValue();
-                    else if (!strcmp(pcszItemChildName, "VirtualQuantity"))
-                        pelmItemChild->copyValue(i.ullVirtualQuantity);
-                    else if (!strcmp(pcszItemChildName, "Reservation"))
-                        pelmItemChild->copyValue(i.ullReservation);
-                    else if (!strcmp(pcszItemChildName, "Limit"))
-                        pelmItemChild->copyValue(i.ullLimit);
-                    else if (!strcmp(pcszItemChildName, "Weight"))
-                        pelmItemChild->copyValue(i.ullWeight);
-                    else if (!strcmp(pcszItemChildName, "ConsumerVisibility"))
-                        i.strConsumerVisibility = pelmItemChild->getValue();
-                    else if (!strcmp(pcszItemChildName, "MappingBehavior"))
-                        i.strMappingBehavior = pelmItemChild->getValue();
-                    else if (!strcmp(pcszItemChildName, "PoolID"))
-                        i.strPoolID = pelmItemChild->getValue();
-                    else if (!strcmp(pcszItemChildName, "BusNumber"))       // seen in some old OVF, but it's not listed in the OVF specs
-                        pelmItemChild->copyValue(i.ulBusNumber);
-                    else if (   pelmItemChild->getPrefix() == NULL
-                             || strcmp(pelmItemChild->getPrefix(), "vmw"))
-                        throw OVFLogicError(N_("Error reading \"%s\": unknown element \"%s\" under Item element, line %d"),
+                        i.checkConsistencyAndCompliance();
+                    }
+                    catch (OVFLogicError &e)
+                    {
+                        throw OVFLogicError(N_("Error reading \"%s\": \"%s\""),
                                             m_strPath.c_str(),
-                                            pcszItemChildName,
-                                            i.ulLineNumber);
+                                            e.what());
+                    }
+
+                    vsys.mapHardwareItems[i.ulInstanceID] = i;
                 }
-
-                // store!
-                vsys.mapHardwareItems[i.ulInstanceID] = i;
             }
 
-            HardDiskController *pPrimaryIDEController = NULL;       // will be set once found
+            {
+                xml::NodesLoop loopVirtualHardwareItems(*pelmThis, "EthernetPortItem");// all "EthernetPortItem" child elements
+                const xml::ElementNode *pelmItem;
+                while ((pelmItem = loopVirtualHardwareItems.forAllNodes()))
+                {
+                    EthernetPortItem i;
+
+                    i.ulLineNumber = pelmItem->getLineNumber();
+                    i.fillItem(pelmItem);
+
+                    try{
+                        i.checkConsistencyAndCompliance();
+                    }
+                    catch (OVFLogicError &e)
+                    {
+                        throw OVFLogicError(N_("Error reading \"%s\": \"%s\""),
+                                            m_strPath.c_str(),
+                                            e.what());
+                    }
+
+                    vsys.mapHardwareItems[i.ulInstanceID] = i;
+                }
+            }
+
+            HardDiskController *pPrimaryIDEController = NULL;// will be set once found
 
             // now go thru all hardware items and handle them according to their type;
@@ -857,4 +831,222 @@
 }
 
+void VirtualHardwareItem::fillItem(const xml::ElementNode *item)
+{
+    xml::NodesLoop loopItemChildren(*item);// all child elements
+    const xml::ElementNode *pelmItemChild;
+    while ((pelmItemChild = loopItemChildren.forAllNodes()))
+    {
+        const char *pcszItemChildName = pelmItemChild->getName();
+        if (!strcmp(pcszItemChildName, "Description"))
+            strDescription = pelmItemChild->getValue();
+        else if (!strcmp(pcszItemChildName, "Caption"))
+            strCaption = pelmItemChild->getValue();
+        else if (!strcmp(pcszItemChildName, "ElementName"))
+            strElementName = pelmItemChild->getValue();
+        else if ((!strcmp(pcszItemChildName, "InstanceID"))
+                 ||(!strcmp(pcszItemChildName, "InstanceId"))
+                )
+            pelmItemChild->copyValue(ulInstanceID);
+        else if (!strcmp(pcszItemChildName, "HostResource"))
+            strHostResource = pelmItemChild->getValue();
+        else if (!strcmp(pcszItemChildName, "ResourceType"))
+        {
+            uint32_t ulType;
+            pelmItemChild->copyValue(ulType);
+            resourceType = (ResourceType_T)ulType;
+            fResourceRequired = true;
+            const char *pcszAttValue;
+            if (pelmItemChild->getAttributeValue("required", pcszAttValue))
+            {
+                if (!strcmp(pcszAttValue, "false"))
+                    fResourceRequired = false;
+            }
+        }
+        else if (!strcmp(pcszItemChildName, "OtherResourceType"))
+            strOtherResourceType = pelmItemChild->getValue();
+        else if (!strcmp(pcszItemChildName, "ResourceSubType"))
+            strResourceSubType = pelmItemChild->getValue();
+        else if (!strcmp(pcszItemChildName, "AutomaticAllocation"))
+            fAutomaticAllocation = (!strcmp(pelmItemChild->getValue(), "true")) ? true : false;
+        else if (!strcmp(pcszItemChildName, "AutomaticDeallocation"))
+            fAutomaticDeallocation = (!strcmp(pelmItemChild->getValue(), "true")) ? true : false;
+        else if (!strcmp(pcszItemChildName, "Parent"))
+            pelmItemChild->copyValue(ulParent);
+        else if (!strcmp(pcszItemChildName, "Connection"))
+            strConnection = pelmItemChild->getValue();
+        else if (!strcmp(pcszItemChildName, "Address"))
+        {
+            strAddress = pelmItemChild->getValue();
+            pelmItemChild->copyValue(lAddress);
+        }
+        else if (!strcmp(pcszItemChildName, "AddressOnParent"))
+            strAddressOnParent = pelmItemChild->getValue();
+        else if (!strcmp(pcszItemChildName, "AllocationUnits"))
+            strAllocationUnits = pelmItemChild->getValue();
+        else if (!strcmp(pcszItemChildName, "VirtualQuantity"))
+            pelmItemChild->copyValue(ullVirtualQuantity);
+        else if (!strcmp(pcszItemChildName, "Reservation"))
+            pelmItemChild->copyValue(ullReservation);
+        else if (!strcmp(pcszItemChildName, "Limit"))
+            pelmItemChild->copyValue(ullLimit);
+        else if (!strcmp(pcszItemChildName, "Weight"))
+            pelmItemChild->copyValue(ullWeight);
+        else if (!strcmp(pcszItemChildName, "ConsumerVisibility"))
+            strConsumerVisibility = pelmItemChild->getValue();
+        else if (!strcmp(pcszItemChildName, "MappingBehavior"))
+            strMappingBehavior = pelmItemChild->getValue();
+        else if (!strcmp(pcszItemChildName, "PoolID"))
+            strPoolID = pelmItemChild->getValue();
+        else if (!strcmp(pcszItemChildName, "BusNumber"))
+            pelmItemChild->copyValue(ulBusNumber);
+//      else if (pelmItemChild->getPrefix() == NULL
+//               || strcmp(pelmItemChild->getPrefix(), "vmw"))
+//          throw OVFLogicError(N_("Unknown element \"%s\" under Item element, line %d"),
+//                              pcszItemChildName,
+//                              ulLineNumber);
+    }
+}
+
+void VirtualHardwareItem::_checkConsistencyAndCompliance() throw (OVFLogicError)
+{
+    RTCString name = getItemName();
+    if (ulInstanceID == 0)
+        throw OVFLogicError(N_("Element InstanceID is absent under %s element, line %d. "
+                               "see DMTF Schema Documentation %s"),
+                name.c_str(), ulLineNumber, DTMF_SPECS_URI);
+    if (resourceType == 0)
+        throw OVFLogicError(N_("Empty element ResourceType under %s element, line %d. "
+                               "see DMTF Schema Documentation %s"),
+                name.c_str(), ulLineNumber, DTMF_SPECS_URI);
+}
+
+void StorageItem::fillItem(const xml::ElementNode *item)
+{
+    VirtualHardwareItem::fillItem(item);
+
+    xml::NodesLoop loopItemChildren(*item);// all child elements
+    const xml::ElementNode *pelmItemChild;
+    while ((pelmItemChild = loopItemChildren.forAllNodes()))
+    {
+        const char *pcszItemChildName = pelmItemChild->getName();
+        if (!strcmp(pcszItemChildName, "HostExtentName"))
+            strHostExtentName = pelmItemChild->getValue();
+        else if (!strcmp(pcszItemChildName, "OtherHostExtentNameFormat"))
+            strOtherHostExtentNameFormat = pelmItemChild->getValue();
+        else if (!strcmp(pcszItemChildName, "OtherHostExtentNameNamespace"))
+            strOtherHostExtentNameNamespace = pelmItemChild->getValue();
+        else if (!strcmp(pcszItemChildName, "VirtualQuantityUnits"))
+            strVirtualQuantityUnits = pelmItemChild->getValue();
+        else if (!strcmp(pcszItemChildName, "Access"))
+        {
+            uint32_t temp;
+            pelmItemChild->copyValue(temp);
+            accessType = (StorageAccessType_T)temp;
+        }
+        else if (!strcmp(pcszItemChildName, "HostExtentNameFormat"))
+        {
+        }
+        else if (!strcmp(pcszItemChildName, "HostExtentNameNamespace"))
+        {
+        }
+        else if (!strcmp(pcszItemChildName, "HostExtentStartingAddress"))
+        {
+        }
+        else if (!strcmp(pcszItemChildName, "HostResourceBlockSize"))
+        {
+            int64_t temp;
+            pelmItemChild->copyValue(temp);
+            hostResourceBlockSize = temp;
+        }
+        else if (!strcmp(pcszItemChildName, "Limit"))
+        {
+            int64_t temp;
+            pelmItemChild->copyValue(temp);
+            limit = temp;
+        }
+        else if (!strcmp(pcszItemChildName, "Reservation"))
+        {
+            int64_t temp;
+            pelmItemChild->copyValue(temp);
+            reservation = temp;
+        }
+        else if (!strcmp(pcszItemChildName, "VirtualQuantity"))
+        {
+            int64_t temp;
+            pelmItemChild->copyValue(temp);
+            virtualQuantity = temp;
+        }
+        else if (!strcmp(pcszItemChildName, "VirtualResourceBlockSize"))
+        {
+            int64_t temp;
+            pelmItemChild->copyValue(temp);
+            virtualResourceBlockSize = temp;
+        }
+    }
+}
+
+
+void StorageItem::_checkConsistencyAndCompliance() throw (OVFLogicError)
+{
+    VirtualHardwareItem::_checkConsistencyAndCompliance();
+
+    RTCString name = getItemName();
+
+    if (accessType == StorageAccessType_Unknown)
+    {
+        //throw OVFLogicError(N_("Access type is unknown under %s element, line %d"),
+        //        name.c_str(), ulLineNumber);
+    }
+
+    if (hostResourceBlockSize <= 0 && reservation > 0)
+    {
+        throw OVFLogicError(N_("Element HostResourceBlockSize is absent under %s element, line %d. "
+                               "see DMTF Schema Documentation %s"),
+                name.c_str(), ulLineNumber, DTMF_SPECS_URI);
+    }
+
+    if (virtualResourceBlockSize <= 0 && virtualQuantity > 0)
+    {
+        throw OVFLogicError(N_("Element VirtualResourceBlockSize is absent under %s element, line %d. "
+                               "see DMTF Schema Documentation %s"),
+                name.c_str(), ulLineNumber, DTMF_SPECS_URI);
+    }
+
+    if (virtualQuantity > 0 && strVirtualQuantityUnits.isEmpty())
+    {
+        throw OVFLogicError(N_("Element VirtualQuantityUnits is absent under %s element, line %d. "
+                               "see DMTF Schema Documentation %s"),
+                name.c_str(), ulLineNumber, DTMF_SPECS_URI);
+    }
+
+    if (virtualResourceBlockSize <= 1 &&
+        strVirtualQuantityUnits.compare(RTCString("count"), RTCString::CaseInsensitive) == 0
+       )
+    {
+        throw OVFLogicError(N_("Element VirtualQuantityUnits is set to \"count\" "
+                               "while VirtualResourceBlockSize is set to 1. "
+                               "under %s element, line %d. "
+                               "It's needed to change on \"byte\". "
+                               "see DMTF Schema Documentation %s"),
+                                name.c_str(), ulLineNumber, DTMF_SPECS_URI);
+    }
+}
+
+void EthernetPortItem::fillItem(const xml::ElementNode *item)
+{
+    VirtualHardwareItem::fillItem(item);
+
+    xml::NodesLoop loopItemChildren(*item);// all child elements
+    const xml::ElementNode *pelmItemChild;
+    while ((pelmItemChild = loopItemChildren.forAllNodes()))
+    {
+    }
+}
+
+void EthernetPortItem::_checkConsistencyAndCompliance() throw (OVFLogicError)
+{
+    VirtualHardwareItem::_checkConsistencyAndCompliance();
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 //
Index: /trunk/src/VBox/Runtime/common/zip/tar.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/zip/tar.cpp	(revision 46517)
+++ /trunk/src/VBox/Runtime/common/zip/tar.cpp	(revision 46518)
@@ -90,14 +90,4 @@
 typedef RTTARRECORD *PRTTARRECORD;
 
-
-#if 0 /* not currently used */
-typedef struct RTTARFILELIST
-{
-    char *pszFilename;
-    RTTARFILELIST *pNext;
-} RTTARFILELIST;
-typedef RTTARFILELIST *PRTTARFILELIST;
-#endif
-
 /** Pointer to a tar file handle. */
 typedef struct RTTARFILEINTERNAL *PRTTARFILEINTERNAL;
@@ -150,4 +140,14 @@
 typedef RTTARFILEINTERNAL *PRTTARFILEINTERNAL;
 
+#if 0 /* not currently used */
+typedef struct RTTARFILELIST
+{
+    char *pszFilename;
+    RTTARFILELIST *pNext;
+} RTTARFILELIST;
+typedef RTTARFILELIST *PRTTARFILELIST;
+#endif
+
+
 
 /******************************************************************************
