Index: /trunk/src/VBox/Main/ApplianceImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/ApplianceImpl.cpp	(revision 29874)
+++ /trunk/src/VBox/Main/ApplianceImpl.cpp	(revision 29875)
@@ -673,4 +673,13 @@
 }
 
+/**
+ * Called from Appliance::importImpl() and Appliance::writeImpl() to set up a
+ * progress object with the proper weights and maximum progress values.
+ *
+ * @param pProgress
+ * @param bstrDescription
+ * @param mode
+ * @return
+ */
 HRESULT Appliance::setUpProgress(ComObjPtr<Progress> &pProgress,
                                  const Bstr &bstrDescription,
@@ -685,4 +694,6 @@
     disksWeight();
 
+    m->ulWeightForManifestOperation = 0;
+
     ULONG cOperations;
     ULONG ulTotalOperationsWeight;
@@ -692,11 +703,11 @@
     if (m->ulTotalDisksMB)
     {
-        m->ulWeightPerOperation = (ULONG)((double)m->ulTotalDisksMB * 1 / 100);    // use 1% of the progress for the XML
-        ulTotalOperationsWeight = m->ulTotalDisksMB + m->ulWeightPerOperation;
+        m->ulWeightForXmlOperation = (ULONG)((double)m->ulTotalDisksMB * 1 / 100);    // use 1% of the progress for the XML
+        ulTotalOperationsWeight = m->ulTotalDisksMB + m->ulWeightForXmlOperation;
     }
     else
     {
         // no disks to export:
-        m->ulWeightPerOperation = 1;
+        m->ulWeightForXmlOperation = 1;
         ulTotalOperationsWeight = 1;
     }
@@ -704,5 +715,14 @@
     switch (mode)
     {
-        case Regular:
+        case ImportFileNoManifest:
+        break;
+
+        case ImportFileWithManifest:
+        case WriteFile:
+            ++cOperations;          // another one for creating the manifest
+
+            // assume that checking or creating the manifest will take 10% of the time it takes to export the disks
+            m->ulWeightForManifestOperation = m->ulTotalDisksMB / 10;
+            ulTotalOperationsWeight += m->ulWeightForManifestOperation;
         break;
 
@@ -718,5 +738,5 @@
             ulTotalOperationsWeight += ulImportWeight;
 
-            m->ulWeightPerOperation = ulImportWeight; /* save for using later */
+            m->ulWeightForXmlOperation = ulImportWeight; /* save for using later */
 
             ULONG ulInitWeight = (ULONG)((double)ulTotalOperationsWeight * 0.1  / 100);  // use 0.1% for init
@@ -731,6 +751,6 @@
             if (m->ulTotalDisksMB)
             {
-                m->ulWeightPerOperation = (ULONG)((double)m->ulTotalDisksMB * 1  / 100);    // use 1% of the progress for OVF file upload (we didn't know the size at this point)
-                ulTotalOperationsWeight = m->ulTotalDisksMB + m->ulWeightPerOperation;
+                m->ulWeightForXmlOperation = (ULONG)((double)m->ulTotalDisksMB * 1  / 100);    // use 1% of the progress for OVF file upload (we didn't know the size at this point)
+                ulTotalOperationsWeight = m->ulTotalDisksMB + m->ulWeightForXmlOperation;
             }
             else
@@ -738,5 +758,5 @@
                 // no disks to export:
                 ulTotalOperationsWeight = 1;
-                m->ulWeightPerOperation = 1;
+                m->ulWeightForXmlOperation = 1;
             }
             ULONG ulOVFCreationWeight = (ULONG)((double)ulTotalOperationsWeight * 50.0 / 100.0); /* Use 50% for the creation of the OVF & the disks */
@@ -746,6 +766,6 @@
     }
 
-    Log(("Setting up progress object: ulTotalMB = %d, cDisks = %d, => cOperations = %d, ulTotalOperationsWeight = %d, m->ulWeightPerOperation = %d\n",
-         m->ulTotalDisksMB, m->cDisks, cOperations, ulTotalOperationsWeight, m->ulWeightPerOperation));
+    Log(("Setting up progress object: ulTotalMB = %d, cDisks = %d, => cOperations = %d, ulTotalOperationsWeight = %d, m->ulWeightForXmlOperation = %d\n",
+         m->ulTotalDisksMB, m->cDisks, cOperations, ulTotalOperationsWeight, m->ulWeightForXmlOperation));
 
     rc = pProgress->init(mVirtualBox, static_cast<IAppliance*>(this),
@@ -755,5 +775,5 @@
                          ulTotalOperationsWeight, // ULONG ulTotalOperationsWeight,
                          bstrDescription, // CBSTR bstrFirstOperationDescription,
-                         m->ulWeightPerOperation); // ULONG ulFirstOperationWeight,
+                         m->ulWeightForXmlOperation); // ULONG ulFirstOperationWeight,
     return rc;
 }
Index: /trunk/src/VBox/Main/ApplianceImplExport.cpp
===================================================================
--- /trunk/src/VBox/Main/ApplianceImplExport.cpp	(revision 29874)
+++ /trunk/src/VBox/Main/ApplianceImplExport.cpp	(revision 29875)
@@ -628,8 +628,7 @@
     try
     {
-        Bstr progressDesc = BstrFmt(tr("Export appliance '%s'"),
-                                    aLocInfo.strPath.c_str());
-
-        rc = setUpProgress(aProgress, progressDesc, (aLocInfo.storageType == VFSType_File) ? Regular : WriteS3);
+        rc = setUpProgress(aProgress,
+                           BstrFmt(tr("Export appliance '%s'"), aLocInfo.strPath.c_str()),
+                           (aLocInfo.storageType == VFSType_File) ? WriteFile : WriteS3);
 
         /* Initialize our worker task */
@@ -1518,7 +1517,6 @@
 
                 // advance to the next operation
-                if (!pProgress.isNull())
-                    pProgress->SetNextOperation(BstrFmt(tr("Exporting to disk image '%s'"), strTargetFilePath.c_str()),
-                                                pDiskEntry->ulSizeMB);     // operation's weight, as set up with the IProgress originally);
+                pProgress->SetNextOperation(BstrFmt(tr("Exporting to disk image '%s'"), strTargetFilePath.c_str()),
+                                            pDiskEntry->ulSizeMB);     // operation's weight, as set up with the IProgress originally);
 
                 // now wait for the background disk operation to complete; this throws HRESULTs on error
@@ -1596,5 +1594,10 @@
         writer.write(locInfo.strPath.c_str(), false /*fSafe*/);
 
-        /* Create & write the manifest file */
+        // Create & write the manifest file
+        Utf8Str strMfFile = manifestFileName(locInfo.strPath.c_str());
+        const char *pcszManifestFileOnly = RTPathFilename(strMfFile.c_str());
+        pProgress->SetNextOperation(BstrFmt(tr("Creating manifest file '%s'"), pcszManifestFileOnly),
+                                    m->ulWeightForManifestOperation);     // operation's weight, as set up with the IProgress originally);
+
         const char** ppManifestFiles = (const char**)RTMemAlloc(sizeof(char*)*diskList.size() + 1);
         ppManifestFiles[0] = locInfo.strPath.c_str();
@@ -1605,11 +1608,10 @@
              ++it1, ++i)
             ppManifestFiles[i] = (*it1).c_str();
-        Utf8Str strMfFile = manifestFileName(locInfo.strPath.c_str());
         int vrc = RTManifestWriteFiles(strMfFile.c_str(), ppManifestFiles, diskList.size()+1);
         RTMemFree(ppManifestFiles);
         if (RT_FAILURE(vrc))
             throw setError(VBOX_E_FILE_ERROR,
-                           tr("Couldn't create manifest file '%s' (%Rrc)"),
-                           RTPathFilename(strMfFile.c_str()), vrc);
+                           tr("Could not create manifest file '%s' (%Rrc)"),
+                           pcszManifestFileOnly, vrc);
     }
     catch(xml::Error &x)
@@ -1705,7 +1707,7 @@
                            tr("Cannot find source file '%s'"), strTmpOvf.c_str());
         /* Add the OVF file */
-        filesList.push_back(pair<Utf8Str, ULONG>(strTmpOvf, m->ulWeightPerOperation)); /* Use 1% of the total for the OVF file upload */
+        filesList.push_back(pair<Utf8Str, ULONG>(strTmpOvf, m->ulWeightForXmlOperation)); /* Use 1% of the total for the OVF file upload */
         Utf8Str strMfFile = manifestFileName(strTmpOvf);
-        filesList.push_back(pair<Utf8Str, ULONG>(strMfFile , m->ulWeightPerOperation)); /* Use 1% of the total for the manifest file upload */
+        filesList.push_back(pair<Utf8Str, ULONG>(strMfFile , m->ulWeightForXmlOperation)); /* Use 1% of the total for the manifest file upload */
 
         /* Now add every disks of every virtual system */
@@ -1748,6 +1750,5 @@
             char *pszFilename = RTPathFilename(s.first.c_str());
             /* Advance to the next operation */
-            if (!pTask->pProgress.isNull())
-                pTask->pProgress->SetNextOperation(BstrFmt(tr("Uploading file '%s'"), pszFilename), s.second);
+            pTask->pProgress->SetNextOperation(BstrFmt(tr("Uploading file '%s'"), pszFilename), s.second);
             vrc = RTS3PutKey(hS3, bucket.c_str(), pszFilename, s.first.c_str());
             if (RT_FAILURE(vrc))
Index: /trunk/src/VBox/Main/ApplianceImplImport.cpp
===================================================================
--- /trunk/src/VBox/Main/ApplianceImplImport.cpp	(revision 29874)
+++ /trunk/src/VBox/Main/ApplianceImplImport.cpp	(revision 29875)
@@ -770,6 +770,5 @@
         hS3 = NIL_RTS3;
 
-        if (!pTask->pProgress.isNull())
-            pTask->pProgress->SetNextOperation(Bstr(tr("Reading")), 1);
+        pTask->pProgress->SetNextOperation(Bstr(tr("Reading")), 1);
 
         /* Prepare the temporary reading of the OVF */
@@ -932,13 +931,28 @@
  * @return
  */
-HRESULT Appliance::importImpl(const LocationInfo &aLocInfo, ComObjPtr<Progress> &aProgress)
+HRESULT Appliance::importImpl(const LocationInfo &aLocInfo,
+                              ComObjPtr<Progress> &aProgress)
 {
-    Bstr progressDesc = BstrFmt(tr("Importing appliance '%s'"),
-                                aLocInfo.strPath.c_str());
     HRESULT rc = S_OK;
 
+    SetUpProgressMode mode;
+    m->strManifestFile.setNull();
+    if (aLocInfo.storageType == VFSType_File)
+    {
+        Utf8Str strMfFile = manifestFileName(aLocInfo.strPath);
+        if (RTPathExists(strMfFile.c_str()))
+        {
+            m->strManifestFile = strMfFile;
+            mode = ImportFileWithManifest;
+        }
+        else
+            mode = ImportFileNoManifest;
+    }
+    else
+         mode = ImportS3;
+
     rc = setUpProgress(aProgress,
-                       progressDesc,
-                       (aLocInfo.storageType == VFSType_File) ? Regular : ImportS3);
+                       BstrFmt(tr("Importing appliance '%s'"), aLocInfo.strPath.c_str()),
+                       mode);
     if (FAILED(rc)) throw rc;
 
@@ -1003,11 +1017,15 @@
  */
 HRESULT Appliance::manifestVerify(const LocationInfo &locInfo,
-                                  const ovf::OVFReader &reader)
+                                  const ovf::OVFReader &reader,
+                                  ComObjPtr<Progress> &pProgress)
 {
     HRESULT rc = S_OK;
 
-    Utf8Str strMfFile = manifestFileName(locInfo.strPath);
-    if (RTPathExists(strMfFile.c_str()))
-    {
+    if (!m->strManifestFile.isEmpty())
+    {
+        const char *pcszManifestFileOnly = RTPathFilename(m->strManifestFile.c_str());
+        pProgress->SetNextOperation(BstrFmt(tr("Verifying manifest file '%s'"), pcszManifestFileOnly),
+                                    m->ulWeightForManifestOperation);     // operation's weight, as set up with the IProgress originally
+
         list<Utf8Str> filesList;
         Utf8Str strSrcDir(locInfo.strPath);
@@ -1054,5 +1072,5 @@
         // this call can take a very long time
         size_t cIndexOnError;
-        vrc = RTManifestVerify(strMfFile.c_str(),
+        vrc = RTManifestVerify(m->strManifestFile.c_str(),
                                pTestList,
                                filesList.size() + 1,
@@ -1063,9 +1081,9 @@
                           tr("The SHA1 digest of '%s' does not match the one in '%s'"),
                           RTPathFilename(pTestList[cIndexOnError].pszTestFile),
-                          RTPathFilename(strMfFile.c_str()));
+                          pcszManifestFileOnly);
         else if (RT_FAILURE(vrc))
             rc = setError(VBOX_E_FILE_ERROR,
                           tr("Could not verify the content of '%s' against the available files (%Rrc)"),
-                          RTPathFilename(strMfFile.c_str()),
+                          pcszManifestFileOnly,
                           vrc);
 
@@ -1130,5 +1148,5 @@
     {
         // if a manifest file exists, verify the content; we then need all files which are referenced by the OVF & the OVF itself
-        rc = manifestVerify(locInfo, reader);
+        rc = manifestVerify(locInfo, reader, pProgress);
         if (FAILED(rc)) throw rc;
 
@@ -1308,5 +1326,5 @@
 
             // advance to the next operation
-            stack.pProgress->SetNextOperation(BstrFmt(tr("Creating virtual disk image '%s'"), strTargetPath.c_str()),
+            stack.pProgress->SetNextOperation(BstrFmt(tr("Creating disk image '%s'"), strTargetPath.c_str()),
                                               di.ulSuggestedSizeMB);     // operation's weight, as set up with the IProgress originally
         }
@@ -2200,6 +2218,5 @@
         hS3 = NIL_RTS3;
 
-        if (!pTask->pProgress.isNull())
-            pTask->pProgress->SetNextOperation(BstrFmt(tr("Importing appliance")), m->ulWeightPerOperation);
+        pTask->pProgress->SetNextOperation(BstrFmt(tr("Importing appliance")), m->ulWeightForXmlOperation);
 
         ComObjPtr<Progress> progress;
Index: /trunk/src/VBox/Main/include/ApplianceImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/ApplianceImpl.h	(revision 29874)
+++ /trunk/src/VBox/Main/include/ApplianceImpl.h	(revision 29875)
@@ -120,5 +120,5 @@
 
     void disksWeight();
-    enum SetUpProgressMode { Regular, ImportS3, WriteS3 };
+    enum SetUpProgressMode { ImportFileWithManifest, ImportFileNoManifest, ImportS3, WriteFile, WriteS3 };
     HRESULT setUpProgress(ComObjPtr<Progress> &pProgress,
                           const Bstr &bstrDescription,
@@ -145,5 +145,5 @@
 
     HRESULT importImpl(const LocationInfo &aLocInfo, ComObjPtr<Progress> &aProgress);
-    HRESULT manifestVerify(const LocationInfo &locInfo, const ovf::OVFReader &reader);
+    HRESULT manifestVerify(const LocationInfo &locInfo, const ovf::OVFReader &reader, ComObjPtr<Progress> &pProgress);
 
     HRESULT importFS(const LocationInfo &locInfo, ComObjPtr<Progress> &aProgress);
Index: /trunk/src/VBox/Main/include/ApplianceImplPrivate.h
===================================================================
--- /trunk/src/VBox/Main/include/ApplianceImplPrivate.h	(revision 29874)
+++ /trunk/src/VBox/Main/include/ApplianceImplPrivate.h	(revision 29875)
@@ -62,21 +62,22 @@
     }
 
-    ApplianceState  state;
+    ApplianceState      state;
 
-    LocationInfo    locInfo;       // location info for the currently processed OVF
+    LocationInfo        locInfo;        // location info for the currently processed OVF
 
-    ovf::OVFReader  *pReader;
-
-    bool            fBusyWriting;          // state protection; while this is true nobody else can call methods
+    ovf::OVFReader      *pReader;
 
     std::list< ComObjPtr<VirtualSystemDescription> >
-                    virtualSystemDescriptions;
+                        virtualSystemDescriptions;
 
-    std::list<Utf8Str>   llWarnings;
+    std::list<Utf8Str>  llWarnings;
 
-    ULONG           ulWeightPerOperation;
-    ULONG           ulTotalDisksMB;
-    ULONG           cDisks;
-    Utf8Str         strOVFSHA1Digest;
+    Utf8Str             strManifestFile;    // on import, contains path of manifest file if it exists
+
+    ULONG               ulWeightForXmlOperation;
+    ULONG               ulWeightForManifestOperation;
+    ULONG               ulTotalDisksMB;
+    ULONG               cDisks;
+    Utf8Str             strOVFSHA1Digest;
 };
 
