diff --git a/CMakeLists.txt b/CMakeLists.txt
index 89e8282986b5b04fa7ee6c8c8ffa1abf9a60855d..35282bcd507663a63c72cc9061c5d2220f04ad10 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -78,6 +78,7 @@ IF(NOT KWSYS_NAMESPACE)
   SET(KWSYS_USE_Process 1)
   SET(KWSYS_USE_RegularExpression 1)
   SET(KWSYS_USE_SystemTools 1)
+  SET(KWSYS_USE_CommandLineArguments 1)
 ENDIF(NOT KWSYS_NAMESPACE)
 
 #-----------------------------------------------------------------------------
@@ -248,12 +249,20 @@ IF(KWSYS_USE_SystemTools)
 ENDIF(KWSYS_USE_SystemTools)
 
 # Add selected C++ classes.
-FOREACH(c Directory RegularExpression SystemTools)
+FOREACH(c Directory RegularExpression SystemTools CommandLineArguments)
   IF(KWSYS_USE_${c})
     SET(KWSYS_CLASSES ${KWSYS_CLASSES} ${c})
   ENDIF(KWSYS_USE_${c})
 ENDFOREACH(c)
 
+IF(KWSYS_USE_CommandLineArguments)
+  IF(NOT ParaView_SOURCE_DIR)
+    IF(NOT KWSYS_STANDALONE)
+      MESSAGE("Command Line Arguments is experimental code for now")
+    ENDIF(NOT KWSYS_STANDALONE)
+  ENDIF(NOT ParaView_SOURCE_DIR)
+ENDIF(KWSYS_USE_CommandLineArguments)
+
 # Add selected C components.
 FOREACH(c Process Base64)
   IF(KWSYS_USE_${c})
@@ -411,9 +420,11 @@ IF(KWSYS_STANDALONE)
   ADD_EXECUTABLE(testIOS testIOS.cxx)
   ADD_EXECUTABLE(testProcess testProcess.c)
   ADD_EXECUTABLE(test1 test1.cxx)
+  ADD_EXECUTABLE(testCommandLineArguments testCommandLineArguments.cxx)
   TARGET_LINK_LIBRARIES(testIOS ${KWSYS_NAMESPACE})
   TARGET_LINK_LIBRARIES(testProcess ${KWSYS_NAMESPACE}_c)
   TARGET_LINK_LIBRARIES(test1 ${KWSYS_NAMESPACE})
+  TARGET_LINK_LIBRARIES(testCommandLineArguments ${KWSYS_NAMESPACE})
 
   IF(BUILD_TESTING)
     ADD_TEST(testProcess-1 testProcess 1)
diff --git a/CommandLineArguments.cxx b/CommandLineArguments.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8fa8af4e9476a5e4340624133daa0c2ee982331c
--- /dev/null
+++ b/CommandLineArguments.cxx
@@ -0,0 +1,591 @@
+/*=========================================================================
+
+  Program:   KWSys - Kitware System Library
+  Module:    CommandLineArguments.cxx
+
+  Copyright (c) Kitware, Inc., Insight Consortium.  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#include "kwsysPrivate.h"
+#include KWSYS_HEADER(CommandLineArguments.hxx)
+
+#include KWSYS_HEADER(Configure.hxx)
+
+#include KWSYS_HEADER(stl/vector)
+#include KWSYS_HEADER(stl/map)
+#include KWSYS_HEADER(stl/set)
+#include KWSYS_HEADER(ios/sstream)
+
+#include <stdio.h>
+
+namespace KWSYS_NAMESPACE
+{
+
+//----------------------------------------------------------------------------
+//============================================================================
+class CommandLineArgumentsString : public kwsys_stl::string 
+{
+public:
+  typedef kwsys_stl::string StdString;
+  CommandLineArgumentsString(): StdString() {}
+  CommandLineArgumentsString(const value_type* s): StdString(s) {}
+  CommandLineArgumentsString(const value_type* s, size_type n): StdString(s, n) {}
+  CommandLineArgumentsString(const StdString& s, size_type pos=0, size_type n=npos):
+    StdString(s, pos, n) {}
+};
+
+class CommandLineArgumentsVectorOfStrings : 
+  public kwsys_stl::vector<CommandLineArgumentsString> {};
+class CommandLineArgumentsSetOfStrings :
+  public kwsys_stl::set<CommandLineArgumentsString> {};
+class CommandLineArgumentsMapOfStrucs : 
+  public kwsys_stl::map<CommandLineArgumentsString,
+    CommandLineArguments::CallbackStructure> {};
+
+class CommandLineArgumentsInternal
+{
+public:
+  CommandLineArgumentsInternal()
+    {
+    this->UnknownArgumentCallback = 0;
+    this->ClientData = 0;
+    this->LastArgument = 0;
+    }
+
+  typedef CommandLineArgumentsVectorOfStrings VectorOfStrings;
+  typedef CommandLineArgumentsMapOfStrucs CallbacksMap;
+  typedef CommandLineArgumentsString String;
+  typedef CommandLineArgumentsSetOfStrings SetOfStrings;
+
+  VectorOfStrings Argv;
+  CallbacksMap Callbacks;
+
+  CommandLineArguments::ErrorCallbackType UnknownArgumentCallback;
+  void*             ClientData;
+
+  VectorOfStrings::size_type LastArgument;
+};
+//============================================================================
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+CommandLineArguments::CommandLineArguments()
+{
+  this->Internals = new CommandLineArguments::Internal;
+  this->Help = "";
+  this->LineLength = 80;
+}
+
+//----------------------------------------------------------------------------
+CommandLineArguments::~CommandLineArguments()
+{
+  delete this->Internals;
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::Initialize(int argc, char* argv[])
+{
+  int cc;
+
+  this->Initialize();
+  for ( cc = 1; cc < argc; cc ++ )
+    {
+    this->ProcessArgument(argv[cc]);
+    }
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::Initialize()
+{
+  this->Internals->Argv.clear();
+  this->Internals->LastArgument = 0;
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::ProcessArgument(const char* arg)
+{
+  this->Internals->Argv.push_back(arg);
+}
+
+//----------------------------------------------------------------------------
+int CommandLineArguments::Parse()
+{
+  CommandLineArguments::Internal::VectorOfStrings::size_type cc;
+  CommandLineArguments::Internal::VectorOfStrings matches;
+  for ( cc = 0; cc < this->Internals->Argv.size(); cc ++ )
+    {
+    matches.clear();
+    CommandLineArguments::Internal::String& arg = this->Internals->Argv[cc];
+    CommandLineArguments::Internal::CallbacksMap::iterator it;
+
+    // Does the argument match to any we know about?
+    for ( it = this->Internals->Callbacks.begin();
+      it != this->Internals->Callbacks.end();
+      it ++ )
+      {
+      const CommandLineArguments::Internal::String& parg = it->first;
+      CommandLineArguments::CallbackStructure *cs = &it->second;
+      if (cs->ArgumentType == CommandLineArguments::NO_ARGUMENT ||
+        cs->ArgumentType == CommandLineArguments::SPACE_ARGUMENT) 
+        {
+        if ( arg == parg )
+          {
+          matches.push_back(parg);
+          }
+        }
+      else if ( arg.find( parg ) == 0 )
+        {
+        matches.push_back(parg);
+        }
+      }
+    if ( matches.size() > 0 )
+      {
+      // Ok, we found one or more arguments that match what user specified.
+      // Let's find the longest one.
+      CommandLineArguments::Internal::VectorOfStrings::size_type kk;
+      CommandLineArguments::Internal::VectorOfStrings::size_type maxidx = 0;
+      CommandLineArguments::Internal::String::size_type maxlen = 0;
+      for ( kk = 0; kk < matches.size(); kk ++ )
+        {
+        if ( matches[kk].size() > maxlen )
+          {
+          maxlen = matches[kk].size();
+          maxidx = kk;
+          }
+        }
+      // So, the longest one is probably the right one. Now see if it has any
+      // additional value
+      const char* value = 0;
+      CommandLineArguments::CallbackStructure *cs 
+        = &this->Internals->Callbacks[matches[maxidx]];
+      const CommandLineArguments::Internal::String& sarg = matches[maxidx];
+      if ( cs->ArgumentType == NO_ARGUMENT )
+        {
+        // No value
+        }
+      else if ( cs->ArgumentType == SPACE_ARGUMENT )
+        {
+        if ( cc == this->Internals->Argv.size()-1 )
+          {
+          return 0;
+          }
+        // Value is the next argument
+        value = this->Internals->Argv[cc+1].c_str();
+        cc ++;
+        }
+      else if ( cs->ArgumentType == EQUAL_ARGUMENT )
+        {
+        if ( arg.size() == sarg.size() || *(arg.c_str() + sarg.size()) != '=' )
+          {
+          return 0;
+          }
+        // Value is everythng followed the '=' sign
+        value = arg.c_str() + sarg.size()+1;
+        }
+      else if ( cs->ArgumentType == CONCAT_ARGUMENT )
+        {
+        // Value is whatever follows the argument
+        value = arg.c_str() + sarg.size();
+        }
+
+      // Call the callback
+      if ( cs->Callback )
+        {
+        if ( !cs->Callback(sarg.c_str(), value, cs->CallData) )
+          {
+          return 0;
+          }
+        }
+      if ( cs->Variable )
+        {
+        kwsys_stl::string var = "1";
+        if ( value )
+          {
+          var = value;
+          }
+        if ( cs->VariableType == CommandLineArguments::INT_TYPE )
+          {
+          int* variable = static_cast<int*>(cs->Variable);
+          char* res = 0;
+          *variable = strtol(var.c_str(), &res, 10);
+          //if ( res && *res )
+          //  {
+          //  Can handle non-int
+          //  }
+          }
+        else if ( cs->VariableType == CommandLineArguments::DOUBLE_TYPE )
+          {
+          double* variable = static_cast<double*>(cs->Variable);
+          char* res = 0;
+          *variable = strtod(var.c_str(), &res);
+          //if ( res && *res )
+          //  {
+          //  Can handle non-int
+          //  }
+          }
+        else if ( cs->VariableType == CommandLineArguments::STRING_TYPE )
+          {
+          char** variable = static_cast<char**>(cs->Variable);
+          if ( *variable )
+            {
+            delete [] *variable;
+            *variable = 0;
+            }
+          *variable = new char[ strlen(var.c_str()) + 1 ];
+          strcpy(*variable, var.c_str());
+          }
+        else if ( cs->VariableType == CommandLineArguments::STL_STRING_TYPE )
+          {
+          kwsys_stl::string* variable = static_cast<kwsys_stl::string*>(cs->Variable);
+          *variable = var;
+          }
+        else if ( cs->VariableType == CommandLineArguments::BOOL_TYPE )
+          {
+          bool* variable = static_cast<bool*>(cs->Variable);
+          if ( var == "1" || var == "ON" || var == "TRUE" || var == "true" || var == "on" ||
+            var == "True" || var == "yes" || var == "Yes" || var == "YES" )
+            {
+            *variable = true;
+            }
+          else
+            {
+            *variable = false;
+            }
+          }
+        else
+          {
+          cerr << "Got unknown argument type: \"" << cs->VariableType << "\"" << endl;
+          return 0;
+          }
+        }
+      }
+    else
+      {
+      // Handle unknown arguments
+      if ( this->Internals->UnknownArgumentCallback )
+        {
+        if ( !this->Internals->UnknownArgumentCallback(arg.c_str(), 
+            this->Internals->ClientData) )
+          {
+          return 0;
+          }
+        return 1;
+        }
+      else
+        {
+        cerr << "Got unknown argument: \"" << arg.c_str() << "\"" << endl;
+        return 0;
+        }
+      }
+    }
+  // We are done parsing, so remember what was the last argument
+  this->Internals->LastArgument = cc;
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::GetRemainingArguments(int* argc, char*** argv)
+{
+  CommandLineArguments::Internal::VectorOfStrings::size_type size 
+    = this->Internals->Argv.size() - this->Internals->LastArgument + 1;
+  CommandLineArguments::Internal::VectorOfStrings::size_type cc;
+
+  char** args = new char*[ size ];
+  args[0] = new char[ this->Internals->Argv[0].size() + 1 ];
+  strcpy(args[0], this->Internals->Argv[0].c_str());
+  int cnt = 1;
+  for ( cc = this->Internals->LastArgument; 
+    cc < this->Internals->Argv.size(); cc ++ )
+    {
+    args[cnt] = new char[ this->Internals->Argv[cc].size() + 1];
+    strcpy(args[cnt], this->Internals->Argv[cc].c_str());
+    cnt ++;
+    }
+  *argc = cnt;
+  *argv = args;
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::AddCallback(const char* argument, ArgumentTypeEnum type, 
+  CallbackType callback, void* call_data, const char* help)
+{
+  CommandLineArguments::CallbackStructure s;
+  s.Argument     = argument;
+  s.ArgumentType = type;
+  s.Callback     = callback;
+  s.CallData     = call_data;
+  s.VariableType = CommandLineArguments::NO_VARIABLE_TYPE;
+  s.Variable     = 0;
+  s.Help         = help;
+
+  this->Internals->Callbacks[argument] = s;
+  this->GenerateHelp();
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
+  VariableTypeEnum vtype, void* variable, const char* help)
+{
+  CommandLineArguments::CallbackStructure s;
+  s.Argument     = argument;
+  s.ArgumentType = type;
+  s.Callback     = 0;
+  s.CallData     = 0;
+  s.VariableType = vtype;
+  s.Variable     = variable;
+  s.Help         = help;
+
+  this->Internals->Callbacks[argument] = s;
+  this->GenerateHelp();
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
+  int* variable, const char* help)
+{
+  this->AddArgument(argument, type, CommandLineArguments::INT_TYPE, variable, help);
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
+  double* variable, const char* help)
+{
+  this->AddArgument(argument, type, CommandLineArguments::DOUBLE_TYPE, variable, help);
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
+  char** variable, const char* help)
+{
+  this->AddArgument(argument, type, CommandLineArguments::STRING_TYPE, variable, help);
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
+  kwsys_stl::string* variable, const char* help)
+{
+  this->AddArgument(argument, type, CommandLineArguments::STL_STRING_TYPE, variable, help);
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
+  bool* variable, const char* help)
+{
+  this->AddArgument(argument, type, CommandLineArguments::BOOL_TYPE, variable, help);
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::AddBooleanArgument(const char* argument, bool*
+  variable, const char* help)
+{
+  this->AddArgument(argument, CommandLineArguments::NO_ARGUMENT,
+    CommandLineArguments::BOOL_TYPE, variable, help);
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::AddBooleanArgument(const char* argument, int*
+  variable, const char* help)
+{
+  this->AddArgument(argument, CommandLineArguments::NO_ARGUMENT,
+    CommandLineArguments::INT_TYPE, variable, help);
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::SetClientData(void* client_data)
+{
+  this->Internals->ClientData = client_data;
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::SetUnknownArgumentCallback(
+  CommandLineArguments::ErrorCallbackType callback)
+{
+  this->Internals->UnknownArgumentCallback = callback;
+}
+
+//----------------------------------------------------------------------------
+const char* CommandLineArguments::GetHelp(const char* arg)
+{
+  CommandLineArguments::Internal::CallbacksMap::iterator it 
+    = this->Internals->Callbacks.find(arg);
+  if ( it == this->Internals->Callbacks.end() )
+    {
+    return 0;
+    }
+
+  // Since several arguments may point to the same argument, find the one this
+  // one point to if this one is pointing to another argument.
+  CommandLineArguments::CallbackStructure *cs = &(it->second);
+  while ( 1 )
+    {
+    CommandLineArguments::Internal::CallbacksMap::iterator hit 
+      = this->Internals->Callbacks.find(cs->Help);
+    if ( hit == this->Internals->Callbacks.end() )
+      {
+      return cs->Help;
+      }
+    cs = &(hit->second);
+    }
+  // Should never happened
+  return 0;
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::GenerateHelp()
+{
+  kwsys_ios::ostringstream str;
+
+  // Collapse all arguments into the map of vectors of all arguments that do
+  // the same thing.
+  CommandLineArguments::Internal::CallbacksMap::iterator it;
+  typedef kwsys_stl::map<CommandLineArguments::Internal::String, 
+     CommandLineArguments::Internal::SetOfStrings > MapArgs;
+  MapArgs mp;
+  MapArgs::iterator mpit, smpit;
+  for ( it = this->Internals->Callbacks.begin();
+    it != this->Internals->Callbacks.end();
+    it ++ )
+    {
+    CommandLineArguments::CallbackStructure *cs = &(it->second);
+    mpit = mp.find(cs->Help);
+    if ( mpit != mp.end() )
+      {
+      mpit->second.insert(it->first);
+      mp[it->first].insert(it->first);
+      }
+    else
+      {
+      mp[it->first].insert(it->first);
+      }
+    }
+  for ( it = this->Internals->Callbacks.begin();
+    it != this->Internals->Callbacks.end();
+    it ++ )
+    {
+    CommandLineArguments::CallbackStructure *cs = &(it->second);
+    mpit = mp.find(cs->Help);
+    if ( mpit != mp.end() )
+      {
+      mpit->second.insert(it->first);
+      smpit = mp.find(it->first);
+      CommandLineArguments::Internal::SetOfStrings::iterator sit;
+      for ( sit = smpit->second.begin(); sit != smpit->second.end(); sit++ )
+        {
+        mpit->second.insert(*sit);
+        }
+      mp.erase(smpit);
+      }
+    else
+      {
+      mp[it->first].insert(it->first);
+      }
+    }
+ 
+  // Find the length of the longest string
+  CommandLineArguments::Internal::String::size_type maxlen = 0;
+  for ( mpit = mp.begin();
+    mpit != mp.end();
+    mpit ++ )
+    {
+    CommandLineArguments::Internal::SetOfStrings::iterator sit;
+    for ( sit = mpit->second.begin(); sit != mpit->second.end(); sit++ )
+      {
+      CommandLineArguments::Internal::String::size_type clen = sit->size();
+      switch ( this->Internals->Callbacks[*sit].ArgumentType )
+        {
+        case CommandLineArguments::NO_ARGUMENT:     clen += 0; break;
+        case CommandLineArguments::CONCAT_ARGUMENT: clen += 6; break;
+        case CommandLineArguments::SPACE_ARGUMENT:  clen += 7; break;
+        case CommandLineArguments::EQUAL_ARGUMENT:  clen += 7; break;
+        }
+      if ( clen > maxlen )
+        {
+        maxlen = clen;
+        }
+      }
+    }
+
+  // Create format for that string
+  char format[80];
+  sprintf(format, "%%%ds", static_cast<unsigned int>(maxlen));
+
+
+  // Print help for each option
+  for ( mpit = mp.begin();
+    mpit != mp.end();
+    mpit ++ )
+    {
+    CommandLineArguments::Internal::SetOfStrings::iterator sit;
+    for ( sit = mpit->second.begin(); sit != mpit->second.end(); sit++ )
+      {
+      str << endl;
+      char argument[100];
+      sprintf(argument, sit->c_str());
+      switch ( this->Internals->Callbacks[*sit].ArgumentType )
+        {
+        case CommandLineArguments::NO_ARGUMENT: break;
+        case CommandLineArguments::CONCAT_ARGUMENT: strcat(argument, "option"); break;
+        case CommandLineArguments::SPACE_ARGUMENT:  strcat(argument, " option"); break;
+        case CommandLineArguments::EQUAL_ARGUMENT:  strcat(argument, "=option"); break;
+        }
+      char buffer[80];
+      sprintf(buffer, format, argument);
+      str << buffer;
+      }
+    str << "\t";
+    const char* ptr = this->Internals->Callbacks[mpit->first].Help;
+    int len = strlen(ptr);
+    int cnt = 0;
+    while ( len > 0)
+      {
+      // If argument with help is longer than line length, split it on previous
+      // space (or tab) and continue on the next line
+      CommandLineArguments::Internal::String::size_type cc;
+      for ( cc = 0; ptr[cc]; cc ++ )
+        {
+        if ( *ptr == ' ' || *ptr == '\t' )
+          {
+          ptr ++;
+          len --;
+          }
+        }
+      if ( cnt > 0 )
+        {
+        for ( cc = 0; cc < maxlen; cc ++ )
+          {
+          str << " ";
+          }
+        str << "\t";
+        }
+      CommandLineArguments::Internal::String::size_type skip = len;
+      if ( skip > this->LineLength - maxlen )
+        {
+        skip = this->LineLength - maxlen;
+        for ( cc = skip-1; cc > 0; cc -- )
+          {
+          if ( ptr[cc] == ' ' || ptr[cc] == '\t' )
+            {
+            break;
+            }
+          }
+        if ( cc != 0 )
+          {
+          skip = cc;
+          }
+        }
+      str.write(ptr, skip);
+      str << endl;
+      ptr += skip;
+      len -= skip;
+      cnt ++;
+      }
+    }
+  this->Help = str.str();
+}
+
+} // namespace KWSYS_NAMESPACE
diff --git a/CommandLineArguments.hxx.in b/CommandLineArguments.hxx.in
new file mode 100644
index 0000000000000000000000000000000000000000..6bf707d928b1c7e8dd713aa2c3595129b11e84ad
--- /dev/null
+++ b/CommandLineArguments.hxx.in
@@ -0,0 +1,173 @@
+/*=========================================================================
+
+  Program:   KWSys - Kitware System Library
+  Module:    CommandLineArguments.hxx.in
+
+  Copyright (c) Kitware, Inc., Insight Consortium.  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef @KWSYS_NAMESPACE@_CommandLineArguments_hxx
+#define @KWSYS_NAMESPACE@_CommandLineArguments_hxx
+
+#include <@KWSYS_NAMESPACE@/Configure.h>
+#include <@KWSYS_NAMESPACE@/Configure.hxx>
+
+#include <@KWSYS_NAMESPACE@/stl/string>
+
+/* Define this macro temporarily to keep the code readable.  */
+#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
+# define kwsys_stl @KWSYS_NAMESPACE@_stl
+#endif
+
+namespace @KWSYS_NAMESPACE@
+{
+
+class CommandLineArgumentsInternal;
+
+/** \class CommandLineArguments
+ * \brief Command line arguments processing code.
+ *
+ * Find specified arguments with optional options and execute specified methods
+ * or set given variables.
+ */
+
+class @KWSYS_NAMESPACE@_EXPORT CommandLineArguments
+{
+public:
+  CommandLineArguments();
+  ~CommandLineArguments();
+
+  /**
+   * Various argument types.
+   */
+  enum ArgumentTypeEnum { 
+    NO_ARGUMENT,    // The option takes no argument             --foo
+    CONCAT_ARGUMENT,// The option takes argument after no space --foobar
+    SPACE_ARGUMENT, // The option takes argument after space    --foo bar
+    EQUAL_ARGUMENT  // The option takes argument after equal    --foo=bar
+  };
+
+  /**
+   * Various string types.
+   */
+  enum VariableTypeEnum {
+    NO_VARIABLE_TYPE = 0, // The variable is not specified
+    INT_TYPE,             // The variable is integer (int)
+    BOOL_TYPE,            // The vairable is boolean (bool)
+    DOUBLE_TYPE,          // The variable is float (double)
+    STRING_TYPE,          // The variable is string (char*)
+    STL_STRING_TYPE       // The variable is string (char*)
+  };
+
+  /**
+   * Prototypes for callbacks for callback interface.
+   */
+  typedef int(*CallbackType)(const char* argument, const char* value, 
+    void* call_data);
+  typedef int(*ErrorCallbackType)(const char* argument, void* client_data);
+
+  struct CallbackStructure
+    {
+    const char* Argument;
+    int ArgumentType;
+    CallbackType Callback;
+    void* CallData;
+    void* Variable;
+    int VariableType;
+    const char* Help;
+    };
+ 
+  /**
+   * Initialize internal data structures. This should be called before parsing.
+   */
+  void Initialize(int argc, char* argv[]);
+
+  /**
+   * Initialize internal data structure and pass arguments one by one. This is
+   * convinience method for use from scripting languages where argc and argv
+   * are not available.
+   */
+  void Initialize();
+  void ProcessArgument(const char* arg);
+
+  /**
+   * This method will parse arguments and call apropriate methods. 
+   */
+  int Parse();
+
+  /**
+   * This method will add a callback for a specific argument. The arguments to
+   * it are argument, argument type, callback method, and call data. The
+   * argument help specifies the help string used with this option. The
+   * callback and call_data can be skipped.
+   */
+  void AddCallback(const char* argument, ArgumentTypeEnum type, CallbackType callback, 
+                   void* call_data, const char* help);
+
+  /**
+   * Add handler for argument which is going to set the variable to the
+   * specified value.
+   */
+  void AddArgument(const char* argument, ArgumentTypeEnum type, VariableTypeEnum vtype, void* variable, const char* help);
+  void AddArgument(const char* argument, ArgumentTypeEnum type, bool* variable, const char* help);
+  void AddArgument(const char* argument, ArgumentTypeEnum type, int* variable, const char* help);
+  void AddArgument(const char* argument, ArgumentTypeEnum type, double* variable, const char* help);
+  void AddArgument(const char* argument, ArgumentTypeEnum type, char** variable, const char* help);
+  void AddArgument(const char* argument, ArgumentTypeEnum type, kwsys_stl::string* variable, const char* help);
+  void AddBooleanArgument(const char* argument, bool* variable, const char* help);
+  void AddBooleanArgument(const char* argument, int* variable, const char* help);
+
+  /**
+   * Set the callbacks for error handling.
+   */
+  void SetClientData(void* client_data);
+  void SetUnknownArgumentCallback(ErrorCallbackType callback);
+
+  /**
+   * Get remaining arguments. It allocates space for argv, so you have to call
+   * delete[] on it.
+   */
+  void GetRemainingArguments(int* argc, char*** argv);
+
+  /**
+   * Return string containing help. If the argument is specified, only return
+   * help for that argument.
+   */
+  const char* GetHelp() { return this->Help.c_str(); }
+  const char* GetHelp(const char* arg);
+
+  /**
+   * Get / Set the help line length. Default length is 80.
+   */
+  void SetLineLength();
+  unsigned int GetLineLength();
+
+protected:
+
+  void GenerateHelp();
+
+  typedef CommandLineArgumentsInternal Internal;
+  Internal* Internals;
+  kwsys_stl::string Help;
+
+  unsigned int LineLength;
+};
+
+} // namespace @KWSYS_NAMESPACE@
+
+/* Undefine temporary macro.  */
+#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
+# undef kwsys_stl
+#endif
+
+#endif
+
+
+
+
+
diff --git a/testCommandLineArguments.cxx b/testCommandLineArguments.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..68dac90829c9597b0303fe5e8a1ef8e9600ae9a4
--- /dev/null
+++ b/testCommandLineArguments.cxx
@@ -0,0 +1,110 @@
+/*=========================================================================
+
+  Program:   KWSys - Kitware System Library
+  Module:    testCommandLineArguments.cxx
+
+  Copyright (c) Kitware, Inc., Insight Consortium.  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#include <kwsys/CommandLineArguments.hxx>
+
+void* random_ptr = (void*)0x123;
+
+int argument(const char* arg, const char* value, void* call_data)
+{
+  cout << "Got argument: \"" << arg << "\" value: \"" << (value?value:"(null)") << "\"" << endl;
+  if ( call_data != random_ptr )
+    {
+    cerr << "Problem processing call_data" << endl;
+    return 0;
+    }
+  return 1;
+}
+
+int unknown_argument(const char* argument, void* call_data)
+{
+  cout << "Got unknown argument: \"" << argument << "\"" << endl;
+  if ( call_data != random_ptr )
+    {
+    cerr << "Problem processing call_data" << endl;
+    return 0;
+    }
+  return 1;
+}
+
+int main(int argc, char* argv[])
+{
+  // Example run: ./testCommandLineArguments --some-int-variable 4
+  // --another-bool-variable --some-bool-variable=yes
+  // --some-stl-string-variable=foobar --set-bool-arg1 --set-bool-arg2
+  // --some-string-variable=hello
+
+  int res = 0;
+  kwsys::CommandLineArguments arg;
+  arg.Initialize(argc, argv);
+
+  // For error handling
+  arg.SetClientData(random_ptr);
+  arg.SetUnknownArgumentCallback(unknown_argument);
+
+  int some_int_variable = 10;
+  double some_double_variable = 10.10;
+  char* some_string_variable = 0;
+  kwsys_stl::string some_stl_string_variable = "";
+  bool some_bool_variable = false;
+  bool some_bool_variable1 = false;
+  bool bool_arg1 = false;
+  int bool_arg2 = 0;
+
+  typedef kwsys::CommandLineArguments argT;
+
+  arg.AddArgument("--some-int-variable", argT::SPACE_ARGUMENT, &some_int_variable, "Set some random int variable");
+  arg.AddArgument("--some-double-variable", argT::CONCAT_ARGUMENT, &some_double_variable, "Set some random double variable");
+  arg.AddArgument("--some-string-variable", argT::EQUAL_ARGUMENT, &some_string_variable, "Set some random string variable");
+  arg.AddArgument("--some-stl-string-variable", argT::EQUAL_ARGUMENT, &some_stl_string_variable, "Set some random stl string variable");
+  arg.AddArgument("--some-bool-variable", argT::EQUAL_ARGUMENT, &some_bool_variable, "Set some random bool variable");
+  arg.AddArgument("--another-bool-variable", argT::NO_ARGUMENT, &some_bool_variable1, "Set some random bool variable 1");
+  arg.AddBooleanArgument("--set-bool-arg1", &bool_arg1, "Test AddBooleanArgument 1");
+  arg.AddBooleanArgument("--set-bool-arg2", &bool_arg2, "Test AddBooleanArgument 2");
+
+  arg.AddCallback("-A", argT::NO_ARGUMENT, argument, random_ptr, "Some option -A. This option has a multiline comment. It should demonstrate how the code splits lines.");
+  arg.AddCallback("-B", argT::SPACE_ARGUMENT, argument, random_ptr, "Option -B takes argument with space");
+  arg.AddCallback("-C", argT::EQUAL_ARGUMENT, argument, random_ptr, "Option -C takes argument after =");
+  arg.AddCallback("-D", argT::CONCAT_ARGUMENT, argument, random_ptr, "This option takes concatinated argument");
+  arg.AddCallback("--long1", argT::NO_ARGUMENT, argument, random_ptr, "-A");
+  arg.AddCallback("--long2", argT::SPACE_ARGUMENT, argument, random_ptr, "-B");
+  arg.AddCallback("--long3", argT::EQUAL_ARGUMENT, argument, random_ptr, "Same as -C but a bit different");
+  arg.AddCallback("--long4", argT::CONCAT_ARGUMENT, argument, random_ptr, "-C");
+
+  if ( !arg.Parse() )
+    {
+    cerr << "Problem parsing arguments" << endl;
+    res = 1;
+    }
+  cout << "Help: " << arg.GetHelp() << endl;
+
+  cout << "Some int variable was set to: " << some_int_variable << endl;
+  cout << "Some double variable was set to: " << some_double_variable << endl;
+  if ( some_string_variable )
+    {
+    cout << "Some string variable was set to: " << some_string_variable << endl;
+    delete [] some_string_variable;
+    }
+  else
+    {
+    cerr << "Problem setting string variable" << endl;
+    res = 1;
+    }
+  cout << "Some STL String variable was set to: " << some_stl_string_variable.c_str() << endl;
+  cout << "Some bool variable was set to: " << some_bool_variable << endl;
+  cout << "Some bool variable was set to: " << some_bool_variable1 << endl;
+  cout << "bool_arg1 variable was set to: " << bool_arg1 << endl;
+  cout << "bool_arg2 variable was set to: " << bool_arg2 << endl;
+  cout << endl;
+  return res;
+}