Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp	(revision 37530)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp	(revision 37531)
@@ -392,8 +392,14 @@
                                                  trgMachine.asOutParam()),
                     RTEXITCODE_FAILURE);
+
+    /* Clone options */
+    com::SafeArray<CloneOptions_T> options;
+    options.push_back(CloneOptions_KeepNATMACs);
+
+    /* Start the cloning */
     ComPtr<IProgress> progress;
     CHECK_ERROR_RET(srcMachine, CloneTo(trgMachine,
                                         mode,
-                                        FALSE,
+                                        ComSafeArrayAsInParam(options),
                                         progress.asOutParam()),
                     RTEXITCODE_FAILURE);
Index: /trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizard.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizard.cpp	(revision 37530)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizard.cpp	(revision 37531)
@@ -80,6 +80,12 @@
     }
 
+    /* NAT network adapters should keep there MAC address to prevent any
+     * reactivation. For the other modes they should be regenerated to prevent
+     * address conflicts in the network. */
+    QVector<KCloneOptions> options;
+    options.append(KCloneOptions_KeepNATMACs);
+
     /* Start cloning. */
-    CProgress progress = m_machine.CloneTo(cloneMachine, mode, false);
+    CProgress progress = m_machine.CloneTo(cloneMachine, mode, options);
     if (!m_machine.isOk())
     {
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 37530)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 37531)
@@ -3529,8 +3529,8 @@
 
     <const name="MachineState"                 value="1">
-      <desc>Clone the state of the machine.</desc>
+      <desc>Clone the state of the selected machine.</desc>
     </const>
     <const name="MachineAndChildStates"        value="2">
-      <desc>Clone the state of the machine and if this machine object has child snapshots the state of this childs.</desc>
+      <desc>Clone the state of the selected machine and if this machine object has child snapshots the state of this childs.</desc>
     </const>
     <const name="AllStates"                    value="3">
@@ -3540,8 +3540,29 @@
   </enum>
 
+  <enum
+    name="CloneOptions" extends="$unknown"
+    uuid="1be61ee1-c0ea-4942-b733-7496f27d4f28"
+    >
+
+    <desc>
+    Clone options, used with <link to="IMachine::cloneTo" />.
+    </desc>
+
+    <const name="Link"               value="1">
+      <desc>Create a clone VM where all virtual disks are linked to the original VM.</desc>
+    </const>
+    <const name="KeepAllMACs"        value="2">
+      <desc>Don't generate new MAC addresses of the attached network adapters.</desc>
+    </const>
+    <const name="KeepNATMACs"        value="3">
+      <desc>Don't generate new MAC addresses of the attached network adapters when they are using NAT.</desc>
+    </const>
+
+  </enum>
+
 
   <interface
     name="IMachine" extends="$unknown"
-    uuid="5A398458-266D-4DCD-9745-0886AEBD761B"
+    uuid="54fd9a53-7c1b-4005-9247-9cf703edd4da"
     wsmap="managed"
     >
@@ -5966,19 +5987,16 @@
       <desc>
         Creates a clone of this machine, either as a full clone (which means
-        creating independent copies of the hard disk media), or as a linked
-        clone (which uses its own differencing media, sharing the parent media
-        with the source machine).
-
-        The target machine object must have been created previously with
-        <link to="IVirtualBox::createMachine"/>, and all the settings will be
-        transferred except the VM name, hardware UUID and the network card
-        MAC addresses. These can be set after the clone operation if required.
-        The operation is performed asynchronously, so the machine object will
-        be not be usable until the @a progress object signals completion. If
-        any step of the machine clone operation fails this will abort the
-        operation. The result will be a machine which is not a complete clone.
-        It is the responsibility of the caller to delete this incomplete
-        machine if desired with <link to="#unregister"/> and/or
-        <link to="#delete"/>.
+        creating independent copies of the hard disk media, save states and so
+        on), or as a linked clone (which uses its own differencing media,
+        sharing the parent media with the source machine).
+
+        The target machine object must have been created previously with <link
+          to="IVirtualBox::createMachine"/>, and all the settings will be
+        transferred except the VM name and the hardware UUID. You can set the
+        VM name and the new hardware UUID when creating the target machine. The
+        network MAC addresses are newly created for all newtwork adapters. You
+        can change that behaviour with the options parameter. The operation is
+        performed asynchronously, so the machine object will be not be usable
+        until the @a progress object signals completion.
 
         <result name="E_INVALIDARG">
@@ -5993,6 +6011,6 @@
         <desc>Which states should be cloned.</desc>
       </param>
-      <param name="fullClone" type="boolean" dir="in">
-        <desc>Selects whether a full or linked clone is created.</desc>
+      <param name="options" type="CloneOptions" dir="in" safearray="yes">
+        <desc>Options for the cloning operation.</desc>
       </param>
       <param name="progress" type="IProgress" dir="return">
@@ -8205,7 +8223,7 @@
       <desc>Don't show the started process according to the guest OS guidelines.</desc>
     </const>
-    <const name="NoProfile"               value="8">
-      <desc>Do not use the user's profile data when exeuting a process.</desc>
-    </const>
+    <const name="NoProfile"               value="8"> 
+      <desc>Do not use the user's profile data when exeuting a process.</desc> 
+    </const> 
   </enum>
 
Index: /trunk/src/VBox/Main/include/MachineImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/MachineImpl.h	(revision 37530)
+++ /trunk/src/VBox/Main/include/MachineImpl.h	(revision 37531)
@@ -529,5 +529,5 @@
     STDMETHOD(AttachHostPciDevice(LONG hostAddress, LONG desiredGuestAddress, BOOL tryToUnbind));
     STDMETHOD(DetachHostPciDevice(LONG hostAddress));
-    STDMETHOD(CloneTo(IMachine *aTarget, CloneMode_T mode, BOOL aFullClone, IProgress **aProgress));
+    STDMETHOD(CloneTo(IMachine *pTarget, CloneMode_T mode, ComSafeArrayIn(CloneOptions_T, options), IProgress **pProgress));
     // public methods only for internal purposes
 
Index: /trunk/src/VBox/Main/include/MachineImplCloneVM.h
===================================================================
--- /trunk/src/VBox/Main/include/MachineImplCloneVM.h	(revision 37530)
+++ /trunk/src/VBox/Main/include/MachineImplCloneVM.h	(revision 37531)
@@ -27,5 +27,5 @@
 {
 public:
-    MachineCloneVM(ComObjPtr<Machine> pSrcMachine, ComObjPtr<Machine> pTrgMachine, CloneMode_T mode, bool fFullClone);
+    MachineCloneVM(ComObjPtr<Machine> pSrcMachine, ComObjPtr<Machine> pTrgMachine, CloneMode_T mode, const RTCList<CloneOptions_T> &opts);
     ~MachineCloneVM();
 
Index: /trunk/src/VBox/Main/src-server/MachineImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 37530)
+++ /trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 37531)
@@ -6074,5 +6074,5 @@
 }
 
-STDMETHODIMP Machine::CloneTo(IMachine *pTarget, CloneMode_T mode, BOOL fFullClone, IProgress **pProgress)
+STDMETHODIMP Machine::CloneTo(IMachine *pTarget, CloneMode_T mode, ComSafeArrayIn(CloneOptions_T, options), IProgress **pProgress)
 {
     LogFlowFuncEnter();
@@ -6080,10 +6080,16 @@
     CheckComArgNotNull(pTarget);
     CheckComArgOutPointerValid(pProgress);
-    AssertReturn(!fFullClone, E_NOTIMPL);
-
-    AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
-    MachineCloneVM *pWorker = new MachineCloneVM(this, static_cast<Machine*>(pTarget), mode, fFullClone);
+
+    /* Convert the options. */
+    RTCList<CloneOptions_T> optList;
+    if (options != NULL)
+        optList = SafeArrayToRTCList(ComSafeArrayInArg(options));
+    AssertReturn(!optList.contains(CloneOptions_Link), E_NOTIMPL);
+    AssertReturn(!(optList.contains(CloneOptions_KeepAllMACs) && optList.contains(CloneOptions_KeepNATMACs)), E_FAIL);
+
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    MachineCloneVM *pWorker = new MachineCloneVM(this, static_cast<Machine*>(pTarget), mode, optList);
 
     HRESULT rc = pWorker->start(pProgress);
Index: /trunk/src/VBox/Main/src-server/MachineImplCloneVM.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/MachineImplCloneVM.cpp	(revision 37530)
+++ /trunk/src/VBox/Main/src-server/MachineImplCloneVM.cpp	(revision 37531)
@@ -20,4 +20,5 @@
 #include "VirtualBoxImpl.h"
 #include "MediumImpl.h"
+#include "HostImpl.h"
 
 #include <iprt/path.h>
@@ -55,5 +56,5 @@
 struct MachineCloneVMPrivate
 {
-    MachineCloneVMPrivate(MachineCloneVM *a_q, ComObjPtr<Machine> &a_pSrcMachine, ComObjPtr<Machine> &a_pTrgMachine, CloneMode_T a_mode, bool a_fFullClone)
+    MachineCloneVMPrivate(MachineCloneVM *a_q, ComObjPtr<Machine> &a_pSrcMachine, ComObjPtr<Machine> &a_pTrgMachine, CloneMode_T a_mode, const RTCList<CloneOptions_T> &opts)
       : q_ptr(a_q)
       , p(a_pSrcMachine)
@@ -61,5 +62,5 @@
       , pTrgMachine(a_pTrgMachine)
       , mode(a_mode)
-      , fLinkDisks(!a_fFullClone)
+      , options(opts)
     {}
 
@@ -91,10 +92,12 @@
 
     /* Private helper methods */
-    HRESULT cloneCreateMachineList(const ComPtr<ISnapshot> &pSnapshot, RTCList< ComObjPtr<Machine> > &machineList) const;
-    settings::Snapshot cloneFindSnapshot(settings::MachineConfigFile *pMCF, const settings::SnapshotsList &snl, const Guid &id) const;
-    void cloneUpdateStorageLists(settings::StorageControllersList &sc, const Bstr &bstrOldId, const Bstr &bstrNewId) const;
-    void cloneUpdateSnapshotStorageLists(settings::SnapshotsList &sl, const Bstr &bstrOldId, const Bstr &bstrNewId) const;
-    void cloneUpdateStateFile(settings::SnapshotsList &snl, const Guid &id, const Utf8Str &strFile) const;
-    static int cloneCopyStateFileProgress(unsigned uPercentage, void *pvUser);
+    HRESULT createMachineList(const ComPtr<ISnapshot> &pSnapshot, RTCList< ComObjPtr<Machine> > &machineList) const;
+    settings::Snapshot findSnapshot(settings::MachineConfigFile *pMCF, const settings::SnapshotsList &snl, const Guid &id) const;
+    void updateMACAddresses(settings::NetworkAdaptersList &nwl) const;
+    void updateMACAddresses(settings::SnapshotsList &sl) const;
+    void updateStorageLists(settings::StorageControllersList &sc, const Bstr &bstrOldId, const Bstr &bstrNewId) const;
+    void updateSnapshotStorageLists(settings::SnapshotsList &sl, const Bstr &bstrOldId, const Bstr &bstrNewId) const;
+    void updateStateFile(settings::SnapshotsList &snl, const Guid &id, const Utf8Str &strFile) const;
+    static int copyStateFileProgress(unsigned uPercentage, void *pvUser);
 
     /* Private q and parent pointer */
@@ -109,10 +112,10 @@
     Guid                        snapshotId;
     CloneMode_T                 mode;
-    bool                        fLinkDisks;
+    RTCList<CloneOptions_T>     options;
     RTCList<MEDIUMTASKCHAIN>    llMedias;
     RTCList<SAVESTATETASK>      llSaveStateFiles; /* Snapshot UUID -> File path */
 };
 
-HRESULT MachineCloneVMPrivate::cloneCreateMachineList(const ComPtr<ISnapshot> &pSnapshot, RTCList< ComObjPtr<Machine> > &machineList) const
+HRESULT MachineCloneVMPrivate::createMachineList(const ComPtr<ISnapshot> &pSnapshot, RTCList< ComObjPtr<Machine> > &machineList) const
 {
     HRESULT rc = S_OK;
@@ -131,5 +134,5 @@
     for (size_t i = 0; i < sfaChilds.size(); ++i)
     {
-        rc = cloneCreateMachineList(sfaChilds[i], machineList);
+        rc = createMachineList(sfaChilds[i], machineList);
         if (FAILED(rc)) return rc;
     }
@@ -138,5 +141,5 @@
 }
 
-settings::Snapshot MachineCloneVMPrivate::cloneFindSnapshot(settings::MachineConfigFile *pMCF, const settings::SnapshotsList &snl, const Guid &id) const
+settings::Snapshot MachineCloneVMPrivate::findSnapshot(settings::MachineConfigFile *pMCF, const settings::SnapshotsList &snl, const Guid &id) const
 {
     settings::SnapshotsList::const_iterator it;
@@ -146,10 +149,34 @@
             return *it;
         else if (!it->llChildSnapshots.empty())
-            return cloneFindSnapshot(pMCF, it->llChildSnapshots, id);
+            return findSnapshot(pMCF, it->llChildSnapshots, id);
     }
     return settings::Snapshot();
 }
 
-void MachineCloneVMPrivate::cloneUpdateStorageLists(settings::StorageControllersList &sc, const Bstr &bstrOldId, const Bstr &bstrNewId) const
+void MachineCloneVMPrivate::updateMACAddresses(settings::NetworkAdaptersList &nwl) const
+{
+    const bool fNotNAT = options.contains(CloneOptions_KeepNATMACs);
+    settings::NetworkAdaptersList::iterator it;
+    for (it = nwl.begin(); it != nwl.end(); ++it)
+    {
+        if (   fNotNAT
+            && it->mode == NetworkAttachmentType_NAT)
+            continue;
+        Host::generateMACAddress(it->strMACAddress);
+    }
+}
+
+void MachineCloneVMPrivate::updateMACAddresses(settings::SnapshotsList &sl) const
+{
+    settings::SnapshotsList::iterator it;
+    for (it = sl.begin(); it != sl.end(); ++it)
+    {
+        updateMACAddresses(it->hardware.llNetworkAdapters);
+        if (!it->llChildSnapshots.empty())
+            updateMACAddresses(it->llChildSnapshots);
+    }
+}
+
+void MachineCloneVMPrivate::updateStorageLists(settings::StorageControllersList &sc, const Bstr &bstrOldId, const Bstr &bstrNewId) const
 {
     settings::StorageControllersList::iterator it3;
@@ -173,5 +200,5 @@
 }
 
-void MachineCloneVMPrivate::cloneUpdateSnapshotStorageLists(settings::SnapshotsList &sl, const Bstr &bstrOldId, const Bstr &bstrNewId) const
+void MachineCloneVMPrivate::updateSnapshotStorageLists(settings::SnapshotsList &sl, const Bstr &bstrOldId, const Bstr &bstrNewId) const
 {
     settings::SnapshotsList::iterator it;
@@ -180,11 +207,11 @@
          ++it)
     {
-        cloneUpdateStorageLists(it->storage.llStorageControllers, bstrOldId, bstrNewId);
+        updateStorageLists(it->storage.llStorageControllers, bstrOldId, bstrNewId);
         if (!it->llChildSnapshots.empty())
-            cloneUpdateSnapshotStorageLists(it->llChildSnapshots, bstrOldId, bstrNewId);
-    }
-}
-
-void MachineCloneVMPrivate::cloneUpdateStateFile(settings::SnapshotsList &snl, const Guid &id, const Utf8Str &strFile) const
+            updateSnapshotStorageLists(it->llChildSnapshots, bstrOldId, bstrNewId);
+    }
+}
+
+void MachineCloneVMPrivate::updateStateFile(settings::SnapshotsList &snl, const Guid &id, const Utf8Str &strFile) const
 {
     settings::SnapshotsList::iterator it;
@@ -194,10 +221,10 @@
             it->strStateFile = strFile;
         else if (!it->llChildSnapshots.empty())
-            cloneUpdateStateFile(it->llChildSnapshots, id, strFile);
+            updateStateFile(it->llChildSnapshots, id, strFile);
     }
 }
 
 /* static */
-int MachineCloneVMPrivate::cloneCopyStateFileProgress(unsigned uPercentage, void *pvUser)
+int MachineCloneVMPrivate::copyStateFileProgress(unsigned uPercentage, void *pvUser)
 {
     ComObjPtr<Progress> pProgress = *static_cast< ComObjPtr<Progress>* >(pvUser);
@@ -215,10 +242,9 @@
 }
 
-
 // The public class
 /////////////////////////////////////////////////////////////////////////////
 
-MachineCloneVM::MachineCloneVM(ComObjPtr<Machine> pSrcMachine, ComObjPtr<Machine> pTrgMachine, CloneMode_T mode, bool fFullClone)
-    : d_ptr(new MachineCloneVMPrivate(this, pSrcMachine, pTrgMachine, mode, fFullClone))
+MachineCloneVM::MachineCloneVM(ComObjPtr<Machine> pSrcMachine, ComObjPtr<Machine> pTrgMachine, CloneMode_T mode, const RTCList<CloneOptions_T> &opts)
+    : d_ptr(new MachineCloneVMPrivate(this, pSrcMachine, pTrgMachine, mode, opts))
 {
 }
@@ -283,5 +309,5 @@
                 rc = d->pSrcMachine->FindSnapshot(Bstr(id).raw(), pSnapshot.asOutParam());
                 if (FAILED(rc)) throw rc;
-                rc = d->cloneCreateMachineList(pSnapshot, machineList);
+                rc = d->createMachineList(pSnapshot, machineList);
                 if (FAILED(rc)) throw rc;
                 if (d->mode == CloneMode_MachineAndChildStates)
@@ -444,5 +470,5 @@
         settings::Snapshot sn;
         if (!d->snapshotId.isEmpty())
-            sn = d->cloneFindSnapshot(&trgMCF, trgMCF.llFirstSnapshot, d->snapshotId);
+            sn = d->findSnapshot(&trgMCF, trgMCF.llFirstSnapshot, d->snapshotId);
 
         if (d->mode == CloneMode_MachineState)
@@ -469,4 +495,11 @@
             trgMCF.llFirstSnapshot.clear();
             trgMCF.llFirstSnapshot.push_back(sn);
+        }
+
+        /* Generate new MAC addresses for all machines when not forbidden. */
+        if (!d->options.contains(CloneOptions_KeepAllMACs))
+        {
+            d->updateMACAddresses(trgMCF.hardwareMachine.llNetworkAdapters);
+            d->updateMACAddresses(trgMCF.llFirstSnapshot);
         }
 
@@ -642,6 +675,6 @@
             /* We have to patch the configuration, so it contains the new
              * medium uuid instead of the old one. */
-            d->cloneUpdateStorageLists(trgMCF.storageMachine.llStorageControllers, bstrSrcId, bstrTrgId);
-            d->cloneUpdateSnapshotStorageLists(trgMCF.llFirstSnapshot, bstrSrcId, bstrTrgId);
+            d->updateStorageLists(trgMCF.storageMachine.llStorageControllers, bstrSrcId, bstrTrgId);
+            d->updateSnapshotStorageLists(trgMCF.llFirstSnapshot, bstrSrcId, bstrTrgId);
         }
         /* Clone all save state files. */
@@ -657,5 +690,5 @@
             if (!newFiles.contains(strTrgSaveState.c_str()))
             {
-                int vrc = RTFileCopyEx(sst.strSaveStateFile.c_str(), strTrgSaveState.c_str(), 0, MachineCloneVMPrivate::cloneCopyStateFileProgress, &d->pProgress);
+                int vrc = RTFileCopyEx(sst.strSaveStateFile.c_str(), strTrgSaveState.c_str(), 0, MachineCloneVMPrivate::copyStateFileProgress, &d->pProgress);
                 if (RT_FAILURE(vrc))
                     throw p->setError(VBOX_E_IPRT_ERROR,
@@ -668,5 +701,5 @@
                 trgMCF.strStateFile = strTrgSaveState;
             else
-                d->cloneUpdateStateFile(trgMCF.llFirstSnapshot, sst.snapshotUuid, strTrgSaveState);
+                d->updateStateFile(trgMCF.llFirstSnapshot, sst.snapshotUuid, strTrgSaveState);
         }
 
