diff --git a/src/OpenFOAM/global/argList/argList.C b/src/OpenFOAM/global/argList/argList.C
index 845b852e95ba12effcba34cdfe05410831623e0d..e4669c657c116817bea78b4af2fb7c656d2b4973 100644
--- a/src/OpenFOAM/global/argList/argList.C
+++ b/src/OpenFOAM/global/argList/argList.C
@@ -40,13 +40,18 @@ License
 Foam::SLList<Foam::string>    Foam::argList::validArgs;
 Foam::HashTable<Foam::string> Foam::argList::validOptions;
 Foam::HashTable<Foam::string> Foam::argList::validParOptions;
-bool Foam::argList::bannerEnabled(true);
+Foam::HashTable<Foam::string> Foam::argList::optionUsage;
+bool Foam::argList::bannerEnabled = true;
 
 
 Foam::argList::initValidTables::initValidTables()
 {
-    validOptions.set("case", "dir");
-    validOptions.set("parallel", "");
+    argList::addOption
+    (
+        "case", "DIR",
+        "specify alternate case directory, default is the cwd"
+    );
+    argList::addBoolOption("parallel", "run in parallel");
     validParOptions.set("parallel", "");
 
     Pstream::addValidParOptions(validParOptions);
@@ -56,6 +61,93 @@ Foam::argList::initValidTables::initValidTables()
 Foam::argList::initValidTables dummyInitValidTables;
 
 
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+void Foam::argList::addBoolOption
+(
+    const word& opt,
+    const string& usage
+)
+{
+    addOption(opt, "", usage);
+}
+
+
+void Foam::argList::addOption
+(
+    const word& opt,
+    const string& param,
+    const string& usage
+)
+{
+    validOptions.set(opt, param);
+    if (!usage.empty())
+    {
+        optionUsage.set(opt, usage);
+    }
+}
+
+
+void Foam::argList::addUsage
+(
+    const word& opt,
+    const string& usage
+)
+{
+    if (usage.empty())
+    {
+        optionUsage.erase(opt);
+    }
+    else
+    {
+        optionUsage.set(opt, usage);
+    }
+}
+
+
+void Foam::argList::removeOption(const word& opt)
+{
+    validOptions.erase(opt);
+    optionUsage.erase(opt);
+}
+
+
+void Foam::argList::noBanner()
+{
+    bannerEnabled = false;
+}
+
+
+void Foam::argList::noParallel()
+{
+    optionUsage.erase("parallel");
+    validOptions.erase("parallel");
+    validParOptions.clear();
+}
+
+
+void Foam::argList::printOptionUsage
+(
+    const label location,
+    const label padWidth,
+    const string& str
+)
+{
+    if (!str.empty())
+    {
+        for (label i = location; i < padWidth; ++i)
+        {
+            Info<<' ';
+        }
+        // we could also add text wrapping if desired
+        Info<<"    " << str.c_str();
+    }
+    Info<< nl;
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
 // convert argv -> args_
 // transform sequences with "(" ... ")" into string lists in the process
 bool Foam::argList::regroupArgv(int& argc, char**& argv)
@@ -70,14 +162,14 @@ bool Foam::argList::regroupArgv(int& argc, char**& argv)
     {
         if (strcmp(argv[argI], "(") == 0)
         {
-            listDepth++;
+            ++listDepth;
             tmpString += "(";
         }
         else if (strcmp(argv[argI], ")") == 0)
         {
             if (listDepth)
             {
-                listDepth--;
+                --listDepth;
                 tmpString += ")";
                 if (listDepth == 0)
                 {
@@ -114,19 +206,12 @@ bool Foam::argList::regroupArgv(int& argc, char**& argv)
 }
 
 
-// get rootPath_ / globalCase_ from one of the following forms
-//   * [-case dir]
-//   * cwd
-//
-// Also export FOAM_CASE and FOAM_CASENAME environment variables
-// so they can be used immediately (eg, in decomposeParDict)
-//
 void Foam::argList::getRootCase()
 {
     fileName casePath;
 
     // [-case dir] specified
-    HashTable<string>::iterator iter = options_.find("case");
+    HashTable<string>::const_iterator iter = options_.find("case");
 
     if (iter != options_.end())
     {
@@ -173,14 +258,6 @@ void Foam::argList::getRootCase()
         setEnv("FOAM_CASE", casePath, true);
         setEnv("FOAM_CASENAME", casePath.name(), true);
     }
-
-
-}
-
-
-Foam::stringList::subList Foam::argList::additionalArgs() const
-{
-    return stringList::subList(args_, args_.size() - 1, 1);
 }
 
 
@@ -198,7 +275,7 @@ Foam::argList::argList
     options_(argc)
 {
     // Check if this run is a parallel run by searching for any parallel option
-    // If found call runPar (might filter argv)
+    // If found call runPar which might filter argv
     for (int argI = 0; argI < argc; argI++)
     {
         if (argv[argI][0] == '-')
@@ -246,13 +323,14 @@ Foam::argList::argList
                 )
             )
             {
-                argI++;
+                ++argI;
                 if (argI >= args_.size())
                 {
                     FatalError
-                        << "option " << "'-" << optionName << '\''
-                        << " requires an argument"
-                        << exit(FatalError);
+                        <<"Option '-" << optionName
+                        << "' requires an argument" << endl;
+                    printUsage();
+                    FatalError.exit();
                 }
 
                 argListString += ' ';
@@ -270,7 +348,7 @@ Foam::argList::argList
             {
                 args_[nArgs] = args_[argI];
             }
-            nArgs++;
+            ++nArgs;
         }
     }
 
@@ -412,8 +490,8 @@ Foam::argList::argList
                 bool hadCaseOpt = options_.found("case");
                 for
                 (
-                    int slave=Pstream::firstSlave();
-                    slave<=Pstream::lastSlave();
+                    int slave = Pstream::firstSlave();
+                    slave <= Pstream::lastSlave();
                     slave++
                 )
                 {
@@ -465,8 +543,8 @@ Foam::argList::argList
                 // Distribute the master's argument list (unaltered)
                 for
                 (
-                    int slave=Pstream::firstSlave();
-                    slave<=Pstream::lastSlave();
+                    int slave = Pstream::firstSlave();
+                    slave <= Pstream::lastSlave();
                     slave++
                 )
                 {
@@ -510,8 +588,8 @@ Foam::argList::argList
             label procI = 0;
             for
             (
-                int slave=Pstream::firstSlave();
-                slave<=Pstream::lastSlave();
+                int slave = Pstream::firstSlave();
+                slave <= Pstream::lastSlave();
                 slave++
             )
             {
@@ -580,53 +658,104 @@ Foam::argList::~argList()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-void Foam::argList::noBanner()
-{
-    bannerEnabled = false;
-}
-
-
-void Foam::argList::noParallel()
+Foam::stringList::subList Foam::argList::additionalArgs() const
 {
-    validOptions.erase("parallel");
+    return stringList::subList(args_, args_.size() - 1, 1);
 }
 
 
 void Foam::argList::printUsage() const
 {
-    Info<< nl
-        << "Usage: " << executable_;
+    Info<< "\nUsage: " << executable_ << " [OPTIONS]";
 
-    for
-    (
-        SLList<string>::iterator iter = validArgs.begin();
-        iter != validArgs.end();
-        ++iter
-    )
+    forAllConstIter(SLList<string>, validArgs, iter)
     {
         Info<< " <" << iter().c_str() << '>';
     }
 
-    for
-    (
-        HashTable<string>::iterator iter = validOptions.begin();
-        iter != validOptions.end();
-        ++iter
-    )
+    Info<< "\noptions:\n";
+
+    // min is length of the -srcDoc option
+    // first get the length of option + param
+    label padWidth = 6;
+
+    forAllConstIter(HashTable<string>, validOptions, iter)
     {
-        Info<< " [-" << iter.key();
+        label len = iter().size();
+        if (len)
+        {
+            len++;   // space between option and param
+        }
+
+        len += iter.key().size();
+        if (padWidth < len)
+        {
+            padWidth = len;
+        }
+    }
+
+    padWidth += 3;  // include leading "  -"
+
+    wordList opts = validOptions.sortedToc();
+    forAll(opts, optI)
+    {
+        const word& optionName = opts[optI];
+
+        HashTable<string>::const_iterator iter = validOptions.find(optionName);
+        Info<< "  -" << optionName;
+        label len = optionName.size() + 3;  // include leading "  -"
 
         if (iter().size())
         {
+            len += iter().size() + 1; // include space between option and param
             Info<< ' ' << iter().c_str();
         }
 
-        Info<< ']';
+        HashTable<string>::const_iterator usageIter =
+            optionUsage.find(optionName);
+
+        if (usageIter != optionUsage.end())
+        {
+            printOptionUsage
+            (
+                len,
+                padWidth,
+                usageIter()
+            );
+        }
+        else
+        {
+            Info<< nl;
+        }
     }
 
-    // place help/doc/srcDoc options of the way at the end,
-    // but with an extra space to separate it a little
-    Info<< "  [-help] [-doc] [-srcDoc]\n" << endl;
+    //
+    // place srcDoc/doc/help options at the end
+    //
+    Info<< "  -srcDoc";
+    printOptionUsage
+    (
+        9,
+        padWidth,
+        "display source code in browser"
+    );
+
+    Info<< "  -doc";
+    printOptionUsage
+    (
+        6,
+        padWidth,
+        "display application documentation in browser"
+    );
+
+    Info<< "  -help";
+    printOptionUsage
+    (
+        7,
+        padWidth,
+        "print the usage"
+    );
+    Info<< endl;
 }
 
 
diff --git a/src/OpenFOAM/global/argList/argList.H b/src/OpenFOAM/global/argList/argList.H
index 787621396852a4d8b07c50a22383c82dcb5312f7..43594b46f8576ea644c09c19ad36e1c4e761ffab 100644
--- a/src/OpenFOAM/global/argList/argList.H
+++ b/src/OpenFOAM/global/argList/argList.H
@@ -59,9 +59,10 @@ Description
 
 Note
     - Adjustment of the valid (mandatory) arguments
-      by directly manipulating the static member argList::validArgs.
+      by directly manipulating the argList::validArgs static member.
     - Adjustment of the valid options
-      by directly manipulating the static member argList::validOptions.
+      via the addOption/removeOption static methods or by directly
+      manipulating the argList::validOptions static member.
 
 SourceFiles
     argList.C
@@ -114,8 +115,22 @@ class argList
         sigSegv sigSegv_;
 
 
-    // Private member functions
+    // Private Member Functions
 
+        //- Helper function for printUsage
+        static void printOptionUsage
+        (
+            const label location,
+            const label padWidth,
+            const string& str
+        );
+
+        //- get rootPath_ / globalCase_ from one of the following forms
+        //   * [-case dir]
+        //   * cwd
+        //
+        // Also export FOAM_CASE and FOAM_CASENAME environment variables
+        // so they can be used immediately (eg, in decomposeParDict)
         void getRootCase();
 
         //- Transcribe argv into internal args_
@@ -136,6 +151,9 @@ public:
         //- A list of valid parallel options
         static HashTable<string> validParOptions;
 
+        //- Short usage information for validOptions
+        static HashTable<string> optionUsage;
+
         //! @cond ignoreDocumentation
         class initValidTables
         {
@@ -185,7 +203,7 @@ public:
             //- Return arguments
             inline const stringList& args() const;
 
-            //- Return additionl arguments,
+            //- Return additional arguments,
             //  i.e. those additional to the executable itself
             stringList::subList additionalArgs() const;
 
@@ -241,6 +259,32 @@ public:
 
         // Edit
 
+            //- Add to a bool option to validOptions with usage information
+            static void addBoolOption
+            (
+                const word& opt,
+                const string& usage = ""
+            );
+
+            //- Add to an option to validOptions with usage information
+            //  An option with an empty param is a bool option
+            static void addOption
+            (
+                const word& opt,
+                const string& param = "",
+                const string& usage = ""
+            );
+
+            //- Add option usage information to optionUsage
+            static void addUsage
+            (
+                const word& opt,
+                const string& usage
+            );
+
+            //- Remove option from validOptions and from optionUsage
+            static void removeOption(const word& opt);
+
             //- Disable emitting the banner information
             static void noBanner();