Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp	(revision 382)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp	(revision 383)
@@ -56,4 +56,5 @@
 #include <VBox/err.h>
 #include <VBox/version.h>
+#include <VBox/VBoxHDD.h>
 
 #include "VBoxManage.h"
@@ -412,5 +413,6 @@
     {
         RTPrintf("VBoxManage modifyvdi        <uuid>|<filename>\n"
-                 "                            -type normal|writethrough|immutable\n"
+                 "                            settype normal|writethrough|immutable |\n"
+                 "                            compact\n"
                  "\n");
     }
@@ -2088,32 +2090,30 @@
 }
 
+static DECLCALLBACK(int) vdiProgressCallback(PVM pVM, unsigned uPercent, void *pvUser)
+{
+    unsigned *pPercent = (unsigned *)pvUser;
+
+    if (*pPercent != uPercent)
+    {
+        *pPercent = uPercent;
+        RTPrintf(".");
+        if ((uPercent % 10) == 0 && uPercent)
+            RTPrintf("%d%%", uPercent);
+        RTStrmFlush(g_pStdOut);
+    }
+
+    return VINF_SUCCESS;
+}
+
+
 static int handleModifyVDI(int argc, char *argv[],
                            ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
 {
     HRESULT rc;
-    char *type = NULL;
-
-    /* The uuid/filename and a the parameter "-type" with an argument. */
-    if (argc != 3)
+
+    /* The uuid/filename and a command */
+    if (argc < 2)
     {
         return errorSyntax(USAGE_MODIFYVDI, "Incorrect number of parameters");
-    }
-
-    /* let's have a closer look at the arguments */
-    for (int i = 1; i < argc; i++)
-    {
-        if (strcmp(argv[i], "-type") == 0)
-        {
-            if (argc <= i + 1)
-            {
-                return errorArgument("Missing argument to '%s'", argv[i]);
-            }
-            i++;
-            type = argv[i];
-        }
-        else
-        {
-            return errorSyntax(USAGE_MODIFYVDI, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
-        }
     }
 
@@ -2136,8 +2136,19 @@
         vdi = hardDisk;
     }
-    if (SUCCEEDED(rc) && hardDisk && vdi)
-    {
-        if (type)
-        {
+
+    /* let's find out which command */
+    if (strcmp(argv[1], "settype") == 0)
+    {
+        /* hard disk must be registered */
+        if (SUCCEEDED(rc) && hardDisk && vdi)
+        {
+            char *type = NULL;
+
+            if (argc <= 2)
+            {
+                return errorArgument("Missing argument to for settype");
+            }
+            type = argv[2];
+
             HardDiskType_T hddType;
             CHECK_ERROR(hardDisk, COMGETTER(Type)(&hddType));
@@ -2164,4 +2175,48 @@
             }
         }
+        else
+        {
+            return errorArgument("Hard disk image not registered");
+        }
+    }
+    else if (strcmp(argv[1], "compact") == 0)
+    {
+        ComPtr<IVirtualDiskImage> vdi;
+
+        /* the hard disk image might not be registered */
+        if (!hardDisk)
+        {
+            virtualBox->OpenVirtualDiskImage(Bstr(argv[0]), vdi.asOutParam());
+            if (!hardDisk)
+            {
+                return errorArgument("Hard disk image not found");
+            }
+        }
+        else
+            vdi = hardDisk;
+
+        if (!vdi)
+            return errorArgument("Invalid hard disk type. The command only works on VDI files\n");
+
+        Bstr fileName;
+        vdi->COMGETTER(FilePath)(fileName.asOutParam());
+
+        /* close the file */
+        hardDisk = NULL;
+        vdi = NULL;
+
+        unsigned uProcent;
+
+        RTPrintf("Shrinking '%lS': 0%%", fileName.raw());
+        int vrc = VDIShrinkImage(Utf8Str(fileName).raw(), vdiProgressCallback, &uProcent);
+        if (VBOX_FAILURE(vrc))
+        {
+            RTPrintf("Error while shrinking hard disk image: %Vrc\n", vrc);
+            rc = E_FAIL;
+        }
+    }
+    else
+    {
+        return errorSyntax(USAGE_MODIFYVDI, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
     }
     return SUCCEEDED(rc) ? 0 : 1;
