Index: /trunk/doc/manual/en_US/user_VBoxManage.xml
===================================================================
--- /trunk/doc/manual/en_US/user_VBoxManage.xml	(revision 50446)
+++ /trunk/doc/manual/en_US/user_VBoxManage.xml	(revision 50447)
@@ -1367,4 +1367,12 @@
     OVF standard 1.0 you can enable a OVF 0.9 legacy mode with the
     <computeroutput>--legacy09</computeroutput> option.</para>
+
+    <para>To specify options controlling the exact content of the appliance
+    file, you can use <computeroutput>--option</computeroutput> to request the
+    creation of a manifest file (encouraged, allows detection of corrupted
+    appliances on import), the additional export of DVD images, and the
+    exclusion of MAC addresses. You can specify a list of options, e.g.
+    <computeroutput>--option manifest,nomacs</computeroutput>. For details,
+    check the help output of <computeroutput>VBoxManage export</computeroutput>.</para>
   </sect1>
 
Index: /trunk/doc/manual/user_ChangeLogImpl.xml
===================================================================
--- /trunk/doc/manual/user_ChangeLogImpl.xml	(revision 50446)
+++ /trunk/doc/manual/user_ChangeLogImpl.xml	(revision 50447)
@@ -18,4 +18,11 @@
 
     <itemizedlist>
+
+      <listitem>
+        <para>VBoxManage: when exporting an appliance, support the suppression
+           of MAC addresses, which means they will be always recreated on
+           import, avoiding duplicate MAC addresses for VMs which are imported
+           several times</para>
+      </listitem>
 
       <listitem>
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp	(revision 50446)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp	(revision 50447)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2009-2013 Oracle Corporation
+ * Copyright (C) 2009-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -788,23 +788,65 @@
 }
 
-static const RTGETOPTDEF g_aExportOptions[]
-    = {
-        { "--output",             'o', RTGETOPT_REQ_STRING },
-        { "--legacy09",           'l', RTGETOPT_REQ_NOTHING },
-        { "--ovf09",              'l', RTGETOPT_REQ_NOTHING },
-        { "--ovf10",              '1', RTGETOPT_REQ_NOTHING },
-        { "--ovf20",              '2', RTGETOPT_REQ_NOTHING },
-        { "--manifest",           'm', RTGETOPT_REQ_NOTHING },
-        { "--iso",                'I', RTGETOPT_REQ_NOTHING },
-        { "--vsys",               's', RTGETOPT_REQ_UINT32 },
-        { "--product",            'p', RTGETOPT_REQ_STRING },
-        { "--producturl",         'P', RTGETOPT_REQ_STRING },
-        { "--vendor",             'n', RTGETOPT_REQ_STRING },
-        { "--vendorurl",          'N', RTGETOPT_REQ_STRING },
-        { "--version",            'v', RTGETOPT_REQ_STRING },
-        { "--description",        'd', RTGETOPT_REQ_STRING },
-        { "--eula",               'e', RTGETOPT_REQ_STRING },
-        { "--eulafile",           'E', RTGETOPT_REQ_STRING },
-      };
+static int parseExportOptions(const char *psz, com::SafeArray<ExportOptions_T> *options)
+{
+    int rc = VINF_SUCCESS;
+    while (psz && *psz && RT_SUCCESS(rc))
+    {
+        size_t len;
+        const char *pszComma = strchr(psz, ',');
+        if (pszComma)
+            len = pszComma - psz;
+        else
+            len = strlen(psz);
+        if (len > 0)
+        {
+            if (!RTStrNICmp(psz, "CreateManifest", len))
+                options->push_back(ExportOptions_CreateManifest);
+            else if (!RTStrNICmp(psz, "manifest", len))
+                options->push_back(ExportOptions_CreateManifest);
+            else if (!RTStrNICmp(psz, "ExportDVDImages", len))
+                options->push_back(ExportOptions_ExportDVDImages);
+            else if (!RTStrNICmp(psz, "iso", len))
+                options->push_back(ExportOptions_ExportDVDImages);
+            else if (!RTStrNICmp(psz, "StripAllMACs", len))
+                options->push_back(ExportOptions_StripAllMACs);
+            else if (!RTStrNICmp(psz, "nomacs", len))
+                options->push_back(ExportOptions_StripAllMACs);
+            else if (!RTStrNICmp(psz, "StripAllNonNATMACs", len))
+                options->push_back(ExportOptions_StripAllNonNATMACs);
+            else if (!RTStrNICmp(psz, "nomacsbutnat", len))
+                options->push_back(ExportOptions_StripAllNonNATMACs);
+            else
+                rc = VERR_PARSE_ERROR;
+        }
+        if (pszComma)
+            psz += len + 1;
+        else
+            psz += len;
+    }
+
+    return rc;
+}
+
+static const RTGETOPTDEF g_aExportOptions[] =
+{
+    { "--output",               'o', RTGETOPT_REQ_STRING },
+    { "--legacy09",             'l', RTGETOPT_REQ_NOTHING },
+    { "--ovf09",                'l', RTGETOPT_REQ_NOTHING },
+    { "--ovf10",                '1', RTGETOPT_REQ_NOTHING },
+    { "--ovf20",                '2', RTGETOPT_REQ_NOTHING },
+    { "--manifest",             'm', RTGETOPT_REQ_NOTHING },    // obsoleted by --options
+    { "--iso",                  'I', RTGETOPT_REQ_NOTHING },    // obsoleted by --options
+    { "--vsys",                 's', RTGETOPT_REQ_UINT32 },
+    { "--product",              'p', RTGETOPT_REQ_STRING },
+    { "--producturl",           'P', RTGETOPT_REQ_STRING },
+    { "--vendor",               'n', RTGETOPT_REQ_STRING },
+    { "--vendorurl",            'N', RTGETOPT_REQ_STRING },
+    { "--version",              'v', RTGETOPT_REQ_STRING },
+    { "--description",          'd', RTGETOPT_REQ_STRING },
+    { "--eula",                 'e', RTGETOPT_REQ_STRING },
+    { "--eulafile",             'E', RTGETOPT_REQ_STRING },
+    { "--options",              'O', RTGETOPT_REQ_STRING },
+};
 
 int handleExportAppliance(HandlerArg *a)
@@ -816,4 +858,5 @@
     bool fManifest = false; // the default
     bool fExportISOImages = false; // the default
+    com::SafeArray<ExportOptions_T> options;
     std::list< ComPtr<IMachine> > llMachines;
 
@@ -844,74 +887,79 @@
 
                 case 'l':   // --legacy09/--ovf09
-                     strOvfFormat = "ovf-0.9";
-                     break;
+                    strOvfFormat = "ovf-0.9";
+                    break;
 
                 case '1':   // --ovf10
-                     strOvfFormat = "ovf-1.0";
-                     break;
+                    strOvfFormat = "ovf-1.0";
+                    break;
 
                 case '2':   // --ovf20
-                     strOvfFormat = "ovf-2.0";
-                     break;
+                    strOvfFormat = "ovf-2.0";
+                    break;
 
                 case 'I':   // --iso
-                     fExportISOImages = true;
-                     break;
+                    fExportISOImages = true;
+                    break;
 
                 case 'm':   // --manifest
-                     fManifest = true;
-                     break;
+                    fManifest = true;
+                    break;
 
                 case 's':   // --vsys
-                     ulCurVsys = ValueUnion.u32;
-                     break;
+                    ulCurVsys = ValueUnion.u32;
+                    break;
 
                 case 'p':   // --product
-                     if (ulCurVsys == (uint32_t)-1)
-                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
-                     mapArgsMapsPerVsys[ulCurVsys]["product"] = ValueUnion.psz;
-                     break;
+                    if (ulCurVsys == (uint32_t)-1)
+                        return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
+                    mapArgsMapsPerVsys[ulCurVsys]["product"] = ValueUnion.psz;
+                    break;
 
                 case 'P':   // --producturl
-                     if (ulCurVsys == (uint32_t)-1)
-                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
-                     mapArgsMapsPerVsys[ulCurVsys]["producturl"] = ValueUnion.psz;
-                     break;
+                    if (ulCurVsys == (uint32_t)-1)
+                        return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
+                    mapArgsMapsPerVsys[ulCurVsys]["producturl"] = ValueUnion.psz;
+                    break;
 
                 case 'n':   // --vendor
-                     if (ulCurVsys == (uint32_t)-1)
-                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
-                     mapArgsMapsPerVsys[ulCurVsys]["vendor"] = ValueUnion.psz;
-                     break;
+                    if (ulCurVsys == (uint32_t)-1)
+                        return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
+                    mapArgsMapsPerVsys[ulCurVsys]["vendor"] = ValueUnion.psz;
+                    break;
 
                 case 'N':   // --vendorurl
-                     if (ulCurVsys == (uint32_t)-1)
-                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
-                     mapArgsMapsPerVsys[ulCurVsys]["vendorurl"] = ValueUnion.psz;
-                     break;
+                    if (ulCurVsys == (uint32_t)-1)
+                        return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
+                    mapArgsMapsPerVsys[ulCurVsys]["vendorurl"] = ValueUnion.psz;
+                    break;
 
                 case 'v':   // --version
-                     if (ulCurVsys == (uint32_t)-1)
-                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
-                     mapArgsMapsPerVsys[ulCurVsys]["version"] = ValueUnion.psz;
-                     break;
+                    if (ulCurVsys == (uint32_t)-1)
+                        return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
+                    mapArgsMapsPerVsys[ulCurVsys]["version"] = ValueUnion.psz;
+                    break;
 
                 case 'd':   // --description
-                     if (ulCurVsys == (uint32_t)-1)
-                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
-                     mapArgsMapsPerVsys[ulCurVsys]["description"] = ValueUnion.psz;
-                     break;
+                    if (ulCurVsys == (uint32_t)-1)
+                        return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
+                    mapArgsMapsPerVsys[ulCurVsys]["description"] = ValueUnion.psz;
+                    break;
 
                 case 'e':   // --eula
-                     if (ulCurVsys == (uint32_t)-1)
-                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
-                     mapArgsMapsPerVsys[ulCurVsys]["eula"] = ValueUnion.psz;
-                     break;
+                    if (ulCurVsys == (uint32_t)-1)
+                        return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
+                    mapArgsMapsPerVsys[ulCurVsys]["eula"] = ValueUnion.psz;
+                    break;
 
                 case 'E':   // --eulafile
-                     if (ulCurVsys == (uint32_t)-1)
-                         return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
-                     mapArgsMapsPerVsys[ulCurVsys]["eulafile"] = ValueUnion.psz;
-                     break;
+                    if (ulCurVsys == (uint32_t)-1)
+                        return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);
+                    mapArgsMapsPerVsys[ulCurVsys]["eulafile"] = ValueUnion.psz;
+                    break;
+
+                case 'O':   // --options
+                    if (RT_FAILURE(parseExportOptions(ValueUnion.psz, &options)))
+                        return errorArgument("Invalid export options '%s'\n", ValueUnion.psz);
+                    break;
 
                 case VINF_GETOPT_NOT_OPTION:
@@ -1057,5 +1105,4 @@
             break;
 
-        com::SafeArray<ExportOptions_T> options;
         if (fManifest)
             options.push_back(ExportOptions_CreateManifest);
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 50446)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 50447)
@@ -415,4 +415,5 @@
                      "                            [--manifest]\n"
                      "                            [--iso]\n"
+                     "                            [--options manifest|iso|nomacs|nomacsbutnat]\n"
                      "                            [--vsys <number of virtual system>]\n"
                      "                                    [--product <product name>]\n"
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 50446)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 50447)
@@ -3,5 +3,5 @@
 <!--
 
-    Copyright (C) 2006-2013 Oracle Corporation
+    Copyright (C) 2006-2014 Oracle Corporation
 
     This file is part of VirtualBox Open Source Edition (OSE), as
@@ -2826,4 +2826,16 @@
       needed for typical VMs.</desc>
     </const>
+    <const name="StripAllMACs"      value="3">
+      <desc>Do not export any MAC address information. Default is to keep them
+      to avoid losing information which can cause trouble after import, at the
+      price of risking duplicate MAC addresses, if the import options are used
+      to keep them.</desc>
+    </const>
+    <const name="StripAllNonNATMACs" value="4">
+      <desc>Do not export any MAC address information, except for adapters
+      using NAT. Default is to keep them to avoid losing information which can
+      cause trouble after import, at the price of risking duplicate MAC
+      addresses, if the import options are used to keep them.</desc>
+    </const>
 
   </enum>
Index: /trunk/src/VBox/Main/src-server/ApplianceImplExport.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/ApplianceImplExport.cpp	(revision 50446)
+++ /trunk/src/VBox/Main/src-server/ApplianceImplExport.cpp	(revision 50447)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2008-2013 Oracle Corporation
+ * Copyright (C) 2008-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -1835,4 +1835,19 @@
         // fill the machine config
         vsdescThis->m->pMachine->copyMachineDataToSettings(*pConfig);
+
+        // Apply export tweaks to machine settings
+        bool fStripAllMACs = m->optListExport.contains(ExportOptions_StripAllMACs);
+        bool fStripAllNonNATMACs = m->optListExport.contains(ExportOptions_StripAllNonNATMACs);
+        if (fStripAllMACs || fStripAllNonNATMACs)
+        {
+            for (settings::NetworkAdaptersList::iterator it = pConfig->hardwareMachine.llNetworkAdapters.begin();
+                 it != pConfig->hardwareMachine.llNetworkAdapters.end();
+                 ++it)
+            {
+                settings::NetworkAdapter &nic = *it;
+                if (fStripAllMACs || (fStripAllNonNATMACs && nic.mode != NetworkAttachmentType_NAT))
+                    nic.strMACAddress.setNull();
+            }
+        }
 
         // write the machine config to the vbox:Machine element
