Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp	(revision 78427)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp	(revision 78428)
@@ -146,10 +146,20 @@
     { "--disk",                 'D', RTGETOPT_REQ_STRING },
     { "--options",              'O', RTGETOPT_REQ_STRING },
+
+    { "--cloud",                'j', RTGETOPT_REQ_NOTHING},
+    { "--cloudprofile",         'k', RTGETOPT_REQ_STRING },
+    { "--cloudinstanceid",      'l', RTGETOPT_REQ_STRING }
 };
+
+enum
+{
+    NOT_SET, LOCAL, CLOUD
+} actionType;
 
 RTEXITCODE handleImportAppliance(HandlerArg *arg)
 {
     HRESULT rc = S_OK;
-
+    bool fCloud = false; // the default
+    actionType = NOT_SET;
     Utf8Str strOvfFilename;
     bool fExecute = true;                  // if true, then we actually do the import
@@ -182,4 +192,12 @@
 
             case 's':   // --vsys
+                if (fCloud == false && actionType == NOT_SET)
+                    actionType = LOCAL;
+
+                if (actionType != LOCAL)
+                    return errorSyntax(USAGE_EXPORTAPPLIANCE,
+                                       "Option \"%s\" can't be used together with \"--cloud\" argument.",
+                                       GetState.pDef->pszLong);
+
                 ulCurVsys = ValueUnion.u32;
                 ulCurUnit = (uint32_t)-1;
@@ -187,11 +205,11 @@
 
             case 'o':   // --ostype
-                if (ulCurVsys == (uint32_t)-1)
-                    return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
+                if (actionType == LOCAL && ulCurVsys == (uint32_t)-1)
+                    return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                 mapArgsMapsPerVsys[ulCurVsys]["ostype"] = ValueUnion.psz;
                 break;
 
             case 'V':   // --vmname
-                if (ulCurVsys == (uint32_t)-1)
+                if (actionType == LOCAL && ulCurVsys == (uint32_t)-1)
                     return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                 mapArgsMapsPerVsys[ulCurVsys]["vmname"] = ValueUnion.psz;
@@ -199,5 +217,5 @@
 
             case 'S':   // --settingsfile
-                if (ulCurVsys == (uint32_t)-1)
+                if (actionType == LOCAL && ulCurVsys == (uint32_t)-1)
                     return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                 mapArgsMapsPerVsys[ulCurVsys]["settingsfile"] = ValueUnion.psz;
@@ -205,5 +223,5 @@
 
             case 'p':   // --basefolder
-                if (ulCurVsys == (uint32_t)-1)
+                if (actionType == LOCAL && ulCurVsys == (uint32_t)-1)
                     return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                 mapArgsMapsPerVsys[ulCurVsys]["basefolder"] = ValueUnion.psz;
@@ -211,5 +229,5 @@
 
             case 'g':   // --group
-                if (ulCurVsys == (uint32_t)-1)
+                if (actionType == LOCAL && ulCurVsys == (uint32_t)-1)
                     return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                 mapArgsMapsPerVsys[ulCurVsys]["group"] = ValueUnion.psz;
@@ -217,5 +235,5 @@
 
             case 'd':   // --description
-                if (ulCurVsys == (uint32_t)-1)
+                if (actionType == LOCAL && ulCurVsys == (uint32_t)-1)
                     return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                 mapArgsMapsPerVsys[ulCurVsys]["description"] = ValueUnion.psz;
@@ -223,5 +241,5 @@
 
             case 'L':   // --eula
-                if (ulCurVsys == (uint32_t)-1)
+                if (actionType == LOCAL && ulCurVsys == (uint32_t)-1)
                     return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                 mapArgsMapsPerVsys[ulCurVsys]["eula"] = ValueUnion.psz;
@@ -229,5 +247,5 @@
 
             case 'm':   // --memory
-                if (ulCurVsys == (uint32_t)-1)
+                if (actionType == LOCAL && ulCurVsys == (uint32_t)-1)
                     return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                 mapArgsMapsPerVsys[ulCurVsys]["memory"] = ValueUnion.psz;
@@ -235,5 +253,5 @@
 
             case 'c':   // --cpus
-                if (ulCurVsys == (uint32_t)-1)
+                if (actionType == LOCAL && ulCurVsys == (uint32_t)-1)
                     return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                 mapArgsMapsPerVsys[ulCurVsys]["cpus"] = ValueUnion.psz;
@@ -245,5 +263,5 @@
 
             case 'x':   // --ignore
-                if (ulCurVsys == (uint32_t)-1)
+                if (actionType == LOCAL && ulCurVsys == (uint32_t)-1)
                     return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                 if (ulCurUnit == (uint32_t)-1)
@@ -253,5 +271,5 @@
 
             case 'T':   // --scsitype
-                if (ulCurVsys == (uint32_t)-1)
+                if (actionType == LOCAL && ulCurVsys == (uint32_t)-1)
                     return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                 if (ulCurUnit == (uint32_t)-1)
@@ -261,5 +279,5 @@
 
             case 'C':   // --controller
-                if (ulCurVsys == (uint32_t)-1)
+                if (actionType == LOCAL && ulCurVsys == (uint32_t)-1)
                     return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                 if (ulCurUnit == (uint32_t)-1)
@@ -269,5 +287,5 @@
 
             case 'D':   // --disk
-                if (ulCurVsys == (uint32_t)-1)
+                if (actionType == LOCAL && ulCurVsys == (uint32_t)-1)
                     return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                 if (ulCurUnit == (uint32_t)-1)
@@ -279,4 +297,35 @@
                 if (RT_FAILURE(parseImportOptions(ValueUnion.psz, &options)))
                     return errorArgument("Invalid import options '%s'\n", ValueUnion.psz);
+                break;
+
+                /*--cloud and --vsys are orthogonal, only one must be presented*/
+            case 'j':   // --cloud
+                if (fCloud == false && actionType == NOT_SET)
+                {
+                    fCloud = true;
+                    actionType = CLOUD;
+                }
+
+                if (actionType != CLOUD)
+                    return errorSyntax(USAGE_IMPORTAPPLIANCE,
+                                       "Option \"%s\" can't be used together with \"--vsys\" argument.",
+                                       GetState.pDef->pszLong);
+
+                ulCurVsys = 0;
+                break;
+
+                /* Cloud export settings */
+            case 'k':   // --cloudprofile
+                if (actionType != CLOUD)
+                    return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.",
+                                       GetState.pDef->pszLong);
+                mapArgsMapsPerVsys[ulCurVsys]["cloudprofile"] = ValueUnion.psz;
+                break;
+
+            case 'l':   // --cloudinstanceid
+                if (actionType != CLOUD)
+                    return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.",
+                                       GetState.pDef->pszLong);
+                mapArgsMapsPerVsys[ulCurVsys]["cloudinstanceid"] = ValueUnion.psz;
                 break;
 
@@ -305,5 +354,5 @@
     }
 
-    if (strOvfFilename.isEmpty())
+    if (actionType == LOCAL && strOvfFilename.isEmpty())
         return errorSyntax(USAGE_IMPORTAPPLIANCE, "Not enough arguments for \"import\" command.");
 
@@ -313,11 +362,25 @@
         CHECK_ERROR_BREAK(arg->virtualBox, CreateAppliance(pAppliance.asOutParam()));
 
+        //in the case of Cloud, append the instance id here because later it's harder to do
+        if (actionType == CLOUD &&
+            mapArgsMapsPerVsys[ulCurVsys]["cloudprofile"].isNotEmpty() &&
+            mapArgsMapsPerVsys[ulCurVsys]["cloudinstanceid"].isNotEmpty())
+        {
+            strOvfFilename.append(mapArgsMapsPerVsys[ulCurVsys]["cloudprofile"]);
+            strOvfFilename.append("/");
+            strOvfFilename.append(mapArgsMapsPerVsys[ulCurVsys]["cloudinstanceid"]);
+        }
+        else 
+            return errorSyntax(USAGE_IMPORTAPPLIANCE, "Not enough arguments for import from the Cloud.");
+
         char *pszAbsFilePath;
         if (strOvfFilename.startsWith("S3://", RTCString::CaseInsensitive) ||
             strOvfFilename.startsWith("SunCloud://", RTCString::CaseInsensitive) ||
-            strOvfFilename.startsWith("webdav://", RTCString::CaseInsensitive))
+            strOvfFilename.startsWith("webdav://", RTCString::CaseInsensitive) ||
+            strOvfFilename.startsWith("OCI://", RTCString::CaseInsensitive))
             pszAbsFilePath = RTStrDup(strOvfFilename.c_str());
         else
             pszAbsFilePath = RTPathAbsDup(strOvfFilename.c_str());
+
         ComPtr<IProgress> progressRead;
         CHECK_ERROR_BREAK(pAppliance, Read(Bstr(pszAbsFilePath).raw(),
@@ -330,41 +393,4 @@
         Bstr path; /* fetch the path, there is stuff like username/password removed if any */
         CHECK_ERROR_BREAK(pAppliance, COMGETTER(Path)(path.asOutParam()));
-        // call interpret(); this can yield both warnings and errors, so we need
-        // to tinker with the error info a bit
-        RTStrmPrintf(g_pStdErr, "Interpreting %ls...\n", path.raw());
-        rc = pAppliance->Interpret();
-        com::ErrorInfo info0(pAppliance, COM_IIDOF(IAppliance));
-
-        com::SafeArray<BSTR> aWarnings;
-        if (SUCCEEDED(pAppliance->GetWarnings(ComSafeArrayAsOutParam(aWarnings))))
-        {
-            size_t cWarnings = aWarnings.size();
-            for (unsigned i = 0; i < cWarnings; ++i)
-            {
-                Bstr bstrWarning(aWarnings[i]);
-                RTMsgWarning("%ls.", bstrWarning.raw());
-            }
-        }
-
-        if (FAILED(rc))     // during interpret, after printing warnings
-        {
-            com::GluePrintErrorInfo(info0);
-            com::GluePrintErrorContext("Interpret", __FILE__, __LINE__);
-            break;
-        }
-
-        RTStrmPrintf(g_pStdErr, "OK.\n");
-
-        // fetch all disks
-        com::SafeArray<BSTR> retDisks;
-        CHECK_ERROR_BREAK(pAppliance,
-                          COMGETTER(Disks)(ComSafeArrayAsOutParam(retDisks)));
-        if (retDisks.size() > 0)
-        {
-            RTPrintf("Disks:\n");
-            for (unsigned i = 0; i < retDisks.size(); i++)
-                RTPrintf("  %ls\n", retDisks[i]);
-            RTPrintf("\n");
-        }
 
         // fetch virtual system descriptions
@@ -375,16 +401,57 @@
         size_t cVirtualSystemDescriptions = aVirtualSystemDescriptions.size();
 
-        // match command line arguments with virtual system descriptions;
-        // this is only to sort out invalid indices at this time
-        ArgsMapsMap::const_iterator it;
-        for (it = mapArgsMapsPerVsys.begin();
-             it != mapArgsMapsPerVsys.end();
-             ++it)
+        if (actionType == LOCAL)
         {
-            uint32_t ulVsys = it->first;
-            if (ulVsys >= cVirtualSystemDescriptions)
-                return errorSyntax(USAGE_IMPORTAPPLIANCE,
-                                   "Invalid index %RI32 with -vsys option; the OVF contains only %zu virtual system(s).",
-                                   ulVsys, cVirtualSystemDescriptions);
+            // call interpret(); this can yield both warnings and errors, so we need
+            // to tinker with the error info a bit
+            RTStrmPrintf(g_pStdErr, "Interpreting %ls...\n", path.raw());
+            rc = pAppliance->Interpret();
+            com::ErrorInfo info0(pAppliance, COM_IIDOF(IAppliance));
+
+            com::SafeArray<BSTR> aWarnings;
+            if (SUCCEEDED(pAppliance->GetWarnings(ComSafeArrayAsOutParam(aWarnings))))
+            {
+                size_t cWarnings = aWarnings.size();
+                for (unsigned i = 0; i < cWarnings; ++i)
+                {
+                    Bstr bstrWarning(aWarnings[i]);
+                    RTMsgWarning("%ls.", bstrWarning.raw());
+                }
+            }
+
+            if (FAILED(rc))     // during interpret, after printing warnings
+            {
+                com::GluePrintErrorInfo(info0);
+                com::GluePrintErrorContext("Interpret", __FILE__, __LINE__);
+                break;
+            }
+
+            RTStrmPrintf(g_pStdErr, "OK.\n");
+
+            // fetch all disks
+            com::SafeArray<BSTR> retDisks;
+            CHECK_ERROR_BREAK(pAppliance,
+                              COMGETTER(Disks)(ComSafeArrayAsOutParam(retDisks)));
+            if (retDisks.size() > 0)
+            {
+                RTPrintf("Disks:\n");
+                for (unsigned i = 0; i < retDisks.size(); i++)
+                    RTPrintf("  %ls\n", retDisks[i]);
+                RTPrintf("\n");
+            }
+
+            // match command line arguments with virtual system descriptions;
+            // this is only to sort out invalid indices at this time
+            ArgsMapsMap::const_iterator it;
+            for (it = mapArgsMapsPerVsys.begin();
+                 it != mapArgsMapsPerVsys.end();
+                 ++it)
+            {
+                uint32_t ulVsys = it->first;
+                if (ulVsys >= cVirtualSystemDescriptions)
+                    return errorSyntax(USAGE_IMPORTAPPLIANCE,
+                                       "Invalid index %RI32 with -vsys option; the OVF contains only %zu virtual system(s).",
+                                       ulVsys, cVirtualSystemDescriptions);
+            }
         }
 
@@ -920,4 +987,6 @@
                         case VirtualSystemDescriptionType_CloudKeepObject:
                         case VirtualSystemDescriptionType_CloudLaunchInstance:
+                        case VirtualSystemDescriptionType_CloudInstanceId:
+                        case VirtualSystemDescriptionType_CloudImageId:
                         case VirtualSystemDescriptionType_Miscellaneous:
                             /** @todo  VirtualSystemDescriptionType_Miscellaneous? */
@@ -1041,9 +1110,4 @@
 };
 
-enum
-{
-    NOT_SET, LOCAL, CLOUD
-} exportType;
-
 RTEXITCODE handleExportAppliance(HandlerArg *a)
 {
@@ -1054,5 +1118,5 @@
     bool fManifest = false; // the default
     bool fCloud = false; // the default
-    exportType = NOT_SET;
+    actionType = NOT_SET;
     bool fExportISOImages = false; // the default
     com::SafeArray<ExportOptions_T> options;
@@ -1109,8 +1173,8 @@
 
                 case 's':   // --vsys
-                    if (fCloud == false && exportType == NOT_SET)
-                        exportType = LOCAL;
-
-                    if (exportType != LOCAL)
+                    if (fCloud == false && actionType == NOT_SET)
+                        actionType = LOCAL;
+
+                    if (actionType != LOCAL)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE,
                                            "Option \"%s\" can't be used together with \"--cloud\" argument.",
@@ -1121,5 +1185,5 @@
 
                 case 'V':   // --vmname
-                    if (exportType == NOT_SET || ulCurVsys == (uint32_t)-1)
+                    if (actionType == NOT_SET || ulCurVsys == (uint32_t)-1)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys or --cloud argument.",
                                            GetState.pDef->pszLong);
@@ -1128,5 +1192,5 @@
 
                 case 'p':   // --product
-                    if (exportType != LOCAL)
+                    if (actionType != LOCAL)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                     mapArgsMapsPerVsys[ulCurVsys]["product"] = ValueUnion.psz;
@@ -1134,5 +1198,5 @@
 
                 case 'P':   // --producturl
-                    if (exportType != LOCAL)
+                    if (actionType != LOCAL)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                     mapArgsMapsPerVsys[ulCurVsys]["producturl"] = ValueUnion.psz;
@@ -1140,5 +1204,5 @@
 
                 case 'n':   // --vendor
-                    if (exportType != LOCAL)
+                    if (actionType != LOCAL)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                     mapArgsMapsPerVsys[ulCurVsys]["vendor"] = ValueUnion.psz;
@@ -1146,5 +1210,5 @@
 
                 case 'N':   // --vendorurl
-                    if (exportType != LOCAL)
+                    if (actionType != LOCAL)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                     mapArgsMapsPerVsys[ulCurVsys]["vendorurl"] = ValueUnion.psz;
@@ -1152,5 +1216,5 @@
 
                 case 'v':   // --version
-                    if (exportType != LOCAL)
+                    if (actionType != LOCAL)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                     mapArgsMapsPerVsys[ulCurVsys]["version"] = ValueUnion.psz;
@@ -1158,5 +1222,5 @@
 
                 case 'd':   // --description
-                    if (exportType != LOCAL)
+                    if (actionType != LOCAL)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                     mapArgsMapsPerVsys[ulCurVsys]["description"] = ValueUnion.psz;
@@ -1164,5 +1228,5 @@
 
                 case 'e':   // --eula
-                    if (exportType != LOCAL)
+                    if (actionType != LOCAL)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                     mapArgsMapsPerVsys[ulCurVsys]["eula"] = ValueUnion.psz;
@@ -1170,5 +1234,5 @@
 
                 case 'E':   // --eulafile
-                    if (exportType != LOCAL)
+                    if (actionType != LOCAL)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
                     mapArgsMapsPerVsys[ulCurVsys]["eulafile"] = ValueUnion.psz;
@@ -1182,11 +1246,11 @@
                     /*--cloud and --vsys are orthogonal, only one must be presented*/
                 case 'C':   // --cloud
-                    if (fCloud == false && exportType == NOT_SET)
+                    if (fCloud == false && actionType == NOT_SET)
                     {
                         fCloud = true;
-                        exportType = CLOUD;
+                        actionType = CLOUD;
                     }
 
-                    if (exportType != CLOUD)
+                    if (actionType != CLOUD)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE,
                                            "Option \"%s\" can't be used together with \"--vsys\" argument.",
@@ -1198,5 +1262,5 @@
                     /* Cloud export settings */
                 case 'S':   // --cloudshape
-                    if (exportType != CLOUD)
+                    if (actionType != CLOUD)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.",
                                            GetState.pDef->pszLong);
@@ -1205,5 +1269,5 @@
 
                 case 'D':   // --clouddomain
-                    if (exportType != CLOUD)
+                    if (actionType != CLOUD)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.",
                                            GetState.pDef->pszLong);
@@ -1212,5 +1276,5 @@
 
                 case 'R':   // --clouddisksize
-                    if (exportType != CLOUD)
+                    if (actionType != CLOUD)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.",
                                            GetState.pDef->pszLong);
@@ -1219,5 +1283,5 @@
 
                 case 'B':   // --cloudbucket
-                    if (exportType != CLOUD)
+                    if (actionType != CLOUD)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.",
                                            GetState.pDef->pszLong);
@@ -1226,5 +1290,5 @@
 
                 case 'Q':   // --cloudocivcn
-                    if (exportType != CLOUD)
+                    if (actionType != CLOUD)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.",
                                            GetState.pDef->pszLong);
@@ -1233,5 +1297,5 @@
 
                 case 'A':   // --cloudpublicip
-                    if (exportType != CLOUD)
+                    if (actionType != CLOUD)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.",
                                            GetState.pDef->pszLong);
@@ -1240,5 +1304,5 @@
 
                 case 'F':   // --cloudprofile
-                    if (exportType != CLOUD)
+                    if (actionType != CLOUD)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.",
                                            GetState.pDef->pszLong);
@@ -1247,5 +1311,5 @@
 
                 case 'T':   // --cloudocisubnet
-                    if (exportType != CLOUD)
+                    if (actionType != CLOUD)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.",
                                            GetState.pDef->pszLong);
@@ -1254,5 +1318,5 @@
 
                 case 'K':   // --cloudkeepobject
-                    if (exportType != CLOUD)
+                    if (actionType != CLOUD)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.",
                                            GetState.pDef->pszLong);
@@ -1261,5 +1325,5 @@
 
                 case 'L':   // --cloudlaunchinstance
-                    if (exportType != CLOUD)
+                    if (actionType != CLOUD)
                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.",
                                            GetState.pDef->pszLong);
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 78427)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 78428)
@@ -3627,5 +3627,5 @@
   <enum
     name="VirtualSystemDescriptionType"
-    uuid="425d0e49-eb9c-43e8-bb0d-be7f78fd3b47"
+    uuid="48875667-19f6-4329-a208-735adf9a47ee"
     >
     <desc>Used with <link to="IVirtualSystemDescription" /> to describe the type of
@@ -3682,4 +3682,6 @@
     <const name="CloudKeepObject" value="35" />
     <const name="CloudLaunchInstance" value="36" />
+    <const name="CloudInstanceId" value="37" />
+    <const name="CloudImageId" value="38" />
   </enum>
 
@@ -25740,5 +25742,5 @@
     name="ICloudClient" extends="$unknown"
     uuid="7acc426a-5f8f-11e9-9032-1b0da54759a8"
-    wsmap="managed" reservedMethods="13" reservedAttributes="8"
+    wsmap="managed" reservedMethods="11" reservedAttributes="8"
     >
 
@@ -25819,4 +25821,34 @@
           Progress object to track the operation completion.
         </desc>
+      </param>
+    </method>
+
+    <method name="getInstanceInfo" const="yes">
+      <desc>
+        Returns the information about an instance in the Cloud.
+      </desc>
+      <param name="instanceId" type="wstring" dir="in">
+        <desc>What to search for. This is the instance ID.</desc>
+      </param>
+      <param name="description" type="IVirtualSystemDescription" dir="in">
+        <desc>VirtualSystemDescription object which is describing a machine</desc>
+      </param>
+    </method>
+
+    <method name="importInstance">
+      <desc>
+        Import an existing instance with passed id to the local host.
+      </desc>
+      <param name="description" type="IVirtualSystemDescription" dir="in">
+        <desc>VirtualSystemDescription object which is describing a machine and all required parameters.</desc>
+      </param>
+      <param name="uid" type="wstring" dir="in">
+        <desc>the UUID of instance imported from the Cloud.</desc>
+      </param>
+      <param name="virtualBox" type="IVirtualBox" dir="in">
+        <desc>Reference to the server-side API root object.</desc>
+      </param>
+      <param name="progress" type="IProgress" dir="in">
+        <desc>Progress object to track the operation completion.</desc>
       </param>
     </method>
Index: /trunk/src/VBox/Main/include/ApplianceImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/ApplianceImpl.h	(revision 78427)
+++ /trunk/src/VBox/Main/include/ApplianceImpl.h	(revision 78428)
@@ -102,5 +102,4 @@
     HRESULT createVFSExplorer(const com::Utf8Str &aURI,
                               ComPtr<IVFSExplorer> &aExplorer);
-    HRESULT createVirtualSystemDescriptions(ULONG aRequested, ULONG *aCreated);
     HRESULT write(const com::Utf8Str &aFormat,
                   const std::vector<ExportOptions_T> &aOptions,
@@ -112,5 +111,5 @@
     HRESULT addPasswords(const std::vector<com::Utf8Str> &aIdentifiers,
                          const std::vector<com::Utf8Str> &aPasswords);
-
+    HRESULT createVirtualSystemDescriptions(ULONG aRequested, ULONG *aCreated);
     /** weak VirtualBox parent */
     VirtualBox* const mVirtualBox;
@@ -124,5 +123,5 @@
     Data *m;
 
-    enum SetUpProgressMode { ImportFile, ImportS3, WriteFile, WriteS3, ExportCloud };
+    enum SetUpProgressMode { ImportFile, ImportS3, WriteFile, WriteS3, ExportCloud, ImportCloud };
 
     /** @name General stuff
@@ -143,5 +142,5 @@
     static void i_importOrExportThreadTask(TaskOVF *pTask);
     static void i_exportOPCThreadTask(TaskOPC *pTask);
-    static void i_exportCloudThreadTask(TaskCloud *pTask);
+    static void i_importOrExportCloudThreadTask(TaskCloud *pTask);
 
     HRESULT i_initBackendNames();
@@ -171,4 +170,6 @@
     HRESULT i_readSignatureFile(TaskOVF *pTask, RTVFSIOSTREAM hIosCert, const char *pszSubFileNm);
     HRESULT i_readTailProcessing(TaskOVF *pTask);
+    HRESULT i_gettingCloudData(TaskCloud *pTask);
+
     /** @}  */
 
@@ -215,4 +216,5 @@
     void    i_importDecompressFile(ImportStack &stack, Utf8Str const &rstrSrcPath, Utf8Str const &rstrDstPath,
                                    const char *pszManifestEntry);
+    HRESULT i_importCloudImpl(TaskCloud *pTask);
     /** @} */
 
@@ -228,5 +230,5 @@
     HRESULT i_writeFSOVA(TaskOVF *pTask, AutoWriteLockBase& writeLock);
     HRESULT i_writeFSOPC(TaskOPC *pTask);
-    HRESULT i_writeFSCloud(TaskCloud *pTask);
+    HRESULT i_exportCloudImpl(TaskCloud *pTask);
     HRESULT i_writeFSImpl(TaskOVF *pTask, AutoWriteLockBase &writeLock, RTVFSFSSTREAM hVfsFssDst);
     HRESULT i_writeBufferToFile(RTVFSFSSTREAM hVfsFssDst, const char *pszFilename, const void *pvContent, size_t cbContent);
Index: /trunk/src/VBox/Main/include/ApplianceImplPrivate.h
===================================================================
--- /trunk/src/VBox/Main/include/ApplianceImplPrivate.h	(revision 78427)
+++ /trunk/src/VBox/Main/include/ApplianceImplPrivate.h	(revision 78428)
@@ -339,5 +339,7 @@
     enum TaskType
     {
-        Export
+        Export,
+        Import,
+        ReadData
     };
 
@@ -353,5 +355,11 @@
         rc(S_OK)
     {
-        m_strTaskName = "CloudExpt";
+        switch (taskType)
+        {
+            case TaskCloud::Export:    m_strTaskName = "CloudExpt"; break;
+            case TaskCloud::Import:    m_strTaskName = "CloudImpt"; break;
+            case TaskCloud::ReadData:  m_strTaskName = "CloudRead"; break;
+            default:                   m_strTaskName = "CloudTask"; break;
+        }
     }
 
@@ -371,5 +379,5 @@
     void handler()
     {
-        Appliance::i_exportCloudThreadTask(this);
+        Appliance::i_importOrExportCloudThreadTask(this);
     }
 };
Index: /trunk/src/VBox/Main/src-server/ApplianceImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/ApplianceImpl.cpp	(revision 78427)
+++ /trunk/src/VBox/Main/src-server/ApplianceImpl.cpp	(revision 78428)
@@ -1104,7 +1104,5 @@
         }
         case ExportCloud:
-            cOperations = 1 + 9;//7
-            ulTotalOperationsWeight = 100*cOperations;
-            m->ulWeightForXmlOperation = 100;
+        case ImportCloud:
             break;
     }
@@ -1340,5 +1338,5 @@
  */
 /* static */
-void Appliance::i_exportCloudThreadTask(TaskCloud *pTask)
+void Appliance::i_importOrExportCloudThreadTask(TaskCloud *pTask)
 {
     LogFlowFuncEnter();
@@ -1351,7 +1349,12 @@
     {
         case TaskCloud::Export:
-            pTask->rc = pAppliance->i_writeFSCloud(pTask);
+            pTask->rc = pAppliance->i_exportCloudImpl(pTask);
             break;
-
+        case TaskCloud::Import:
+            pTask->rc = pAppliance->i_importCloudImpl(pTask);
+            break;
+        case TaskCloud::ReadData:
+            pTask->rc = pAppliance->i_gettingCloudData(pTask);
+            break;
         default:
             AssertFailed();
@@ -1411,25 +1414,25 @@
 
     /* Not necessary on a file based URI */
-    if (locInfo.storageType != VFSType_File)
-    {
-        size_t uppos = strUri.find("@"); /* username:password combo */
-        if (uppos != Utf8Str::npos)
-        {
-            locInfo.strUsername = strUri.substr(0, uppos);
-            strUri = strUri.substr(uppos + 1);
-            size_t upos = locInfo.strUsername.find(":");
-            if (upos != Utf8Str::npos)
-            {
-                locInfo.strPassword = locInfo.strUsername.substr(upos + 1);
-                locInfo.strUsername = locInfo.strUsername.substr(0, upos);
-            }
-        }
-        size_t hpos = strUri.find("/"); /* hostname part */
-        if (hpos != Utf8Str::npos)
-        {
-            locInfo.strHostname = strUri.substr(0, hpos);
-            strUri = strUri.substr(hpos);
-        }
-    }
+//  if (locInfo.storageType != VFSType_File)
+//  {
+//      size_t uppos = strUri.find("@"); /* username:password combo */
+//      if (uppos != Utf8Str::npos)
+//      {
+//          locInfo.strUsername = strUri.substr(0, uppos);
+//          strUri = strUri.substr(uppos + 1);
+//          size_t upos = locInfo.strUsername.find(":");
+//          if (upos != Utf8Str::npos)
+//          {
+//              locInfo.strPassword = locInfo.strUsername.substr(upos + 1);
+//              locInfo.strUsername = locInfo.strUsername.substr(0, upos);
+//          }
+//      }
+//      size_t hpos = strUri.find("/"); /* hostname part */
+//      if (hpos != Utf8Str::npos)
+//      {
+//          locInfo.strHostname = strUri.substr(0, hpos);
+//          strUri = strUri.substr(hpos);
+//      }
+//  }
 
     locInfo.strPath = strUri;
Index: /trunk/src/VBox/Main/src-server/ApplianceImplExport.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/ApplianceImplExport.cpp	(revision 78427)
+++ /trunk/src/VBox/Main/src-server/ApplianceImplExport.cpp	(revision 78428)
@@ -653,5 +653,5 @@
     i_parseURI(aPath, m->locInfo);
 
-    if (m->locInfo.storageType == VFSType_Cloud)//(isCloudDestination(aPath))
+    if (m->locInfo.storageType == VFSType_Cloud)
     {
         rc = S_OK;
@@ -2242,5 +2242,5 @@
  * instance with this image in the OCI Compute service.
  */
-HRESULT Appliance::i_writeFSCloud(TaskCloud *pTask)
+HRESULT Appliance::i_exportCloudImpl(TaskCloud *pTask)
 {
     LogFlowFuncEnter();
@@ -2250,5 +2250,5 @@
     hrc = mVirtualBox->COMGETTER(CloudProviderManager)(cpm.asOutParam());
     if (FAILED(hrc))
-        return setErrorVrc(VERR_COM_OBJECT_NOT_FOUND, tr("Cloud: Cloud provider manager object wasn't found"));
+        return setErrorVrc(VERR_COM_OBJECT_NOT_FOUND, tr("%: Cloud provider manager object wasn't found", __FUNCTION__));
 
     Utf8Str strProviderName = pTask->locInfo.strProvider;
@@ -2258,5 +2258,5 @@
 
     if (FAILED(hrc))
-        return setErrorVrc(VERR_COM_OBJECT_NOT_FOUND, tr("Cloud: Cloud provider object wasn't found"));
+        return setErrorVrc(VERR_COM_OBJECT_NOT_FOUND, tr("%s: Cloud provider object wasn't found", __FUNCTION__));
 
     ComPtr<IVirtualSystemDescription> vsd = m->virtualSystemDescriptions.front();
@@ -2279,16 +2279,14 @@
     Utf8Str profileName(aVBoxValues[0]);
     if (profileName.isEmpty())
-        return setErrorVrc(VBOX_E_OBJECT_NOT_FOUND, tr("Cloud: Cloud user profile name wasn't found"));
+        return setErrorVrc(VBOX_E_OBJECT_NOT_FOUND, tr("%s: Cloud user profile name wasn't found", __FUNCTION__));
 
     hrc = cloudProvider->GetProfileByName(aVBoxValues[0], cloudProfile.asOutParam());
     if (FAILED(hrc))
-        return setErrorVrc(VERR_COM_OBJECT_NOT_FOUND, tr("Cloud: Cloud profile object wasn't found"));
+        return setErrorVrc(VERR_COM_OBJECT_NOT_FOUND, tr("%s: Cloud profile object wasn't found", __FUNCTION__));
 
     ComObjPtr<ICloudClient> cloudClient;
     hrc = cloudProfile->CreateCloudClient(cloudClient.asOutParam());
     if (FAILED(hrc))
-        return setErrorVrc(VERR_COM_OBJECT_NOT_FOUND, tr("Cloud: Cloud client object wasn't found"));
-
-    LogRel(("Appliance::i_writeFSCloud(): calling CloudClient::ExportLaunchVM\n"));
+        return setErrorVrc(VERR_COM_OBJECT_NOT_FOUND, tr("%s: Cloud client object wasn't found", __FUNCTION__));
 
     if (m->virtualSystemDescriptions.size() == 1)
Index: /trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp	(revision 78427)
+++ /trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp	(revision 78428)
@@ -88,9 +88,4 @@
     }
 
-    // see if we can handle this file; for now we insist it has an ovf/ova extension
-    if (   !aFile.endsWith(".ovf", Utf8Str::CaseInsensitive)
-        && !aFile.endsWith(".ova", Utf8Str::CaseInsensitive))
-        return setError(VBOX_E_FILE_ERROR, tr("Appliance file must have .ovf or .ova extension"));
-
     ComObjPtr<Progress> progress;
     try
@@ -98,4 +93,11 @@
         /* Parse all necessary info out of the URI */
         i_parseURI(aFile, m->locInfo);
+
+        // see if we can handle this file; for now we insist it has an ovf/ova extension
+        if (   m->locInfo.storageType == VFSType_File 
+            && !aFile.endsWith(".ovf", Utf8Str::CaseInsensitive)
+            && !aFile.endsWith(".ova", Utf8Str::CaseInsensitive))
+            return setError(VBOX_E_FILE_ERROR, tr("Appliance file must have .ovf or .ova extension"));
+
         i_readImpl(m->locInfo, progress);
     }
@@ -790,5 +792,6 @@
         return E_ACCESSDENIED;
 
-    if (!m->pReader)
+    //check for the local import only. For import from the Cloud m->pReader is always NULL.
+    if (m->locInfo.storageType == VFSType_File && !m->pReader)
         return setError(E_FAIL,
                         tr("Cannot import machines without reading it first (call read() before i_importMachines())"));
@@ -1121,4 +1124,10 @@
                              bstrDesc.raw(),
                              TRUE /* aCancelable */);
+
+    else if (aLocInfo.storageType == VFSType_Cloud)
+        /* 1 operation only for now */
+        rc = aProgress->init(mVirtualBox, static_cast<IAppliance*>(this),
+                             "Getting cloud instance information...",
+                             TRUE /* aCancelable */);
     else
         /* 4/5 is downloading, 1/5 is reading */
@@ -1134,17 +1143,342 @@
 
     /* Initialize our worker task */
-    TaskOVF *task = NULL;
+    TaskOVF *ovfTask = NULL;
+    TaskCloud *cloudTask = NULL;
     try
     {
-        task = new TaskOVF(this, TaskOVF::Read, aLocInfo, aProgress);
-    }
+        if (aLocInfo.storageType == VFSType_File)
+        {
+            ovfTask = new TaskOVF(this, TaskOVF::Read, aLocInfo, aProgress);
+            rc = ovfTask->createThread();
+            if (FAILED(rc)) throw rc;
+        }
+        else if (aLocInfo.storageType == VFSType_Cloud)
+        {
+            cloudTask = new TaskCloud(this, TaskCloud::ReadData, aLocInfo, aProgress);
+            rc = cloudTask->createThread();
+            if (FAILED(rc)) throw rc;
+        }
+    }
+    catch (HRESULT aRc)
+    {
+        rc = aRc;
+    } 
     catch (...)
     {
-        throw setError(VBOX_E_OBJECT_NOT_FOUND,
-                       tr("Could not create TaskOVF object for reading the OVF from disk"));
-    }
-
-    rc = task->createThread();
-    if (FAILED(rc)) throw rc;
+        rc = setError(VBOX_E_OBJECT_NOT_FOUND,
+                      tr("Could not create a task object for reading the Appliance data"));
+    }
+
+    if (FAILED(rc))
+    {
+        if (ovfTask)
+            delete ovfTask;
+        if (cloudTask)
+            delete cloudTask;
+        throw rc;
+    }
+}
+
+HRESULT Appliance::i_gettingCloudData(TaskCloud *pTask)
+{
+    LogFlowFuncEnter();
+    LogFlowFunc(("Appliance %p\n", this));
+
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    AutoWriteLock appLock(this COMMA_LOCKVAL_SRC_POS);
+
+    HRESULT hrc = S_OK;
+
+    try
+    {
+        Utf8Str strBasename(pTask->locInfo.strPath);
+        RTCList<RTCString, RTCString *> parts = strBasename.split("/");
+        if (parts.size() != 2)//profile + instance id
+        {
+            return setErrorVrc(VERR_MISMATCH, tr("%s: The profile name or instance id are absent or"
+                                                 "contain unsupported characters.", __FUNCTION__));
+        }
+
+        //Get information about the passed cloud instance    
+        ComPtr<ICloudProviderManager> cpm;
+        hrc = mVirtualBox->COMGETTER(CloudProviderManager)(cpm.asOutParam());
+        if (FAILED(hrc))
+            return setErrorVrc(VERR_COM_OBJECT_NOT_FOUND, tr("%s: Cloud provider manager object wasn't found", __FUNCTION__));
+
+        Utf8Str strProviderName = pTask->locInfo.strProvider;
+        ComPtr<ICloudProvider> cloudProvider;
+        ComPtr<ICloudProfile> cloudProfile;
+        hrc = cpm->GetProviderByShortName(Bstr(strProviderName.c_str()).raw(), cloudProvider.asOutParam());
+
+        if (FAILED(hrc))
+            return setErrorVrc(VERR_COM_OBJECT_NOT_FOUND, tr("%s: Cloud provider object wasn't found", __FUNCTION__));
+
+        Utf8Str profileName(parts.at(0));//profile
+        if (profileName.isEmpty())
+            return setErrorVrc(VBOX_E_OBJECT_NOT_FOUND, tr("%s: Cloud user profile name wasn't found", __FUNCTION__));
+
+        hrc = cloudProvider->GetProfileByName(Bstr(parts.at(0)).raw(), cloudProfile.asOutParam());
+        if (FAILED(hrc))
+            return setErrorVrc(VERR_COM_OBJECT_NOT_FOUND, tr("%s: Cloud profile object wasn't found", __FUNCTION__));
+
+        ComObjPtr<ICloudClient> cloudClient;
+        hrc = cloudProfile->CreateCloudClient(cloudClient.asOutParam());
+        if (FAILED(hrc))
+            return setErrorVrc(VERR_COM_OBJECT_NOT_FOUND, tr("%s: Cloud client object wasn't found", __FUNCTION__));
+
+        m->virtualSystemDescriptions.clear();//clear all for assurance before creating new
+        std::vector<ComPtr<IVirtualSystemDescription> > vsdArray;
+        uint32_t requestedVSDnums = 1;
+        uint32_t newVSDnums = 0;
+        hrc = createVirtualSystemDescriptions(requestedVSDnums, &newVSDnums);
+        if (FAILED(hrc)) throw hrc;
+        if (requestedVSDnums != newVSDnums)
+            throw setErrorVrc(VERR_MISMATCH, tr("%s: Requested and created numbers of VSD are differ.", __FUNCTION__));
+
+        hrc = getVirtualSystemDescriptions(vsdArray);
+        if (FAILED(hrc)) throw hrc;
+        ComPtr<IVirtualSystemDescription> instanceDescription = vsdArray[0];
+
+        LogRel(("%s: calling CloudClient::GetInstanceInfo()\n", __FUNCTION__));
+        hrc = cloudClient->GetInstanceInfo(Bstr(parts.at(1)).raw(), instanceDescription);//instance id
+        if (FAILED(hrc)) throw hrc;
+
+        // set cloud profile
+        instanceDescription->AddDescription(VirtualSystemDescriptionType_CloudProfileName,
+                             Bstr(profileName).raw(),
+                             Bstr(profileName).raw());
+        // set name
+        Utf8Str strSetting = "cloud VM (";
+        strSetting.append(parts.at(1)).append(")");
+        // set description
+        strSetting = "VM with id ";
+        strSetting.append(parts.at(1)).append(" imported from the cloud provider ").append(strProviderName);
+
+        // description
+        instanceDescription->AddDescription(VirtualSystemDescriptionType_Description,
+                             Bstr(strSetting).raw(),
+                             Bstr(strSetting).raw());
+    }
+    catch (HRESULT arc)
+    {
+        LogFlowFunc(("arc=%Rhrc\n", arc));
+        hrc = arc;
+    }
+
+    LogFlowFunc(("rc=%Rhrc\n", hrc));
+    LogFlowFuncLeave();
+
+    return hrc;
+}
+
+/**
+ * Actual worker code for import from the Cloud
+ *
+ * @param pTask
+ * @return
+ */
+HRESULT Appliance::i_importCloudImpl(TaskCloud *pTask)
+{
+    LogFlowFuncEnter();
+    LogFlowFunc(("Appliance %p\n", this));
+
+    /* Change the appliance state so we can safely leave the lock while doing
+     * time-consuming operations; also the below method calls do all kinds of
+     * locking which conflicts with the appliance object lock. */
+    AutoWriteLock writeLock(this COMMA_LOCKVAL_SRC_POS);
+    /* Check if the appliance is currently busy. */
+    if (!i_isApplianceIdle())
+        return E_ACCESSDENIED;
+    /* Set the internal state to importing. */
+    m->state = Data::ApplianceImporting;
+
+    HRESULT hrc = S_OK;
+
+    /* Clear the list of imported machines, if any */
+    m->llGuidsMachinesCreated.clear();
+
+    /*
+     * Actual code for the cloud import
+     *
+    */
+
+    ComPtr<ICloudProviderManager> cpm;
+    hrc = mVirtualBox->COMGETTER(CloudProviderManager)(cpm.asOutParam());
+    if (FAILED(hrc))
+        return setErrorVrc(VERR_COM_OBJECT_NOT_FOUND, tr("%s: Cloud provider manager object wasn't found", __FUNCTION__));
+
+    Utf8Str strProviderName = pTask->locInfo.strProvider;
+    ComPtr<ICloudProvider> cloudProvider;
+    ComPtr<ICloudProfile> cloudProfile;
+    hrc = cpm->GetProviderByShortName(Bstr(strProviderName.c_str()).raw(), cloudProvider.asOutParam());
+
+    if (FAILED(hrc))
+        return setErrorVrc(VERR_COM_OBJECT_NOT_FOUND, tr("%s: Cloud provider object wasn't found", __FUNCTION__));
+
+    ComPtr<IVirtualSystemDescription> vsd = m->virtualSystemDescriptions.front();
+
+    com::SafeArray<VirtualSystemDescriptionType_T> retTypes;
+    com::SafeArray<BSTR> aRefs;
+    com::SafeArray<BSTR> aOvfValues;
+    com::SafeArray<BSTR> aVBoxValues;
+    com::SafeArray<BSTR> aExtraConfigValues;
+
+    hrc = vsd->GetDescriptionByType(VirtualSystemDescriptionType_CloudProfileName,
+                             ComSafeArrayAsOutParam(retTypes),
+                             ComSafeArrayAsOutParam(aRefs),
+                             ComSafeArrayAsOutParam(aOvfValues),
+                             ComSafeArrayAsOutParam(aVBoxValues),
+                             ComSafeArrayAsOutParam(aExtraConfigValues));
+    if (FAILED(hrc))
+        return hrc;
+
+    Utf8Str profileName(aVBoxValues[0]);
+    if (profileName.isEmpty())
+        return setErrorVrc(VBOX_E_OBJECT_NOT_FOUND, tr("%s: Cloud user profile name wasn't found", __FUNCTION__));
+
+    hrc = cloudProvider->GetProfileByName(aVBoxValues[0], cloudProfile.asOutParam());
+    if (FAILED(hrc))
+        return setErrorVrc(VERR_COM_OBJECT_NOT_FOUND, tr("%s: Cloud profile object wasn't found", __FUNCTION__));
+
+    ComObjPtr<ICloudClient> cloudClient;
+    hrc = cloudProfile->CreateCloudClient(cloudClient.asOutParam());
+    if (FAILED(hrc))
+        return setErrorVrc(VERR_COM_OBJECT_NOT_FOUND, tr("%s: Cloud client object wasn't found", __FUNCTION__));
+
+    if (m->virtualSystemDescriptions.size() == 1)
+    {
+        do
+        {
+            ComPtr<IVirtualBox> VBox(mVirtualBox);
+            retTypes.setNull();
+            aRefs.setNull();
+            aOvfValues.setNull();
+            aVBoxValues.setNull();
+            aExtraConfigValues.setNull();
+            hrc = vsd->GetDescriptionByType(VirtualSystemDescriptionType_CloudInstanceId,
+                                            ComSafeArrayAsOutParam(retTypes),
+                                            ComSafeArrayAsOutParam(aRefs),
+                                            ComSafeArrayAsOutParam(aOvfValues),
+                                            ComSafeArrayAsOutParam(aVBoxValues),
+                                            ComSafeArrayAsOutParam(aExtraConfigValues));
+            if (FAILED(hrc))
+                break;
+
+            ComPtr<IProgress> pProgress;
+            pTask->pProgress.queryInterfaceTo(pProgress.asOutParam());
+
+            LogRel(("%s: calling CloudClient::ImportInstance\n", __FUNCTION__));
+            hrc = cloudClient->ImportInstance(m->virtualSystemDescriptions.front(),
+                                              aVBoxValues[0],
+                                              VBox,
+                                              pProgress);
+            Bstr instId(aVBoxValues[0]);
+            Utf8Str strInsId(instId);
+            if (FAILED(hrc))
+            {
+                hrc = setError(hrc, "%s: Import cloud instance \'%s\' failed\n", __FUNCTION__, strInsId.c_str());
+                break;
+            }
+
+            Utf8Str vsdData;
+
+            retTypes.setNull();
+            aRefs.setNull();
+            aOvfValues.setNull();
+            aVBoxValues.setNull();
+            aExtraConfigValues.setNull();
+            hrc = vsd->GetDescriptionByType(VirtualSystemDescriptionType_CPU,
+                                            ComSafeArrayAsOutParam(retTypes),
+                                            ComSafeArrayAsOutParam(aRefs),
+                                            ComSafeArrayAsOutParam(aOvfValues),
+                                            ComSafeArrayAsOutParam(aVBoxValues),
+                                            ComSafeArrayAsOutParam(aExtraConfigValues));
+            if (FAILED(hrc))
+                break;
+            vsdData = aVBoxValues[0];
+            if (vsdData.isEmpty())
+                LogRel(("%s: Number of CPUs wasn't found\n", __FUNCTION__));
+            else
+                LogRel(("%s: Number of CPUs is %s\n", __FUNCTION__, vsdData.c_str()));
+
+            retTypes.setNull();
+            aRefs.setNull();
+            aOvfValues.setNull();
+            aVBoxValues.setNull();
+            aExtraConfigValues.setNull();
+            hrc = vsd->GetDescriptionByType(VirtualSystemDescriptionType_Memory,
+                                            ComSafeArrayAsOutParam(retTypes),
+                                            ComSafeArrayAsOutParam(aRefs),
+                                            ComSafeArrayAsOutParam(aOvfValues),
+                                            ComSafeArrayAsOutParam(aVBoxValues),
+                                            ComSafeArrayAsOutParam(aExtraConfigValues));
+            if (FAILED(hrc))
+                break;
+            vsdData = aVBoxValues[0];
+            if (vsdData.isEmpty())
+                LogRel(("%s: Size of RAM wasn't found\n", __FUNCTION__));
+            else
+                LogRel(("%s: Size of RAM is %sMB\n", __FUNCTION__, vsdData.c_str()));
+
+            retTypes.setNull();
+            aRefs.setNull();
+            aOvfValues.setNull();
+            aVBoxValues.setNull();
+            aExtraConfigValues.setNull();
+            hrc = vsd->GetDescriptionByType(VirtualSystemDescriptionType_OS,
+                                            ComSafeArrayAsOutParam(retTypes),
+                                            ComSafeArrayAsOutParam(aRefs),
+                                            ComSafeArrayAsOutParam(aOvfValues),
+                                            ComSafeArrayAsOutParam(aVBoxValues),
+                                            ComSafeArrayAsOutParam(aExtraConfigValues));
+            if (FAILED(hrc))
+                break;
+            vsdData = aVBoxValues[0];
+            if (vsdData.isEmpty())
+                LogRel(("%s: OS type wasn't found", __FUNCTION__));
+            else
+                LogRel(("%s: OS type is %s\n", __FUNCTION__, vsdData.c_str()));
+
+            retTypes.setNull();
+            aRefs.setNull();
+            aOvfValues.setNull();
+            aVBoxValues.setNull();
+            aExtraConfigValues.setNull();
+            hrc = vsd->GetDescriptionByType(VirtualSystemDescriptionType_Name,
+                                            ComSafeArrayAsOutParam(retTypes),
+                                            ComSafeArrayAsOutParam(aRefs),
+                                            ComSafeArrayAsOutParam(aOvfValues),
+                                            ComSafeArrayAsOutParam(aVBoxValues),
+                                            ComSafeArrayAsOutParam(aExtraConfigValues));
+            if (FAILED(hrc))
+                break;
+            vsdData = aVBoxValues[0];
+            if (vsdData.isEmpty())
+                LogRel(("%s: VM name wasn't found", __FUNCTION__));
+            else
+                LogRel(("%s: VM name is %s\n", __FUNCTION__, vsdData.c_str()));
+        } while (0);
+    }
+    else
+        hrc = setErrorVrc(VERR_MISMATCH, tr("Import from Cloud isn't supported for more than one VM instance."));
+
+    if (FAILED(hrc))
+    {
+        //some roll-back actions
+    }
+    else
+    {
+        //continue and create new VM using data from VSD and downloaded image as base image
+        //The downloaded image should be converted to VDI/VMDK if it has another format
+    }
+
+    /* Reset the state so others can call methods again */
+    m->state = Data::ApplianceIdle;
+
+    LogFlowFunc(("rc=%Rhrc\n", hrc));
+    LogFlowFuncLeave();
+    return hrc;
 }
 
@@ -1981,27 +2315,73 @@
     if (locInfo.storageType == VFSType_File)
         mode = ImportFile;
+    else if (locInfo.storageType == VFSType_Cloud)
+        mode = ImportCloud;
     else
         mode = ImportS3;
 
-    rc = i_setUpProgress(progress,
-                         BstrFmt(tr("Importing appliance '%s'"), locInfo.strPath.c_str()),
-                         mode);
-    if (FAILED(rc)) throw rc;
-
     /* Initialize our worker task */
-    TaskOVF* task = NULL;
+    TaskOVF* ovfTask = NULL;
+    TaskCloud* cloudTask = NULL;
     try
     {
-        task = new TaskOVF(this, TaskOVF::Import, locInfo, progress);
-    }
-    catch(...)
-    {
-        delete task;
-        throw rc = setError(VBOX_E_OBJECT_NOT_FOUND,
-                            tr("Could not create TaskOVF object for importing OVF data into VirtualBox"));
-    }
-
-    rc = task->createThread();
-    if (FAILED(rc)) throw rc;
+        if (mode == ImportFile)
+        {
+            rc = i_setUpProgress(progress,
+                                 BstrFmt(tr("Importing appliance '%s'"), locInfo.strPath.c_str()),
+                                 mode);
+            if (FAILED(rc)) throw rc;
+
+            ovfTask = new TaskOVF(this, TaskOVF::Import, locInfo, progress);
+            rc = ovfTask->createThread();
+        }
+        else if (mode == ImportCloud)
+        {
+            /*
+             1. Create a custom imaghe from the instance
+             2. Import the custom image into the Object Storage (OCI format - TAR file with QCOW2 image and JSON file)
+             3. Download the object from the Object Storage
+             4. Open the object, extract QCOW2 image and convert one QCOW2->VDI
+             5. Create VM with user settings and attach the converted image to VM
+             6. Lauch VM.
+            */
+            progress.createObject();
+            if (locInfo.strProvider.equals("OCI"))
+            {
+                progress->init(mVirtualBox, static_cast<IAppliance*>(this),
+                             Bstr("Importing VM from Cloud...").raw(),
+                             TRUE /* aCancelable */,
+                             6, // ULONG cOperations,
+                             750, // ULONG ulTotalOperationsWeight,
+                             Bstr("Importing VM from Cloud...").raw(), // aFirstOperationDescription
+                             10); // ULONG ulFirstOperationWeight
+            }
+            else
+                return setErrorVrc(VBOX_E_NOT_SUPPORTED,
+                                   tr("Only \"OCI\" cloud provider is supported for now. \"%s\" isn't supported."),
+                                   locInfo.strProvider.c_str());
+
+            cloudTask = new TaskCloud(this, TaskCloud::Import, locInfo, progress);
+            rc = cloudTask->createThread();
+            if (FAILED(rc)) throw rc;
+        }
+    }
+    catch (HRESULT aRc)
+    {
+        rc = aRc;
+    } 
+    catch (...)
+    {
+        rc = setError(VBOX_E_OBJECT_NOT_FOUND,
+                            tr("Could not create a task object for importing appliance into VirtualBox"));
+    }
+
+    if (FAILED(rc))
+    {
+        if (ovfTask)
+            delete ovfTask;
+        if (cloudTask)
+            delete cloudTask;
+        throw rc;
+    }
 
     return rc;
