Index: /trunk/src/VBox/Frontends/VBoxManage/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/Makefile.kmk	(revision 49620)
+++ /trunk/src/VBox/Frontends/VBoxManage/Makefile.kmk	(revision 49621)
@@ -23,6 +23,8 @@
 endif
 VBoxManageHelp_TEMPLATE   = VBoxAdvBldProg
-VBoxManageHelp_DEFS      += VBOX_ONLY_DOCS
-VBoxManageHelp_SOURCES = \
+VBoxManageHelp_DEFS      += \
+	VBOX_ONLY_DOCS \
+	$(if $(VBOX_WITH_GUEST_CONTROL),VBOX_WITH_GUEST_CONTROL)
+VBoxManageHelp_SOURCES    = \
 	VBoxManage.cpp \
 	VBoxManageHelp.cpp \
@@ -35,5 +37,5 @@
 VBoxManage_TEMPLATE   = VBOXMAINCLIENTEXE
 VBoxManage_DEFS.win   = _WIN32_WINNT=0x0500
-VBoxManage_SOURCES = \
+VBoxManage_SOURCES    = \
 	VBoxManage.cpp \
 	VBoxInternalManage.cpp \
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp	(revision 49620)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp	(revision 49621)
@@ -2384,5 +2384,5 @@
 
             default:
-                return errorGetOpt(USAGE_DEBUGLOG , ch, &ValueUnion);
+                return errorGetOpt(USAGE_DEBUGLOG, ch, &ValueUnion);
         }
     }
@@ -2454,5 +2454,5 @@
 
             default:
-                return errorGetOpt(USAGE_GUESTSTATS , ch, &ValueUnion);
+                return errorGetOpt(USAGE_GUESTSTATS, ch, &ValueUnion);
         }
     }
@@ -2523,5 +2523,5 @@
         return CmdLoadSyms(a->argc - 1, &a->argv[1], a->virtualBox, a->session);
     //if (!strcmp(pszCmd, "unloadsyms"))
-    //    return CmdUnloadSyms(argc - 1 , &a->argv[1]);
+    //    return CmdUnloadSyms(argc - 1, &a->argv[1]);
     if (!strcmp(pszCmd, "sethduuid") || !strcmp(pszCmd, "sethdparentuuid"))
         return CmdSetHDUUID(a->argc, &a->argv[0], a->virtualBox, a->session);
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp	(revision 49620)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp	(revision 49621)
@@ -333,5 +333,5 @@
             {
                 showLogo(g_pStdOut);
-                printUsage(USAGE_ALL, g_pStdOut);
+                printUsage(USAGE_ALL, ~0U, g_pStdOut);
                 return 0;
             }
@@ -357,5 +357,5 @@
             /* Special option to dump really all commands,
              * even the ones not understood on this platform. */
-            printUsage(USAGE_DUMPOPTS, g_pStdOut);
+            printUsage(USAGE_DUMPOPTS, ~0U, g_pStdOut);
             return 0;
         }
@@ -555,5 +555,5 @@
                         && s_commandHandlers[commandIndex].help))
                 {
-                    printUsage(s_commandHandlers[commandIndex].help, g_pStdOut);
+                    printUsage(s_commandHandlers[commandIndex].help, ~0U, g_pStdOut);
                     rcExit = RTEXITCODE_FAILURE; /* error */
                 }
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h	(revision 49620)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h	(revision 49621)
@@ -30,4 +30,5 @@
 #include <iprt/message.h>
 #include <iprt/stream.h>
+#include <iprt/getopt.h>
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -106,4 +107,22 @@
 /** @} */
 
+#ifdef VBOX_WITH_GUEST_CONTROL
+# define USAGE_GSTCTRL_EXEC         RT_BIT(0)
+# define USAGE_GSTCTRL_COPYFROM     RT_BIT(1)
+# define USAGE_GSTCTRL_COPYTO       RT_BIT(2)
+# define USAGE_GSTCTRL_CREATEDIR    RT_BIT(3)
+# define USAGE_GSTCTRL_REMOVEDIR    RT_BIT(4)
+# define USAGE_GSTCTRL_REMOVEFILE   RT_BIT(5)
+# define USAGE_GSTCTRL_RENAME       RT_BIT(6)
+# define USAGE_GSTCTRL_CREATETEMP   RT_BIT(7)
+# define USAGE_GSTCTRL_LIST         RT_BIT(8)
+# define USAGE_GSTCTRL_PROCESS      RT_BIT(9)
+# define USAGE_GSTCTRL_KILL         RT_BIT(10)
+# define USAGE_GSTCTRL_SESSION      RT_BIT(11)
+# define USAGE_GSTCTRL_STAT         RT_BIT(12)
+# define USAGE_GSTCTRL_UPDATEADDS   RT_BIT(13)
+# define USAGE_GSTCTRL_WATCH        RT_BIT(14)
+#endif
+
 typedef uint64_t USAGECATEGORY;
 
@@ -148,10 +167,12 @@
 
 /* VBoxManageHelp.cpp */
-void printUsage(USAGECATEGORY u64Cmd, PRTSTREAM pStrm);
-RTEXITCODE errorSyntax(USAGECATEGORY u64Cmd, const char *pszFormat, ...);
-RTEXITCODE errorGetOpt(USAGECATEGORY u64Cmd, int rc, union RTGETOPTUNION const *pValueUnion);
+void printUsage(USAGECATEGORY fCategory, uint32_t fSubCategory, PRTSTREAM pStrm);
+RTEXITCODE errorSyntax(USAGECATEGORY fCategory, const char *pszFormat, ...);
+RTEXITCODE errorSyntaxEx(USAGECATEGORY fCategory, uint32_t fSubCategory, const char *pszFormat, ...);
+RTEXITCODE errorGetOpt(USAGECATEGORY fCategory, int rc, union RTGETOPTUNION const *pValueUnion);
+RTEXITCODE errorGetOptEx(USAGECATEGORY fCategory, uint32_t fSubCategory, int rc, union RTGETOPTUNION const *pValueUnion);
 RTEXITCODE errorArgument(const char *pszFormat, ...);
 
-void printUsageInternal(USAGECATEGORY u64Cmd, PRTSTREAM pStrm);
+void printUsageInternal(USAGECATEGORY fCategory, PRTSTREAM pStrm);
 
 #ifndef VBOX_ONLY_DOCS
@@ -187,5 +208,5 @@
 
 /* VBoxManageGuestCtrl.cpp */
-extern void usageGuestControl(PRTSTREAM pStrm, const char *pcszSep1, const char *pcszSep2);
+extern void usageGuestControl(PRTSTREAM pStrm, const char *pcszSep1, const char *pcszSep2, uint32_t fSubCategory);
 
 #ifndef VBOX_ONLY_DOCS
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageBandwidthControl.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageBandwidthControl.cpp	(revision 49620)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageBandwidthControl.cpp	(revision 49621)
@@ -275,6 +275,9 @@
         switch (c)
         {
-            case 'M':   enmDetails = VMINFO_MACHINEREADABLE; break;
-            default:    return errorGetOpt(USAGE_BANDWIDTHCONTROL, c, &ValueUnion);
+            case 'M':
+                enmDetails = VMINFO_MACHINEREADABLE;
+                break;
+            default:
+                return errorGetOpt(USAGE_BANDWIDTHCONTROL, c, &ValueUnion);
         }
     }
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp	(revision 49620)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp	(revision 49621)
@@ -301,88 +301,119 @@
 #endif /* VBOX_ONLY_DOCS */
 
-void usageGuestControl(PRTSTREAM pStrm, const char *pcszSep1, const char *pcszSep2)
+void usageGuestControl(PRTSTREAM pStrm, const char *pcszSep1, const char *pcszSep2, uint32_t uSubCmd)
 {
     RTStrmPrintf(pStrm,
-                       "%s guestcontrol %s    <uuid|vmname>\n"
-                 "                            exec[ute]\n"
-                 "                            --image <path to program> --username <name>\n"
-                 "                            [--passwordfile <file> | --password <password>]\n"
-                 "                            [--domain <domain>] [--verbose] [--timeout <msec>]\n"
-                 "                            [--environment \"<NAME>=<VALUE> [<NAME>=<VALUE>]\"]\n"
-                 "                            [--wait-exit] [--wait-stdout] [--wait-stderr]\n"
-                 "                            [--dos2unix] [--unix2dos]\n"
-                 "                            [-- [<argument1>] ... [<argumentN>]]\n"
-                 /** @todo Add a "--" parameter (has to be last parameter) to directly execute
-                  *        stuff, e.g. "VBoxManage guestcontrol execute <VMName> --username <> ... -- /bin/rm -Rf /foo". */
-                 "\n"
-                 "                            copyfrom\n"
-                 "                            <guest source> <host dest> --username <name>\n"
-                 "                            [--passwordfile <file> | --password <password>]\n"
-                 "                            [--domain <domain>] [--verbose]\n"
-                 "                            [--dryrun] [--follow] [--recursive]\n"
-                 "\n"
-                 "                            copyto|cp\n"
-                 "                            <host source> <guest dest> --username <name>\n"
-                 "                            [--passwordfile <file> | --password <password>]\n"
-                 "                            [--domain <domain>] [--verbose]\n"
-                 "                            [--dryrun] [--follow] [--recursive]\n"
-                 "\n"
-                 "                            createdir[ectory]|mkdir|md\n"
-                 "                            <guest directory>... --username <name>\n"
-                 "                            [--passwordfile <file> | --password <password>]\n"
-                 "                            [--domain <domain>] [--verbose]\n"
-                 "                            [--parents] [--mode <mode>]\n"
-                 "\n"
-                 "                            removedir[ectory]|rmdir\n"
-                 "                            <guest directory>... --username <name>\n"
-                 "                            [--passwordfile <file> | --password <password>]\n"
-                 "                            [--domain <domain>] [--verbose]\n"
-                 "                            [--recursive|-R|-r]\n"
-                 "\n"
-                 "                            removefile|rm\n"
-                 "                            <guest file>... --username <name>\n"
-                 "                            [--passwordfile <file> | --password <password>]\n"
-                 "                            [--domain <domain>] [--verbose]\n"
-                 "\n"
-                 "                            ren[ame]|mv\n"
-                 "                            <source>... <dest> --username <name>\n"
-                 "                            [--passwordfile <file> | --password <password>]\n"
-                 "                            [--domain <domain>] [--verbose]\n"
-                 "\n"
-                 "                            createtemp[orary]|mktemp\n"
-                 "                            <template> --username <name>\n"
-                 "                            [--passwordfile <file> | --password <password>]\n"
-                 "                            [--directory] [--secure] [--tmpdir <directory>]\n"
-                 "                            [--domain <domain>] [--mode <mode>] [--verbose]\n"
-                 "\n"
-                 "                            list <all|sessions|processes|files> [--verbose]\n"
-                 "\n"
-                 /** @todo Add an own help group for "session" and "process" sub commands. */
-                 "                            process kill --session-id <ID>\n"
+                       "%s guestcontrol %s    <uuid|vmname>\n%s",
+                 pcszSep1, pcszSep2,
+                 uSubCmd == ~0U ? "\n" : "");
+    if (uSubCmd & USAGE_GSTCTRL_EXEC)
+        RTStrmPrintf(pStrm,
+                 "                              exec[ute]\n"
+                 "                              --image <path to program> --username <name>\n"
+                 "                              [--passwordfile <file> | --password <password>]\n"
+                 "                              [--domain <domain>] [--verbose] [--timeout <msec>]\n"
+                 "                              [--environment \"<NAME>=<VALUE> [<NAME>=<VALUE>]\"]\n"
+                 "                              [--wait-exit] [--wait-stdout] [--wait-stderr]\n"
+                 "                              [--dos2unix] [--unix2dos]\n"
+                 "                              [-- [<argument1>] ... [<argumentN>]]\n"
+                 "\n");
+    if (uSubCmd & USAGE_GSTCTRL_COPYFROM)
+        RTStrmPrintf(pStrm,
+                 "                              copyfrom\n"
+                 "                              <guest source> <host dest> --username <name>\n"
+                 "                              [--passwordfile <file> | --password <password>]\n"
+                 "                              [--domain <domain>] [--verbose]\n"
+                 "                              [--dryrun] [--follow] [--recursive]\n"
+                 "\n");
+    if (uSubCmd & USAGE_GSTCTRL_COPYTO)
+        RTStrmPrintf(pStrm,
+                 "                              copyto|cp\n"
+                 "                              <host source> <guest dest> --username <name>\n"
+                 "                              [--passwordfile <file> | --password <password>]\n"
+                 "                              [--domain <domain>] [--verbose]\n"
+                 "                              [--dryrun] [--follow] [--recursive]\n"
+                 "\n");
+    if (uSubCmd & USAGE_GSTCTRL_CREATEDIR)
+        RTStrmPrintf(pStrm,
+                 "                              createdir[ectory]|mkdir|md\n"
+                 "                              <guest directory>... --username <name>\n"
+                 "                              [--passwordfile <file> | --password <password>]\n"
+                 "                              [--domain <domain>] [--verbose]\n"
+                 "                              [--parents] [--mode <mode>]\n"
+                 "\n");
+    if (uSubCmd & USAGE_GSTCTRL_REMOVEDIR)
+        RTStrmPrintf(pStrm,
+                 "                              removedir[ectory]|rmdir\n"
+                 "                              <guest directory>... --username <name>\n"
+                 "                              [--passwordfile <file> | --password <password>]\n"
+                 "                              [--domain <domain>] [--verbose]\n"
+                 "                              [--recursive|-R|-r]\n"
+                 "\n");
+    if (uSubCmd & USAGE_GSTCTRL_REMOVEFILE)
+        RTStrmPrintf(pStrm,
+                 "                              removefile|rm\n"
+                 "                              <guest file>... --username <name>\n"
+                 "                              [--passwordfile <file> | --password <password>]\n"
+                 "                              [--domain <domain>] [--verbose]\n"
+                 "\n");
+    if (uSubCmd & USAGE_GSTCTRL_RENAME)
+        RTStrmPrintf(pStrm,
+                 "                              ren[ame]|mv\n"
+                 "                              <source>... <dest> --username <name>\n"
+                 "                              [--passwordfile <file> | --password <password>]\n"
+                 "                              [--domain <domain>] [--verbose]\n"
+                 "\n");
+    if (uSubCmd & USAGE_GSTCTRL_CREATETEMP)
+        RTStrmPrintf(pStrm,
+                 "                              createtemp[orary]|mktemp\n"
+                 "                              <template> --username <name>\n"
+                 "                              [--passwordfile <file> | --password <password>]\n"
+                 "                              [--directory] [--secure] [--tmpdir <directory>]\n"
+                 "                              [--domain <domain>] [--mode <mode>] [--verbose]\n"
+                 "\n");
+    if (uSubCmd & USAGE_GSTCTRL_LIST)
+        RTStrmPrintf(pStrm,
+                 "                              list <all|sessions|processes|files> [--verbose]\n"
+                 "\n");
+    /** @todo Add an own help group for "session" and "process" sub commands. */
+    if (uSubCmd & USAGE_GSTCTRL_PROCESS)
+         RTStrmPrintf(pStrm,
+                 "                              process kill --session-id <ID>\n"
+                 "                                           | --session-name <name or pattern>\n"
+                 "                                           [--verbose]\n"
+                 "                                           <PID> ... <PID n>\n"
+                 "\n");
+    if (uSubCmd & USAGE_GSTCTRL_KILL)
+        RTStrmPrintf(pStrm,
+                 "                              [p[s]]kill --session-id <ID>\n"
                  "                                         | --session-name <name or pattern>\n"
                  "                                         [--verbose]\n"
                  "                                         <PID> ... <PID n>\n"
-                 "\n"
-                 "                            [p[s]]kill --session-id <ID>\n"
-                 "                                       | --session-name <name or pattern>\n"
-                 "                                       [--verbose]\n"
-                 "                                       <PID> ... <PID n>\n"
-                 "\n"
-                 "                            session close  --session-id <ID>\n"
-                 "                                         | --session-name <name or pattern>\n"
-                 "                                         | --all\n"
-                 "                                         [--verbose]\n"
-                 "                            stat\n"
-                 "                            <file>... --username <name>\n"
-                 "                            [--passwordfile <file> | --password <password>]\n"
-                 "                            [--domain <domain>] [--verbose]\n"
-                 "\n"
-                 "                            updateadditions\n"
-                 "                            [--source <guest additions .ISO>] [--verbose]\n"
-                 "                            [--wait-start]\n"
-                 "                            [-- [<argument1>] ... [<argumentN>]]\n"
-                 "\n"
-                 "                            watch [--verbose]\n"
-                 "\n", pcszSep1, pcszSep2);
+                 "\n");
+    if (uSubCmd & USAGE_GSTCTRL_SESSION)
+        RTStrmPrintf(pStrm,
+                 "                              session close  --session-id <ID>\n"
+                 "                                           | --session-name <name or pattern>\n"
+                 "                                           | --all\n"
+                 "                                           [--verbose]\n"
+                 "\n");
+    if (uSubCmd & USAGE_GSTCTRL_STAT)
+        RTStrmPrintf(pStrm,
+                 "                              stat\n"
+                 "                              <file>... --username <name>\n"
+                 "                              [--passwordfile <file> | --password <password>]\n"
+                 "                              [--domain <domain>] [--verbose]\n"
+                 "\n");
+    if (uSubCmd & USAGE_GSTCTRL_UPDATEADDS)
+        RTStrmPrintf(pStrm,
+                 "                              updateadditions\n"
+                 "                              [--source <guest additions .ISO>] [--verbose]\n"
+                 "                              [--wait-start]\n"
+                 "                              [-- [<argument1>] ... [<argumentN>]]\n"
+                 "\n");
+    if (uSubCmd & USAGE_GSTCTRL_WATCH)
+        RTStrmPrintf(pStrm,
+                 "                              watch [--verbose]\n"
+                 "\n");
 }
 
@@ -749,5 +780,5 @@
  */
 static RTEXITCODE ctrlInitVM(HandlerArg *pArg,
-                             PGCTLCMDCTX pCtx, uint32_t uFlags)
+                             PGCTLCMDCTX pCtx, uint32_t uFlags, uint32_t uUsage)
 {
     AssertPtrReturn(pArg, RTEXITCODE_FAILURE);
@@ -859,4 +890,8 @@
                         iArgIdx = GetState.iNext;
                         break;
+
+                    case 'h': /* Help */
+                        errorGetOptEx(USAGE_GUESTCONTROL, uUsage, ch, &ValueUnion);
+                        return RTEXITCODE_SYNTAX;
 
                     default:
@@ -909,5 +944,5 @@
         {
             if (pCtx->strUsername.isEmpty())
-                rcExit = errorSyntax(USAGE_GUESTCONTROL, "No user name specified!");
+                rcExit = errorSyntaxEx(USAGE_GUESTCONTROL, uUsage, "No user name specified!");
         }
     }
@@ -1160,5 +1195,6 @@
                 case GETOPTDEF_EXEC_DOS2UNIX:
                     if (eOutputType != OUTPUTTYPE_UNDEFINED)
-                        return errorSyntax(USAGE_GUESTCONTROL, "More than one output type (dos2unix/unix2dos) specified!");
+                        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_EXEC,
+                                             "More than one output type (dos2unix/unix2dos) specified!");
                     eOutputType = OUTPUTTYPE_DOS2UNIX;
                     break;
@@ -1171,5 +1207,6 @@
                     vrc = RTGetOptArgvFromString(&papszArg, &cArgs, ValueUnion.psz, NULL);
                     if (RT_FAILURE(vrc))
-                        return errorSyntax(USAGE_GUESTCONTROL, "Failed to parse environment value, rc=%Rrc", vrc);
+                        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_EXEC,
+                                             "Failed to parse environment value, rc=%Rrc", vrc);
                     for (int j = 0; j < cArgs; j++)
                         aEnv.push_back(Bstr(papszArg[j]).raw());
@@ -1199,5 +1236,6 @@
                 case GETOPTDEF_EXEC_UNIX2DOS:
                     if (eOutputType != OUTPUTTYPE_UNDEFINED)
-                        return errorSyntax(USAGE_GUESTCONTROL, "More than one output type (dos2unix/unix2dos) specified!");
+                        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_EXEC,
+                                             "More than one output type (dos2unix/unix2dos) specified!");
                     eOutputType = OUTPUTTYPE_UNIX2DOS;
                     break;
@@ -1233,5 +1271,5 @@
                         aArgs.push_back(Bstr(ValueUnion.psz).raw());
                     else
-                        return RTGetOptPrintError(ch, &ValueUnion);
+                        return errorGetOptEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_EXEC, ch, &ValueUnion);
                     break;
 
@@ -1248,9 +1286,11 @@
 
     if (strCmd.isEmpty())
-        return errorSyntax(USAGE_GUESTCONTROL, "No command to execute specified!");
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_EXEC,
+                             "No command to execute specified!");
 
     /** @todo Any output conversion not supported yet! */
     if (eOutputType != OUTPUTTYPE_UNDEFINED)
-        return errorSyntax(USAGE_GUESTCONTROL, "Output conversion not implemented yet!");
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_EXEC,
+                             "Output conversion not implemented yet!");
 
     RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
@@ -2394,4 +2434,5 @@
     bool fCopyRecursive = false;
     bool fDryRun = false;
+    uint32_t uUsage = fHostToGuest ? USAGE_GSTCTRL_COPYTO : USAGE_GSTCTRL_COPYFROM;
 
     SOURCEVEC vecSources;
@@ -2438,16 +2479,15 @@
 
             default:
-                return RTGetOptPrintError(ch, &ValueUnion);
-                break;
+                return errorGetOptEx(USAGE_GUESTCONTROL, uUsage, ch, &ValueUnion);
         }
     }
 
     if (!vecSources.size())
-        return errorSyntax(USAGE_GUESTCONTROL,
-                           "No source(s) specified!");
+        return errorSyntaxEx(USAGE_GUESTCONTROL, uUsage,
+                             "No source(s) specified!");
 
     if (strDest.isEmpty())
-        return errorSyntax(USAGE_GUESTCONTROL,
-                           "No destination specified!");
+        return errorSyntaxEx(USAGE_GUESTCONTROL, uUsage,
+                             "No destination specified!");
 
     /*
@@ -2663,6 +2703,5 @@
 
             default:
-                return RTGetOptPrintError(ch, &ValueUnion);
-                break;
+                return errorGetOptEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_CREATEDIR, ch, &ValueUnion);
         }
     }
@@ -2670,5 +2709,6 @@
     uint32_t cDirs = mapDirs.size();
     if (!cDirs)
-        return errorSyntax(USAGE_GUESTCONTROL, "No directory to create specified!");
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_CREATEDIR,
+                             "No directory to create specified!");
 
     /*
@@ -2726,6 +2766,5 @@
 
             default:
-                return RTGetOptPrintError(ch, &ValueUnion);
-                break;
+                return errorGetOptEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_REMOVEDIR, ch, &ValueUnion);
         }
     }
@@ -2733,5 +2772,6 @@
     uint32_t cDirs = mapDirs.size();
     if (!cDirs)
-        return errorSyntax(USAGE_GUESTCONTROL, "No directory to remove specified!");
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_REMOVEDIR,
+                             "No directory to remove specified!");
 
     /*
@@ -2809,6 +2849,5 @@
 
             default:
-                return RTGetOptPrintError(ch, &ValueUnion);
-                break;
+                return errorGetOptEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_REMOVEFILE, ch, &ValueUnion);
         }
     }
@@ -2816,5 +2855,6 @@
     uint32_t cFiles = mapDirs.size();
     if (!cFiles)
-        return errorSyntax(USAGE_GUESTCONTROL, "No file to remove specified!");
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_REMOVEFILE,
+                             "No file to remove specified!");
 
     /*
@@ -2879,6 +2919,5 @@
 
                 default:
-                    return RTGetOptPrintError(ch, &ValueUnion);
-                    break;
+                    return errorGetOptEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_RENAME, ch, &ValueUnion);
             }
         }
@@ -2894,7 +2933,9 @@
     uint32_t cSources = vecSources.size();
     if (!cSources)
-        return errorSyntax(USAGE_GUESTCONTROL, "No source(s) to move specified!");
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_RENAME,
+                             "No source(s) to move specified!");
     if (cSources < 2)
-        return errorSyntax(USAGE_GUESTCONTROL, "No destination specified!");
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_RENAME,
+                             "No destination specified!");
 
     /* Delete last element, which now is the destination. */
@@ -3055,20 +3096,21 @@
                     strTemplate = ValueUnion.psz;
                 else
-                    return errorSyntax(USAGE_GUESTCONTROL,
-                                       "More than one template specified!\n");
+                    return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_CREATETEMP,
+                                         "More than one template specified!\n");
                 break;
             }
 
             default:
-                return RTGetOptPrintError(ch, &ValueUnion);
-                break;
+                return errorGetOptEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_CREATETEMP, ch, &ValueUnion);
         }
     }
 
     if (strTemplate.isEmpty())
-        return errorSyntax(USAGE_GUESTCONTROL, "No template specified!");
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_CREATETEMP,
+                             "No template specified!");
 
     if (!fDirectory)
-        return errorSyntax(USAGE_GUESTCONTROL, "Creating temporary files is currently not supported!");
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_CREATETEMP,
+                             "Creating temporary files is currently not supported!");
 
     /*
@@ -3136,7 +3178,6 @@
             case 'c': /* Format */
             case 't': /* Terse */
-                return errorSyntax(USAGE_GUESTCONTROL, "Command \"%s\" not implemented yet!",
-                                   ValueUnion.psz);
-                break; /* Never reached. */
+                return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_STAT,
+                                     "Command \"%s\" not implemented yet!", ValueUnion.psz);
 
             case VINF_GETOPT_NOT_OPTION:
@@ -3145,6 +3186,5 @@
 
             default:
-                return RTGetOptPrintError(ch, &ValueUnion);
-                break;
+                return errorGetOptEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_STAT, ch, &ValueUnion);
         }
     }
@@ -3152,5 +3192,6 @@
     uint32_t cObjs = mapObjs.size();
     if (!cObjs)
-        return errorSyntax(USAGE_GUESTCONTROL, "No element(s) to check specified!");
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_STAT,
+                             "No element(s) to check specified!");
 
     HRESULT rc;
@@ -3257,6 +3298,5 @@
 
             default:
-                return RTGetOptPrintError(ch, &ValueUnion);
-                break;
+                return errorGetOptEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_UPDATEADDS, ch, &ValueUnion);
         }
     }
@@ -3335,5 +3375,6 @@
 
     if (pCtx->iArgc < 1)
-        return errorSyntax(USAGE_GUESTCONTROL, "Must specify a listing category");
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_LIST,
+                             "Must specify a listing category");
 
     RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
@@ -3459,5 +3500,6 @@
     }
     else
-        return errorSyntax(USAGE_GUESTCONTROL, "Invalid listing category '%s", pCtx->ppaArgv[0]);
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_LIST,
+                             "Invalid listing category '%s", pCtx->ppaArgv[0]);
 
     return rcExit;
@@ -3469,5 +3511,6 @@
 
     if (pCtx->iArgc < 1)
-        return errorSyntax(USAGE_GUESTCONTROL, "Must specify at least a PID to close");
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_PROCESS,
+                             "Must specify at least a PID to close");
 
     static const RTGETOPTDEF s_aOptions[] =
@@ -3524,24 +3567,25 @@
 
             default:
-                return RTGetOptPrintError(ch, &ValueUnion);
-                break;
+                return errorGetOptEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_PROCESS, ch, &ValueUnion);
         }
     }
 
     if (vecPID.empty())
-        return errorSyntax(USAGE_GUESTCONTROL, "At least one PID must be specified to kill!");
-    else if (   strSessionName.isEmpty()
-             && ulSessionID == UINT32_MAX)
-    {
-        return errorSyntax(USAGE_GUESTCONTROL, "No session ID specified!");
-    }
-    else if (   !strSessionName.isEmpty()
-             && ulSessionID != UINT32_MAX)
-    {
-        return errorSyntax(USAGE_GUESTCONTROL, "Either session ID or name (pattern) must be specified");
-    }
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_PROCESS,
+                             "At least one PID must be specified to kill!");
+
+    if (   strSessionName.isEmpty()
+        && ulSessionID == UINT32_MAX)
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_PROCESS,
+                             "No session ID specified!");
+
+    if (   !strSessionName.isEmpty()
+        && ulSessionID != UINT32_MAX)
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_PROCESS,
+                             "Either session ID or name (pattern) must be specified");
 
     if (RT_FAILURE(vrc))
-        return errorSyntax(USAGE_GUESTCONTROL, "Invalid parameters specified");
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_PROCESS,
+                             "Invalid parameters specified");
 
     HRESULT rc = S_OK;
@@ -3646,5 +3690,6 @@
 
     if (pCtx->iArgc < 1)
-        return errorSyntax(USAGE_GUESTCONTROL, "Must specify an action");
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_PROCESS,
+                             "Must specify an action");
 
     /** Use RTGetOpt here when handling command line args gets more complex. */
@@ -3658,5 +3703,6 @@
     }
 
-    return errorSyntax(USAGE_GUESTCONTROL, "Invalid process action '%s'", pCtx->ppaArgv[0]);
+    return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_PROCESS,
+                         "Invalid process action '%s'", pCtx->ppaArgv[0]);
 }
 
@@ -3666,5 +3712,6 @@
 
     if (pCtx->iArgc < 1)
-        return errorSyntax(USAGE_GUESTCONTROL, "Must specify at least a session to close");
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_SESSION,
+                             "Must specify at least a session to close");
 
     static const RTGETOPTDEF s_aOptions[] =
@@ -3706,6 +3753,5 @@
 
             default:
-                return RTGetOptPrintError(ch, &ValueUnion);
-                break;
+                return errorGetOptEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_SESSION, ch, &ValueUnion);
         }
     }
@@ -3713,12 +3759,11 @@
     if (   strSessionName.isEmpty()
         && ulSessionID == UINT32_MAX)
-    {
-        return errorSyntax(USAGE_GUESTCONTROL, "No session ID specified!");
-    }
-    else if (   !strSessionName.isEmpty()
-             && ulSessionID != UINT32_MAX)
-    {
-        return errorSyntax(USAGE_GUESTCONTROL, "Either session ID or name (pattern) must be specified");
-    }
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_SESSION,
+                             "No session ID specified!");
+
+    if (   !strSessionName.isEmpty()
+        && ulSessionID != UINT32_MAX)
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_SESSION,
+                             "Either session ID or name (pattern) must be specified");
 
     HRESULT rc = S_OK;
@@ -3786,5 +3831,6 @@
 
     if (pCtx->iArgc < 1)
-        return errorSyntax(USAGE_GUESTCONTROL, "Must specify an action");
+        return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_SESSION,
+                             "Must specify an action");
 
     /** Use RTGetOpt here when handling command line args gets more complex. */
@@ -3798,5 +3844,6 @@
     }
 
-    return errorSyntax(USAGE_GUESTCONTROL, "Invalid session action '%s'", pCtx->ppaArgv[0]);
+    return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_SESSION,
+                         "Invalid session action '%s'", pCtx->ppaArgv[0]);
 }
 
@@ -3825,6 +3872,5 @@
 
             default:
-                return RTGetOptPrintError(ch, &ValueUnion);
-                break;
+                return errorGetOptEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_WATCH, ch, &ValueUnion);
         }
     }
@@ -3908,33 +3954,58 @@
 
     uint32_t uCmdCtxFlags = 0;
+    uint32_t uUsage;
     GCTLCMD gctlCmd;
     if (   !RTStrICmp(pArg->argv[1], "exec")
         || !RTStrICmp(pArg->argv[1], "execute"))
+    {
         gctlCmd.pfnHandler = handleCtrlProcessExec;
+        uUsage = USAGE_GSTCTRL_EXEC;
+    }
     else if (!RTStrICmp(pArg->argv[1], "copyfrom"))
+    {
         gctlCmd.pfnHandler = handleCtrlCopyFrom;
+        uUsage = USAGE_GSTCTRL_COPYFROM;
+    }
     else if (   !RTStrICmp(pArg->argv[1], "copyto")
              || !RTStrICmp(pArg->argv[1], "cp"))
+    {
         gctlCmd.pfnHandler = handleCtrlCopyTo;
+        uUsage = USAGE_GSTCTRL_COPYTO;
+    }
     else if (   !RTStrICmp(pArg->argv[1], "createdirectory")
              || !RTStrICmp(pArg->argv[1], "createdir")
              || !RTStrICmp(pArg->argv[1], "mkdir")
              || !RTStrICmp(pArg->argv[1], "md"))
+    {
         gctlCmd.pfnHandler = handleCtrlCreateDirectory;
+        uUsage = USAGE_GSTCTRL_CREATEDIR;
+    }
     else if (   !RTStrICmp(pArg->argv[1], "removedirectory")
              || !RTStrICmp(pArg->argv[1], "removedir")
              || !RTStrICmp(pArg->argv[1], "rmdir"))
+    {
         gctlCmd.pfnHandler = handleCtrlRemoveDirectory;
+        uUsage = USAGE_GSTCTRL_REMOVEDIR;
+    }
     else if (   !RTStrICmp(pArg->argv[1], "rm")
              || !RTStrICmp(pArg->argv[1], "removefile"))
+    {
         gctlCmd.pfnHandler = handleCtrlRemoveFile;
+        uUsage = USAGE_GSTCTRL_REMOVEFILE;
+    }
     else if (   !RTStrICmp(pArg->argv[1], "ren")
              || !RTStrICmp(pArg->argv[1], "rename")
              || !RTStrICmp(pArg->argv[1], "mv"))
+    {
         gctlCmd.pfnHandler = handleCtrlRename;
+        uUsage = USAGE_GSTCTRL_RENAME;
+    }
     else if (   !RTStrICmp(pArg->argv[1], "createtemporary")
              || !RTStrICmp(pArg->argv[1], "createtemp")
              || !RTStrICmp(pArg->argv[1], "mktemp"))
+    {
         gctlCmd.pfnHandler = handleCtrlCreateTemp;
+        uUsage = USAGE_GSTCTRL_CREATETEMP;
+    }
     else if (   !RTStrICmp(pArg->argv[1], "kill")    /* Linux. */
              || !RTStrICmp(pArg->argv[1], "pkill")   /* Solaris / *BSD. */
@@ -3945,8 +4016,12 @@
                      | CTLCMDCTX_FLAGS_NO_SIGNAL_HANDLER;
         gctlCmd.pfnHandler = handleCtrlProcessClose;
+        uUsage = USAGE_GSTCTRL_KILL;
     }
     /** @todo Implement "killall"? */
     else if (   !RTStrICmp(pArg->argv[1], "stat"))
+    {
         gctlCmd.pfnHandler = handleCtrlStat;
+        uUsage = USAGE_GSTCTRL_STAT;
+    }
     else if (   !RTStrICmp(pArg->argv[1], "updateadditions")
              || !RTStrICmp(pArg->argv[1], "updateadds"))
@@ -3955,4 +4030,5 @@
                      | CTLCMDCTX_FLAGS_NO_SIGNAL_HANDLER;
         gctlCmd.pfnHandler = handleCtrlUpdateAdditions;
+        uUsage = USAGE_GSTCTRL_UPDATEADDS;
     }
     else if (   !RTStrICmp(pArg->argv[1], "list"))
@@ -3961,4 +4037,5 @@
                      | CTLCMDCTX_FLAGS_NO_SIGNAL_HANDLER;
         gctlCmd.pfnHandler = handleCtrlList;
+        uUsage = USAGE_GSTCTRL_LIST;
     }
     else if (   !RTStrICmp(pArg->argv[1], "session"))
@@ -3967,4 +4044,5 @@
                      | CTLCMDCTX_FLAGS_NO_SIGNAL_HANDLER;
         gctlCmd.pfnHandler = handleCtrlSession;
+        uUsage = USAGE_GSTCTRL_SESSION;
     }
     else if (   !RTStrICmp(pArg->argv[1], "process"))
@@ -3973,4 +4051,5 @@
                      | CTLCMDCTX_FLAGS_NO_SIGNAL_HANDLER;
         gctlCmd.pfnHandler = handleCtrlProcess;
+        uUsage = USAGE_GSTCTRL_PROCESS;
     }
     else if (   !RTStrICmp(pArg->argv[1], "watch"))
@@ -3979,4 +4058,5 @@
                      | CTLCMDCTX_FLAGS_NO_SIGNAL_HANDLER;
         gctlCmd.pfnHandler = handleCtrlWatch;
+        uUsage = USAGE_GSTCTRL_WATCH;
     }
     else
@@ -3986,5 +4066,5 @@
     RT_ZERO(cmdCtx);
 
-    RTEXITCODE rcExit = ctrlInitVM(pArg, &cmdCtx, uCmdCtxFlags);
+    RTEXITCODE rcExit = ctrlInitVM(pArg, &cmdCtx, uCmdCtxFlags, uUsage);
     if (rcExit == RTEXITCODE_SUCCESS)
     {
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 49620)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 49621)
@@ -47,5 +47,5 @@
 }
 
-void printUsage(USAGECATEGORY u64Cmd, PRTSTREAM pStrm)
+void printUsage(USAGECATEGORY fCategory, uint32_t fSubCategory, PRTSTREAM pStrm)
 {
     bool fDumpOpts = false;
@@ -81,5 +81,5 @@
 #endif
 
-    if (u64Cmd == USAGE_DUMPOPTS)
+    if (fCategory == USAGE_DUMPOPTS)
     {
         fDumpOpts = true;
@@ -90,5 +90,5 @@
         fDarwin = true;
         fVBoxSDL = true;
-        u64Cmd = USAGE_ALL;
+        fCategory = USAGE_ALL;
     }
 
@@ -97,5 +97,5 @@
                  "\n");
 
-    if (u64Cmd == USAGE_ALL)
+    if (fCategory == USAGE_ALL)
         RTStrmPrintf(pStrm,
                      "  VBoxManage [<general option>] <command>\n"
@@ -111,5 +111,5 @@
     const char *pcszSep1 = " ";
     const char *pcszSep2 = "         ";
-    if (u64Cmd != USAGE_ALL)
+    if (fCategory != USAGE_ALL)
     {
         pcszSep1 = "VBoxManage";
@@ -119,5 +119,5 @@
 #define SEP pcszSep1, pcszSep2
 
-    if (u64Cmd & USAGE_LIST)
+    if (fCategory & USAGE_LIST)
         RTStrmPrintf(pStrm,
                            "%s list [--long|-l]%s vms|runningvms|ostypes|hostdvds|hostfloppies|\n"
@@ -132,5 +132,5 @@
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_SHOWVMINFO)
+    if (fCategory & USAGE_SHOWVMINFO)
         RTStrmPrintf(pStrm,
                            "%s showvminfo %s      <uuid|vmname> [--details]\n"
@@ -139,15 +139,15 @@
                      "\n", SEP, SEP);
 
-    if (u64Cmd & USAGE_REGISTERVM)
+    if (fCategory & USAGE_REGISTERVM)
         RTStrmPrintf(pStrm,
                            "%s registervm %s      <filename>\n"
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_UNREGISTERVM)
+    if (fCategory & USAGE_UNREGISTERVM)
         RTStrmPrintf(pStrm,
                            "%s unregistervm %s    <uuid|vmname> [--delete]\n"
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_CREATEVM)
+    if (fCategory & USAGE_CREATEVM)
         RTStrmPrintf(pStrm,
                            "%s createvm %s        --name <name>\n"
@@ -159,5 +159,5 @@
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_MODIFYVM)
+    if (fCategory & USAGE_MODIFYVM)
     {
         RTStrmPrintf(pStrm,
@@ -382,5 +382,5 @@
     }
 
-    if (u64Cmd & USAGE_CLONEVM)
+    if (fCategory & USAGE_CLONEVM)
         RTStrmPrintf(pStrm,
                            "%s clonevm %s         <uuid|vmname>\n"
@@ -396,5 +396,5 @@
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_IMPORTAPPLIANCE)
+    if (fCategory & USAGE_IMPORTAPPLIANCE)
         RTStrmPrintf(pStrm,
                            "%s import %s          <ovfname/ovaname>\n"
@@ -405,5 +405,5 @@
                      "                             for a particular OVF)\n\n", SEP);
 
-    if (u64Cmd & USAGE_EXPORTAPPLIANCE)
+    if (fCategory & USAGE_EXPORTAPPLIANCE)
         RTStrmPrintf(pStrm,
                            "%s export %s          <machines> --output|-o <name>.<ovf/ova>\n"
@@ -422,5 +422,5 @@
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_STARTVM)
+    if (fCategory & USAGE_STARTVM)
     {
         RTStrmPrintf(pStrm,
@@ -434,5 +434,5 @@
     }
 
-    if (u64Cmd & USAGE_CONTROLVM)
+    if (fCategory & USAGE_CONTROLVM)
     {
         RTStrmPrintf(pStrm,
@@ -487,15 +487,15 @@
     }
 
-    if (u64Cmd & USAGE_DISCARDSTATE)
+    if (fCategory & USAGE_DISCARDSTATE)
         RTStrmPrintf(pStrm,
                            "%s discardstate %s    <uuid|vmname>\n"
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_ADOPTSTATE)
+    if (fCategory & USAGE_ADOPTSTATE)
         RTStrmPrintf(pStrm,
                            "%s adoptstate %s      <uuid|vmname> <state_file>\n"
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_SNAPSHOT)
+    if (fCategory & USAGE_SNAPSHOT)
         RTStrmPrintf(pStrm,
                            "%s snapshot %s        <uuid|vmname>\n"
@@ -511,5 +511,5 @@
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_CLOSEMEDIUM)
+    if (fCategory & USAGE_CLOSEMEDIUM)
         RTStrmPrintf(pStrm,
                            "%s closemedium %s     disk|dvd|floppy <uuid|filename>\n"
@@ -517,5 +517,5 @@
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_STORAGEATTACH)
+    if (fCategory & USAGE_STORAGEATTACH)
         RTStrmPrintf(pStrm,
                            "%s storageattach %s   <uuid|vmname>\n"
@@ -549,5 +549,5 @@
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_STORAGECONTROLLER)
+    if (fCategory & USAGE_STORAGECONTROLLER)
         RTStrmPrintf(pStrm,
                            "%s storagectl %s      <uuid|vmname>\n"
@@ -562,5 +562,5 @@
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_BANDWIDTHCONTROL)
+    if (fCategory & USAGE_BANDWIDTHCONTROL)
         RTStrmPrintf(pStrm,
                            "%s bandwidthctl %s    <uuid|vmname>\n"
@@ -575,10 +575,10 @@
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_SHOWHDINFO)
+    if (fCategory & USAGE_SHOWHDINFO)
         RTStrmPrintf(pStrm,
                            "%s showhdinfo %s      <uuid|filename>\n"
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_CREATEHD)
+    if (fCategory & USAGE_CREATEHD)
         RTStrmPrintf(pStrm,
                            "%s createhd %s        --filename <filename>\n"
@@ -589,5 +589,5 @@
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_MODIFYHD)
+    if (fCategory & USAGE_MODIFYHD)
         RTStrmPrintf(pStrm,
                            "%s modifyhd %s        <uuid|filename>\n"
@@ -600,5 +600,5 @@
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_CLONEHD)
+    if (fCategory & USAGE_CLONEHD)
         RTStrmPrintf(pStrm,
                            "%s clonehd %s         <uuid|inputfile> <uuid|outputfile>\n"
@@ -608,5 +608,5 @@
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_CONVERTFROMRAW)
+    if (fCategory & USAGE_CONVERTFROMRAW)
         RTStrmPrintf(pStrm,
                            "%s convertfromraw %s  <filename> <outputfile>\n"
@@ -620,5 +620,5 @@
                      "\n", SEP, SEP);
 
-    if (u64Cmd & USAGE_GETEXTRADATA)
+    if (fCategory & USAGE_GETEXTRADATA)
         RTStrmPrintf(pStrm,
                            "%s getextradata %s    global|<uuid|vmname>\n"
@@ -626,5 +626,5 @@
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_SETEXTRADATA)
+    if (fCategory & USAGE_SETEXTRADATA)
         RTStrmPrintf(pStrm,
                            "%s setextradata %s    global|<uuid|vmname>\n"
@@ -633,5 +633,5 @@
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_SETPROPERTY)
+    if (fCategory & USAGE_SETPROPERTY)
         RTStrmPrintf(pStrm,
                            "%s setproperty %s     machinefolder default|<folder> |\n"
@@ -645,5 +645,5 @@
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_USBFILTER_ADD)
+    if (fCategory & USAGE_USBFILTER_ADD)
         RTStrmPrintf(pStrm,
                            "%s usbfilter %s       add <index,0-N>\n"
@@ -662,5 +662,5 @@
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_USBFILTER_MODIFY)
+    if (fCategory & USAGE_USBFILTER_MODIFY)
         RTStrmPrintf(pStrm,
                            "%s usbfilter %s       modify <index,0-N>\n"
@@ -679,5 +679,5 @@
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_USBFILTER_REMOVE)
+    if (fCategory & USAGE_USBFILTER_REMOVE)
         RTStrmPrintf(pStrm,
                            "%s usbfilter %s       remove <index,0-N>\n"
@@ -685,5 +685,5 @@
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_SHAREDFOLDER_ADD)
+    if (fCategory & USAGE_SHAREDFOLDER_ADD)
         RTStrmPrintf(pStrm,
                            "%s sharedfolder %s    add <uuid|vmname>\n"
@@ -692,5 +692,5 @@
                      "\n", SEP);
 
-    if (u64Cmd & USAGE_SHAREDFOLDER_REMOVE)
+    if (fCategory & USAGE_SHAREDFOLDER_REMOVE)
         RTStrmPrintf(pStrm,
                            "%s sharedfolder %s    remove <uuid|vmname>\n"
@@ -699,14 +699,14 @@
 
 #ifdef VBOX_WITH_GUEST_PROPS
-    if (u64Cmd & USAGE_GUESTPROPERTY)
+    if (fCategory & USAGE_GUESTPROPERTY)
         usageGuestProperty(pStrm, SEP);
 #endif /* VBOX_WITH_GUEST_PROPS defined */
 
 #ifdef VBOX_WITH_GUEST_CONTROL
-    if (u64Cmd & USAGE_GUESTCONTROL)
-        usageGuestControl(pStrm, SEP);
+    if (fCategory & USAGE_GUESTCONTROL)
+        usageGuestControl(pStrm, SEP, fSubCategory);
 #endif /* VBOX_WITH_GUEST_CONTROL defined */
 
-    if (u64Cmd & USAGE_DEBUGVM)
+    if (fCategory & USAGE_DEBUGVM)
     {
         RTStrmPrintf(pStrm,
@@ -730,5 +730,5 @@
                      "\n", SEP);
     }
-    if (u64Cmd & USAGE_METRICS)
+    if (fCategory & USAGE_METRICS)
         RTStrmPrintf(pStrm,
                            "%s metrics %s         list [*|host|<vmname> [<metric_list>]]\n"
@@ -755,5 +755,5 @@
 
 #if defined(VBOX_WITH_NAT_SERVICE)
-    if (u64Cmd & USAGE_NATNETWORK)
+    if (fCategory & USAGE_NATNETWORK)
     {
         RTStrmPrintf(pStrm,
@@ -786,5 +786,5 @@
 
 #if defined(VBOX_WITH_NETFLT)
-    if (u64Cmd & USAGE_HOSTONLYIFS)
+    if (fCategory & USAGE_HOSTONLYIFS)
     {
         RTStrmPrintf(pStrm,
@@ -801,5 +801,5 @@
 #endif
 
-    if (u64Cmd & USAGE_DHCPSERVER)
+    if (fCategory & USAGE_DHCPSERVER)
     {
         RTStrmPrintf(pStrm,
@@ -819,5 +819,5 @@
                      "\n", SEP, SEP);
     }
-    if (u64Cmd & USAGE_EXTPACK)
+    if (fCategory & USAGE_EXTPACK)
     {
         RTStrmPrintf(pStrm,
@@ -833,5 +833,5 @@
  * @returns RTEXITCODE_SYNTAX.
  */
-RTEXITCODE errorSyntax(USAGECATEGORY u64Cmd, const char *pszFormat, ...)
+RTEXITCODE errorSyntax(USAGECATEGORY fCategory, const char *pszFormat, ...)
 {
     va_list args;
@@ -839,7 +839,7 @@
 #ifndef VBOX_ONLY_DOCS
     if (g_fInternalMode)
-        printUsageInternal(u64Cmd, g_pStdErr);
+        printUsageInternal(fCategory, g_pStdErr);
     else
-        printUsage(u64Cmd, g_pStdErr);
+        printUsage(fCategory, ~0U, g_pStdErr);
 #endif /* !VBOX_ONLY_DOCS */
     va_start(args, pszFormat);
@@ -847,4 +847,85 @@
     va_end(args);
     return RTEXITCODE_SYNTAX;
+}
+
+/**
+ * Print a usage synopsis and the syntax error message.
+ * @returns RTEXITCODE_SYNTAX.
+ */
+RTEXITCODE errorSyntaxEx(USAGECATEGORY fCategory, uint32_t fSubCategory, const char *pszFormat, ...)
+{
+    va_list args;
+    showLogo(g_pStdErr); // show logo even if suppressed
+#ifndef VBOX_ONLY_DOCS
+    if (g_fInternalMode)
+        printUsageInternal(fCategory, g_pStdErr);
+    else
+        printUsage(fCategory, fSubCategory, g_pStdErr);
+#endif /* !VBOX_ONLY_DOCS */
+    va_start(args, pszFormat);
+    RTStrmPrintf(g_pStdErr, "\nSyntax error: %N\n", pszFormat, &args);
+    va_end(args);
+    return RTEXITCODE_SYNTAX;
+}
+
+/**
+ * errorSyntax for RTGetOpt users.
+ *
+ * @returns RTEXITCODE_SYNTAX.
+ *
+ * @param   fCategory          The usage category of the command.
+ * @param   fSubCategory         The usage sub-category of the command.
+ * @param   rc              The RTGetOpt return code.
+ * @param   pValueUnion     The value union.
+ */
+RTEXITCODE errorGetOptEx(USAGECATEGORY fCategory, uint32_t fSubCategory, int rc, union RTGETOPTUNION const *pValueUnion)
+{
+    /*
+     * Check if it is an unhandled standard option.
+     */
+    if (rc == 'V')
+    {
+        RTPrintf("%sr%d\n", VBOX_VERSION_STRING, RTBldCfgRevision());
+        return RTEXITCODE_SUCCESS;
+    }
+
+    if (rc == 'h')
+    {
+        showLogo(g_pStdErr);
+#ifndef VBOX_ONLY_DOCS
+        if (g_fInternalMode)
+            printUsageInternal(fCategory, g_pStdOut);
+        else
+            printUsage(fCategory, fSubCategory, g_pStdOut);
+#endif
+        return RTEXITCODE_SUCCESS;
+    }
+
+    /*
+     * General failure.
+     */
+    showLogo(g_pStdErr); // show logo even if suppressed
+#ifndef VBOX_ONLY_DOCS
+    if (g_fInternalMode)
+        printUsageInternal(fCategory, g_pStdErr);
+    else
+        printUsage(fCategory, fSubCategory, g_pStdErr);
+#endif /* !VBOX_ONLY_DOCS */
+
+    if (rc == VINF_GETOPT_NOT_OPTION)
+        return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid parameter '%s'", pValueUnion->psz);
+    if (rc > 0)
+    {
+        if (RT_C_IS_PRINT(rc))
+            return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid option -%c", rc);
+        return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid option case %i", rc);
+    }
+    if (rc == VERR_GETOPT_UNKNOWN_OPTION)
+        return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown option: %s", pValueUnion->psz);
+    if (rc == VERR_GETOPT_INVALID_ARGUMENT_FORMAT)
+        return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid argument format: %s", pValueUnion->psz);
+    if (pValueUnion->pDef)
+        return RTMsgErrorExit(RTEXITCODE_SYNTAX, "%s: %Rrs", pValueUnion->pDef->pszLong, rc);
+    return RTMsgErrorExit(RTEXITCODE_SYNTAX, "%Rrs", rc);
 }
 
@@ -858,53 +939,7 @@
  * @param   pValueUnion     The value union.
  */
-RTEXITCODE errorGetOpt(USAGECATEGORY fUsageCategory, int rc, union RTGETOPTUNION const *pValueUnion)
+RTEXITCODE errorGetOpt(USAGECATEGORY fCategory, int rc, union RTGETOPTUNION const *pValueUnion)
 {
-    /*
-     * Check if it is an unhandled standard option.
-     */
-    if (rc == 'V')
-    {
-        RTPrintf("%sr%d\n", VBOX_VERSION_STRING, RTBldCfgRevision());
-        return RTEXITCODE_SUCCESS;
-    }
-
-    if (rc == 'h')
-    {
-        showLogo(g_pStdErr);
-#ifndef VBOX_ONLY_DOCS
-        if (g_fInternalMode)
-            printUsageInternal(fUsageCategory, g_pStdOut);
-        else
-            printUsage(fUsageCategory, g_pStdOut);
-#endif
-        return RTEXITCODE_SUCCESS;
-    }
-
-    /*
-     * General failure.
-     */
-    showLogo(g_pStdErr); // show logo even if suppressed
-#ifndef VBOX_ONLY_DOCS
-    if (g_fInternalMode)
-        printUsageInternal(fUsageCategory, g_pStdErr);
-    else
-        printUsage(fUsageCategory, g_pStdErr);
-#endif /* !VBOX_ONLY_DOCS */
-
-    if (rc == VINF_GETOPT_NOT_OPTION)
-        return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid parameter '%s'", pValueUnion->psz);
-    if (rc > 0)
-    {
-        if (RT_C_IS_PRINT(rc))
-            return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid option -%c", rc);
-        return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid option case %i", rc);
-    }
-    if (rc == VERR_GETOPT_UNKNOWN_OPTION)
-        return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown option: %s", pValueUnion->psz);
-    if (rc == VERR_GETOPT_INVALID_ARGUMENT_FORMAT)
-        return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid argument format: %s", pValueUnion->psz);
-    if (pValueUnion->pDef)
-        return RTMsgErrorExit(RTEXITCODE_SYNTAX, "%s: %Rrs", pValueUnion->pDef->pszLong, rc);
-    return RTMsgErrorExit(RTEXITCODE_SYNTAX, "%Rrs", rc);
+    return errorGetOptEx(fCategory, ~0U, rc, pValueUnion);
 }
 
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp	(revision 49620)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp	(revision 49621)
@@ -1027,5 +1027,5 @@
                             strAttachment = "nat";
                             strNatSettings = Utf8StrFmt("mtu=\"%d\"\nsockSnd=\"%d\"\nsockRcv=\"%d\"\ntcpWndSnd=\"%d\"\ntcpWndRcv=\"%d\"\n",
-                                mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64 , tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
+                                mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64, tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
                         }
                         else
@@ -1033,5 +1033,5 @@
                             strAttachment = "NAT";
                             strNatSettings = Utf8StrFmt("NIC %d Settings:  MTU: %d, Socket (send: %d, receive: %d), TCP Window (send:%d, receive: %d)\n",
-                                currentNIC + 1, mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64 , tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
+                                currentNIC + 1, mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64, tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
                         }
                         break;
