[libcommons-cli-java] 10/31: Imported Upstream version 1.1

Tony Mancill tmancill at moszumanska.debian.org
Mon Jun 22 05:52:46 UTC 2015


This is an automated email from the git hooks/post-receive script.

tmancill pushed a commit to branch master
in repository libcommons-cli-java.

commit 63cbb5dc16d1b5fd73f613faa0cb963555f92385
Author: tony mancill <tmancill at debian.org>
Date:   Mon Jun 22 04:36:19 2015 +0000

    Imported Upstream version 1.1
---
 .cvsignore                                         |    7 -
 LICENSE.txt                                        |  262 +++-
 NOTICE.txt                                         |    5 +
 README.txt                                         |   11 +-
 RELEASE-NOTES.txt                                  |   51 +-
 build-gump.xml                                     |   36 -
 build.xml                                          |  236 ++--
 gump.xml                                           |   40 -
 maven.xml                                          |   45 +-
 project.properties                                 |   42 +-
 project.xml                                        |  173 ++-
 src/conf/MANIFEST.MF                               |   10 +-
 .../commons/cli/AlreadySelectedException.java      |   84 +-
 src/java/org/apache/commons/cli/BasicParser.java   |   79 +-
 src/java/org/apache/commons/cli/CommandLine.java   |  312 ++---
 .../org/apache/commons/cli/CommandLineParser.java  |  128 +-
 src/java/org/apache/commons/cli/GnuParser.java     |  217 ++-
 src/java/org/apache/commons/cli/HelpFormatter.java | 1439 +++++++++++++-------
 .../commons/cli/MissingArgumentException.java      |   87 +-
 .../apache/commons/cli/MissingOptionException.java |   87 +-
 src/java/org/apache/commons/cli/Option.java        |  846 +++++++-----
 src/java/org/apache/commons/cli/OptionBuilder.java |  325 ++---
 src/java/org/apache/commons/cli/OptionGroup.java   |  151 +-
 .../org/apache/commons/cli/OptionValidator.java    |  101 ++
 src/java/org/apache/commons/cli/Options.java       |  293 ++--
 .../org/apache/commons/cli/ParseException.java     |   89 +-
 src/java/org/apache/commons/cli/Parser.java        |  396 ++++--
 .../apache/commons/cli/PatternOptionBuilder.java   |  239 ++--
 src/java/org/apache/commons/cli/PosixParser.java   |  253 ++--
 src/java/org/apache/commons/cli/TypeHandler.java   |  245 ++--
 .../commons/cli/UnrecognizedOptionException.java   |   89 +-
 src/java/org/apache/commons/cli/Util.java          |   70 +
 src/java/org/apache/commons/cli/package.html       |    2 +-
 src/media/logo.xcf                                 |  Bin 0 -> 20269 bytes
 src/test/data/.hidden.txt                          |    1 +
 src/test/data/readable.txt                         |    1 +
 src/test/data/writable.txt                         |    1 +
 .../org/apache/commons/cli/ApplicationTest.java    |   16 +
 .../apache/commons/cli/ArgumentIsOptionTest.java   |  100 ++
 src/test/org/apache/commons/cli/BugsTest.java      |  221 ++-
 src/test/org/apache/commons/cli/BuildTest.java     |   22 +-
 src/test/org/apache/commons/cli/GnuParseTest.java  |   24 +-
 .../apache/commons/cli/HelpFormatterExamples.java  |   21 +-
 ...stHelpFormatter.java => HelpFormatterTest.java} |   83 +-
 .../apache/commons/cli/LongOptionWithShort.java    |  114 ++
 .../org/apache/commons/cli/OptionBuilderTest.java  |   25 +-
 .../org/apache/commons/cli/OptionGroupTest.java    |   55 +-
 src/test/org/apache/commons/cli/OptionTest.java    |   82 ++
 src/test/org/apache/commons/cli/OptionsTest.java   |  121 ++
 .../org/apache/commons/cli/ParseRequiredTest.java  |   24 +-
 src/test/org/apache/commons/cli/ParseTest.java     |   25 +-
 .../commons/cli/PatternOptionBuilderTest.java      |   61 +-
 src/test/org/apache/commons/cli/UtilTest.java      |   30 +
 src/test/org/apache/commons/cli/ValueTest.java     |  191 ++-
 src/test/org/apache/commons/cli/ValuesTest.java    |   26 +-
 .../org/apache/commons/cli/bug/BugCLI133Test.java  |   34 +
 .../org/apache/commons/cli/bug/BugCLI13Test.java   |   52 +
 .../org/apache/commons/cli/bug/BugCLI18Test.java   |   43 +
 .../org/apache/commons/cli/bug/BugCLI51Test.java   |   51 +
 .../org/apache/commons/cli/bug/BugCLI71Test.java   |   77 ++
 xdocs/images/1x1.gif                               |  Bin 43 -> 0 bytes
 xdocs/index.xml                                    |   29 -
 xdocs/introduction.xml                             |   87 --
 xdocs/navigation.xml                               |   14 -
 xdocs/properties.xml                               |   97 --
 xdocs/usage.xml                                    |  350 -----
 66 files changed, 4958 insertions(+), 3570 deletions(-)

diff --git a/.cvsignore b/.cvsignore
deleted file mode 100644
index b487296..0000000
--- a/.cvsignore
+++ /dev/null
@@ -1,7 +0,0 @@
-build.properties
-dist
-target
-velocity.log
-.project
-
-maven.log
diff --git a/LICENSE.txt b/LICENSE.txt
index a8684f1..57bc88a 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,60 +1,202 @@
-/*
- * $Header: /home/cvs/jakarta-commons/LICENSE,v 1.4 2002/04/11 13:24:02 dion Exp $
- * $Revision: 1.4 $
- * $Date: 2002/04/11 13:24:02 $
- *
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
diff --git a/NOTICE.txt b/NOTICE.txt
new file mode 100644
index 0000000..b7535ae
--- /dev/null
+++ b/NOTICE.txt
@@ -0,0 +1,5 @@
+Apache Commons CLI
+Copyright 2001-2007 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/README.txt b/README.txt
index 05ca410..1b2aa23 100644
--- a/README.txt
+++ b/README.txt
@@ -12,7 +12,7 @@ for you):
 
   http://www.junit.org/
 
-There are two ways to build CLI, either with ant or maven.
+There are two ways to build CLI, either with Ant or Maven 1.
 
 Ant can be found here :
 
@@ -22,18 +22,17 @@ and to build and test the system use:
 
   ant dist
 
-Maven can be found here :
+Maven 1 can be found here :
 
-  http://jakarta.apache.org/turbine/maven/
+  http://maven.apache.org
 
 and to build and test the system use:
 
-  maven java:jar
+  maven clean jar
 
 The system will build and test itself.
 
-For complete documentation and to create a local copy of the
-CLI project website, type:
+For complete documentation type:
 
   maven site
 
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index f29b7b2..1f20417 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -1,26 +1,61 @@
-$Id: RELEASE-NOTES.txt,v 1.1 2002/11/06 05:09:21 bayard Exp $
+$Id: RELEASE-NOTES.txt 553359 2007-07-05 01:35:30Z bayard $
 
 			Commons CLI Package
-			   Version 1.0
+			   Version 1.1
 			    Release Notes
 
 
 INTRODUCTION:
 
-This document contains the release notes for this version of the Commons
-CLI package. Commons CLI provdes a simple API for working with the command line arguments and options.
+This document contains the release notes for this version of the Commons CLI package. Commons CLI provides a simple API for working with the command line arguments and options.
 
-This is the first release of the CLI component, therefore all features are new, 
-there are no bug-fixes, nothing is deprecated and there are no changes.
+CLI 1.1 is a bugfix release of CLI. The following changes notable API changes were made: 
 
-For more information, read the documentation on the project site at 
-http://jakarta.apache.org/commons/cli/
+ * The Parser abstract class has two additional parse methods that take a Properties parameter. 
+ * The HelpFormatter class had publicly accessible fields. These should now be accessed via get/set methods and the public fields are deprecated. 
+ * The Option class addValue(String) method now throws UnsupportedOperationException. 
+ * OptionValidator is a newly added class. 
+ * Option's now have equals(Object) and hashCode() methods. 
+ * The Option class also received two new methods, setDescription(String) and hasValueSeparator();boolean. 
+
+The jar should be API backwards compatible, though if you were calling addValue(String) then you won't be happy. Please let us know your use case if that is so. 
+
+For more information, read the documentation on the project site at http://jakarta.apache.org/commons/cli/
 
 NEW FEATURES:
 
+  CLI-78 - Setting description of a Option. 
+
 BUG FIXES:
 
 DEPRECATIONS:
 
 CHANGES: 
 
+  CLI-2   - Wrong usage summary. 
+  CLI-5   - Dependecy on commons-lang-2.0 but commons-lang-1.0 is obtained. 
+  CLI-8   - Line separator as first char for helpformatter (footer) throws exception. 
+  CLI-13  - CommandLine.getOptionValue() behaves contrary to docs. 
+  CLI-21  - clone method in Option should use super.clone(). 
+  CLI-23  - Passing properties in Parser does not work for options with a single argument. 
+  CLI-26  - Only long options without short option seems to be noticed. 
+  CLI-28  - Infinite Loop in Command-Line processing. 
+  CLI-29  - Options should not be able to be added more than once. 
+  CLI-35  - HelpFormatter doesn't sort options properly. 
+  CLI-38  - HelpFormatter doesn't function correctly for options with only LongOpt. 
+  CLI-44  - Document enhancement. 
+  CLI-45  - Documentation errors. 
+  CLI-51  - Parameter value "-something" misinterpreted as a parameter. 
+  CLI-56  - clone() method doesn't fully clone contents. 
+  CLI-59  - No Javadoc for HelpFormatter!. 
+  CLI-65  - Parser breaks up command line parms into single characters. 
+  CLI-67  - Missing arguments in HelpFormatter.renderOptions(..). 
+  CLI-69  - Error parsing option arguments. 
+  CLI-71  - A weakness of parser. 
+  CLI-129 - CLI_1_BRANCH build.xml doesn't work. 
+  CLI-130 - Remove the Commons Lang dependency. 
+  CLI-131 - Options class returns options in random order. 
+  CLI-132 - MissingOptionException should contain a useful error message. 
+  CLI-133 - NullPointerException in Util.stripLeadingHyphens when passed a null argument. 
+  CLI-134 - 1.1 is not backwards compatible because it adds methods to the CommandLineParser interface. 
+  CLI-135 - Backwards compatibility between 1.1 and 1.0 broken due to Option.addValue removal. 
diff --git a/build-gump.xml b/build-gump.xml
deleted file mode 100644
index b5d7d58..0000000
--- a/build-gump.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<!--
-
-  WARNING: This file is generated! Do not edit by hand!
-  
--->
-
-<project name="maven" default="jar" basedir=".">
-
-  <target
-    name="jar">
-    
-    <property name="maven.build.dir" value="target"/>
-    <property name="maven.build.dest" value="${maven.build.dir}/classes"/>
-    
-    <mkdir dir="${maven.build.dest}"/>
-    
-    <javac
-      destdir="${maven.build.dest}"
-      excludes="**/package.html"
-      debug="false"
-      deprecation="false"
-      optimize="false">
-      <src>
-         <pathelement location="src/java"/>
-      </src>
-    </javac>
-
-    <jar
-      jarfile="${maven.build.dir}/${maven.final.name}.jar"
-      basedir="${maven.build.dest}"
-      excludes="**/package.html"
-    />
-    
-  </target>
-
-</project>
diff --git a/build.xml b/build.xml
index 28a5ef1..6cdbf03 100644
--- a/build.xml
+++ b/build.xml
@@ -1,158 +1,166 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
+<!--build.xml generated by maven from project.xml version 1.1
+  on date July 4 2007, time 1948-->
+
 <project default="jar" name="commons-cli" basedir=".">
-  
-  <property name="defaulttargetdir" value="target"></property> 
-  <property name="classesdir" value="target/classes"></property>
-  <property name="testclassesdir" value="target/test-classes"></property>
-  <property name="testreportdir" value="target/test-reports"></property>
-  <property name="distdir" value="dist"></property>
-  <property name="javadocdir" value="target/docs/apidocs"></property>
-  <property name="final.name" value="commons-cli-1.0-beta-2-dev"></property>
-  
+  <property name="defaulttargetdir" value="target">
+  </property>
+  <property name="libdir" value="target/lib">
+  </property>
+  <property name="classesdir" value="target/classes">
+  </property>
+  <property name="testclassesdir" value="target/test-classes">
+  </property>
+  <property name="testclassesdir" value="target/test-classes">
+  </property>
+  <property name="testreportdir" value="target/test-reports">
+  </property>
+  <property name="distdir" value="dist">
+  </property>
+  <property name="javadocdir" value="dist/docs/api">
+  </property>
+  <property name="final.name" value="commons-cli-1.1">
+  </property>
+  <path id="build.classpath">
+    <fileset dir="${libdir}">
+      <include name="**/*.jar">
+      </include>
+    </fileset>
+  </path>
   <target name="init" description="o Initializes some properties">
-
+    <mkdir dir="${libdir}">
+    </mkdir>
     <condition property="noget">
-      <equals arg2="only" arg1="${build.sysclasspath}"></equals>
+      <equals arg2="only" arg1="${build.sysclasspath}">
+      </equals>
     </condition>
-  </target>
-    
-  <target name="jar" description="o Create the jar" depends="get-deps">
-
-    <mkdir dir="${classesdir}"></mkdir>
+    <!--Test if JUNIT is present in ANT classpath-->
 
+    <available property="Junit.present" classname="junit.framework.Test">
+    </available>
+  </target>
+  <target name="compile" description="o Compile the code" depends="get-deps">
+    <mkdir dir="${classesdir}">
+    </mkdir>
     <javac destdir="${classesdir}" deprecation="true" debug="true" optimize="false" excludes="**/package.html">
       <src>
-        <pathelement location="src/java"></pathelement>
+        <pathelement location="src/java">
+        </pathelement>
       </src>
-      <classpath>
-        <fileset dir="lib">
-          <include name="*.jar"></include>
-        </fileset>
+      <classpath refid="build.classpath">
       </classpath>
     </javac>
-
-    
-    <jar jarfile="target/${final.name}.jar" excludes="**/package.html" basedir="${classesdir}"></jar>
-
+    <mkdir dir="${classesdir}/META-INF">
+    </mkdir>
+    <copy todir="${classesdir}/META-INF">
+      <fileset dir=".">
+        <include name="NOTICE.txt">
+        </include>
+      </fileset>
+    </copy>
+  </target>
+  <target name="jar" description="o Create the jar" depends="compile,test">
+    <jar jarfile="${defaulttargetdir}/${final.name}.jar" excludes="**/package.html" basedir="${classesdir}">
+    </jar>
   </target>
-  
   <target name="clean" description="o Clean up the generated directories">
-    <delete dir="${defaulttargetdir}"></delete>
-    <delete dir="${distdir}"></delete>
+    <delete dir="${defaulttargetdir}">
+    </delete>
+    <delete dir="${distdir}">
+    </delete>
   </target>
-
   <target name="dist" description="o Create a distribution" depends="jar, javadoc">
-    <mkdir dir="dist"></mkdir>
+    <mkdir dir="dist">
+    </mkdir>
     <copy todir="dist">
-      <fileset dir="${defaulttargetdir}"></fileset>
+      <fileset dir="${defaulttargetdir}" includes="*.jar">
+      </fileset>
+      <fileset dir="${basedir}" includes="LICENSE*, README*">
+      </fileset>
     </copy>
   </target>
- 
-  <target name="test" description="o Run the test cases" depends="compile-tests">
-    <mkdir dir="${testreportdir}"></mkdir>
-    <junit dir="./" printSummary="yes" fork="true" haltonerror="true">
-      <sysproperty key="basedir" value="src/test"></sysproperty>
-      <formatter type="xml"></formatter>
-      <formatter usefile="true" type="plain"></formatter>
+  <target name="test" description="o Run the test cases" if="test.failure" depends="internal-test">
+    <fail message="There were test failures.">
+    </fail>
+  </target>
+  <target name="internal-test" if="Junit.present" depends="junit-present,compile-tests">
+    <mkdir dir="${testreportdir}">
+    </mkdir>
+    <junit dir="./" failureproperty="test.failure" printSummary="yes" fork="true" haltonerror="true">
+      <sysproperty key="basedir" value=".">
+      </sysproperty>
+      <formatter type="xml">
+      </formatter>
+      <formatter usefile="false" type="plain">
+      </formatter>
       <classpath>
-        <fileset dir="lib">
-          <include name="*.jar"></include>
-        </fileset>
-        <pathelement location="target/${final.name}.jar"></pathelement>
-        <pathelement path="${testclassesdir}"></pathelement>
+        <path refid="build.classpath">
+        </path>
+        <pathelement path="${testclassesdir}">
+        </pathelement>
+        <pathelement path="${classesdir}">
+        </pathelement>
       </classpath>
       <batchtest todir="${testreportdir}">
         <fileset dir="src/test">
-              
-                <include name="**/*Test*.java"></include>
-              
-              
+          <include name="**/*Test.java">
+          </include>
         </fileset>
       </batchtest>
     </junit>
   </target>
-
-  <target name="compile-tests" depends="jar">
-    <mkdir dir="${testclassesdir}"></mkdir>
+  <target name="junit-present" unless="Junit.present" depends="init">
+    <echo>================================= WARNING ================================</echo>
+    <echo>Junit isn't present in your ${ANT_HOME}/lib directory. Tests not executed.</echo>
+    <echo>==========================================================================</echo>
+  </target>
+  <target name="compile-tests" if="Junit.present" depends="junit-present,compile">
+    <mkdir dir="${testclassesdir}">
+    </mkdir>
     <javac destdir="${testclassesdir}" deprecation="true" debug="true" optimize="false" excludes="**/package.html">
       <src>
-        <pathelement location="src/test"></pathelement>
+        <pathelement location="src/test">
+        </pathelement>
       </src>
       <classpath>
-        <fileset dir="lib">
-          <include name="*.jar"></include>
-        </fileset>
-        <pathelement location="target/${final.name}.jar"></pathelement>
+        <path refid="build.classpath">
+        </path>
+        <pathelement path="${classesdir}">
+        </pathelement>
       </classpath>
     </javac>
-
-    
-   
-    
- 
-    <copy todir="${testclassesdir}">
-      <fileset dir="src/test">
-      
-      
-      </fileset>
-    </copy>
-    
   </target>
-
-  <target name="javadoc" description="o Generate javadoc" depends="jar">
- 
- 
-    <mkdir dir="${javadocdir}"></mkdir>
- 
-    
+  <target name="javadoc" description="o Generate javadoc" depends="get-deps">
+    <mkdir dir="${javadocdir}">
+    </mkdir>
     <tstamp>
-      <format pattern="2002-yyyy" property="year"></format>
+      <format pattern="2002-yyyy" property="year">
+      </format>
     </tstamp>
- 
-    <property name="copyright" value="Copyright &copy;  Apache Software Foundation. All Rights Reserved."></property>
- 
-    <property name="title" value="CLI 1.0-beta-2-dev API"></property>
- 
-    <javadoc use="true" private="true" destdir="${javadocdir}" author="true" version="true" sourcepath="src/java" packagenames="org.apache.commons.cli.*">
+    <property name="copyright" value="Copyright &copy; 2002-2007 Apache Software Foundation. All Rights Reserved.">
+    </property>
+    <property name="title" value="CLI 1.1 API">
+    </property>
+    <javadoc use="true" private="true" destdir="${javadocdir}" author="true" version="true" sourcepath="src/java" packagenames="org.apache.commons.*">
       <classpath>
-        <fileset dir="lib">
-          <include name="*.jar"></include>
-        </fileset>
-        <pathelement location="target/${final.name}.jar"></pathelement>
+        <path refid="build.classpath">
+        </path>
       </classpath>
     </javadoc>
- 
   </target>
-
   <target name="get-deps" unless="noget" depends="init">
-  
-    <mkdir dir="lib"></mkdir>
-    
-    <get dest="lib/commons-logging-1.0.jar" usetimestamp="true" ignoreerrors="true" src="http://www.ibiblio.org/maven/commons-logging/jars/commons-logging-1.0.jar"></get>
-    <get dest="lib/commons-lang-SNAPSHOT.jar" usetimestamp="true" ignoreerrors="true" src="http://www.ibiblio.org/maven/commons-lang/jars/commons-lang-SNAPSHOT.jar"></get>
-    <get dest="lib/junit-3.7.jar" usetimestamp="true" ignoreerrors="true" src="http://www.ibiblio.org/maven/junit/jars/junit-3.7.jar"></get>
-  
-  </target>
-
-  
-  
-  
-  
-  
-  
-  
-  
+    <!--Proxy settings works only with a JDK 1.2 and higher.-->
 
+    <setproxy>
+    </setproxy>
+    <get dest="${libdir}/junit-3.8.1.jar" usetimestamp="true" ignoreerrors="true" src="http://repo1.maven.org/maven/junit/jars/junit-3.8.1.jar">
+    </get>
+  </target>
   <target name="install-maven">
-
-    
-
-    <get dest="${user.home}/maven-install-latest.jar" usetimestamp="true" src="${maven.repo.remote}/maven/maven-install-latest.jar"></get>
-    
-    <unjar dest="${maven.home}" src="${user.home}/maven-install-latest.jar"></unjar>
-    
+    <get dest="${user.home}/maven-install-latest.jar" usetimestamp="true" src="${repo}/maven/maven-install-latest.jar">
+    </get>
+    <unjar dest="${maven.home}" src="${user.home}/maven-install-latest.jar">
+    </unjar>
   </target>
-
-</project>
-    
\ No newline at end of file
+</project>
\ No newline at end of file
diff --git a/gump.xml b/gump.xml
deleted file mode 100644
index 34dda13..0000000
--- a/gump.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<module name="commons-cli">
-
-
-  <description>Commons CLI</description>
-  <url href="http://jakarta.apache.org/commons/sandbox/cli.html"/>
-  
-  <cvs repository="jakarta"/>
-  
-  <!-- This is really the cvs module. We need to change this but -->
-  <!-- I will leave this for now until everything works.         -->
-  
-  <project name="commons-cli">
-    
-    <!-- Standard Maven target to produce Javadocs, source -->
-    <!-- and binary distributions.                         -->
-    <ant buildfile="build-gump.xml" target="jar">
-      <property name="maven.final.name" value="commons-cli-@@DATE@@"/>
-    </ant>
-
-    <package>org.apache.commons.cli</package>
-
-    <!-- All Maven projects need Ant and Xerces to build. -->
-    <depend project="jakarta-ant"/>
-    <depend project="xml-xerces"/>
-
-    <depend project="commons-logging"/>
-    <depend project="commons-lang"/>
-
-    <work nested="target/classes"/>
-    <home nested="target"/>
-    <jar name="commons-cli-@@DATE@@.jar"/>
-    <javadoc nested="docs/apidocs"/>
-
-    <nag from="Maven Developers <turbine-maven-dev at jakarta.apache.org>"
-         to="commons-dev at jakarta.apache.org"/>
-
-    
-  </project>
-  
-</module>
diff --git a/maven.xml b/maven.xml
index 1a28e1d..953c587 100644
--- a/maven.xml
+++ b/maven.xml
@@ -1,4 +1,47 @@
-<project default="java:jar"
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<project default="jar:jar"
   xmlns:j="jelly:core">
 
+  <!-- Ensures that the release notes and NOTICE.txt are included in the
+       source distro.
+   -->
+  <postGoal name="dist:prepare-src-filesystem">
+    <j:set var="maven.dist.src.assembly.dir" value="${pom.getPluginContext('maven-dist-plugin').getVariable('maven.dist.src.assembly.dir')}" />
+    <copy todir="${maven.dist.src.assembly.dir}">
+      <fileset file="${basedir}/NOTICE.txt"/>
+      <fileset file="${basedir}/RELEASE-NOTES.txt"/>
+    </copy>
+  </postGoal>
+
+  <!-- Ensures that release notes NOTICE.txt is added to the binary distro -->
+  <preGoal name="dist:build-bin">
+    <copy todir="${maven.dist.bin.assembly.dir}">
+      <fileset file="${basedir}/NOTICE.txt"/>
+      <fileset file="${basedir}/RELEASE-NOTES.txt"/>
+    </copy>
+  </preGoal>
+
+ <preGoal name="dist:prepare-bin-filesystem">
+   <attainGoal name="ant:generate-build"/>
+ </preGoal>
+
+ <preGoal name="dist:prepare-src-filesystem">
+   <attainGoal name="ant:generate-build"/>
+ </preGoal>
+
 </project>
diff --git a/project.properties b/project.properties
index db972c6..7e0f95f 100644
--- a/project.properties
+++ b/project.properties
@@ -1,32 +1,38 @@
 # -------------------------------------------------------------------
 # P R O J E C T  P R O P E R T I E S
 # -------------------------------------------------------------------
+maven.repo.remote=http://repo1.maven.org/maven
+
+maven.changelog.factory=org.apache.maven.svnlib.SvnChangeLogFactory
+
+maven.changes.issue.template=http://issues.apache.org/jira/browse/%ISSUE%
 
 compile.debug = on
 compile.optimize = off
 compile.deprecation = off
 
+maven.compile.source=1.3
+maven.compile.target=1.3
+
 maven.jarResources.basedir=${basedir}/src/java
- 
-# coding standards
 
-maven.checkstyle.rcurly = ignore
-maven.checkstyle.lcurly.type = ignore
-maven.checkstyle.lcurly.method = ignore
-maven.checkstyle.lcurly.other = ignore
-maven.checkstyle.header.file = LICENSE.txt
-maven.checkstyle.header.ignore.line = 1,2,3,4
-maven.checkstyle.const.pattern = ^[A-Z0-9_]*$
-maven.checkstyle.static.pattern = ^[a-zA-Z][a-zA-Z0-9_]*$
-maven.checkstyle.member.pattern = ^[_]?[a-z]?[a-zA-Z0-9]*$
-maven.checkstyle.ignore.line.len.pattern = ^[ \* \$]+[.]*
+# Make the source distro unzip to a different directory
+maven.dist.src.assembly.dir=${maven.dist.assembly.dir}/src/${maven.final.name}-src
 
-maven.checkstyle.javadoc.scope = protected
+# Reset the checkstyle properties to use the default sun settings
+maven.checkstyle.properties=
+maven.checkstyle.format=sun
 
-# disable these non-critical errors to highlight
-# more important ones like missing javadoc
+maven.xdoc.date=left
+maven.xdoc.version=${pom.currentVersion}
+maven.xdoc.developmentProcessUrl=http://jakarta.apache.org/commons/charter.html
+maven.xdoc.poweredby.image=maven-feather.png
 
-maven.checkstyle.max.line.len = 100
-maven.checkstyle.ignore.whitespace = true
-maven.checkstyle.ignore.public.in.interface = true
+maven.javadoc.links=http://java.sun.com/j2se/1.4/docs/api/
 
+# Jar Manifest and Additional Attributes
+maven.jar.manifest=${basedir}/src/conf/MANIFEST.MF
+maven.jar.manifest.attributes.list=Implementation-Vendor-Id,X-Compile-Source-JDK,X-Compile-Target-JDK
+maven.jar.manifest.attribute.Implementation-Vendor-Id=org.apache
+maven.jar.manifest.attribute.X-Compile-Source-JDK=${maven.compile.source}
+maven.jar.manifest.attribute.X-Compile-Target-JDK=${maven.compile.target}
diff --git a/project.xml b/project.xml
index 60a5661..66b7171 100644
--- a/project.xml
+++ b/project.xml
@@ -1,20 +1,76 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
 
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
 <project>
-  <extend>../project.xml</extend>
-  <id>commons-cli</id>
+  <groupId>commons-cli</groupId>
+  <artifactId>commons-cli</artifactId>
   <name>CLI</name>
-
-  <currentVersion>1.0</currentVersion>
+  <currentVersion>1.1</currentVersion>
   <inceptionYear>2002</inceptionYear>
   <shortDescription>Commons CLI</shortDescription>
-  <gumpRepositoryId>jakarta</gumpRepositoryId>
-  <logo>/images/1x1.gif</logo>
-  
   <description>
-  	Commons CLI provides a simple API for working with the command line arguments and options.
+    Commons CLI provides a simple API for presenting, processing and
+    validating a command line interface.
   </description>
-  
+  <logo>/images/logo.png</logo>
+
+  <url>http://jakarta.apache.org/commons/cli/</url>
+  <package>org.apache.commons</package>
+
+  <organization>
+    <name>Apache Software Foundation</name>
+    <url>http://www.apache.org</url>
+    <logo>http://jakarta.apache.org/images/original-jakarta-logo.gif</logo>
+  </organization>
+
+  <licenses>
+    <license>
+      <name>The Apache Software License, Version 2.0</name>
+      <url>/LICENSE.txt</url>
+      <distribution>repo</distribution>
+    </license>
+  </licenses>
+
+  <gumpRepositoryId>jakarta</gumpRepositoryId>
+  <issueTrackingUrl>http://issues.apache.org/jira/</issueTrackingUrl>
+  <siteAddress>people.apache.org</siteAddress>
+  <siteDirectory>/www/jakarta.apache.org/commons/cli/</siteDirectory>
+  <distributionDirectory>/www/jakarta.apache.org/builds/jakarta-commons/cli/</distributionDirectory>
+
+  <repository>
+    <connection>scm:svn:http://svn.apache.org/repos/asf/jakarta/commons/proper/cli/trunk</connection>
+    <url>http://svn.apache.org/repos/asf/jakarta/commons/proper/cli/trunk</url>
+  </repository>
+
+  <mailingLists>
+    <mailingList>
+      <name>Commons Dev List</name>
+      <subscribe>commons-dev-subscribe at jakarta.apache.org</subscribe>
+      <unsubscribe>commons-dev-unsubscribe at jakarta.apache.org</unsubscribe>
+      <archive>http://mail-archives.apache.org/mod_mbox/jakarta-commons-dev/</archive>
+    </mailingList>
+    <mailingList>
+      <name>Commons User List</name>
+      <subscribe>commons-user-subscribe at jakarta.apache.org</subscribe>
+      <unsubscribe>commons-user-unsubscribe at jakarta.apache.org</unsubscribe>
+      <archive>http://mail-archives.apache.org/mod_mbox/jakarta-commons-user/</archive>
+    </mailingList>
+  </mailingLists>
+
   <developers>
     <developer>
       <name>James Strachan</name>
@@ -23,30 +79,54 @@
       <organization>SpiritSoft, Inc.</organization>
     </developer>
     <developer>
-      <name>bob mcwhirter</name>
+      <name>Bob McWhirter</name>
       <id>bob</id>
       <email>bob at werken.com</email>
       <organization>Werken</organization>
+      <roles>
+        <role>contributed ideas and code from werken.opt</role>
+      </roles>
     </developer>
     <developer>
       <name>John Keyes</name>
       <id>jkeyes</id>
       <email>jbjk at mac.com</email>
       <organization>integral Source</organization>
+      <roles>
+        <role>contributed ideas and code from Optz</role>
+      </roles>
+    </developer>
+    <developer>
+      <name>Rob Oxspring</name>
+      <id>roxspring</id>
+      <email>roxspring at imapmail.org</email>
+      <organization>Indigo Stone</organization>
+      <roles>
+        <role>designed CLI2</role>
+      </roles>
     </developer>
   </developers>
 
   <contributors>
-    <!-- Helped in merging Avalon CLI -->
+    <contributor>
+      <name>Peter Donald</name>
+      <roles>
+        <role>contributed ideas and code from Avalon Excalibur's cli package</role>
+      </roles>
+    </contributor>
+    <contributor>
+      <name>Brian Egge</name>
+      <roles>
+        <role>made the 1.1 release happen</role>
+      </roles>
+    </contributor>
     <contributor>
       <name>Berin Loritsch</name>
       <email>bloritsch at apache.org</email>
-      <id>bloritsch</id>
       <roles>
         <role>helped in the Avalon CLI merge</role>
       </roles>
     </contributor>
-    <!-- Supplied patch -->
     <contributor>
       <name>Peter Maddocks</name>
       <email>peter_maddocks at hp.com</email>
@@ -55,33 +135,68 @@
         <role>supplied patch</role>
       </roles>
     </contributor>
+    <contributor>
+      <name>Andrew Shirley</name>
+      <roles>
+        <role>lots of fixes for 1.1 and 2.0</role>
+      </roles>
+    </contributor>
   </contributors>
 
   <dependencies>
-    
-    <dependency>
-      <id>commons-logging</id>
-      <version>1.0</version>
-    </dependency>
-    
-    <dependency>
-      <id>commons-lang</id>
-      <version>1.0</version>
-    </dependency>
-  
+
+    <!-- used for unit tests -->
     <dependency>
-      <id>junit</id>
-      <version>3.7</version>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <properties>
+       <scope>test</scope>
+       <comment>
+        Required only for testing.
+       </comment>
+      </properties>
     </dependency>
-  
+
   </dependencies>
-  
+
   <build>
+    <nagEmailAddress>commons-dev at jakarta.apache.org</nagEmailAddress>
+    <sourceDirectory>src/java</sourceDirectory>
+    <unitTestSourceDirectory>src/test</unitTestSourceDirectory>
+
     <!-- Unit test classes -->
     <unitTest>
       <includes>
-        <include>**/*Test*.java</include>
+        <include>**/*Test.java</include>
       </includes>
     </unitTest>
+    <resources>
+      <resource>
+        <directory>${basedir}</directory>
+        <targetPath>META-INF</targetPath>
+        <includes>
+          <include>NOTICE.txt</include>
+        </includes>
+      </resource>
+    </resources>
   </build>
+
+  <reports>
+    <report>maven-changes-plugin</report>
+
+    <!-- Pointless given tht the code is most definitely not 'sun' style -->
+    <!--report>maven-checkstyle-plugin</report-->  
+
+    <report>maven-javadoc-plugin</report>
+    <report>maven-junit-report-plugin</report>
+    <report>maven-jxr-plugin</report>
+    <report>maven-license-plugin</report>
+    <report>maven-pmd-plugin</report>
+    <!--
+    <report>maven-simian-plugin</report>
+    <report>maven-jcoverage-plugin</report>
+    <report>maven-findbugs-plugin</report>
+    -->
+  </reports>
 </project>
diff --git a/src/conf/MANIFEST.MF b/src/conf/MANIFEST.MF
index d2989c5..02ae373 100644
--- a/src/conf/MANIFEST.MF
+++ b/src/conf/MANIFEST.MF
@@ -1,6 +1,4 @@
-Extension-Name: org.apache.commons.cli
-Specification-Vendor: Apache Software Foundation
-Specification-Version: 1.0
-Implementation-Vendor: Apache Software Foundation
-Implementation-Version: 1.0-dev
-
+Implementation-Title: Jakarta Commons CLI
+Specification-Title: Jakarta Commons CLI
+Specification-Vendor: Apache Software Foundation
+Specification-Version: 1.1
diff --git a/src/java/org/apache/commons/cli/AlreadySelectedException.java b/src/java/org/apache/commons/cli/AlreadySelectedException.java
index 6dcd3cb..aea7807 100644
--- a/src/java/org/apache/commons/cli/AlreadySelectedException.java
+++ b/src/java/org/apache/commons/cli/AlreadySelectedException.java
@@ -1,62 +1,18 @@
-/*
- * $Header: /home/cvs/jakarta-commons-sandbox/cli/src/java/org/apache/commons/cli/AlreadySelectedException.java,v 1.4 2002/06/06 09:37:26 jstrachan Exp $
- * $Revision: 1.4 $
- * $Date: 2002/06/06 09:37:26 $
- *
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 package org.apache.commons.cli;
 
@@ -67,7 +23,8 @@ package org.apache.commons.cli;
  * @author John Keyes ( john at integralsource.com )
  * @see ParseException
  */
-public class AlreadySelectedException extends ParseException {
+public class AlreadySelectedException
+    extends ParseException {
 
     /** 
      * <p>Construct a new <code>AlreadySelectedException</code> 
@@ -75,7 +32,8 @@ public class AlreadySelectedException extends ParseException {
      *
      * @param message the detail message
      */
-    public AlreadySelectedException( String message ) {
-        super( message );
+    public AlreadySelectedException(String message)
+    {
+        super(message);
     }
-}
+}
\ No newline at end of file
diff --git a/src/java/org/apache/commons/cli/BasicParser.java b/src/java/org/apache/commons/cli/BasicParser.java
index a3526ef..24ce212 100644
--- a/src/java/org/apache/commons/cli/BasicParser.java
+++ b/src/java/org/apache/commons/cli/BasicParser.java
@@ -1,62 +1,18 @@
-/*
- * $Header: /home/cvspublic/jakarta-commons/cli/src/java/org/apache/commons/cli/BasicParser.java,v 1.3 2002/09/19 22:59:43 jkeyes Exp $
- * $Revision: 1.3 $
- * $Date: 2002/09/19 22:59:43 $
- *
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 package org.apache.commons.cli;
 
@@ -82,9 +38,8 @@ public class BasicParser extends Parser {
      * when an non option is found.
      * @return The <code>arguments</code> String array.
      */
-    protected String[] flatten( Options options, 
-                                String[] arguments, 
-                                boolean stopAtNonOption )
+    protected String[] flatten(Options options, String[] arguments, 
+                               boolean stopAtNonOption)
     {
         // just echo the arguments
         return arguments;
diff --git a/src/java/org/apache/commons/cli/CommandLine.java b/src/java/org/apache/commons/cli/CommandLine.java
index 8b45ea2..190161c 100644
--- a/src/java/org/apache/commons/cli/CommandLine.java
+++ b/src/java/org/apache/commons/cli/CommandLine.java
@@ -1,72 +1,27 @@
-/*
- * $Header: /home/cvs/jakarta-commons-sandbox/cli/src/java/org/apache/commons/cli/CommandLine.java,v 1.4 2002/06/06 22:32:37 bayard Exp $
- * $Revision: 1.4 $
- * $Date: 2002/06/06 22:32:37 $
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 package org.apache.commons.cli;
 
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.Iterator;
-import java.util.List;
 import java.util.LinkedList;
-import java.util.Map;
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
 
 /** 
  * <p>Represents list of arguments parsed against
@@ -84,169 +39,213 @@ import java.util.Map;
  * @author John Keyes (john at integralsource.com)
  */
 public class CommandLine {
-    
+
     /** the unrecognised options/arguments */
-    private List args    = new LinkedList();
+    private List args = new LinkedList();
 
     /** the processed options */
-    private Map options = new HashMap();
+    private Set options = new HashSet();
 
     /** Map of unique options for ease to get complete list of options */
-    private Map hashcodeMap = new HashMap();
-
-    /** the processed options */
-    private Option[] optionsArray;
+//    private Set allOptions = new HashSet();
 
     /**
-     * <p>Creates a command line.</p>
+     * Creates a command line.
      */
-    CommandLine() {
+    CommandLine()
+    {
+        // nothing to do
     }
-    
+
     /** 
-     * <p>Query to see if an option has been set.</p>
+     * Query to see if an option has been set.
      *
      * @param opt Short name of the option
      * @return true if set, false if not
      */
-    public boolean hasOption(String opt) {
-        return options.containsKey( opt );
+    public boolean hasOption(String opt)
+    {
+        return options.contains( resolveOption(opt));
     }
 
     /** 
-     * <p>Query to see if an option has been set.</p>
+     * Query to see if an option has been set.
      *
      * @param opt character name of the option
      * @return true if set, false if not
      */
-    public boolean hasOption( char opt ) {
-        return hasOption( String.valueOf( opt ) );
+    public boolean hasOption(char opt)
+    {
+        return hasOption(String.valueOf(opt));
     }
 
     /**
-     * <p>Return the <code>Object</code> type of this <code>Option</code>.</p>
+     * Return the <code>Object</code> type of this <code>Option</code>.
      *
      * @param opt the name of the option
      * @return the type of this <code>Option</code>
      */
-    public Object getOptionObject( String opt ) {
-        String res = getOptionValue( opt );
-        
-        Object type = ((Option)((List)options.get(opt)).iterator().next()).getType();
-        return res == null ? null : TypeHandler.createValue(res, type);
+    public Object getOptionObject(String opt)
+    {
+        String res = getOptionValue(opt);
+
+        Option option = resolveOption(opt);
+        if (option == null)
+        {
+            return null;
+        }
+
+        Object type = option.getType();
+
+        return (res == null)        ? null : TypeHandler.createValue(res, type);
     }
 
     /**
-     * <p>Return the <code>Object</code> type of this <code>Option</code>.</p>
+     * Return the <code>Object</code> type of this <code>Option</code>.
      *
      * @param opt the name of the option
      * @return the type of opt
      */
-    public Object getOptionObject( char opt ) {
-        return getOptionObject( String.valueOf( opt ) );
+    public Object getOptionObject(char opt)
+    {
+        return getOptionObject(String.valueOf(opt));
     }
 
     /** 
-     * <p>Retrieve the argument, if any, of this option.</p>
+     * Retrieve the argument, if any, of this option.
      *
      * @param opt the name of the option
      * @return Value of the argument if option is set, and has an argument,
      * otherwise null.
      */
-    public String getOptionValue( String opt ) {
+    public String getOptionValue(String opt)
+    {
         String[] values = getOptionValues(opt);
+
         return (values == null) ? null : values[0];
     }
 
     /** 
-     * <p>Retrieve the argument, if any, of this option.</p>
+     * Retrieve the argument, if any, of this option.
      *
      * @param opt the character name of the option
      * @return Value of the argument if option is set, and has an argument,
      * otherwise null.
      */
-    public String getOptionValue( char opt ) {
-        return getOptionValue( String.valueOf( opt ) );
+    public String getOptionValue(char opt)
+    {
+        return getOptionValue(String.valueOf(opt));
     }
 
     /** 
-     * <p>Retrieves the array of values, if any, of an option.</p>
+     * Retrieves the array of values, if any, of an option.
      *
      * @param opt string name of the option
      * @return Values of the argument if option is set, and has an argument,
      * otherwise null.
      */
-    public String[] getOptionValues( String opt ) {
-        List values = new java.util.ArrayList();
+    public String[] getOptionValues(String opt)
+    {
+        Option key = resolveOption( opt );
 
-        if( options.containsKey( opt ) ) {
-            List opts = (List)options.get( opt );
-            Iterator iter = opts.iterator();
+        if (options.contains(key))
+        {
+            return key.getValues();
+        }
 
-            while( iter.hasNext() ) {
-                Option optt = (Option)iter.next();
-                values.addAll( optt.getValuesList() );
+        return null;
+        }
+
+    /**
+     * <p>Retrieves the option object given the long or short option as a String</p>
+     * @param opt short or long name of the option
+     * @return Canonicalized option
+     */
+    private Option resolveOption( String opt )
+    {
+        opt = Util.stripLeadingHyphens(opt);
+        for ( Iterator it = options.iterator(); it.hasNext(); )
+        {
+            Option option = (Option) it.next();
+            if (opt.equals(option.getOpt()))
+            {
+                return option;
             }
+            if (opt.equals( option.getLongOpt()))
+            {
+                return option;
+        }
+
         }
-        return (values.size() == 0) ? null : (String[])values.toArray(new String[]{});
+        return null;
     }
 
     /** 
-     * <p>Retrieves the array of values, if any, of an option.</p>
+     * Retrieves the array of values, if any, of an option.
      *
      * @param opt character name of the option
      * @return Values of the argument if option is set, and has an argument,
      * otherwise null.
      */
-    public String[] getOptionValues( char opt ) {
-        return getOptionValues( String.valueOf( opt ) );
+    public String[] getOptionValues(char opt)
+    {
+        return getOptionValues(String.valueOf(opt));
     }
-    
+
     /** 
-     * <p>Retrieve the argument, if any, of an option.</p>
+     * Retrieve the argument, if any, of an option.
      *
      * @param opt name of the option
-     * @param defaultValue is the default value to be returned if the option is not specified
+     * @param defaultValue is the default value to be returned if the option 
+     * is not specified
      * @return Value of the argument if option is set, and has an argument,
      * otherwise <code>defaultValue</code>.
      */
-    public String getOptionValue( String opt, String defaultValue ) {
-        String answer = getOptionValue( opt );
-        return ( answer != null ) ? answer : defaultValue;
+    public String getOptionValue(String opt, String defaultValue)
+    {
+        String answer = getOptionValue(opt);
+
+        return (answer != null) ? answer : defaultValue;
     }
-    
+
     /** 
-     * <p>Retrieve the argument, if any, of an option.</p>
+     * Retrieve the argument, if any, of an option.
      *
      * @param opt character name of the option
-     * @param defaultValue is the default value to be returned if the option is not specified
+     * @param defaultValue is the default value to be returned if the option 
+     * is not specified
      * @return Value of the argument if option is set, and has an argument,
      * otherwise <code>defaultValue</code>.
      */
-    public String getOptionValue( char opt, String defaultValue ) {
-        return getOptionValue( String.valueOf( opt ), defaultValue );
+    public String getOptionValue(char opt, String defaultValue)
+    {
+        return getOptionValue(String.valueOf(opt), defaultValue);
     }
 
     /** 
-     * <p>Retrieve any left-over non-recognized options and arguments</p>
+     * Retrieve any left-over non-recognized options and arguments
      *
      * @return remaining items passed in but not parsed as an array
      */
-    public String[] getArgs() {
-        String[] answer = new String[ args.size() ];
-        args.toArray( answer );
+    public String[] getArgs()
+    {
+        String[] answer = new String[args.size()];
+
+        args.toArray(answer);
+
         return answer;
     }
-    
+
     /** 
-     * <p>Retrieve any left-over non-recognized options and arguments</p>
+     * Retrieve any left-over non-recognized options and arguments
      *
      * @return remaining items passed in but not parsed as a <code>List</code>.
      */
-    public List getArgList() {
+    public List getArgList()
+    {
         return args;
     }
-    
+
     /** 
      * jkeyes
      * - commented out until it is implemented properly
@@ -254,75 +253,66 @@ public class CommandLine {
      *
      * @return Stringified form of this object
      */
+
     /*
     public String toString() {
         StringBuffer buf = new StringBuffer();
-        
-        buf.append( "[ CommandLine: [ options: " );
-        buf.append( options.toString() );
-        buf.append( " ] [ args: ");
-        buf.append( args.toString() );
-        buf.append( " ] ]" );
-        
+            
+        buf.append("[ CommandLine: [ options: ");
+        buf.append(options.toString());
+        buf.append(" ] [ args: ");
+        buf.append(args.toString());
+        buf.append(" ] ]");
+            
         return buf.toString();
     }
     */
 
     /**
-     * <p>Add left-over unrecognized option/argument.</p>
+     * Add left-over unrecognized option/argument.
      *
      * @param arg the unrecognised option/argument.
      */
-    void addArg(String arg) {
-        args.add( arg );
+    void addArg(String arg)
+    {
+        args.add(arg);
     }
-        
+
     /**
-     * <p>Add an option to the command line.  The values of 
-     * the option are stored.</p>
+     * Add an option to the command line.  The values of 
+     * the option are stored.
      *
      * @param opt the processed option
      */
-    void addOption( Option opt ) {
-        hashcodeMap.put( new Integer( opt.hashCode() ), opt );
-
-        String key = opt.getOpt();
-        if( " ".equals(key) ) {
-            key = opt.getLongOpt();
-        }
-
-        if( options.get( key ) != null ) {
-            ((java.util.List)options.get( key )).add( opt );
-        }
-        else {
-            options.put( key, new java.util.ArrayList() );
-            ((java.util.List)options.get( key ) ).add( opt );
-        }
+    void addOption(Option opt)
+    {
+        options.add(opt);
     }
 
     /**
-     * <p>Returns an iterator over the Option members of CommandLine.</p>
+     * Returns an iterator over the Option members of CommandLine.
      *
      * @return an <code>Iterator</code> over the processed {@link Option} 
      * members of this {@link CommandLine}
      */
-    public Iterator iterator( ) {
-        return hashcodeMap.values().iterator();
+    public Iterator iterator()
+    {
+        return options.iterator();
     }
 
     /**
-     * <p>Returns an array of the processed {@link Option}s.</p>
+     * Returns an array of the processed {@link Option}s.
      *
      * @return an array of the processed {@link Option}s.
      */
-    public Option[] getOptions( ) {
-        Collection processed = hashcodeMap.values();
+    public Option[] getOptions()
+    {
+        Collection processed = options;
 
         // reinitialise array
-        optionsArray = new Option[ processed.size() ];
+        Option[] optionsArray = new Option[processed.size()];
 
         // return the array
-        return (Option[]) processed.toArray( optionsArray );
+        return (Option[]) processed.toArray(optionsArray);
     }
-
-}
+}
\ No newline at end of file
diff --git a/src/java/org/apache/commons/cli/CommandLineParser.java b/src/java/org/apache/commons/cli/CommandLineParser.java
index f2e6186..f165d99 100644
--- a/src/java/org/apache/commons/cli/CommandLineParser.java
+++ b/src/java/org/apache/commons/cli/CommandLineParser.java
@@ -1,65 +1,23 @@
-/*
- * $Header: /home/cvspublic/jakarta-commons/cli/src/java/org/apache/commons/cli/CommandLineParser.java,v 1.4 2002/09/19 22:59:43 jkeyes Exp $
- * $Revision: 1.4 $
- * $Date: 2002/09/19 22:59:43 $
- *
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 package org.apache.commons.cli;
 
+import java.util.Properties;
+
 /**
  * A class that implements the <code>CommandLineParser</code> interface 
  * can parse a String array according to the {@link Options} specified
@@ -68,18 +26,39 @@ package org.apache.commons.cli;
  * @author John Keyes (john at integralsource.com)
  */
 public interface CommandLineParser {
-    
+
     /**
      * Parse the arguments according to the specified options.
      *
      * @param options the specified Options
      * @param arguments the command line arguments
      * @return the list of atomic option and value tokens
+     *
+     * @throws ParseException if there are any problems encountered
+     * while parsing the command line tokens.
+     */
+    CommandLine parse(Options options, String[] arguments)
+               throws ParseException;
+
+    /**
+     * Parse the arguments according to the specified options and
+     * properties.
+     *
+     * @param options the specified Options
+     * @param arguments the command line arguments
+     * @param properties command line option name-value pairs
+     * @return the list of atomic option and value tokens
+     *
      * @throws ParseException if there are any problems encountered
      * while parsing the command line tokens.
      */
-    public CommandLine parse( Options options, String[] arguments )
-    throws ParseException;
+    /* To maintain binary compatibility, this is commented out. 
+       It is still in the abstract Parser class, so most users will 
+       still reap the benefit. 
+    CommandLine parse(Options options, String[] arguments, 
+                      Properties properties)
+               throws ParseException;
+     */
 
     /**
      * Parse the arguments according to the specified options.
@@ -88,10 +67,33 @@ public interface CommandLineParser {
      * @param arguments the command line arguments
      * @param stopAtNonOption specifies whether to continue parsing the
      * arguments if a non option is encountered.
+     *
      * @return the list of atomic option and value tokens
      * @throws ParseException if there are any problems encountered
      * while parsing the command line tokens.
      */
-    public CommandLine parse( Options options, String[] arguments, boolean stopAtNonOption )
-    throws ParseException;
-}
\ No newline at end of file
+    CommandLine parse(Options options, String[] arguments, 
+                      boolean stopAtNonOption)
+               throws ParseException;
+
+    /**
+     * Parse the arguments according to the specified options and
+     * properties.
+     *
+     * @param options the specified Options
+     * @param arguments the command line arguments
+     * @param properties command line option name-value pairs
+     * @param stopAtNonOption specifies whether to continue parsing the
+     *
+     * @return the list of atomic option and value tokens
+     * @throws ParseException if there are any problems encountered
+     * while parsing the command line tokens.
+     */
+    /* To maintain binary compatibility, this is commented out. 
+       It is still in the abstract Parser class, so most users will 
+       still reap the benefit. 
+    CommandLine parse(Options options, String[] arguments, 
+                      Properties properties, boolean stopAtNonOption)
+               throws ParseException;
+     */
+}
diff --git a/src/java/org/apache/commons/cli/GnuParser.java b/src/java/org/apache/commons/cli/GnuParser.java
index 198c015..dd5f3d7 100644
--- a/src/java/org/apache/commons/cli/GnuParser.java
+++ b/src/java/org/apache/commons/cli/GnuParser.java
@@ -1,69 +1,22 @@
-/*
- * $Header: /home/cvspublic/jakarta-commons/cli/src/java/org/apache/commons/cli/GnuParser.java,v 1.10 2002/09/19 22:59:43 jkeyes Exp $
- * $Revision: 1.10 $
- * $Date: 2002/09/19 22:59:43 $
- *
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 package org.apache.commons.cli;
 
-import java.util.Arrays;
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
 
 /**
  * The class GnuParser provides an implementation of the 
@@ -71,7 +24,7 @@ import java.util.Iterator;
  *
  * @author John Keyes (john at integralsource.com)
  * @see Parser
- * @version $Revision: 1.10 $
+ * @version $Revision: 542151 $
  */
 public class GnuParser extends Parser {
 
@@ -82,7 +35,8 @@ public class GnuParser extends Parser {
      * <p>Resets the members to their original state i.e. remove
      * all of <code>tokens</code> entries.
      */
-    private void init() {
+    private void init()
+    {
         tokens.clear();
     }
 
@@ -98,90 +52,127 @@ public class GnuParser extends Parser {
      *  </li>
      * </ol>
      * </p>
+     *
+     * @param options The Options to parse the arguments by.
+     * @param arguments The arguments that have to be flattened.
+     * @param stopAtNonOption specifies whether to stop 
+     * flattening when a non option has been encountered
+     * @return a String array of the flattened arguments
      */
-    protected String[] flatten( Options options, 
-                                String[] arguments, 
-                                boolean stopAtNonOption )
+    protected String[] flatten(Options options, String[] arguments, 
+                               boolean stopAtNonOption)
     {
         init();
+
         boolean eatTheRest = false;
         Option currentOption = null;
 
-        for( int i = 0; i < arguments.length; i++ ) {
-            if( "--".equals( arguments[i] ) ) {
+        for (int i = 0; i < arguments.length; i++)
+        {
+            if ("--".equals(arguments[i]))
+            {
                 eatTheRest = true;
-                tokens.add( "--" );
+                tokens.add("--");
             }
-            else if ( "-".equals( arguments[i] ) ) {
-                tokens.add( "-" );
+            else if ("-".equals(arguments[i]))
+            {
+                tokens.add("-");
             }
-            else if( arguments[i].startsWith( "-" ) ) {
-                Option option = options.getOption( arguments[i] );
+            else if (arguments[i].startsWith("-"))
+            {
+                Option option = options.getOption(arguments[i]);
 
                 // this is not an Option
-                if( option == null ) {
+                if (option == null)
+                {
                     // handle special properties Option
-                    Option specialOption = options.getOption( arguments[i].substring(0,2) );
-                    if( specialOption != null ) {
-                        tokens.add( arguments[i].substring(0,2) );
-                        tokens.add( arguments[i].substring(2) );
+                    Option specialOption = 
+                            options.getOption(arguments[i].substring(0, 2));
+
+                    if (specialOption != null)
+                    {
+                        tokens.add(arguments[i].substring(0, 2));
+                        tokens.add(arguments[i].substring(2));
                     }
-                    else if( stopAtNonOption ) {
+                    else if (stopAtNonOption)
+                    {
                         eatTheRest = true;
-                        tokens.add( arguments[i] );
+                        tokens.add(arguments[i]);
                     }
-                    else {
-                        tokens.add( arguments[i] );
+                    else
+                    {
+                        tokens.add(arguments[i]);
                     }
                 }
-                else {
+                else
+                {
+                    // WARNING: Findbugs reports major problems with the following code. 
+                    //          As option cannot be null, currentOption cannot and 
+                    //          much of the code below is never going to be run.
+
                     currentOption = option;
+
                     // special option
-                    Option specialOption = options.getOption( arguments[i].substring(0,2) );
-                    if( specialOption != null && option == null ) {
-                        tokens.add( arguments[i].substring(0,2) );
-                        tokens.add( arguments[i].substring(2) );
+                    Option specialOption = 
+                            options.getOption(arguments[i].substring(0, 2));
+
+                    if ((specialOption != null) && (option == null))
+                    {
+                        tokens.add(arguments[i].substring(0, 2));
+                        tokens.add(arguments[i].substring(2));
                     }
-                    else if( currentOption != null && currentOption.hasArg() ) {
-                        if( currentOption.hasArg() ) {
-                            tokens.add( arguments[i] );
-                            currentOption= null;
+                    else if ((currentOption != null) && currentOption.hasArg())
+                    {
+                        if (currentOption.hasArg())
+                        {
+                            tokens.add(arguments[i]);
+                            currentOption = null;
                         }
-                        else if ( currentOption.hasArgs() ) {
-                            tokens.add( arguments[i] );
+                        else if (currentOption.hasArgs())
+                        {
+                            tokens.add(arguments[i]);
                         }
-                        else if ( stopAtNonOption ) {
+                        else if (stopAtNonOption)
+                        {
                             eatTheRest = true;
-                            tokens.add( "--" );
-                            tokens.add( arguments[i] );
+                            tokens.add("--");
+                            tokens.add(arguments[i]);
                         }
-                        else {
-                            tokens.add( arguments[i] );
+                        else
+                        {
+                            tokens.add(arguments[i]);
                         }
-                    } 
-                    else if (currentOption != null ) {
-                        tokens.add( arguments[i] );
-                    } 
-                    else if ( stopAtNonOption ) {
+                    }
+                    else if (currentOption != null)
+                    {
+                        tokens.add(arguments[i]);
+                    }
+                    else if (stopAtNonOption)
+                    {
                         eatTheRest = true;
-                        tokens.add( "--" );
-                        tokens.add( arguments[i] );
+                        tokens.add("--");
+                        tokens.add(arguments[i]);
                     }
-                    else {
-                        tokens.add( arguments[i] );
+                    else
+                    {
+                        tokens.add(arguments[i]);
                     }
                 }
             }
-            else {
-                tokens.add( arguments[i] );
+            else
+            {
+                tokens.add(arguments[i]);
             }
 
-            if( eatTheRest ) {
-                for( i++; i < arguments.length; i++ ) {
-                    tokens.add( arguments[i] );
+            if (eatTheRest)
+            {
+                for (i++; i < arguments.length; i++)
+                {
+                    tokens.add(arguments[i]);
                 }
             }
         }
-        return (String[])tokens.toArray( new String[] {} );
+
+        return (String[]) tokens.toArray(new String[tokens.size()]);
     }
-}
\ No newline at end of file
+}
diff --git a/src/java/org/apache/commons/cli/HelpFormatter.java b/src/java/org/apache/commons/cli/HelpFormatter.java
index 1cffbf5..639b9d5 100644
--- a/src/java/org/apache/commons/cli/HelpFormatter.java
+++ b/src/java/org/apache/commons/cli/HelpFormatter.java
@@ -1,67 +1,23 @@
-/*
- * $Header: /home/cvs/jakarta-commons-sandbox/cli/src/java/org/apache/commons/cli/CommandLine.java,v 1.4 2002/06/06 22:32:37 bayard Exp $
- * $Revision: 1.4 $
- * $Date: 2002/06/06 22:32:37 $
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
 import java.io.PrintWriter;
+
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -75,466 +31,927 @@ import java.util.List;
  * @author Slawek Zachcial
  * @author John Keyes (john at integralsource.com)
  **/
-public class HelpFormatter
-{
-   // --------------------------------------------------------------- Constants
-
-   public static final int DEFAULT_WIDTH              = 74;
-   public static final int DEFAULT_LEFT_PAD           = 1;
-   public static final int DEFAULT_DESC_PAD           = 3;
-   public static final String DEFAULT_SYNTAX_PREFIX   = "usage: ";
-   public static final String DEFAULT_OPT_PREFIX      = "-";
-   public static final String DEFAULT_LONG_OPT_PREFIX = "--";
-   public static final String DEFAULT_ARG_NAME        = "arg";
-
-   // ------------------------------------------------------------------ Static
-
-   // -------------------------------------------------------------- Attributes
-
-   public int defaultWidth;
-   public int defaultLeftPad;
-   public int defaultDescPad;
-   public String defaultSyntaxPrefix;
-   public String defaultNewLine;
-   public String defaultOptPrefix;
-   public String defaultLongOptPrefix;
-   public String defaultArgName;
-
-   // ------------------------------------------------------------ Constructors
-   public HelpFormatter()
-   {
-      defaultWidth = DEFAULT_WIDTH;
-      defaultLeftPad = DEFAULT_LEFT_PAD;
-      defaultDescPad = DEFAULT_DESC_PAD;
-      defaultSyntaxPrefix = DEFAULT_SYNTAX_PREFIX;
-      defaultNewLine = System.getProperty("line.separator");
-      defaultOptPrefix = DEFAULT_OPT_PREFIX;
-      defaultLongOptPrefix = DEFAULT_LONG_OPT_PREFIX;
-      defaultArgName = DEFAULT_ARG_NAME;
-   }
-
-   // ------------------------------------------------------------------ Public
-
-   public void printHelp( String cmdLineSyntax,
-                          Options options )
-   {
-       printHelp( defaultWidth, cmdLineSyntax, null, options, null, false );
-   }
-
-   public void printHelp( String cmdLineSyntax,
-                          Options options,
-                          boolean autoUsage )
-   {
-       printHelp( defaultWidth, cmdLineSyntax, null, options, null, autoUsage );
-   }
-
-   public void printHelp( String cmdLineSyntax,
-                          String header,
-                          Options options,
-                          String footer )
-   {
-       printHelp( cmdLineSyntax, header, options, footer, false );
-   }
-
-   public void printHelp( String cmdLineSyntax,
-                          String header,
-                          Options options,
-                          String footer,
-                          boolean autoUsage )
-   {
-      printHelp(defaultWidth, cmdLineSyntax, header, options, footer, autoUsage );
-   }
-   
-   public void printHelp( int width,
-                          String cmdLineSyntax,
-                          String header,
-                          Options options,
-                          String footer )
-   {
-       printHelp( width, cmdLineSyntax, header, options, footer, false );
-   }
-
-   public void printHelp( int width,
-                          String cmdLineSyntax,
-                          String header,
-                          Options options,
-                          String footer,
-                          boolean autoUsage )
-   {
-      PrintWriter pw = new PrintWriter(System.out);
-      printHelp( pw, width, cmdLineSyntax, header,
-                 options, defaultLeftPad, defaultDescPad, footer, autoUsage );
-      pw.flush();
-   }
-   public void printHelp( PrintWriter pw,
-                          int width,
-                          String cmdLineSyntax,
-                          String header,
-                          Options options,
-                          int leftPad,
-                          int descPad,
-                          String footer )
-   throws IllegalArgumentException
-   {
-       printHelp( pw, width, cmdLineSyntax, header, options, leftPad, descPad, footer, false );
-   }
-
-   public void printHelp( PrintWriter pw,
-                          int width,
-                          String cmdLineSyntax,
-                          String header,
-                          Options options,
-                          int leftPad,
-                          int descPad,
-                          String footer,
-                          boolean autoUsage )
-      throws IllegalArgumentException
-   {
-      if ( cmdLineSyntax == null || cmdLineSyntax.length() == 0 )
-      {
-         throw new IllegalArgumentException("cmdLineSyntax not provided");
-      }
-
-      if ( autoUsage ) {
-          printUsage( pw, width, cmdLineSyntax, options );
-      }
-      else {
-          printUsage( pw, width, cmdLineSyntax );
-      }
-
-      if ( header != null && header.trim().length() > 0 )
-      {
-         printWrapped( pw, width, header );
-      }
-      printOptions( pw, width, options, leftPad, descPad );
-      if ( footer != null && footer.trim().length() > 0 )
-      {
-         printWrapped( pw, width, footer );
-      }
-   }
-
-   /**
-    * <p>Prints the usage statement for the specified application.</p>
-    *
-    * @param pw The PrintWriter to print the usage statement 
-    * @param width ??
-    * @param appName The application name
-    * @param options The command line Options
-    *
-    */
-   public void printUsage( PrintWriter pw, int width, String app, Options options ) 
-   {
-       // initialise the string buffer
-       StringBuffer buff = new StringBuffer( defaultSyntaxPrefix ).append( app ).append( " " );
-       
-       // create a list for processed option groups
-       ArrayList list = new ArrayList();
-
-       // temp variable
-       Option option;
-
-       // iterate over the options
-       for ( Iterator i = options.getOptions().iterator(); i.hasNext(); )
-       {
-           // get the next Option
-           option = (Option) i.next();
-
-           // check if the option is part of an OptionGroup
-           OptionGroup group = options.getOptionGroup( option );
-
-           // if the option is part of a group and the group has not already
-           // been processed
-           if( group != null && !list.contains(group)) {
-
-               // add the group to the processed list
-               list.add( group );
-
-               // get the names of the options from the OptionGroup
-               Collection names = group.getNames();
-
-               buff.append( "[" ); 
-
-               // for each option in the OptionGroup
-               for( Iterator iter = names.iterator(); iter.hasNext(); ) {
-                   buff.append( iter.next() );
-                   if( iter.hasNext() ) {
-                       buff.append( " | " );
-                   }
-               }
-               buff.append( "]" );
-           }
-           // if the Option is not part of an OptionGroup
-           else {
-               // if the Option is not a required option
-               if( !option.isRequired() ) {
-                   buff.append( "[" );
-               }
-               
-               if( !" ".equals( option.getOpt() ) ) {
-                   buff.append( "-" ).append( option.getOpt() );
-               }
-               else {
-                   buff.append( "--" ).append( option.getLongOpt() );
-               }
-
-               if( option.hasArg() ){
-                   buff.append( " " );
-               }
-
-               // if the Option has a value
-               if( option.hasArg() ) {
-                   buff.append( option.getArgName() );
-               }
-
-               // if the Option is not a required option
-               if( !option.isRequired() ) {
-                   buff.append( "]" );
-               }
-               buff.append( " " );
-           }
-       }
-
-       // call printWrapped
-       printWrapped( pw, width, buff.toString().indexOf(' ')+1,
-                     buff.toString() );
-   }
-
-   public void printUsage( PrintWriter pw, int width, String cmdLineSyntax )
-   {
-      int argPos = cmdLineSyntax.indexOf(' ') + 1;
-      printWrapped(pw, width, defaultSyntaxPrefix.length() + argPos,
-                   defaultSyntaxPrefix + cmdLineSyntax);
-   }
-
-   public void printOptions( PrintWriter pw, int width, Options options, int leftPad, int descPad )
-   {
-      StringBuffer sb = new StringBuffer();
-      renderOptions(sb, width, options, leftPad, descPad);
-      pw.println(sb.toString());
-   }
-
-   public void printWrapped( PrintWriter pw, int width, String text )
-   {
-      printWrapped(pw, width, 0, text);
-   }
-
-   public void printWrapped( PrintWriter pw, int width, int nextLineTabStop, String text )
-   {
-      StringBuffer sb = new StringBuffer(text.length());
-      renderWrappedText(sb, width, nextLineTabStop, text);
-      pw.println(sb.toString());
-   }
-
-   // --------------------------------------------------------------- Protected
-
-   protected StringBuffer renderOptions( StringBuffer sb,
-                                         int width,
-                                         Options options,
-                                         int leftPad,
-                                         int descPad )
-   {
-      final String lpad = createPadding(leftPad);
-      final String dpad = createPadding(descPad);
-
-      //first create list containing only <lpad>-a,--aaa where -a is opt and --aaa is
-      //long opt; in parallel look for the longest opt string
-      //this list will be then used to sort options ascending
-      int max = 0;
-      StringBuffer optBuf;
-      List prefixList = new ArrayList();
-      Option option;
-      List optList = options.helpOptions();
-      Collections.sort( optList, new StringBufferComparator() );
-      for ( Iterator i = optList.iterator(); i.hasNext(); )
-      {
-         option = (Option) i.next();
-         optBuf = new StringBuffer(8);
-
-         if (option.getOpt().equals(" "))
-         {
-             optBuf.append(lpad).append("   " + defaultLongOptPrefix).append(option.getLongOpt());
-         }
-         else
-         {
-             optBuf.append(lpad).append(defaultOptPrefix).append(option.getOpt());
-             if ( option.hasLongOpt() )
-             {
-                optBuf.append(',').append(defaultLongOptPrefix).append(option.getLongOpt());
-             }
-
-         }
-
-         if( option.hasArg() ) {
-             if( option.hasArgName() ) {
-                 optBuf.append(" <").append( option.getArgName() ).append( '>' );
-             }
-             else {
-                 optBuf.append(' ');
-             }
-         }
-
-         prefixList.add(optBuf);
-         max = optBuf.length() > max ? optBuf.length() : max;
-      }
-      int x = 0;
-      for ( Iterator i = optList.iterator(); i.hasNext(); )
-      {
-         option = (Option) i.next();
-         optBuf = new StringBuffer( prefixList.get( x++ ).toString() );
-
-         if ( optBuf.length() < max )
-         {
-             optBuf.append(createPadding(max - optBuf.length()));
-         }
-         optBuf.append( dpad );
-         
-         int nextLineTabStop = max + descPad;
-         renderWrappedText(sb, width, nextLineTabStop,
-                           optBuf.append(option.getDescription()).toString());
-         if ( i.hasNext() )
-         {
-             sb.append(defaultNewLine);
-         }
-      }
-
-      return sb;
-   }
-
-   protected StringBuffer renderWrappedText( StringBuffer sb,
-                                             int width,
-                                             int nextLineTabStop,
-                                             String text )
-   {
-      int pos = findWrapPos( text, width, 0);
-      if ( pos == -1 )
-      {
-         sb.append(rtrim(text));
-         return sb;
-      }
-      else
-      {
-         sb.append(rtrim(text.substring(0, pos))).append(defaultNewLine);
-      }
-
-      //all following lines must be padded with nextLineTabStop space characters
-      final String padding = createPadding(nextLineTabStop);
-
-      while ( true )
-      {
-         text = padding + text.substring(pos).trim();
-         pos = findWrapPos( text, width, nextLineTabStop );
-         if ( pos == -1 )
-         {
-            sb.append(text);
-            return sb;
-         }
-
-         sb.append(rtrim(text.substring(0, pos))).append(defaultNewLine);
-      }
-
-   }
-
-   /**
-    * Finds the next text wrap position after <code>startPos</code> for the text
-    * in <code>sb</code> with the column width <code>width</code>.
-    * The wrap point is the last postion before startPos+width having a whitespace
-    * character (space, \n, \r).
-    *
-    * @param sb text to be analyzed
-    * @param width width of the wrapped text
-    * @param startPos position from which to start the lookup whitespace character
-    * @return postion on which the text must be wrapped or -1 if the wrap position is at the end
-    *         of the text
-    */
-   protected int findWrapPos( String text, int width, int startPos )
-   {
-      int pos = -1;
-      // the line ends before the max wrap pos or a new line char found
-      if ( ((pos = text.indexOf('\n', startPos)) != -1 && pos <= width)  ||
-           ((pos = text.indexOf('\t', startPos)) != -1 && pos <= width) )
-      {
-         return pos;
-      }
-      else if ( (startPos + width) >= text.length() )
-      {
-         return -1;
-      }
-
-      //look for the last whitespace character before startPos+width
-      pos = startPos + width;
-      char c;
-      while ( pos >= startPos && (c = text.charAt(pos)) != ' ' && c != '\n' && c != '\r' )
-      {
-         --pos;
-      }
-      //if we found it - just return
-      if ( pos > startPos )
-      {
-         return pos;
-      }
-      else
-      {
-         //must look for the first whitespace chearacter after startPos + width
-         pos = startPos + width;
-         while ( pos <= text.length() && (c = text.charAt(pos)) != ' ' && c != '\n' && c != '\r' )
-         {
-            ++pos;
-         }
-         return pos == text.length() ? -1 : pos;
-      }
-   }
-
-   protected String createPadding(int len)
-   {
-      StringBuffer sb = new StringBuffer(len);
-      for ( int i = 0; i < len; ++i )
-      {
-         sb.append(' ');
-      }
-      return sb.toString();
-   }
-
-   protected String rtrim( String s )
-   {
-      if ( s == null || s.length() == 0 )
-      {
-         return s;
-      }
-
-      int pos = s.length();
-      while ( pos >= 0 && Character.isWhitespace(s.charAt(pos-1)) )
-      {
-         --pos;
-      }
-      return s.substring(0, pos);
-   }
-
-   // ------------------------------------------------------- Package protected
-   
-   // ----------------------------------------------------------------- Private
-   
-   // ----------------------------------------------------------- Inner classes
-
-    private static class StringBufferComparator
-    implements Comparator
-    {
-        public int compare( Object o1, Object o2 )
+public class HelpFormatter {
+    // --------------------------------------------------------------- Constants
+
+    /** default number of characters per line */
+    public static final int DEFAULT_WIDTH = 74;
+
+    /** default padding to the left of each line */
+    public static final int DEFAULT_LEFT_PAD = 1;
+
+    /**
+     * the number of characters of padding to be prefixed
+     * to each description line
+     */
+    public static final int DEFAULT_DESC_PAD = 3;
+
+    /** the string to display at the begining of the usage statement */
+    public static final String DEFAULT_SYNTAX_PREFIX = "usage: ";
+
+    /** default prefix for shortOpts */
+    public static final String DEFAULT_OPT_PREFIX = "-";
+
+    /** default prefix for long Option */
+    public static final String DEFAULT_LONG_OPT_PREFIX = "--";
+
+    /** default name for an argument */
+    public static final String DEFAULT_ARG_NAME = "arg";
+
+    // -------------------------------------------------------------- Attributes
+
+    /**
+     * number of characters per line
+     *
+     * @deprecated Scope will be made private for next major version
+     * - use get/setWidth methods instead.
+     */
+    public int defaultWidth = DEFAULT_WIDTH;
+
+    /**
+     * amount of padding to the left of each line
+     *
+     * @deprecated Scope will be made private for next major version
+     * - use get/setLeftPadding methods instead.
+     */
+    public int defaultLeftPad = DEFAULT_LEFT_PAD;
+
+    /**
+     * the number of characters of padding to be prefixed
+     * to each description line
+     *
+     * @deprecated Scope will be made private for next major version
+     * - use get/setDescPadding methods instead.
+     */
+    public int defaultDescPad = DEFAULT_DESC_PAD;
+
+    /**
+     * the string to display at the begining of the usage statement
+     *
+     * @deprecated Scope will be made private for next major version
+     * - use get/setSyntaxPrefix methods instead.
+     */
+    public String defaultSyntaxPrefix = DEFAULT_SYNTAX_PREFIX;
+
+    /**
+     * the new line string
+     *
+     * @deprecated Scope will be made private for next major version
+     * - use get/setNewLine methods instead.
+     */
+    public String defaultNewLine = System.getProperty("line.separator");
+
+    /**
+     * the shortOpt prefix
+     *
+     * @deprecated Scope will be made private for next major version
+     * - use get/setOptPrefix methods instead.
+     */
+    public String defaultOptPrefix = DEFAULT_OPT_PREFIX;
+
+    /**
+     * the long Opt prefix
+     *
+     * @deprecated Scope will be made private for next major version
+     * - use get/setLongOptPrefix methods instead.
+     */
+    public String defaultLongOptPrefix = DEFAULT_LONG_OPT_PREFIX;
+
+    /**
+     * the name of the argument
+     *
+     * @deprecated Scope will be made private for next major version
+     * - use get/setArgName methods instead.
+     */
+    public String defaultArgName = DEFAULT_ARG_NAME;
+
+    /**
+     * Sets the 'width'.
+     *
+     * @param width the new value of 'width'
+     */
+    public void setWidth(int width)
+    {
+        this.defaultWidth = width;
+    }
+
+    /**
+     * Returns the 'width'.
+     *
+     * @return the 'width'
+     */
+    public int getWidth()
+    {
+        return this.defaultWidth;
+    }
+
+    /**
+     * Sets the 'leftPadding'.
+     *
+     * @param padding the new value of 'leftPadding'
+     */
+    public void setLeftPadding(int padding)
+    {
+        this.defaultLeftPad = padding;
+    }
+
+    /**
+     * Returns the 'leftPadding'.
+     *
+     * @return the 'leftPadding'
+     */
+    public int getLeftPadding()
+    {
+        return this.defaultLeftPad;
+    }
+
+    /**
+     * Sets the 'descPadding'.
+     *
+     * @param padding the new value of 'descPadding'
+     */
+    public void setDescPadding(int padding)
+    {
+        this.defaultDescPad = padding;
+    }
+
+    /**
+     * Returns the 'descPadding'.
+     *
+     * @return the 'descPadding'
+     */
+    public int getDescPadding()
+    {
+        return this.defaultDescPad;
+    }
+
+    /**
+     * Sets the 'syntaxPrefix'.
+     *
+     * @param prefix the new value of 'syntaxPrefix'
+     */
+    public void setSyntaxPrefix(String prefix)
+    {
+        this.defaultSyntaxPrefix = prefix;
+    }
+
+    /**
+     * Returns the 'syntaxPrefix'.
+     *
+     * @return the 'syntaxPrefix'
+     */
+    public String getSyntaxPrefix()
+    {
+        return this.defaultSyntaxPrefix;
+    }
+
+    /**
+     * Sets the 'newLine'.
+     *
+     * @param newline the new value of 'newLine'
+     */
+    public void setNewLine(String newline)
+    {
+        this.defaultNewLine = newline;
+    }
+
+    /**
+     * Returns the 'newLine'.
+     *
+     * @return the 'newLine'
+     */
+    public String getNewLine()
+    {
+        return this.defaultNewLine;
+    }
+
+    /**
+     * Sets the 'optPrefix'.
+     *
+     * @param prefix the new value of 'optPrefix'
+     */
+    public void setOptPrefix(String prefix)
+    {
+        this.defaultOptPrefix = prefix;
+    }
+
+    /**
+     * Returns the 'optPrefix'.
+     *
+     * @return the 'optPrefix'
+     */
+    public String getOptPrefix()
+    {
+        return this.defaultOptPrefix;
+    }
+
+    /**
+     * Sets the 'longOptPrefix'.
+     *
+     * @param prefix the new value of 'longOptPrefix'
+     */
+    public void setLongOptPrefix(String prefix)
+    {
+        this.defaultLongOptPrefix = prefix;
+    }
+
+    /**
+     * Returns the 'longOptPrefix'.
+     *
+     * @return the 'longOptPrefix'
+     */
+    public String getLongOptPrefix()
+    {
+        return this.defaultLongOptPrefix;
+    }
+
+    /**
+     * Sets the 'argName'.
+     *
+     * @param name the new value of 'argName'
+     */
+    public void setArgName(String name)
+    {
+        this.defaultArgName = name;
+    }
+
+    /**
+     * Returns the 'argName'.
+     *
+     * @return the 'argName'
+     */
+    public String getArgName()
+    {
+        return this.defaultArgName;
+    }
+
+
+    // ------------------------------------------------------------------ Public
+
+    /**
+     * <p>Print the help for <code>options</code> with the specified
+     * command line syntax.  This method prints help information to
+     * System.out.</p>
+     *
+     * @param cmdLineSyntax the syntax for this application
+     * @param options the Options instance
+     */
+    public void printHelp(String cmdLineSyntax, Options options)
+    {
+        printHelp(defaultWidth, cmdLineSyntax, null, options, null, false);
+    }
+
+    /**
+     * <p>Print the help for <code>options</code> with the specified
+     * command line syntax.  This method prints help information to 
+     * System.out.</p>
+     *
+     * @param cmdLineSyntax the syntax for this application
+     * @param options the Options instance
+     * @param autoUsage whether to print an automatically generated 
+     * usage statement
+     */
+    public void printHelp(String cmdLineSyntax, Options options, 
+                          boolean autoUsage)
+    {
+        printHelp(defaultWidth, cmdLineSyntax, null, options, null, autoUsage);
+    }
+
+    /**
+     * <p>Print the help for <code>options</code> with the specified
+     * command line syntax.  This method prints help information to
+     * System.out.</p>
+     *
+     * @param cmdLineSyntax the syntax for this application
+     * @param header the banner to display at the begining of the help
+     * @param options the Options instance
+     * @param footer the banner to display at the end of the help
+     */
+    public void printHelp(String cmdLineSyntax, String header, Options options, 
+                          String footer)
+    {
+        printHelp(cmdLineSyntax, header, options, footer, false);
+    }
+
+    /**
+     * <p>Print the help for <code>options</code> with the specified
+     * command line syntax.  This method prints help information to 
+     * System.out.</p>
+     *
+     * @param cmdLineSyntax the syntax for this application
+     * @param header the banner to display at the begining of the help
+     * @param options the Options instance
+     * @param footer the banner to display at the end of the help
+     * @param autoUsage whether to print an automatically generated 
+     * usage statement
+     */
+    public void printHelp(String cmdLineSyntax, String header, Options options, 
+                          String footer, boolean autoUsage)
+    {
+        printHelp(defaultWidth, cmdLineSyntax, header, options, footer, 
+                  autoUsage);
+    }
+
+    /**
+     * <p>Print the help for <code>options</code> with the specified
+     * command line syntax.  This method prints help information to
+     * System.out.</p>
+     *
+     * @param width the number of characters to be displayed on each line
+     * @param cmdLineSyntax the syntax for this application
+     * @param header the banner to display at the begining of the help
+     * @param options the Options instance
+     * @param footer the banner to display at the end of the help
+     */
+    public void printHelp(int width, String cmdLineSyntax, String header, 
+                          Options options, String footer)
+    {
+        printHelp(width, cmdLineSyntax, header, options, footer, false);
+    }
+
+    /**
+     * <p>Print the help for <code>options</code> with the specified
+     * command line syntax.  This method prints help information to
+     * System.out.</p>
+     *
+     * @param width the number of characters to be displayed on each line
+     * @param cmdLineSyntax the syntax for this application
+     * @param header the banner to display at the begining of the help
+     * @param options the Options instance
+     * @param footer the banner to display at the end of the help
+     * @param autoUsage whether to print an automatically generated 
+     * usage statement
+     */
+    public void printHelp(int width, String cmdLineSyntax, String header, 
+                          Options options, String footer, boolean autoUsage)
+    {
+        PrintWriter pw = new PrintWriter(System.out);
+
+        printHelp(pw, width, cmdLineSyntax, header, options, defaultLeftPad, 
+                  defaultDescPad, footer, autoUsage);
+        pw.flush();
+    }
+
+    /**
+     * <p>Print the help for <code>options</code> with the specified
+     * command line syntax.</p>
+     *
+     * @param pw the writer to which the help will be written
+     * @param width the number of characters to be displayed on each line
+     * @param cmdLineSyntax the syntax for this application
+     * @param header the banner to display at the begining of the help
+     * @param options the Options instance
+     * @param leftPad the number of characters of padding to be prefixed
+     * to each line
+     * @param descPad the number of characters of padding to be prefixed
+     * to each description line
+     * @param footer the banner to display at the end of the help
+     */
+    public void printHelp(PrintWriter pw, int width, String cmdLineSyntax, 
+                          String header, Options options, int leftPad, 
+                          int descPad, String footer)
+    {
+        printHelp(pw, width, cmdLineSyntax, header, options, leftPad, descPad, 
+                  footer, false);
+    }
+
+
+    /**
+     * <p>Print the help for <code>options</code> with the specified
+     * command line syntax.</p>
+     *
+     * @param pw the writer to which the help will be written
+     * @param width the number of characters to be displayed on each line
+     * @param cmdLineSyntax the syntax for this application
+     * @param header the banner to display at the begining of the help
+     * @param options the Options instance
+     * @param leftPad the number of characters of padding to be prefixed
+     * to each line
+     * @param descPad the number of characters of padding to be prefixed
+     * to each description line
+     * @param footer the banner to display at the end of the help
+     * @param autoUsage whether to print an automatically generated 
+     * usage statement
+     */
+    public void printHelp(PrintWriter pw, int width, String cmdLineSyntax, 
+                          String header, Options options, int leftPad, 
+                          int descPad, String footer, boolean autoUsage)
+    {
+        if ((cmdLineSyntax == null) || (cmdLineSyntax.length() == 0))
+        {
+            throw new IllegalArgumentException("cmdLineSyntax not provided");
+        }
+
+        if (autoUsage)
+        {
+            printUsage(pw, width, cmdLineSyntax, options);
+        }
+        else
+        {
+            printUsage(pw, width, cmdLineSyntax);
+        }
+
+        if ((header != null) && (header.trim().length() > 0))
+        {
+            printWrapped(pw, width, header);
+        }
+
+        printOptions(pw, width, options, leftPad, descPad);
+
+        if ((footer != null) && (footer.trim().length() > 0))
+        {
+            printWrapped(pw, width, footer);
+        }
+    }
+
+    /**
+     * <p>Prints the usage statement for the specified application.</p>
+     *
+     * @param pw The PrintWriter to print the usage statement 
+     * @param width The number of characters to display per line
+     * @param app The application name
+     * @param options The command line Options
+     *
+     */
+    public void printUsage(PrintWriter pw, int width, String app, 
+                           Options options)
+    {
+        // initialise the string buffer
+        StringBuffer buff = new StringBuffer(defaultSyntaxPrefix).append(app)
+                                                                 .append(" ");
+
+        // create a list for processed option groups
+        final Collection processedGroups = new ArrayList();
+
+        // temp variable
+        Option option;
+
+        List optList = new ArrayList(options.getOptions());
+        Collections.sort(optList, new OptionComparator());
+        // iterate over the options
+        for (Iterator i = optList.iterator(); i.hasNext();)
+        {
+            // get the next Option
+            option = (Option) i.next();
+
+            // check if the option is part of an OptionGroup
+            OptionGroup group = options.getOptionGroup(option);
+
+            // if the option is part of a group 
+            if (group != null)
+            {
+                // and if the group has not already been processed
+                if (!processedGroups.contains(group))
+                {
+                    // add the group to the processed list
+                    processedGroups.add(group);
+
+
+                    // add the usage clause
+                    appendOptionGroup(buff, group);
+                }
+
+                // otherwise the option was displayed in the group
+                // previously so ignore it.
+            }
+
+            // if the Option is not part of an OptionGroup
+            else
+            {
+                appendOption(buff, option, option.isRequired());
+            }
+
+            if (i.hasNext())
+            {
+                buff.append(" ");
+            }
+        }
+
+
+        // call printWrapped
+        printWrapped(pw, width, buff.toString().indexOf(' ') + 1, 
+                     buff.toString());
+    }
+
+    /**
+     * Appends the usage clause for an OptionGroup to a StringBuffer.  
+     * The clause is wrapped in square brackets if the group is required.
+     * The display of the options is handled by appendOption
+     * @param buff the StringBuffer to append to
+     * @param group the group to append
+     * @see #appendOption(StringBuffer,Option,boolean)
+     */
+    private static void appendOptionGroup(final StringBuffer buff, 
+                                          final OptionGroup group)
+    {
+        if (!group.isRequired())
+        {
+            buff.append("[");
+        }
+
+        List optList = new ArrayList(group.getOptions());
+        Collections.sort(optList, new OptionComparator());
+        // for each option in the OptionGroup
+        for (Iterator i = optList.iterator(); i.hasNext();)
+        {
+            // whether the option is required or not is handled at group level
+            appendOption(buff, (Option) i.next(), true);
+
+            if (i.hasNext())
+            {
+                buff.append(" | ");
+            }
+        }
+
+        if (!group.isRequired())
+        {
+            buff.append("]");
+        }
+    }
+
+    /**
+     * Appends the usage clause for an Option to a StringBuffer.  
+     *
+     * @param buff the StringBuffer to append to
+     * @param option the Option to append
+     * @param required whether the Option is required or not
+     */
+    private static void appendOption(final StringBuffer buff, 
+                                     final Option option, 
+                                     final boolean required)
+    {
+        if (!required)
+        {
+            buff.append("[");
+        }
+
+        if (option.getOpt() != null)
+        {
+            buff.append("-").append(option.getOpt());
+        }
+        else
+        {
+            buff.append("--").append(option.getLongOpt());
+        }
+
+        // if the Option has a value
+        if (option.hasArg() && (option.getArgName() != null))
+        {
+            buff.append(" <").append(option.getArgName()).append(">");
+        }
+
+        // if the Option is not a required option
+        if (!required)
+        {
+            buff.append("]");
+        }
+    }
+
+    /**
+     * <p>Print the cmdLineSyntax to the specified writer, using the
+     * specified width.</p>
+     *
+     * @param pw The printWriter to write the help to
+     * @param width The number of characters per line for the usage statement.
+     * @param cmdLineSyntax The usage statement.
+     */
+    public void printUsage(PrintWriter pw, int width, String cmdLineSyntax)
+    {
+        int argPos = cmdLineSyntax.indexOf(' ') + 1;
+
+        printWrapped(pw, width, defaultSyntaxPrefix.length() + argPos, 
+                     defaultSyntaxPrefix + cmdLineSyntax);
+    }
+
+    /**
+     * <p>Print the help for the specified Options to the specified writer, 
+     * using the specified width, left padding and description padding.</p>
+     *
+     * @param pw The printWriter to write the help to
+     * @param width The number of characters to display per line
+     * @param options The command line Options
+     * @param leftPad the number of characters of padding to be prefixed
+     * to each line
+     * @param descPad the number of characters of padding to be prefixed
+     * to each description line
+     */
+    public void printOptions(PrintWriter pw, int width, Options options, 
+                             int leftPad, int descPad)
+    {
+        StringBuffer sb = new StringBuffer();
+
+        renderOptions(sb, width, options, leftPad, descPad);
+        pw.println(sb.toString());
+    }
+
+    /**
+     * <p>Print the specified text to the specified PrintWriter.</p>
+     *
+     * @param pw The printWriter to write the help to
+     * @param width The number of characters to display per line
+     * @param text The text to be written to the PrintWriter
+     */
+    public void printWrapped(PrintWriter pw, int width, String text)
+    {
+        printWrapped(pw, width, 0, text);
+    }
+
+    /**
+     * <p>Print the specified text to the specified PrintWriter.</p>
+     *
+     * @param pw The printWriter to write the help to
+     * @param width The number of characters to display per line
+     * @param nextLineTabStop The position on the next line for the first tab.
+     * @param text The text to be written to the PrintWriter
+     */
+    public void printWrapped(PrintWriter pw, int width, int nextLineTabStop, 
+                             String text)
+    {
+        StringBuffer sb = new StringBuffer(text.length());
+
+        renderWrappedText(sb, width, nextLineTabStop, text);
+        pw.println(sb.toString());
+    }
+
+    // --------------------------------------------------------------- Protected
+
+    /**
+     * <p>Render the specified Options and return the rendered Options
+     * in a StringBuffer.</p>
+     *
+     * @param sb The StringBuffer to place the rendered Options into.
+     * @param width The number of characters to display per line
+     * @param options The command line Options
+     * @param leftPad the number of characters of padding to be prefixed
+     * to each line
+     * @param descPad the number of characters of padding to be prefixed
+     * to each description line
+     *
+     * @return the StringBuffer with the rendered Options contents.
+     */
+    protected StringBuffer renderOptions(StringBuffer sb, int width, 
+                                         Options options, int leftPad, 
+                                         int descPad)
+    {
+        final String lpad = createPadding(leftPad);
+        final String dpad = createPadding(descPad);
+
+        // first create list containing only <lpad>-a,--aaa where 
+        // -a is opt and --aaa is long opt; in parallel look for 
+        // the longest opt string this list will be then used to 
+        // sort options ascending
+        int max = 0;
+        StringBuffer optBuf;
+        List prefixList = new ArrayList();
+        Option option;
+        List optList = options.helpOptions();
+
+        Collections.sort(optList, new OptionComparator());
+
+        for (Iterator i = optList.iterator(); i.hasNext();)
         {
-            String str1 = stripPrefix(o1.toString());
-            String str2 = stripPrefix(o2.toString());
-            return (str1.compareTo(str2));
+            option = (Option) i.next();
+            optBuf = new StringBuffer(8);
+
+            if (option.getOpt() == null)
+            {
+                optBuf.append(lpad).append("   " + defaultLongOptPrefix)
+                      .append(option.getLongOpt());
+            }
+            else
+            {
+                optBuf.append(lpad).append(defaultOptPrefix)
+                      .append(option.getOpt());
+
+                if (option.hasLongOpt())
+                {
+                    optBuf.append(',').append(defaultLongOptPrefix)
+                          .append(option.getLongOpt());
+                }
+            }
+
+            if (option.hasArg())
+            {
+                if (option.hasArgName())
+                {
+                    optBuf.append(" <").append(option.getArgName()).append(">");
+                }
+                else
+                {
+                    optBuf.append(' ');
+                }
+            }
+
+            prefixList.add(optBuf);
+            max = (optBuf.length() > max)       ? optBuf.length() : max;
         }
 
-        private String stripPrefix(String strOption)
+        int x = 0;
+
+        for (Iterator i = optList.iterator(); i.hasNext();)
         {
-            // Strip any leading '-' characters
-            int iStartIndex = strOption.lastIndexOf('-');
-            if (iStartIndex == -1)
+            option = (Option) i.next();
+            optBuf = new StringBuffer(prefixList.get(x++).toString());
+
+            if (optBuf.length() < max)
+            {
+                optBuf.append(createPadding(max - optBuf.length()));
+            }
+
+            optBuf.append(dpad);
+
+            int nextLineTabStop = max + descPad;
+
+            if (option.getDescription() != null)
             {
-              iStartIndex = 0;
+                optBuf.append(option.getDescription());
             }
-            return strOption.substring(iStartIndex);
 
+            renderWrappedText(sb, width, nextLineTabStop, optBuf.toString());
+
+            if (i.hasNext())
+            {
+                sb.append(defaultNewLine);
+            }
+        }
+
+        return sb;
+    }
+
+    /**
+     * <p>Render the specified text and return the rendered Options
+     * in a StringBuffer.</p>
+     *
+     * @param sb The StringBuffer to place the rendered text into.
+     * @param width The number of characters to display per line
+     * @param nextLineTabStop The position on the next line for the first tab.
+     * @param text The text to be rendered.
+     *
+     * @return the StringBuffer with the rendered Options contents.
+     */
+    protected StringBuffer renderWrappedText(StringBuffer sb, int width, 
+                                             int nextLineTabStop, String text)
+    {
+        int pos = findWrapPos(text, width, 0);
+
+        if (pos == -1)
+        {
+            sb.append(rtrim(text));
+
+            return sb;
+        }
+        sb.append(rtrim(text.substring(0, pos))).append(defaultNewLine);
+
+        // all following lines must be padded with nextLineTabStop space 
+        // characters
+        final String padding = createPadding(nextLineTabStop);
+
+        while (true)
+        {
+            text = padding + text.substring(pos).trim();
+            pos = findWrapPos(text, width, nextLineTabStop);
+
+            if (pos == -1)
+            {
+                sb.append(text);
+
+                return sb;
+            }
+
+            sb.append(rtrim(text.substring(0, pos))).append(defaultNewLine);
+        }
+    }
+
+    /**
+     * Finds the next text wrap position after <code>startPos</code> for the 
+     * text in <code>text</code> with the column width <code>width</code>.
+     * The wrap point is the last postion before startPos+width having a 
+     * whitespace character (space, \n, \r).
+     *
+     * @param text The text being searched for the wrap position
+     * @param width width of the wrapped text
+     * @param startPos position from which to start the lookup whitespace 
+     * character
+     * @return postion on which the text must be wrapped or -1 if the wrap 
+     * position is at the end of the text
+     */
+    protected int findWrapPos(String text, int width, int startPos)
+    {
+        int pos = -1;
+
+        // the line ends before the max wrap pos or a new line char found
+        if (((pos = text.indexOf('\n', startPos)) != -1 && pos <= width)
+            || ((pos = text.indexOf('\t', startPos)) != -1 && pos <= width))
+        {
+            return pos+1;
+        }
+        else if ((startPos + width) >= text.length())
+        {
+            return -1;
+        }
+
+
+        // look for the last whitespace character before startPos+width
+        pos = startPos + width;
+
+        char c;
+
+        while ((pos >= startPos) && ((c = text.charAt(pos)) != ' ')
+               && (c != '\n') && (c != '\r'))
+        {
+            --pos;
+        }
+
+        // if we found it - just return
+        if (pos > startPos)
+        {
+            return pos;
+        }
+        
+        // must look for the first whitespace chearacter after startPos 
+        // + width
+        pos = startPos + width;
+
+        while ((pos <= text.length()) && ((c = text.charAt(pos)) != ' ')
+               && (c != '\n') && (c != '\r'))
+        {
+            ++pos;
+        }
+
+        return (pos == text.length())        ? (-1) : pos;
+    }
+
+    /**
+     * <p>Return a String of padding of length <code>len</code>.</p>
+     *
+     * @param len The length of the String of padding to create.
+     *
+     * @return The String of padding
+     */
+    protected String createPadding(int len)
+    {
+        StringBuffer sb = new StringBuffer(len);
+
+        for (int i = 0; i < len; ++i)
+        {
+            sb.append(' ');
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * <p>Remove the trailing whitespace from the specified String.</p>
+     *
+     * @param s The String to remove the trailing padding from.
+     *
+     * @return The String of without the trailing padding
+     */
+    protected String rtrim(String s)
+    {
+        if ((s == null) || (s.length() == 0))
+        {
+            return s;
+        }
+
+        int pos = s.length();
+
+        while ((pos > 0) && Character.isWhitespace(s.charAt(pos - 1)))
+        {
+            --pos;
+        }
+
+        return s.substring(0, pos);
+    }
+
+    // ------------------------------------------------------ Package protected
+    // ---------------------------------------------------------------- Private
+    // ---------------------------------------------------------- Inner classes
+    /**
+     * <p>This class implements the <code>Comparator</code> interface
+     * for comparing Options.</p>
+     */
+    private static class OptionComparator
+        implements Comparator {
+
+        /**
+         * <p>Compares its two arguments for order. Returns a negative 
+         * integer, zero, or a positive integer as the first argument 
+         * is less than, equal to, or greater than the second.</p>
+         *
+         * @param o1 The first Option to be compared.
+         * @param o2 The second Option to be compared.
+         *
+         * @return a negative integer, zero, or a positive integer as 
+         * the first argument is less than, equal to, or greater than the 
+         * second.
+         */
+        public int compare(Object o1, Object o2)
+        {
+            Option opt1 = (Option)o1;
+            Option opt2 = (Option)o2;
+
+            return opt1.getKey().compareToIgnoreCase(opt2.getKey());
         }
     }
 }
diff --git a/src/java/org/apache/commons/cli/MissingArgumentException.java b/src/java/org/apache/commons/cli/MissingArgumentException.java
index 23b23bd..3b3378e 100644
--- a/src/java/org/apache/commons/cli/MissingArgumentException.java
+++ b/src/java/org/apache/commons/cli/MissingArgumentException.java
@@ -1,64 +1,19 @@
-/*
- * $Header: /home/cvs/jakarta-commons-sandbox/cli/src/java/org/apache/commons/cli/MissingArgumentException.java,v 1.2 2002/06/06 09:37:26 jstrachan Exp $
- * $Revision: 1.2 $
- * $Date: 2002/06/06 09:37:26 $
- *
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
 /** 
@@ -68,15 +23,17 @@ package org.apache.commons.cli;
  * @author John Keyes (john at integralsource.com)
  * @see ParseException
  */
-public class MissingArgumentException extends ParseException {
-    
+public class MissingArgumentException
+    extends ParseException {
+
     /** 
      * <p>Construct a new <code>MissingArgumentException</code> 
      * with the specified detail message.</p>
      *
      * @param message the detail message
      */
-    public MissingArgumentException( String message ) {
-        super( message );
+    public MissingArgumentException(String message)
+    {
+        super(message);
     }
-}
+}
\ No newline at end of file
diff --git a/src/java/org/apache/commons/cli/MissingOptionException.java b/src/java/org/apache/commons/cli/MissingOptionException.java
index 7a8157b..b877b76 100644
--- a/src/java/org/apache/commons/cli/MissingOptionException.java
+++ b/src/java/org/apache/commons/cli/MissingOptionException.java
@@ -1,64 +1,19 @@
-/*
- * $Header: /home/cvs/jakarta-commons-sandbox/cli/src/java/org/apache/commons/cli/MissingOptionException.java,v 1.2 2002/06/06 09:37:26 jstrachan Exp $
- * $Revision: 1.2 $
- * $Date: 2002/06/06 09:37:26 $
- *
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
 /** 
@@ -67,15 +22,17 @@ package org.apache.commons.cli;
  * @author John Keyes ( john at integralsource.com )
  * @see ParseException
  */
-public class MissingOptionException extends ParseException {
-    
+public class MissingOptionException
+    extends ParseException {
+
     /** 
      * <p>Construct a new <code>MissingSelectedException</code> 
      * with the specified detail message.</p>
      *
      * @param message the detail message
      */
-    public MissingOptionException( String message ) {
-        super( message );
+    public MissingOptionException(String message)
+    {
+        super(message);
     }
-}
+}
\ No newline at end of file
diff --git a/src/java/org/apache/commons/cli/Option.java b/src/java/org/apache/commons/cli/Option.java
index 3868227..76a24d3 100644
--- a/src/java/org/apache/commons/cli/Option.java
+++ b/src/java/org/apache/commons/cli/Option.java
@@ -1,74 +1,19 @@
-/*
- * $Header: /home/cvs/jakarta-commons-sandbox/cli/src/java/org/apache/commons/cli/Option.java,v 1.6 2002/06/06 22:50:14 bayard Exp $
- * $Revision: 1.6 $
- * $Date: 2002/06/06 22:50:14 $
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * ====================================================================
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-/*
- * Copyright (C) The Apache Software Foundation. All rights reserved.
- *
- * This software is published under the terms of the Apache Software License
- * version 1.1, a copy of which has been included with this distribution in
- * the LICENSE file.
- * 
- * $Id: Option.java,v 1.6 2002/06/06 22:50:14 bayard Exp $
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
 import java.util.ArrayList;
@@ -86,18 +31,18 @@ import java.util.ArrayList;
  *
  * @author bob mcwhirter (bob @ werken.com)
  * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
- * @version $Revision: 1.6 $
+ * @version $Revision: 551821 $
  */
-
 public class Option implements Cloneable {
 
-    /** constant that specifies the number of argument values has not been specified */
-    public final static int UNINITIALIZED = -1;
-    
+    /** constant that specifies the number of argument values has 
+        not been specified */
+    public static final int UNINITIALIZED = -1;
+
     /** constant that specifies the number of argument values is infinite */
-    public final static int UNLIMITED_VALUES = -2;
-    
-    /** opt the single character representation of the option */
+    public static final int UNLIMITED_VALUES = -2;
+
+    /** opt the name of the option */
     private String opt;
 
     /** longOpt is the long representation of the option */
@@ -107,7 +52,7 @@ public class Option implements Cloneable {
     private boolean hasArg;
 
     /** argName specifies the name of the argument for this option */
-    private String argName;
+    private String argName = "arg";
 
     /** description of the option */
     private String description;
@@ -122,104 +67,30 @@ public class Option implements Cloneable {
      * numberOfArgs specifies the number of argument values this option 
      * can have 
      */
-    private int numberOfArgs = UNINITIALIZED;   
+    private int numberOfArgs = UNINITIALIZED;
 
     /** the type of this Option */
     private Object type;
 
     /** the list of argument values **/
     private ArrayList values = new ArrayList();
-    
-    /** option char (only valid for single character options) */
-    private char id;
 
     /** the character that is the value separator */
     private char valuesep;
 
     /**
-     * <p>Validates whether <code>opt</code> is a permissable Option
-     * shortOpt.  The rules that specify if the <code>opt</code>
-     * is valid are:</p>
-     * <ul>
-     *  <li><code>opt</code> is not NULL</li>
-     *  <li>a single character <code>opt</code> that is either
-     *  ' '(special case), '?', '@' or a letter</li>
-     *  <li>a multi character <code>opt</code> that only contains
-     *  letters.</li>
-     * </ul>
-     *
-     * @param opt The option string to validate
-     * @throws IllegalArgumentException if the Option is not valid.
-     */
-    private void validateOption( String opt ) 
-    throws IllegalArgumentException
-    {
-        // check that opt is not NULL
-        if( opt == null ) {
-            throw new IllegalArgumentException( "opt is null" );
-        }
-        // handle the single character opt
-        else if( opt.length() == 1 ) {
-            char ch = opt.charAt( 0 );
-            if ( !isValidOpt( ch ) ) {
-                throw new IllegalArgumentException( "illegal option value '" 
-                                                    + ch + "'" );
-            }
-            id = ch;
-        }
-        // handle the multi character opt
-        else {
-            char[] chars = opt.toCharArray();
-            for( int i = 0; i < chars.length; i++ ) {
-                if( !isValidChar( chars[i] ) ) {
-                    throw new IllegalArgumentException( "opt contains illegal character value '" + chars[i] + "'" );
-                }
-            }
-        }
-    }
-
-    /**
-     * <p>Returns whether the specified character is a valid Option.</p>
-     *
-     * @param c the option to validate
-     * @return true if <code>c</code> is a letter, ' ', '?' or '@', otherwise false.
-     */
-    private boolean isValidOpt( char c ) {
-        return ( isValidChar( c ) || c == ' ' || c == '?' || c == '@' );
-    }
-
-    /**
-     * <p>Returns whether the specified character is a valid character.</p>
-     *
-     * @param c the character to validate
-     * @return true if <code>c</code> is a letter.
-     */
-    private boolean isValidChar( char c ) {
-        return Character.isJavaIdentifierPart( c );
-    }
-
-    /**
-     * <p>Returns the id of this Option.  This is only set when the
-     * Option shortOpt is a single character.  This is used for switch
-     * statements.</p>
-     *
-     * @return the id of this Option
-     */
-    public int getId( ) {
-        return id;
-    }
-
-    /**
      * Creates an Option using the specified parameters.
      *
      * @param opt short representation of the option
-     * @param hasArg specifies whether the Option takes an argument or not
      * @param description describes the function of the option
+     *
+     * @throws IllegalArgumentException if there are any non valid
+     * Option characters in <code>opt</code>.
      */
-    public Option( String opt, String description ) 
-    throws IllegalArgumentException
+    public Option(String opt, String description)
+           throws IllegalArgumentException
     {
-        this( opt, null, false, description );
+        this(opt, null, false, description);
     }
 
     /**
@@ -228,348 +99,581 @@ public class Option implements Cloneable {
      * @param opt short representation of the option
      * @param hasArg specifies whether the Option takes an argument or not
      * @param description describes the function of the option
+     *
+     * @throws IllegalArgumentException if there are any non valid
+     * Option characters in <code>opt</code>.
      */
-    public Option( String opt, boolean hasArg, String description ) 
-    throws IllegalArgumentException
+    public Option(String opt, boolean hasArg, String description)
+           throws IllegalArgumentException
     {
-        this( opt, null, hasArg, description );
+        this(opt, null, hasArg, description);
     }
-    
+
     /**
-     * <p>Creates an Option using the specified parameters.</p>
+     * Creates an Option using the specified parameters.
      *
      * @param opt short representation of the option
      * @param longOpt the long representation of the option
      * @param hasArg specifies whether the Option takes an argument or not
      * @param description describes the function of the option
+     *
+     * @throws IllegalArgumentException if there are any non valid
+     * Option characters in <code>opt</code>.
      */
-    public Option( String opt, String longOpt, boolean hasArg, String description ) 
-    throws IllegalArgumentException
+    public Option(String opt, String longOpt, boolean hasArg, 
+                  String description)
+           throws IllegalArgumentException
     {
         // ensure that the option is valid
-        validateOption( opt );
+        OptionValidator.validateOption(opt);
 
-        this.opt          = opt;
-        this.longOpt      = longOpt;
+        this.opt = opt;
+        this.longOpt = longOpt;
 
         // if hasArg is set then the number of arguments is 1
-        if( hasArg ) {
+        if (hasArg)
+        {
             this.numberOfArgs = 1;
         }
 
-        this.hasArg       = hasArg;
-        this.description  = description;
+        this.hasArg = hasArg;
+        this.description = description;
     }
-    
-    /** <p>Retrieve the name of this Option.</p>
+
+    /**
+     * Returns the id of this Option.  This is only set when the
+     * Option shortOpt is a single character.  This is used for switch
+     * statements.
      *
-     * <p>It is this String which can be used with
+     * @return the id of this Option
+     */
+    public int getId()
+    {
+        return getKey().charAt(0);
+    }
+
+    /**
+     * Returns the 'unique' Option identifier.
+     * 
+     * @return the 'unique' Option identifier
+     */
+    String getKey()
+    {
+        // if 'opt' is null, then it is a 'long' option
+        if (opt == null)
+        {
+            return this.longOpt;
+        }
+
+        return this.opt;
+    }
+
+    /** 
+     * Retrieve the name of this Option.
+     *
+     * It is this String which can be used with
      * {@link CommandLine#hasOption(String opt)} and
      * {@link CommandLine#getOptionValue(String opt)} to check
-     * for existence and argument.<p>
+     * for existence and argument.
      *
      * @return The name of this option
      */
-    public String getOpt() {
+    public String getOpt()
+    {
         return this.opt;
     }
 
     /**
-     * <p>Retrieve the type of this Option.</p>
+     * Retrieve the type of this Option.
      * 
      * @return The type of this option
      */
-    public Object getType() {
+    public Object getType()
+    {
         return this.type;
     }
 
     /**
-     * <p>Sets the type of this Option.</p>
+     * Sets the type of this Option.
      *
      * @param type the type of this Option
      */
-    public void setType( Object type ) {
+    public void setType(Object type)
+    {
         this.type = type;
     }
-    
+
     /** 
-     * <p>Retrieve the long name of this Option.</p>
+     * Retrieve the long name of this Option.
      *
      * @return Long name of this option, or null, if there is no long name
      */
-    public String getLongOpt() {
+    public String getLongOpt()
+    {
         return this.longOpt;
     }
 
     /**
-     * <p>Sets the long name of this Option.</p>
+     * Sets the long name of this Option.
      *
      * @param longOpt the long name of this Option
      */
-    public void setLongOpt( String longOpt ) {
+    public void setLongOpt(String longOpt)
+    {
         this.longOpt = longOpt;
     }
 
     /**
-     * <p>Sets whether this Option can have an optional argument.</p>
+     * Sets whether this Option can have an optional argument.
      *
      * @param optionalArg specifies whether the Option can have
      * an optional argument.
      */
-    public void setOptionalArg( boolean optionalArg ) {
+    public void setOptionalArg(boolean optionalArg)
+    {
         this.optionalArg = optionalArg;
     }
 
     /**
      * @return whether this Option can have an optional argument
      */
-    public boolean hasOptionalArg( ) {
+    public boolean hasOptionalArg()
+    {
         return this.optionalArg;
     }
-    
-    /** <p>Query to see if this Option has a long name</p>
+
+    /** 
+     * Query to see if this Option has a long name
      *
      * @return boolean flag indicating existence of a long name
      */
-    public boolean hasLongOpt() {
-        return ( this.longOpt != null );
+    public boolean hasLongOpt()
+    {
+        return (this.longOpt != null);
     }
-    
-    /** <p>Query to see if this Option requires an argument</p>
+
+    /** 
+     * Query to see if this Option requires an argument
      *
      * @return boolean flag indicating if an argument is required
      */
-    public boolean hasArg() {
-        return this.numberOfArgs > 0 || numberOfArgs == UNLIMITED_VALUES;
+    public boolean hasArg()
+    {
+        return (this.numberOfArgs > 0) || (numberOfArgs == UNLIMITED_VALUES);
     }
-    
-    /** <p>Retrieve the self-documenting description of this Option</p>
+
+    /** 
+     * Retrieve the self-documenting description of this Option
      *
      * @return The string description of this option
      */
-    public String getDescription() {
+    public String getDescription()
+    {
         return this.description;
     }
 
-     /** 
-      * <p>Query to see if this Option requires an argument</p>
-      *
-      * @return boolean flag indicating if an argument is required
-      */
-     public boolean isRequired() {
-         return this.required;
-     }
-
-     /**
-      * <p>Sets whether this Option is mandatory.</p>
-      *
-      * @param required specifies whether this Option is mandatory
-      */
-     public void setRequired( boolean required ) {
-         this.required = required;
-     }
-
-     /**
-      * <p>Sets the display name for the argument value.</p>
-      *
-      * @param argName the display name for the argument value.
-      */
-     public void setArgName( String argName ) {
-         this.argName = argName;
-     }
-
-     /**
-      * <p>Gets the display name for the argument value.</p>
-      *
-      * @return the display name for the argument value.
-      */
-     public String getArgName() {
-         return this.argName;
-     }
-
-     /**
-      * <p>Returns whether the display name for the argument value
-      * has been set.</p>
-      *
-      * @return if the display name for the argument value has been
-      * set.
-      */
-     public boolean hasArgName() {
-         return (this.argName != null && this.argName.length() > 0 );
-     }
-
-     /** 
-      * <p>Query to see if this Option can take many values</p>
-      *
-      * @return boolean flag indicating if multiple values are allowed
-      */
-     public boolean hasArgs() {
-         return ( this.numberOfArgs > 1 || this.numberOfArgs == UNLIMITED_VALUES );
-     }
-
-     /** 
-      * <p>Sets the number of argument values this Option can take.</p>
-      *
-      * @param num the number of argument values
-      */
-     public void setArgs( int num ) {
-         this.numberOfArgs = num;
-     }
-
-     /**
-      * <p>Sets the value separator.  For example if the argument value
-      * was a Java property, the value separator would be '='.</p>
-      *
-      * @param sep The value separator.
-      */
-     public void setValueSeparator( char sep ) {
-         this.valuesep = sep;
-     }
-
-     /**
-      * <p>Returns the value separator character.</p>
-      *
-      * @return the value separator character.
-      */
-     public char getValueSeparator() {
-         return this.valuesep;
-     }
-
-     /** 
-      * <p>Returns the number of argument values this Option can take.</p>
-      *
-      * @return num the number of argument values
-      */
-     public int getArgs( ) {
-         return this.numberOfArgs;
-     }
+   /** 
+     * Sets the self-documenting description of this Option
+     *
+     * @param description The description of this option
+     */
+    public void setDescription(String description)
+    {
+        this.description = description;
+    }
 
     /** 
-     * <p>Dump state, suitable for debugging.</p>
+     * Query to see if this Option requires an argument
      *
-     * @return Stringified form of this object
+     * @return boolean flag indicating if an argument is required
      */
-    public String toString() {
-        StringBuffer buf = new StringBuffer().append("[ option: ");
-        
-        buf.append( this.opt );
-        
-        if ( this.longOpt != null ) {
-            buf.append(" ")
-            .append(this.longOpt);
-        }
-        
-        buf.append(" ");
-        
-        if ( hasArg ) {
-            buf.append( "+ARG" );
-        }
-        
-        buf.append(" :: ")
-        .append( this.description );
-        
-        if ( this.type != null ) {
-            buf.append(" :: ")
-            .append( this.type );
-        }
+    public boolean isRequired()
+    {
+        return this.required;
+    }
 
-        buf.append(" ]");
-        return buf.toString();
+    /**
+     * Sets whether this Option is mandatory.
+     *
+     * @param required specifies whether this Option is mandatory
+     */
+    public void setRequired(boolean required)
+    {
+        this.required = required;
+    }
+
+    /**
+     * Sets the display name for the argument value.
+     *
+     * @param argName the display name for the argument value.
+     */
+    public void setArgName(String argName)
+    {
+        this.argName = argName;
+    }
+
+    /**
+     * Gets the display name for the argument value.
+     *
+     * @return the display name for the argument value.
+     */
+    public String getArgName()
+    {
+        return this.argName;
+    }
+
+    /**
+     * Returns whether the display name for the argument value
+     * has been set.
+     *
+     * @return if the display name for the argument value has been
+     * set.
+     */
+    public boolean hasArgName()
+    {
+        return (this.argName != null && this.argName.length() > 0);
+    }
+
+    /** 
+     * Query to see if this Option can take many values.
+     *
+     * @return boolean flag indicating if multiple values are allowed
+     */
+    public boolean hasArgs()
+    {
+        return (this.numberOfArgs > 1) 
+                || (this.numberOfArgs == UNLIMITED_VALUES);
+    }
+
+    /** 
+     * Sets the number of argument values this Option can take.
+     *
+     * @param num the number of argument values
+     */
+    public void setArgs(int num)
+    {
+        this.numberOfArgs = num;
     }
 
     /**
-     * <p>Adds the specified value to this Option.</p>
+     * Sets the value separator.  For example if the argument value
+     * was a Java property, the value separator would be '='.
+     *
+     * @param sep The value separator.
+     */
+    public void setValueSeparator(char sep)
+    {
+        this.valuesep = sep;
+    }
+
+    /**
+     * Returns the value separator character.
+     *
+     * @return the value separator character.
+     */
+    public char getValueSeparator()
+    {
+        return this.valuesep;
+    }
+
+    /**
+     * Return whether this Option has specified a value separator.
+     * 
+     * @return whether this Option has specified a value separator.
+     */
+    public boolean hasValueSeparator()
+    {
+        return (this.valuesep > 0);
+    }
+
+    /** 
+     * Returns the number of argument values this Option can take.
+     *
+     * @return num the number of argument values
+     */
+    public int getArgs()
+    {
+        return this.numberOfArgs;
+    }
+
+    /**
+     * Adds the specified value to this Option.
      * 
      * @param value is a/the value of this Option
      */
-    public boolean addValue( String value ) {
-
-        switch( numberOfArgs ) {
-            case UNINITIALIZED:
-                return false;
-            case UNLIMITED_VALUES:
-                if( getValueSeparator() > 0 ) {
-                    int index = 0;
-                    while( (index = value.indexOf( getValueSeparator() ) ) != -1 ) {
-                        this.values.add( value.substring( 0, index ) );
-                        value = value.substring( index+1 );
-                    }
-                }
-                this.values.add( value );
-                return true;
-            default:
-                if( getValueSeparator() > 0 ) {
-                    int index = 0;
-                    while( (index = value.indexOf( getValueSeparator() ) ) != -1 ) {
-                        if( values.size() > numberOfArgs-1 ) {
-                            return false;
-                        }
-                        this.values.add( value.substring( 0, index ) );
-                        value = value.substring( index+1 );
-                    }
-                }
-                if( values.size() > numberOfArgs-1 ) {
-                    return false;
+    void addValueForProcessing(String value)
+    {
+        switch (numberOfArgs)
+        {
+        case UNINITIALIZED:
+            throw new RuntimeException("NO_ARGS_ALLOWED");
+
+        default:
+            processValue(value);
+        }
+    }
+
+    /**
+     * Processes the value.  If this Option has a value separator
+     * the value will have to be parsed into individual tokens.  When
+     * n-1 tokens have been processed and there are more value separators
+     * in the value, parsing is ceased and the remaining characters are
+     * added as a single token.
+     *
+     * @param value The String to be processed.
+     *
+     * @since 1.0.1
+     */
+    private void processValue(String value)
+    {
+        // this Option has a separator character
+        if (hasValueSeparator())
+        {
+            // get the separator character
+            char sep = getValueSeparator();
+
+            // store the index for the value separator
+            int index = value.indexOf(sep);
+
+            // while there are more value separators
+            while (index != -1)
+            {
+                // next value to be added 
+                if (values.size() == (numberOfArgs - 1))
+                {
+                    break;
                 }
-                this.values.add( value );
-                return true;
+
+
+                // store
+                add(value.substring(0, index));
+
+
+                // parse
+                value = value.substring(index + 1);
+
+
+                // get new index
+                index = value.indexOf(sep);
+            }
         }
+
+
+        // store the actual value or the last value that has been parsed
+        add(value);
+    }
+
+    /**
+     * Add the value to this Option.  If the number of arguments
+     * is greater than zero and there is enough space in the list then
+     * add the value.  Otherwise, throw a runtime exception.
+     *
+     * @param value The value to be added to this Option
+     *
+     * @since 1.0.1
+     */
+    private void add(String value)
+    {
+        if ((numberOfArgs > 0) && (values.size() > (numberOfArgs - 1)))
+        {
+            throw new RuntimeException("Cannot add value, list full.");
+        }
+
+
+        // store value
+        this.values.add(value);
     }
 
     /**
+     * Returns the specified value of this Option or 
+     * <code>null</code> if there is no value.
+     *
      * @return the value/first value of this Option or 
-     * <code>null</code> if there are no values.
+     * <code>null</code> if there is no value.
      */
-    public String getValue() {
-        return this.values.size()==0 ? null : (String)this.values.get( 0 );
+    public String getValue()
+    {
+        return hasNoValues() ? null : (String) this.values.get(0);
     }
 
     /**
+     * Returns the specified value of this Option or 
+     * <code>null</code> if there is no value.
+     *
+     * @param index The index of the value to be returned.
+     *
      * @return the specified value of this Option or 
-     * <code>null</code> if there are no values.
+     * <code>null</code> if there is no value.
+     *
+     * @throws IndexOutOfBoundsException if index is less than 1
+     * or greater than the number of the values for this Option.
      */
-    public String getValue( int index ) 
-    throws IndexOutOfBoundsException
+    public String getValue(int index)
+        throws IndexOutOfBoundsException
     {
-        return ( this.values.size()==0 ) ? null : (String)this.values.get( index );
+        return hasNoValues() ? null : (String) this.values.get(index);
     }
 
     /**
+     * Returns the value/first value of this Option or the 
+     * <code>defaultValue</code> if there is no value.
+     *
+     * @param defaultValue The value to be returned if ther
+     * is no value.
+     *
      * @return the value/first value of this Option or the 
      * <code>defaultValue</code> if there are no values.
      */
-    public String getValue( String defaultValue ) {
-        String value = getValue( );
-        return ( value != null ) ? value : defaultValue;
+    public String getValue(String defaultValue)
+    {
+        String value = getValue();
+
+        return (value != null) ? value : defaultValue;
     }
 
     /**
+     * Return the values of this Option as a String array 
+     * or null if there are no values
+     *
      * @return the values of this Option as a String array 
      * or null if there are no values
      */
-    public String[] getValues() {
-        return this.values.size()==0 ? null : (String[])this.values.toArray(new String[]{});
+    public String[] getValues()
+    {
+        return hasNoValues()
+               ? null : (String[]) this.values.toArray(new String[this.values.size()]);
     }
 
     /**
      * @return the values of this Option as a List
      * or null if there are no values
      */
-    public java.util.List getValuesList() {
+    public java.util.List getValuesList()
+    {
         return this.values;
     }
 
+    /** 
+     * Dump state, suitable for debugging.
+     *
+     * @return Stringified form of this object
+     */
+    public String toString()
+    {
+        StringBuffer buf = new StringBuffer().append("[ option: ");
+
+        buf.append(this.opt);
+
+        if (this.longOpt != null)
+        {
+            buf.append(" ").append(this.longOpt);
+        }
+
+        buf.append(" ");
+
+        if (hasArg)
+        {
+            buf.append("+ARG");
+        }
+
+        buf.append(" :: ").append(this.description);
+
+        if (this.type != null)
+        {
+            buf.append(" :: ").append(this.type);
+        }
+
+        buf.append(" ]");
+
+        return buf.toString();
+    }
+
+    /**
+     * Returns whether this Option has any values.
+     *
+     * @return whether this Option has any values.
+     */
+    private boolean hasNoValues()
+    {
+        return this.values.size() == 0;
+    }
+
+    public boolean equals( Object o )
+    {
+        if ( this == o )
+        {
+            return true;
+        }
+        if ( o == null || getClass() != o.getClass() )
+        {
+            return false;
+        }
+
+        Option option = (Option) o;
+
+
+        if ( opt != null ? !opt.equals( option.opt ) : option.opt != null )
+        {
+            return false;
+        }
+        if ( longOpt != null ? !longOpt.equals( option.longOpt ) : option.longOpt != null )
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+    public int hashCode()
+    {
+        int result;
+        result = ( opt != null ? opt.hashCode() : 0 );
+        result = 31 * result + ( longOpt != null ? longOpt.hashCode() : 0 );
+        return result;
+    }
+
     /**
-     * @return a copy of this Option
+     * A rather odd clone method - due to incorrect code in 1.0 it is public 
+     * and in 1.1 rather than throwing a CloneNotSupportedException it throws 
+     * a RuntimeException so as to maintain backwards compat at the API level. 
+     *
+     * After calling this method, it is very likely you will want to call 
+     * clearValues(). 
+     *
+     * @throws RuntimeException
      */
     public Object clone() {
-        Option option = new Option( getOpt(), getDescription() );
-        option.setArgs( getArgs() );
-        option.setOptionalArg( hasOptionalArg() );
-        option.setRequired( isRequired() );
-        option.setLongOpt( getLongOpt() );
-        option.setType( getType() );
-        option.setValueSeparator( getValueSeparator() );
-        return option;
+        try {
+            Option option = (Option) super.clone();
+            option.values = new ArrayList(values);
+            return option;
+        } catch(CloneNotSupportedException cnse) {
+            throw new RuntimeException("A CloneNotSupportedException was thrown: " + cnse.getMessage());
+        }
+    }
+
+    /**
+     * <p>Clear the Option values. After a 
+     * parse is complete, these are left with data in them 
+     * and they need clearing if another parse is done. </p>
+     *
+     * See: <a href="https://issues.apache.org/jira/browse/CLI-71">CLI-71</a>
+     */
+    void clearValues() {
+        this.values.clear();
+    }
+
+    /**
+     * This method is not intended to be used. It was a piece of internal 
+     * API that was made public in 1.0. It currently throws an UnsupportedOperationException. 
+     * @deprecated
+     * @throws UnsupportedOperationException
+     */
+    public boolean addValue(String value) {
+        throw new UnsupportedOperationException(
+           "The addValue method is not intended for client use. " + 
+           "Subclasses should use the addValueForProcessing method instead. "
+           );
     }
+
 }
diff --git a/src/java/org/apache/commons/cli/OptionBuilder.java b/src/java/org/apache/commons/cli/OptionBuilder.java
index d5fa11c..f1888a8 100644
--- a/src/java/org/apache/commons/cli/OptionBuilder.java
+++ b/src/java/org/apache/commons/cli/OptionBuilder.java
@@ -1,343 +1,345 @@
-/*
- * $Header: /home/cvspublic/jakarta-commons/cli/src/java/org/apache/commons/cli/OptionBuilder.java,v 1.12 2002/10/15 22:50:45 jkeyes Exp $
- * $Revision: 1.12 $
- * $Date: 2002/10/15 22:50:45 $
- *
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
 /**
  * <p>OptionBuilder allows the user to create Options using descriptive
  * methods.</p>
  * <p>Details on the Builder pattern can be found at 
- * <a href="http://c2.com/cgi-bin/wiki?BuilderPattern">http://c2.com/cgi-bin/wiki?BuilderPattern</a>.</p>
+ * <a href="http://c2.com/cgi-bin/wiki?BuilderPattern">
+ * http://c2.com/cgi-bin/wiki?BuilderPattern</a>.</p>
  *
- * @author John Keyes ( john at integralsource.com )
+ * @author John Keyes (john at integralsource.com)
  * @since 1.0
  */
 public class OptionBuilder {
 
     /** long option */
     private static String longopt;
+
     /** option description */
     private static String description;
+
     /** argument name */
     private static String argName;
+
     /** is required? */
     private static boolean required;
+
     /** the number of arguments */
     private static int numberOfArgs = Option.UNINITIALIZED;
+
     /** option type */
     private static Object type;
+
     /** option can have an optional argument value */
     private static boolean optionalArg;
+
     /** value separator for argument value */
     private static char valuesep;
 
     /** option builder instance */
     private static OptionBuilder instance = new OptionBuilder();
 
-    // private constructor
-    private OptionBuilder() {
+    /**
+     * private constructor to prevent instances being created
+     */
+    private OptionBuilder()
+    {
+        // hide the constructor
     }
 
     /**
-     * <p>Resets the member variables to their default values.</p>
+     * Resets the member variables to their default values.
      */
-    private static void reset() {
+    private static void reset()
+    {
         description = null;
-        argName = null;
+        argName = "arg";
         longopt = null;
         type = null;
         required = false;
         numberOfArgs = Option.UNINITIALIZED;
 
+
         // PMM 9/6/02 - these were missing
         optionalArg = false;
         valuesep = (char) 0;
     }
 
     /**
-     * <p>The next Option created will have the following long option value.</p>
+     * The next Option created will have the following long option value.
      *
-     * @param longopt the long option value
+     * @param newLongopt the long option value
      * @return the OptionBuilder instance
      */
-    public static OptionBuilder withLongOpt( String longopt ) {
-        instance.longopt = longopt;
+    public static OptionBuilder withLongOpt(String newLongopt)
+    {
+        OptionBuilder.longopt = newLongopt;
+
         return instance;
     }
 
     /**
-     * <p>The next Option created will require an argument value.</p>
+     * The next Option created will require an argument value.
      *
      * @return the OptionBuilder instance
      */
-    public static OptionBuilder hasArg( ) {
-        instance.numberOfArgs = 1;
+    public static OptionBuilder hasArg()
+    {
+        OptionBuilder.numberOfArgs = 1;
+
         return instance;
     }
 
     /**
-     * <p>The next Option created will require an argument value if
-     * <code>hasArg</code> is true.</p>
+     * The next Option created will require an argument value if
+     * <code>hasArg</code> is true.
      *
      * @param hasArg if true then the Option has an argument value
      * @return the OptionBuilder instance
      */
-    public static OptionBuilder hasArg( boolean hasArg ) {
-        instance.numberOfArgs = ( hasArg == true ) ? 1 : Option.UNINITIALIZED;
+    public static OptionBuilder hasArg(boolean hasArg)
+    {
+        OptionBuilder.numberOfArgs = (hasArg == true) ? 1 : Option.UNINITIALIZED;
+
         return instance;
     }
 
     /**
-     * <p>The next Option created will have the specified argument value 
-     * name.</p>
+     * The next Option created will have the specified argument value 
+     * name.
      *
      * @param name the name for the argument value
      * @return the OptionBuilder instance
      */
-    public static OptionBuilder withArgName( String name ) {
-        instance.argName = name;
+    public static OptionBuilder withArgName(String name)
+    {
+        OptionBuilder.argName = name;
+
         return instance;
     }
 
     /**
-     * <p>The next Option created will be required.</p>
+     * The next Option created will be required.
      *
      * @return the OptionBuilder instance
      */
-    public static OptionBuilder isRequired( ) {
-        instance.required = true;
+    public static OptionBuilder isRequired()
+    {
+        OptionBuilder.required = true;
+
         return instance;
     }
 
     /**
-     * <p>The next Option created uses <code>sep</code> as a means to
-     * separate argument values.</p>
+     * The next Option created uses <code>sep</code> as a means to
+     * separate argument values.
      *
      * <b>Example:</b>
      * <pre>
-     * Option opt = OptionBuilder.withValueSeparator( ':' )
-     *                           .create( 'D' );
+     * Option opt = OptionBuilder.withValueSeparator(':')
+     *                           .create('D');
      *
-     * CommandLine line = parser.parse( args );
-     * String propertyName = opt.getValue( 0 );
-     * String propertyValue = opt.getValue( 1 );
+     * CommandLine line = parser.parse(args);
+     * String propertyName = opt.getValue(0);
+     * String propertyValue = opt.getValue(1);
      * </pre>
      *
+     * @param sep The value separator to be used for the argument values.
+     *
      * @return the OptionBuilder instance
      */
-    public static OptionBuilder withValueSeparator( char sep ) {
-        instance.valuesep = sep;
+    public static OptionBuilder withValueSeparator(char sep)
+    {
+        OptionBuilder.valuesep = sep;
+
         return instance;
     }
 
     /**
-     * <p>The next Option created uses '<code>=</code>' as a means to
-     * separate argument values.</p>
+     * The next Option created uses '<code>=</code>' as a means to
+     * separate argument values.
      *
      * <b>Example:</b>
      * <pre>
-     * Option opt = OptionBuilder.withValueSeparator( )
-     *                           .create( 'D' );
+     * Option opt = OptionBuilder.withValueSeparator()
+     *                           .create('D');
      *
-     * CommandLine line = parser.parse( args );
-     * String propertyName = opt.getValue( 0 );
-     * String propertyValue = opt.getValue( 1 );
+     * CommandLine line = parser.parse(args);
+     * String propertyName = opt.getValue(0);
+     * String propertyValue = opt.getValue(1);
      * </pre>
      *
      * @return the OptionBuilder instance
      */
-    public static OptionBuilder withValueSeparator( ) {
-        instance.valuesep = '=';
+    public static OptionBuilder withValueSeparator()
+    {
+        OptionBuilder.valuesep = '=';
+
         return instance;
     }
 
     /**
-     * <p>The next Option created will be required if <code>required</code>
-     * is true.</p>
+     * The next Option created will be required if <code>required</code>
+     * is true.
      *
-     * @param required if true then the Option is required
+     * @param newRequired if true then the Option is required
      * @return the OptionBuilder instance
      */
-    public static OptionBuilder isRequired( boolean required ) {
-        instance.required = required;
+    public static OptionBuilder isRequired(boolean newRequired)
+    {
+        OptionBuilder.required = newRequired;
+
         return instance;
     }
 
     /**
-     * <p>The next Option created can have unlimited argument values.</p>
+     * The next Option created can have unlimited argument values.
      *
      * @return the OptionBuilder instance
      */
-    public static OptionBuilder hasArgs( ) {
-        instance.numberOfArgs = Option.UNLIMITED_VALUES;
+    public static OptionBuilder hasArgs()
+    {
+        OptionBuilder.numberOfArgs = Option.UNLIMITED_VALUES;
+
         return instance;
     }
 
     /**
-     * <p>The next Option created can have <code>num</code> 
-     * argument values.</p>
+     * The next Option created can have <code>num</code> 
+     * argument values.
      *
      * @param num the number of args that the option can have
      * @return the OptionBuilder instance
      */
-    public static OptionBuilder hasArgs( int num ) {
-        instance.numberOfArgs = num;
+    public static OptionBuilder hasArgs(int num)
+    {
+        OptionBuilder.numberOfArgs = num;
+
         return instance;
     }
 
     /**
-     * <p>The next Option can have an optional argument.</p>
+     * The next Option can have an optional argument.
      *
      * @return the OptionBuilder instance
      */
-    public static OptionBuilder hasOptionalArg( ) {
-        instance.numberOfArgs = 1;
-        instance.optionalArg = true;
+    public static OptionBuilder hasOptionalArg()
+    {
+        OptionBuilder.numberOfArgs = 1;
+        OptionBuilder.optionalArg = true;
+
         return instance;
     }
 
     /**
-     * <p>The next Option can have an unlimited number of
-     * optional arguments.</p>
+     * The next Option can have an unlimited number of
+     * optional arguments.
      *
      * @return the OptionBuilder instance
      */
-    public static OptionBuilder hasOptionalArgs( ) {
-        instance.numberOfArgs = Option.UNLIMITED_VALUES;
-        instance.optionalArg = true;
+    public static OptionBuilder hasOptionalArgs()
+    {
+        OptionBuilder.numberOfArgs = Option.UNLIMITED_VALUES;
+        OptionBuilder.optionalArg = true;
+
         return instance;
     }
 
     /**
-     * <p>The next Option can have the specified number of 
-     * optional arguments.</p>
+     * The next Option can have the specified number of 
+     * optional arguments.
      *
      * @param numArgs - the maximum number of optional arguments
      * the next Option created can have.
      * @return the OptionBuilder instance
      */
-    public static OptionBuilder hasOptionalArgs( int numArgs ) {
-        instance.numberOfArgs = numArgs;
-        instance.optionalArg = true;
+    public static OptionBuilder hasOptionalArgs(int numArgs)
+    {
+        OptionBuilder.numberOfArgs = numArgs;
+        OptionBuilder.optionalArg = true;
+
         return instance;
     }
 
     /**
-     * <p>The next Option created will have a value that will be an instance 
-     * of <code>type</code>.</p>
+     * The next Option created will have a value that will be an instance 
+     * of <code>type</code>.
      *
-     * @param type the type of the Options argument value
+     * @param newType the type of the Options argument value
      * @return the OptionBuilder instance
      */
-    public static OptionBuilder withType( Object type ) {
-        instance.type = type;
+    public static OptionBuilder withType(Object newType)
+    {
+        OptionBuilder.type = newType;
+
         return instance;
     }
 
     /**
-     * <p>The next Option created will have the specified description</p>
+     * The next Option created will have the specified description
      *
-     * @param description a description of the Option's purpose
+     * @param newDescription a description of the Option's purpose
      * @return the OptionBuilder instance
      */
-    public static OptionBuilder withDescription( String description ) {
-        instance.description = description;
+    public static OptionBuilder withDescription(String newDescription)
+    {
+        OptionBuilder.description = newDescription;
+
         return instance;
     }
 
     /**
-     * <p>Create an Option using the current settings and with 
-     * the specified Option <code>char</code>.</p>
+     * Create an Option using the current settings and with 
+     * the specified Option <code>char</code>.
      *
      * @param opt the character representation of the Option
      * @return the Option instance
      * @throws IllegalArgumentException if <code>opt</code> is not
      * a valid character.  See Option.
      */
-    public static Option create( char opt )
-    throws IllegalArgumentException
+    public static Option create(char opt)
+                         throws IllegalArgumentException
     {
-        return create( String.valueOf( opt ) );
+        return create(String.valueOf(opt));
     }
 
     /**
-     * <p>Create an Option using the current settings</p>
+     * Create an Option using the current settings
      *
      * @return the Option instance
      * @throws IllegalArgumentException if <code>longOpt</code> has
      * not been set.  
      */
-    public static Option create() 
-    throws IllegalArgumentException
+    public static Option create()
+                         throws IllegalArgumentException
     {
-        if( longopt == null ) {
-            throw new IllegalArgumentException( "must specify longopt" );
+        if (longopt == null)
+        {
+            throw new IllegalArgumentException("must specify longopt");
         }
 
-        return create( " " );
+        return create(null);
     }
 
     /**
-     * <p>Create an Option using the current settings and with 
-     * the specified Option <code>char</code>.</p>
+     * Create an Option using the current settings and with 
+     * the specified Option <code>char</code>.
      *
      * @param opt the <code>java.lang.String</code> representation 
      * of the Option
@@ -345,22 +347,25 @@ public class OptionBuilder {
      * @throws IllegalArgumentException if <code>opt</code> is not
      * a valid character.  See Option.
      */
-    public static Option create( String opt ) 
-    throws IllegalArgumentException
+    public static Option create(String opt)
+                         throws IllegalArgumentException
     {
         // create the option
-        Option option = new Option( opt, description );
+        Option option = new Option(opt, description);
+
 
         // set the option properties
-        option.setLongOpt( longopt );
-        option.setRequired( required );
-        option.setOptionalArg( optionalArg );
-        option.setArgs( numberOfArgs );
-        option.setType( type );
-        option.setValueSeparator( valuesep );
-        option.setArgName( argName );
+        option.setLongOpt(longopt);
+        option.setRequired(required);
+        option.setOptionalArg(optionalArg);
+        option.setArgs(numberOfArgs);
+        option.setType(type);
+        option.setValueSeparator(valuesep);
+        option.setArgName(argName);
+
+
         // reset the OptionBuilder properties
-        instance.reset();
+        OptionBuilder.reset();
 
         // return the Option instance
         return option;
diff --git a/src/java/org/apache/commons/cli/OptionGroup.java b/src/java/org/apache/commons/cli/OptionGroup.java
index afa2f8c..675bcb1 100644
--- a/src/java/org/apache/commons/cli/OptionGroup.java
+++ b/src/java/org/apache/commons/cli/OptionGroup.java
@@ -1,64 +1,19 @@
-/*
- * $Header: /home/cvs/jakarta-commons-sandbox/cli/src/java/org/apache/commons/cli/OptionGroup.java,v 1.2 2002/06/06 09:37:26 jstrachan Exp $
- * $Revision: 1.2 $
- * $Date: 2002/06/06 09:37:26 $
- *
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
 import java.util.Collection;
@@ -68,7 +23,7 @@ import java.util.Iterator;
 /**
  * A group of mutually exclusive options.
  * @author John Keyes ( john at integralsource.com )
- * @version $Revision: 1.2 $
+ * @version $Revision: 542144 $
  */
 public class OptionGroup {
 
@@ -87,10 +42,12 @@ public class OptionGroup {
      * @param opt the option to add to this group
      * @return this option group with opt added
      */
-    public OptionGroup addOption(Option opt) {
+    public OptionGroup addOption(Option opt)
+    {
         // key   - option name
         // value - the option
-        optionMap.put( "-" + opt.getOpt(), opt );
+        optionMap.put(opt.getKey(), opt);
+
         return this;
     }
 
@@ -98,7 +55,8 @@ public class OptionGroup {
      * @return the names of the options in this group as a 
      * <code>Collection</code>
      */
-    public Collection getNames() {
+    public Collection getNames()
+    {
         // the key set is the collection of names
         return optionMap.keySet();
     }
@@ -106,7 +64,8 @@ public class OptionGroup {
     /**
      * @return the options in this group as a <code>Collection</code>
      */
-    public Collection getOptions() {
+    public Collection getOptions()
+    {
         // the values are the collection of options
         return optionMap.values();
     }
@@ -117,41 +76,47 @@ public class OptionGroup {
      * @throws AlreadySelectedException if an option from this group has 
      * already been selected.
      */
-    public void setSelected(Option opt) throws AlreadySelectedException {
+    public void setSelected(Option opt)
+                     throws AlreadySelectedException
+    {
         // if no option has already been selected or the 
         // same option is being reselected then set the
         // selected member variable
-
-        if ( this.selected == null || this.selected.equals( opt.getOpt() ) ) {
+        if ((this.selected == null) || this.selected.equals(opt.getOpt()))
+        {
             this.selected = opt.getOpt();
         }
-        else {
-            throw new AlreadySelectedException( "an option from this group has " + 
-                                                "already been selected: '" + 
-                                                selected + "'");
+        else
+        {
+            throw new AlreadySelectedException("an option from this group has "
+                                               + "already been selected: '"
+                                               + selected + "'");
         }
     }
 
     /**
      * @return the selected option name
      */
-    public String getSelected() {
+    public String getSelected()
+    {
         return selected;
     }
 
     /**
      * @param required specifies if this group is required
      */
-    public void setRequired( boolean required ) {
+    public void setRequired(boolean required)
+    {
         this.required = required;
     }
 
     /**
      * Returns whether this option group is required.
      *
-     * @returns whether this option group is required
+     * @return whether this option group is required
      */
-    public boolean isRequired() {
+    public boolean isRequired()
+    {
         return this.required;
     }
 
@@ -159,26 +124,40 @@ public class OptionGroup {
      * <p>Returns the stringified version of this OptionGroup.</p>
      * @return the stringified representation of this group
      */
-    public String toString() {
+    public String toString()
+    {
         StringBuffer buff = new StringBuffer();
 
         Iterator iter = getOptions().iterator();
 
-        buff.append( "[" );
-        while( iter.hasNext() ) {
-            Option option = (Option)iter.next();
+        buff.append("[");
 
-            buff.append( "-" );
-            buff.append( option.getOpt() );
-            buff.append( " " );
-            buff.append( option.getDescription( ) );
+        while (iter.hasNext())
+        {
+            Option option = (Option) iter.next();
 
-            if( iter.hasNext() ) {
-                buff.append( ", " );
+            if (option.getOpt() != null)
+            {
+                buff.append("-");
+                buff.append(option.getOpt());
+            }
+            else
+            {
+                buff.append("--");
+                buff.append(option.getLongOpt());
+            }
+
+            buff.append(" ");
+            buff.append(option.getDescription());
+
+            if (iter.hasNext())
+            {
+                buff.append(", ");
             }
         }
-        buff.append( "]" );
+
+        buff.append("]");
 
         return buff.toString();
     }
-}
+}
\ No newline at end of file
diff --git a/src/java/org/apache/commons/cli/OptionValidator.java b/src/java/org/apache/commons/cli/OptionValidator.java
new file mode 100644
index 0000000..265a277
--- /dev/null
+++ b/src/java/org/apache/commons/cli/OptionValidator.java
@@ -0,0 +1,101 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.cli;
+
+/**
+ * Validates an Option string.
+ *
+ * @author John Keyes ( john at integralsource.com )
+ */
+public class OptionValidator {
+
+    /**
+     * <p>Validates whether <code>opt</code> is a permissable Option
+     * shortOpt.  The rules that specify if the <code>opt</code>
+     * is valid are:</p>
+     * <ul>
+     *  <li><code>opt</code> is not NULL</li>
+     *  <li>a single character <code>opt</code> that is either
+     *  ' '(special case), '?', '@' or a letter</li>
+     *  <li>a multi character <code>opt</code> that only contains
+     *  letters.</li>
+     * </ul>
+     *
+     * @param opt The option string to validate
+     * @throws IllegalArgumentException if the Option is not valid.
+     */
+    static void validateOption(String opt)
+                        throws IllegalArgumentException
+    {
+        // check that opt is not NULL
+        if (opt == null)
+        {
+            return;
+        }
+
+        // handle the single character opt
+        else if (opt.length() == 1)
+        {
+            char ch = opt.charAt(0);
+
+            if (!isValidOpt(ch))
+            {
+                throw new IllegalArgumentException("illegal option value '" + ch
+                                                   + "'");
+            }
+        }
+
+        // handle the multi character opt
+        else
+        {
+            char[] chars = opt.toCharArray();
+
+            for (int i = 0; i < chars.length; i++)
+            {
+                if (!isValidChar(chars[i]))
+                {
+                    throw new IllegalArgumentException(
+                            "opt contains illegal character value '" + chars[i]
+                            + "'");
+                }
+            }
+        }
+    }
+
+    /**
+     * <p>Returns whether the specified character is a valid Option.</p>
+     *
+     * @param c the option to validate
+     * @return true if <code>c</code> is a letter, ' ', '?' or '@', 
+     * otherwise false.
+     */
+    private static boolean isValidOpt(char c)
+    {
+        return (isValidChar(c) || (c == ' ') || (c == '?') || c == '@');
+    }
+
+    /**
+     * <p>Returns whether the specified character is a valid character.</p>
+     *
+     * @param c the character to validate
+     * @return true if <code>c</code> is a letter.
+     */
+    private static boolean isValidChar(char c)
+    {
+        return Character.isJavaIdentifierPart(c);
+    }
+}
\ No newline at end of file
diff --git a/src/java/org/apache/commons/cli/Options.java b/src/java/org/apache/commons/cli/Options.java
index 11cf3a8..bec089c 100644
--- a/src/java/org/apache/commons/cli/Options.java
+++ b/src/java/org/apache/commons/cli/Options.java
@@ -1,74 +1,29 @@
-/*
- * $Header: /home/cvs/jakarta-commons-sandbox/cli/src/java/org/apache/commons/cli/Options.java,v 1.5 2002/06/06 22:32:37 bayard Exp $
- * $Revision: 1.5 $
- * $Date: 2002/06/06 22:32:37 $
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.*;
 
 /** <p>Main entry-point into the library.</p>
  *
@@ -83,69 +38,88 @@ import java.util.*;
  *
  * @author bob mcwhirter (bob @ werken.com)
  * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
- * @version $Revision: 1.5 $
+ * @version $Revision: 542144 $
  */
 public class Options {
 
     /** a map of the options with the character key */
-    private Map  shortOpts    = new HashMap();
+    private Map shortOpts = new HashMap();
 
     /** a map of the options with the long key */
-    private Map  longOpts     = new HashMap();
+    private Map longOpts = new HashMap();
 
     /** a map of the required options */
     private List requiredOpts = new ArrayList();
-    
+
     /** a map of the option groups */
-    private Map optionGroups  = new HashMap();
+    private Map optionGroups = new HashMap();
 
-    /** <p>Construct a new Options descriptor</p>
+    /** Construct a new Options descriptor
      */
-    public Options() {        
+    public Options()
+    {
+        // nothing to do
     }
 
     /**
-     * <p>Add the specified option group.</p>
+     * Add the specified option group.
      *
      * @param group the OptionGroup that is to be added
      * @return the resulting Options instance
      */
-    public Options addOptionGroup( OptionGroup group ) {
+    public Options addOptionGroup(OptionGroup group)
+    {
         Iterator options = group.getOptions().iterator();
 
-        if( group.isRequired() ) {
-            requiredOpts.add( group );
+        if (group.isRequired())
+        {
+            requiredOpts.add(group);
         }
 
-        while( options.hasNext() ) {
-            Option option = (Option)options.next();
+        while (options.hasNext())
+        {
+            Option option = (Option) options.next();
+
+
             // an Option cannot be required if it is in an
             // OptionGroup, either the group is required or
             // nothing is required
-            option.setRequired( false );
-            addOption( option );
+            option.setRequired(false);
+            addOption(option);
 
-            optionGroups.put( option.getOpt(), group );
+            optionGroups.put(option.getKey(), group);
         }
 
         return this;
     }
+    
+    /**
+     * Lists the OptionGroups that are members of this Options instance.
+     * @return a Collection of OptionGroup instances.
+     */
+    Collection getOptionGroups(){
+    	return new HashSet(optionGroups.values());
+    }
 
-    /** <p>Add an option that only contains a short-name</p>
-     * <p>It may be specified as requiring an argument.</p>
+    /** 
+     * Add an option that only contains a short-name.
+     * It may be specified as requiring an argument.
      *
      * @param opt Short single-character name of the option.
      * @param hasArg flag signally if an argument is required after this option
      * @param description Self-documenting description
      * @return the resulting Options instance
      */
-    public Options addOption(String opt, boolean hasArg, String description) {
-        addOption( opt, null, hasArg, description );
+    public Options addOption(String opt, boolean hasArg, String description)
+    {
+        addOption(opt, null, hasArg, description);
+
         return this;
     }
-    
-    /** <p>Add an option that contains a short-name and a long-name</p>
-     * <p>It may be specified as requiring an argument.</p>
+
+    /** 
+     * Add an option that contains a short-name and a long-name.
+     * It may be specified as requiring an argument.
      *
      * @param opt Short single-character name of the option.
      * @param longOpt Long multi-character name of the option.
@@ -153,147 +127,152 @@ public class Options {
      * @param description Self-documenting description
      * @return the resulting Options instance
      */
-    public Options addOption(String opt, String longOpt, boolean hasArg, String description) {
-        addOption( new Option( opt, longOpt, hasArg, description ) );        
+    public Options addOption(String opt, String longOpt, boolean hasArg, 
+                             String description)
+    {
+        addOption(new Option(opt, longOpt, hasArg, description));
+
         return this;
     }
 
     /**
-     * <p>Adds an option instance</p>
+     * Adds an option instance
      *
      * @param opt the option that is to be added 
      * @return the resulting Options instance
      */
-    public Options addOption(Option opt)  {
-        String shortOpt = "-" + opt.getOpt();
-        
+    public Options addOption(Option opt)
+    {
+        String key = opt.getKey();
+
         // add it to the long option list
-        if ( opt.hasLongOpt() ) {
-            longOpts.put( "--" + opt.getLongOpt(), opt );
+        if (opt.hasLongOpt())
+        {
+            longOpts.put(opt.getLongOpt(), opt);
         }
-        
+
         // if the option is required add it to the required list
-        if ( opt.isRequired() ) {
-            requiredOpts.add( shortOpt );
+        if (opt.isRequired() ) 
+        {
+            if( requiredOpts.contains(key) ) {
+                requiredOpts.remove( requiredOpts.indexOf(key) );
+            }
+            requiredOpts.add(key);
         }
 
-        shortOpts.put( shortOpt, opt );
-        
+        shortOpts.put(key, opt);
+
         return this;
     }
-    
-    /** <p>Retrieve a read-only list of options in this set</p>
+
+    /** 
+     * Retrieve a read-only list of options in this set
      *
      * @return read-only Collection of {@link Option} objects in this descriptor
      */
-    public Collection getOptions() {
-        List opts = new ArrayList( shortOpts.values() );
+    public Collection getOptions()
+    {
+        return Collections.unmodifiableCollection(helpOptions());
+    }
+
+    /**
+     * Returns the Options for use by the HelpFormatter.
+     *
+     * @return the List of Options
+     */
+    List helpOptions()
+    {
+        List opts = new ArrayList(shortOpts.values());
 
         // now look through the long opts to see if there are any Long-opt
         // only options
         Iterator iter = longOpts.values().iterator();
+
         while (iter.hasNext())
         {
             Object item = iter.next();
+
             if (!opts.contains(item))
             {
                 opts.add(item);
             }
         }
-        return Collections.unmodifiableCollection( opts );
-    }
 
-    /**
-     * <p>Returns the Options for use by the HelpFormatter.</p>
-     *
-     * @return the List of Options
-     */
-    List helpOptions() {
-        return new ArrayList( shortOpts.values() );
+        return new ArrayList(opts);
     }
 
-    /** <p>Returns the required options as a 
-     * <code>java.util.Collection</code>.</p>
+    /** 
+     * Returns the required options as a
+     * <code>java.util.Collection</code>.
      *
      * @return Collection of required options
      */
-    public List getRequiredOptions() {
+    public List getRequiredOptions()
+    {
         return requiredOpts;
     }
-    
-    /** <p>Retrieve the named {@link Option}</p>
+
+    /** 
+     * Retrieve the named {@link Option}
      *
      * @param opt short or long name of the {@link Option}
      * @return the option represented by opt
      */
-    public Option getOption( String opt ) {
-
-        Option option = null;
+    public Option getOption(String opt)
+    {
+        opt = Util.stripLeadingHyphens(opt);
 
-        // short option
-        if( opt.length() == 1 ) {
-            option = (Option)shortOpts.get( "-" + opt );
-        }
-        // long option
-        else if( opt.startsWith( "--" ) ) {
-            option = (Option)longOpts.get( opt );
-        }
-        // a just-in-case
-        else {
-            option = (Option)shortOpts.get( opt );
+        if (shortOpts.containsKey(opt))
+        {
+            return (Option) shortOpts.get(opt);
         }
 
-        return (option == null) ? null : (Option)option.clone();
+        return (Option) longOpts.get(opt);
     }
 
     /** 
-     * <p>Returns whether the named {@link Option} is a member
-     * of this {@link Options}</p>
+     * Returns whether the named {@link Option} is a member
+     * of this {@link Options}.
      *
      * @param opt short or long name of the {@link Option}
      * @return true if the named {@link Option} is a member
      * of this {@link Options}
      */
-    public boolean hasOption( String opt ) {
+    public boolean hasOption(String opt)
+    {
+        opt = Util.stripLeadingHyphens(opt);
 
-        // short option
-        if( opt.length() == 1 ) {
-            return shortOpts.containsKey( "-" + opt );
-        }
-        // long option
-        else if( opt.startsWith( "--" ) ) {
-            return longOpts.containsKey( opt );
-        }
-        // a just-in-case
-        else {
-            return shortOpts.containsKey( opt );
-        }
+        return shortOpts.containsKey(opt) || longOpts.containsKey(opt);
     }
 
-    /** <p>Returns the OptionGroup the <code>opt</code>
-     * belongs to.</p>
+    /** 
+     * Returns the OptionGroup the <code>opt</code>
+     * belongs to.
      * @param opt the option whose OptionGroup is being queried.
      *
      * @return the OptionGroup if <code>opt</code> is part
      * of an OptionGroup, otherwise return null
      */
-    public OptionGroup getOptionGroup( Option opt ) {
-        return (OptionGroup)optionGroups.get( opt.getOpt() );
+    public OptionGroup getOptionGroup(Option opt)
+    {
+        return (OptionGroup) optionGroups.get(opt.getKey());
     }
-    
-    /** <p>Dump state, suitable for debugging.</p>
+
+    /** 
+     * Dump state, suitable for debugging.
      *
      * @return Stringified form of this object
      */
-    public String toString() {
+    public String toString()
+    {
         StringBuffer buf = new StringBuffer();
-        
+
         buf.append("[ Options: [ short ");
-        buf.append( shortOpts.toString() );
-        buf.append( " ] [ long " );
-        buf.append( longOpts );
-        buf.append( " ]");
-        
+        buf.append(shortOpts.toString());
+        buf.append(" ] [ long ");
+        buf.append(longOpts);
+        buf.append(" ]");
+
         return buf.toString();
     }
-}
+}
\ No newline at end of file
diff --git a/src/java/org/apache/commons/cli/ParseException.java b/src/java/org/apache/commons/cli/ParseException.java
index dd14a23..7212e0f 100644
--- a/src/java/org/apache/commons/cli/ParseException.java
+++ b/src/java/org/apache/commons/cli/ParseException.java
@@ -1,82 +1,37 @@
-/*
- * $Header: /home/cvs/jakarta-commons-sandbox/cli/src/java/org/apache/commons/cli/ParseException.java,v 1.2 2002/06/06 09:37:26 jstrachan Exp $
- * $Revision: 1.2 $
- * $Date: 2002/06/06 09:37:26 $
- *
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
 /** 
  * <p>Base for Exceptions thrown during parsing of a command-line.</p>
  *
  * @author bob mcwhirter (bob @ werken.com)
- * @version $Revision: 1.2 $
+ * @version $Revision: 542144 $
  */
-public class ParseException extends Exception 
-{
-    
+public class ParseException extends Exception {
+
     /** 
      * <p>Construct a new <code>ParseException</code> 
      * with the specified detail message.</p>
      *
      * @param message the detail message
      */
-    public ParseException( String message ) {
-        super( message );
+    public ParseException(String message)
+    {
+        super(message);
     }
-}
+}
\ No newline at end of file
diff --git a/src/java/org/apache/commons/cli/Parser.java b/src/java/org/apache/commons/cli/Parser.java
index b740d13..a3fe43e 100644
--- a/src/java/org/apache/commons/cli/Parser.java
+++ b/src/java/org/apache/commons/cli/Parser.java
@@ -1,85 +1,43 @@
-/*
- * $Header: /home/cvspublic/jakarta-commons/cli/src/java/org/apache/commons/cli/Parser.java,v 1.7 2002/10/24 23:17:49 jkeyes Exp $
- * $Revision: 1.7 $
- * $Date: 2002/10/24 23:17:49 $
- *
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
 import java.util.Arrays;
+import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
-import java.util.Map;
+import java.util.Properties;
 
 /**
  * <p><code>Parser</code> creates {@link CommandLine}s.</p>
  *
  * @author John Keyes (john at integralsource.com)
  * @see Parser
- * @version $Revision: 1.7 $
+ * @version $Revision: 551815 $
  */
 public abstract class Parser implements CommandLineParser {
 
     /** commandline instance */
     private CommandLine cmd;
+
     /** current Options */
     private Options options;
+
     /** list of required options strings */
     private List requiredOptions;
 
@@ -89,14 +47,13 @@ public abstract class Parser implements CommandLineParser {
      * method.</p>
      *
      * @param opts The Options to parse the arguments by.
-     * @param args The arguments that have to be flattened.
+     * @param arguments The arguments that have to be flattened.
      * @param stopAtNonOption specifies whether to stop 
      * flattening when a non option has been encountered
      * @return a String array of the flattened arguments
      */
-    abstract protected String[] flatten( Options opts, 
-                                         String[] arguments, 
-                                         boolean stopAtNonOption );
+    protected abstract String[] flatten(Options opts, String[] arguments, 
+                                        boolean stopAtNonOption);
 
     /**
      * <p>Parses the specified <code>arguments</code> 
@@ -108,10 +65,29 @@ public abstract class Parser implements CommandLineParser {
      * @throws ParseException if an error occurs when parsing the
      * arguments.
      */
-    public CommandLine parse( Options options, String[] arguments ) 
-    throws ParseException 
+    public CommandLine parse(Options options, String[] arguments)
+                      throws ParseException
+    {
+        return parse(options, arguments, null, false);
+    }
+
+    /**
+     * Parse the arguments according to the specified options and
+     * properties.
+     *
+     * @param options the specified Options
+     * @param arguments the command line arguments
+     * @param properties command line option name-value pairs
+     * @return the list of atomic option and value tokens
+     *
+     * @throws ParseException if there are any problems encountered
+     * while parsing the command line tokens.
+     */
+    public CommandLine parse(Options options, String[] arguments, 
+                             Properties properties)
+        throws ParseException
     {
-        return parse( options, arguments, false );
+        return parse(options, arguments, properties, false);
     }
 
     /**
@@ -124,160 +100,318 @@ public abstract class Parser implements CommandLineParser {
      * interpreting the arguments when a non option has 
      * been encountered and to add them to the CommandLines
      * args list.
+     *
      * @return the <code>CommandLine</code>
      * @throws ParseException if an error occurs when parsing the
      * arguments.
      */
-    public CommandLine parse( Options opts, 
-                              String[] arguments, 
-                              boolean stopAtNonOption ) 
-    throws ParseException 
+    public CommandLine parse(Options options, String[] arguments, 
+                             boolean stopAtNonOption)
+        throws ParseException
+    {
+        return parse(options, arguments, null, stopAtNonOption);
+    }
+
+    /**
+     * Parse the arguments according to the specified options and
+     * properties.
+     *
+     * @param options the specified Options
+     * @param arguments the command line arguments
+     * @param properties command line option name-value pairs
+     * @param stopAtNonOption stop parsing the arguments when the first
+     * non option is encountered.
+     *
+     * @return the list of atomic option and value tokens
+     *
+     * @throws ParseException if there are any problems encountered
+     * while parsing the command line tokens.
+     */
+    public CommandLine parse(Options options, String[] arguments, 
+                             Properties properties, boolean stopAtNonOption)
+        throws ParseException
     {
         // initialise members
-        options = opts;
+        this.options = options;
+
+        // clear out the data in options in case it's been used before (CLI-71)
+        for (Iterator it = options.helpOptions().iterator(); it.hasNext();) {
+            Option opt = (Option) it.next();
+            opt.clearValues();
+        }
+
         requiredOptions = options.getRequiredOptions();
         cmd = new CommandLine();
 
         boolean eatTheRest = false;
 
-        List tokenList = Arrays.asList( flatten( opts, arguments, stopAtNonOption ) );
+        if (arguments == null)
+        {
+            arguments = new String[0];
+        }
+
+        List tokenList = Arrays.asList(flatten(this.options, 
+                                               arguments, 
+                                               stopAtNonOption));
+
         ListIterator iterator = tokenList.listIterator();
 
         // process each flattened token
-        while( iterator.hasNext() ) {
-            String t = (String)iterator.next();
+        while (iterator.hasNext())
+        {
+            String t = (String) iterator.next();
 
             // the value is the double-dash
-            if( "--".equals( t ) ) {
+            if ("--".equals(t))
+            {
                 eatTheRest = true;
             }
+
             // the value is a single dash
-            else if( "-".equals( t ) ) {
-                if( stopAtNonOption ) {
+            else if ("-".equals(t))
+            {
+                if (stopAtNonOption)
+                {
                     eatTheRest = true;
                 }
-                else {
-                    cmd.addArg(t );
+                else
+                {
+                    cmd.addArg(t);
                 }
             }
+
             // the value is an option
-            else if( t.startsWith( "-" ) ) {
-                if ( stopAtNonOption && !options.hasOption( t ) ) {
+            else if (t.startsWith("-"))
+            {
+                if (stopAtNonOption && !options.hasOption(t))
+                {
                     eatTheRest = true;
-                    cmd.addArg( t );
+                    cmd.addArg(t);
                 }
-                else {
-                    processOption( t, iterator );
+                else
+                {
+                    processOption(t, iterator);
                 }
             }
+
             // the value is an argument
-            else {
-                cmd.addArg( t );
-                if( stopAtNonOption ) {
+            else
+            {
+                cmd.addArg(t);
+
+                if (stopAtNonOption)
+                {
                     eatTheRest = true;
                 }
             }
 
             // eat the remaining tokens
-            if( eatTheRest ) {
-                while( iterator.hasNext() ) {
-                    String str = (String)iterator.next();
+            if (eatTheRest)
+            {
+                while (iterator.hasNext())
+                {
+                    String str = (String) iterator.next();
+
                     // ensure only one double-dash is added
-                    if( !"--".equals( str ) ) {
-                        cmd.addArg( str );
+                    if (!"--".equals(str))
+                    {
+                        cmd.addArg(str);
                     }
                 }
             }
         }
+
+        processProperties(properties);
         checkRequiredOptions();
+
         return cmd;
     }
 
     /**
+     * <p>Sets the values of Options using the values in 
+     * <code>properties</code>.</p>
+     *
+     * @param properties The value properties to be processed.
+     */
+    private void processProperties(Properties properties)
+    {
+        if (properties == null)
+        {
+            return;
+        }
+
+        for (Enumeration e = properties.propertyNames(); e.hasMoreElements();)
+        {
+            String option = e.nextElement().toString();
+
+            if (!cmd.hasOption(option))
+            {
+                Option opt = options.getOption(option);
+
+                // get the value from the properties instance
+                String value = properties.getProperty(option);
+
+                if (opt.hasArg())
+                {
+                    if ((opt.getValues() == null)
+                        || (opt.getValues().length == 0))
+                    {
+                        try
+                        {
+                            opt.addValueForProcessing(value);
+                        }
+                        catch (RuntimeException exp)
+                        {
+                            // if we cannot add the value don't worry about it
+                        }
+                    }
+                }
+                else if (!("yes".equalsIgnoreCase(value) 
+                           || "true".equalsIgnoreCase(value)
+                           || "1".equalsIgnoreCase(value)))
+                {
+                    // if the value is not yes, true or 1 then don't add the
+                    // option to the CommandLine
+                    break;
+                }
+
+                cmd.addOption(opt);
+            }
+        }
+    }
+
+    /**
      * <p>Throws a {@link MissingOptionException} if all of the
      * required options are no present.</p>
+     *
+     * @throws MissingOptionException if any of the required Options
+     * are not present.
      */
     private void checkRequiredOptions()
-    throws MissingOptionException 
+        throws MissingOptionException
     {
-
         // if there are required options that have not been
         // processsed
-        if( requiredOptions.size() > 0 ) {
+        if (requiredOptions.size() > 0)
+        {
             Iterator iter = requiredOptions.iterator();
-            StringBuffer buff = new StringBuffer();
+            StringBuffer buff = new StringBuffer("Missing required option");
+            buff.append(requiredOptions.size() == 1 ? "" : "s");
+            buff.append(": ");
+
 
             // loop through the required options
-            while( iter.hasNext() ) {
-                buff.append( iter.next() );
+            while (iter.hasNext())
+            {
+                buff.append(iter.next());
             }
 
-            throw new MissingOptionException( buff.toString() );
+            throw new MissingOptionException(buff.toString());
         }
     }
 
-    public void processArgs( Option opt, ListIterator iter ) 
-    throws ParseException
+    /**
+     * <p>Process the argument values for the specified Option
+     * <code>opt</code> using the values retrieved from the 
+     * specified iterator <code>iter</code>.
+     *
+     * @param opt The current Option
+     * @param iter The iterator over the flattened command line
+     * Options.
+     *
+     * @throws ParseException if an argument value is required
+     * and it is has not been found.
+     */
+    public void processArgs(Option opt, ListIterator iter)
+        throws ParseException
     {
         // loop until an option is found
-        while( iter.hasNext() ) {
-            String var = (String)iter.next();
+        while (iter.hasNext())
+        {
+            String str = (String) iter.next();
 
-            // found an Option
-            if( options.hasOption( var ) ) {
+            // found an Option, not an argument
+            if (options.hasOption(str) && str.startsWith("-"))
+            {
                 iter.previous();
                 break;
             }
+
             // found a value
-            else if( !opt.addValue( var ) ) {
+            try
+            {
+                opt.addValueForProcessing( Util.stripLeadingAndTrailingQuotes(str) );
+            }
+            catch (RuntimeException exp)
+            {
                 iter.previous();
                 break;
             }
         }
 
-        if( opt.getValues() == null && !opt.hasOptionalArg() ) {
-            throw new MissingArgumentException( "no argument for:" + opt.getOpt() );
+        if ((opt.getValues() == null) && !opt.hasOptionalArg())
+        {
+            throw new MissingArgumentException("Missing argument for option:"
+                                               + opt.getKey());
         }
     }
 
-    private void processOption( String arg, ListIterator iter ) 
-    throws ParseException
+    /**
+     * <p>Process the Option specified by <code>arg</code>
+     * using the values retrieved from the specfied iterator
+     * <code>iter</code>.
+     *
+     * @param arg The String value representing an Option
+     * @param iter The iterator over the flattened command 
+     * line arguments.
+     *
+     * @throws ParseException if <code>arg</code> does not
+     * represent an Option
+     */
+    private void processOption(String arg, ListIterator iter)
+        throws ParseException
     {
-        // get the option represented by arg
-        Option opt = null;
-
-        boolean hasOption = options.hasOption( arg );
+        boolean hasOption = options.hasOption(arg);
 
         // if there is no option throw an UnrecognisedOptionException
-        if( !hasOption ) {
-            throw new UnrecognizedOptionException("Unrecognized option: " + arg);
-        }
-        else {
-            opt = (Option) options.getOption( arg );
+        if (!hasOption)
+        {
+            throw new UnrecognizedOptionException("Unrecognized option: " 
+                                                  + arg);
         }
+        
+        // get the option represented by arg
+        final Option opt = options.getOption(arg);
 
         // if the option is a required option remove the option from
         // the requiredOptions list
-        if ( opt.isRequired() ) {
-            requiredOptions.remove( "-" + opt.getOpt() );
+        if (opt.isRequired())
+        {
+            requiredOptions.remove(opt.getKey());
         }
 
         // if the option is in an OptionGroup make that option the selected
         // option of the group
-        if ( options.getOptionGroup( opt ) != null ) {
-            OptionGroup group = ( OptionGroup ) options.getOptionGroup( opt );
-            if( group.isRequired() ) {
-                requiredOptions.remove( group );
+        if (options.getOptionGroup(opt) != null)
+        {
+            OptionGroup group = options.getOptionGroup(opt);
+
+            if (group.isRequired())
+            {
+                requiredOptions.remove(group);
             }
-            group.setSelected( opt );
+
+            group.setSelected(opt);
         }
 
         // if the option takes an argument value
-        if ( opt.hasArg() ) {
-            processArgs( opt, iter );
+        if (opt.hasArg())
+        {
+            processArgs(opt, iter);
         }
 
+
         // set the option on the command line
-        cmd.addOption( opt );
+        cmd.addOption(opt);
     }
-}
\ No newline at end of file
+}
diff --git a/src/java/org/apache/commons/cli/PatternOptionBuilder.java b/src/java/org/apache/commons/cli/PatternOptionBuilder.java
index d544e69..893e73d 100644
--- a/src/java/org/apache/commons/cli/PatternOptionBuilder.java
+++ b/src/java/org/apache/commons/cli/PatternOptionBuilder.java
@@ -1,99 +1,84 @@
-/*
- * $Header: /home/cvs/jakarta-commons-sandbox/cli/src/java/org/apache/commons/cli/PatternOptionBuilder.java,v 1.2 2002/06/06 22:49:36 bayard Exp $
- * $Revision: 1.2 $
- * $Date: 2002/06/06 22:49:36 $
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
 /** 
+ * <p>
  * Allows Options to be created from a single String.
+ * The pattern contains various single character flags and via
+ * an optional punctuation character, their expected type.
+ * </p>
+ *
+ * <table border="1">
+ * <tr><td>a</td><td>-a flag</td></tr>
+ * <tr><td>b@</td><td>-b [classname]</td></tr>
+ * <tr><td>c></td><td>-c [filename]</td></tr>
+ * <tr><td>d+</td><td>-d [classname] (creates object via empty contructor)</td></tr>
+ * <tr><td>e%</td><td>-e [number] (creates Double/Long instance depeding on existing of a '.')</td></tr>
+ * <tr><td>f/</td><td>-f [url]</td></tr>
+ * <tr><td>g:</td><td>-g [string]</td></tr>
+ * </table>
+ *
+ * <p>
+ * For example, the following allows command line flags of '-v -p string-value -f /dir/file'.
+ * </p>
+ * <code>Options options = PatternOptionBuilder.parsePattern("vp:f/");</code>
  *
+ * <p>
+ * TODO These need to break out to OptionType and also 
+ * to be pluggable.
+ * </p>
  *
  * @author Henri Yandell (bayard @ generationjava.com)
- * @version $Revision: 1.2 $
+ * @version $Revision: 542144 $
  */
 public class PatternOptionBuilder {
 
-    /// TODO: These need to break out to OptionType and also to be pluggable.
-
     /** String class */
-    public static final Class STRING_VALUE        = java.lang.String.class;
+    public static final Class STRING_VALUE = java.lang.String.class;
+
     /** Object class */
-    public static final Class OBJECT_VALUE        = java.lang.Object.class;
+    public static final Class OBJECT_VALUE = java.lang.Object.class;
+
     /** Number class */
-    public static final Class NUMBER_VALUE        = java.lang.Number.class;
+    public static final Class NUMBER_VALUE = java.lang.Number.class;
+
     /** Date class */
-    public static final Class DATE_VALUE          = java.util.Date.class;
+    public static final Class DATE_VALUE = java.util.Date.class;
+
     /** Class class */
-    public static final Class CLASS_VALUE         = java.lang.Class.class;
+    public static final Class CLASS_VALUE = java.lang.Class.class;
+
+    /// can we do this one?? 
+    // is meant to check that the file exists, else it errors.
+    // ie) it's for reading not writing.
 
-/// can we do this one?? 
-// is meant to check that the file exists, else it errors.
-// ie) it's for reading not writing.
     /** FileInputStream class */
-    public static final Class EXISTING_FILE_VALUE = java.io.FileInputStream.class;
+    public static final Class EXISTING_FILE_VALUE = 
+            java.io.FileInputStream.class;
+
     /** File class */
-    public static final Class FILE_VALUE          = java.io.File.class;
+    public static final Class FILE_VALUE = java.io.File.class;
+
     /** File array class */
-    public static final Class FILES_VALUE         = java.io.File[].class;
+    public static final Class FILES_VALUE = java.io.File[].class;
+
     /** URL class */
-    public static final Class URL_VALUE           = java.net.URL.class;
+    public static final Class URL_VALUE = java.net.URL.class;
 
     /**
      * <p>Retrieve the class that <code>ch</code> represents.</p>
@@ -101,29 +86,48 @@ public class PatternOptionBuilder {
      * @param ch the specified character
      * @return The class that <code>ch</code> represents
      */
-    public static Object getValueClass(char ch) {
-        if (ch == '@') {
+    public static Object getValueClass(char ch)
+    {
+        if (ch == '@')
+        {
             return PatternOptionBuilder.OBJECT_VALUE;
-        } else if (ch == ':') {
+        }
+        else if (ch == ':')
+        {
             return PatternOptionBuilder.STRING_VALUE;
-        } else if (ch == '%') {
+        }
+        else if (ch == '%')
+        {
             return PatternOptionBuilder.NUMBER_VALUE;
-        } else if (ch == '+') {
+        }
+        else if (ch == '+')
+        {
             return PatternOptionBuilder.CLASS_VALUE;
-        } else if (ch == '#') {
+        }
+        else if (ch == '#')
+        {
             return PatternOptionBuilder.DATE_VALUE;
-        } else if (ch == '<') {
+        }
+        else if (ch == '<')
+        {
             return PatternOptionBuilder.EXISTING_FILE_VALUE;
-        } else if (ch == '>') {
+        }
+        else if (ch == '>')
+        {
             return PatternOptionBuilder.FILE_VALUE;
-        } else if (ch == '*') {
+        }
+        else if (ch == '*')
+        {
             return PatternOptionBuilder.FILES_VALUE;
-        } else if (ch == '/') {
+        }
+        else if (ch == '/')
+        {
             return PatternOptionBuilder.URL_VALUE;
         }
+
         return null;
     }
- 
+
     /**
      * <p>Returns whether <code>ch</code> is a value code, i.e.
      * whether it represents a class in a pattern.</p>
@@ -131,23 +135,18 @@ public class PatternOptionBuilder {
      * @param ch the specified character
      * @return true if <code>ch</code> is a value code, otherwise false.
      */
-    public static boolean isValueCode(char ch) {
-        if( (ch != '@') &&
-            (ch != ':') &&
-            (ch != '%') &&
-            (ch != '+') &&
-            (ch != '#') &&
-            (ch != '<') &&
-            (ch != '>') &&
-            (ch != '*') &&
-            (ch != '/')
-          )
+    public static boolean isValueCode(char ch)
+    {
+        if ((ch != '@') && (ch != ':') && (ch != '%') && (ch != '+')
+            && (ch != '#') && (ch != '<') && (ch != '>') && (ch != '*')
+            && (ch != '/') && (ch != '!'))
         {
             return false;
         }
+
         return true;
-    }       
- 
+    }
+
     /**
      * <p>Returns the {@link Options} instance represented by 
      * <code>pattern</code>.</p>
@@ -155,7 +154,8 @@ public class PatternOptionBuilder {
      * @param pattern the pattern string
      * @return The {@link Options} instance
      */
-    public static Options parsePattern(String pattern) {
+    public static Options parsePattern(String pattern)
+    {
         int sz = pattern.length();
 
         char opt = ' ';
@@ -164,41 +164,50 @@ public class PatternOptionBuilder {
         Object type = null;
 
         Options options = new Options();
-        
-        for(int i=0; i<sz; i++) {
+
+        for (int i = 0; i < sz; i++)
+        {
             ch = pattern.charAt(i);
 
             // a value code comes after an option and specifies 
             // details about it
-            if(!isValueCode(ch)) {
-                if(opt != ' ') {
+            if (!isValueCode(ch))
+            {
+                if (opt != ' ')
+                {
+                    OptionBuilder.hasArg(type != null);
+                    OptionBuilder.isRequired(required);
+                    OptionBuilder.withType(type);
+                    
                     // we have a previous one to deal with
-                    options.addOption( OptionBuilder.hasArg( type != null )
-                                                    .isRequired( required )
-                                                    .withType( type )
-                                                    .create( opt ) );
+                    options.addOption(OptionBuilder.create(opt));
                     required = false;
                     type = null;
                     opt = ' ';
                 }
+
                 opt = ch;
-            } else
-            if(ch == '!') {
+            }
+            else if (ch == '!')
+            {
                 required = true;
-            } else {
+            }
+            else
+            {
                 type = getValueClass(ch);
             }
         }
 
-        if(opt != ' ') {
+        if (opt != ' ')
+        {
+            OptionBuilder.hasArg(type != null);
+            OptionBuilder.isRequired(required);
+            OptionBuilder.withType(type);
+            
             // we have a final one to deal with
-            options.addOption( OptionBuilder.hasArg( type != null )
-                                            .isRequired( required )
-                                            .withType( type )
-                                            .create( opt ) );
+            options.addOption(OptionBuilder.create(opt));
         }
 
         return options;
     }
-
 }
diff --git a/src/java/org/apache/commons/cli/PosixParser.java b/src/java/org/apache/commons/cli/PosixParser.java
index 3169df6..3f91680 100644
--- a/src/java/org/apache/commons/cli/PosixParser.java
+++ b/src/java/org/apache/commons/cli/PosixParser.java
@@ -1,70 +1,24 @@
-/*
- * $Header: /home/cvspublic/jakarta-commons/cli/src/java/org/apache/commons/cli/PosixParser.java,v 1.11 2002/09/19 22:59:43 jkeyes Exp $
- * $Revision: 1.11 $
- * $Date: 2002/09/19 22:59:43 $
- *
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 package org.apache.commons.cli;
 
-import java.util.Arrays;
 import java.util.ArrayList;
-import java.util.Collection;
+import java.util.Arrays;
 import java.util.Iterator;
-import java.util.Map;
 
 /**
  * The class PosixParser provides an implementation of the 
@@ -72,16 +26,19 @@ import java.util.Map;
  *
  * @author John Keyes (john at integralsource.com)
  * @see Parser
- * @version $Revision: 1.11 $
+ * @version $Revision: 542151 $
  */
 public class PosixParser extends Parser {
 
     /** holder for flattened tokens */
     private ArrayList tokens = new ArrayList();
+
     /** specifies if bursting should continue */
     private boolean eatTheRest;
+
     /** holder for the current option */
     private Option currentOption;
+
     /** the command line Options */
     private Options options;
 
@@ -90,7 +47,8 @@ public class PosixParser extends Parser {
      * all of <code>tokens</code> entries, set <code>eatTheRest</code>
      * to false and set <code>currentOption</code> to null.</p>
      */
-    private void init() {
+    private void init()
+    {
         eatTheRest = false;
         tokens.clear();
         currentOption = null;
@@ -121,7 +79,7 @@ public class PosixParser extends Parser {
      *  characters in length and the first character is "<b>-</b>" then
      *  we need to burst the entry to determine its constituents.  For more
      *  information on the bursting algorithm see 
-     *  {@link PosixParser#burstToken( String, boolean) burstToken}.</li>
+     *  {@link PosixParser#burstToken(String, boolean) burstToken}.</li>
      *  <li>if the current <code>arguments</code> entry is not handled 
      *  by any of the previous rules, then the entry is added to the list
      *  of processed tokens.</li>
@@ -134,61 +92,75 @@ public class PosixParser extends Parser {
      * when an non option is found.
      * @return The flattened <code>arguments</code> String array.
      */
-    protected String[] flatten( Options options, 
-                                String[] arguments, 
-                                boolean stopAtNonOption )
+    protected String[] flatten(Options options, String[] arguments, 
+                               boolean stopAtNonOption)
     {
         init();
         this.options = options;
 
         // an iterator for the command line tokens
-        Iterator iter = Arrays.asList( arguments ).iterator();
-        String token = null;
-        
-        // process each command line token
-        while ( iter.hasNext() ) {
+        Iterator iter = Arrays.asList(arguments).iterator();
+        String token;
 
+        // process each command line token
+        while (iter.hasNext())
+        {
             // get the next command line token
             token = (String) iter.next();
 
             // handle SPECIAL TOKEN
-            if( token.startsWith( "--" ) ) {
-                if( token.indexOf( '=' ) != -1 ) {
-                    tokens.add( token.substring( 0, token.indexOf( '=' ) ) );
-                    tokens.add( token.substring( token.indexOf( '=' ) + 1,
-                                                 token.length() ) );
+            if (token.startsWith("--"))
+            {
+                if (token.indexOf('=') != -1)
+                {
+                    tokens.add(token.substring(0, token.indexOf('=')));
+                    tokens.add(token.substring(token.indexOf('=') + 1, 
+                                               token.length()));
+                }
+                else
+                {
+                    tokens.add(token);
                 }
-                else {
-                    tokens.add( token );
-                }	
             }
+
             // single hyphen
-            else if( "-".equals( token ) ) {
-                processSingleHyphen( token );
+            else if ("-".equals(token))
+            {
+                processSingleHyphen(token);
             }
-            else if( token.startsWith( "-" ) ) {
+            else if (token.startsWith("-"))
+            {
                 int tokenLength = token.length();
-                if( tokenLength == 2 ) {
-                    processOptionToken( token, stopAtNonOption );
+
+                if (tokenLength == 2)
+                {
+                    processOptionToken(token, stopAtNonOption);
+                }
+                else if (options.hasOption(token)) {
+                	tokens.add(token);
                 }
                 // requires bursting
-                else {
-                    burstToken( token, stopAtNonOption );
+                else
+                {
+                    burstToken(token, stopAtNonOption);
                 }
             }
-            else {
-                if( stopAtNonOption ) {
-                    process( token );
+            else
+            {
+                if (stopAtNonOption)
+                {
+                    process(token);
                 }
-                else {
-                    tokens.add( token );
+                else
+                {
+                    tokens.add(token);
                 }
             }
 
-            gobble( iter );
+            gobble(iter);
         }
 
-        return (String[])tokens.toArray( new String[] {} );
+        return (String[]) tokens.toArray(new String[tokens.size()]);
     }
 
     /**
@@ -196,10 +168,13 @@ public class PosixParser extends Parser {
      *
      * @param iter An iterator over the remaining tokens
      */
-    private void gobble( Iterator iter ) {
-        if( eatTheRest ) {
-            while( iter.hasNext() ) {
-                tokens.add( iter.next() );
+    private void gobble(Iterator iter)
+    {
+        if (eatTheRest)
+        {
+            while (iter.hasNext())
+            {
+                tokens.add(iter.next());
             }
         }
     }
@@ -217,20 +192,25 @@ public class PosixParser extends Parser {
      *
      * @param value The current token
      */
-    private void process( String value ) {
-        if( currentOption != null && currentOption.hasArg() ) {
-            if( currentOption.hasArg() ) {
-                tokens.add( value );
+    private void process(String value)
+    {
+        if ((currentOption != null) && currentOption.hasArg())
+        {
+            if (currentOption.hasArg())
+            {
+                tokens.add(value);
                 currentOption = null;
             }
-            else if (currentOption.hasArgs() ) {
-                tokens.add( value );
+            else if (currentOption.hasArgs())
+            {
+                tokens.add(value);
             }
         }
-        else {
+        else
+        {
             eatTheRest = true;
-            tokens.add( "--" );
-            tokens.add( value );
+            tokens.add("--");
+            tokens.add(value);
         }
     }
 
@@ -240,8 +220,9 @@ public class PosixParser extends Parser {
      *
      * @param hyphen The hyphen token
      */
-    private void processSingleHyphen( String hyphen ) {
-        tokens.add( hyphen );
+    private void processSingleHyphen(String hyphen)
+    {
+        tokens.add(hyphen);
     }
 
     /**
@@ -256,12 +237,15 @@ public class PosixParser extends Parser {
      * @param stopAtNonOption Specifies whether flattening should halt
      * at the first non option.
      */
-    private void processOptionToken( String token, boolean stopAtNonOption ) {
-        if( this.options.hasOption( token ) ) {
-            currentOption = this.options.getOption( token );
-            tokens.add( token );
+    private void processOptionToken(String token, boolean stopAtNonOption)
+    {
+        if (this.options.hasOption(token))
+        {
+            currentOption = this.options.getOption(token);
+            tokens.add(token);
         }
-        else if( stopAtNonOption ) {
+        else if (stopAtNonOption)
+        {
             eatTheRest = true;
         }
     }
@@ -270,7 +254,7 @@ public class PosixParser extends Parser {
      * <p>Breaks <code>token</code> into its constituent parts
      * using the following algorithm.
      * <ul>
-     *  <li>ignore the first character ("<b>-</b>" )</li>
+     *  <li>ignore the first character ("<b>-</b>")</li>
      *  <li>foreach remaining character check if an {@link Option}
      *  exists with that id.</li>
      *  <li>if an {@link Option} does exist then add that character
@@ -287,28 +271,41 @@ public class PosixParser extends Parser {
      *  character prepended with "<b>-</b>".</li>
      * </ul>
      * </p>
+     *
+     * @param token The current token to be <b>burst</b>
+     * @param stopAtNonOption Specifies whether to stop processing
+     * at the first non-Option encountered.
      */
-    protected void burstToken( String token, boolean stopAtNonOption ) {
+    protected void burstToken(String token, boolean stopAtNonOption)
+    {
         int tokenLength = token.length();
 
-        for( int i = 1; i < tokenLength; i++) {
-            String ch = String.valueOf( token.charAt( i ) );
-            boolean hasOption = options.hasOption( ch );
+        for (int i = 1; i < tokenLength; i++)
+        {
+            String ch = String.valueOf(token.charAt(i));
+            boolean hasOption = options.hasOption(ch);
+
+            if (hasOption)
+            {
+                tokens.add("-" + ch);
+                currentOption = options.getOption(ch);
+
+                if (currentOption.hasArg() && (token.length() != (i + 1)))
+                {
+                    tokens.add(token.substring(i + 1));
 
-            if( hasOption ) {
-                tokens.add( "-" + ch );
-                currentOption = options.getOption( ch );
-                if( currentOption.hasArg() && token.length()!=i+1 ) {
-                    tokens.add( token.substring( i+1 ) );
                     break;
                 }
             }
-            else if( stopAtNonOption ) {
-                process( token.substring( i ) );
+            else if (stopAtNonOption)
+            {
+                process(token.substring(i));
             }
-            else {
-                tokens.add( "-" + ch );
+            else
+            {
+                tokens.add(token);
+                break;
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/java/org/apache/commons/cli/TypeHandler.java b/src/java/org/apache/commons/cli/TypeHandler.java
index e0ea277..c6b3728 100644
--- a/src/java/org/apache/commons/cli/TypeHandler.java
+++ b/src/java/org/apache/commons/cli/TypeHandler.java
@@ -1,72 +1,27 @@
 /*
- * $Header: /home/cvs/jakarta-commons-sandbox/cli/src/java/org/apache/commons/cli/TypeHandler.java,v 1.2 2002/06/06 22:49:36 bayard Exp $
- * $Revision: 1.2 $
- * $Date: 2002/06/06 22:49:36 $
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
 import java.io.File;
-import java.net.URL;
+
 import java.net.MalformedURLException;
-import java.util.Date;
+import java.net.URL;
 
-import org.apache.commons.lang.NumberUtils;
+import java.util.Date;
 
 /**
   * This is a temporary implementation. TypeHandler will handle the 
@@ -75,8 +30,8 @@ import org.apache.commons.lang.NumberUtils;
   * alreayd. BeanUtils I think.
   *
   * @author Henri Yandell (bayard @ generationjava.com)
-  * @version $Revision: 1.2 $
-  */    
+  * @version $Revision: 542151 $
+  */
 public class TypeHandler {
 
     /**
@@ -88,8 +43,9 @@ public class TypeHandler {
      * @return The instance of <code>obj</code> initialised with
      * the value of <code>str</code>.
      */
-    public static Object createValue(String str, Object obj) {
-        return createValue(str, (Class)obj);
+    public static Object createValue(String str, Object obj)
+    {
+        return createValue(str, (Class) obj);
     }
 
     /**
@@ -101,34 +57,46 @@ public class TypeHandler {
      * @return The instance of <code>clazz</code> initialised with
      * the value of <code>str</code>.
      */
-    public static Object createValue(String str, Class clazz) {
-        if( PatternOptionBuilder.STRING_VALUE == clazz) {
+    public static Object createValue(String str, Class clazz)
+    {
+        if (PatternOptionBuilder.STRING_VALUE == clazz)
+        {
             return str;
-        } else
-        if( PatternOptionBuilder.OBJECT_VALUE == clazz) {
+        }
+        else if (PatternOptionBuilder.OBJECT_VALUE == clazz)
+        {
             return createObject(str);
-        } else
-        if( PatternOptionBuilder.NUMBER_VALUE == clazz) {
+        }
+        else if (PatternOptionBuilder.NUMBER_VALUE == clazz)
+        {
             return createNumber(str);
-        } else
-        if( PatternOptionBuilder.DATE_VALUE   == clazz) {
+        }
+        else if (PatternOptionBuilder.DATE_VALUE == clazz)
+        {
             return createDate(str);
-        } else
-        if( PatternOptionBuilder.CLASS_VALUE  == clazz) {
+        }
+        else if (PatternOptionBuilder.CLASS_VALUE == clazz)
+        {
             return createClass(str);
-        } else
-        if( PatternOptionBuilder.FILE_VALUE   == clazz) {
+        }
+        else if (PatternOptionBuilder.FILE_VALUE == clazz)
+        {
             return createFile(str);
-        } else
-        if( PatternOptionBuilder.EXISTING_FILE_VALUE   == clazz) {
+        }
+        else if (PatternOptionBuilder.EXISTING_FILE_VALUE == clazz)
+        {
             return createFile(str);
-        } else
-        if( PatternOptionBuilder.FILES_VALUE  == clazz) {
+        }
+        else if (PatternOptionBuilder.FILES_VALUE == clazz)
+        {
             return createFiles(str);
-        } else
-        if( PatternOptionBuilder.URL_VALUE    == clazz) {
+        }
+        else if (PatternOptionBuilder.URL_VALUE == clazz)
+        {
             return createURL(str);
-        } else {
+        }
+        else
+        {
             return null;
         }
     }
@@ -137,27 +105,42 @@ public class TypeHandler {
       * <p>Create an Object from the classname and empty constructor.</p>
       *
       * @param str the argument value
-      * @return the initialised object, or null if it couldn't create the Object.
+      * @return the initialised object, or null if it couldn't create 
+      * the Object.
       */
-    public static Object createObject(String str) {
+    public static Object createObject(String str)
+    {
         Class cl = null;
-        try {
+
+        try
+        {
             cl = Class.forName(str);
-        } catch (ClassNotFoundException cnfe) {
-            System.err.println("Unable to find: "+str);
+        }
+        catch (ClassNotFoundException cnfe)
+        {
+            System.err.println("Unable to find: " + str);
+
             return null;
         }
 
         Object instance = null;
 
-        try {
+        try
+        {
             instance = cl.newInstance();
-        } catch (InstantiationException cnfe) {
-            System.err.println("InstantiationException; Unable to create: "+str);
+        }
+        catch (InstantiationException cnfe)
+        {
+            System.err.println("InstantiationException; Unable to create: "
+                               + str);
+
             return null;
         }
-        catch (IllegalAccessException cnfe) {
-            System.err.println("IllegalAccessException; Unable to create: "+str);
+        catch (IllegalAccessException cnfe)
+        {
+            System.err.println("IllegalAccessException; Unable to create: "
+                               + str);
+
             return null;
         }
 
@@ -165,21 +148,35 @@ public class TypeHandler {
     }
 
     /**
-     * <p>Create a number from a String.</p>
+     * <p>Create a number from a String. If a . is present, it creates a 
+     *    Double, otherwise a Long. </p>
      *
      * @param str the value
      * @return the number represented by <code>str</code>, if <code>str</code>
      * is not a number, null is returned.
      */
-    public static Number createNumber(String str) {
-        // Needs to be able to create
-        try {
-            // do searching for decimal point etc, but atm just make an Integer
-            return NumberUtils.createNumber(str);
-        } catch (NumberFormatException nfe) {
+    public static Number createNumber(String str)
+    {
+        try
+        {
+            if( str != null )
+            {
+                if( str.indexOf('.') != -1 )
+                {
+                    return Double.valueOf(str);
+                }
+                else
+                {
+                    return Long.valueOf(str);
+                }
+            }
+        }
+        catch (NumberFormatException nfe)
+        {
             System.err.println(nfe.getMessage());
-            return null;
         }
+
+        return null;
     }
 
     /**
@@ -188,11 +185,16 @@ public class TypeHandler {
      * @param str the class name
      * @return The class if it is found, otherwise return null
      */
-    public static Class createClass(String str) {
-        try {
+    public static Class createClass(String str)
+    {
+        try
+        {
             return Class.forName(str);
-        } catch (ClassNotFoundException cnfe) {
-            System.err.println("Unable to find: "+str);
+        }
+        catch (ClassNotFoundException cnfe)
+        {
+            System.err.println("Unable to find: " + str);
+
             return null;
         }
     }
@@ -204,12 +206,9 @@ public class TypeHandler {
      * @return The date if <code>str</code> is a valid date string,
      * otherwise return null.
      */
-    public static Date createDate(String str) {
-        Date date = null;
-        if(date == null) {
-            System.err.println("Unable to parse: "+str);
-        }
-        return date;
+    public static Date createDate(String str)
+    {
+        throw new UnsupportedOperationException("Not yet implemented");
     }
 
     /**
@@ -219,11 +218,16 @@ public class TypeHandler {
      * @return The URL is <code>str</code> is well-formed, otherwise
      * return null.
      */
-    public static URL createURL(String str) {
-        try {
+    public static URL createURL(String str)
+    {
+        try
+        {
             return new URL(str);
-        } catch (MalformedURLException mue) {
-            System.err.println("Unable to parse: "+str);
+        }
+        catch (MalformedURLException mue)
+        {
+            System.err.println("Unable to parse: " + str);
+
             return null;
         }
     }
@@ -234,7 +238,8 @@ public class TypeHandler {
      * @param str the File location
      * @return The file represented by <code>str</code>.
      */
-    public static File createFile(String str) {
+    public static File createFile(String str)
+    {
         return new File(str);
     }
 
@@ -244,10 +249,10 @@ public class TypeHandler {
      * @param str the paths to the files
      * @return The File[] represented by <code>str</code>.
      */
-    public static File[] createFiles(String str) {
-// to implement/port:
-//        return FileW.findFiles(str);
+    public static File[] createFiles(String str)
+    {
+        // to implement/port:
+        //        return FileW.findFiles(str);
         return null;
     }
-
 }
diff --git a/src/java/org/apache/commons/cli/UnrecognizedOptionException.java b/src/java/org/apache/commons/cli/UnrecognizedOptionException.java
index 553efc3..e7d5d35 100644
--- a/src/java/org/apache/commons/cli/UnrecognizedOptionException.java
+++ b/src/java/org/apache/commons/cli/UnrecognizedOptionException.java
@@ -1,64 +1,19 @@
-/*
- * $Header: /home/cvs/jakarta-commons-sandbox/cli/src/java/org/apache/commons/cli/UnrecognizedOptionException.java,v 1.2 2002/06/06 09:37:26 jstrachan Exp $
- * $Revision: 1.2 $
- * $Date: 2002/06/06 09:37:26 $
- *
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
 /** 
@@ -66,17 +21,19 @@ package org.apache.commons.cli;
  * option was seen.<p>
  *
  * @author bob mcwhiter (bob @ werken.com)
- * @version $Revision: 1.2 $
+ * @version $Revision: 542144 $
  */
-public class UnrecognizedOptionException extends ParseException {
-    
+public class UnrecognizedOptionException
+    extends ParseException {
+
     /** 
      * <p>Construct a new <code>UnrecognizedArgumentException</code> 
      * with the specified detail message.</p>
      *
      * @param message the detail message
      */
-    public UnrecognizedOptionException( String message ) {
-        super( message );
+    public UnrecognizedOptionException(String message)
+    {
+        super(message);
     }
-}
+}
\ No newline at end of file
diff --git a/src/java/org/apache/commons/cli/Util.java b/src/java/org/apache/commons/cli/Util.java
new file mode 100644
index 0000000..94e97e3
--- /dev/null
+++ b/src/java/org/apache/commons/cli/Util.java
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.cli;
+
+/**
+ * Contains useful helper methods for classes within this package.
+ *
+ * @author John Keyes (john at integralsource.com)
+ */
+class Util {
+
+    /**
+     * <p>Remove the hyphens from the begining of <code>str</code> and
+     * return the new String.</p>
+     *
+     * @param str The string from which the hyphens should be removed.
+     *
+     * @return the new String.
+     */
+    static String stripLeadingHyphens(String str)
+    {
+        if (str == null) {
+            return null;
+        }
+        if (str.startsWith("--"))
+        {
+            return str.substring(2, str.length());
+        }
+        else if (str.startsWith("-"))
+        {
+            return str.substring(1, str.length());
+        }
+
+        return str;
+    }
+
+    /**
+     * Remove the leading and trailing quotes from <code>str</code>.
+     * E.g. if str is '"one two"', then 'one two' is returned.
+     *
+     * @param str The string from which the leading and trailing quotes
+     * should be removed.
+     *
+     * @return The string without the leading and trailing quotes.
+     */
+    static String stripLeadingAndTrailingQuotes(String str)
+    {
+        if (str.startsWith("\"")) {
+            str = str.substring(1, str.length());
+        }
+        if (str.endsWith("\"")) {
+            str = str.substring(0, str.length()-1);
+        }
+        return str;
+    }
+}
\ No newline at end of file
diff --git a/src/java/org/apache/commons/cli/package.html b/src/java/org/apache/commons/cli/package.html
index 5dcaef1..5bf2066 100644
--- a/src/java/org/apache/commons/cli/package.html
+++ b/src/java/org/apache/commons/cli/package.html
@@ -1,6 +1,6 @@
 
 <body>
 
-    <p>Commons CLI 1.0</p>
+    Commons CLI 1.0
 
 </body>
diff --git a/src/media/logo.xcf b/src/media/logo.xcf
new file mode 100644
index 0000000..fb1cd2b
Binary files /dev/null and b/src/media/logo.xcf differ
diff --git a/src/test/data/.hidden.txt b/src/test/data/.hidden.txt
new file mode 100644
index 0000000..d18fa71
--- /dev/null
+++ b/src/test/data/.hidden.txt
@@ -0,0 +1 @@
+Hidden text file.
diff --git a/src/test/data/readable.txt b/src/test/data/readable.txt
new file mode 100644
index 0000000..cada839
--- /dev/null
+++ b/src/test/data/readable.txt
@@ -0,0 +1 @@
+Readable text file.
diff --git a/src/test/data/writable.txt b/src/test/data/writable.txt
new file mode 100644
index 0000000..53f7f5d
--- /dev/null
+++ b/src/test/data/writable.txt
@@ -0,0 +1 @@
+Writable text file.
diff --git a/src/test/org/apache/commons/cli/ApplicationTest.java b/src/test/org/apache/commons/cli/ApplicationTest.java
index 87a43f3..169433a 100644
--- a/src/test/org/apache/commons/cli/ApplicationTest.java
+++ b/src/test/org/apache/commons/cli/ApplicationTest.java
@@ -1,3 +1,19 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.apache.commons.cli;
 
 import junit.framework.Test;
diff --git a/src/test/org/apache/commons/cli/ArgumentIsOptionTest.java b/src/test/org/apache/commons/cli/ArgumentIsOptionTest.java
new file mode 100644
index 0000000..61ca1b9
--- /dev/null
+++ b/src/test/org/apache/commons/cli/ArgumentIsOptionTest.java
@@ -0,0 +1,100 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.cli;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+public class ArgumentIsOptionTest extends TestCase {
+    private Options options = null;
+    private CommandLineParser parser = null;
+
+    public ArgumentIsOptionTest(String name) {
+        super(name);
+    }
+
+    public static Test suite() {
+        return new TestSuite(ArgumentIsOptionTest.class);
+    }
+
+    public void setUp() {
+        options = new Options().addOption("p", false, "Option p").addOption("attr",
+                true, "Option accepts argument");
+
+        parser = new PosixParser();
+    }
+
+    public void tearDown() {
+    }
+
+    public void testOptionAndOptionWithArgument() {
+        String[] args = new String[] {
+                "-p",
+                "-attr",
+                "p"
+            };
+
+        try {
+            CommandLine cl = parser.parse(options, args);
+            assertTrue("Confirm -p is set", cl.hasOption("p"));
+            assertTrue("Confirm -attr is set", cl.hasOption("attr"));
+            assertTrue("Confirm arg of -attr",
+                cl.getOptionValue("attr").equals("p"));
+            assertTrue("Confirm all arguments recognized", cl.getArgs().length == 0);
+        }
+        catch (ParseException e) {
+            fail(e.toString());
+        }
+    }
+
+    public void testOptionWithArgument() {
+        String[] args = new String[] {
+                "-attr",
+                "p"
+            };
+
+        try {
+            CommandLine cl = parser.parse(options, args);
+            assertFalse("Confirm -p is set", cl.hasOption("p"));
+            assertTrue("Confirm -attr is set", cl.hasOption("attr"));
+            assertTrue("Confirm arg of -attr",
+                cl.getOptionValue("attr").equals("p"));
+            assertTrue("Confirm all arguments recognized", cl.getArgs().length == 0);
+        }
+        catch (ParseException e) {
+            fail(e.toString());
+        }
+    }
+
+    public void testOption() {
+        String[] args = new String[] {
+                "-p"
+            };
+
+        try {
+            CommandLine cl = parser.parse(options, args);
+            assertTrue("Confirm -p is set", cl.hasOption("p"));
+            assertFalse("Confirm -attr is not set", cl.hasOption("attr"));
+            assertTrue("Confirm all arguments recognized", cl.getArgs().length == 0);
+        }
+        catch (ParseException e) {
+            fail(e.toString());
+        }
+    }
+}
diff --git a/src/test/org/apache/commons/cli/BugsTest.java b/src/test/org/apache/commons/cli/BugsTest.java
index 147c5ce..0f8494b 100644
--- a/src/test/org/apache/commons/cli/BugsTest.java
+++ b/src/test/org/apache/commons/cli/BugsTest.java
@@ -1,15 +1,27 @@
-/*
- * Copyright (C) The Apache Software Foundation. All rights reserved.
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * This software is published under the terms of the Apache Software License
- * version 1.1, a copy of which has been included with this distribution in
- * the LICENSE file.
- * 
- * $Id: BugsTest.java,v 1.10 2002/10/24 23:17:49 jkeyes Exp $
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Properties;
+
 import junit.framework.Test;
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
@@ -269,12 +281,30 @@ public class BugsTest extends TestCase
                                        .hasArg()
                                        .create( 'd' );
         options.addOption( dir );
-        try {
-            HelpFormatter formatter = new HelpFormatter();
-            formatter.printHelp( "dir", options );
+        
+        
+        final PrintStream oldSystemOut = System.out;
+        try{
+            final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+            final PrintStream print = new PrintStream(bytes);
+            
+            // capture this platform's eol symbol
+            print.println();
+            final String eol = bytes.toString();
+            bytes.reset();
+            
+            System.setOut(new PrintStream(bytes));
+            try {
+                HelpFormatter formatter = new HelpFormatter();
+                formatter.printHelp( "dir", options );
+            }
+            catch( Exception exp ) {
+                fail( "Unexpected Exception: " + exp.getMessage() );
+            }
+            assertEquals("usage: dir"+eol+" -d <arg>   dir"+eol,bytes.toString());
         }
-        catch( Exception exp ) {
-            fail( "Unexpected Exception: " + exp.getMessage() );
+        finally {
+            System.setOut(oldSystemOut);
         }
     }
 
@@ -331,7 +361,7 @@ public class BugsTest extends TestCase
             CommandLine line = parser.parse( opts, args );
         }
         catch( ParseException exp ) {
-            fail( "Unexpected exception: " + exp.getMessage() );
+            fail( "Unexpected exception: " + exp.getClass().getName() + ":" + exp.getMessage() );
         }
 
         opts.addOption( forward );
@@ -340,7 +370,168 @@ public class BugsTest extends TestCase
             CommandLine line = parser.parse( opts, args );
         }
         catch( ParseException exp ) {
-            fail( "Unexpected exception: " + exp.getMessage() );
+            fail( "Unexpected exception: " + exp.getClass().getName() + ":" + exp.getMessage() );
         }
     }
+
+    public void test14786() throws Exception {
+        Option o = OptionBuilder.isRequired().withDescription("test").create("test");
+        Options opts = new Options();
+        opts.addOption(o);
+        opts.addOption(o);
+
+        CommandLineParser parser = new GnuParser();
+
+        String[] args = new String[] { "-test" };
+
+        CommandLine line = parser.parse( opts, args );
+        assertTrue( line.hasOption( "test" ) );
+    }
+
+    public void test15046() throws Exception {
+        CommandLineParser parser = new PosixParser();
+        final String[] CLI_ARGS = new String[] {"-z", "c"};
+        Option option = new Option("z", "timezone", true, 
+                                   "affected option");
+        Options cliOptions = new Options();
+        cliOptions.addOption(option);
+        parser.parse(cliOptions, CLI_ARGS);
+		
+        //now add conflicting option
+        cliOptions.addOption("c", "conflict", true, "conflict option");
+        CommandLine line = parser.parse(cliOptions, CLI_ARGS);
+        assertEquals( option.getValue(), "c" );
+        assertTrue( !line.hasOption("c") );
+    }
+
+    public void test15648() throws Exception {
+        CommandLineParser parser = new PosixParser();
+        final String[] args = new String[] { "-m", "\"Two Words\"" };
+        Option m = OptionBuilder.hasArgs().create("m");
+        Options options = new Options();
+        options.addOption( m );
+        CommandLine line = parser.parse( options, args );
+        assertEquals( "Two Words", line.getOptionValue( "m" ) );
+    }
+
+    public void test27635() {
+        Option help = new Option("h", "help", false, "print this message");
+        Option version = new Option("v", "version", false, "print version information");
+        Option newRun = new Option("n", "new", false, "Create NLT cache entries only for new items");
+        Option trackerRun = new Option("t", "tracker", false, "Create NLT cache entries only for tracker items");
+        
+        Option timeLimit = OptionBuilder.withLongOpt("limit")
+                                        .hasArg()
+                                        .withValueSeparator()
+                                        .withDescription("Set time limit for execution, in mintues")
+                                        .create("l");
+        
+        Option age = OptionBuilder.withLongOpt("age")
+                                        .hasArg()
+                                        .withValueSeparator()
+                                        .withDescription("Age (in days) of cache item before being recomputed")
+                                        .create("a");
+        
+        Option server = OptionBuilder.withLongOpt("server")
+                                        .hasArg()
+                                        .withValueSeparator()
+                                        .withDescription("The NLT server address")
+                                        .create("s");
+        
+        Option numResults = OptionBuilder.withLongOpt("results")
+                                        .hasArg()
+                                        .withValueSeparator()
+                                        .withDescription("Number of results per item")
+                                        .create("r");
+        
+        Option configFile = OptionBuilder.withLongOpt("config")
+                                        .hasArg()
+                                        .withValueSeparator()
+                                        .withDescription("Use the specified configuration file")
+                                        .create();
+        
+        Options mOptions = new Options();
+        mOptions.addOption(help);
+        mOptions.addOption(version);
+        mOptions.addOption(newRun);
+        mOptions.addOption(trackerRun);
+        mOptions.addOption(timeLimit);
+        mOptions.addOption(age);
+        mOptions.addOption(server);
+        mOptions.addOption(numResults);
+        mOptions.addOption(configFile);
+        
+        HelpFormatter formatter = new HelpFormatter();
+        final String EOL = System.getProperty("line.separator");
+        StringWriter out = new StringWriter();
+        formatter.printHelp(new PrintWriter(out),80,"commandline","header",mOptions,2,2,"footer",true);
+        assertEquals(
+                "usage: commandline [-a <arg>] [--config <arg>] [-h] [-l <arg>] [-n] [-r <arg>]" + EOL +
+                "       [-s <arg>] [-t] [-v]" + EOL +
+                "header"+EOL+
+                "  -a,--age <arg>      Age (in days) of cache item before being recomputed"+EOL+
+                "     --config <arg>   Use the specified configuration file"+EOL+
+                "  -h,--help           print this message"+EOL+
+                "  -l,--limit <arg>    Set time limit for execution, in mintues"+EOL+
+                "  -n,--new            Create NLT cache entries only for new items"+EOL+
+                "  -r,--results <arg>  Number of results per item"+EOL+
+                "  -s,--server <arg>   The NLT server address"+EOL+
+                "  -t,--tracker        Create NLT cache entries only for tracker items"+EOL+
+                "  -v,--version        print version information"+EOL+
+                "footer"+EOL
+                ,out.toString());
+    }
+    
+    public void test31148() throws ParseException {
+        Option multiArgOption = new Option("o","option with multiple args");
+        multiArgOption.setArgs(1);
+        
+        Options options = new Options();
+        options.addOption(multiArgOption);
+        
+        Parser parser = new PosixParser();
+        String[] args = new String[]{};
+        Properties props = new Properties();
+        props.setProperty("o","ovalue");
+        CommandLine cl = parser.parse(options,args,props);
+        
+        assertTrue(cl.hasOption('o'));
+        assertEquals("ovalue",cl.getOptionValue('o'));
+    }
+    
+    public void test21215() {
+        Options options = new Options();
+        HelpFormatter formatter = new HelpFormatter();
+        String SEP = System.getProperty("line.separator");
+        String header = SEP+"Header";
+        String footer = "Footer";
+        StringWriter out = new StringWriter();
+        formatter.printHelp(new PrintWriter(out),80, "foobar", header, options, 2, 2, footer, true);
+        assertEquals(
+                "usage: foobar"+SEP+
+                ""+SEP+
+                "Header"+SEP+
+                ""+SEP+
+                "Footer"+SEP
+                ,out.toString());
+    }
+    
+    public void test19383() {
+        Options options = new Options();
+        options.addOption(new Option("a","aaa",false,"aaaaaaa"));
+        options.addOption(new Option(null,"bbb",false,"bbbbbbb"));
+        options.addOption(new Option("c",null,false,"ccccccc"));
+        
+        HelpFormatter formatter = new HelpFormatter();
+        String SEP = System.getProperty("line.separator");
+        StringWriter out = new StringWriter();
+        formatter.printHelp(new PrintWriter(out),80, "foobar", "", options, 2, 2, "", true);
+        assertEquals(
+                "usage: foobar [-a] [--bbb] [-c]"+SEP+
+                "  -a,--aaa  aaaaaaa"+SEP+
+                "     --bbb  bbbbbbb"+SEP+
+                "  -c        ccccccc"+SEP
+                ,out.toString());
+    }
+
 }
diff --git a/src/test/org/apache/commons/cli/BuildTest.java b/src/test/org/apache/commons/cli/BuildTest.java
index 88035d7..7a3abb9 100644
--- a/src/test/org/apache/commons/cli/BuildTest.java
+++ b/src/test/org/apache/commons/cli/BuildTest.java
@@ -1,13 +1,19 @@
-/*
- * Copyright (C) The Apache Software Foundation. All rights reserved.
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * This software is published under the terms of the Apache Software License
- * version 1.1, a copy of which has been included with this distribution in
- * the LICENSE file.
- * 
- * $Id: BuildTest.java,v 1.1 2001/12/19 18:16:25 jstrachan Exp $
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
 import junit.framework.Test;
diff --git a/src/test/org/apache/commons/cli/GnuParseTest.java b/src/test/org/apache/commons/cli/GnuParseTest.java
index c300bd6..504b59c 100644
--- a/src/test/org/apache/commons/cli/GnuParseTest.java
+++ b/src/test/org/apache/commons/cli/GnuParseTest.java
@@ -1,13 +1,19 @@
-/*
- * Copyright (C) The Apache Software Foundation. All rights reserved.
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * This software is published under the terms of the Apache Software License
- * version 1.1, a copy of which has been included with this distribution in
- * the LICENSE file.
- * 
- * $Id: GnuParseTest.java,v 1.3 2002/09/19 22:59:44 jkeyes Exp $
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
 import junit.framework.Test;
@@ -17,7 +23,7 @@ import junit.framework.TestSuite;
 public class GnuParseTest extends TestCase
 {
     private Options _options = null;
-    private CommandLineParser _parser = null;
+    private Parser _parser = null;
 
     public static Test suite() { 
         return new TestSuite( GnuParseTest.class ); 
diff --git a/src/test/org/apache/commons/cli/HelpFormatterExamples.java b/src/test/org/apache/commons/cli/HelpFormatterExamples.java
index 5cb802b..071c00b 100644
--- a/src/test/org/apache/commons/cli/HelpFormatterExamples.java
+++ b/src/test/org/apache/commons/cli/HelpFormatterExamples.java
@@ -1,11 +1,18 @@
-/*
- * Copyright (C) The Apache Software Foundation. All rights reserved.
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * This software is published under the terms of the Apache Software License
- * version 1.1, a copy of which has been included with this distribution in
- * the LICENSE file.
- * 
- * $Id: HelpFormatterExamples.java,v 1.2 2002/05/17 11:44:32 jstrachan Exp $
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 package org.apache.commons.cli;
 
diff --git a/src/test/org/apache/commons/cli/TestHelpFormatter.java b/src/test/org/apache/commons/cli/HelpFormatterTest.java
similarity index 65%
rename from src/test/org/apache/commons/cli/TestHelpFormatter.java
rename to src/test/org/apache/commons/cli/HelpFormatterTest.java
index 8142dc8..5b8fbf3 100644
--- a/src/test/org/apache/commons/cli/TestHelpFormatter.java
+++ b/src/test/org/apache/commons/cli/HelpFormatterTest.java
@@ -1,41 +1,51 @@
-/*
- * Copyright (C) The Apache Software Foundation. All rights reserved.
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * This software is published under the terms of the Apache Software License
- * version 1.1, a copy of which has been included with this distribution in
- * the LICENSE file.
- * 
- * $Id: TestHelpFormatter.java,v 1.2 2002/05/17 11:44:32 jstrachan Exp $
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 package org.apache.commons.cli;
 
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
 import java.io.ByteArrayOutputStream;
 import java.io.PrintWriter;
-import java.io.StringWriter;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
 
 /** 
  * Test case for the HelpFormatter class 
  *
  * @author Slawek Zachcial
  * @author John Keyes ( john at integralsource.com )
+ * @author brianegge
  **/
-public class TestHelpFormatter extends TestCase
+public class HelpFormatterTest extends TestCase
 {
+
+   private static final String EOL = System.getProperty("line.separator");
+
    public static void main( String[] args )
    {
-      String[] testName = { TestHelpFormatter.class.getName() };
+      String[] testName = { HelpFormatterTest.class.getName() };
       junit.textui.TestRunner.main(testName);
    }
 
    public static TestSuite suite()
    {
-      return new TestSuite(TestHelpFormatter.class);
+      return new TestSuite(HelpFormatterTest.class);
    }
 
-   public TestHelpFormatter( String s )
+   public HelpFormatterTest( String s )
    {
       super( s );
    }
@@ -64,18 +74,18 @@ public class TestHelpFormatter extends TestCase
       String text = "This is a test.";
       String expected;
 
-      expected = "This is a" + hf.defaultNewLine + "test.";
+      expected = "This is a" + hf.getNewLine() + "test.";
       hf.renderWrappedText(sb, 12, 0, text);
       assertEquals("single line text", expected, sb.toString());
 
       sb.setLength(0);
-      expected = "This is a" + hf.defaultNewLine + "    test.";
+      expected = "This is a" + hf.getNewLine() + "    test.";
       hf.renderWrappedText(sb, 12, 4, text);
       assertEquals("single line padded text", expected, sb.toString());
 
       text =
-         "aaaa aaaa aaaa" + hf.defaultNewLine +
-         "aaaaaa" + hf.defaultNewLine +
+         "aaaa aaaa aaaa" + hf.getNewLine() +
+         "aaaaaa" + hf.getNewLine() +
          "aaaaa";
 
       expected = text;
@@ -84,8 +94,8 @@ public class TestHelpFormatter extends TestCase
       assertEquals("multi line text", expected, sb.toString());
 
       expected =
-         "aaaa aaaa aaaa" + hf.defaultNewLine +
-         "    aaaaaa" + hf.defaultNewLine +
+         "aaaa aaaa aaaa" + hf.getNewLine() +
+         "    aaaaaa" + hf.getNewLine() +
          "    aaaaa";
       sb.setLength(0);
       hf.renderWrappedText(sb, 16, 4, text);
@@ -111,7 +121,7 @@ public class TestHelpFormatter extends TestCase
 
        int nextLineTabStop = leftPad+descPad+"-a".length();
        expected =
-           lpad + "-a" + dpad + "aaaa aaaa aaaa" + hf.defaultNewLine +
+           lpad + "-a" + dpad + "aaaa aaaa aaaa" + hf.getNewLine() +
            hf.createPadding(nextLineTabStop) + "aaaa aaaa";
        sb.setLength(0);
        hf.renderOptions(sb, nextLineTabStop+17, options, leftPad, descPad);
@@ -126,7 +136,7 @@ public class TestHelpFormatter extends TestCase
 
        nextLineTabStop = leftPad+descPad+"-a,--aaa".length();
        expected =
-           lpad + "-a,--aaa" + dpad + "dddd dddd" + hf.defaultNewLine +
+           lpad + "-a,--aaa" + dpad + "dddd dddd" + hf.getNewLine() +
            hf.createPadding(nextLineTabStop) + "dddd dddd";
        sb.setLength(0);
        hf.renderOptions(sb, 25, options, leftPad, descPad);
@@ -136,9 +146,9 @@ public class TestHelpFormatter extends TestCase
            addOption("a", "aaa", false, "dddd dddd dddd dddd").
            addOption("b", false, "feeee eeee eeee eeee");
        expected =
-           lpad + "-a,--aaa" + dpad + "dddd dddd" + hf.defaultNewLine +
-           hf.createPadding(nextLineTabStop) + "dddd dddd" + hf.defaultNewLine +
-           lpad + "-b      " + dpad + "feeee eeee" + hf.defaultNewLine +
+           lpad + "-a,--aaa" + dpad + "dddd dddd" + hf.getNewLine() +
+           hf.createPadding(nextLineTabStop) + "dddd dddd" + hf.getNewLine() +
+           lpad + "-b      " + dpad + "feeee eeee" + hf.getNewLine() +
            hf.createPadding(nextLineTabStop) + "eeee eeee";
        sb.setLength(0);
        hf.renderOptions(sb, 25, options, leftPad, descPad);
@@ -160,7 +170,7 @@ public class TestHelpFormatter extends TestCase
        assertEquals("simple auto usage", expected, out.toString().trim());
        out.reset();
 
-       expected = "usage: app [-b] [-a]";
+       expected = "usage: app [-a] [-b]";
        options = new Options().addOption("a", false, "aaaa aaaa aaaa aaaa aaaa")
        .addOption("b", false, "bbb" );
        hf.printUsage( pw, 60, "app", options );
@@ -168,4 +178,23 @@ public class TestHelpFormatter extends TestCase
        assertEquals("simple auto usage", expected, out.toString().trim());
        out.reset();
    }
+
+    // This test ensures the options are properly sorted
+    // See https://issues.apache.org/jira/browse/CLI-131
+    public void testPrintUsage() {
+        Option optionA = new Option("a", "first");
+        Option optionB = new Option("b", "second");
+        Option optionC = new Option("c", "third");
+        Options opts = new Options();
+        opts.addOption(optionA);
+        opts.addOption(optionB);
+        opts.addOption(optionC);
+        HelpFormatter helpFormatter = new HelpFormatter();
+        ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
+        PrintWriter printWriter = new PrintWriter(bytesOut);
+        helpFormatter.printUsage(printWriter, 80, "app", opts);
+        printWriter.close();
+        assertEquals("usage: app [-a] [-b] [-c]" + EOL, bytesOut.toString());
+    }
+
 }
diff --git a/src/test/org/apache/commons/cli/LongOptionWithShort.java b/src/test/org/apache/commons/cli/LongOptionWithShort.java
new file mode 100644
index 0000000..0fb46e3
--- /dev/null
+++ b/src/test/org/apache/commons/cli/LongOptionWithShort.java
@@ -0,0 +1,114 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.cli;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * <p>
+ * This is a collection of tests that test real world
+ * applications command lines focusing on options with
+ * long and short names.
+ * </p>
+ */
+public class LongOptionWithShort extends TestCase {
+    public LongOptionWithShort(String name) {
+        super(name);
+    }
+
+    public static Test suite() {
+        return new TestSuite(LongOptionWithShort.class);
+    }
+
+    /**
+     *
+     */
+    public void testLongOptionWithShort() {
+        Option help = new Option("h", "help", false, "print this message");
+        Option version = new Option("v", "version", false,
+                "print version information");
+        Option newRun = new Option("n", "new", false,
+                "Create NLT cache entries only for new items");
+        Option trackerRun = new Option("t", "tracker", false,
+                "Create NLT cache entries only for tracker items");
+
+        Option timeLimit = OptionBuilder.withLongOpt("limit").hasArg()
+                                        .withValueSeparator()
+                                        .withDescription("Set time limit for execution, in mintues")
+                                        .create("l");
+
+        Option age = OptionBuilder.withLongOpt("age").hasArg()
+                                  .withValueSeparator()
+                                  .withDescription("Age (in days) of cache item before being recomputed")
+                                  .create("a");
+
+        Option server = OptionBuilder.withLongOpt("server").hasArg()
+                                     .withValueSeparator()
+                                     .withDescription("The NLT server address")
+                                     .create("s");
+
+        Option numResults = OptionBuilder.withLongOpt("results").hasArg()
+                                         .withValueSeparator()
+                                         .withDescription("Number of results per item")
+                                         .create("r");
+
+        Option configFile = OptionBuilder.withLongOpt("file").hasArg()
+                                         .withValueSeparator()
+                                         .withDescription("Use the specified configuration file")
+                                         .create();
+
+        Options options = new Options();
+        options.addOption(help);
+        options.addOption(version);
+        options.addOption(newRun);
+        options.addOption(trackerRun);
+        options.addOption(timeLimit);
+        options.addOption(age);
+        options.addOption(server);
+        options.addOption(numResults);
+        options.addOption(configFile);
+
+        // create the command line parser
+        CommandLineParser parser = new PosixParser();
+
+        String[] args = new String[] {
+                "-v",
+                "-l",
+                "10",
+                "-age",
+                "5",
+                "-file",
+                "filename"
+            };
+
+        try {
+            CommandLine line = parser.parse(options, args);
+            assertTrue(line.hasOption("v"));
+            assertEquals(line.getOptionValue("l"), "10");
+            assertEquals(line.getOptionValue("limit"), "10");
+            assertEquals(line.getOptionValue("a"), "5");
+            assertEquals(line.getOptionValue("age"), "5");
+            assertEquals(line.getOptionValue("file"), "filename");
+        }
+        catch (ParseException exp) {
+            fail("Unexpected exception:" + exp.getMessage());
+        }
+    }
+}
diff --git a/src/test/org/apache/commons/cli/OptionBuilderTest.java b/src/test/org/apache/commons/cli/OptionBuilderTest.java
index 35ffce8..ff460f4 100644
--- a/src/test/org/apache/commons/cli/OptionBuilderTest.java
+++ b/src/test/org/apache/commons/cli/OptionBuilderTest.java
@@ -1,3 +1,19 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.apache.commons.cli;
 
 import junit.framework.Test;
@@ -137,15 +153,6 @@ public class OptionBuilderTest extends TestCase {
             // success
         }
 
-        // null option
-        try {
-            Option opt = OptionBuilder.create( null );
-            fail( "IllegalArgumentException not caught" );
-        }
-        catch( IllegalArgumentException exp ) {
-            // success
-        }
-
         // valid option 
         try {
             Option opt = OptionBuilder.create( "opt" );
diff --git a/src/test/org/apache/commons/cli/OptionGroupTest.java b/src/test/org/apache/commons/cli/OptionGroupTest.java
index e9109c3..6f6a6a6 100644
--- a/src/test/org/apache/commons/cli/OptionGroupTest.java
+++ b/src/test/org/apache/commons/cli/OptionGroupTest.java
@@ -1,13 +1,19 @@
-/*
- * Copyright (C) The Apache Software Foundation. All rights reserved.
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * This software is published under the terms of the Apache Software License
- * version 1.1, a copy of which has been included with this distribution in
- * the LICENSE file.
- * 
- * $Id: OptionGroupTest.java,v 1.1 2002/04/23 16:08:02 jstrachan Exp $
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
 import junit.framework.Test;
@@ -16,7 +22,7 @@ import junit.framework.TestSuite;
 
 /**
  * @author John Keyes (john at integralsource.com)
- * @version $Revision: 1.1 $
+ * @version $Revision: 542144 $
  */
 public class OptionGroupTest extends TestCase
 {
@@ -51,6 +57,14 @@ public class OptionGroupTest extends TestCase
         group2.addOption( chapter );
 
         _options.addOptionGroup( group2 );
+
+        Option importOpt = new Option( null, "import", false, "section to process" );
+        Option exportOpt = new Option( null, "export", false, "chapter to process" );
+        OptionGroup group3 = new OptionGroup();
+        group3.addOption( importOpt );
+        group3.addOption( exportOpt );
+        _options.addOptionGroup( group3 );
+
         _options.addOption( "r", "revision", false, "revision number" );
     }
 
@@ -240,5 +254,28 @@ public class OptionGroupTest extends TestCase
         }
     }
 
+    public void testValidLongOnlyOptions()
+    {
+        try
+        {
+            CommandLine cl = parser.parse( _options, new String[]{"--export"});
+            assertTrue( "Confirm --export is set", cl.hasOption("export") );
+        }
+        catch (ParseException e)
+        {
+            fail( e.toString() );
+        }
+                            
+        try
+        {
+            CommandLine cl = parser.parse( _options, new String[]{"--import"});
+            assertTrue( "Confirm --import is set", cl.hasOption("import") );
+        }
+        catch (ParseException e)
+        {
+            fail( e.toString() );
+        }
+    }
+
 
 }
diff --git a/src/test/org/apache/commons/cli/OptionTest.java b/src/test/org/apache/commons/cli/OptionTest.java
new file mode 100644
index 0000000..10af03f
--- /dev/null
+++ b/src/test/org/apache/commons/cli/OptionTest.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.cli;
+
+import junit.framework.TestCase;
+
+/**
+ * @author brianegge
+ */
+public class OptionTest extends TestCase {
+
+   private static class TestOption extends Option {
+        public TestOption(String opt, boolean hasArg, String description) throws IllegalArgumentException {
+            super(opt, hasArg, description);
+        }
+        public boolean addValue(String value) {
+            addValueForProcessing(value);
+            return true;
+        }
+   }
+
+   public void testClear() {
+       TestOption option = new TestOption("x", true, "");
+       assertEquals(0, option.getValuesList().size());
+       option.addValue("a");
+       assertEquals(1, option.getValuesList().size());
+       option.clearValues();
+       assertEquals(0, option.getValuesList().size());
+   }
+
+    // See http://issues.apache.org/jira/browse/CLI-21
+    public void testClone() throws CloneNotSupportedException {
+        TestOption a = new TestOption("a", true, "");
+        TestOption b = (TestOption) a.clone();
+        assertEquals(a, b);
+        assertNotSame(a, b);
+        a.setDescription("a");
+        assertEquals("", b.getDescription());
+        b.setArgs(2);
+        b.addValue("b1");
+        b.addValue("b2");
+        assertEquals(1, a.getArgs());
+        assertEquals(0, a.getValuesList().size());
+        assertEquals(2, b.getValues().length);
+    }
+
+    private static class DefaultOption extends Option {
+
+        private final String defaultValue;
+
+        public DefaultOption(String opt, String description, String defaultValue) throws IllegalArgumentException {
+            super(opt, true, description);
+            this.defaultValue = defaultValue;
+        }
+
+        public String getValue() {
+            return super.getValue() != null ? super.getValue() : defaultValue;
+        }
+    }
+
+    public void testSubclass() throws CloneNotSupportedException {
+        Option option = new DefaultOption("f", "file", "myfile.txt");
+        Option clone = (Option) option.clone();
+        assertEquals("myfile.txt", clone.getValue());
+        assertEquals(DefaultOption.class, clone.getClass());
+    }
+
+}
diff --git a/src/test/org/apache/commons/cli/OptionsTest.java b/src/test/org/apache/commons/cli/OptionsTest.java
new file mode 100644
index 0000000..af7fac8
--- /dev/null
+++ b/src/test/org/apache/commons/cli/OptionsTest.java
@@ -0,0 +1,121 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.cli;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * @author Rob Oxspring roxspring at apache.org
+ * @version $Revision: 544360 $
+ */
+public class OptionsTest extends TestCase
+{
+
+    public static Test suite() 
+    { 
+        return new TestSuite ( OptionsTest.class ); 
+    }
+
+    public OptionsTest( String name )
+    {
+        super( name );
+    }
+
+    public void setUp()
+    {
+    }
+
+    public void tearDown()
+    {
+    }
+    
+    public void testHelpOptions(){
+        
+        Option longOnly1 = OptionBuilder
+            .withLongOpt("long-only1")
+            .create();
+        
+        Option longOnly2 = OptionBuilder
+            .withLongOpt("long-only2")
+            .create();
+                
+        Option shortOnly1 = OptionBuilder
+            .create("1");
+                
+        Option shortOnly2 = OptionBuilder
+            .create("2");
+                
+        Option bothA = OptionBuilder
+            .withLongOpt("bothA")
+            .create("a");
+                
+        Option bothB = OptionBuilder
+            .withLongOpt("bothB")
+            .create("b");
+        
+        Options options = new Options();
+        options.addOption(longOnly1);
+        options.addOption(longOnly2);
+        options.addOption(shortOnly1);
+        options.addOption(shortOnly2);
+        options.addOption(bothA);
+        options.addOption(bothB);
+        
+        Collection allOptions = new ArrayList();
+        allOptions.add(longOnly1);
+        allOptions.add(longOnly2);
+        allOptions.add(shortOnly1);
+        allOptions.add(shortOnly2);
+        allOptions.add(bothA);
+        allOptions.add(bothB);
+        
+        Collection helpOptions = options.helpOptions();
+        
+        assertTrue("Everything in all should be in help",helpOptions.containsAll(allOptions));
+        assertTrue("Everything in help should be in all",allOptions.containsAll(helpOptions));        
+    }
+
+    public void testMissingOptionException() throws ParseException {
+        Options options = new Options();
+        options.addOption(OptionBuilder.isRequired().create("f"));
+        try {
+            new PosixParser().parse(options, new String[0]);
+            fail("Expected MissingOptionException to be thrown");
+        } catch (MissingOptionException e) {
+            assertEquals("Missing required option: f", e.getMessage());
+        }
+    }
+
+    public void testMissingOptionsException() throws ParseException {
+        Options options = new Options();
+        options.addOption(OptionBuilder.isRequired().create("f"));
+        options.addOption(OptionBuilder.isRequired().create("x"));
+        try {
+            new PosixParser().parse(options, new String[0]);
+            fail("Expected MissingOptionException to be thrown");
+        } catch (MissingOptionException e) {
+            assertEquals("Missing required options: fx", e.getMessage());
+        }
+    }
+
+}
+
diff --git a/src/test/org/apache/commons/cli/ParseRequiredTest.java b/src/test/org/apache/commons/cli/ParseRequiredTest.java
index a2b23ab..f457b8f 100644
--- a/src/test/org/apache/commons/cli/ParseRequiredTest.java
+++ b/src/test/org/apache/commons/cli/ParseRequiredTest.java
@@ -1,13 +1,19 @@
-/*
- * Copyright (C) The Apache Software Foundation. All rights reserved.
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * This software is published under the terms of the Apache Software License
- * version 1.1, a copy of which has been included with this distribution in
- * the LICENSE file.
- * 
- * $Id: ParseRequiredTest.java,v 1.1 2002/04/23 16:08:02 jstrachan Exp $
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
 import junit.framework.Test;
@@ -16,7 +22,7 @@ import junit.framework.TestSuite;
 
 /**
  * @author John Keyes (john at integralsource.com)
- * @version $Revision: 1.1 $
+ * @version $Revision: 542144 $
  */
 public class ParseRequiredTest extends TestCase
 {
diff --git a/src/test/org/apache/commons/cli/ParseTest.java b/src/test/org/apache/commons/cli/ParseTest.java
index f5990c2..b70bcd2 100644
--- a/src/test/org/apache/commons/cli/ParseTest.java
+++ b/src/test/org/apache/commons/cli/ParseTest.java
@@ -1,13 +1,19 @@
-/*
- * Copyright (C) The Apache Software Foundation. All rights reserved.
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * This software is published under the terms of the Apache Software License
- * version 1.1, a copy of which has been included with this distribution in
- * the LICENSE file.
- * 
- * $Id: ParseTest.java,v 1.1 2001/12/19 18:16:25 jstrachan Exp $
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
 import junit.framework.Test;
@@ -18,7 +24,7 @@ public class ParseTest extends TestCase
 {
 
     private Options _options = null;
-    private CommandLineParser _parser = null;
+    private Parser _parser = null;
 
     public static Test suite() { 
         return new TestSuite(ParseTest.class); 
@@ -87,6 +93,7 @@ public class ParseTest extends TestCase
             assertTrue( "Confirm -a is set", cl.hasOption("a") );
             assertTrue( "Confirm -b is set", cl.hasOption("b") );
             assertTrue( "Confirm arg of -b", cl.getOptionValue("b").equals("toast") );
+            assertTrue( "Confirm arg of --bfile", cl.getOptionValue( "bfile" ).equals( "toast" ) );
             assertTrue( "Confirm size of extra args", cl.getArgList().size() == 2);
         } 
         catch (ParseException e)
diff --git a/src/test/org/apache/commons/cli/PatternOptionBuilderTest.java b/src/test/org/apache/commons/cli/PatternOptionBuilderTest.java
index c0d66ff..9a8f3ab 100644
--- a/src/test/org/apache/commons/cli/PatternOptionBuilderTest.java
+++ b/src/test/org/apache/commons/cli/PatternOptionBuilderTest.java
@@ -1,20 +1,24 @@
-/*
- * Copyright (C) The Apache Software Foundation. All rights reserved.
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * This software is published under the terms of the Apache Software License
- * version 1.1, a copy of which has been included with this distribution in
- * the LICENSE file.
- * 
- * $Id: PatternOptionBuilderTest.java,v 1.1 2002/06/06 22:09:25 bayard Exp $
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 package org.apache.commons.cli;
 
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
 
-import java.io.StringWriter;
-import java.io.PrintWriter;
-
 /** 
  * Test case for the PatternOptionBuilder class 
  *
@@ -23,22 +27,12 @@ import java.io.PrintWriter;
 public class PatternOptionBuilderTest
 extends TestCase
 {
-    public static void main( String[] args )
-   {
-      String[] testName = { PatternOptionBuilderTest.class.getName() };
-      junit.textui.TestRunner.main(testName);
-   }
 
    public static TestSuite suite()
    {
       return new TestSuite(PatternOptionBuilderTest.class);
    }
 
-   public PatternOptionBuilderTest( String s )
-   {
-      super( s );
-   }
-
    public void testSimplePattern()
    {
        try {
@@ -48,26 +42,27 @@ extends TestCase
            CommandLineParser parser = new PosixParser();
            CommandLine line = parser.parse(options,args);
 
-           // tests the char methods of CommandLine that delegate to
-           // the String methods
            assertEquals("flag a", "foo", line.getOptionValue("a"));
-           assertEquals("flag a", "foo", line.getOptionValue('a'));
            assertEquals("string flag a", "foo", line.getOptionObject("a"));
-           assertEquals("string flag a", "foo", line.getOptionObject('a'));
            assertEquals("object flag b", new java.util.Vector(), line.getOptionObject("b"));
-           assertEquals("object flag b", new java.util.Vector(), line.getOptionObject('b'));
-           assertEquals("boolean true flag c", true, line.hasOption("c"));
-           assertEquals("boolean true flag c", true, line.hasOption('c'));
-           assertEquals("boolean false flag d", false, line.hasOption("d"));
-           assertEquals("boolean false flag d", false, line.hasOption('d'));
+           assertTrue("boolean true flag c", line.hasOption("c"));
+           assertFalse("boolean false flag d", line.hasOption("d"));
            assertEquals("file flag e", new java.io.File("build.xml"), line.getOptionObject("e"));
-           assertEquals("file flag e", new java.io.File("build.xml"), line.getOptionObject('e'));
            assertEquals("class flag f", java.util.Calendar.class, line.getOptionObject("f"));
-           assertEquals("class flag f", java.util.Calendar.class, line.getOptionObject('f'));
-           assertEquals("number flag n", new Float(4.5), line.getOptionObject("n"));
-           assertEquals("number flag n", new Float(4.5), line.getOptionObject('n'));
+           assertEquals("number flag n", new Double(4.5), line.getOptionObject("n"));
            assertEquals("url flag t", new java.net.URL("http://jakarta.apache.org/"), line.getOptionObject("t"));
+
+           // tests the char methods of CommandLine that delegate to the String methods
+           assertEquals("flag a", "foo", line.getOptionValue('a'));
+           assertEquals("string flag a", "foo", line.getOptionObject('a'));
+           assertEquals("object flag b", new java.util.Vector(), line.getOptionObject('b'));
+           assertTrue("boolean true flag c", line.hasOption('c'));
+           assertFalse("boolean false flag d", line.hasOption('d'));
+           assertEquals("file flag e", new java.io.File("build.xml"), line.getOptionObject('e'));
+           assertEquals("class flag f", java.util.Calendar.class, line.getOptionObject('f'));
+           assertEquals("number flag n", new Double(4.5), line.getOptionObject('n'));
            assertEquals("url flag t", new java.net.URL("http://jakarta.apache.org/"), line.getOptionObject('t'));
+
            /// DATES NOT SUPPORTED YET.
            //      assertEquals("number flag t", new java.util.Date(1023400137276L), line.getOptionObject('z'));
            //     input is:  "Thu Jun 06 17:48:57 EDT 2002"
diff --git a/src/test/org/apache/commons/cli/UtilTest.java b/src/test/org/apache/commons/cli/UtilTest.java
new file mode 100644
index 0000000..3aae1d1
--- /dev/null
+++ b/src/test/org/apache/commons/cli/UtilTest.java
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.cli;
+
+import junit.framework.TestCase;
+
+/**
+ * @author brianegge
+ */
+public class UtilTest extends TestCase {
+    public void testStripLeadingHyphens() {
+        assertEquals("f", Util.stripLeadingHyphens("-f"));
+        assertEquals("foo", Util.stripLeadingHyphens("--foo"));
+        assertNull(Util.stripLeadingHyphens(null));
+    }
+}
diff --git a/src/test/org/apache/commons/cli/ValueTest.java b/src/test/org/apache/commons/cli/ValueTest.java
index 21d6f92..1af91bf 100644
--- a/src/test/org/apache/commons/cli/ValueTest.java
+++ b/src/test/org/apache/commons/cli/ValueTest.java
@@ -1,19 +1,28 @@
-/*
- * Copyright (C) The Apache Software Foundation. All rights reserved.
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * This software is published under the terms of the Apache Software License
- * version 1.1, a copy of which has been included with this distribution in
- * the LICENSE file.
- * 
- * $Id: ValueTest.java,v 1.1 2001/12/19 18:16:25 jstrachan Exp $
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
 import junit.framework.Test;
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
 
+import java.util.Arrays;
+import java.util.Properties;
+
 public class ValueTest extends TestCase
 {
 
@@ -71,6 +80,9 @@ public class ValueTest extends TestCase
         opts.addOption( OptionBuilder.hasOptionalArgs( )
                         .create( 'j' ) );
 
+        opts.addOption( OptionBuilder.hasArgs( ).withValueSeparator( ',' )
+                        .create( 'k' ) );
+
         String[] args = new String[] { "-a",
             "-b", "foo",
             "--c",
@@ -79,7 +91,7 @@ public class ValueTest extends TestCase
 
         try
         {
-            CommandLineParser parser = new PosixParser();
+            Parser parser = new PosixParser();
             _cl = parser.parse(opts,args);
         }
         catch (ParseException e)
@@ -125,7 +137,7 @@ public class ValueTest extends TestCase
         };
         try
         {
-            CommandLineParser parser = new PosixParser();
+            Parser parser = new PosixParser();
             CommandLine cmd = parser.parse(opts,args);
             assertTrue( cmd.hasOption("e") );
             assertNull( cmd.getOptionValue("e") );
@@ -142,7 +154,7 @@ public class ValueTest extends TestCase
         };
         try
         {
-            CommandLineParser parser = new PosixParser();
+            Parser parser = new PosixParser();
             CommandLine cmd = parser.parse(opts,args);
             assertTrue( cmd.hasOption("e") );
             assertEquals( "everything", cmd.getOptionValue("e") );
@@ -159,7 +171,7 @@ public class ValueTest extends TestCase
         };
         try
         {
-            CommandLineParser parser = new PosixParser();
+            Parser parser = new PosixParser();
             CommandLine cmd = parser.parse(opts,args);
             assertTrue( cmd.hasOption("fish") );
             assertNull( cmd.getOptionValue("fish") );
@@ -176,7 +188,7 @@ public class ValueTest extends TestCase
         };
         try
         {
-            CommandLineParser parser = new PosixParser();
+            Parser parser = new PosixParser();
             CommandLine cmd = parser.parse(opts,args);
             assertTrue( cmd.hasOption("fish") );
             assertEquals( "face", cmd.getOptionValue("fish") );
@@ -193,7 +205,7 @@ public class ValueTest extends TestCase
         };
         try
         {
-            CommandLineParser parser = new PosixParser();
+            Parser parser = new PosixParser();
             CommandLine cmd = parser.parse(opts,args);
             assertTrue( cmd.hasOption("j") );
             assertEquals( "ink", cmd.getOptionValue("j") );
@@ -213,7 +225,7 @@ public class ValueTest extends TestCase
         };
         try
         {
-            CommandLineParser parser = new PosixParser();
+            Parser parser = new PosixParser();
             CommandLine cmd = parser.parse(opts,args);
             assertTrue( cmd.hasOption("gravy") );
             assertEquals( "gold", cmd.getOptionValue("gravy") );
@@ -233,7 +245,7 @@ public class ValueTest extends TestCase
         };
         try
         {
-            CommandLineParser parser = new PosixParser();
+            Parser parser = new PosixParser();
             CommandLine cmd = parser.parse(opts,args);
             assertTrue( cmd.hasOption("i") );
             assertEquals( "ink", cmd.getOptionValue("i") );
@@ -251,11 +263,14 @@ public class ValueTest extends TestCase
 
     public void testLongOptionalNArgValues()
     {
-        String[] args = new String[] { "--hide", "house", "hair", "head"
+        String[] args = new String[] { 
+            "--hide", "house", "hair", "head"
         };
+
+        Parser parser = new PosixParser();
+
         try
         {
-            CommandLineParser parser = new PosixParser();
             CommandLine cmd = parser.parse(opts,args);
             assertTrue( cmd.hasOption("hide") );
             assertEquals( "house", cmd.getOptionValue("hide") );
@@ -269,4 +284,144 @@ public class ValueTest extends TestCase
             fail("Cannot setUp() CommandLine: " + e.toString());
         }
     }
+
+    public void testPropertyOptionSingularValue()
+    {
+        Properties properties = new Properties();
+        properties.setProperty( "hide", "seek" );
+
+        Parser parser = new PosixParser();
+        
+        try
+        {
+            CommandLine cmd = parser.parse(opts, null, properties);
+            assertTrue( cmd.hasOption("hide") );
+            assertEquals( "seek", cmd.getOptionValue("hide") );
+            assertTrue( !cmd.hasOption("fake") );
+        }
+        catch (ParseException e)
+        {
+            fail("Cannot setUp() CommandLine: " + e.toString());
+        }
+    }
+
+    public void testPropertyOptionFlags()
+    {
+        Properties properties = new Properties();
+        properties.setProperty( "a", "true" );
+        properties.setProperty( "c", "yes" );
+        properties.setProperty( "e", "1" );
+
+        Parser parser = new PosixParser();
+        
+        try
+        {
+            CommandLine cmd = parser.parse(opts, null, properties);
+            assertTrue( cmd.hasOption("a") );
+            assertTrue( cmd.hasOption("c") );
+            assertTrue( cmd.hasOption("e") );
+        }
+        catch (ParseException e)
+        {
+            fail("Cannot setUp() CommandLine: " + e.toString());
+        }
+
+        properties = new Properties();
+        properties.setProperty( "a", "false" );
+        properties.setProperty( "c", "no" );
+        properties.setProperty( "e", "0" );
+        try
+        {
+            CommandLine cmd = parser.parse(opts, null, properties);
+            assertTrue( !cmd.hasOption("a") );
+            assertTrue( !cmd.hasOption("c") );
+            assertTrue( !cmd.hasOption("e") );
+        }
+        catch (ParseException e)
+        {
+            fail("Cannot setUp() CommandLine: " + e.toString());
+        }
+
+        properties = new Properties();
+        properties.setProperty( "a", "TRUE" );
+        properties.setProperty( "c", "nO" );
+        properties.setProperty( "e", "TrUe" );
+        try
+        {
+            CommandLine cmd = parser.parse(opts, null, properties);
+            assertTrue( cmd.hasOption("a") );
+            assertTrue( !cmd.hasOption("c") );
+            assertTrue( cmd.hasOption("e") );
+        }
+        catch (ParseException e)
+        {
+            fail("Cannot setUp() CommandLine: " + e.toString());
+        }
+
+        properties = new Properties();
+        properties.setProperty( "a", "just a string" );
+        properties.setProperty( "e", "" );
+        try
+        {
+            CommandLine cmd = parser.parse(opts, null, properties);
+            assertTrue( !cmd.hasOption("a") );
+            assertTrue( !cmd.hasOption("c") );
+            assertTrue( !cmd.hasOption("e") );
+        }
+        catch (ParseException e)
+        {
+            fail("Cannot setUp() CommandLine: " + e.toString());
+        }
+
+    } 
+
+    public void testPropertyOptionMultipleValues()
+    {
+        Properties properties = new Properties();
+        properties.setProperty( "k", "one,two" );
+
+        Parser parser = new PosixParser();
+        
+        String[] values = new String[] {
+            "one", "two"
+        };
+        try
+        {
+            CommandLine cmd = parser.parse(opts, null, properties);
+            assertTrue( cmd.hasOption("k") );
+            assertTrue( Arrays.equals( values, cmd.getOptionValues('k') ) );
+        }
+        catch (ParseException e)
+        {
+            fail("Cannot setUp() CommandLine: " + e.toString());
+        }
+    }
+
+    public void testPropertyOverrideValues()
+    {
+        String[] args = new String[] { 
+            "-j",
+            "found",
+            "-i",
+            "ink"
+        };
+
+        Properties properties = new Properties();
+        properties.setProperty( "j", "seek" );
+        try
+        {
+            Parser parser = new PosixParser();
+            CommandLine cmd = parser.parse(opts, args, properties);
+            assertTrue( cmd.hasOption("j") );
+            assertEquals( "found", cmd.getOptionValue("j") );
+            assertTrue( cmd.hasOption("i") );
+            assertEquals( "ink", cmd.getOptionValue("i") );
+            assertTrue( !cmd.hasOption("fake") );
+        }
+        catch (ParseException e)
+        {
+            fail("Cannot setUp() CommandLine: " + e.toString());
+        }
+    }
+
 }
diff --git a/src/test/org/apache/commons/cli/ValuesTest.java b/src/test/org/apache/commons/cli/ValuesTest.java
index c447219..2135f2d 100644
--- a/src/test/org/apache/commons/cli/ValuesTest.java
+++ b/src/test/org/apache/commons/cli/ValuesTest.java
@@ -1,13 +1,19 @@
-/*
- * Copyright (C) The Apache Software Foundation. All rights reserved.
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * This software is published under the terms of the Apache Software License
- * version 1.1, a copy of which has been included with this distribution in
- * the LICENSE file.
- * 
- * $Id: ValueTest.java,v 1.1 2001/12/19 18:16:25 jstrachan Exp $
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package org.apache.commons.cli;
 
 import java.util.Arrays;
@@ -192,8 +198,8 @@ public class ValuesTest extends TestCase
         String[] values = new String[] { "key", "value", "key", "value" };
         assertTrue( _cmdline.hasOption( "j" ) );
         assertTrue( _cmdline.hasOption( 'j' ) );
-        assertTrue( _cmdline.getOptionValues( "j" ).length == 4);
-        assertTrue( _cmdline.getOptionValues( 'j' ).length == 4);
+        assertEquals( 4, _cmdline.getOptionValues( "j" ).length );
+        assertEquals( 4, _cmdline.getOptionValues( 'j' ).length );
         assertTrue( Arrays.equals( values, _cmdline.getOptionValues( "j" ) ) );
         assertTrue( Arrays.equals( values, _cmdline.getOptionValues( 'j' ) ) );
 
diff --git a/src/test/org/apache/commons/cli/bug/BugCLI133Test.java b/src/test/org/apache/commons/cli/bug/BugCLI133Test.java
new file mode 100644
index 0000000..0ada0bc
--- /dev/null
+++ b/src/test/org/apache/commons/cli/bug/BugCLI133Test.java
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.cli.bug;
+
+import junit.framework.TestCase;
+import org.apache.commons.cli.*;
+
+/**
+ * @author brianegge
+ */
+public class BugCLI133Test extends TestCase {
+    public void testOrder() throws ParseException {
+        Option optionA = new Option("a", "first");
+        Options opts = new Options();
+        opts.addOption(optionA);
+        PosixParser posixParser = new PosixParser();
+        CommandLine line = posixParser.parse(opts, null);
+        assertFalse(line.hasOption(null));
+    }
+}
diff --git a/src/test/org/apache/commons/cli/bug/BugCLI13Test.java b/src/test/org/apache/commons/cli/bug/BugCLI13Test.java
new file mode 100644
index 0000000..7e63dfa
--- /dev/null
+++ b/src/test/org/apache/commons/cli/bug/BugCLI13Test.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.cli.bug;
+
+import junit.framework.TestCase;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.PosixParser;
+
+/**
+ * @author brianegge
+ */
+public class BugCLI13Test
+    extends TestCase
+{
+    public void testCLI13()
+        throws ParseException
+    {
+        final String debugOpt = "debug";
+        Option debug = OptionBuilder
+            .withArgName( debugOpt )
+            .withDescription( "turn on debugging" )
+            .withLongOpt( debugOpt )
+            .hasArg()
+            .create( 'd' );
+        Options options = new Options();
+        options.addOption( debug );
+        CommandLine commandLine = new PosixParser().parse( options, new String[]{"-d", "true"} );
+
+        assertEquals("true", commandLine.getOptionValue( debugOpt ));
+        assertEquals("true", commandLine.getOptionValue( 'd' ));
+        assertTrue(commandLine.hasOption( 'd'));
+        assertTrue(commandLine.hasOption( debugOpt));
+    }
+}
diff --git a/src/test/org/apache/commons/cli/bug/BugCLI18Test.java b/src/test/org/apache/commons/cli/bug/BugCLI18Test.java
new file mode 100644
index 0000000..9ba3ca3
--- /dev/null
+++ b/src/test/org/apache/commons/cli/bug/BugCLI18Test.java
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.cli.bug;
+
+import org.apache.commons.cli.*;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import junit.framework.TestCase;
+
+/**
+ * http://issues.apache.org/jira/browse/CLI-18
+ */
+public class BugCLI18Test extends TestCase {
+
+  public void testCLI18() {
+    Options options = new Options();
+    options.addOption(new Option("a","aaa",false,"aaaaaaa"));
+    options.addOption(new Option(null,"bbb",false,"bbbbbbb dksh fkshd fkhs dkfhsdk fhskd hksdks dhfowehfsdhfkjshf skfhkshf sf jkshfk sfh skfh skf f"));
+    options.addOption(new Option("c",null,false,"ccccccc"));
+
+    HelpFormatter formatter = new HelpFormatter();
+    StringWriter out = new StringWriter();
+
+    formatter.printHelp(new PrintWriter(out),80, "foobar", "dsfkfsh kdh hsd hsdh fkshdf ksdh fskdh fsdh fkshfk sfdkjhskjh fkjh fkjsh khsdkj hfskdhf skjdfh ksf khf s", options, 2, 2, "blort j jgj j jg jhghjghjgjhgjhg jgjhgj jhg jhg hjg jgjhghjg jhg hjg jhgjg jgjhghjg jg jgjhgjgjg jhg jhgjh" + '\r' + '\n' + "rarrr", true);
+  }
+}
+
diff --git a/src/test/org/apache/commons/cli/bug/BugCLI51Test.java b/src/test/org/apache/commons/cli/bug/BugCLI51Test.java
new file mode 100644
index 0000000..7fca189
--- /dev/null
+++ b/src/test/org/apache/commons/cli/bug/BugCLI51Test.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.cli.bug;
+
+import junit.framework.TestCase;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.PosixParser;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.Option;
+
+/**
+ * @author brianegge
+ */
+public class BugCLI51Test
+    extends TestCase
+{
+    public void test() throws Exception
+    {
+        Options options = buildCommandLineOptions();
+        CommandLineParser parser = new PosixParser();
+        String[] args = new String[] {"-t", "-something" };
+        CommandLine commandLine;
+        commandLine = parser.parse( options, args );
+        assertEquals("-something", commandLine.getOptionValue( 't'));
+    }
+
+    private Options buildCommandLineOptions()
+    {
+        Option opt = OptionBuilder.withArgName( "t").hasArg().create('t');
+        Options options = new Options();
+        options.addOption( opt);
+        return options;
+    }
+}
diff --git a/src/test/org/apache/commons/cli/bug/BugCLI71Test.java b/src/test/org/apache/commons/cli/bug/BugCLI71Test.java
new file mode 100644
index 0000000..e2bd2d1
--- /dev/null
+++ b/src/test/org/apache/commons/cli/bug/BugCLI71Test.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.cli.bug;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.cli.*;
+
+public class BugCLI71Test extends TestCase {
+
+    private Options options;
+    private CommandLineParser parser;
+
+    public void setUp() {
+        options = new Options();
+
+        Option algorithm = new Option("a" , "algo", true, "the algorithm which it to perform executing");
+        algorithm.setArgName("algorithm name");
+        options.addOption(algorithm);
+
+        Option key = new Option("k" , "key", true, "the key the setted algorithm uses to process");
+        algorithm.setArgName("value");
+        options.addOption(key);
+
+        parser = new PosixParser();
+    }
+
+    public void testBasic() throws Exception {
+        String[] args = new String[] { "-a", "Caesar", "-k", "A" };
+        CommandLine line = parser.parse( options, args);
+        assertEquals( "Caesar", line.getOptionValue("a") );
+        assertEquals( "A", line.getOptionValue("k") );
+    }
+
+    public void testMistakenArgument() throws Exception {
+        String[] args = new String[] { "-a", "Caesar", "-k", "A" };
+        CommandLine line = parser.parse( options, args);
+        args = new String[] { "-a", "Caesar", "-k", "a" };
+        line = parser.parse( options, args);
+        assertEquals( "Caesar", line.getOptionValue("a") );
+        assertEquals( "a", line.getOptionValue("k") );
+    }
+
+    public void testLackOfError() throws Exception {
+        String[] args = new String[] { "-k", "-a",  "Caesar" };
+        try {
+            CommandLine line = parser.parse( options, args);
+            fail("MissingArgumentException expected");
+        } catch(MissingArgumentException mae) {
+            // expected
+        }
+    }
+
+    public void testGetsDefaultIfOptional() throws Exception {
+        String[] args = new String[] { "-k", "-a", "Caesar" };
+        options.getOption("k").setOptionalArg(true);
+        CommandLine line = parser.parse( options, args);
+        
+        assertEquals( "Caesar", line.getOptionValue("a") );
+        assertEquals( "a", line.getOptionValue("k", "a") );
+    }
+
+}
diff --git a/xdocs/images/1x1.gif b/xdocs/images/1x1.gif
deleted file mode 100755
index 35d42e8..0000000
Binary files a/xdocs/images/1x1.gif and /dev/null differ
diff --git a/xdocs/index.xml b/xdocs/index.xml
deleted file mode 100644
index c8e57e0..0000000
--- a/xdocs/index.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0"?>
-
-<document>
-
- <properties>
-  <title></title>
-  <author email="jstrachan at apache.org">James Strachan</author>
- </properties>
-
-<body>
-
-<section name="CLI : Command Line Interface">
-
-<p>
-   The CLI library provides a simple and easy to use API for working
-   with the command line arguments and options.</p>
-<p>
-   CLI is based on ideas and code from 
-   <ul>
-     <li>werken.opt by Bob Mcwhirter</li>
-     <li>The cli package in Avalon Excalibur by Peter Donald</li>
-     <li>Optz by John Keyes</li>
-   </ul>
-</p>
-
-</section>
-
-</body>
-</document>
diff --git a/xdocs/introduction.xml b/xdocs/introduction.xml
deleted file mode 100644
index a2eb765..0000000
--- a/xdocs/introduction.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0"?>
-<document>
-
-  <properties>
-    <author email="jbjk at mac.com">John Keyes</author>
-    <title>Introduction</title>
-  </properties>
-
-  <body>
-    <section name="Introduction">
-      <p>
-        There are three stages to command line processing.  They are the
-        definition, parsing and interrogation stages.  The following 
-        sections will discuss each of these stages in turn, and discuss how
-        to implement them with CLI.
-      </p>
-    </section>
-    <section name="Definition Stage">
-      <p>
-        Each command line must define the set of options that will be used 
-        to define the interface to the application.
-      </p>
-      <p>
-        CLI uses the <a href="apidocs/org/apache/commons/cli/Options.html">
-        Options</a> class, as a container for 
-        <a href="apidocs/org/apache/commons/cli/Options.html">
-        Option</a> instances.  There are two ways to create
-        <code>Option</code>s in CLI.  One of them is via the constuctors,
-        the other way is via the factory methods defined in 
-        <code>Options</code>.
-      </p>
-      <p>
-        The <a href="usage.html">Usage Scenarios</a> document provides
-        examples how to create an <code>Options</code> object and also
-        provides some real world examples.
-      </p>
-      <p>
-        The result of the definition stage is an <code>Options</code> 
-        instance.
-      </p>
-    </section>
-    <section name="Parsing Stage">
-      <p>
-        The parsing stage is where the text passed into the 
-        application via the command line is processed.  The text is 
-        processed according to the rules defined by the parser 
-        implementation.
-      </p>
-      <p>
-        The <code>parse</code> method defined on 
-        <a href="apidocs/org/apache/commons/cli/CommandLineParser.html">
-        CommandLineParser</a> takes an <code>Options</code>
-        instance and a <code>java.util.List</code> of arguments and 
-        returns a 
-        <a href="apidocs/org/apache/commons/cli/CommandLine.html">
-        CommandLine</a>.
-      </p>
-      <p>
-        The result of the parsing stage is a <code>CommandLine</code>
-        instance.
-      </p>
-    </section>
-    <section name="Interrogation Stage">
-      <p>
-        The interrogation stage is where the application querys the
-        <code>CommandLine</code> to decide what execution branch to
-        take depending on boolean options and to use the option values
-        to provide the application data.
-      </p>
-      <p>
-        This stage is implemented in the user code.  The accessor methods 
-        on <code>CommandLine</code> provide the interrogation capability
-        to the user code.
-      </p>
-      <p>
-        The <a href="usage.html">Usage Scenarios</a> document provides examples
-        how to create an <code>Options</code> object.
-      </p>
-      <p>
-        The result of the interrogation stage is that the user code 
-        is fully informed of all the text that was supplied on the command
-        line and processed according to the parser and <code>Options</code>
-        rules.
-      </p>
-    </section>
-  </body>
-</document>
diff --git a/xdocs/navigation.xml b/xdocs/navigation.xml
deleted file mode 100644
index 3e4acb9..0000000
--- a/xdocs/navigation.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<project name="CLI">
-
-  <title>CLI</title>
-
-  <body>
-    <menu name="User Documentation">
-      <item name="Introduction"      href="/introduction.html"/>
-      <item name="Usage Scenarios"   href="/usage.html"/>
-      <item name="Option Properties" href="/properties.html"/>
-      <item name="Download" href="http://jakarta.apache.org/builds/jakarta-commons/release/commons-cli/v1.0/"/>
-    </menu>
-  </body>
-</project>
diff --git a/xdocs/properties.xml b/xdocs/properties.xml
deleted file mode 100644
index f94b1d9..0000000
--- a/xdocs/properties.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0"?>
-<document>
-
-  <properties>
-    <author email="john at integralsource.com">John Keyes</author>
-    <title>Option Properties</title>
-  </properties>
-
-  <body>
-    <section name="Option Properties">
-      <p>
-        The following are the properties that each 
-        <a href="apidocs/org/apache/commons/cli/Options.html">Option</a> has.  All of these
-        can be set using the accessors or using the methods
-        defined on the
-        <a href="apidocs/org/apache/commons/cli/OptionBuilder.html">OptionBuilder</a>.
-      </p>
-      <table>
-        <tr>
-          <th>Name</th>
-          <th>Type</th>
-          <th>Description</th>
-        </tr>
-        <tr>
-          <td>opt</td>
-          <td>java.lang.String</td>
-          <td>the identification string of the Option.</td>
-        </tr>
-        <tr>
-          <td>longOpt</td>
-          <td>java.lang.String</td>
-          <td>an alias and more descriptive identification string</td>
-        </tr>
-        <tr>
-          <td>description</td>
-          <td>java.lang.String</td>
-          <td>a description of the function of the option</td>
-        </tr>
-        <tr>
-          <td>required</td>
-          <td>boolean</td>
-          <td>a flag to say whether the option <b>must</b> appear on 
-            the command line.</td>
-        </tr>
-        <tr>
-          <td>multipleArgs</td>
-          <td>boolean</td>
-          <td>a flag to say whether the option takes multiple argument 
-            values</td>
-        </tr>
-        <tr>
-          <td>arg</td>
-          <td>boolean</td>
-          <td>a flag to say whether the option takes an argument</td>
-        </tr>
-        <tr>
-          <td>args</td>
-          <td>boolean</td>
-          <td>a flag to say whether the option takes more than one argument</td>
-        </tr>
-        <tr>
-          <td>optionalArg</td>
-          <td>boolean</td>
-          <td>a flag to say whether the option's argument is optional</td>
-        </tr>
-        <tr>
-          <td>argName</td>
-          <td>java.lang.String</td>
-          <td>the name of the argument value for the usage statement</td>
-        </tr>
-        <tr>
-          <td>valueSeparator</td>
-          <td>char</td>
-          <td>the character value used to split the argument string, that
-            is used in conjunction with multipleArgs e.g.
-            if the separator is ',' and the argument string is 'a,b,c' then
-            there are three argument values, 'a', 'b' and 'c'.</td>
-        </tr>
-        <tr>
-          <td>type</td>
-          <td>java.lang.Object</td>
-          <td>the type of the argument</td>
-        </tr>
-        <tr>
-          <td>value</td>
-          <td>java.lang.String</td>
-          <td>the value of the option</td>
-        </tr>
-        <tr>
-          <td>values</td>
-          <td>java.lang.String[]</td>
-          <td>the values of the option</td>
-        </tr>
-      </table>
-    </section>
-  </body>
-</document>
diff --git a/xdocs/usage.xml b/xdocs/usage.xml
deleted file mode 100644
index 6120814..0000000
--- a/xdocs/usage.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0"?>
-<document>
-
-  <properties>
-    <author email="john at integralsource.com">John Keyes</author>
-    <title>Usage Scenarios</title>
-  </properties>
-
-  <body>
-    <section name="Usage Scenarios">
-      <p>
-        The following sections describe some example scenarios on how to 
-        use CLI in applications.
-      </p>
-
-      <subsection name="Using a boolean option">
-        <p>
-          A boolean option is represented on a command line by the presence
-          of the option, i.e. if the option is found then the option value
-          is true, otherwise the value is false.
-        </p>
-        <p>
-          The <code>DateApp</code> utility prints the current date to standard
-          output.  If the <code>-t</code> option is present the current time is 
-          also printed.
-        </p>
-      </subsection>
-      <subsection name="Create the Options">
-        <p>
-          An <a href="apidocs/org/apache/commons/cli/Options.html">
-          Options</a> object must be created and the<code>Option</code> must be 
-          added to it.
-        </p>
-        <source>
-// create Options object
-Options options = new Options();
-
-// add t option
-options.addOption("t", false, "display current time");</source>
-          <p>
-            The <code>addOption</code> method has three parameters.  The first
-            parameter is a <code>java.lang.String</code> that represents the option. 
-            Thesecond paramter is a <code>boolean</code> that specifies whether the
-            option requires an argument or not.  In the case of a boolean option
-            (sometimes referred to as a flag) an argument value is not present so
-            it <code>false</code> is passed.  The third parameter is the description
-            of the option.  This description will be used in the usage text of the
-            application.
-          </p>
-      </subsection>
-      <subsection name="Parsing the command line arguments">
-        <p>
-          The <code>parse</code> methods of <code>Options</code> are used to 
-          parse the command line arguments.  
-        </p>
-        <source>CommandLine cmd = options.parse(args);</source>
-        <p>
-          Now we need to check if the <code>t</code> option is present.  To do
-          this we will interrogate the 
-          <a href="apidocs/org/apache/commons/cli/CommandLine.html">CommandLine
-          </a> object.  The <code>hasOption</code> method takes a 
-          <code>java.lang.String</code> parameter and returns true if the option 
-          represented by the <code>java.lang.String</code> is present, otherwise 
-          it returns false.
-        </p>
-        <source>if(cmd.hasOption("t")) {
-    // print the date and time
-}
-else {
-    // print the date
-}</source>
-      </subsection>
-      <subsection name="International Time">
-        <p>
-          The <code>InternationalDateApp</code> utility extends the 
-          <code>DateApp</code> utility by providing the ability to print the
-          date and time in any country in the world.  To facilitate this a new
-          command line option, <code>c</code>, has been introduced.
-        </p>
-        <source>// add c option
-options.addOption("c", true, "country code");</source>
-        <p>
-          The second parameter is true this time.  This specifies that the
-          <code>c</code> option requires an argument value.  If the required option
-          argument value is specified on the command line it is returned,
-          otherwise <code>null</code> is returned.
-        </p>
-      </subsection>
-      <subsection name="Retrieving the argument value">
-        <p>
-          The <code>getOptionValue</code> methods of <code>Options</code> are
-          used to retrieve the argument values of options.
-        </p>
-        <source>// get c option value
-String countryCode = options.getOptionValue("c");
-
-if(countryCode == null) {
-    // print default date
-}
-else {
-    // print date for country specified by countryCode
-}</source>
-      </subsection>
-    </section>
-
-    <section name="Ant Example">
-      <p>
-        As one of the most ubquituous Java applications 
-        <a href="http://jakarta.apache.org/ant">Ant</a> it will be used
-        here to illustrate how to create the Options required.  The following
-        is the help output for Ant.
-      </p>
-      <source>ant [options] [target [target2 [target3] ...]]
-  Options: 
-  -help                  print this message
-  -projecthelp           print project help information
-  -version               print the version information and exit
-  -quiet                 be extra quiet
-  -verbose               be extra verbose
-  -debug                 print debugging information
-  -emacs                 produce logging information without adornments
-  -logfile <file>        use given file for log
-  -logger <classname>    the class which is to perform logging
-  -listener <classname>  add an instance of class as a project listener
-  -buildfile <file>      use given buildfile
-  -D<property>=<value>   use value for given property
-  -find <file>           search for buildfile towards the root of the
-                         filesystem and use it</source>
-      <subsection name="Boolean Options">
-        <p>
-          Lets create the boolean options for the application as they
-          are the easiest to create.  For clarity the constructors on
-          Option are used here.
-        </p>
-        <source>Option help = new Option( "help", "print this message" );
-Option projecthelp = new Option( "projecthelp", "print project help information" );
-Option version = new Option( "version", "print the version information and exit" );
-Option quiet = new Option( "quiet", "be extra quiet" );
-Option verbose = new Option( "verbose", "be extra verbose" );
-Option debug = new Option( "debug", "print debugging information" );
-Option emacs = new Option( "emacs",
-                           "produce logging information without adornments" );</source>
-      </subsection>
-      <subsection name="Argument Options">
-        <p> 
-          The argument options are created using the OptionBuilder.
-        </p>
-        <source>Option logfile   = OptionBuilder.withArgName( "file" )
-                                .hasArg()
-                                .withDescription(  "use given file for log" )
-                                .create( "file" );
-
-Option logger    = OptionBuilder.withArgName( "classname" )
-                                .hasArg()
-                                .withDescription( "the class which it to perform "
-                                                  + "logging" )
-                                .create( "logger" );
-
-Option listener  = OptionBuilder.withArgName( "classname" )
-                                .hasArg()
-                                .withDescription( "add an instance of class as "
-                                                  + "a project listener" )
-                                .create( "listener"); 
-
-Option buildfile = OptionBuilder.withArgName( "file" )
-                                .hasArg()
-                                .withDescription(  "use given buildfile" )
-                                .create( "buildfile");
-
-Option find      = OptionBuilder.withArgName( "file" )
-                                .hasArg()
-                                .withDescription( "search for buildfile towards the "
-                                  + "root of the filesystem and use it" )
-                                .create( "file" );</source>
-      </subsection>
-      <subsection name="Java Property Option">
-        <p>
-          The last option to create is the Java property and it too is created
-          using the OptionBuilder.
-        </p>
-        <source>Option property  = OptionBuilder.withArgName( "property=value" )
-                                .hasArg()
-                                .withValueSeparator()
-                                .withDescription( "use value for given property" )
-                                .create( "D" );</source>
-      </subsection>
-      <subsection name="Create the Options">
-        <p>
-          Now that we have created each 
-          <a href="apidocs/org/apache/commons/cli/Option.html">Option</a> we need 
-          to create the 
-          <a href="apidocs/org/apache/commons/cli/Options.html">Options</a> 
-          instance.  This is achieved using the 
-          <a href="apidocs/org/apache/commons/cli/CommandLine.html#hasOption(java.lang.String)">addOption</a> 
-          method of <code>Options</code>.
-        </p>
-        <source>Options options = new Options();
-
-options.addOption( help );
-options.addOption( projecthelp );
-options.addOption( version );
-options.addOption( quiet );
-options.addOption( verbose );
-options.addOption( debug );
-options.addOption( emacs );
-options.addOption( logfile );
-options.addOption( logger );
-options.addOption( listener );
-options.addOption( buildfile );
-options.addOption( find );
-options.addOption( property );</source>
-        <p>
-          All the preperation is now complete and we are now ready to
-          parse the command line arguments.
-        </p>
-      </subsection>
-      <subsection name="Create the Parser">
-        <p>
-          We now need to create a Parser.  This will parse the command
-          line arguments, using the rules specified by the Options and
-          return an instance of <a href="apidocs/org/apache/commons/cli/CommandLine.html">CommandLine</a>.
-        </p>
-        <source>public static void main( String[] args ) {
-    // create the parser
-    CommandLineParser parser = new PosixParser();
-    try {
-        // parse the command line arguments
-        CommandLine line = parser.parse( options, args );
-    }
-    catch( ParseException exp ) {
-        // oops, something went wrong
-        System.err.println( "Parsing failed.  Reason: " + exp.getMessage() );
-    }
-}</source>
-      </subsection>
-      <subsection name="Querying the commandline">
-        <p>
-          To see if an option has been passed the<code>hasOption</code>
-          method is used.  The argument value can be retrieved using
-          the <code>getValue</code> method.
-        </p>
-        <source>// has the buildfile argument been passed?
-if( line.hasOption( "buildfile" ) ) {
-    // initialise the member variable
-    this.buildfile = line.getValue( "buildfile" );
-}</source>
-      </subsection>
-      <subsection name="Usage/Help">
-        <p>
-          CLI also provides the means to automatically generate usage
-          and help information.  This is achieved with the
-          <a href="apidocs/org/apache/commons/cli/HelpFormatter.html">HelpFormatter</a>
-          class.
-        </p>
-        <source>// automatically generate the help statement
-HelpFormatter formatter = new HelpFormatter();
-formatter.printHelp( "ant", options );</source>
-        <p>
-          When executed the following output is produced:
-        </p>
-        <source>usage: ant
--D <property=value>     use value for given property
--buildfile <file>       use given buildfile
--debug                  print debugging information
--emacs                  produce logging information without adornments
--file <file>            search for buildfile towards the root of the
-                        filesystem and use it
--help                   print this message
--listener <classname>   add an instance of class as a project listener
--logger <classname>     the class which it to perform logging
--projecthelp            print project help information
--quiet                  be extra quiet
--verbose                be extra verbose
--version                print the version information and exit</source>
-        <p>
-          If you also require to have a usage statement printed 
-          then calling <code>formatter.printHelp( "ant", options, true )</code>
-          will generate a usage statment as well as the help information.
-        </p>
-      </subsection>
-    </section>
-
-    <section name="ls Example">
-      <p>
-        One of the most widely used command line applications in the *nix world
-        is <code>ls</code>.  To parse a command line for an application like this
-        a different parser is required, the
-        <a href="apidocs/org/apache/commons/cli/PosixParser.html">PosixParser</a>.
-        Due to the large number of options required for <code>ls</code> this
-        example will only cover a small proportion of the options.  The following
-        is a section of the help output.
-      </p>
-      <source>Usage: ls [OPTION]... [FILE]...
-List information about the FILEs (the current directory by default).
-Sort entries alphabetically if none of -cftuSUX nor --sort.
-
--a, --all                  do not hide entries starting with .
--A, --almost-all           do not list implied . and ..
--b, --escape               print octal escapes for nongraphic characters
-    --block-size=SIZE      use SIZE-byte blocks
--B, --ignore-backups       do not list implied entries ending with ~
--c                         with -lt: sort by, and show, ctime (time of last
-                           modification of file status information)
-                           with -l: show ctime and sort by name
-                           otherwise: sort by ctime
--C                         list entries by columns</source>
-      <p>
-        The following is the code that is used to create the 
-        <a href="apidocs/org/apache/commons/cli/Options.html">Options</a> for this example.
-      </p>
-      <source>// create the command line parser
-CommandLineParser parser = new PosixParser();
-
-// create the Options
-Options options = new Options();
-options.addOption( "a", "all", false, "do not hide entries starting with ." );
-options.addOption( "A", "almost-all", false, "do not list implied . and .." );
-options.addOption( "b", "escape", false, "print octal escapes for nongraphic "
-                                         + "characters" );
-options.addOption( OptionBuilder.withLongOpt( "block-size" )
-                                .withDescription( "use SIZE-byte blocks" )
-                                .withValueSeparator( '=' )
-                                .hasArg()
-                                .create() );
-options.addOption( "B", "ignore-backups", false, "do not list implied entried "
-                                                 + "ending with ~");
-options.addOption( "c", false, "with -lt: sort by, and show, ctime (time of last " 
-                               + "modification of file status information) with "
-                               + "-l:show ctime and sort by name otherwise: sort "
-                               + "by ctime" );
-options.addOption( "C", false, "list entries by columns" );
-
-String[] args = new String[]{ "--block-size=10" };
-
-try {
-    // parse the command line arguments
-    CommandLine line = parser.parse( options, args );
-
-    // validate that block-size has been set
-    if( line.hasOption( "block-size" ) ) {
-        // print the value of block-size
-        System.out.println( line.getOptionValue( "block-size" ) );
-    }
-}
-catch( ParseException exp ) {
-    System.out.println( "Unexpected exception:" + exp.getMessage() );
-}</source>
-    </section>
-  </body>
-</document>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/libcommons-cli-java.git



More information about the pkg-java-commits mailing list