Index: src/VBox/Devices/Storage/VBoxHDD-new.cpp
===================================================================
--- src/VBox/Devices/Storage/VBoxHDD-new.cpp	(revision 7281)
+++ src/VBox/Devices/Storage/VBoxHDD-new.cpp	(working copy)
@@ -1575,7 +1575,112 @@
                          bool fMoveByRename, uint64_t cbSize,
                          PFNVMPROGRESS pfnProgress, void *pvUser)
 {
-    return VERR_NOT_IMPLEMENTED;
+    int rc = VINF_SUCCESS;
+    void *pvBuf = NULL;
+
+    do {
+        /* Check arguments. */
+        AssertMsgBreak(VALID_PTR(pDiskFrom), ("pDiskFrom=%#p\n", pDiskFrom),
+                       rc = VERR_INVALID_PARAMETER);
+        AssertMsg(pDiskFrom->u32Signature == VBOXHDDDISK_SIGNATURE,
+                  ("u32Signature=%08x\n", pDiskFrom->u32Signature)); 
+
+        PVDIMAGE pImageFrom = vdGetImageByNumber(pDiskFrom, nImage);
+        AssertBreak(VALID_PTR(pImageFrom), rc = VERR_VDI_IMAGE_NOT_FOUND);
+        AssertMsgBreak(VALID_PTR(pDiskTo), ("pDiskTo=%#p\n", pDiskTo),
+                       rc = VERR_INVALID_PARAMETER);
+        AssertMsg(pDiskTo->u32Signature == VBOXHDDDISK_SIGNATURE,
+                  ("u32Signature=%08x\n", pDiskTo->u32Signature)); 
+
+        AssertMsgBreak(VALID_PTR(pszFilename) && *pszFilename,
+                       ("pszFilename=%#p \"%s\"\n", pszFilename, pszFilename),
+                       rc = VERR_INVALID_PARAMETER);
+
+        /* @todo Implement these. */
+        AssertBreak(pDiskFrom != pDiskTo, rc = VERR_NOT_IMPLEMENTED);
+        AssertBreak(fMoveByRename == false, rc = VERR_NOT_IMPLEMENTED);
+
+        /* Collect properties of source image. */
+        VDIMAGETYPE enmTypeFrom;
+        rc = VDGetImageType(pDiskFrom, nImage, &enmTypeFrom);
+        if (VBOX_FAILURE(rc))
+            break;
+
+        uint64_t cbSizeFrom = VDGetSize(pDiskFrom, nImage);
+        if (cbSizeFrom == 0) {
+            rc = VERR_VDI_VALUE_NOT_FOUND;
+            break;
+        }
+        
+        if (cbSize == 0)
+            cbSize = cbSizeFrom;
+
+        unsigned uImageFlagsFrom;
+        rc = VDGetImageFlags(pDiskFrom, nImage, &uImageFlagsFrom);
+        if (VBOX_FAILURE(rc))
+            break;
+     
+        /* @todo Get this from the source image. */
+        PDMMEDIAGEOMETRY PCHSGeometryFrom = {0, 0, 0};
+        PDMMEDIAGEOMETRY LCHSGeometryFrom = {0, 0, 0};
+        
+        unsigned uOpenFlagsFrom;
+        rc = VDGetOpenFlags(pDiskFrom, nImage, &uOpenFlagsFrom);
+        if (VBOX_FAILURE(rc))
+            break;
+
+        /* Create destination image with the properties of the source image. */
+        /* @todo Copy the comment. */
+        if (enmTypeFrom == VD_IMAGE_TYPE_DIFF) {
+            rc = VDCreateDiff(pDiskTo, pszBackend, pszFilename, uImageFlagsFrom,
+                              "", uOpenFlagsFrom, NULL, NULL);
+        } else {
+            rc = VDCreateBase(pDiskTo, pszBackend, pszFilename, enmTypeFrom,
+                              cbSize, uImageFlagsFrom, "",
+                              &PCHSGeometryFrom, &LCHSGeometryFrom,
+                              uOpenFlagsFrom, NULL, NULL);
+        }
+        if (VBOX_FAILURE(rc))
+            break;
+
+        PVDIMAGE pImageTo = pDiskTo->pLast;
+        AssertBreak(VALID_PTR(pImageTo), rc = VERR_VDI_IMAGE_NOT_FOUND);
+
+        /* Allocate tmp buffer. */
+        pvBuf = RTMemTmpAlloc(VD_MERGE_BUFFER_SIZE);
+        if (!pvBuf)
+        {
+            rc = VERR_NO_MEMORY;
+            break;
+        }
+
+        /* Copy the data. */
+        uint64_t uOffset = 0;
+        uint64_t cbRemaining = cbSize;
+        
+        do
+        {
+            size_t cbThisRead = RT_MIN(VD_MERGE_BUFFER_SIZE, cbRemaining);
+
+            rc = vdReadHelper(pDiskFrom, pImageFrom, uOffset, pvBuf,
+                              cbThisRead);
+            if (VBOX_FAILURE(rc))
+                break;
+
+            rc = vdWriteHelper(pDiskTo, pImageTo, uOffset, pvBuf,
+                               cbThisRead);
+            if (VBOX_FAILURE(rc))
+                break;
+
+            uOffset += cbThisRead;
+            cbRemaining -= cbThisRead;
+        } while (uOffset < cbSize);
+    } while (0);
+
+    if (pvBuf)
+        RTMemTmpFree(pvBuf);
+
+    return rc;
 }
 
 /**
