[libcommons-cli-java] 19/31: Imported Upstream version 1.3.1

Tony Mancill tmancill at moszumanska.debian.org
Mon Jun 22 05:52:47 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 ff6a75df80fe29b9f87f7d791d7b4a9f555f6aa9
Author: tony mancill <tmancill at debian.org>
Date:   Mon Jun 22 04:48:31 2015 +0000

    Imported Upstream version 1.3.1
---
 CONTRIBUTING.md                                    |   97 ++
 NOTICE.txt                                         |    4 +-
 README.md                                          |   98 ++
 README.txt                                         |   26 -
 RELEASE-NOTES.txt                                  |  286 +++--
 pom.xml                                            |  211 ++--
 src/assembly/bin.xml                               |    4 +-
 src/assembly/src.xml                               |   10 +-
 src/changes/changes.xml                            |  248 +++++
 src/conf/MANIFEST.MF                               |   21 -
 src/conf/checkstyle-suppressions.xml               |   38 +
 src/conf/checkstyle.xml                            |   45 +-
 src/conf/findbugs-exclude-filter.xml               |   34 +
 .../commons/cli/AlreadySelectedException.java      |    8 +-
 .../commons/cli/AmbiguousOptionException.java      |   88 ++
 .../java/org/apache/commons/cli/BasicParser.java   |   10 +-
 .../java/org/apache/commons/cli/CommandLine.java   |   87 +-
 .../org/apache/commons/cli/CommandLineParser.java  |   14 +-
 .../java/org/apache/commons/cli/DefaultParser.java |  694 ++++++++++++
 .../java/org/apache/commons/cli/GnuParser.java     |   12 +-
 .../java/org/apache/commons/cli/HelpFormatter.java |  378 ++++---
 .../commons/cli/MissingArgumentException.java      |    8 +-
 .../apache/commons/cli/MissingOptionException.java |   33 +-
 .../java/org/apache/commons/cli/Option.java        |  422 +++++++-
 .../java/org/apache/commons/cli/OptionBuilder.java |   97 +-
 .../java/org/apache/commons/cli/OptionGroup.java   |   41 +-
 .../org/apache/commons/cli/OptionValidator.java    |   34 +-
 .../java/org/apache/commons/cli/Options.java       |  138 ++-
 .../org/apache/commons/cli/ParseException.java     |    8 +-
 .../java/org/apache/commons/cli/Parser.java        |  127 ++-
 .../apache/commons/cli/PatternOptionBuilder.java   |   78 +-
 .../java/org/apache/commons/cli/PosixParser.java   |   58 +-
 .../java/org/apache/commons/cli/TypeHandler.java   |   77 +-
 .../commons/cli/UnrecognizedOptionException.java   |    8 +-
 .../java/org/apache/commons/cli/Util.java          |   17 +-
 .../java/org/apache/commons/cli/overview.html      |    2 +-
 .../java/org/apache/commons/cli/package-info.java} |    7 +
 src/media/logo.xcf                                 |  Bin 20269 -> 21179 bytes
 src/site/resources/download_cli.cgi                |    4 +
 src/site/resources/images/1x1.gif                  |  Bin 0 -> 43 bytes
 src/site/resources/images/logo.png                 |  Bin 0 -> 11003 bytes
 src/site/resources/images/options.png              |  Bin 0 -> 27463 bytes
 src/site/resources/images/svg/commandlines.svg     |   57 +
 src/site/resources/images/svg/diagrams-cli2.js     |  291 +++++
 .../resources/images/svg/diagrams.css}             |   64 +-
 src/site/resources/images/svg/diagrams.js          |  368 +++++++
 src/site/resources/images/svg/options.svg          |   66 ++
 src/site/resources/images/svg/util.svg             |   47 +
 src/site/resources/profile.jacoco                  |    0
 src/site/site.xml                                  |   45 +
 src/site/xdoc/download_cli.xml                     |  138 +++
 src/site/xdoc/index.xml                            |  116 ++
 src/site/xdoc/introduction.xml                     |  101 ++
 src/site/xdoc/issue-tracking.xml                   |  102 ++
 src/site/xdoc/mail-lists.xml                       |  202 ++++
 src/site/xdoc/properties.xml                       |  109 ++
 .../cli/package.html => site/xdoc/release_1_0.xml} |   26 +-
 RELEASE-NOTES.txt => src/site/xdoc/release_1_2.xml |   42 +-
 src/site/xdoc/release_1_3.xml                      |  154 +++
 src/site/xdoc/release_1_3_1.xml                    |   52 +
 src/site/xdoc/upgrading-1.0-to-1.1.xml             |   48 +
 src/site/xdoc/usage.xml                            |  372 +++++++
 .../org/apache/commons/cli/ApplicationTest.java    |  133 ++-
 .../apache/commons/cli/ArgumentIsOptionTest.java   |   13 +-
 .../org/apache/commons/cli/BasicParserTest.java    |  175 ++++
 .../org/apache/commons/cli/CommandLineTest.java    |   40 +-
 .../org/apache/commons/cli/DefaultParserTest.java} |   12 +-
 .../java/org/apache/commons/cli/GnuParserTest.java |  157 +++
 .../org/apache/commons/cli/HelpFormatterTest.java  |  325 ++++--
 .../org/apache/commons/cli/OptionBuilderTest.java  |   41 +-
 .../org/apache/commons/cli/OptionGroupTest.java    |   45 +-
 .../java/org/apache/commons/cli/OptionTest.java    |  219 ++++
 .../org/apache/commons/cli/OptionsTest.java        |   43 +-
 .../org/apache/commons/cli/ParserTestCase.java     | 1108 ++++++++++++++++++++
 .../commons/cli/PatternOptionBuilderTest.java      |   28 +-
 .../org/apache/commons/cli/PosixParserTest.java    |   88 ++
 .../org/apache/commons/cli/UtilTest.java           |   16 +-
 .../org/apache/commons/cli/ValueTest.java          |  126 +--
 .../org/apache/commons/cli/ValuesTest.java         |  113 +-
 .../org/apache/commons/cli/bug/BugCLI133Test.java  |   13 +-
 .../org/apache/commons/cli/bug/BugCLI13Test.java   |   14 +-
 .../org/apache/commons/cli/bug/BugCLI148Test.java  |   51 +-
 .../org/apache/commons/cli/bug/BugCLI162Test.java  |  114 +-
 .../org/apache/commons/cli/bug/BugCLI18Test.java   |    6 +-
 .../org/apache/commons/cli/bug/BugCLI252Test.java} |   40 +-
 .../org/apache/commons/cli/bug/BugCLI71Test.java   |   22 +-
 .../org/apache/commons/cli/bug}/BugsTest.java      |  111 +-
 .../org/apache/commons/cli/BasicParserTest.java    |   56 -
 src/test/org/apache/commons/cli/OptionTest.java    |  140 ---
 .../org/apache/commons/cli/ParseRequiredTest.java  |  138 ---
 .../org/apache/commons/cli/ParserTestCase.java     |  306 ------
 .../org/apache/commons/cli/PosixParserTest.java    |  188 ----
 92 files changed, 7806 insertions(+), 2047 deletions(-)

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..9d05cf6
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,97 @@
+<!---
+ 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.
+-->
+<!---
+ +======================================================================+
+ |****                                                              ****|
+ |****      THIS FILE IS GENERATED BY THE COMMONS BUILD PLUGIN      ****|
+ |****                    DO NOT EDIT DIRECTLY                      ****|
+ |****                                                              ****|
+ +======================================================================+
+ | TEMPLATE FILE: contributing-md-template.md                           |
+ | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
+ +======================================================================+
+ |                                                                      |
+ | 1) Re-generate using: mvn commons:contributing-md                    |
+ |                                                                      |
+ | 2) Set the following properties in the component's pom:              |
+ |    - commons.jira.id  (required, alphabetic, upper case)             |
+ |                                                                      |
+ | 3) Example Properties                                                |
+ |                                                                      |
+ |  <properties>                                                        |
+ |    <commons.jira.id>MATH</commons.jira.id>                           |
+ |  </properties>                                                       |
+ |                                                                      |
+ +======================================================================+
+--->
+Contributing to Apache Commons CLI
+======================
+
+You have found a bug or you have an idea for a cool new feature? Contributing code is a great way to give something back to
+the open source community. Before you dig right into the code there are a few guidelines that we need contributors to
+follow so that we can have a chance of keeping on top of things.
+
+Getting Started
+---------------
+
++ Make sure you have a [JIRA account](https://issues.apache.org/jira/).
++ Make sure you have a [GitHub account](https://github.com/signup/free).
++ If you're planning to implement a new feature it makes sense to discuss you're changes on the [dev list](https://commons.apache.org/mail-lists.html) first. This way you can make sure you're not wasting your time on something that isn't considered to be in Apache Commons CLI's scope.
++ Submit a ticket for your issue, assuming one does not already exist.
+  + Clearly describe the issue including steps to reproduce when it is a bug.
+  + Make sure you fill in the earliest version that you know has the issue.
++ Fork the repository on GitHub.
+
+Making Changes
+--------------
+
++ Create a topic branch from where you want to base your work (this is usually the master/trunk branch).
++ Make commits of logical units.
++ Respect the original code style:
+  + Only use spaces for indentation.
+  + Create minimal diffs - disable on save actions like reformat source code or organize imports. If you feel the source code should be reformatted create a separate PR for this change.
+  + Check for unnecessary whitespace with git diff --check before committing.
++ Make sure your commit messages are in the proper format. Your commit message should contain the key of the JIRA issue.
++ Make sure you have added the necessary tests for your changes.
++ Run all the tests with `mvn clean verify` to assure nothing else was accidentally broken.
+
+Making Trivial Changes
+----------------------
+
+For changes of a trivial nature to comments and documentation, it is not always necessary to create a new ticket in JIRA.
+In this case, it is appropriate to start the first line of a commit with '(doc)' instead of a ticket number.
+
+Submitting Changes
+------------------
+
++ Sign the [Contributor License Agreement][cla] if you haven't already.
++ Push your changes to a topic branch in your fork of the repository.
++ Submit a pull request to the repository in the apache organization.
++ Update your JIRA ticket and include a link to the pull request in the ticket.
+
+Additional Resources
+--------------------
+
++ [Contributing patches](https://commons.apache.org/patches.html)
++ [Apache Commons CLI JIRA project page](https://issues.apache.org/jira/browse/CLI)
++ [Contributor License Agreement][cla]
++ [General GitHub documentation](https://help.github.com/)
++ [GitHub pull request documentation](https://help.github.com/send-pull-requests/)
++ [Apache Commons Twitter Account](https://twitter.com/ApacheCommons)
++ #apachecommons IRC channel on freenode.org
+
+[cla]:https://www.apache.org/licenses/#clas
diff --git a/NOTICE.txt b/NOTICE.txt
index 72eb32a..cee9ac2 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -1,5 +1,5 @@
 Apache Commons CLI
-Copyright 2001-2009 The Apache Software Foundation
+Copyright 2001-2015 The Apache Software Foundation
 
-This product includes software developed by
+This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..6958b41
--- /dev/null
+++ b/README.md
@@ -0,0 +1,98 @@
+<!---
+ 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.
+-->
+<!---
+ +======================================================================+
+ |****                                                              ****|
+ |****      THIS FILE IS GENERATED BY THE COMMONS BUILD PLUGIN      ****|
+ |****                    DO NOT EDIT DIRECTLY                      ****|
+ |****                                                              ****|
+ +======================================================================+
+ | TEMPLATE FILE: readme-md-template.md                                 |
+ | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
+ +======================================================================+
+ |                                                                      |
+ | 1) Re-generate using: mvn commons:readme-md                          |
+ |                                                                      |
+ | 2) Set the following properties in the component's pom:              |
+ |    - commons.componentid (required, alphabetic, lower case)          |
+ |    - commons.release.version (required)                              |
+ |                                                                      |
+ | 3) Example Properties                                                |
+ |                                                                      |
+ |  <properties>                                                        |
+ |    <commons.componentid>math</commons.componentid>                   |
+ |    <commons.release.version>1.2</commons.release.version>            |
+ |  </properties>                                                       |
+ |                                                                      |
+ +======================================================================+
+--->
+Apache Commons CLI
+===================
+
+Apache Commons CLI provides a simple API for presenting, processing and validating a command line interface.
+
+Documentation
+-------------
+
+More information can be found on the [homepage](https://commons.apache.org/proper/commons-cli).
+The [JavaDoc](https://commons.apache.org/proper/commons-cli/javadocs/api-release) can be browsed.
+Questions related to the usage of Apache Commons CLI should be posted to the [user mailing list][ml].
+
+Where can I get the latest release?
+-----------------------------------
+You can download source and binaries from our [download page](https://commons.apache.org/proper/commons-cli/download_cli.cgi).
+
+Alternatively you can pull it from the central Maven repositories:
+
+```xml
+<dependency>
+  <groupId>commons-cli</groupId>
+  <artifactId>commons-cli</artifactId>
+  <version>1.3</version>
+</dependency>
+```
+
+Contributing
+------------
+
+We accept PRs via github. The [developer mailing list][ml] is the main channel of communication for contributors.
+There are some guidelines which will make applying PRs easier for us:
++ No tabs! Please use spaces for indentation.
++ Respect the code style.
++ Create minimal diffs - disable on save actions like reformat source code or organize imports. If you feel the source code should be reformatted create a separate PR for this change.
++ Provide JUnit tests for your changes and make sure your changes don't break any existing tests by running ```mvn clean test```.
+
+If you plan to contribute on a regular basis, please consider filing a [contributor license agreement](https://www.apache.org/licenses/#clas).
+You can learn more about contributing via GitHub in our [contribution guidelines](CONTRIBUTING.md).
+
+License
+-------
+Code is under the [Apache Licence v2](https://www.apache.org/licenses/LICENSE-2.0.txt).
+
+Donations
+---------
+You like Apache Commons CLI? Then [donate back to the ASF](https://www.apache.org/foundation/contributing.html) to support the development.
+
+Additional Resources
+--------------------
+
++ [Apache Commons Homepage](https://commons.apache.org/)
++ [Apache Bugtracker (JIRA)](https://issues.apache.org/jira/)
++ [Apache Commons Twitter Account](https://twitter.com/ApacheCommons)
++ #apachecommons IRC channel on freenode.org
+
+[ml]:https://commons.apache.org/mail-lists.html
diff --git a/README.txt b/README.txt
deleted file mode 100644
index 46f5e9e..0000000
--- a/README.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-Apache Commons CLI
-===================
-
-Welcome to the CLI 1.x component of the Apache Commons project.
-
-The information in this file is relevant if you have
-downloaded a CLI source distribution.
-
-CLI is built with Maven 2, which can be found here:
-
-  http://maven.apache.org
-
-and to build and test the system use:
-
-  mvn clean package
-
-The system will build and test itself.
-
-For complete documentation and to create a local copy of the
-CLI project website, type:
-
-  mvn site
-
-Good luck!
-
-- The Apache Commons Team
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index fe5dca0..0ac6207 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -1,7 +1,5 @@
-$Id: RELEASE-NOTES.txt 695235 2008-09-14 15:26:10Z ebourg $
-
-            Commons CLI Package
-                Version 1.2
+            Apache Commons CLI
+                Version 1.3.1
                Release Notes
 
 
@@ -11,63 +9,223 @@ 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.
 
-Commons CLI 1.2 is a bugfix release. The following notable changes were made:
-
- * A major regression introduced in CLI 1.1 that prevented the usage of repeated options has been fixed.
- * Several parser issues have been fixed, especially with the PosixParser.
- * HelpFormatter now wraps the lines properly
- * The ordering of the option in the help message can now be defined.
- * Various API enhancements (improved exceptions, serializable classes)
-
-Commons CLI 1.2 is binary compatible with the previous versions, except for
-the OptionValidator class that is no longer public.
-
-More information can be found on the project site at http://commons.apache.org/cli
-
-
-NEW FEATURES:
-
-  * The method getOptionProperties() in the CommandLine class was added
-    to retrieve easily the key/value pairs specified with options like
-    -Dkey1=value1 -Dkey2=value2.
-
-  * GnuParser now supports long options with an '=' sign
-    (ie. --foo=bar and -foo=bar) (CLI-157)
-
-  * The ordering of options can be defined in help messages. (CLI-155)
-
-
-BUG FIXES:
-
-  * The number of arguments defined for an option specifies the arguments
-    per occurrence of the option and not for all occurrences. (CLI-137)
-
-  * PosixParser no longer ignores unrecognized short options. (CLI-164)
-
-  * PosixParser no longer stops the bursting process of a token if stopAtNonOption
-    is enabled and a non option character is encountered. (CLI-163)
-
-  * PosixParser no longer keeps processing the tokens after an unrecognized
-    long option when stopAtNonOption is enabled. (CLI-165)
-
-  * Required options are properly checked if an Options instance is used twice
-    to parse a command line. (CLI-156)
-
-  * The line wrapping in HelpFormatter now works properly. (CLI-151)
-
-
-CHANGES:
-
-  * The message of MissingOptionException has been improved. (CLI-149)
-
-  * The exceptions have been enhanced with methods to retrieve easily
-    the related options. (CLI-86)
-
-  * Option.toString() now reports arguments properly. (CLI-141)
-
-  * The Parser class has been changed to be more easily extendable. (CLI-142)
-
-  * The following classes are now serializable: Option, OptionGroup,
-    CommandLine and Options. (CLI-140)
-
-  * OptionValidator is no longer public, its methods were all private.
+Commons CLI 1.3.1 is a bug fix release and binary compatible with the
+previous versions, except for the OptionValidator class that is no longer public
+(change introduced in v1.2). Commons CLI 1.3.1 at least requires Java 5.0.
+
+More information can be found on the project site at 
+http://commons.apache.org/cli.
+
+BUG FIXES
+=========
+
+o CLI-252: LongOpt falsely detected as ambiguous. Thanks to Simon Harrer.
+
+
+                Release Notes for version 1.3
+
+NOTES
+=====
+
+A new parser is available: DefaultParser. It combines the features of the
+GnuParser and the PosixParser. It also provides additional features like
+partial matching for the long options, and long options without
+separator (i.e like the JVM memory settings: -Xmx512m). This new parser
+deprecates the previous ones.
+
+DEPRECATIONS
+============
+
+o org.apache.commons.cli.BasicParser 
+    replaced by org.apache.commons.cli.DefaultParser
+
+o org.apache.commons.cli.GnuParser 
+    replaced by org.apache.commons.cli.DefaultParser
+
+o org.apache.commons.cli.OptionBuilder 
+    replaced by org.apache.commons.cli.Option.builder()
+                org.apache.commons.cli.Option.builder(String)
+                org.apache.commons.cli.Option.Builder
+
+o org.apache.commons.cli.Parser 
+    replaced by org.apache.commons.cli.DefaultParser
+
+o org.apache.commons.cli.PosixParser 
+    replaced by org.apache.commons.cli.DefaultParser
+
+
+NEW FEATURES
+============
+
+o CLI-161: PosixParser doesn't stop the parsing on "--" tokens following an
+           option with an argument
+o CLI-167: Support options like Java memory settings (-Xmx512M)
+o CLI-181: Unified Parser
+o CLI-224: Added new fluent API to create Option instances via builder class
+           Option.Builder. This replaces the now deprecated OptionBuilder.
+           Thanks to Duncan Jones, Brian Blount.
+o CLI-160: PosixParser now supports partial long options (--ver instead of
+           --version). 
+o CLI-169: HelpFormatter now supports setting the displayed separator of long
+           options. Thanks to J. Lewis Muir. 
+o CLI-214: Added new method Options.addOption(String, String). Thanks to
+           Alexandru Mocanu.
+
+
+BUG FIXES
+=========
+
+o CLI-248: Dead links on doc page.
+o CLI-234: Fixed code example in javadoc of
+           "Option#Builder#valueSeparator(char)". Thanks to Greg Thomas.
+o CLI-241: Clarified behavior of "OptionValidator#validateOption(String)"
+           in case of null input. Thanks to Beluga Behr.
+o CLI-202: Default options will now work correctly with required options that
+           are missing.
+o CLI-203: Default options will now work correctly together with option groups. 
+o CLI-205: HelpFormatter.setArgName(String) now correctly sets the argument
+           name.
+o CLI-204: Passing default values for not defined options to a parser will now
+           trigger a ParseException instead of a NullPointerException.
+o CLI-201: Default properties provided as input to the Parser.parse() methods
+           are now correctly processed.
+o CLI-215: CommandLine.getParsedOptionValue() now returns a String object if no
+           option type has been explicitly set. Thanks to Manuel M�ller. 
+o CLI-212: HelpFormatter now prints command-line options in the same order as
+           they have been added. Thanks to Per Cederberg.
+o CLI-186: Standard help text now shows mandatory arguments also for the first
+           option. Thanks to Kristoff Kiefer.
+o CLI-207: HelpFormatter does not strip anymore leading whitespace in the
+           footer text. Thanks to Uri Moszkowicz.
+o CLI-185: Strip quotes contained in argument values only if there is exactly
+           one at the beginning and one at the end. Thanks to
+           Einar M. R. Rosenvinge.
+o CLI-184: Negative numerical arguments take precedence over numerical options. 
+o CLI-193: Fix possible StringIndexOutOfBoundsException in HelpFormatter.
+           Thanks to Travis McLeskey.
+o CLI-183: OptionGroups no longer throw an AlreadySelectedException when reused
+           for several parsings.
+o CLI-182: OptionGroup now selects properly an option with no short name.
+
+
+CHANGES
+=======
+
+o CLI-240: Small cleanup of Option class. Thanks to Beluga Behr.
+o CLI-230: Options.getRequiredOptions() now returns an unmodifiable list. 
+o CLI-218: Clarify javadoc for CommandLine.getOptionValue() that the first
+           specified argument will be returned. Thanks to Sven. 
+o CLI-227: Changed unit tests to junit 4 annotation style. Thanks to
+           Duncan Jones. 
+o CLI-209: The javadoc of OptionBuilder now states that the class is not
+           thread-safe. Thanks to Thomas Herre. 
+o CLI-200: Fixed typo in javadoc of class CommandLine. Thanks to
+           Gerard Weatherby. 
+o CLI-223: Source code now uses generic types instead of raw types where
+           possible. Thanks to Gerard Weatherby. 
+o CLI-220  Corrected javadoc for return type of
+           MissingOptionException.getMissingOptions(). Thanks to Joe Casadonte.
+o CLI-197: Improve description of parameter "stopAtNonOption" in method
+           CommandLine.parse(Options, String[], boolean). Thanks to
+           Anders Larsson.
+o CLI-231: Removed DoubleCheckedLocking test from checkstyle configuration.
+           Thanks to Duncan Jones.
+
+
+                Release Notes for version 1.2
+
+NEW FEATURES
+============
+
+o --     : The method getOptionProperties() in the CommandLine class was added
+           to retrieve easily the key/value pairs specified with options like
+           -Dkey1=value1 -Dkey2=value2.
+o CLI-157: GnuParser now supports long options with an '=' sign 
+           (ie. --foo=bar and -foo=bar)
+o CLI-155: The ordering of options can be defined in help messages.
+
+
+BUG FIXES
+=========
+
+o CLI-137: The number of arguments defined for an option specifies the
+           arguments per occurence of the option and not for all occurences.
+o CLI-164: PosixParser no longer ignores unrecognized short options.
+o CLI-163: PosixParser no longer stops the bursting process of a token if
+           stopAtNonOption is enabled and a non option character is
+           encountered.
+o CLI-165: PosixParser no longer keeps processing the tokens after an 
+           unrecognized long option when stopAtNonOption is enabled.
+o CLI-156: Required options are properly checked if an Options instance is used
+           twice to parse a command line.
+o CLI-151: The line wrapping in HelpFormatter now works properly.
+
+
+CHANGES
+=======
+
+o CLI-149: The message of MissingOptionException has been improved.
+o CLI-86:  The exceptions have been enhanced with methods to retrieve easily
+           the related options.
+o CLI-141: Option.toString() now reports arguments properly.
+o CLI-142: The Parser class has been changed to be more easily extendable.
+o CLI-140: The following classes are now serializable: Option, OptionGroup,
+           CommandLine and Options.
+o --     : OptionValidator is no longer public, its methods were all private.
+
+
+                Release Notes for version 1.1
+
+NEW FEATURES
+============
+
+o CLI-78:  Setting description of a Option. 
+
+CHANGES
+=======
+
+o CLI-2:   Wrong usage summary. 
+o CLI-5:   Dependecy on commons-lang-2.0 but commons-lang-1.0 is obtained. 
+o CLI-8:   Line separator as first char for helpformatter (footer) throws
+           exception. 
+o CLI-13:  CommandLine.getOptionValue() behaves contrary to docs. 
+o CLI-21:  clone method in Option should use super.clone(). 
+o CLI-23:  Passing properties in Parser does not work for options with a single
+           argument. 
+o CLI-26:  Only long options without short option seems to be noticed. 
+o CLI-28:  Infinite Loop in Command-Line processing. 
+o CLI-29:  Options should not be able to be added more than once. 
+o CLI-35:  HelpFormatter doesn't sort options properly. 
+o CLI-38:  HelpFormatter doesn't function correctly for options with only
+           LongOpt. 
+o CLI-44:  Document enhancement. 
+o CLI-45:  Documentation errors. 
+o CLI-51:  Parameter value "-something" misinterpreted as a parameter. 
+o CLI-56:  clone() method doesn't fully clone contents. 
+o CLI-59:  No Javadoc for HelpFormatter!. 
+o CLI-65:  Parser breaks up command line parms into single characters. 
+o CLI-67:  Missing arguments in HelpFormatter.renderOptions(..).
+o CLI-69:  Error parsing option arguments.
+o CLI-71:  A weakness of parser.
+o CLI-129: CLI_1_BRANCH build.xml doesn't work.
+o CLI-130: Remove the Commons Lang dependency.
+o CLI-131: Options class returns options in random order.
+o CLI-132: MissingOptionException should contain a useful error message.
+o CLI-133: NullPointerException in Util.stripLeadingHyphens when passed a null
+           argument. 
+o CLI-134: 1.1 is not backwards compatible because it adds methods to the
+           CommandLineParser interface. 
+o CLI-135: Backwards compatibility between 1.1 and 1.0 broken due to
+           Option.addValue removal. 
+
+
+Historical list of changes: http://commons.apache.org/cli/changes-report.html
+
+For complete information on Commons CLI, including instructions on how to
+submit bug reports, patches, or suggestions for improvement, see the 
+Apache Commons CLI website:
+
+http://commons.apache.org/cli/
+
+Have fun!
+-Apache Commons CLI team
diff --git a/pom.xml b/pom.xml
index 21e6d30..5a439e3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,20 +19,20 @@
   <parent>
     <groupId>org.apache.commons</groupId>
     <artifactId>commons-parent</artifactId>
-    <version>11</version>
+    <version>37</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>commons-cli</groupId>
   <artifactId>commons-cli</artifactId>
-  <version>1.2</version>
-  <name>Commons CLI</name>
+  <version>1.3.1</version>
+  <name>Apache Commons CLI</name>
 
   <inceptionYear>2002</inceptionYear>
   <description>
-    Commons CLI provides a simple API for presenting, processing and validating a command line interface.
+    Apache Commons CLI provides a simple API for presenting, processing and validating a command line interface.
   </description>
 
-  <url>http://commons.apache.org/cli/</url>
+  <url>http://commons.apache.org/proper/commons-cli/</url>
 
   <issueManagement>
     <system>jira</system>
@@ -40,9 +40,9 @@
   </issueManagement>
 
   <scm>
-    <connection>scm:svn:http://svn.apache.org/repos/asf/commons/proper/cli/branches/cli-1.x/</connection>
-    <developerConnection>scm:svn:https://svn.apache.org/repos/asf/commons/proper/cli/branches/cli-1.x/</developerConnection>
-    <url>http://svn.apache.org/viewvc/commons/proper/cli/branches/cli-1.x/</url>
+    <connection>scm:svn:http://svn.apache.org/repos/asf/commons/proper/cli/tags/cli-1.3.1/</connection>
+    <developerConnection>scm:svn:https://svn.apache.org/repos/asf/commons/proper/cli/tags/cli-1.3.1/</developerConnection>
+    <url>http://svn.apache.org/viewvc/commons/proper/cli/tags/cli-1.3.1/</url>
   </scm>
 
   <developers>
@@ -79,10 +79,24 @@
         <role>designed CLI2</role>
       </roles>
     </developer>
+    <developer>
+      <name>Emmanuel Bourg</name>
+      <id>ebourg</id>
+      <email>ebourg at apache.org</email>
+      <organization>Ariane Software</organization>
+    </developer>
+    <developer>
+      <name>Thomas Neidhart</name>
+      <id>tn</id>
+      <email>tn at apache.org</email>
+    </developer>
   </developers>
 
   <contributors>
     <contributor>
+      <name>Beluga Behr</name>
+    </contributor>
+    <contributor>
       <name>Peter Donald</name>
       <roles>
         <role>contributed ideas and code from Avalon Excalibur's cli package</role>
@@ -95,6 +109,12 @@
       </roles>
     </contributor>
     <contributor>
+      <name>Duncan Jones</name>
+      <roles>
+        <role>supplied patches</role>
+      </roles>
+    </contributor>
+    <contributor>
       <name>Berin Loritsch</name>
       <email>bloritsch at apache.org</email>
       <roles>
@@ -110,50 +130,54 @@
       </roles>
     </contributor>
     <contributor>
+      <name>Alexandru Mocanu</name>
+      <roles>
+        <role>supplied patch</role>
+      </roles>
+    </contributor>
+    <contributor>
       <name>Andrew Shirley</name>
       <roles>
         <role>lots of fixes for 1.1</role>
       </roles>
     </contributor>
+    <contributor>
+      <name>Greg Thomas</name>
+    </contributor>
+    <contributor>
+      <name>Slawek Zachcial</name>
+      <roles>
+        <role>unit tests</role>
+      </roles>
+    </contributor>
+    
   </contributors>
 
   <dependencies>
-    <!-- used for unit tests -->
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
-      <version>3.8.1</version>
+      <version>4.12</version>
       <scope>test</scope>
     </dependency>
   </dependencies>
 
   <properties>
-    <maven.compile.source>1.4</maven.compile.source>
-    <maven.compile.target>1.4</maven.compile.target>
+    <maven.compiler.source>1.5</maven.compiler.source>
+    <maven.compiler.target>1.5</maven.compiler.target>
     <commons.componentid>cli</commons.componentid>
-    <commons.release.version>1.2</commons.release.version>
+    <commons.release.version>1.3.1</commons.release.version>
     <commons.release.name>commons-cli-${commons.release.version}</commons.release.name>
     <commons.osgi.symbolicName>org.apache.commons.cli</commons.osgi.symbolicName>
-    <commons.binary.suffix />
     <commons.jira.id>CLI</commons.jira.id>
     <commons.jira.pid>12310463</commons.jira.pid>
     <!-- The RC version used in the staging repository URL. -->
-    <commons.rc.version>RC7</commons.rc.version>    
+    <commons.rc.version>RC1</commons.rc.version>
+
+    <commons.scmPubCheckoutDirectory>site-content</commons.scmPubCheckoutDirectory>
   </properties>
 
   <build>
-    <sourceDirectory>src/java</sourceDirectory>
-    <testSourceDirectory>src/test</testSourceDirectory>
-    <resources>
-      <resource>
-        <directory>.</directory>
-        <targetPath>META-INF</targetPath>
-        <includes>
-          <include>NOTICE.txt</include>
-          <include>LICENSE.txt</include>
-        </includes>
-      </resource>
-    </resources>
     <plugins>
       <plugin>
         <artifactId>maven-assembly-plugin</artifactId>
@@ -165,75 +189,80 @@
           <tarLongFileMode>gnu</tarLongFileMode>
         </configuration>
       </plugin>
-      <!--
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-ant-plugin</artifactId>
-        <version>2.1.1-SNAPSHOT</version>
-      </plugin>
-      -->
     </plugins>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-scm-publish-plugin</artifactId>
+          <configuration>
+            <ignorePathsToDelete>
+              <ignorePathToDelete>javadocs**</ignorePathToDelete>
+            </ignorePathsToDelete>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
   </build>
 
   <reporting>
     <plugins>
       <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>findbugs-maven-plugin</artifactId>
-        <version>1.2</version>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
         <configuration>
-          <threshold>Normal</threshold>
-          <effort>Default</effort>
+          <linksource>true</linksource>
+          <links>
+            <link>http://download.oracle.com/javase/6/docs/api</link>
+          </links>
         </configuration>
       </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-checkstyle-plugin</artifactId>
+        <version>2.15</version>
         <configuration>
-          <configLocation>src/conf/checkstyle.xml</configLocation>
+          <configLocation>${basedir}/src/conf/checkstyle.xml</configLocation>
+          <enableRulesSummary>false</enableRulesSummary>
+          <suppressionsLocation>${basedir}/src/conf/checkstyle-suppressions.xml</suppressionsLocation>
         </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-pmd-plugin</artifactId>
+        <reportSets>
+          <reportSet>
+            <reports>
+              <report>checkstyle</report>
+            </reports>
+          </reportSet>
+        </reportSets>
       </plugin>
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
-        <artifactId>cobertura-maven-plugin</artifactId>
-        <version>2.2</version>
+        <artifactId>findbugs-maven-plugin</artifactId>
+        <version>3.0.1</version>
+        <configuration>
+          <threshold>Normal</threshold>
+          <effort>Default</effort>
+          <excludeFilterFile>${basedir}/src/conf/findbugs-exclude-filter.xml</excludeFilterFile>
+       </configuration>
       </plugin>
       <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>clirr-maven-plugin</artifactId>
-        <version>2.2.1</version>
+        <artifactId>maven-pmd-plugin</artifactId>
+        <version>3.4</version>
         <configuration>
-          <comparisonVersion>1.1</comparisonVersion>
+          <targetJdk>${maven.compiler.target}</targetJdk>
         </configuration>
       </plugin>
     </plugins>
   </reporting>
 
+  <distributionManagement>
+    <site>
+      <id>apache.website</id>
+      <name>Apache Commons Site</name>
+      <url>scm:svn:${commons.scmPubUrl}</url>
+    </site>
+  </distributionManagement>
 
   <profiles>
-    <!-- Profile to let Gump choose the name of the jar file generated -->
-    <profile>
-      <id>gump</id>
-      <activation>
-        <property>
-          <name>maven.final.name</name>
-        </property>
-      </activation>
-      <build>
-        <plugins>
-          <plugin>
-            <artifactId>maven-jar-plugin</artifactId>
-            <configuration>
-              <finalName>${maven.final.name}</finalName>
-            </configuration>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
     <profile>
       <id>rc</id>
       <distributionManagement>
@@ -245,6 +274,50 @@
         </site>
       </distributionManagement>
     </profile>
+    <profile>
+      <id>setup-checkout</id>
+      <activation>
+        <file>
+          <missing>site-content</missing>
+        </file>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-antrun-plugin</artifactId>
+            <version>1.7</version>
+            <executions>
+              <execution>
+                <id>prepare-checkout</id>
+                <phase>pre-site</phase>
+                <goals>
+                  <goal>run</goal>
+                </goals>
+                <configuration>
+                  <tasks>
+                    <exec executable="svn">
+                      <arg line="checkout --depth immediates ${commons.scmPubUrl} ${commons.scmPubCheckoutDirectory}" />
+                    </exec>
+
+                    <exec executable="svn">
+                      <arg line="update --set-depth exclude ${commons.scmPubCheckoutDirectory}/javadocs" />
+                    </exec>
+
+                    <pathconvert pathsep=" " property="dirs">
+                      <dirset dir="${commons.scmPubCheckoutDirectory}" includes="*" />
+                    </pathconvert>
+                    <exec executable="svn">
+                      <arg line="update --set-depth infinity ${dirs}" />
+                    </exec>
+                  </tasks>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
   </profiles>
 
 </project>
diff --git a/src/assembly/bin.xml b/src/assembly/bin.xml
index 5762291..c8b784f 100644
--- a/src/assembly/bin.xml
+++ b/src/assembly/bin.xml
@@ -27,11 +27,13 @@
                 <include>LICENSE.txt</include>
                 <include>NOTICE.txt</include>
                 <include>RELEASE-NOTES.txt</include>
+                <include>README.md</include>
+                <include>CONTRIBUTING.md</include>
             </includes>
         </fileSet>
         <fileSet>
             <directory>target</directory>
-            <outputDirectory></outputDirectory>
+            <outputDirectory/>
             <includes>
                 <include>*.jar</include>
             </includes>
diff --git a/src/assembly/src.xml b/src/assembly/src.xml
index f3c0bda..9da17bb 100644
--- a/src/assembly/src.xml
+++ b/src/assembly/src.xml
@@ -24,22 +24,16 @@
     <fileSets>
         <fileSet>
             <includes>
-                <include>build.xml</include>
-                <include>build.properties</include>
-                <include>CLI2Converter.java</include>
-                <include>CLI2ConverterTest.java</include>
                 <include>LICENSE.txt</include>
                 <include>NOTICE.txt</include>
                 <include>pom.xml</include>
-                <include>README.txt</include>
                 <include>RELEASE-NOTES.txt</include>
+                <include>README.md</include>
+                <include>CONTRIBUTING.md</include>
             </includes>
         </fileSet>
         <fileSet>
             <directory>src</directory>
         </fileSet>
-        <fileSet>
-            <directory>xdocs</directory>
-        </fileSet>
     </fileSets>
 </assembly>
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
new file mode 100644
index 0000000..875cd11
--- /dev/null
+++ b/src/changes/changes.xml
@@ -0,0 +1,248 @@
+<?xml version="1.0"?>
+<!--
+   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.
+-->
+
+<document>
+  <properties>
+    <title>Commons CLI Release Notes</title>
+  </properties>
+  <body>
+
+    <release version="1.3.1" date="tba" description="Bug fix release for 1.3">
+      <action type="fix" dev="britter" issue="CLI-252" due-to="Simon Harrer">
+        LongOpt falsely detected as ambiguous
+      </action>
+    </release>
+
+    <release version="1.3" date="2015-05-09" description="This is a feature and maintenance bug fix release.">
+      <action type="fix" dev="djones" issue="CLI-248">
+        Fixed broken Javadoc links on Introduction page.
+      </action>
+      <action type="fix" dev="tn" issue="CLI-234" due-to="Greg Thomas">
+        Fixed code example in javadoc of "Option#Builder#valueSeparator(char)".
+      </action>
+      <action type="fix" dev="tn" issue="CLI-241" due-to="Beluga Behr">
+        Clarified behavior of "OptionValidator#validateOption(String)" in case of null input.
+      </action>
+      <action type="update" dev="tn" issue="CLI-240" due-to="Beluga Behr">
+        Small cleanup of Option class.
+      </action>
+      <action type="update" dev="tn" issue="CLI-231" due-to="Duncan Jones">
+        Removed DoubleCheckedLocking test from checkstyle configuration.
+      </action>
+      <action type="update" dev="tn" issue="CLI-230">
+        Options.getRequiredOptions() now returns an unmodifiable list.
+      </action>
+      <action type="add" dev="tn" issue="CLI-224" due-to="Duncan Jones, Brian Blount">
+        Added new fluent API to create Option instances via builder class Option.Builder.
+        This replaces the now deprecated OptionBuilder.
+      </action>
+      <action type="update" dev="tn" issue="CLI-218" due-to="Sven">
+        Clarify javadoc for CommandLine.getOptionValue() that the first specified
+        argument will be returned.
+      </action>
+      <action type="add" dev="tn" issue="CLI-214" due-to="Alexandru Mocanu">
+        Added new method Options.addOption(String, String).
+      </action>
+      <action type="update" dev="tn" issue="CLI-227" due-to="Duncan Jones">
+        Changed unit tests to junit 4 annotation style.
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-202">
+        Default options will now work correctly with required options that are missing.
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-203">
+        Default options will now work correctly together with option groups.
+      </action>
+      <action type="update" dev="ebourg" issue="CLI-209" due-to="Thomas Herre">
+        The javadoc of OptionBuilder now states that the class is not thread-safe.
+      </action>
+      <action type="add" dev="ebourg" issue="CLI-169" due-to="J. Lewis Muir">
+        HelpFormatter now supports setting the displayed separator of long options.
+      </action>
+      <action type="update" dev="ebourg" issue="CLI-197" due-to="Anders Larsson">
+        Improve description of parameter "stopAtNonOption" in method
+        CommandLine.parse(Options, String[], boolean).
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-204">
+        Passing default values for not defined options to a parser will now trigger
+        a ParseException instead of a NullPointerException.
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-205">
+        HelpFormatter.setArgName(String) now correctly sets the argument name.
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-201">
+        Default properties provided as input to the Parser.parse() methods are now
+        correctly processed.
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-215" due-to="Manuel Müller">
+        CommandLine.getParsedOptionValue() now returns a String object if no
+        option type has been explicitly set.
+      </action>
+      <action type="update" dev="ggregory" issue="CLI-200" due-to="Gerard Weatherby">
+        Fixed typo in javadoc of class CommandLine.
+      </action>
+      <action type="update" dev="ebourg" issue="CLI-223" due-to="Gerard Weatherby">
+        Source code now uses generic types instead of raw types where possible.
+      </action>
+      <action type="update" dev="ebourg" issue="CLI-220" due-to="Joe Casadonte">
+        Corrected javadoc for return type of MissingOptionException.getMissingOptions().
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-212" due-to="Per Cederberg">
+        HelpFormatter now prints command-line options in the same order as they
+        have been added.
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-186" due-to="Kristoff Kiefer">
+        Standard help text now shows mandatory arguments also for the first option.
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-207" due-to="Uri Moszkowicz">
+        HelpFormatter does not strip anymore leading whitespace in the footer text.
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-185" due-to="Einar M R Rosenvinge">
+        Strip quotes contained in argument values only if there is exactly one at the
+        beginning and one at the end.
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-184">
+        Negative numerical arguments take precedence over numerical options (only supported
+        by the new DefaultParser).
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-193" due-to="Travis McLeskey">
+        Fix possible StringIndexOutOfBoundsException in HelpFormatter.
+      </action>
+      <action type="add" dev="ebourg" issue="CLI-161,CLI-167,CLI-181">
+        A new parser is available: DefaultParser. It combines the features of the GnuParser and the PosixParser.
+        It also provides additional features like partial matching for the long options, and long options without
+        separator (i.e like the JVM memory settings: -Xmx512m). This new parser deprecates the previous ones.
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-183">
+        OptionGroups no longer throw an AlreadySelectedException when reused for several parsings.
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-182">
+        OptionGroup now selects properly an option with no short name.
+      </action>
+      <action type="add" dev="ebourg" issue="CLI-160">
+        PosixParser now supports partial long options (--ver instead of --version).
+      </action>
+    </release>
+
+    <release version="1.2" date="2009-03-19" description="This is a maintenance release containing bug fixes.">
+      <action type="fix" dev="joehni" issue="CLI-177">
+        OptionBuilder is now reseted if an IllegalArgumentException occurs in create().
+      </action>
+      <action type="remove" dev="bayard">
+        Ant build system removed. 
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-154">
+        Incomplete usage documentation about Java property option.
+      </action>
+      <action type="fix" dev="bayard" issue="CLI-170">
+        TypeHandler prints messages to stderr.
+      </action>
+      <action type="fix" dev="bayard" issue="CLI-162">
+        Infinite loop in the wrapping code of HelpFormatter.
+      </action>
+      <action type="fix" dev="sgoeschl">
+        Fixing some minor javadoc issues.
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-137">
+        The number of arguments defined for an option specifies the arguments per occurrence of the option
+        and not for all occurrences. This was a major regression in CLI 1.1 which prevented the use of repeated options.
+      </action>
+      <action type="add" dev="ebourg">
+        Added a getOptionProperties() method in the CommandLine class to retrieve easily the key/value pairs
+        specified with options like -Dkey1=value1 -Dkey2=value2.
+      </action>
+      <action type="update" dev="ebourg" issue="CLI-157">
+        GnuParser now supports long options with an '=' sign (ie. --foo=bar and -foo=bar)
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-164">
+        PosixParser no longer ignores unrecognized short options.
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-163">
+        PosixParser no longer stops the bursting process of a token if stopAtNonOption is enabled and a non option
+        character is encountered.
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-165">
+        PosixParser no longer keeps processing the tokens after an unrecognized long option
+        when stopAtNonOption is enabled.
+      </action>
+      <action type="fix" dev="ebourg" issue="CLI-156">
+        Required options are properly checked if an Options instance is used twice to parse a command line.
+      </action>
+      <action type="update" dev="bayard" issue="CLI-155">
+        The ordering of options can be defined in help messages.
+      </action>
+      <action type="fix" dev="bayard" issue="CLI-151" due-to="Dan Armbrust">
+        The line wrapping in HelpFormatter now works properly. This caused CLI-162, and thus there was a feature change 
+        for the HelpFormatter in that it is strict on width now rather than what seemed to be lenience before. Text without 
+        whitespace will be cut off to fit in the spacing, and an IllegalStateException will be thrown if it is impossible 
+        to output the information due to spacing constraints. 
+      </action>
+      <action type="fix" dev="bayard" issue="CLI-149">
+        The message of MissingOptionException has been improved.
+      </action>
+      <action type="update" dev="ebourg" issue="CLI-86">
+        The exceptions have been enhanced with methods to retrieve easily the related options.
+      </action>
+      <action type="fix" dev="bayard" issue="CLI-141" due-to="Henning Schmiedehausen, Bjorn Townsend">
+        Option.toString() now reports arguments properly.
+      </action>
+      <action type="update" dev="bayard" issue="CLI-142" due-to="Henning Schmiedehausen">
+        The Parser class has been changed to be more easily extendable.
+      </action>
+      <action type="update" dev="bayard" issue="CLI-140">
+        The following classes are now serializable: Option, OptionGroup, CommandLine and Options.
+      </action>
+      <action type="remove" dev="ebourg">
+        OptionValidator is no longer public, its methods were all private.
+      </action>
+    </release>
+
+    <release version="1.1" date="2007-07-08" description="This is a maintenance release containing bug fixes.">
+      <action type="fix" issue="CLI-2">Wrong usage summary. </action>
+      <action type="fix" issue="CLI-5">Dependecy on commons-lang-2.0 but commons-lang-1.0 is obtained. </action>
+      <action type="fix" issue="CLI-8">Line separator as first char for helpformatter (footer) throws exception. </action>
+      <action type="fix" issue="CLI-13">CommandLine.getOptionValue() behaves contrary to docs. </action>
+      <action type="fix" issue="CLI-21">clone method in Option should use super.clone(). </action>
+      <action type="fix" issue="CLI-23">Passing properties in Parser does not work for options with a single argument. </action>
+      <action type="fix" issue="CLI-26">Only long options without short option seems to be noticed. </action>
+      <action type="fix" issue="CLI-28">Infinite Loop in Command-Line processing. </action>
+      <action type="fix" issue="CLI-29">Options should not be able to be added more than once. </action>
+      <action type="fix" issue="CLI-35">HelpFormatter doesn't sort options properly. </action>
+      <action type="fix" issue="CLI-38">HelpFormatter doesn't function correctly for options with only LongOpt. </action>
+      <action type="fix" issue="CLI-44">Document enhancement. </action>
+      <action type="fix" issue="CLI-45">Documentation errors. </action>
+      <action type="fix" issue="CLI-51">Parameter value "-something" misinterpreted as a parameter. </action>
+      <action type="fix" issue="CLI-56">clone() method doesn't fully clone contents. </action>
+      <action type="fix" issue="CLI-59">No Javadoc for HelpFormatter!. </action>
+      <action type="fix" issue="CLI-65">Parser breaks up command line parms into single characters. </action>
+      <action type="fix" issue="CLI-67">Missing arguments in HelpFormatter.renderOptions(..). </action>
+      <action type="fix" issue="CLI-69">Error parsing option arguments. </action>
+      <action type="fix" issue="CLI-71">A weakness of parser. </action>
+      <action type="add" issue="CLI-78">Setting description of a Option. </action>
+      <action type="fix" issue="CLI-129">CLI_1_BRANCH build.xml doesn't work. </action>
+      <action type="fix" issue="CLI-130">Remove the Commons Lang dependency. </action>
+      <action type="fix" issue="CLI-131">Options class returns options in random order. </action>
+      <action type="fix" issue="CLI-132">MissingOptionException should contain a useful error message. </action>
+      <action type="fix" issue="CLI-133">NullPointerException in Util.stripLeadingHyphens when passed a null argument. </action>
+      <action type="fix" issue="CLI-134">1.1 is not backwards compatible because it adds methods to the CommandLineParser interface. </action>
+      <action type="fix" issue="CLI-135">Backwards compatibility between 1.1 and 1.0 broken due to Option.addValue removal. </action>
+    </release>
+
+    <release version="1.0" date="2002-11-06" description="Initial release"/>    
+
+  </body>
+</document>
diff --git a/src/conf/MANIFEST.MF b/src/conf/MANIFEST.MF
deleted file mode 100644
index cd23a6e..0000000
--- a/src/conf/MANIFEST.MF
+++ /dev/null
@@ -1,21 +0,0 @@
-Manifest-Version: 1.0
-Implementation-Title: Commons CLI
-Implementation-Vendor: The Apache Software Foundation
-Implementation-Vendor-Id: org.apache
-Implementation-Version: 1.2-SNAPSHOT
-Specification-Title: Commons CLI
-Specification-Vendor: The Apache Software Foundation
-Specification-Version: 1.2-SNAPSHOT
-X-Compile-Source-JDK: 1.3
-X-Compile-Target-JDK: 1.3
-Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
-Import-Package: org.apache.commons.cli;version="1.2.0.SNAPSHOT"
-Export-Package: org.apache.commons.cli;version="1.2.0.SNAPSHOT"
-Bundle-Version: 1.2.0.SNAPSHOT
-Bundle-Name: Commons CLI
-Bundle-Description: Commons CLI provides a simple API for presenting,
- processing and validating a command line interface.
-Bundle-DocURL: http://commons.apache.org/cli/
-Bundle-ManifestVersion: 2
-Bundle-Vendor: The Apache Software Foundation
-Bundle-SymbolicName: org.apache.commons.cli
diff --git a/src/conf/checkstyle-suppressions.xml b/src/conf/checkstyle-suppressions.xml
new file mode 100644
index 0000000..46d9635
--- /dev/null
+++ b/src/conf/checkstyle-suppressions.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!DOCTYPE suppressions PUBLIC "-//Puppy Crawl//DTD Suppressions 1.0//EN" "http://www.puppycrawl.com/dtds/suppressions_1_0.dtd">
+<!--
+   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.
+-->
+
+<suppressions>
+
+  <!-- Suppress visibility check of some member fields as they have to be kept
+       for binary compatibility reasons                                         -->
+  <suppress checks="VisibilityModifier" files="HelpFormatter.java" />
+
+  <!-- Cannot hide public constructor due to binary compatibility reasons       -->
+  <suppress checks="HideUtilityClassConstructor" files="PatternOptionBuilder.java" />
+  <suppress checks="HideUtilityClassConstructor" files="TypeHandler.java" />
+
+  <!-- Constant used in hashCode() method                                       -->
+  <suppress checks="MagicNumber" files="Option.java" />
+
+  <!-- These are final package private classes, and we do not want to hide the
+       constructor as this will negatively affect the code coverage             -->
+  <suppress checks="HideUtilityClassConstructor" files="OptionValidator.java" />
+  <suppress checks="HideUtilityClassConstructor" files="Util.java" />
+
+</suppressions>
diff --git a/src/conf/checkstyle.xml b/src/conf/checkstyle.xml
index b027be6..1daf46a 100644
--- a/src/conf/checkstyle.xml
+++ b/src/conf/checkstyle.xml
@@ -24,10 +24,11 @@ limitations under the License.
 
 <module name="Checker">
     <property name="localeLanguage" value="en"/>
+    <property name="severity" value="warning"/>
 
     <!-- Checks that a package.html file exists for each package.     -->
-    <!-- See http://checkstyle.sf.net/config_javadoc.html#PackageHtml -->
-    <module name="PackageHtml"/>
+    <!-- See http://checkstyle.sourceforge.net/config_javadoc.html#JavadocPackage -->
+    <module name="JavadocPackage"/>
 
     <!-- Checks whether files end with a new line.                        -->
     <!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile -->
@@ -38,11 +39,13 @@ limitations under the License.
     <module name="Translation"/>
 
     <!-- Exceptions -->
-    <!--
     <module name="SuppressionFilter">
-        <property name="file" value="conf/checkstyle-suppressions.xml"/>
+        <property name="file" value="${checkstyle.suppressions.file}"/>
+    </module>
+
+    <module name="FileTabCharacter">
+      <property name="eachLine" value="true"/>
     </module>
-    -->
 
     <module name="TreeWalker">
 
@@ -55,9 +58,7 @@ limitations under the License.
             <property name="allowUndeclaredRTE" value="true"/>
             <property name="allowMissingJavadoc" value="true"/>
         </module>
-        <module name="JavadocType">
-            <property name="authorFormat" value="\S"/>
-        </module>
+        <module name="JavadocType"/>
         <module name="JavadocVariable"/>
 
 
@@ -73,17 +74,6 @@ limitations under the License.
         <module name="StaticVariableName"/>
         <module name="TypeName"/>
 
-
-        <!-- Checks for Headers                              -->
-        <!-- See http://checkstyle.sf.net/config_header.html -->
-        <module name="Header">
-            <property name="headerFile" value="src/conf/HEADER.txt"/>
-        </module>
-
-        <!-- Following interprets the header file as regular expressions. -->
-        <!-- <module name="RegexpHeader"/>                                -->
-
-
         <!-- Checks for imports                              -->
         <!-- See http://checkstyle.sf.net/config_import.html -->
         <module name="AvoidStarImport"/>
@@ -99,7 +89,9 @@ limitations under the License.
             <property name="max" value="120"/>
         </module>
         <module name="MethodLength"/>
-        <module name="ParameterNumber"/>
+        <module name="ParameterNumber">
+            <property name="max" value="9"/>
+        </module>
 
 
         <!-- Checks for whitespace                               -->
@@ -109,24 +101,23 @@ limitations under the License.
         <module name="NoWhitespaceBefore"/>
         <module name="OperatorWrap"/>
         <module name="ParenPad"/>
-        <module name="TabCharacter"/>
+
         <module name="WhitespaceAfter"/>
         <module name="WhitespaceAround">
           <property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, EQUAL, GE, GT, LAND, LCURLY, LE, LITERAL_ASSERT, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN, LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, RCURLY, SL, SLIST, SL_ASSIGN, SR, SR_ASSIGN, STAR, STAR_ASSIGN [...]
         </module>
 
-
-
         <!-- Modifier Checks                                    -->
         <!-- See http://checkstyle.sf.net/config_modifiers.html -->
         <module name="ModifierOrder"/>
         <module name="RedundantModifier"/>
 
-
         <!-- Checks for blocks. You know, those {}'s         -->
         <!-- See http://checkstyle.sf.net/config_blocks.html -->
         <module name="AvoidNestedBlocks"/>
-        <module name="EmptyBlock"/>
+        <module name="EmptyBlock">
+            <property name="option" value="text"/>        
+        </module>
         <module name="LeftCurly">
             <property name="option" value="nl"/>
         </module>
@@ -135,11 +126,9 @@ limitations under the License.
             <property name="option" value="alone"/>
         </module>
 
-
         <!-- Checks for common coding problems               -->
         <!-- See http://checkstyle.sf.net/config_coding.html -->
         <module name="CovariantEquals"/>
-        <module name="DoubleCheckedLocking"/>
         <module name="EqualsHashCode"/>
         <module name="IllegalInstantiation"/>
         <module name="InnerAssignment"/>
@@ -170,8 +159,6 @@ limitations under the License.
             <property name="protectedAllowed" value="true"/>
         </module>
 
-
-
         <!-- Miscellaneous other checks.                   -->
         <!-- See http://checkstyle.sf.net/config_misc.html -->
         <module name="ArrayTypeStyle"/>
diff --git a/src/conf/findbugs-exclude-filter.xml b/src/conf/findbugs-exclude-filter.xml
new file mode 100644
index 0000000..975e290
--- /dev/null
+++ b/src/conf/findbugs-exclude-filter.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+   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.
+-->
+
+<!--
+  This file contains some false positive bugs detected by findbugs. Their
+  false positive nature has been analyzed individually and they have been
+  put here to instruct findbugs it must ignore them.
+-->
+<FindBugsFilter>
+
+  <!--  default encoding is intended when writing to System.out -->
+  <Match>
+    <Class name="org.apache.commons.cli.HelpFormatter" />
+    <Method name="printHelp"
+            params="int,java.lang.String,java.lang.String,org.apache.commons.cli.Options,java.lang.String,boolean" returns="void" />
+    <Bug pattern="DM_DEFAULT_ENCODING" />
+  </Match>
+
+</FindBugsFilter>
diff --git a/src/java/org/apache/commons/cli/AlreadySelectedException.java b/src/main/java/org/apache/commons/cli/AlreadySelectedException.java
similarity index 91%
rename from src/java/org/apache/commons/cli/AlreadySelectedException.java
rename to src/main/java/org/apache/commons/cli/AlreadySelectedException.java
index a5ed661..7078cd7 100644
--- a/src/java/org/apache/commons/cli/AlreadySelectedException.java
+++ b/src/main/java/org/apache/commons/cli/AlreadySelectedException.java
@@ -21,11 +21,15 @@ package org.apache.commons.cli;
  * Thrown when more than one option in an option group
  * has been provided.
  *
- * @author John Keyes ( john at integralsource.com )
- * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ * @version $Id: AlreadySelectedException.java 1443102 2013-02-06 18:12:16Z tn $
  */
 public class AlreadySelectedException extends ParseException
 {
+    /**
+     * This exception {@code serialVersionUID}.
+     */
+    private static final long serialVersionUID = 3674381532418544760L;
+
     /** The option group selected. */
     private OptionGroup group;
 
diff --git a/src/main/java/org/apache/commons/cli/AmbiguousOptionException.java b/src/main/java/org/apache/commons/cli/AmbiguousOptionException.java
new file mode 100644
index 0000000..92d87f0
--- /dev/null
+++ b/src/main/java/org/apache/commons/cli/AmbiguousOptionException.java
@@ -0,0 +1,88 @@
+/**
+ * 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.Collection;
+import java.util.Iterator;
+
+/**
+ * Exception thrown when an option can't be identified from a partial name.
+ * 
+ * @version $Id: AmbiguousOptionException.java 1669814 2015-03-28 18:09:26Z britter $
+ * @since 1.3
+ */
+public class AmbiguousOptionException extends UnrecognizedOptionException
+{
+    /**
+     * This exception {@code serialVersionUID}.
+     */
+    private static final long serialVersionUID = 5829816121277947229L;
+
+    /** The list of options matching the partial name specified */
+    private final Collection<String> matchingOptions;
+
+    /**
+     * Constructs a new AmbiguousOptionException.
+     *
+     * @param option          the partial option name
+     * @param matchingOptions the options matching the name
+     */
+    public AmbiguousOptionException(String option, Collection<String> matchingOptions)
+    {
+        super(createMessage(option, matchingOptions), option);
+        this.matchingOptions = matchingOptions;
+    }
+
+    /**
+     * Returns the options matching the partial name.
+     * @return a collection of options matching the name
+     */
+    public Collection<String> getMatchingOptions()
+    {
+        return matchingOptions;
+    }
+
+    /**
+     * Build the exception message from the specified list of options.
+     * 
+     * @param option
+     * @param matchingOptions
+     * @return
+     */
+    private static String createMessage(String option, Collection<String> matchingOptions)
+    {
+        StringBuilder buf = new StringBuilder("Ambiguous option: '");
+        buf.append(option);
+        buf.append("'  (could be: ");
+
+        Iterator<String> it = matchingOptions.iterator();
+        while (it.hasNext())
+        {
+            buf.append("'");
+            buf.append(it.next());
+            buf.append("'");
+            if (it.hasNext())
+            {
+                buf.append(", ");
+            }
+        }
+        buf.append(")");
+
+        return buf.toString();
+    }
+}
diff --git a/src/java/org/apache/commons/cli/BasicParser.java b/src/main/java/org/apache/commons/cli/BasicParser.java
similarity index 83%
rename from src/java/org/apache/commons/cli/BasicParser.java
rename to src/main/java/org/apache/commons/cli/BasicParser.java
index a89a84a..d1c1c0e 100644
--- a/src/java/org/apache/commons/cli/BasicParser.java
+++ b/src/main/java/org/apache/commons/cli/BasicParser.java
@@ -21,9 +21,10 @@ package org.apache.commons.cli;
  * The class BasicParser provides a very simple implementation of
  * the {@link Parser#flatten(Options,String[],boolean) flatten} method.
  *
- * @author John Keyes (john at integralsource.com)
- * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ * @version $Id: BasicParser.java 1443102 2013-02-06 18:12:16Z tn $
+ * @deprecated since 1.3, use the {@link DefaultParser} instead
  */
+ at Deprecated
 public class BasicParser extends Parser
 {
     /**
@@ -39,7 +40,10 @@ 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)
+    @Override
+    protected String[] flatten(@SuppressWarnings("unused") Options options,
+            String[] arguments,
+            @SuppressWarnings("unused") boolean stopAtNonOption)
     {
         // just echo the arguments
         return arguments;
diff --git a/src/java/org/apache/commons/cli/CommandLine.java b/src/main/java/org/apache/commons/cli/CommandLine.java
similarity index 82%
rename from src/java/org/apache/commons/cli/CommandLine.java
rename to src/main/java/org/apache/commons/cli/CommandLine.java
index 14137af..bac7bcd 100644
--- a/src/java/org/apache/commons/cli/CommandLine.java
+++ b/src/main/java/org/apache/commons/cli/CommandLine.java
@@ -27,33 +27,31 @@ import java.util.Properties;
 
 /**
  * Represents list of arguments parsed against a {@link Options} descriptor.
- *
- * <p>It allows querying of a boolean {@link #hasOption(String opt)},
+ * <p>
+ * It allows querying of a boolean {@link #hasOption(String opt)},
  * in addition to retrieving the {@link #getOptionValue(String opt)}
- * for options requiring arguments.</p>
- *
- * <p>Additionally, any left-over or unrecognized arguments,
- * are available for further processing.</p>
+ * for options requiring arguments.
+ * <p>
+ * Additionally, any left-over or unrecognized arguments,
+ * are available for further processing.
  *
- * @author bob mcwhirter (bob @ werken.com)
- * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
- * @author John Keyes (john at integralsource.com)
- * @version $Revision: 735247 $, $Date: 2009-01-17 00:23:35 -0800 (Sat, 17 Jan 2009) $
+ * @version $Id: CommandLine.java 1444365 2013-02-09 14:21:27Z tn $
  */
 public class CommandLine implements Serializable
 {
+    /** The serial version UID. */
     private static final long serialVersionUID = 1L;
 
     /** the unrecognised options/arguments */
-    private List args = new LinkedList();
+    private final List<String> args = new LinkedList<String>();
 
     /** the processed options */
-    private List options = new ArrayList();
+    private final List<Option> options = new ArrayList<Option>();
 
     /**
      * Creates a command line.
      */
-    CommandLine()
+    protected CommandLine()
     {
         // nothing to do
     }
@@ -87,13 +85,16 @@ public class CommandLine implements Serializable
      * @return the type of this <code>Option</code>
      * @deprecated due to System.err message. Instead use getParsedOptionValue(String)
      */
+    @Deprecated
     public Object getOptionObject(String opt)
     {
-        try {
+        try
+        {
             return getParsedOptionValue(opt);
-        } catch(ParseException pe) {
-            System.err.println("Exception found converting " + opt + " to desired type: " + 
-                pe.getMessage() );
+        }
+        catch (ParseException pe)
+        {
+            System.err.println("Exception found converting " + opt + " to desired type: " + pe.getMessage());
             return null;
         }
     }
@@ -102,24 +103,22 @@ public class CommandLine implements Serializable
      * Return a version of this <code>Option</code> converted to a particular type. 
      *
      * @param opt the name of the option
-     * @return the value parsed into a particluar object
+     * @return the value parsed into a particular object
      * @throws ParseException if there are problems turning the option value into the desired type
      * @see PatternOptionBuilder
+     * @since 1.2
      */
-    public Object getParsedOptionValue(String opt)
-    throws ParseException
+    public Object getParsedOptionValue(String opt) throws ParseException
     {
         String res = getOptionValue(opt);
-
         Option option = resolveOption(opt);
-        if (option == null)
+        
+        if (option == null || res == null)
         {
             return null;
         }
-
-        Object type = option.getType();
-
-        return (res == null)        ? null : TypeHandler.createValue(res, type);
+        
+        return TypeHandler.createValue(res, option.getType());
     }
 
     /**
@@ -134,7 +133,7 @@ public class CommandLine implements Serializable
     }
 
     /** 
-     * Retrieve the argument, if any, of this option.
+     * Retrieve the first 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,
@@ -148,7 +147,7 @@ public class CommandLine implements Serializable
     }
 
     /** 
-     * Retrieve the argument, if any, of this option.
+     * Retrieve the first 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,
@@ -168,18 +167,17 @@ public class CommandLine implements Serializable
      */
     public String[] getOptionValues(String opt)
     {
-        List values = new ArrayList();
+        List<String> values = new ArrayList<String>();
 
-        for (Iterator it = options.iterator(); it.hasNext();)
+        for (Option option : options)
         {
-            Option option = (Option) it.next();
             if (opt.equals(option.getOpt()) || opt.equals(option.getLongOpt()))
             {
                 values.addAll(option.getValuesList());
             }
         }
 
-        return values.isEmpty() ? null : (String[]) values.toArray(new String[values.size()]);
+        return values.isEmpty() ? null : values.toArray(new String[values.size()]);
     }
 
     /**
@@ -191,9 +189,8 @@ public class CommandLine implements Serializable
     private Option resolveOption(String opt)
     {
         opt = Util.stripLeadingHyphens(opt);
-        for (Iterator it = options.iterator(); it.hasNext();)
+        for (Option option : options)
         {
-            Option option = (Option) it.next();
             if (opt.equals(option.getOpt()))
             {
                 return option;
@@ -221,7 +218,7 @@ public class CommandLine implements Serializable
     }
 
     /** 
-     * Retrieve the argument, if any, of an option.
+     * Retrieve the first argument, if any, of an option.
      *
      * @param opt name of the option
      * @param defaultValue is the default value to be returned if the option
@@ -267,13 +264,11 @@ public class CommandLine implements Serializable
     {
         Properties props = new Properties();
 
-        for (Iterator it = options.iterator(); it.hasNext();)
+        for (Option option : options)
         {
-            Option option = (Option) it.next();
-
             if (opt.equals(option.getOpt()) || opt.equals(option.getLongOpt()))
             {
-                List values = option.getValuesList();
+                List<String> values = option.getValuesList();
                 if (values.size() >= 2)
                 {
                     // use the first 2 arguments as the key/value pair
@@ -309,7 +304,7 @@ public class CommandLine implements Serializable
      *
      * @return remaining items passed in but not parsed as a <code>List</code>.
      */
-    public List getArgList()
+    public List<String> getArgList()
     {
         return args;
     }
@@ -324,7 +319,7 @@ public class CommandLine implements Serializable
 
     /*
     public String toString() {
-        StringBuffer buf = new StringBuffer();
+        StringBuilder buf = new StringBuilder();
             
         buf.append("[ CommandLine: [ options: ");
         buf.append(options.toString());
@@ -341,7 +336,7 @@ public class CommandLine implements Serializable
      *
      * @param arg the unrecognised option/argument.
      */
-    void addArg(String arg)
+    protected void addArg(String arg)
     {
         args.add(arg);
     }
@@ -351,7 +346,7 @@ public class CommandLine implements Serializable
      *
      * @param opt the processed option
      */
-    void addOption(Option opt)
+    protected void addOption(Option opt)
     {
         options.add(opt);
     }
@@ -362,7 +357,7 @@ public class CommandLine implements Serializable
      * @return an <code>Iterator</code> over the processed {@link Option}
      * members of this {@link CommandLine}
      */
-    public Iterator iterator()
+    public Iterator<Option> iterator()
     {
         return options.iterator();
     }
@@ -374,12 +369,12 @@ public class CommandLine implements Serializable
      */
     public Option[] getOptions()
     {
-        Collection processed = options;
+        Collection<Option> processed = options;
 
         // reinitialise array
         Option[] optionsArray = new Option[processed.size()];
 
         // return the array
-        return (Option[]) processed.toArray(optionsArray);
+        return processed.toArray(optionsArray);
     }
 }
diff --git a/src/java/org/apache/commons/cli/CommandLineParser.java b/src/main/java/org/apache/commons/cli/CommandLineParser.java
similarity index 84%
rename from src/java/org/apache/commons/cli/CommandLineParser.java
rename to src/main/java/org/apache/commons/cli/CommandLineParser.java
index f507231..5b1bd83 100644
--- a/src/java/org/apache/commons/cli/CommandLineParser.java
+++ b/src/main/java/org/apache/commons/cli/CommandLineParser.java
@@ -22,8 +22,7 @@ package org.apache.commons.cli;
  * can parse a String array according to the {@link Options} specified
  * and return a {@link CommandLine}.
  *
- * @author John Keyes (john at integralsource.com)
- * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ * @version $Id: CommandLineParser.java 1443102 2013-02-06 18:12:16Z tn $
  */
 public interface CommandLineParser
 {
@@ -63,8 +62,10 @@ public interface CommandLineParser
      *
      * @param options the specified Options
      * @param arguments the command line arguments
-     * @param stopAtNonOption specifies whether to continue parsing the
-     * arguments if a non option is encountered.
+     * @param stopAtNonOption if <tt>true</tt> an unrecognized argument stops
+     *     the parsing and the remaining arguments are added to the 
+     *     {@link CommandLine}s args list. If <tt>false</tt> an unrecognized
+     *     argument triggers a ParseException.
      *
      * @return the list of atomic option and value tokens
      * @throws ParseException if there are any problems encountered
@@ -79,7 +80,10 @@ public interface CommandLineParser
      * @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
+     * @param stopAtNonOption if <tt>true</tt> an unrecognized argument stops
+     *     the parsing and the remaining arguments are added to the 
+     *     {@link CommandLine}s args list. If <tt>false</tt> an unrecognized
+     *     argument triggers a ParseException.
      *
      * @return the list of atomic option and value tokens
      * @throws ParseException if there are any problems encountered
diff --git a/src/main/java/org/apache/commons/cli/DefaultParser.java b/src/main/java/org/apache/commons/cli/DefaultParser.java
new file mode 100644
index 0000000..4d0e0ab
--- /dev/null
+++ b/src/main/java/org/apache/commons/cli/DefaultParser.java
@@ -0,0 +1,694 @@
+/**
+ * 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.Enumeration;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * Default parser.
+ * 
+ * @version $Id: DefaultParser.java 1677454 2015-05-03 17:13:54Z ggregory $
+ * @since 1.3
+ */
+public class DefaultParser implements CommandLineParser
+{
+    /** The command-line instance. */
+    protected CommandLine cmd;
+    
+    /** The current options. */
+    protected Options options;
+
+    /**
+     * Flag indicating how unrecognized tokens are handled. <tt>true</tt> to stop
+     * the parsing and add the remaining tokens to the args list.
+     * <tt>false</tt> to throw an exception. 
+     */
+    protected boolean stopAtNonOption;
+
+    /** The token currently processed. */
+    protected String currentToken;
+ 
+    /** The last option parsed. */
+    protected Option currentOption;
+ 
+    /** Flag indicating if tokens should no longer be analyzed and simply added as arguments of the command line. */
+    protected boolean skipParsing;
+ 
+    /** The required options and groups expected to be found when parsing the command line. */
+    protected List expectedOpts;
+ 
+    public CommandLine parse(Options options, String[] arguments) throws ParseException
+    {
+        return parse(options, arguments, null);
+    }
+
+    /**
+     * 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, properties, false);
+    }
+
+    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 if <tt>true</tt> an unrecognized argument stops
+     *     the parsing and the remaining arguments are added to the 
+     *     {@link CommandLine}s args list. If <tt>false</tt> an unrecognized
+     *     argument triggers a ParseException.
+     *
+     * @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
+    {
+        this.options = options;
+        this.stopAtNonOption = stopAtNonOption;
+        skipParsing = false;
+        currentOption = null;
+        expectedOpts = new ArrayList(options.getRequiredOptions());
+
+        // clear the data from the groups
+        for (OptionGroup group : options.getOptionGroups())
+        {
+            group.setSelected(null);
+        }
+
+        cmd = new CommandLine();
+
+        if (arguments != null)
+        {
+            for (String argument : arguments)
+            {
+                handleToken(argument);
+            }
+        }
+
+        // check the arguments of the last option
+        checkRequiredArgs();
+
+        // add the default options
+        handleProperties(properties);
+
+        checkRequiredOptions();
+
+        return cmd;
+    }
+
+    /**
+     * Sets the values of Options using the values in <code>properties</code>.
+     *
+     * @param properties The value properties to be processed.
+     */
+    private void handleProperties(Properties properties) throws ParseException
+    {
+        if (properties == null)
+        {
+            return;
+        }
+
+        for (Enumeration<?> e = properties.propertyNames(); e.hasMoreElements();)
+        {
+            String option = e.nextElement().toString();
+
+            Option opt = options.getOption(option);
+            if (opt == null)
+            {
+                throw new UnrecognizedOptionException("Default option wasn't defined", option);
+            }
+
+            // if the option is part of a group, check if another option of the group has been selected
+            OptionGroup group = options.getOptionGroup(opt);
+            boolean selected = group != null && group.getSelected() != null;
+
+            if (!cmd.hasOption(option) && !selected)
+            {
+                // get the value from the properties
+                String value = properties.getProperty(option);
+
+                if (opt.hasArg())
+                {
+                    if (opt.getValues() == null || opt.getValues().length == 0)
+                    {
+                        opt.addValueForProcessing(value);
+                    }
+                }
+                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
+                    continue;
+                }
+
+                handleOption(opt);
+                currentOption = null;
+            }
+        }
+    }
+
+    /**
+     * Throws a {@link MissingOptionException} if all of the required options
+     * are not present.
+     *
+     * @throws MissingOptionException if any of the required Options
+     * are not present.
+     */
+    private void checkRequiredOptions() throws MissingOptionException
+    {
+        // if there are required options that have not been processed
+        if (!expectedOpts.isEmpty())
+        {
+            throw new MissingOptionException(expectedOpts);
+        }
+    }
+
+    /**
+     * Throw a {@link MissingArgumentException} if the current option
+     * didn't receive the number of arguments expected.
+     */
+    private void checkRequiredArgs() throws ParseException
+    {
+        if (currentOption != null && currentOption.requiresArg())
+        {
+            throw new MissingArgumentException(currentOption);
+        }
+    }
+
+    /**
+     * Handle any command line token.
+     *
+     * @param token the command line token to handle
+     * @throws ParseException
+     */
+    private void handleToken(String token) throws ParseException
+    {
+        currentToken = token;
+
+        if (skipParsing)
+        {
+            cmd.addArg(token);
+        }
+        else if ("--".equals(token))
+        {
+            skipParsing = true;
+        }
+        else if (currentOption != null && currentOption.acceptsArg() && isArgument(token))
+        {
+            currentOption.addValueForProcessing(Util.stripLeadingAndTrailingQuotes(token));
+        }
+        else if (token.startsWith("--"))
+        {
+            handleLongOption(token);
+        }
+        else if (token.startsWith("-") && !"-".equals(token))
+        {
+            handleShortAndLongOption(token);
+        }
+        else
+        {
+            handleUnknownToken(token);
+        }
+
+        if (currentOption != null && !currentOption.acceptsArg())
+        {
+            currentOption = null;
+        }
+    }
+
+    /**
+     * Returns true is the token is a valid argument.
+     *
+     * @param token
+     */
+    private boolean isArgument(String token)
+    {
+        return !isOption(token) || isNegativeNumber(token);
+    }
+
+    /**
+     * Check if the token is a negative number.
+     *
+     * @param token
+     */
+    private boolean isNegativeNumber(String token)
+    {
+        try
+        {
+            Double.parseDouble(token);
+            return true;
+        }
+        catch (NumberFormatException e)
+        {
+            return false;
+        }
+    }
+
+    /**
+     * Tells if the token looks like an option.
+     *
+     * @param token
+     */
+    private boolean isOption(String token)
+    {
+        return isLongOption(token) || isShortOption(token);
+    }
+
+    /**
+     * Tells if the token looks like a short option.
+     * 
+     * @param token
+     */
+    private boolean isShortOption(String token)
+    {
+        // short options (-S, -SV, -S=V, -SV1=V2, -S1S2)
+        return token.startsWith("-") && token.length() >= 2 && options.hasShortOption(token.substring(1, 2));
+    }
+
+    /**
+     * Tells if the token looks like a long option.
+     *
+     * @param token
+     */
+    private boolean isLongOption(String token)
+    {
+        if (!token.startsWith("-") || token.length() == 1)
+        {
+            return false;
+        }
+
+        int pos = token.indexOf("=");
+        String t = pos == -1 ? token : token.substring(0, pos);
+
+        if (!options.getMatchingOptions(t).isEmpty())
+        {
+            // long or partial long options (--L, -L, --L=V, -L=V, --l, --l=V)
+            return true;
+        }
+        else if (getLongPrefix(token) != null && !token.startsWith("--"))
+        {
+            // -LV
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Handles an unknown token. If the token starts with a dash an 
+     * UnrecognizedOptionException is thrown. Otherwise the token is added 
+     * to the arguments of the command line. If the stopAtNonOption flag 
+     * is set, this stops the parsing and the remaining tokens are added 
+     * as-is in the arguments of the command line.
+     *
+     * @param token the command line token to handle
+     */
+    private void handleUnknownToken(String token) throws ParseException
+    {
+        if (token.startsWith("-") && token.length() > 1 && !stopAtNonOption)
+        {
+            throw new UnrecognizedOptionException("Unrecognized option: " + token, token);
+        }
+
+        cmd.addArg(token);
+        if (stopAtNonOption)
+        {
+            skipParsing = true;
+        }
+    }
+
+    /**
+     * Handles the following tokens:
+     *
+     * --L
+     * --L=V
+     * --L V
+     * --l
+     *
+     * @param token the command line token to handle
+     */
+    private void handleLongOption(String token) throws ParseException
+    {
+        if (token.indexOf('=') == -1)
+        {
+            handleLongOptionWithoutEqual(token);
+        }
+        else
+        {
+            handleLongOptionWithEqual(token);
+        }
+    }
+
+    /**
+     * Handles the following tokens:
+     *
+     * --L
+     * -L
+     * --l
+     * -l
+     * 
+     * @param token the command line token to handle
+     */
+    private void handleLongOptionWithoutEqual(String token) throws ParseException
+    {
+        List<String> matchingOpts = options.getMatchingOptions(token);
+        if (matchingOpts.isEmpty())
+        {
+            handleUnknownToken(currentToken);
+        }
+        else if (matchingOpts.size() > 1)
+        {
+            throw new AmbiguousOptionException(token, matchingOpts);
+        }
+        else
+        {
+            handleOption(options.getOption(matchingOpts.get(0)));
+        }
+    }
+
+    /**
+     * Handles the following tokens:
+     *
+     * --L=V
+     * -L=V
+     * --l=V
+     * -l=V
+     *
+     * @param token the command line token to handle
+     */
+    private void handleLongOptionWithEqual(String token) throws ParseException
+    {
+        int pos = token.indexOf('=');
+
+        String value = token.substring(pos + 1);
+
+        String opt = token.substring(0, pos);
+
+        List<String> matchingOpts = options.getMatchingOptions(opt);
+        if (matchingOpts.isEmpty())
+        {
+            handleUnknownToken(currentToken);
+        }
+        else if (matchingOpts.size() > 1)
+        {
+            throw new AmbiguousOptionException(opt, matchingOpts);
+        }
+        else
+        {
+            Option option = options.getOption(matchingOpts.get(0));
+
+            if (option.acceptsArg())
+            {
+                handleOption(option);
+                currentOption.addValueForProcessing(value);
+                currentOption = null;
+            }
+            else
+            {
+                handleUnknownToken(currentToken);
+            }
+        }
+    }
+
+    /**
+     * Handles the following tokens:
+     *
+     * -S
+     * -SV
+     * -S V
+     * -S=V
+     * -S1S2
+     * -S1S2 V
+     * -SV1=V2
+     *
+     * -L
+     * -LV
+     * -L V
+     * -L=V
+     * -l
+     *
+     * @param token the command line token to handle
+     */
+    private void handleShortAndLongOption(String token) throws ParseException
+    {
+        String t = Util.stripLeadingHyphens(token);
+
+        int pos = t.indexOf('=');
+
+        if (t.length() == 1)
+        {
+            // -S
+            if (options.hasShortOption(t))
+            {
+                handleOption(options.getOption(t));
+            }
+            else
+            {
+                handleUnknownToken(token);
+            }
+        }
+        else if (pos == -1)
+        {
+            // no equal sign found (-xxx)
+            if (options.hasShortOption(t))
+            {
+                handleOption(options.getOption(t));
+            }
+            else if (!options.getMatchingOptions(t).isEmpty())
+            {
+                // -L or -l
+                handleLongOptionWithoutEqual(token);
+            }
+            else
+            {
+                // look for a long prefix (-Xmx512m)
+                String opt = getLongPrefix(t);
+
+                if (opt != null && options.getOption(opt).acceptsArg())
+                {
+                    handleOption(options.getOption(opt));
+                    currentOption.addValueForProcessing(t.substring(opt.length()));
+                    currentOption = null;
+                }
+                else if (isJavaProperty(t))
+                {
+                    // -SV1 (-Dflag)
+                    handleOption(options.getOption(t.substring(0, 1)));
+                    currentOption.addValueForProcessing(t.substring(1));
+                    currentOption = null;
+                }
+                else
+                {
+                    // -S1S2S3 or -S1S2V
+                    handleConcatenatedOptions(token);
+                }
+            }
+        }
+        else
+        {
+            // equal sign found (-xxx=yyy)
+            String opt = t.substring(0, pos);
+            String value = t.substring(pos + 1);
+
+            if (opt.length() == 1)
+            {
+                // -S=V
+                Option option = options.getOption(opt);
+                if (option != null && option.acceptsArg())
+                {
+                    handleOption(option);
+                    currentOption.addValueForProcessing(value);
+                    currentOption = null;
+                }
+                else
+                {
+                    handleUnknownToken(token);
+                }
+            }
+            else if (isJavaProperty(opt))
+            {
+                // -SV1=V2 (-Dkey=value)
+                handleOption(options.getOption(opt.substring(0, 1)));
+                currentOption.addValueForProcessing(opt.substring(1));
+                currentOption.addValueForProcessing(value);
+                currentOption = null;
+            }
+            else
+            {
+                // -L=V or -l=V
+                handleLongOptionWithEqual(token);
+            }
+        }
+    }
+
+    /**
+     * Search for a prefix that is the long name of an option (-Xmx512m)
+     *
+     * @param token
+     */
+    private String getLongPrefix(String token)
+    {
+        String t = Util.stripLeadingHyphens(token);
+
+        int i;
+        String opt = null;
+        for (i = t.length() - 2; i > 1; i--)
+        {
+            String prefix = t.substring(0, i);
+            if (options.hasLongOption(prefix))
+            {
+                opt = prefix;
+                break;
+            }
+        }
+        
+        return opt;
+    }
+
+    /**
+     * Check if the specified token is a Java-like property (-Dkey=value).
+     */
+    private boolean isJavaProperty(String token)
+    {
+        String opt = token.substring(0, 1);
+        Option option = options.getOption(opt);
+
+        return option != null && (option.getArgs() >= 2 || option.getArgs() == Option.UNLIMITED_VALUES);
+    }
+
+    private void handleOption(Option option) throws ParseException
+    {
+        // check the previous option before handling the next one
+        checkRequiredArgs();
+
+        option = (Option) option.clone();
+
+        updateRequiredOptions(option);
+
+        cmd.addOption(option);
+
+        if (option.hasArg())
+        {
+            currentOption = option;
+        }
+        else
+        {
+            currentOption = null;
+        }
+    }
+
+    /**
+     * Removes the option or its group from the list of expected elements.
+     *
+     * @param option
+     */
+    private void updateRequiredOptions(Option option) throws AlreadySelectedException
+    {
+        if (option.isRequired())
+        {
+            expectedOpts.remove(option.getKey());
+        }
+
+        // if the option is in an OptionGroup make that option the selected option of the group
+        if (options.getOptionGroup(option) != null)
+        {
+            OptionGroup group = options.getOptionGroup(option);
+
+            if (group.isRequired())
+            {
+                expectedOpts.remove(group);
+            }
+
+            group.setSelected(option);
+        }
+    }
+
+    /**
+     * Breaks <code>token</code> into its constituent parts
+     * using the following algorithm.
+     *
+     * <ul>
+     *  <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
+     *  prepended with "<b>-</b>" to the list of processed tokens.</li>
+     *  <li>if the {@link Option} can have an argument value and there
+     *  are remaining characters in the token then add the remaining
+     *  characters as a token to the list of processed tokens.</li>
+     *  <li>if an {@link Option} does <b>NOT</b> exist <b>AND</b>
+     *  <code>stopAtNonOption</code> <b>IS</b> set then add the special token
+     *  "<b>--</b>" followed by the remaining characters and also
+     *  the remaining tokens directly to the processed tokens list.</li>
+     *  <li>if an {@link Option} does <b>NOT</b> exist <b>AND</b>
+     *  <code>stopAtNonOption</code> <b>IS NOT</b> set then add that
+     *  character prepended with "<b>-</b>".</li>
+     * </ul>
+     *
+     * @param token The current token to be <b>burst</b>
+     * at the first non-Option encountered.
+     * @throws ParseException if there are any problems encountered
+     *                        while parsing the command line token.
+     */
+    protected void handleConcatenatedOptions(String token) throws ParseException
+    {
+        for (int i = 1; i < token.length(); i++)
+        {
+            String ch = String.valueOf(token.charAt(i));
+
+            if (options.hasOption(ch))
+            {
+                handleOption(options.getOption(ch));
+
+                if (currentOption != null && token.length() != i + 1)
+                {
+                    // add the trail as an argument of the option
+                    currentOption.addValueForProcessing(token.substring(i + 1));
+                    break;
+                }
+            }
+            else
+            {
+                handleUnknownToken(stopAtNonOption && i > 1 ? token.substring(i) : token);
+                break;
+            }
+        }
+    }
+}
diff --git a/src/java/org/apache/commons/cli/GnuParser.java b/src/main/java/org/apache/commons/cli/GnuParser.java
similarity index 92%
rename from src/java/org/apache/commons/cli/GnuParser.java
rename to src/main/java/org/apache/commons/cli/GnuParser.java
index 9aff6aa..05def78 100644
--- a/src/java/org/apache/commons/cli/GnuParser.java
+++ b/src/main/java/org/apache/commons/cli/GnuParser.java
@@ -24,9 +24,10 @@ import java.util.List;
  * The class GnuParser provides an implementation of the
  * {@link Parser#flatten(Options, String[], boolean) flatten} method.
  *
- * @author John Keyes (john at integralsource.com)
- * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ * @version $Id: GnuParser.java 1445352 2013-02-12 20:48:19Z tn $
+ * @deprecated since 1.3, use the {@link DefaultParser} instead
  */
+ at Deprecated
 public class GnuParser extends Parser
 {
     /**
@@ -46,9 +47,10 @@ public class GnuParser extends Parser
      *                        a non option has been encountered
      * @return a String array of the flattened arguments
      */
+    @Override
     protected String[] flatten(Options options, String[] arguments, boolean stopAtNonOption)
     {
-        List tokens = new ArrayList();
+        List<String> tokens = new ArrayList<String>();
 
         boolean eatTheRest = false;
 
@@ -101,13 +103,13 @@ public class GnuParser extends Parser
 
             if (eatTheRest)
             {
-                for (i++; i < arguments.length; i++)
+                for (i++; i < arguments.length; i++) //NOPMD
                 {
                     tokens.add(arguments[i]);
                 }
             }
         }
 
-        return (String[]) tokens.toArray(new String[tokens.size()]);
+        return tokens.toArray(new String[tokens.size()]);
     }
 }
diff --git a/src/java/org/apache/commons/cli/HelpFormatter.java b/src/main/java/org/apache/commons/cli/HelpFormatter.java
similarity index 70%
rename from src/java/org/apache/commons/cli/HelpFormatter.java
rename to src/main/java/org/apache/commons/cli/HelpFormatter.java
index 5fddef9..9d9bbdd 100644
--- a/src/java/org/apache/commons/cli/HelpFormatter.java
+++ b/src/main/java/org/apache/commons/cli/HelpFormatter.java
@@ -17,20 +17,58 @@
 
 package org.apache.commons.cli;
 
+import java.io.BufferedReader;
+import java.io.IOException;
 import java.io.PrintWriter;
+import java.io.Serializable;
+import java.io.StringReader;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 
-/** 
- * A formatter of help messages for the current command line options
+/**
+ * A formatter of help messages for command line options.
  *
- * @author Slawek Zachcial
- * @author John Keyes (john at integralsource.com)
- * @version $Revision: 751120 $, $Date: 2009-03-06 14:45:57 -0800 (Fri, 06 Mar 2009) $
+ * <p>Example:</p>
+ * 
+ * <pre>
+ * Options options = new Options();
+ * options.addOption(OptionBuilder.withLongOpt("file")
+ *                                .withDescription("The file to be processed")
+ *                                .hasArg()
+ *                                .withArgName("FILE")
+ *                                .isRequired()
+ *                                .create('f'));
+ * options.addOption(OptionBuilder.withLongOpt("version")
+ *                                .withDescription("Print the version of the application")
+ *                                .create('v'));
+ * options.addOption(OptionBuilder.withLongOpt("help").create('h'));
+ * 
+ * String header = "Do something useful with an input file\n\n";
+ * String footer = "\nPlease report issues at http://example.com/issues";
+ * 
+ * HelpFormatter formatter = new HelpFormatter();
+ * formatter.printHelp("myapp", header, options, footer, true);
+ * </pre>
+ * 
+ * This produces the following output:
+ * 
+ * <pre>
+ * usage: myapp -f <FILE> [-h] [-v]
+ * Do something useful with an input file
+ * 
+ *  -f,--file <FILE>   The file to be processed
+ *  -h,--help
+ *  -v,--version       Print the version of the application
+ * 
+ * Please report issues at http://example.com/issues
+ * </pre>
+ * 
+ * @version $Id: HelpFormatter.java 1677407 2015-05-03 14:31:12Z britter $
  */
 public class HelpFormatter
 {
@@ -42,10 +80,7 @@ public class HelpFormatter
     /** 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
-     */
+    /** number of space characters to be prefixed to each description line */
     public static final int DEFAULT_DESC_PAD = 3;
 
     /** the string to display at the beginning of the usage statement */
@@ -57,6 +92,13 @@ public class HelpFormatter
     /** default prefix for long Option */
     public static final String DEFAULT_LONG_OPT_PREFIX = "--";
 
+    /** 
+     * default separator displayed between a long Option and its value
+     * 
+     * @since 1.3
+     **/
+    public static final String DEFAULT_LONG_OPT_SEPARATOR = " ";
+
     /** default name for an argument */
     public static final String DEFAULT_ARG_NAME = "arg";
 
@@ -68,6 +110,7 @@ public class HelpFormatter
      * @deprecated Scope will be made private for next major version
      * - use get/setWidth methods instead.
      */
+    @Deprecated
     public int defaultWidth = DEFAULT_WIDTH;
 
     /**
@@ -76,6 +119,7 @@ public class HelpFormatter
      * @deprecated Scope will be made private for next major version
      * - use get/setLeftPadding methods instead.
      */
+    @Deprecated
     public int defaultLeftPad = DEFAULT_LEFT_PAD;
 
     /**
@@ -85,14 +129,16 @@ public class HelpFormatter
      * @deprecated Scope will be made private for next major version
      * - use get/setDescPadding methods instead.
      */
+    @Deprecated
     public int defaultDescPad = DEFAULT_DESC_PAD;
 
     /**
-     * the string to display at the begining of the usage statement
+     * the string to display at the beginning of the usage statement
      *
      * @deprecated Scope will be made private for next major version
      * - use get/setSyntaxPrefix methods instead.
      */
+    @Deprecated
     public String defaultSyntaxPrefix = DEFAULT_SYNTAX_PREFIX;
 
     /**
@@ -101,6 +147,7 @@ public class HelpFormatter
      * @deprecated Scope will be made private for next major version
      * - use get/setNewLine methods instead.
      */
+    @Deprecated
     public String defaultNewLine = System.getProperty("line.separator");
 
     /**
@@ -109,6 +156,7 @@ public class HelpFormatter
      * @deprecated Scope will be made private for next major version
      * - use get/setOptPrefix methods instead.
      */
+    @Deprecated
     public String defaultOptPrefix = DEFAULT_OPT_PREFIX;
 
     /**
@@ -117,6 +165,7 @@ public class HelpFormatter
      * @deprecated Scope will be made private for next major version
      * - use get/setLongOptPrefix methods instead.
      */
+    @Deprecated
     public String defaultLongOptPrefix = DEFAULT_LONG_OPT_PREFIX;
 
     /**
@@ -125,6 +174,7 @@ public class HelpFormatter
      * @deprecated Scope will be made private for next major version
      * - use get/setArgName methods instead.
      */
+    @Deprecated
     public String defaultArgName = DEFAULT_ARG_NAME;
 
     /**
@@ -132,7 +182,10 @@ public class HelpFormatter
      * 
      * Defaults to case-insensitive alphabetical sorting by option key
      */
-    protected Comparator optionComparator = new OptionComparator();
+    protected Comparator<Option> optionComparator = new OptionComparator();
+
+    /** The separator displayed between the long option and its value. */
+    private String longOptSeparator = DEFAULT_LONG_OPT_SEPARATOR;
 
     /**
      * Sets the 'width'.
@@ -275,6 +328,30 @@ public class HelpFormatter
     }
 
     /**
+     * Set the separator displayed between a long option and its value.
+     * Ensure that the separator specified is supported by the parser used,
+     * typically ' ' or '='.
+     * 
+     * @param longOptSeparator the separator, typically ' ' or '='.
+     * @since 1.3
+     */
+    public void setLongOptSeparator(String longOptSeparator)
+    {
+        this.longOptSeparator = longOptSeparator;
+    }
+
+    /**
+     * Returns the separator displayed between a long option and its value.
+     * 
+     * @return the separator
+     * @since 1.3
+     */
+    public String getLongOptSeparator()
+    {
+        return longOptSeparator;
+    }
+
+    /**
      * Sets the 'argName'.
      *
      * @param name the new value of 'argName'
@@ -295,30 +372,27 @@ public class HelpFormatter
     }
 
     /**
-     * Comparator used to sort the options when they output in help text
-     * 
-     * Defaults to case-insensitive alphabetical sorting by option key
+     * Comparator used to sort the options when they output in help text.
+     * Defaults to case-insensitive alphabetical sorting by option key.
+     *
+     * @return the {@link Comparator} currently in use to sort the options
+     * @since 1.2
      */
-    public Comparator getOptionComparator()
+    public Comparator<Option> getOptionComparator()
     {
         return optionComparator;
     }
 
     /**
-     * Set the comparator used to sort the options when they output in help text
-     * 
-     * Passing in a null parameter will set the ordering to the default mode
+     * Set the comparator used to sort the options when they output in help text.
+     * Passing in a null comparator will keep the options in the order they were declared.
+     *
+     * @param comparator the {@link Comparator} to use for sorting the options
+     * @since 1.2
      */
-    public void setOptionComparator(Comparator comparator)
+    public void setOptionComparator(Comparator<Option> comparator)
     {
-        if (comparator == null)
-        {
-            this.optionComparator = new OptionComparator();
-        }
-        else
-        {
-            this.optionComparator = comparator;
-        }
+        this.optionComparator = comparator;
     }
 
     /**
@@ -331,7 +405,7 @@ public class HelpFormatter
      */
     public void printHelp(String cmdLineSyntax, Options options)
     {
-        printHelp(defaultWidth, cmdLineSyntax, null, options, null, false);
+        printHelp(getWidth(), cmdLineSyntax, null, options, null, false);
     }
 
     /**
@@ -346,7 +420,7 @@ public class HelpFormatter
      */
     public void printHelp(String cmdLineSyntax, Options options, boolean autoUsage)
     {
-        printHelp(defaultWidth, cmdLineSyntax, null, options, null, autoUsage);
+        printHelp(getWidth(), cmdLineSyntax, null, options, null, autoUsage);
     }
 
     /**
@@ -355,7 +429,7 @@ public class HelpFormatter
      * System.out.
      *
      * @param cmdLineSyntax the syntax for this application
-     * @param header the banner to display at the begining of the help
+     * @param header the banner to display at the beginning of the help
      * @param options the Options instance
      * @param footer the banner to display at the end of the help
      */
@@ -370,7 +444,7 @@ public class HelpFormatter
      * System.out.
      *
      * @param cmdLineSyntax the syntax for this application
-     * @param header the banner to display at the begining of the help
+     * @param header the banner to display at the beginning 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
@@ -378,7 +452,7 @@ public class HelpFormatter
      */
     public void printHelp(String cmdLineSyntax, String header, Options options, String footer, boolean autoUsage)
     {
-        printHelp(defaultWidth, cmdLineSyntax, header, options, footer, autoUsage);
+        printHelp(getWidth(), cmdLineSyntax, header, options, footer, autoUsage);
     }
 
     /**
@@ -404,7 +478,7 @@ public class HelpFormatter
      *
      * @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 header the banner to display at the beginning 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 
@@ -415,7 +489,7 @@ public class HelpFormatter
     {
         PrintWriter pw = new PrintWriter(System.out);
 
-        printHelp(pw, width, cmdLineSyntax, header, options, defaultLeftPad, defaultDescPad, footer, autoUsage);
+        printHelp(pw, width, cmdLineSyntax, header, options, getLeftPadding(), getDescPadding(), footer, autoUsage);
         pw.flush();
     }
 
@@ -426,7 +500,7 @@ public class HelpFormatter
      * @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 header the banner to display at the beginning of the help
      * @param options the Options instance
      * @param leftPad the number of characters of padding to be prefixed
      * to each line
@@ -451,7 +525,7 @@ public class HelpFormatter
      * @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 header the banner to display at the beginning of the help
      * @param options the Options instance
      * @param leftPad the number of characters of padding to be prefixed
      * to each line
@@ -467,7 +541,7 @@ public class HelpFormatter
                           String header, Options options, int leftPad,
                           int descPad, String footer, boolean autoUsage)
     {
-        if ((cmdLineSyntax == null) || (cmdLineSyntax.length() == 0))
+        if (cmdLineSyntax == null || cmdLineSyntax.length() == 0)
         {
             throw new IllegalArgumentException("cmdLineSyntax not provided");
         }
@@ -481,46 +555,45 @@ public class HelpFormatter
             printUsage(pw, width, cmdLineSyntax);
         }
 
-        if ((header != null) && (header.trim().length() > 0))
+        if (header != null && header.trim().length() > 0)
         {
             printWrapped(pw, width, header);
         }
 
         printOptions(pw, width, options, leftPad, descPad);
 
-        if ((footer != null) && (footer.trim().length() > 0))
+        if (footer != null && footer.trim().length() > 0)
         {
             printWrapped(pw, width, footer);
         }
     }
 
     /**
-     * <p>Prints the usage statement for the specified application.</p>
+     * Prints the usage statement for the specified application.
      *
      * @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(" ");
+        StringBuffer buff = new StringBuffer(getSyntaxPrefix()).append(app).append(" ");
 
         // create a list for processed option groups
-        final Collection processedGroups = new ArrayList();
+        Collection<OptionGroup> processedGroups = new ArrayList<OptionGroup>();
 
-        // temp variable
-        Option option;
-
-        List optList = new ArrayList(options.getOptions());
-        Collections.sort(optList, getOptionComparator());
+        List<Option> optList = new ArrayList<Option>(options.getOptions());
+        if (getOptionComparator() != null)
+        {
+            Collections.sort(optList, getOptionComparator());
+        }
         // iterate over the options
-        for (Iterator i = optList.iterator(); i.hasNext();)
+        for (Iterator<Option> it = optList.iterator(); it.hasNext();)
         {
             // get the next Option
-            option = (Option) i.next();
+            Option option = it.next();
 
             // check if the option is part of an OptionGroup
             OptionGroup group = options.getOptionGroup(option);
@@ -549,7 +622,7 @@ public class HelpFormatter
                 appendOption(buff, option, option.isRequired());
             }
 
-            if (i.hasNext())
+            if (it.hasNext())
             {
                 buff.append(" ");
             }
@@ -568,22 +641,25 @@ public class HelpFormatter
      * @param group the group to append
      * @see #appendOption(StringBuffer,Option,boolean)
      */
-    private void appendOptionGroup(final StringBuffer buff, final OptionGroup group)
+    private void appendOptionGroup(StringBuffer buff, OptionGroup group)
     {
         if (!group.isRequired())
         {
             buff.append("[");
         }
 
-        List optList = new ArrayList(group.getOptions());
-        Collections.sort(optList, getOptionComparator());
+        List<Option> optList = new ArrayList<Option>(group.getOptions());
+        if (getOptionComparator() != null)
+        {
+            Collections.sort(optList, getOptionComparator());
+        }
         // for each option in the OptionGroup
-        for (Iterator i = optList.iterator(); i.hasNext();)
+        for (Iterator<Option> it = optList.iterator(); it.hasNext();)
         {
             // whether the option is required or not is handled at group level
-            appendOption(buff, (Option) i.next(), true);
+            appendOption(buff, it.next(), true);
 
-            if (i.hasNext())
+            if (it.hasNext())
             {
                 buff.append(" | ");
             }
@@ -602,7 +678,7 @@ public class HelpFormatter
      * @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)
+    private void appendOption(StringBuffer buff, Option option, boolean required)
     {
         if (!required)
         {
@@ -617,13 +693,14 @@ public class HelpFormatter
         {
             buff.append("--").append(option.getLongOpt());
         }
-
-        // if the Option has a value
-        if (option.hasArg() && option.hasArgName())
+        
+        // if the Option has a value and a non blank argname
+        if (option.hasArg() && (option.getArgName() == null || option.getArgName().length() != 0))
         {
-            buff.append(" <").append(option.getArgName()).append(">");
+            buff.append(option.getOpt() == null ? longOptSeparator : " ");
+            buff.append("<").append(option.getArgName() != null ? option.getArgName() : getArgName()).append(">");
         }
-
+        
         // if the Option is not a required option
         if (!required)
         {
@@ -643,12 +720,12 @@ public class HelpFormatter
     {
         int argPos = cmdLineSyntax.indexOf(' ') + 1;
 
-        printWrapped(pw, width, defaultSyntaxPrefix.length() + argPos, defaultSyntaxPrefix + cmdLineSyntax);
+        printWrapped(pw, width, getSyntaxPrefix().length() + argPos, getSyntaxPrefix() + cmdLineSyntax);
     }
 
     /**
-     * <p>Print the help for the specified Options to the specified writer, 
-     * using the specified width, left padding and description padding.</p>
+     * Print the help for the specified Options to the specified writer, 
+     * using the specified width, left padding and description padding.
      *
      * @param pw The printWriter to write the help to
      * @param width The number of characters to display per line
@@ -691,7 +768,7 @@ public class HelpFormatter
     {
         StringBuffer sb = new StringBuffer(text.length());
 
-        renderWrappedText(sb, width, nextLineTabStop, text);
+        renderWrappedTextBlock(sb, width, nextLineTabStop, text);
         pw.println(sb.toString());
     }
 
@@ -721,54 +798,58 @@ public class HelpFormatter
         // the longest opt string this list will be then used to 
         // sort options ascending
         int max = 0;
-        StringBuffer optBuf;
-        List prefixList = new ArrayList();
+        List<StringBuffer> prefixList = new ArrayList<StringBuffer>();
 
-        List optList = options.helpOptions();
+        List<Option> optList = options.helpOptions();
 
-        Collections.sort(optList, getOptionComparator());
+        if (getOptionComparator() != null)
+        {
+            Collections.sort(optList, getOptionComparator());
+        }
 
-        for (Iterator i = optList.iterator(); i.hasNext();)
+        for (Option option : optList)
         {
-            Option option = (Option) i.next();
-            optBuf = new StringBuffer(8);
+            StringBuffer optBuf = new StringBuffer();
 
             if (option.getOpt() == null)
             {
-                optBuf.append(lpad).append("   " + defaultLongOptPrefix).append(option.getLongOpt());
+                optBuf.append(lpad).append("   ").append(getLongOptPrefix()).append(option.getLongOpt());
             }
             else
             {
-                optBuf.append(lpad).append(defaultOptPrefix).append(option.getOpt());
+                optBuf.append(lpad).append(getOptPrefix()).append(option.getOpt());
 
                 if (option.hasLongOpt())
                 {
-                    optBuf.append(',').append(defaultLongOptPrefix).append(option.getLongOpt());
+                    optBuf.append(',').append(getLongOptPrefix()).append(option.getLongOpt());
                 }
             }
 
             if (option.hasArg())
             {
-                if (option.hasArgName())
+                String argName = option.getArgName();
+                if (argName != null && argName.length() == 0)
                 {
-                    optBuf.append(" <").append(option.getArgName()).append(">");
+                    // if the option has a blank argname
+                    optBuf.append(' ');
                 }
                 else
                 {
-                    optBuf.append(' ');
+                    optBuf.append(option.hasLongOpt() ? longOptSeparator : " ");
+                    optBuf.append("<").append(argName != null ? option.getArgName() : getArgName()).append(">");
                 }
             }
 
             prefixList.add(optBuf);
-            max = (optBuf.length() > max) ? optBuf.length() : max;
+            max = optBuf.length() > max ? optBuf.length() : max;
         }
 
         int x = 0;
 
-        for (Iterator i = optList.iterator(); i.hasNext();)
+        for (Iterator<Option> it = optList.iterator(); it.hasNext();)
         {
-            Option option = (Option) i.next();
-            optBuf = new StringBuffer(prefixList.get(x++).toString());
+            Option option = it.next();
+            StringBuilder optBuf = new StringBuilder(prefixList.get(x++).toString());
 
             if (optBuf.length() < max)
             {
@@ -786,9 +867,9 @@ public class HelpFormatter
 
             renderWrappedText(sb, width, nextLineTabStop, optBuf.toString());
 
-            if (i.hasNext())
+            if (it.hasNext())
             {
-                sb.append(defaultNewLine);
+                sb.append(getNewLine());
             }
         }
 
@@ -817,7 +898,7 @@ public class HelpFormatter
 
             return sb;
         }
-        sb.append(rtrim(text.substring(0, pos))).append(defaultNewLine);
+        sb.append(rtrim(text.substring(0, pos))).append(getNewLine());
 
         if (nextLineTabStop >= width)
         {
@@ -825,8 +906,7 @@ public class HelpFormatter
             nextLineTabStop = 1;
         }
 
-        // all following lines must be padded with nextLineTabStop space 
-        // characters
+        // all following lines must be padded with nextLineTabStop space characters
         final String padding = createPadding(nextLineTabStop);
 
         while (true)
@@ -840,54 +920,95 @@ public class HelpFormatter
 
                 return sb;
             }
-            
-            if ( (text.length() > width) && (pos == nextLineTabStop - 1) ) 
+
+            if (text.length() > width && pos == nextLineTabStop - 1)
             {
                 pos = width;
             }
 
-            sb.append(rtrim(text.substring(0, pos))).append(defaultNewLine);
+            sb.append(rtrim(text.substring(0, pos))).append(getNewLine());
+        }
+    }
+
+    /**
+     * Render the specified text width a maximum width. This method differs
+     * from renderWrappedText by not removing leading spaces after a new line.
+     *
+     * @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.
+     */
+    private Appendable renderWrappedTextBlock(StringBuffer sb, int width, int nextLineTabStop, String text)
+    {
+        try
+        {
+            BufferedReader in = new BufferedReader(new StringReader(text));
+            String line;
+            boolean firstLine = true;
+            while ((line = in.readLine()) != null)
+            {
+                if (!firstLine)
+                {
+                    sb.append(getNewLine());
+                }
+                else
+                {
+                    firstLine = false;
+                }
+                renderWrappedText(sb, width, nextLineTabStop, line);
+            }
         }
+        catch (IOException e) //NOPMD
+        {
+            // cannot happen
+        }
+
+        return sb;
     }
 
     /**
      * 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).
+     * The wrap point is the last position before startPos+width having a 
+     * whitespace character (space, \n, \r). If there is no whitespace character
+     * before startPos+width, it will return startPos+width.
      *
      * @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
+     * @return position 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))
+        int pos = text.indexOf('\n', startPos);
+        if (pos != -1 && pos <= width)
         {
             return pos + 1;
         }
-        else if (startPos + width >= text.length())
+
+        pos = text.indexOf('\t', startPos);
+        if (pos != -1 && pos <= width)
         {
-            return -1;
+            return pos + 1;
         }
 
+        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'))
+        for (pos = startPos + width; pos >= startPos; --pos)
         {
-            --pos;
+            final char c = text.charAt(pos);
+            if (c == ' ' || c == '\n' || c == '\r')
+            {
+                break;
+            }
         }
 
         // if we found it - just return
@@ -895,18 +1016,11 @@ public class HelpFormatter
         {
             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;
-        }
+        // if we didn't find one, simply chop at startPos+width
+        pos = startPos + width;
 
-        return (pos == text.length()) ? (-1) : pos;
+        return pos == text.length() ? -1 : pos;
     }
 
     /**
@@ -918,14 +1032,10 @@ public class HelpFormatter
      */
     protected String createPadding(int len)
     {
-        StringBuffer sb = new StringBuffer(len);
-
-        for (int i = 0; i < len; ++i)
-        {
-            sb.append(' ');
-        }
+        char[] padding = new char[len];
+        Arrays.fill(padding, ' ');
 
-        return sb.toString();
+        return new String(padding);
     }
 
     /**
@@ -937,14 +1047,14 @@ public class HelpFormatter
      */
     protected String rtrim(String s)
     {
-        if ((s == null) || (s.length() == 0))
+        if (s == null || s.length() == 0)
         {
             return s;
         }
 
         int pos = s.length();
 
-        while ((pos > 0) && Character.isWhitespace(s.charAt(pos - 1)))
+        while (pos > 0 && Character.isWhitespace(s.charAt(pos - 1)))
         {
             --pos;
         }
@@ -959,26 +1069,26 @@ public class HelpFormatter
      * This class implements the <code>Comparator</code> interface
      * for comparing Options.
      */
-    private static class OptionComparator implements Comparator
+    private static class OptionComparator implements Comparator<Option>, Serializable
     {
+        /** The serial version UID. */
+        private static final long serialVersionUID = 5305467873966684014L;
 
         /**
          * 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.
          *
-         * @param o1 The first Option to be compared.
-         * @param o2 The second Option to be compared.
+         * @param opt1 The first Option to be compared.
+         * @param opt2 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)
+        public int compare(Option opt1, Option opt2)
         {
-            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/main/java/org/apache/commons/cli/MissingArgumentException.java
similarity index 89%
rename from src/java/org/apache/commons/cli/MissingArgumentException.java
rename to src/main/java/org/apache/commons/cli/MissingArgumentException.java
index c5d33ea..9974775 100644
--- a/src/java/org/apache/commons/cli/MissingArgumentException.java
+++ b/src/main/java/org/apache/commons/cli/MissingArgumentException.java
@@ -21,11 +21,15 @@ package org.apache.commons.cli;
  * Thrown when an option requiring an argument
  * is not provided with an argument.
  *
- * @author John Keyes (john at integralsource.com)
- * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ * @version $Id: MissingArgumentException.java 1443102 2013-02-06 18:12:16Z tn $
  */
 public class MissingArgumentException extends ParseException
 {
+    /**
+     * This exception {@code serialVersionUID}.
+     */
+    private static final long serialVersionUID = -7098538588704965017L;
+
     /** The option requiring additional arguments */
     private Option option;
 
diff --git a/src/java/org/apache/commons/cli/MissingOptionException.java b/src/main/java/org/apache/commons/cli/MissingOptionException.java
similarity index 66%
rename from src/java/org/apache/commons/cli/MissingOptionException.java
rename to src/main/java/org/apache/commons/cli/MissingOptionException.java
index 9ad5905..b7df24e 100644
--- a/src/java/org/apache/commons/cli/MissingOptionException.java
+++ b/src/main/java/org/apache/commons/cli/MissingOptionException.java
@@ -23,12 +23,14 @@ import java.util.Iterator;
 /**
  * Thrown when a required option has not been provided.
  *
- * @author John Keyes ( john at integralsource.com )
- * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ * @version $Id: MissingOptionException.java 1443102 2013-02-06 18:12:16Z tn $
  */
 public class MissingOptionException extends ParseException
 {
-    /** The list of missing options */
+    /** This exception {@code serialVersionUID}. */
+    private static final long serialVersionUID = 8161889051578563249L;
+
+    /** The list of missing options and groups */
     private List missingOptions;
 
     /**
@@ -46,7 +48,7 @@ public class MissingOptionException extends ParseException
      * Constructs a new <code>MissingSelectedException</code> with the
      * specified list of missing options.
      *
-     * @param missingOptions the list of missing options
+     * @param missingOptions the list of missing options and groups
      * @since 1.2
      */
     public MissingOptionException(List missingOptions)
@@ -56,9 +58,10 @@ public class MissingOptionException extends ParseException
     }
 
     /**
-     * Return the list of options (as strings) missing in the command line parsed.
+     * Returns the list of options or option groups missing in the command line parsed.
      *
-     * @return the missing options
+     * @return the missing options, consisting of String instances for simple
+     *         options, and OptionGroup instances for required option groups.
      * @since 1.2
      */
     public List getMissingOptions()
@@ -69,25 +72,25 @@ public class MissingOptionException extends ParseException
     /**
      * Build the exception message from the specified list of options.
      *
-     * @param missingOptions
+     * @param missingOptions the list of missing options and groups
      * @since 1.2
      */
-    private static String createMessage(List missingOptions)
+    private static String createMessage(List<?> missingOptions)
     {
-        StringBuffer buff = new StringBuffer("Missing required option");
-        buff.append(missingOptions.size() == 1 ? "" : "s");
-        buff.append(": ");
+        StringBuilder buf = new StringBuilder("Missing required option");
+        buf.append(missingOptions.size() == 1 ? "" : "s");
+        buf.append(": ");
 
-        Iterator it = missingOptions.iterator();
+        Iterator<?> it = missingOptions.iterator();
         while (it.hasNext())
         {
-            buff.append(it.next());
+            buf.append(it.next());
             if (it.hasNext())
             {
-                buff.append(", ");
+                buf.append(", ");
             }
         }
 
-        return buff.toString();
+        return buf.toString();
     }
 }
diff --git a/src/java/org/apache/commons/cli/Option.java b/src/main/java/org/apache/commons/cli/Option.java
similarity index 57%
rename from src/java/org/apache/commons/cli/Option.java
rename to src/main/java/org/apache/commons/cli/Option.java
index af33ae8..2e67e4a 100644
--- a/src/java/org/apache/commons/cli/Option.java
+++ b/src/main/java/org/apache/commons/cli/Option.java
@@ -21,39 +21,43 @@ import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 
-/** <p>Describes a single command-line option.  It maintains
+/**
+ * Describes a single command-line option.  It maintains
  * information regarding the short-name of the option, the long-name,
  * if any exists, a flag indicating if an argument is required for
- * this option, and a self-documenting description of the option.</p>
- *
- * <p>An Option is not created independantly, but is create through
- * an instance of {@link Options}.<p>
+ * this option, and a self-documenting description of the option.
+ * <p>
+ * An Option is not created independently, but is created through
+ * an instance of {@link Options}. An Option is required to have
+ * at least a short or a long-name.
+ * <p>
+ * <b>Note:</b> once an {@link Option} has been added to an instance
+ * of {@link Options}, it's required flag may not be changed anymore.
  *
  * @see org.apache.commons.cli.Options
  * @see org.apache.commons.cli.CommandLine
  *
- * @author bob mcwhirter (bob @ werken.com)
- * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
- * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ * @version $Id: Option.java 1677406 2015-05-03 14:27:31Z britter $
  */
 public class Option implements Cloneable, Serializable
 {
-    private static final long serialVersionUID = 1L;
-
     /** 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 static final int UNLIMITED_VALUES = -2;
 
+    /** The serial version UID. */
+    private static final long serialVersionUID = 1L;
+
     /** the name of the option */
-    private String opt;
+    private final String opt;
 
     /** the long representation of the option */
     private String longOpt;
 
     /** the name of the argument for this option */
-    private String argName = "arg";
+    private String argName;
 
     /** description of the option */
     private String description;
@@ -68,16 +72,35 @@ public class Option implements Cloneable, Serializable
     private int numberOfArgs = UNINITIALIZED;
 
     /** the type of this Option */
-    private Object type;
+    private Class<?> type = String.class;
 
     /** the list of argument values **/
-    private List values = new ArrayList();
+    private List<String> values = new ArrayList<String>();
 
     /** the character that is the value separator */
     private char valuesep;
 
     /**
+     * Private constructor used by the nested Builder class.
+     * 
+     * @param builder builder used to create this option
+     */
+    private Option(final Builder builder)
+    {
+        this.argName = builder.argName;
+        this.description = builder.description;
+        this.longOpt = builder.longOpt;
+        this.numberOfArgs = builder.numberOfArgs;
+        this.opt = builder.opt;
+        this.optionalArg = builder.optionalArg;
+        this.required = builder.required;
+        this.type = builder.type;
+        this.valuesep = builder.valuesep;
+    }
+    
+    /**
      * Creates an Option using the specified parameters.
+     * The option does not take an argument.
      *
      * @param opt short representation of the option
      * @param description describes the function of the option
@@ -154,12 +177,7 @@ public class Option implements Cloneable, Serializable
     String getKey()
     {
         // if 'opt' is null, then it is a 'long' option
-        if (opt == null)
-        {
-            return longOpt;
-        }
-
-        return opt;
+        return (opt == null) ? longOpt : opt;
     }
 
     /** 
@@ -189,11 +207,27 @@ public class Option implements Cloneable, Serializable
 
     /**
      * Sets the type of this Option.
+     * <p>
+     * <b>Note:</b> this method is kept for binary compatibility and the
+     * input type is supposed to be a {@link Class} object. 
      *
      * @param type the type of this Option
+     * @deprecated since 1.3, use {@link #setType(Class)} instead
      */
+    @Deprecated
     public void setType(Object type)
     {
+        setType((Class<?>) type);
+    }
+
+    /**
+     * Sets the type of this Option.
+     *
+     * @param type the type of this Option
+     * @since 1.3
+     */
+    public void setType(Class<?> type)
+    {
         this.type = type;
     }
 
@@ -278,9 +312,9 @@ public class Option implements Cloneable, Serializable
     }
 
     /** 
-     * Query to see if this Option requires an argument
+     * Query to see if this Option is mandatory
      *
-     * @return boolean flag indicating if an argument is required
+     * @return boolean flag indicating whether this Option is mandatory
      */
     public boolean isRequired()
     {
@@ -318,11 +352,9 @@ public class Option implements Cloneable, Serializable
     }
 
     /**
-     * Returns whether the display name for the argument value
-     * has been set.
+     * Returns whether the display name for the argument value has been set.
      *
-     * @return if 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()
     {
@@ -398,14 +430,11 @@ public class Option implements Cloneable, Serializable
      */
     void addValueForProcessing(String value)
     {
-        switch (numberOfArgs)
+        if (numberOfArgs == UNINITIALIZED)
         {
-            case UNINITIALIZED:
-                throw new RuntimeException("NO_ARGS_ALLOWED");
-
-            default:
-                processValue(value);
+            throw new RuntimeException("NO_ARGS_ALLOWED");
         }
+        processValue(value);
     }
 
     /**
@@ -434,7 +463,7 @@ public class Option implements Cloneable, Serializable
             while (index != -1)
             {
                 // next value to be added 
-                if (values.size() == (numberOfArgs - 1))
+                if (values.size() == numberOfArgs - 1)
                 {
                     break;
                 }
@@ -465,7 +494,7 @@ public class Option implements Cloneable, Serializable
      */
     private void add(String value)
     {
-        if ((numberOfArgs > 0) && (values.size() > (numberOfArgs - 1)))
+        if (!acceptsArg())
         {
             throw new RuntimeException("Cannot add value, list full.");
         }
@@ -483,7 +512,7 @@ public class Option implements Cloneable, Serializable
      */
     public String getValue()
     {
-        return hasNoValues() ? null : (String) values.get(0);
+        return hasNoValues() ? null : values.get(0);
     }
 
     /**
@@ -500,14 +529,14 @@ public class Option implements Cloneable, Serializable
      */
     public String getValue(int index) throws IndexOutOfBoundsException
     {
-        return hasNoValues() ? null : (String) values.get(index);
+        return hasNoValues() ? null : 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
+     * @param defaultValue The value to be returned if there
      * is no value.
      *
      * @return the value/first value of this Option or the 
@@ -529,14 +558,14 @@ public class Option implements Cloneable, Serializable
      */
     public String[] getValues()
     {
-        return hasNoValues() ? null : (String[]) values.toArray(new String[values.size()]);
+        return hasNoValues() ? null : values.toArray(new String[values.size()]);
     }
 
     /**
      * @return the values of this Option as a List
      * or null if there are no values
      */
-    public List getValuesList()
+    public List<String> getValuesList()
     {
         return values;
     }
@@ -546,9 +575,10 @@ public class Option implements Cloneable, Serializable
      *
      * @return Stringified form of this object
      */
+    @Override
     public String toString()
     {
-        StringBuffer buf = new StringBuffer().append("[ option: ");
+        StringBuilder buf = new StringBuilder().append("[ option: ");
 
         buf.append(opt);
 
@@ -590,6 +620,7 @@ public class Option implements Cloneable, Serializable
         return values.isEmpty();
     }
 
+    @Override
     public boolean equals(Object o)
     {
         if (this == o)
@@ -616,10 +647,11 @@ public class Option implements Cloneable, Serializable
         return true;
     }
 
+    @Override
     public int hashCode()
     {
         int result;
-        result = (opt != null ? opt.hashCode() : 0);
+        result = opt != null ? opt.hashCode() : 0;
         result = 31 * result + (longOpt != null ? longOpt.hashCode() : 0);
         return result;
     }
@@ -632,14 +664,17 @@ public class Option implements Cloneable, Serializable
      * After calling this method, it is very likely you will want to call 
      * clearValues(). 
      *
-     * @throws RuntimeException
+     * @return a clone of this Option instance
+     * @throws RuntimeException if a {@link CloneNotSupportedException} has been thrown
+     * by {@code super.clone()}
      */
+    @Override
     public Object clone()
     {
         try
         {
             Option option = (Option) super.clone();
-            option.values = new ArrayList(values);
+            option.values = new ArrayList<String>(values);
             return option;
         }
         catch (CloneNotSupportedException cnse)
@@ -661,14 +696,311 @@ public class Option implements Cloneable, Serializable
 
     /**
      * 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. 
+     * API that was made public in 1.0. It currently throws an UnsupportedOperationException.
+     *
+     * @param value the value to add
+     * @return always throws an {@link UnsupportedOperationException}
+     * @throws UnsupportedOperationException always
      * @deprecated
-     * @throws UnsupportedOperationException
      */
+    @Deprecated
     public boolean addValue(String value)
     {
         throw new UnsupportedOperationException("The addValue method is not intended for client use. "
                 + "Subclasses should use the addValueForProcessing method instead. ");
     }
 
+    /**
+     * Tells if the option can accept more arguments.
+     * 
+     * @return false if the maximum number of arguments is reached
+     * @since 1.3
+     */
+    boolean acceptsArg()
+    {
+        return (hasArg() || hasArgs() || hasOptionalArg()) && (numberOfArgs <= 0 || values.size() < numberOfArgs);
+    }
+
+    /**
+     * Tells if the option requires more arguments to be valid.
+     * 
+     * @return false if the option doesn't require more arguments
+     * @since 1.3
+     */
+    boolean requiresArg()
+    {
+        if (optionalArg)
+        {
+            return false;
+        }
+        if (numberOfArgs == UNLIMITED_VALUES)
+        {
+            return values.isEmpty();
+        }
+        return acceptsArg();
+    }
+    
+    /**
+     * Returns a {@link Builder} to create an {@link Option} using descriptive
+     * methods.  
+     * 
+     * @return a new {@link Builder} instance
+     * @since 1.3
+     */
+    public static Builder builder()
+    {
+        return builder(null);
+    }
+    
+    /**
+     * Returns a {@link Builder} to create an {@link Option} using descriptive
+     * methods.  
+     *
+     * @param opt short representation of the option
+     * @return a new {@link Builder} instance
+     * @throws IllegalArgumentException if there are any non valid Option characters in {@code opt}
+     * @since 1.3
+     */
+    public static Builder builder(final String opt)
+    {
+        return new Builder(opt);
+    }
+    
+    /**
+     * A nested builder class to create <code>Option</code> instances
+     * using descriptive methods.
+     * <p>
+     * Example usage:
+     * <pre>
+     * Option option = Option.builder("a")
+     *     .required(true)
+     *     .longOpt("arg-name")
+     *     .build();
+     * </pre>
+     * 
+     * @since 1.3
+     */
+    public static final class Builder 
+    {
+        /** the name of the option */
+        private final String opt;
+
+        /** description of the option */
+        private String description;
+
+        /** the long representation of the option */
+        private String longOpt;
+
+        /** the name of the argument for this option */
+        private String argName;
+
+        /** specifies whether this option is required to be present */
+        private boolean required;
+
+        /** specifies whether the argument value of this Option is optional */
+        private boolean optionalArg;
+
+        /** the number of argument values this option can have */
+        private int numberOfArgs = UNINITIALIZED;
+
+        /** the type of this Option */
+        private Class<?> type = String.class;
+
+        /** the character that is the value separator */
+        private char valuesep;
+
+        /**
+         * Constructs a new <code>Builder</code> with the minimum
+         * required parameters for an <code>Option</code> instance.
+         * 
+         * @param opt short representation of the option
+         * @throws IllegalArgumentException if there are any non valid Option characters in {@code opt}
+         */
+        private Builder(final String opt) throws IllegalArgumentException
+        {
+            OptionValidator.validateOption(opt);
+            this.opt = opt;
+        }
+        
+        /**
+         * Sets the display name for the argument value.
+         *
+         * @param argName the display name for the argument value.
+         * @return this builder, to allow method chaining
+         */
+        public Builder argName(final String argName)
+        {
+            this.argName = argName;
+            return this;
+        }
+
+        /**
+         * Sets the description for this option.
+         *
+         * @param description the description of the option.
+         * @return this builder, to allow method chaining
+         */
+        public Builder desc(final String description)
+        {
+            this.description = description;
+            return this;
+        }
+
+        /**
+         * Sets the long name of the Option.
+         *
+         * @param longOpt the long name of the Option
+         * @return this builder, to allow method chaining
+         */        
+        public Builder longOpt(final String longOpt)
+        {
+            this.longOpt = longOpt;
+            return this;
+        }
+        
+        /** 
+         * Sets the number of argument values the Option can take.
+         *
+         * @param numberOfArgs the number of argument values
+         * @return this builder, to allow method chaining
+         */        
+        public Builder numberOfArgs(final int numberOfArgs)
+        {
+            this.numberOfArgs = numberOfArgs;
+            return this;
+        }
+        
+        /**
+         * Sets whether the Option can have an optional argument.
+         *
+         * @param isOptional specifies whether the Option can have
+         * an optional argument.
+         * @return this builder, to allow method chaining
+         */
+        public Builder optionalArg(final boolean isOptional)
+        {
+            this.optionalArg = isOptional;
+            return this;
+        }
+        
+        /**
+         * Marks this Option as required.
+         *
+         * @return this builder, to allow method chaining
+         */
+        public Builder required()
+        {
+            return required(true);
+        }
+
+        /**
+         * Sets whether the Option is mandatory.
+         *
+         * @param required specifies whether the Option is mandatory
+         * @return this builder, to allow method chaining
+         */
+        public Builder required(final boolean required)
+        {
+            this.required = required;
+            return this;
+        }
+        
+        /**
+         * Sets the type of the Option.
+         *
+         * @param type the type of the Option
+         * @return this builder, to allow method chaining
+         */
+        public Builder type(final Class<?> type)
+        {
+            this.type = type;
+            return this;
+        }
+
+        /**
+         * The Option will use '=' as a means to separate argument value.
+         *
+         * @return this builder, to allow method chaining
+         */
+        public Builder valueSeparator()
+        {
+            return valueSeparator('=');
+        }
+
+        /**
+         * The Option will use <code>sep</code> as a means to
+         * separate argument values.
+         * <p>
+         * <b>Example:</b>
+         * <pre>
+         * Option opt = Option.builder("D").hasArgs()
+         *                                 .valueSeparator('=')
+         *                                 .build();
+         * Options options = new Options();
+         * options.addOption(opt);
+         * String[] args = {"-Dkey=value"};
+         * CommandLineParser parser = new DefaultParser();
+         * CommandLine line = parser.parse(options, args);
+         * String propertyName = line.getOptionValues("D")[0];  // will be "key"
+         * String propertyValue = line.getOptionValues("D")[1]; // will be "value"
+         * </pre>
+         *
+         * @param sep The value separator.
+         * @return this builder, to allow method chaining
+         */
+        public Builder valueSeparator(final char sep)
+        {
+            valuesep = sep;
+            return this;
+        }
+        
+        /**
+         * Indicates that the Option will require an argument.
+         * 
+         * @return this builder, to allow method chaining
+         */
+        public Builder hasArg()
+        {
+            return hasArg(true);
+        }
+
+        /**
+         * Indicates if the Option has an argument or not.
+         * 
+         * @param hasArg specifies whether the Option takes an argument or not
+         * @return this builder, to allow method chaining
+         */
+        public Builder hasArg(final boolean hasArg)
+        {
+            // set to UNINITIALIZED when no arg is specified to be compatible with OptionBuilder
+            numberOfArgs = hasArg ? 1 : Option.UNINITIALIZED;
+            return this;
+        }
+
+        /**
+         * Indicates that the Option can have unlimited argument values.
+         * 
+         * @return this builder, to allow method chaining
+         */
+        public Builder hasArgs()
+        {
+            numberOfArgs = Option.UNLIMITED_VALUES;
+            return this;
+        }
+
+        /**
+         * Constructs an Option with the values declared by this {@link Builder}.
+         * 
+         * @return the new {@link Option}
+         * @throws IllegalArgumentException if neither {@code opt} or {@code longOpt} has been set
+         */
+        public Option build()
+        {
+            if (opt == null && longOpt == null)
+            {
+                throw new IllegalArgumentException("Either opt or longOpt must be specified");
+            }
+            return new Option(this);
+        }
+    }
 }
diff --git a/src/java/org/apache/commons/cli/OptionBuilder.java b/src/main/java/org/apache/commons/cli/OptionBuilder.java
similarity index 82%
rename from src/java/org/apache/commons/cli/OptionBuilder.java
rename to src/main/java/org/apache/commons/cli/OptionBuilder.java
index 93816c1..6b287d3 100644
--- a/src/java/org/apache/commons/cli/OptionBuilder.java
+++ b/src/main/java/org/apache/commons/cli/OptionBuilder.java
@@ -19,15 +19,17 @@ package org.apache.commons.cli;
 
 /**
  * OptionBuilder allows the user to create Options using descriptive methods.
- *
- * <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>
- *
- * @author John Keyes (john at integralsource.com)
- * @version $Revision: 754830 $, $Date: 2009-03-16 00:26:44 -0700 (Mon, 16 Mar 2009) $
+ * <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>
+ * This class is NOT thread safe. See <a href="https://issues.apache.org/jira/browse/CLI-209">CLI-209</a>
+ * 
+ * @version $Id: OptionBuilder.java 1677400 2015-05-03 13:46:08Z britter $
  * @since 1.0
+ * @deprecated since 1.3, use {@link Option#builder(String)} instead
  */
+ at Deprecated
 public final class OptionBuilder
 {
     /** long option */
@@ -46,7 +48,7 @@ public final class OptionBuilder
     private static int numberOfArgs = Option.UNINITIALIZED;
 
     /** option type */
-    private static Object type;
+    private static Class<?> type;
 
     /** option can have an optional argument value */
     private static boolean optionalArg;
@@ -55,7 +57,13 @@ public final class OptionBuilder
     private static char valuesep;
 
     /** option builder instance */
-    private static OptionBuilder instance = new OptionBuilder();
+    private static final OptionBuilder INSTANCE = new OptionBuilder();
+
+    static
+    {
+        // ensure the consistency of the initial values
+        reset();
+    }
 
     /**
      * private constructor to prevent instances being created
@@ -71,14 +79,11 @@ public final class OptionBuilder
     private static void reset()
     {
         description = null;
-        argName = "arg";
+        argName = null;
         longopt = null;
-        type = null;
+        type = String.class;
         required = false;
         numberOfArgs = Option.UNINITIALIZED;
-
-
-        // PMM 9/6/02 - these were missing
         optionalArg = false;
         valuesep = (char) 0;
     }
@@ -93,7 +98,7 @@ public final class OptionBuilder
     {
         OptionBuilder.longopt = newLongopt;
 
-        return instance;
+        return INSTANCE;
     }
 
     /**
@@ -105,7 +110,7 @@ public final class OptionBuilder
     {
         OptionBuilder.numberOfArgs = 1;
 
-        return instance;
+        return INSTANCE;
     }
 
     /**
@@ -119,7 +124,7 @@ public final class OptionBuilder
     {
         OptionBuilder.numberOfArgs = hasArg ? 1 : Option.UNINITIALIZED;
 
-        return instance;
+        return INSTANCE;
     }
 
     /**
@@ -132,7 +137,7 @@ public final class OptionBuilder
     {
         OptionBuilder.argName = name;
 
-        return instance;
+        return INSTANCE;
     }
 
     /**
@@ -144,21 +149,22 @@ public final class OptionBuilder
     {
         OptionBuilder.required = true;
 
-        return instance;
+        return INSTANCE;
     }
 
     /**
      * The next Option created uses <code>sep</code> as a means to
      * separate argument values.
-     *
+     * <p>
      * <b>Example:</b>
      * <pre>
-     * Option opt = OptionBuilder.withValueSeparator(':')
+     * Option opt = OptionBuilder.withValueSeparator('=')
      *                           .create('D');
      *
+     * String args = "-Dkey=value";
      * CommandLine line = parser.parse(args);
-     * String propertyName = opt.getValue(0);
-     * String propertyValue = opt.getValue(1);
+     * String propertyName = opt.getValue(0);  // will be "key"
+     * String propertyValue = opt.getValue(1); // will be "value"
      * </pre>
      *
      * @param sep The value separator to be used for the argument values.
@@ -169,7 +175,7 @@ public final class OptionBuilder
     {
         OptionBuilder.valuesep = sep;
 
-        return instance;
+        return INSTANCE;
     }
 
     /**
@@ -192,7 +198,7 @@ public final class OptionBuilder
     {
         OptionBuilder.valuesep = '=';
 
-        return instance;
+        return INSTANCE;
     }
 
     /**
@@ -206,7 +212,7 @@ public final class OptionBuilder
     {
         OptionBuilder.required = newRequired;
 
-        return instance;
+        return INSTANCE;
     }
 
     /**
@@ -218,7 +224,7 @@ public final class OptionBuilder
     {
         OptionBuilder.numberOfArgs = Option.UNLIMITED_VALUES;
 
-        return instance;
+        return INSTANCE;
     }
 
     /**
@@ -231,7 +237,7 @@ public final class OptionBuilder
     {
         OptionBuilder.numberOfArgs = num;
 
-        return instance;
+        return INSTANCE;
     }
 
     /**
@@ -244,7 +250,7 @@ public final class OptionBuilder
         OptionBuilder.numberOfArgs = 1;
         OptionBuilder.optionalArg = true;
 
-        return instance;
+        return INSTANCE;
     }
 
     /**
@@ -257,7 +263,7 @@ public final class OptionBuilder
         OptionBuilder.numberOfArgs = Option.UNLIMITED_VALUES;
         OptionBuilder.optionalArg = true;
 
-        return instance;
+        return INSTANCE;
     }
 
     /**
@@ -272,21 +278,39 @@ public final class OptionBuilder
         OptionBuilder.numberOfArgs = numArgs;
         OptionBuilder.optionalArg = true;
 
-        return instance;
+        return INSTANCE;
     }
 
     /**
      * The next Option created will have a value that will be an instance
      * of <code>type</code>.
+     * <p>
+     * <b>Note:</b> this method is kept for binary compatibility and the
+     * input type is supposed to be a {@link Class} object. 
      *
      * @param newType the type of the Options argument value
      * @return the OptionBuilder instance
+     * @deprecated since 1.3, use {@link #withType(Class)} instead
      */
+    @Deprecated
     public static OptionBuilder withType(Object newType)
     {
+        return withType((Class<?>) newType);
+    }
+
+    /**
+     * The next Option created will have a value that will be an instance
+     * of <code>type</code>.
+     *
+     * @param newType the type of the Options argument value
+     * @return the OptionBuilder instance
+     * @since 1.3
+     */
+    public static OptionBuilder withType(Class<?> newType)
+    {
         OptionBuilder.type = newType;
 
-        return instance;
+        return INSTANCE;
     }
 
     /**
@@ -299,7 +323,7 @@ public final class OptionBuilder
     {
         OptionBuilder.description = newDescription;
 
-        return instance;
+        return INSTANCE;
     }
 
     /**
@@ -346,7 +370,8 @@ public final class OptionBuilder
     public static Option create(String opt) throws IllegalArgumentException
     {
         Option option = null;
-        try {
+        try
+        {
             // create the option
             option = new Option(opt, description);
 
@@ -358,7 +383,9 @@ public final class OptionBuilder
             option.setType(type);
             option.setValueSeparator(valuesep);
             option.setArgName(argName);
-        } finally {
+        }
+        finally
+        {
             // reset the OptionBuilder properties
             OptionBuilder.reset();
         }
diff --git a/src/java/org/apache/commons/cli/OptionGroup.java b/src/main/java/org/apache/commons/cli/OptionGroup.java
similarity index 81%
rename from src/java/org/apache/commons/cli/OptionGroup.java
rename to src/main/java/org/apache/commons/cli/OptionGroup.java
index 28b6399..640504c 100644
--- a/src/java/org/apache/commons/cli/OptionGroup.java
+++ b/src/main/java/org/apache/commons/cli/OptionGroup.java
@@ -26,15 +26,15 @@ import java.util.Map;
 /**
  * A group of mutually exclusive options.
  *
- * @author John Keyes ( john at integralsource.com )
- * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ * @version $Id: OptionGroup.java 1669814 2015-03-28 18:09:26Z britter $
  */
 public class OptionGroup implements Serializable
 {
+    /** The serial version UID. */
     private static final long serialVersionUID = 1L;
     
     /** hold the options */
-    private Map optionMap = new HashMap();
+    private final Map<String, Option> optionMap = new HashMap<String, Option>();
 
     /** the name of the selected option */
     private String selected;
@@ -61,7 +61,7 @@ public class OptionGroup implements Serializable
      * @return the names of the options in this group as a 
      * <code>Collection</code>
      */
-    public Collection getNames()
+    public Collection<String> getNames()
     {
         // the key set is the collection of names
         return optionMap.keySet();
@@ -70,7 +70,7 @@ public class OptionGroup implements Serializable
     /**
      * @return the options in this group as a <code>Collection</code>
      */
-    public Collection getOptions()
+    public Collection<Option> getOptions()
     {
         // the values are the collection of options
         return optionMap.values();
@@ -85,12 +85,19 @@ public class OptionGroup implements Serializable
      */
     public void setSelected(Option option) throws AlreadySelectedException
     {
+        if (option == null)
+        {
+            // reset the option previously selected
+            selected = null;
+            return;
+        }
+        
         // if no option has already been selected or the 
         // same option is being reselected then set the
         // selected member variable
-        if (selected == null || selected.equals(option.getOpt()))
+        if (selected == null || selected.equals(option.getKey()))
         {
-            selected = option.getOpt();
+            selected = option.getKey();
         }
         else
         {
@@ -129,17 +136,18 @@ public class OptionGroup implements Serializable
      * 
      * @return the stringified representation of this group
      */
+    @Override
     public String toString()
     {
-        StringBuffer buff = new StringBuffer();
-
-        Iterator iter = getOptions().iterator();
+        StringBuilder buff = new StringBuilder();
+        
+        Iterator<Option> iter = getOptions().iterator();
 
         buff.append("[");
 
         while (iter.hasNext())
         {
-            Option option = (Option) iter.next();
+            Option option = iter.next();
 
             if (option.getOpt() != null)
             {
@@ -151,10 +159,13 @@ public class OptionGroup implements Serializable
                 buff.append("--");
                 buff.append(option.getLongOpt());
             }
-
-            buff.append(" ");
-            buff.append(option.getDescription());
-
+            
+            if (option.getDescription() != null)
+            {
+                buff.append(" ");
+                buff.append(option.getDescription());
+            }
+            
             if (iter.hasNext())
             {
                 buff.append(", ");
diff --git a/src/java/org/apache/commons/cli/OptionValidator.java b/src/main/java/org/apache/commons/cli/OptionValidator.java
similarity index 71%
rename from src/java/org/apache/commons/cli/OptionValidator.java
rename to src/main/java/org/apache/commons/cli/OptionValidator.java
index 5e32e18..659ee43 100644
--- a/src/java/org/apache/commons/cli/OptionValidator.java
+++ b/src/main/java/org/apache/commons/cli/OptionValidator.java
@@ -20,57 +20,56 @@ package org.apache.commons.cli;
 /**
  * Validates an Option string.
  *
- * @author John Keyes ( john at integralsource.com )
- * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ * @version $Id: OptionValidator.java 1544819 2013-11-23 15:34:31Z tn $
  * @since 1.1
  */
-class OptionValidator
+final class OptionValidator
 {
     /**
-     * Validates whether <code>opt</code> is a permissable Option
+     * Validates whether <code>opt</code> is a permissible Option
      * shortOpt.  The rules that specify if the <code>opt</code>
      * is valid are:
      *
      * <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>
+     * <p>
+     * In case {@code opt} is {@code null} no further validation is performed.
      *
-     * @param opt The option string to validate
+     * @param opt The option string to validate, may be null
      * @throws IllegalArgumentException if the Option is not valid.
      */
     static void validateOption(String opt) throws IllegalArgumentException
     {
-        // check that opt is not NULL
+        // if opt is NULL do not check further
         if (opt == null)
         {
             return;
         }
-
+        
         // handle the single character opt
-        else if (opt.length() == 1)
+        if (opt.length() == 1)
         {
             char ch = opt.charAt(0);
 
             if (!isValidOpt(ch))
             {
-                throw new IllegalArgumentException("illegal option value '" + ch + "'");
+                throw new IllegalArgumentException("Illegal option name '" + ch + "'");
             }
         }
 
         // handle the multi character opt
         else
         {
-            char[] chars = opt.toCharArray();
-
-            for (int i = 0; i < chars.length; i++)
+            for (char ch : opt.toCharArray())
             {
-                if (!isValidChar(chars[i]))
+                if (!isValidChar(ch))
                 {
-                    throw new IllegalArgumentException("opt contains illegal character value '" + chars[i] + "'");
+                    throw new IllegalArgumentException("The option '" + opt + "' contains an illegal "
+                                                       + "character : '" + ch + "'");
                 }
             }
         }
@@ -80,12 +79,11 @@ class OptionValidator
      * Returns whether the specified character is a valid Option.
      *
      * @param c the option to validate
-     * @return true if <code>c</code> is a letter, ' ', '?' or '@',
-     *         otherwise false.
+     * @return true if <code>c</code> is a letter, '?' or '@', otherwise false.
      */
     private static boolean isValidOpt(char c)
     {
-        return isValidChar(c) || c == ' ' || c == '?' || c == '@';
+        return isValidChar(c) || c == '?' || c == '@';
     }
 
     /**
diff --git a/src/java/org/apache/commons/cli/Options.java b/src/main/java/org/apache/commons/cli/Options.java
similarity index 62%
rename from src/java/org/apache/commons/cli/Options.java
rename to src/main/java/org/apache/commons/cli/Options.java
index 0370be8..ba0af56 100644
--- a/src/java/org/apache/commons/cli/Options.java
+++ b/src/main/java/org/apache/commons/cli/Options.java
@@ -23,41 +23,42 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
 /**
- * <p>Main entry-point into the library.</p>
- *
- * <p>Options represents a collection of {@link Option} objects, which
- * describe the possible options for a command-line.<p>
- *
- * <p>It may flexibly parse long and short options, with or without
+ * Main entry-point into the library.
+ * <p>
+ * Options represents a collection of {@link Option} objects, which
+ * describe the possible options for a command-line.
+ * <p>
+ * It may flexibly parse long and short options, with or without
  * values.  Additionally, it may parse only a portion of a commandline,
- * allowing for flexible multi-stage parsing.<p>
+ * allowing for flexible multi-stage parsing.
  *
  * @see org.apache.commons.cli.CommandLine
  *
- * @author bob mcwhirter (bob @ werken.com)
- * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
- * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ * @version $Id: Options.java 1685376 2015-06-14 09:51:59Z britter $
  */
 public class Options implements Serializable
 {
+    /** The serial version UID. */
     private static final long serialVersionUID = 1L;
 
     /** a map of the options with the character key */
-    private Map shortOpts = new HashMap();
+    private final Map<String, Option> shortOpts = new LinkedHashMap<String, Option>();
 
     /** a map of the options with the long key */
-    private Map longOpts = new HashMap();
+    private final Map<String, Option> longOpts = new LinkedHashMap<String, Option>();
 
     /** a map of the required options */
-    private List requiredOpts = new ArrayList();
+    // N.B. This can contain either a String (addOption) or an OptionGroup (addOptionGroup)
+    // TODO this seems wrong
+    private final List<Object> requiredOpts = new ArrayList<Object>();
 
     /** a map of the option groups */
-    private Map optionGroups = new HashMap();
+    private final Map<String, OptionGroup> optionGroups = new HashMap<String, OptionGroup>();
 
     /**
      * Add the specified option group.
@@ -67,17 +68,13 @@ public class Options implements Serializable
      */
     public Options addOptionGroup(OptionGroup group)
     {
-        Iterator options = group.getOptions().iterator();
-
         if (group.isRequired())
         {
             requiredOpts.add(group);
         }
 
-        while (options.hasNext())
+        for (Option option : group.getOptions())
         {
-            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
@@ -95,9 +92,24 @@ public class Options implements Serializable
      *
      * @return a Collection of OptionGroup instances.
      */
-    Collection getOptionGroups()
+    Collection<OptionGroup> getOptionGroups()
+    {
+        return new HashSet<OptionGroup>(optionGroups.values());
+    }
+
+    /**
+     * Add an option that only contains a short name.
+     * The option does not take an argument.
+     *
+     * @param opt Short single-character name of the option.
+     * @param description Self-documenting description
+     * @return the resulting Options instance
+     * @since 1.3
+     */
+    public Options addOption(String opt, String description)
     {
-        return new HashSet(optionGroups.values());
+        addOption(opt, null, false, description);
+        return this;
     }
 
     /**
@@ -112,7 +124,6 @@ public class Options implements Serializable
     public Options addOption(String opt, boolean hasArg, String description)
     {
         addOption(opt, null, hasArg, description);
-
         return this;
     }
 
@@ -129,7 +140,6 @@ public class Options implements Serializable
     public Options addOption(String opt, String longOpt, boolean hasArg, String description)
     {
         addOption(new Option(opt, longOpt, hasArg, description));
-
         return this;
     }
 
@@ -169,7 +179,7 @@ public class Options implements Serializable
      *
      * @return read-only Collection of {@link Option} objects in this descriptor
      */
-    public Collection getOptions()
+    public Collection<Option> getOptions()
     {
         return Collections.unmodifiableCollection(helpOptions());
     }
@@ -179,19 +189,19 @@ public class Options implements Serializable
      *
      * @return the List of Options
      */
-    List helpOptions()
+    List<Option> helpOptions()
     {
-        return new ArrayList(shortOpts.values());
+        return new ArrayList<Option>(shortOpts.values());
     }
 
     /**
      * Returns the required options.
      *
-     * @return List of required options
+     * @return read-only List of required options
      */
     public List getRequiredOptions()
     {
-        return requiredOpts;
+        return Collections.unmodifiableList(requiredOpts);
     }
 
     /**
@@ -207,18 +217,47 @@ public class Options implements Serializable
 
         if (shortOpts.containsKey(opt))
         {
-            return (Option) shortOpts.get(opt);
+            return shortOpts.get(opt);
+        }
+
+        return longOpts.get(opt);
+    }
+
+    /**
+     * Returns the options with a long name starting with the name specified.
+     * 
+     * @param opt the partial name of the option
+     * @return the options matching the partial name specified, or an empty list if none matches
+     * @since 1.3
+     */
+    public List<String> getMatchingOptions(String opt)
+    {
+        opt = Util.stripLeadingHyphens(opt);
+        
+        List<String> matchingOpts = new ArrayList<String>();
+
+        // for a perfect match return the single option only
+        if (longOpts.keySet().contains(opt))
+        {
+            return Collections.singletonList(opt);
         }
 
-        return (Option) longOpts.get(opt);
+        for (String longOpt : longOpts.keySet())
+        {
+            if (longOpt.startsWith(opt))
+            {
+                matchingOpts.add(longOpt);
+            }
+        }
+        
+        return matchingOpts;
     }
 
     /**
      * 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}
+     * @return true if the named {@link Option} is a member of this {@link Options}
      */
     public boolean hasOption(String opt)
     {
@@ -228,6 +267,34 @@ public class Options implements Serializable
     }
 
     /**
+     * Returns whether the named {@link Option} is a member of this {@link Options}.
+     *
+     * @param opt long name of the {@link Option}
+     * @return true if the named {@link Option} is a member of this {@link Options}
+     * @since 1.3
+     */
+    public boolean hasLongOption(String opt)
+    {
+        opt = Util.stripLeadingHyphens(opt);
+
+        return longOpts.containsKey(opt);
+    }
+
+    /**
+     * Returns whether the named {@link Option} is a member of this {@link Options}.
+     *
+     * @param opt short name of the {@link Option}
+     * @return true if the named {@link Option} is a member of this {@link Options}
+     * @since 1.3
+     */
+    public boolean hasShortOption(String opt)
+    {
+        opt = Util.stripLeadingHyphens(opt);
+
+        return shortOpts.containsKey(opt);
+    }
+
+    /**
      * Returns the OptionGroup the <code>opt</code> belongs to.
      * @param opt the option whose OptionGroup is being queried.
      *
@@ -236,7 +303,7 @@ public class Options implements Serializable
      */
     public OptionGroup getOptionGroup(Option opt)
     {
-        return (OptionGroup) optionGroups.get(opt.getKey());
+        return optionGroups.get(opt.getKey());
     }
 
     /**
@@ -244,9 +311,10 @@ public class Options implements Serializable
      *
      * @return Stringified form of this object
      */
+    @Override
     public String toString()
     {
-        StringBuffer buf = new StringBuffer();
+        StringBuilder buf = new StringBuilder();
 
         buf.append("[ Options: [ short ");
         buf.append(shortOpts.toString());
diff --git a/src/java/org/apache/commons/cli/ParseException.java b/src/main/java/org/apache/commons/cli/ParseException.java
similarity index 85%
rename from src/java/org/apache/commons/cli/ParseException.java
rename to src/main/java/org/apache/commons/cli/ParseException.java
index cb13320..e0cdd3f 100644
--- a/src/java/org/apache/commons/cli/ParseException.java
+++ b/src/main/java/org/apache/commons/cli/ParseException.java
@@ -20,12 +20,16 @@ package org.apache.commons.cli;
 /**
  * Base for Exceptions thrown during parsing of a command-line.
  *
- * @author bob mcwhirter (bob @ werken.com)
- * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ * @version $Id: ParseException.java 1443102 2013-02-06 18:12:16Z tn $
  */
 public class ParseException extends Exception
 {
     /**
+     * This exception {@code serialVersionUID}.
+     */
+    private static final long serialVersionUID = 9112808380089253192L;
+
+    /**
      * Construct a new <code>ParseException</code>
      * with the specified detail message.
      *
diff --git a/src/java/org/apache/commons/cli/Parser.java b/src/main/java/org/apache/commons/cli/Parser.java
similarity index 75%
rename from src/java/org/apache/commons/cli/Parser.java
rename to src/main/java/org/apache/commons/cli/Parser.java
index d6826f5..0025275 100644
--- a/src/java/org/apache/commons/cli/Parser.java
+++ b/src/main/java/org/apache/commons/cli/Parser.java
@@ -20,7 +20,6 @@ package org.apache.commons.cli;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Enumeration;
-import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Properties;
@@ -28,9 +27,10 @@ import java.util.Properties;
 /**
  * <code>Parser</code> creates {@link CommandLine}s.
  *
- * @author John Keyes (john at integralsource.com)
- * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ * @version $Id: Parser.java 1677406 2015-05-03 14:27:31Z britter $
+ * @deprecated since 1.3, the two-pass parsing with the flatten method is not enough flexible to handle complex cases
  */
+ at Deprecated
 public abstract class Parser implements CommandLineParser
 {
     /** commandline instance */
@@ -42,7 +42,7 @@ public abstract class Parser implements CommandLineParser
     /** list of required options strings */
     private List requiredOptions;
 
-    protected void setOptions(final Options options)
+    protected void setOptions(Options options)
     {
         this.options = options;
         this.requiredOptions = new ArrayList(options.getRequiredOptions());
@@ -67,18 +67,21 @@ public abstract class Parser implements CommandLineParser
      * @param stopAtNonOption specifies whether to stop
      * flattening when a non option has been encountered
      * @return a String array of the flattened arguments
+     * @throws ParseException if there are any problems encountered
+     *                        while parsing the command line tokens.
      */
-    protected abstract String[] flatten(Options opts, String[] arguments, boolean stopAtNonOption);
+    protected abstract String[] flatten(Options opts, String[] arguments, boolean stopAtNonOption)
+            throws ParseException;
 
     /**
      * Parses the specified <code>arguments</code> based
-     * on the specifed {@link Options}.
+     * on the specified {@link Options}.
      *
      * @param options the <code>Options</code>
      * @param arguments the <code>arguments</code>
      * @return the <code>CommandLine</code>
-     * @throws ParseException if an error occurs when parsing the
-     * arguments.
+     * @throws ParseException if there are any problems encountered
+     *                        while parsing the command line tokens.
      */
     public CommandLine parse(Options options, String[] arguments) throws ParseException
     {
@@ -104,13 +107,14 @@ public abstract class Parser implements CommandLineParser
 
     /**
      * Parses the specified <code>arguments</code>
-     * based on the specifed {@link Options}.
+     * based on the specified {@link Options}.
      *
      * @param options         the <code>Options</code>
      * @param arguments       the <code>arguments</code>
-     * @param stopAtNonOption specifies whether to stop interpreting the
-     *                        arguments when a non option has been encountered
-     *                        and to add them to the CommandLines args list.
+     * @param stopAtNonOption if <tt>true</tt> an unrecognized argument stops
+     *     the parsing and the remaining arguments are added to the 
+     *     {@link CommandLine}s args list. If <tt>false</tt> an unrecognized
+     *     argument triggers a ParseException.
      * @return the <code>CommandLine</code>
      * @throws ParseException if an error occurs when parsing the arguments.
      */
@@ -126,8 +130,10 @@ public abstract class Parser implements CommandLineParser
      * @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.
+     * @param stopAtNonOption if <tt>true</tt> an unrecognized argument stops
+     *     the parsing and the remaining arguments are added to the 
+     *     {@link CommandLine}s args list. If <tt>false</tt> an unrecognized
+     *     argument triggers a ParseException.
      *
      * @return the list of atomic option and value tokens
      *
@@ -140,11 +146,16 @@ public abstract class Parser implements CommandLineParser
             throws ParseException
     {
         // clear out the data in options in case it's been used before (CLI-71)
-        for (Iterator it = options.helpOptions().iterator(); it.hasNext();)
+        for (Option opt : options.helpOptions())
         {
-            Option opt = (Option) it.next();
             opt.clearValues();
         }
+        
+        // clear the data from the groups
+        for (OptionGroup group : options.getOptionGroups())
+        {
+            group.setSelected(null);
+        }        
 
         // initialise members
         setOptions(options);
@@ -158,14 +169,14 @@ public abstract class Parser implements CommandLineParser
             arguments = new String[0];
         }
 
-        List tokenList = Arrays.asList(flatten(getOptions(), arguments, stopAtNonOption));
+        List<String> tokenList = Arrays.asList(flatten(getOptions(), arguments, stopAtNonOption));
 
-        ListIterator iterator = tokenList.listIterator();
+        ListIterator<String> iterator = tokenList.listIterator();
 
         // process each flattened token
         while (iterator.hasNext())
         {
-            String t = (String) iterator.next();
+            String t = iterator.next();
 
             // the value is the double-dash
             if ("--".equals(t))
@@ -216,7 +227,7 @@ public abstract class Parser implements CommandLineParser
             {
                 while (iterator.hasNext())
                 {
-                    String str = (String) iterator.next();
+                    String str = iterator.next();
 
                     // ensure only one double-dash is added
                     if (!"--".equals(str))
@@ -237,22 +248,32 @@ public abstract class Parser implements CommandLineParser
      * Sets the values of Options using the values in <code>properties</code>.
      *
      * @param properties The value properties to be processed.
+     * @throws ParseException if there are any problems encountered
+     *                        while processing the properties.
      */
-    protected void processProperties(Properties properties)
+    protected void processProperties(Properties properties) throws ParseException
     {
         if (properties == null)
         {
             return;
         }
 
-        for (Enumeration e = properties.propertyNames(); e.hasMoreElements();)
+        for (Enumeration<?> e = properties.propertyNames(); e.hasMoreElements();)
         {
             String option = e.nextElement().toString();
-
-            if (!cmd.hasOption(option))
+            
+            Option opt = options.getOption(option);
+            if (opt == null)
+            {
+                throw new UnrecognizedOptionException("Default option wasn't defined", option);
+            }
+            
+            // if the option is part of a group, check if another option of the group has been selected
+            OptionGroup group = options.getOptionGroup(opt);
+            boolean selected = group != null && group.getSelected() != null;
+            
+            if (!cmd.hasOption(option) && !selected)
             {
-                Option opt = getOptions().getOption(option);
-
                 // get the value from the properties instance
                 String value = properties.getProperty(option);
 
@@ -264,7 +285,7 @@ public abstract class Parser implements CommandLineParser
                         {
                             opt.addValueForProcessing(value);
                         }
-                        catch (RuntimeException exp)
+                        catch (RuntimeException exp) //NOPMD
                         {
                             // if we cannot add the value don't worry about it
                         }
@@ -276,10 +297,11 @@ public abstract class Parser implements CommandLineParser
                 {
                     // if the value is not yes, true or 1 then don't add the
                     // option to the CommandLine
-                    break;
+                    continue;
                 }
 
                 cmd.addOption(opt);
+                updateRequiredOptions(opt);
             }
         }
     }
@@ -288,12 +310,11 @@ public abstract class Parser implements CommandLineParser
      * Throws a {@link MissingOptionException} if all of the required options
      * are not present.
      *
-     * @throws MissingOptionException if any of the required Options
-     * are not present.
+     * @throws MissingOptionException if any of the required Options are not present.
      */
     protected void checkRequiredOptions() throws MissingOptionException
     {
-        // if there are required options that have not been processsed
+        // if there are required options that have not been processed
         if (!getRequiredOptions().isEmpty())
         {
             throw new MissingOptionException(getRequiredOptions());
@@ -301,24 +322,23 @@ public abstract class Parser implements CommandLineParser
     }
 
     /**
-     * <p>Process the argument values for the specified Option
+     * 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.
+     * @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
+    public void processArgs(Option opt, ListIterator<String> iter) throws ParseException
     {
         // loop until an option is found
         while (iter.hasNext())
         {
-            String str = (String) iter.next();
-
+            String str = iter.next();
+            
             // found an Option, not an argument
             if (getOptions().hasOption(str) && str.startsWith("-"))
             {
@@ -346,14 +366,14 @@ public abstract class Parser implements CommandLineParser
 
     /**
      * Process the Option specified by <code>arg</code> using the values
-     * retrieved from the specfied iterator <code>iter</code>.
+     * retrieved from the specified 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
      */
-    protected void processOption(String arg, ListIterator iter) throws ParseException
+    protected void processOption(String arg, ListIterator<String> iter) throws ParseException
     {
         boolean hasOption = getOptions().hasOption(arg);
 
@@ -365,7 +385,27 @@ public abstract class Parser implements CommandLineParser
 
         // get the option represented by arg
         Option opt = (Option) getOptions().getOption(arg).clone();
+        
+        // update the required options and groups
+        updateRequiredOptions(opt);
+        
+        // if the option takes an argument value
+        if (opt.hasArg())
+        {
+            processArgs(opt, iter);
+        }
+        
+        // set the option on the command line
+        cmd.addOption(opt);
+    }
 
+    /**
+     * Removes the option or its group from the list of expected elements.
+     * 
+     * @param opt
+     */
+    private void updateRequiredOptions(Option opt) throws ParseException
+    {
         // if the option is a required option remove the option from
         // the requiredOptions list
         if (opt.isRequired())
@@ -386,14 +426,5 @@ public abstract class Parser implements CommandLineParser
 
             group.setSelected(opt);
         }
-
-        // if the option takes an argument value
-        if (opt.hasArg())
-        {
-            processArgs(opt, iter);
-        }
-
-        // set the option on the command line
-        cmd.addOption(opt);
     }
 }
diff --git a/src/java/org/apache/commons/cli/PatternOptionBuilder.java b/src/main/java/org/apache/commons/cli/PatternOptionBuilder.java
similarity index 68%
rename from src/java/org/apache/commons/cli/PatternOptionBuilder.java
rename to src/main/java/org/apache/commons/cli/PatternOptionBuilder.java
index 6176027..6a5c4ce 100644
--- a/src/java/org/apache/commons/cli/PatternOptionBuilder.java
+++ b/src/main/java/org/apache/commons/cli/PatternOptionBuilder.java
@@ -23,67 +23,69 @@ import java.net.URL;
 import java.util.Date;
 
 /**
- * <p>
- * Allows Options to be created from a single String.
+ * <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>
+ *   <caption>Overview of PatternOptionBuilder patterns</caption>
+ *   <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 constructor)</td></tr>
+ *   <tr><td>e%</td><td>-e [number] (creates Double/Long instance depending 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'.
  * The exclamation mark precede a mandatory option.
  * </p>
- * <code>Options options = PatternOptionBuilder.parsePattern("vp:!f/");</code>
+ *
+ * <pre>
+ *     Options options = PatternOptionBuilder.parsePattern("vp:!f/");
+ * </pre>
  *
  * <p>
- * TODO These need to break out to OptionType and also
- * to be pluggable.
+ * TODO: These need to break out to OptionType and also to be pluggable.
  * </p>
  *
- * @version $Revision: 734339 $, $Date: 2009-01-13 21:56:47 -0800 (Tue, 13 Jan 2009) $
+ * @version $Id: PatternOptionBuilder.java 1677406 2015-05-03 14:27:31Z britter $
  */
 public class PatternOptionBuilder
 {
     /** String class */
-    public static final Class STRING_VALUE = String.class;
+    public static final Class<String> STRING_VALUE = String.class;
 
     /** Object class */
-    public static final Class OBJECT_VALUE = Object.class;
+    public static final Class<Object> OBJECT_VALUE = Object.class;
 
     /** Number class */
-    public static final Class NUMBER_VALUE = Number.class;
+    public static final Class<Number> NUMBER_VALUE = Number.class;
 
     /** Date class */
-    public static final Class DATE_VALUE = Date.class;
+    public static final Class<Date> DATE_VALUE = Date.class;
 
     /** Class class */
-    public static final Class CLASS_VALUE = Class.class;
+    public static final Class<?> CLASS_VALUE = 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.
 
     /** FileInputStream class */
-    public static final Class EXISTING_FILE_VALUE = FileInputStream.class;
+    public static final Class<FileInputStream> EXISTING_FILE_VALUE = FileInputStream.class;
 
     /** File class */
-    public static final Class FILE_VALUE = File.class;
+    public static final Class<File> FILE_VALUE = File.class;
 
     /** File array class */
-    public static final Class FILES_VALUE = File[].class;
+    public static final Class<File[]> FILES_VALUE = File[].class;
 
     /** URL class */
-    public static final Class URL_VALUE = URL.class;
+    public static final Class<URL> URL_VALUE = URL.class;
 
     /**
      * Retrieve the class that <code>ch</code> represents.
@@ -149,7 +151,7 @@ public class PatternOptionBuilder
     {
         char opt = ' ';
         boolean required = false;
-        Object type = null;
+        Class<?> type = null;
 
         Options options = new Options();
 
@@ -163,12 +165,14 @@ public class PatternOptionBuilder
             {
                 if (opt != ' ')
                 {
-                    OptionBuilder.hasArg(type != null);
-                    OptionBuilder.isRequired(required);
-                    OptionBuilder.withType(type);
-
+                    final Option option = Option.builder(String.valueOf(opt))
+                        .hasArg(type != null)
+                        .required(required)
+                        .type(type)
+                        .build();
+                    
                     // we have a previous one to deal with
-                    options.addOption(OptionBuilder.create(opt));
+                    options.addOption(option);
                     required = false;
                     type = null;
                     opt = ' ';
@@ -182,18 +186,20 @@ public class PatternOptionBuilder
             }
             else
             {
-                type = getValueClass(ch);
+                type = (Class<?>) getValueClass(ch);
             }
         }
 
         if (opt != ' ')
         {
-            OptionBuilder.hasArg(type != null);
-            OptionBuilder.isRequired(required);
-            OptionBuilder.withType(type);
-
+            final Option option = Option.builder(String.valueOf(opt))
+                .hasArg(type != null)
+                .required(required)
+                .type(type)
+                .build();
+            
             // we have a final one to deal with
-            options.addOption(OptionBuilder.create(opt));
+            options.addOption(option);
         }
 
         return options;
diff --git a/src/java/org/apache/commons/cli/PosixParser.java b/src/main/java/org/apache/commons/cli/PosixParser.java
similarity index 84%
rename from src/java/org/apache/commons/cli/PosixParser.java
rename to src/main/java/org/apache/commons/cli/PosixParser.java
index d384b23..24eb533 100644
--- a/src/java/org/apache/commons/cli/PosixParser.java
+++ b/src/main/java/org/apache/commons/cli/PosixParser.java
@@ -26,13 +26,14 @@ import java.util.List;
  * The class PosixParser provides an implementation of the
  * {@link Parser#flatten(Options,String[],boolean) flatten} method.
  *
- * @author John Keyes (john at integralsource.com)
- * @version $Revision: 695760 $, $Date: 2008-09-16 01:05:03 -0700 (Tue, 16 Sep 2008) $
+ * @version $Id: PosixParser.java 1677451 2015-05-03 17:09:29Z ggregory $
+ * @deprecated since 1.3, use the {@link DefaultParser} instead
  */
+ at Deprecated
 public class PosixParser extends Parser
 {
     /** holder for flattened tokens */
-    private List tokens = new ArrayList();
+    private final List<String> tokens = new ArrayList<String>();
 
     /** specifies if bursting should continue */
     private boolean eatTheRest;
@@ -58,7 +59,7 @@ public class PosixParser extends Parser
      * <p>An implementation of {@link Parser}'s abstract
      * {@link Parser#flatten(Options,String[],boolean) flatten} method.</p>
      *
-     * <p>The following are the rules used by this flatten method.
+     * <p>The following are the rules used by this flatten method.</p>
      * <ol>
      *  <li>if <code>stopAtNonOption</code> is <b>true</b> then do not
      *  burst anymore of <code>arguments</code> entries, just add each
@@ -84,7 +85,6 @@ public class PosixParser extends Parser
      *  by any of the previous rules, then the entry is added to the list
      *  of processed tokens.</li>
      * </ol>
-     * </p>
      *
      * @param options The command line {@link Options}
      * @param arguments The command line arguments to be parsed
@@ -92,35 +92,48 @@ 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)
+    @Override
+    protected String[] flatten(Options options, String[] arguments, boolean stopAtNonOption) throws ParseException
     {
         init();
         this.options = options;
 
         // an iterator for the command line tokens
-        Iterator iter = Arrays.asList(arguments).iterator();
+        Iterator<String> iter = Arrays.asList(arguments).iterator();
 
         // process each command line token
         while (iter.hasNext())
         {
             // get the next command line token
-            String token = (String) iter.next();
+            String token = iter.next();
 
+            // single or double hyphen
+            if ("-".equals(token) || "--".equals(token))
+            {
+                tokens.add(token);
+            }
+            
             // handle long option --foo or --foo=bar
-            if (token.startsWith("--"))
+            else if (token.startsWith("--"))
             {
                 int pos = token.indexOf('=');
                 String opt = pos == -1 ? token : token.substring(0, pos); // --foo
+                
+                List<String> matchingOpts = options.getMatchingOptions(opt);
 
-                if (!options.hasOption(opt))
+                if (matchingOpts.isEmpty())
                 {
                     processNonOptionToken(token, stopAtNonOption);
                 }
+                else if (matchingOpts.size() > 1)
+                {
+                    throw new AmbiguousOptionException(opt, matchingOpts);
+                }
                 else
                 {
-                    currentOption = options.getOption(opt);
+                    currentOption = options.getOption(matchingOpts.get(0));
                     
-                    tokens.add(opt);
+                    tokens.add("--" + currentOption.getLongOpt());
                     if (pos != -1)
                     {
                         tokens.add(token.substring(pos + 1));
@@ -128,17 +141,22 @@ public class PosixParser extends Parser
                 }
             }
 
-            // single hyphen
-            else if ("-".equals(token))
-            {
-                tokens.add(token);
-            }
             else if (token.startsWith("-"))
             {
                 if (token.length() == 2 || options.hasOption(token))
                 {
                     processOptionToken(token, stopAtNonOption);
                 }
+                else if (!options.getMatchingOptions(token).isEmpty())
+                {
+                    List<String> matchingOpts = options.getMatchingOptions(token);
+                    if (matchingOpts.size() > 1)
+                    {
+                        throw new AmbiguousOptionException(token, matchingOpts);
+                    }
+                    Option opt = options.getOption(matchingOpts.get(0));
+                    processOptionToken("-" + opt.getLongOpt(), stopAtNonOption);
+                }
                 // requires bursting
                 else
                 {
@@ -153,7 +171,7 @@ public class PosixParser extends Parser
             gobble(iter);
         }
 
-        return (String[]) tokens.toArray(new String[tokens.size()]);
+        return tokens.toArray(new String[tokens.size()]);
     }
 
     /**
@@ -161,7 +179,7 @@ public class PosixParser extends Parser
      *
      * @param iter An iterator over the remaining tokens
      */
-    private void gobble(Iterator iter)
+    private void gobble(Iterator<String> iter)
     {
         if (eatTheRest)
         {
@@ -254,7 +272,7 @@ public class PosixParser extends Parser
                 tokens.add("-" + ch);
                 currentOption = options.getOption(ch);
 
-                if (currentOption.hasArg() && (token.length() != (i + 1)))
+                if (currentOption.hasArg() && token.length() != i + 1)
                 {
                     tokens.add(token.substring(i + 1));
 
diff --git a/src/java/org/apache/commons/cli/TypeHandler.java b/src/main/java/org/apache/commons/cli/TypeHandler.java
similarity index 73%
rename from src/java/org/apache/commons/cli/TypeHandler.java
rename to src/main/java/org/apache/commons/cli/TypeHandler.java
index 5289b82..cc91274 100644
--- a/src/java/org/apache/commons/cli/TypeHandler.java
+++ b/src/main/java/org/apache/commons/cli/TypeHandler.java
@@ -25,13 +25,13 @@ import java.net.URL;
 import java.util.Date;
 
 /**
-  * This is a temporary implementation. TypeHandler will handle the
-  * pluggableness of OptionTypes and it will direct all of these types
-  * of conversion functionalities to ConvertUtils component in Commons
-  * already. BeanUtils I think.
-  *
-  * @version $Revision: 741425 $, $Date: 2009-02-05 22:10:54 -0800 (Thu, 05 Feb 2009) $
-  */
+ * This is a temporary implementation. TypeHandler will handle the
+ * pluggableness of OptionTypes and it will direct all of these types
+ * of conversion functionalities to ConvertUtils component in Commons
+ * already. BeanUtils I think.
+ *
+ * @version $Id: TypeHandler.java 1677452 2015-05-03 17:10:00Z ggregory $
+ */
 public class TypeHandler
 {
     /**
@@ -42,11 +42,11 @@ public class TypeHandler
      * @param obj the type of argument
      * @return The instance of <code>obj</code> initialised with
      * the value of <code>str</code>.
+     * @throws ParseException if the value creation for the given object type failed
      */
-    public static Object createValue(String str, Object obj)
-    throws ParseException
+    public static Object createValue(String str, Object obj) throws ParseException
     {
-        return createValue(str, (Class) obj);
+        return createValue(str, (Class<?>) obj);
     }
 
     /**
@@ -57,9 +57,9 @@ public class TypeHandler
      * @param clazz the type of argument
      * @return The instance of <code>clazz</code> initialised with
      * the value of <code>str</code>.
+     * @throws ParseException if the value creation for the given class failed
      */
-    public static Object createValue(String str, Class clazz)
-    throws ParseException
+    public static Object createValue(String str, Class<?> clazz) throws ParseException
     {
         if (PatternOptionBuilder.STRING_VALUE == clazz)
         {
@@ -107,13 +107,12 @@ public class TypeHandler
       * Create an Object from the classname and empty constructor.
       *
       * @param classname the argument value
-      * @return the initialised object, or null if it couldn't create
-      * the Object.
+      * @return the initialised object
+      * @throws ParseException if the class could not be found or the object could not be created
       */
-    public static Object createObject(String classname)
-    throws ParseException
+    public static Object createObject(String classname) throws ParseException
     {
-        Class cl = null;
+        Class<?> cl;
 
         try
         {
@@ -123,19 +122,15 @@ public class TypeHandler
         {
             throw new ParseException("Unable to find the class: " + classname);
         }
-
-        Object instance = null;
-
+        
         try
         {
-            instance = cl.newInstance();
+            return cl.newInstance();
         }
         catch (Exception e)
         {
             throw new ParseException(e.getClass().getName() + "; Unable to create an instance of: " + classname);
         }
-
-        return instance;
     }
 
     /**
@@ -143,11 +138,10 @@ public class TypeHandler
      * Double, otherwise a Long.
      *
      * @param str the value
-     * @return the number represented by <code>str</code>, if <code>str</code>
-     * is not a number, null is returned.
+     * @return the number represented by <code>str</code>
+     * @throws ParseException if <code>str</code> is not a number
      */
-    public static Number createNumber(String str)
-    throws ParseException
+    public static Number createNumber(String str) throws ParseException
     {
         try
         {
@@ -155,10 +149,7 @@ public class TypeHandler
             {
                 return Double.valueOf(str);
             }
-            else
-            {
-                return Long.valueOf(str);
-            }
+            return Long.valueOf(str);
         }
         catch (NumberFormatException e)
         {
@@ -170,10 +161,10 @@ public class TypeHandler
      * Returns the class whose name is <code>classname</code>.
      *
      * @param classname the class name
-     * @return The class if it is found, otherwise return null
+     * @return The class if it is found
+     * @throws ParseException if the class could not be found
      */
-    public static Class createClass(String classname)
-    throws ParseException
+    public static Class<?> createClass(String classname) throws ParseException
     {
         try
         {
@@ -187,13 +178,16 @@ public class TypeHandler
 
     /**
      * Returns the date represented by <code>str</code>.
+     * <p>
+     * This method is not yet implemented and always throws an
+     * {@link UnsupportedOperationException}.
      *
      * @param str the date string
      * @return The date if <code>str</code> is a valid date string,
      * otherwise return null.
+     * @throws UnsupportedOperationException always
      */
     public static Date createDate(String str)
-    throws ParseException
     {
         throw new UnsupportedOperationException("Not yet implemented");
     }
@@ -202,11 +196,10 @@ public class TypeHandler
      * Returns the URL represented by <code>str</code>.
      *
      * @param str the URL string
-     * @return The URL is <code>str</code> is well-formed, otherwise
-     * return null.
+     * @return The URL in <code>str</code> is well-formed
+     * @throws ParseException if the URL in <code>str</code> is not well-formed
      */
-    public static URL createURL(String str)
-    throws ParseException
+    public static URL createURL(String str) throws ParseException
     {
         try
         {
@@ -225,19 +218,21 @@ public class TypeHandler
      * @return The file represented by <code>str</code>.
      */
     public static File createFile(String str)
-    throws ParseException
     {
         return new File(str);
     }
 
     /**
      * Returns the File[] represented by <code>str</code>.
+     * <p>
+     * This method is not yet implemented and always throws an
+     * {@link UnsupportedOperationException}.
      *
      * @param str the paths to the files
      * @return The File[] represented by <code>str</code>.
+     * @throws UnsupportedOperationException always
      */
     public static File[] createFiles(String str)
-    throws ParseException
     {
         // to implement/port:
         //        return FileW.findFiles(str);
diff --git a/src/java/org/apache/commons/cli/UnrecognizedOptionException.java b/src/main/java/org/apache/commons/cli/UnrecognizedOptionException.java
similarity index 89%
rename from src/java/org/apache/commons/cli/UnrecognizedOptionException.java
rename to src/main/java/org/apache/commons/cli/UnrecognizedOptionException.java
index d06b05f..4754c95 100644
--- a/src/java/org/apache/commons/cli/UnrecognizedOptionException.java
+++ b/src/main/java/org/apache/commons/cli/UnrecognizedOptionException.java
@@ -21,11 +21,15 @@ package org.apache.commons.cli;
  * Exception thrown during parsing signalling an unrecognized
  * option was seen.
  *
- * @author bob mcwhiter (bob @ werken.com)
- * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ * @version $Id: UnrecognizedOptionException.java 1443102 2013-02-06 18:12:16Z tn $
  */
 public class UnrecognizedOptionException extends ParseException
 {
+    /**
+     * This exception {@code serialVersionUID}.
+     */
+    private static final long serialVersionUID = -252504690284625623L;
+
     /** The  unrecognized option */
     private String option;
 
diff --git a/src/java/org/apache/commons/cli/Util.java b/src/main/java/org/apache/commons/cli/Util.java
similarity index 82%
rename from src/java/org/apache/commons/cli/Util.java
rename to src/main/java/org/apache/commons/cli/Util.java
index 4efa307..89cf5ff 100644
--- a/src/java/org/apache/commons/cli/Util.java
+++ b/src/main/java/org/apache/commons/cli/Util.java
@@ -20,13 +20,12 @@ package org.apache.commons.cli;
 /**
  * Contains useful helper methods for classes within this package.
  *
- * @author John Keyes (john at integralsource.com)
- * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ * @version $Id: Util.java 1443102 2013-02-06 18:12:16Z tn $
  */
-class Util
+final class Util
 {
     /**
-     * Remove the hyphens from the begining of <code>str</code> and
+     * Remove the hyphens from the beginning of <code>str</code> and
      * return the new String.
      *
      * @param str The string from which the hyphens should be removed.
@@ -62,14 +61,12 @@ class Util
      */
     static String stripLeadingAndTrailingQuotes(String str)
     {
-        if (str.startsWith("\""))
+        int length = str.length();
+        if (length > 1 && str.startsWith("\"") && str.endsWith("\"") && str.substring(1, length - 1).indexOf('"') == -1)
         {
-            str = str.substring(1, str.length());
-        }
-        if (str.endsWith("\""))
-        {
-            str = str.substring(0, str.length() - 1);
+            str = str.substring(1, length - 1);
         }
+        
         return str;
     }
 }
diff --git a/src/java/org/apache/commons/cli/overview.html b/src/main/java/org/apache/commons/cli/overview.html
similarity index 97%
rename from src/java/org/apache/commons/cli/overview.html
rename to src/main/java/org/apache/commons/cli/overview.html
index eec9ce7..3eab806 100644
--- a/src/java/org/apache/commons/cli/overview.html
+++ b/src/main/java/org/apache/commons/cli/overview.html
@@ -16,7 +16,7 @@ limitations under the License.
 -->
 <body>
 
-    <p>Commons CLI -- version 1.2</p>
+    <p>Commons CLI -- version 1.3</p>
 
     <p>The commons-cli package aides in parsing command-line arguments.</p>
 
diff --git a/src/conf/HEADER.txt b/src/main/java/org/apache/commons/cli/package-info.java
similarity index 85%
rename from src/conf/HEADER.txt
rename to src/main/java/org/apache/commons/cli/package-info.java
index 8c563ab..2b7dd19 100644
--- a/src/conf/HEADER.txt
+++ b/src/main/java/org/apache/commons/cli/package-info.java
@@ -14,3 +14,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+/**
+ * Commons CLI 1.3
+ * 
+ * @version $Id: package-info.java 1443102 2013-02-06 18:12:16Z tn $
+ */
+package org.apache.commons.cli;
diff --git a/src/media/logo.xcf b/src/media/logo.xcf
index fb1cd2b..df9cbda 100644
Binary files a/src/media/logo.xcf and b/src/media/logo.xcf differ
diff --git a/src/site/resources/download_cli.cgi b/src/site/resources/download_cli.cgi
new file mode 100644
index 0000000..495cde1
--- /dev/null
+++ b/src/site/resources/download_cli.cgi
@@ -0,0 +1,4 @@
+#!/bin/sh
+# Just call the standard mirrors.cgi script. It will use download.html
+# as the input template.
+exec /www/www.apache.org/dyn/mirrors/mirrors.cgi $*
\ No newline at end of file
diff --git a/src/site/resources/images/1x1.gif b/src/site/resources/images/1x1.gif
new file mode 100755
index 0000000..35d42e8
Binary files /dev/null and b/src/site/resources/images/1x1.gif differ
diff --git a/src/site/resources/images/logo.png b/src/site/resources/images/logo.png
new file mode 100644
index 0000000..4423550
Binary files /dev/null and b/src/site/resources/images/logo.png differ
diff --git a/src/site/resources/images/options.png b/src/site/resources/images/options.png
new file mode 100644
index 0000000..b0f9d8f
Binary files /dev/null and b/src/site/resources/images/options.png differ
diff --git a/src/site/resources/images/svg/commandlines.svg b/src/site/resources/images/svg/commandlines.svg
new file mode 100644
index 0000000..3ab520c
--- /dev/null
+++ b/src/site/resources/images/svg/commandlines.svg
@@ -0,0 +1,57 @@
+<?xml version="1.0" standalone="no"?>
+<?xml-stylesheet type="text/css" href="diagrams.css" ?>
+<!--
+ * 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.
+-->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+
+<svg id="root" width="420" height="360" x="0" y="0">
+
+<script type="text/ecmascript" xlink:href="diagrams.js"/>
+<script type="text/ecmascript" xlink:href="diagrams-cli2.js"/>
+<script type="text/ecmascript">
+
+displayAttributes = false;
+displayMethods = false;
+
+</script>
+
+<g 
+	onload="new PackageSymbol('org.apache.commons.cli2',400,340).insert(evt)" 
+	transform="translate(10,10)"><g transform="translate(10,30)">
+	
+	<g transform="translate(  0, 30)" class="option"   onload="CommandLine.insert(evt);" />
+	<g transform="translate(  0,130)" class="group"    onload="WriteableCommandLine.insert(evt);"/>
+	
+	<g 
+		onload="new PackageSymbol('commandline',180,300).insert(evt)" 
+		transform="translate(200,0)"><g transform="translate(10,30)">
+		
+		<g transform="translate(0,  0)" class="option"   onload="Parser.insert(evt);" />
+		<g transform="translate(0, 50)" class="parent"   onload="DefaultingCommandLine.insert(evt);" />
+		<g transform="translate(0,100)" class="parent"   onload="PropertiesCommandLine.insert(evt);" />
+		<g transform="translate(0,190)" class="parent"   onload="PreferencesCommandLine.insert(evt);" />
+	</g></g>
+<!--	
+-->
+
+<polyline class="extends"    points="80,130 80,70"/>
+<polyline class="implements" points="210, 95 180, 95 180,45 170,45"/>
+<polyline class="implements" points="210,145 180,145 180,45 170,45"/>
+<polyline class="implements" points="210,235 180,235 180,45 170,45"/>
+
+</g></g>
+</svg>
\ No newline at end of file
diff --git a/src/site/resources/images/svg/diagrams-cli2.js b/src/site/resources/images/svg/diagrams-cli2.js
new file mode 100644
index 0000000..9f1a9a2
--- /dev/null
+++ b/src/site/resources/images/svg/diagrams-cli2.js
@@ -0,0 +1,291 @@
+/*
+ * 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.
+ */
+ 
+var Option = new Interface("Option");
+Option.addMethod("process(...)");
+Option.addMethod("canProcess(...)");
+Option.addMethod("getTriggers()");
+Option.addMethod("getPrefixes()");
+Option.addMethod("validate(...)");
+Option.addMethod("helpLines(...)");
+Option.addMethod("appendUsage(...)");
+Option.addMethod("getPreferredName()");
+Option.addMethod("getDescription()");
+Option.addMethod("getId()");
+Option.addMethod("findOption(...)");
+
+var Group = new Interface("Group");
+Group.addMethod("appendUsage(...)");
+Group.addNote("-a | -b | -c | -d | -e");
+
+var Parent = new Interface("Parent");
+Parent.addMethod("processParent(...)");
+Parent.addNote("-f <arg1>");
+
+var Argument = new Interface("Argument");
+Argument.addMethod("getInitialSeparator()");
+Argument.addMethod("processValues(...)");
+Argument.addMethod("validate(...)");
+Argument.addNote("<arg1> [<arg2> ...]");
+
+var CommandLine = new Interface("CommandLine");
+CommandLine.addMethod("hasOption(...)");
+CommandLine.addMethod("getOption(...)");
+CommandLine.addMethod("getValue(...)");
+CommandLine.addMethod("getValues(...)");
+CommandLine.addMethod("getSwitch(...)");
+CommandLine.addMethod("getProperty(...)");
+CommandLine.addMethod("getProperties()");
+CommandLine.addMethod("getOptionCount(...)");
+CommandLine.addMethod("getOptions()");
+CommandLine.addMethod("getOptionTriggers()");
+
+var WriteableCommandLine = new Interface("WriteableCommandLine");
+WriteableCommandLine.addMethod("addOption(...)");
+WriteableCommandLine.addMethod("addValue(...)");
+WriteableCommandLine.addMethod("addSwitch(...)");
+WriteableCommandLine.addMethod("addProperty(...)");
+WriteableCommandLine.addMethod("looksLikeOption(...)");
+
+
+
+
+
+var PropertyOption = new Class("PropertyOption");
+PropertyOption.addAttribute("optionString");
+PropertyOption.addAttribute("description");
+PropertyOption.addAttribute("prefixes");
+PropertyOption.addNote("-Dproperty=value");
+
+var DefaultOption = new Class("DefaultOption");
+DefaultOption.addAttribute("optionString");
+DefaultOption.addAttribute("description");
+DefaultOption.addAttribute("prefixes");
+DefaultOption.addNote("-f (--file, --filelist)");
+
+var Command = new Class("Command");
+Command.addAttribute("preferredName");
+Command.addAttribute("aliases");
+Command.addAttribute("required");
+Command.addAttribute("triggers");
+Command.addNote("update (up, upd)");
+
+var Switch = new Class("Switch");
+Switch.addAttribute("enabledPrefix");
+Switch.addAttribute("disabledPrefix");
+Switch.addAttribute("preferredName");
+Switch.addAttribute("aliases");
+Switch.addAttribute("required");
+Switch.addAttribute("triggers");
+Switch.addAttribute("prefixes");
+Switch.addNote("+d|-d (+display|-display)");
+
+var SourceDestArgument = new Class("SourceDestArgument");
+SourceDestArgument.addAttribute("preferredName");
+SourceDestArgument.addAttribute("aliases");
+SourceDestArgument.addAttribute("required");
+SourceDestArgument.addAttribute("triggers");
+SourceDestArgument.addNote("<src1> <src2> ... <dst>");
+
+
+
+
+var Parser = new Class("Parser");
+Parser.addMethod("parse(...)");
+Parser.addMethod("parseAndHelp(...)");
+Parser.addMethod("setGroup(...)");
+Parser.addMethod("setHelpFormatter(...)");
+Parser.addMethod("setHelpOption(...)");
+Parser.addMethod("setHelpTrigger(...)");
+
+var DefaultingCommandLine = new Class("DefaultingCommandLine");
+DefaultingCommandLine.addMethod("appendCommandLine(...)");
+DefaultingCommandLine.addMethod("insertCommandLine(...)");
+DefaultingCommandLine.addMethod("commandLines()");
+
+var PropertiesCommandLine = new Class("PropertiesCommandLine");
+PropertiesCommandLine.addAttribute("properties");
+PropertiesCommandLine.addNote("java.util.Properties");
+
+var PreferencesCommandLine = new Class("PreferencesCommandLine");
+PreferencesCommandLine.addAttribute("preferences");
+PreferencesCommandLine.addNote("java.util.prefs.Preferences");
+
+
+
+
+
+var ArgumentBuilder = new Class("ArgumentBuilder");
+ArgumentBuilder.addMethod("withId(...)");
+ArgumentBuilder.addMethod("withName(...)");
+ArgumentBuilder.addMethod("withDescription(...)");
+ArgumentBuilder.addMethod("withConsumeRemaining(...)");
+ArgumentBuilder.addMethod("withValidator(...)");
+ArgumentBuilder.addMethod("withMinimum(...)");
+ArgumentBuilder.addMethod("withMaximum(...)");
+ArgumentBuilder.addMethod("withDefault(...)");
+ArgumentBuilder.addMethod("withDefaults(...)");
+ArgumentBuilder.addMethod("withInitialSeparator(...)");
+ArgumentBuilder.addMethod("withSubsequentSeparator(...)");
+ArgumentBuilder.addMethod("create()");
+ArgumentBuilder.addMethod("reset()");
+
+var CommandBuilder = new Class("CommandBuilder");
+CommandBuilder.addMethod("withId(...)");
+CommandBuilder.addMethod("withName(...)");
+CommandBuilder.addMethod("withDescription(...)");
+CommandBuilder.addMethod("withArgument(...)");
+CommandBuilder.addMethod("withChildren(...)");
+CommandBuilder.addMethod("withRequired(...)");
+CommandBuilder.addMethod("create()");
+CommandBuilder.addMethod("reset()");
+
+var DefaultOptionBuilder = new Class("DefaultOptionBuilder");
+DefaultOptionBuilder.addMethod("withId(...)");
+DefaultOptionBuilder.addMethod("withShortName(...)");
+DefaultOptionBuilder.addMethod("withLongName(...)");
+DefaultOptionBuilder.addMethod("withDescription(...)");
+DefaultOptionBuilder.addMethod("withArgument(...)");
+DefaultOptionBuilder.addMethod("withChildren(...)");
+DefaultOptionBuilder.addMethod("withRequired(...)");
+DefaultOptionBuilder.addMethod("create()");
+DefaultOptionBuilder.addMethod("reset()");
+DefaultOptionBuilder.addAttribute("shortPrefix");
+DefaultOptionBuilder.addAttribute("longPrefix");
+DefaultOptionBuilder.addAttribute("burstEnabled");
+
+var DefaultOptionBuilder = new Class("DefaultOptionBuilder");
+DefaultOptionBuilder.addMethod("withId(...)");
+DefaultOptionBuilder.addMethod("withShortName(...)");
+DefaultOptionBuilder.addMethod("withLongName(...)");
+DefaultOptionBuilder.addMethod("withDescription(...)");
+DefaultOptionBuilder.addMethod("withArgument(...)");
+DefaultOptionBuilder.addMethod("withChildren(...)");
+DefaultOptionBuilder.addMethod("withRequired(...)");
+DefaultOptionBuilder.addMethod("create()");
+DefaultOptionBuilder.addMethod("reset()");
+
+var GroupBuilder = new Class("GroupBuilder");
+GroupBuilder.addMethod("withName(...)");
+GroupBuilder.addMethod("withDescription(...)");
+GroupBuilder.addMethod("withOption(...)");
+GroupBuilder.addMethod("withMinimum(...)");
+GroupBuilder.addMethod("withMaximum(...)");
+GroupBuilder.addMethod("create()");
+GroupBuilder.addMethod("reset()");
+
+var PatternBuilder = new Class("PatternBuilder");
+PatternBuilder.addMethod("withPattern(...)");
+PatternBuilder.addMethod("create()");
+PatternBuilder.addMethod("reset()");
+PatternBuilder.addAttribute("groupBuilder");
+PatternBuilder.addAttribute("optionBuilder");
+PatternBuilder.addAttribute("argumentBuilder");
+
+var SwitchBuilder = new Class("SwitchBuilder");
+SwitchBuilder.addMethod("withId(...)");
+SwitchBuilder.addMethod("withName(...)");
+SwitchBuilder.addMethod("withDescription(...)");
+SwitchBuilder.addMethod("withArgument(...)");
+SwitchBuilder.addMethod("withChildren(...)");
+SwitchBuilder.addMethod("withRequired(...)");
+SwitchBuilder.addMethod("create()");
+SwitchBuilder.addMethod("reset()");
+SwitchBuilder.addAttribute("enabledPrefix");
+SwitchBuilder.addAttribute("disabledPrefix");
+
+
+
+var Validator = new Class("Validator");
+Validator.addMethod("validate(...)");
+
+var ClassValidator = new Class("ClassValidator");
+ClassValidator.addAttribute("classLoader");
+ClassValidator.addAttribute("instance");
+ClassValidator.addAttribute("loadable");
+
+var DateValidator = new Class("DateValidator");
+DateValidator.addAttribute("formats");
+DateValidator.addAttribute("minimum");
+DateValidator.addAttribute("maximum");
+
+var EnumValidator = new Class("EnumValidator");
+EnumValidator.addAttribute("validValues");
+
+var FileValidator = new Class("FileValidator");
+FileValidator.addAttribute("directory");
+FileValidator.addAttribute("existing");
+FileValidator.addAttribute("file");
+FileValidator.addAttribute("hidden");
+FileValidator.addAttribute("readable");
+FileValidator.addAttribute("writable");
+
+var FileValidator = new Class("FileValidator");
+FileValidator.addAttribute("format");
+FileValidator.addAttribute("minimum");
+FileValidator.addAttribute("maximum");
+
+var UrlValidator = new Class("UrlValidator");
+UrlValidator.addAttribute("format");
+UrlValidator.addAttribute("minimum");
+UrlValidator.addAttribute("maximum");
+
+
+
+
+var Comparators = new Class("Comparators");
+Comparators.addMethod("chain(...)");
+Comparators.addMethod("commandFirst(...)");
+Comparators.addMethod("commandLast(...)");
+Comparators.addMethod("defaultOptionFirst(...)");
+Comparators.addMethod("defaultOptionLast(...)");
+Comparators.addMethod("groupFirst(...)");
+Comparators.addMethod("groupLast(...)");
+Comparators.addMethod("namedFirst(...)");
+Comparators.addMethod("namedLast(...)");
+Comparators.addMethod("preferredNameFirst(...)");
+Comparators.addMethod("preferredNameLast(...)");
+Comparators.addMethod("requiredFirst(...)");
+Comparators.addMethod("requiredLast(...)");
+Comparators.addMethod("switchFirst(...)");
+Comparators.addMethod("switchLast(...)");
+
+var HelpFormatter = new Class("HelpFormatter");
+HelpFormatter.addMethod("print()");
+HelpFormatter.addMethod("printDivider()");
+HelpFormatter.addMethod("printException()");
+HelpFormatter.addMethod("printFooter()");
+HelpFormatter.addMethod("printGutterLeft()");
+HelpFormatter.addMethod("printGutterRight()");
+HelpFormatter.addMethod("printHeader()");
+HelpFormatter.addMethod("printHelp()");
+HelpFormatter.addMethod("printUsage()");
+HelpFormatter.addAttribute("comparator");
+HelpFormatter.addAttribute("displaySettings");
+HelpFormatter.addAttribute("divider");
+HelpFormatter.addAttribute("exception");
+HelpFormatter.addAttribute("footer");
+HelpFormatter.addAttribute("fullUsageSettings");
+HelpFormatter.addAttribute("group");
+HelpFormatter.addAttribute("gutterCenter");
+HelpFormatter.addAttribute("gutterLeft");
+HelpFormatter.addAttribute("gutterRight");
+HelpFormatter.addAttribute("header");
+HelpFormatter.addAttribute("lineUsageSettings");
+HelpFormatter.addAttribute("pageWidth");
+HelpFormatter.addAttribute("printWriter");
+HelpFormatter.addAttribute("shellCommand");
diff --git a/src/test/org/apache/commons/cli/UtilTest.java b/src/site/resources/images/svg/diagrams.css
similarity index 50%
copy from src/test/org/apache/commons/cli/UtilTest.java
copy to src/site/resources/images/svg/diagrams.css
index c8c614a..d8691da 100644
--- a/src/test/org/apache/commons/cli/UtilTest.java
+++ b/src/site/resources/images/svg/diagrams.css
@@ -1,4 +1,4 @@
-/**
+/*
  * 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.
@@ -14,26 +14,52 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+ 
+.option .outline, .option polygon.note {
+	fill:rgb(191,255,255);
+}
+.group rect.outline, .group polygon.note {
+	fill:rgb(255,191,191);
+}
 
-package org.apache.commons.cli;
+.parent rect.outline, .parent polygon.note {
+	fill:rgb(191,255,191);
+}
+.argument rect.outline, .argument polygon.note {
+	fill:rgb(191,191,255);
+}
+.property rect.outline, .property polygon.note {
+	fill:rgb(255,191,255);
+}
 
-import junit.framework.TestCase;
+.package rect {
+	fill:rgb(255,255,191);
+}
 
-/**
- * @author brianegge
- */
-public class UtilTest extends TestCase
-{
-    public void testStripLeadingHyphens()
-    {
-        assertEquals("f", Util.stripLeadingHyphens("-f"));
-        assertEquals("foo", Util.stripLeadingHyphens("--foo"));
-        assertEquals("-foo", Util.stripLeadingHyphens("---foo"));
-        assertNull(Util.stripLeadingHyphens(null));
-    }
+.package rect.inner {
+	fill: rgb(255,255,255);
+	stroke: none;
+}
+
+text.title {
+	text-anchor: middle;
+}
+
+.type text {
+	fill: rgb(0,0,0);
+}
+rect, line, polygon, polyline {
+	stroke:rgb(0,0,0);
+	stroke-width:2;
+	stroke-linejoin: bevel;
+	stroke-linecap: round;
+}
+
+.implements, .extends {
+	fill: none;
+	marker-end: url(util.svg#HollowArrow); 
+}
 
-    public void testStripLeadingAndTrailingQuotes()
-    {
-        assertEquals("foo", Util.stripLeadingAndTrailingQuotes("\"foo\""));
-    }
+.implements, .note.connect {
+	stroke-dasharray: 5;
 }
diff --git a/src/site/resources/images/svg/diagrams.js b/src/site/resources/images/svg/diagrams.js
new file mode 100644
index 0000000..4e8a5a7
--- /dev/null
+++ b/src/site/resources/images/svg/diagrams.js
@@ -0,0 +1,368 @@
+/*
+ * 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.
+ */
+ 
+
+var textHeight = 10;
+var padding = 10;
+var namespace = "http://www.w3.org/2000/svg";
+
+var displayAttributes = true;
+var displayMethods = true;
+var displayNotes = true;
+
+function Type(name){
+	this.width = 160;
+	this.style = "type";
+	
+	this.insert = function(evt){
+		y = 0;
+		y = this.insertOutline(evt,y);
+		y = this.insertName(evt,y);
+		if(displayAttributes==true){
+			y = this.insertAttributes(evt,y);
+		}
+		if(displayMethods==true){
+			y = this.insertMethods(evt,y);
+		}
+		if(displayNotes==true){
+			y = this.insertNotes(evt,y);
+		}
+	}
+	
+	this.height = function(){
+		height = 0;
+		height += this.heightName();
+		if(displayAttributes==true){
+			height += this.heightAttributes();
+		}
+		if(displayMethods==true){
+			height += this.heightMethods();
+		}
+		return height;
+	}
+	
+	
+	
+	
+	
+	
+	this.insertOutline = function(evt,y){
+
+		style = evt.target.getAttributeNS(null, "class");
+		evt.target.setAttributeNS(null,"class",style+" "+this.style);
+
+		e = document.createElementNS(namespace, "rect");
+		e.setAttributeNS(null, "x", 0);
+		e.setAttributeNS(null, "y", 0);
+		e.setAttributeNS(null, "width",  this.width);
+		e.setAttributeNS(null, "height", this.height());
+        	e.setAttributeNS(null, "class", "outline");
+        	evt.target.appendChild(e);
+
+		return y;
+	}
+	
+	
+	
+	
+	
+	
+	
+	this.name = name;
+	
+	this.heightName = function(){
+		return padding * 2 + textHeight;
+	}
+	
+	this.insertName = function(evt,y){
+	
+		y += padding;
+		y += textHeight;
+		
+		e = document.createElementNS(namespace, "text");
+		e.setAttributeNS(null, "x", this.width/2);
+		e.setAttributeNS(null, "y", y);
+		e.setAttributeNS(null, "class", "title");
+		e.appendChild(document.createTextNode(this.name));
+		evt.target.appendChild(e);
+        
+		y += padding;
+	
+		return y;
+	}
+	
+	
+	
+	
+	
+	
+	
+	this.attributeList = new Array();
+	this.attributeCount = 0;
+	
+	this.addAttribute = function(text){
+		this.attributeList[this.attributeCount++]=text;
+	}
+	
+	this.heightAttributes = function(){
+		if(this.attributeCount>0){
+			return padding * 2 + this.attributeCount*textHeight;
+		}
+		else{
+			return padding;
+		}
+	}
+	
+	this.insertAttributes = function(evt,y){
+	
+		e = document.createElementNS(namespace, "line");
+		e.setAttributeNS(null, "x1", 0);
+		e.setAttributeNS(null, "y1", y);
+		e.setAttributeNS(null, "x2", this.width);
+		e.setAttributeNS(null, "y2", y);
+		e.setAttributeNS(null, "class", "divider");
+		evt.target.appendChild(e);
+		
+		y += padding;
+		
+		for(i=0;i<this.attributeCount;++i){
+			y += textHeight;
+			
+			e = document.createElementNS(namespace, "text");
+			e.setAttributeNS(null, "x", padding);
+			e.setAttributeNS(null, "y", y);
+			e.setAttributeNS(null, "class", "attribute");
+			e.appendChild(document.createTextNode(this.attributeList[i]));
+			evt.target.appendChild(e);
+		}
+		
+		if(this.attributeCount>0){
+			y += padding;
+		}
+	
+		return y;
+	}
+	
+	
+	
+	
+	
+	this.methodList = new Array();
+	this.methodCount = 0;
+	
+	this.addMethod = function(text){
+		this.methodList[this.methodCount++]=text;
+	}
+	
+	this.heightMethods = function(){
+		if(this.methodCount>0){
+			return padding * 2 + this.methodCount*textHeight;
+		}
+		else{
+			return padding;
+		}
+	}
+	
+	this.insertMethods = function(evt,y){
+	
+		e = document.createElementNS(namespace, "line");
+		e.setAttributeNS(null, "x1", 0);
+		e.setAttributeNS(null, "y1", y);
+		e.setAttributeNS(null, "x2", this.width);
+		e.setAttributeNS(null, "y2", y);
+		e.setAttributeNS(null, "class", "divider");
+		evt.target.appendChild(e);
+		
+		y += padding;
+		
+		for(i=0;i<this.methodCount;++i){
+			y += textHeight;
+			
+			e = document.createElementNS(namespace, "text");
+			e.setAttributeNS(null, "x", padding);
+			e.setAttributeNS(null, "y", y);
+			e.setAttributeNS(null, "class", "method");
+			e.appendChild(document.createTextNode(this.methodList[i]));
+			evt.target.appendChild(e);
+		}
+		
+		if(this.methodCount>0){
+			y += padding;
+		}
+	
+		return y;
+	}
+	
+	
+	
+	
+	
+	this.noteList = new Array();
+	this.noteCount = 0;
+	
+	this.addNote = function(text){
+		this.noteList[this.noteCount++]=text;
+	}
+	
+	this.insertNotes = function(evt,y){
+		if(this.noteCount>0){
+			joinTop = y;
+		
+			y += padding;
+			
+			e = document.createElementNS(namespace, "line");
+			e.setAttributeNS(null, "x1", this.width/2-padding*2);
+			e.setAttributeNS(null, "y1", y);
+			e.setAttributeNS(null, "x2", this.width/2+padding*2);
+			e.setAttributeNS(null, "y2", joinTop);
+			e.setAttributeNS(null, "class", "note connect");
+			evt.target.appendChild(e);
+			
+			
+			
+			height = this.heightNotes();
+			
+			e = document.createElementNS(namespace, "polygon");
+			e.setAttributeNS(null, "points", "0,"+(y+padding)+" 0,"+(y+height)+" "+this.width+","+(y+height)+" "+this.width+","+y+" "+padding+","+y);
+			e.setAttributeNS(null, "class", "note");
+			evt.target.appendChild(e);
+			
+			e = document.createElementNS(namespace, "polygon");
+			e.setAttributeNS(null, "points", ""+padding+","+y+" 0,"+(y+padding)+" "+padding+","+(y+padding));
+			e.setAttributeNS(null, "class", "note corner");
+			evt.target.appendChild(e);
+			
+			y += padding;
+			
+		
+			for(i=0;i<this.noteCount;++i){
+				y += textHeight;
+
+				e = document.createElementNS(namespace, "text");
+				e.setAttributeNS(null, "x", padding);
+				e.setAttributeNS(null, "y", y);
+				e.setAttributeNS(null, "class", "note");
+				e.appendChild(document.createTextNode(this.noteList[i]));
+				evt.target.appendChild(e);
+			}
+		}
+	}
+	
+	this.heightNotes = function(){
+		if(this.noteCount>0){
+			return padding*2 + this.noteCount*textHeight;
+		}
+	}
+}
+
+function Interface(name){
+	this.superclass = Type;
+	this.superclass(name);
+	delete this.superclass; 
+	this.rounded = true;
+	
+	this.insertOutline = function(evt,y){
+
+		style = evt.target.getAttributeNS(null, "class");
+		evt.target.setAttributeNS(null,"class",style+" "+this.style);
+
+		e = document.createElementNS(namespace, "rect");
+		e.setAttributeNS(null, "x", 0);
+		e.setAttributeNS(null, "y", 0);
+		e.setAttributeNS(null, "width",  this.width);
+		e.setAttributeNS(null, "height", this.height());
+		e.setAttributeNS(null, "rx", padding*1.5);
+		e.setAttributeNS(null, "ry", padding*1.5);
+        	e.setAttributeNS(null, "class", "outline");
+		evt.target.appendChild(e);
+
+		return y;
+	}
+	
+	this.heightAttributes = function(){
+		return 0;
+	}
+	
+	this.insertAttributes = function(evt,y){
+		return y;
+	}
+	
+}
+Interface.prototype = new Type;
+
+function Class(name){
+	this.superclass = Type;
+	this.superclass(name);
+	delete this.superclass; 
+	this.rounded = false;
+}
+Class.prototype = new Type;
+
+
+
+
+function PackageSymbol(name,width,height){
+	this.name = name;
+	this.nameWidth = 150;
+	this.width = width;
+	this.height = height;
+	
+	this.insert = function(evt){
+		
+		style = evt.target.getAttributeNS(null, "class");
+		evt.target.setAttributeNS(null,"class",style+" package");
+		
+		first = evt.target.getFirstChild();
+		
+		e = document.createElementNS(namespace, "rect");
+		e.setAttributeNS(null, "x", 0);
+		e.setAttributeNS(null, "y", 0);
+		e.setAttributeNS(null, "width", this.nameWidth);
+		e.setAttributeNS(null, "height", textHeight+padding);
+		e.setAttributeNS(null, "class", "outline");
+		e.appendChild(document.createTextNode(this.name));
+		evt.target.insertBefore(e,first);
+		
+		e = document.createElementNS(namespace, "text");
+		e.setAttributeNS(null, "x", this.nameWidth/2);
+		e.setAttributeNS(null, "y", textHeight+padding/2);
+		e.setAttributeNS(null, "class", "title");
+		e.appendChild(document.createTextNode(this.name));
+		evt.target.insertBefore(e,first);
+		
+		e = document.createElementNS(namespace, "rect");
+		e.setAttributeNS(null, "x", 0);
+		e.setAttributeNS(null, "y", textHeight+padding);
+		e.setAttributeNS(null, "width", this.width);
+		e.setAttributeNS(null, "height", this.height-textHeight-padding);
+		e.setAttributeNS(null, "class", "outline");
+		e.appendChild(document.createTextNode(this.name));
+		evt.target.insertBefore(e,first);
+		
+		e = document.createElementNS(namespace, "rect");
+		e.setAttributeNS(null, "x", padding);
+		e.setAttributeNS(null, "y", textHeight+padding*2);
+		e.setAttributeNS(null, "width", this.width-padding*2);
+		e.setAttributeNS(null, "height", this.height-textHeight-padding*3);
+		e.setAttributeNS(null, "class", "inner");
+		e.appendChild(document.createTextNode(this.name));
+		evt.target.insertBefore(e,first);
+		
+		
+	}
+}
+
diff --git a/src/site/resources/images/svg/options.svg b/src/site/resources/images/svg/options.svg
new file mode 100644
index 0000000..cdb5160
--- /dev/null
+++ b/src/site/resources/images/svg/options.svg
@@ -0,0 +1,66 @@
+<?xml version="1.0" standalone="no"?>
+<?xml-stylesheet type="text/css" href="diagrams.css" ?>
+<!--
+ * 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.
+-->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg id="root" width="460" height="530" x="0" y="0">
+
+<script type="text/ecmascript" xlink:href="diagrams.js"/>
+<script type="text/ecmascript" xlink:href="diagrams-cli2.js"/>
+<script type="text/ecmascript">
+
+displayAttributes = false;
+displayMethods = false;
+
+</script>
+
+<g 
+	onload="new PackageSymbol('org.apache.commons.cli2',440,510).insert(evt)" 
+	transform="translate(10,10)"><g transform="translate(10,30)">
+	
+	<g transform="translate(  0, 30)" class="option"   onload="Option.insert(evt);" />
+	<g transform="translate( 50,120)" class="group"    onload="Group.insert(evt);"/>
+	<g transform="translate( 50,210)" class="parent"   onload="Parent.insert(evt);"/>
+	<g transform="translate( 50,390)" class="argument" onload="Argument.insert(evt);"/>
+	
+	
+	<g 
+		onload="new PackageSymbol('option',180,470).insert(evt)" 
+		transform="translate(240,0)"><g transform="translate(10,30)">
+		
+		<g transform="translate(0,  0)" class="option"   onload="PropertyOption.insert(evt);" />
+		<g transform="translate(0, 90)" class="parent"   onload="DefaultOption.insert(evt);" />
+		<g transform="translate(0,180)" class="parent"   onload="Command.insert(evt);" />
+		<g transform="translate(0,270)" class="parent"   onload="Switch.insert(evt);" />
+		<g transform="translate(0,360)" class="argument" onload="SourceDestArgument.insert(evt);" />
+	</g></g>
+</g></g>
+
+<polyline class="implements" points="270,85 190,85 "/>
+
+<polyline class="implements" points="270,175 250,175 250,265 240,265"/>
+<polyline class="implements" points="270,265 250,265 250,265 240,265"/>
+<polyline class="implements" points="270,355 250,355 250,265 240,265"/>
+
+<polyline class="implements" points="270,445 240,445 "/>
+
+<polyline class="extends" points="70,445 40,445 40,110"/>
+<polyline class="extends" points="70,265 40,265 40,110"/>
+<polyline class="extends" points="70,175 40,175 40,110"/>
+
+
+</svg>
\ No newline at end of file
diff --git a/src/site/resources/images/svg/util.svg b/src/site/resources/images/svg/util.svg
new file mode 100644
index 0000000..b86d760
--- /dev/null
+++ b/src/site/resources/images/svg/util.svg
@@ -0,0 +1,47 @@
+<?xml version="1.0" standalone="no"?>
+<!--
+ * 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.
+-->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="1" height="1">
+	<defs>
+        <marker 
+            id="FilledArrow"
+            viewBox="0 0 10 10" refX="0" refY="5" 
+            markerUnits="strokeWidth"
+            markerWidth="5" markerHeight="14"
+            orient="auto"
+            >
+            <path 
+                d="M 10 0 L 0 5 L 10 10 L 10 0 Z" 
+                fill="rgb(0,0,0)"
+                />
+        </marker>
+        <marker 
+            id="HollowArrow"
+            markerUnits="userSpaceOnUse"
+            rexX="10" refY="5"
+            markerWidth="20" markerHeight="20"
+            orient="auto"
+            >
+            <path 
+                d="M 10 5 L 1 0 L 1 10 L 10 5 " 
+                fill="rgb(255,255,255)"
+                stroke="rgb(0,0,0)"
+                />
+        </marker>
+	</defs>	
+</svg>
\ No newline at end of file
diff --git a/src/site/resources/profile.jacoco b/src/site/resources/profile.jacoco
new file mode 100644
index 0000000..e69de29
diff --git a/src/site/site.xml b/src/site/site.xml
new file mode 100644
index 0000000..b36c871
--- /dev/null
+++ b/src/site/site.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ 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 name="Commons CLI">
+    <bannerRight>
+        <name>Commons CLI</name>
+        <src>/images/logo.png</src>
+        <href>/index.html</href>
+    </bannerRight>
+
+    <body>
+        <menu name="Commons CLI">
+            <item name="Overview"             href="/index.html"/>
+            <item name="Download"             href="http://commons.apache.org/cli/download_cli.cgi"/>
+            <item name="Changes Report"       href="/changes-report.html"/>
+            <item name="Mailing Lists"        href="/mail-lists.html"/>
+            <item name="Issue Tracking"       href="/issue-tracking.html"/>
+            <item name="Source Repository"    href="/source-repository.html"/>
+        </menu>
+
+        <menu name="User Guide">
+            <item name="Getting started"      href="/introduction.html"/>
+            <item name="Usage scenarios"      href="/usage.html"/>
+            <item name="Option properties"    href="/properties.html"/>
+            <item name="Javadoc (Current ${project.version})"        href="/apidocs/index.html"/>
+            <item name="Javadoc (1.3.1)"      href="/javadocs/api-release/index.html"/>
+        </menu>
+
+    </body>
+
+</project>
diff --git a/src/site/xdoc/download_cli.xml b/src/site/xdoc/download_cli.xml
new file mode 100644
index 0000000..21ceb75
--- /dev/null
+++ b/src/site/xdoc/download_cli.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0"?>
+<!--
+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.
+-->
+<!--
+ +======================================================================+
+ |****                                                              ****|
+ |****      THIS FILE IS GENERATED BY THE COMMONS BUILD PLUGIN      ****|
+ |****                    DO NOT EDIT DIRECTLY                      ****|
+ |****                                                              ****|
+ +======================================================================+
+ | TEMPLATE FILE: download-page-template.xml                            |
+ | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
+ +======================================================================+
+ |                                                                      |
+ | 1) Re-generate using: mvn commons:download-page                      |
+ |                                                                      |
+ | 2) Set the following properties in the component's pom:              |
+ |    - commons.componentid (required, alphabetic, lower case)          |
+ |    - commons.release.version (required)                              |
+ |    - commons.binary.suffix (optional)                                |
+ |      (defaults to "-bin", set to "" for pre-maven2 releases)         |
+ |                                                                      |
+ | 3) Example Properties                                                |
+ |                                                                      |
+ |  <properties>                                                        |
+ |    <commons.componentid>math</commons.componentid>                   |
+ |    <commons.release.version>1.2</commons.release.version>            |
+ |  </properties>                                                       |
+ |                                                                      |
+ +======================================================================+
+-->
+<document>
+  <properties>
+    <title>Download Apache Commons CLI</title>
+    <author email="dev at commons.apache.org">Commons Documentation Team</author>
+  </properties>
+  <body>
+    <section name="Download Apache Commons CLI">
+    <subsection name="Using a Mirror">
+      <p>
+        We recommend you use a mirror to download our release
+        builds, but you <strong>must</strong> verify the integrity of
+        the downloaded files using signatures downloaded from our main
+        distribution directories. Recent releases (48 hours) may not yet
+        be available from the mirrors.
+      </p>
+
+      <p>
+        You are currently using <b>[preferred]</b>.  If you
+        encounter a problem with this mirror, please select another
+        mirror.  If all mirrors are failing, there are <i>backup</i>
+        mirrors (at the end of the mirrors list) that should be
+        available.
+        <br></br>
+        [if-any logo]<a href="[link]"><img align="right" src="[logo]" border="0"></img></a>[end]
+      </p>
+
+      <form action="[location]" method="get" id="SelectMirror">
+        <p>
+          Other mirrors:
+          <select name="Preferred">
+          [if-any http]
+            [for http]<option value="[http]">[http]</option>[end]
+          [end]
+          [if-any ftp]
+            [for ftp]<option value="[ftp]">[ftp]</option>[end]
+          [end]
+          [if-any backup]
+            [for backup]<option value="[backup]">[backup] (backup)</option>[end]
+          [end]
+          </select>
+          <input type="submit" value="Change"></input>
+        </p>
+      </form>
+
+      <p>
+        The <a href="http://www.apache.org/dist/commons/KEYS">KEYS</a>
+        link links to the code signing keys used to sign the product.
+        The <code>PGP</code> link downloads the OpenPGP compatible signature from our main site.
+        The <code>MD5</code> link downloads the checksum from the main site.
+      </p>
+    </subsection>
+    </section>
+    <section name="Apache Commons CLI 1.3.1 ">
+      <subsection name="Binaries">
+        <table>
+          <tr>
+              <td><a href="[preferred]/commons/cli/binaries/commons-cli-1.3.1-bin.tar.gz">commons-cli-1.3.1-bin.tar.gz</a></td>
+              <td><a href="http://www.apache.org/dist/commons/cli/binaries/commons-cli-1.3.1-bin.tar.gz.md5">md5</a></td>
+              <td><a href="http://www.apache.org/dist/commons/cli/binaries/commons-cli-1.3.1-bin.tar.gz.asc">pgp</a></td>
+          </tr>
+          <tr>
+              <td><a href="[preferred]/commons/cli/binaries/commons-cli-1.3.1-bin.zip">commons-cli-1.3.1-bin.zip</a></td>
+              <td><a href="http://www.apache.org/dist/commons/cli/binaries/commons-cli-1.3.1-bin.zip.md5">md5</a></td>
+              <td><a href="http://www.apache.org/dist/commons/cli/binaries/commons-cli-1.3.1-bin.zip.asc">pgp</a></td>
+          </tr>
+        </table>
+      </subsection>
+      <subsection name="Source">
+        <table>
+          <tr>
+              <td><a href="[preferred]/commons/cli/source/commons-cli-1.3.1-src.tar.gz">commons-cli-1.3.1-src.tar.gz</a></td>
+              <td><a href="http://www.apache.org/dist/commons/cli/source/commons-cli-1.3.1-src.tar.gz.md5">md5</a></td>
+              <td><a href="http://www.apache.org/dist/commons/cli/source/commons-cli-1.3.1-src.tar.gz.asc">pgp</a></td>
+          </tr>
+          <tr>
+              <td><a href="[preferred]/commons/cli/source/commons-cli-1.3.1-src.zip">commons-cli-1.3.1-src.zip</a></td>
+              <td><a href="http://www.apache.org/dist/commons/cli/source/commons-cli-1.3.1-src.zip.md5">md5</a></td>
+              <td><a href="http://www.apache.org/dist/commons/cli/source/commons-cli-1.3.1-src.zip.asc">pgp</a></td>
+          </tr>
+        </table>
+      </subsection>
+    </section>
+    <section name="Archives">
+        <p>
+          Older releases can be obtained from the archives.
+        </p>
+        <ul>
+          <li class="download"><a href="[preferred]/commons/cli/">browse download area</a></li>
+          <li><a href="http://archive.apache.org/dist/commons/cli/">archives...</a></li>
+        </ul>
+    </section>
+  </body>
+</document>
diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml
new file mode 100644
index 0000000..aa3717b
--- /dev/null
+++ b/src/site/xdoc/index.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<document>
+
+  <properties>
+    <title>Home</title>
+    <author email="dev at commons.apache.org">commons-dev</author>
+  </properties>
+
+  <body>
+    <section name="Commons CLI">
+      <p>
+        The Apache Commons CLI library provides an API for parsing command line options passed to programs.
+        It's also able to print help messages detailing the options available for a command line tool.
+      </p>
+      <p>
+        Commons CLI supports different types of options:
+      </p>
+      <ul>
+        <li>POSIX like options (ie. <code>tar -zxvf foo.tar.gz</code>)</li>
+        <li>GNU like long options (ie. <code>du --human-readable --max-depth=1</code>)</li>
+        <li>Java like properties (ie. <code>java -Djava.awt.headless=true -Djava.net.useSystemProxies=true Foo</code>)</li>
+        <li>Short options with value attached (ie. <code>gcc -O2 foo.c</code>)</li>
+        <li>long options with single hyphen (ie. <code>ant -projecthelp</code>)</li>
+      </ul>
+      <p>
+        A typical help message displayed by Commons CLI looks like this:
+      </p>
+      <source>
+usage: ls
+ -A,--almost-all          do not list implied . and ..
+ -a,--all                 do not hide entries starting with .
+ -B,--ignore-backups      do not list implied entried ending with ~
+ -b,--escape              print octal escapes for nongraphic characters
+    --block-size <SIZE>   use SIZE-byte blocks
+ -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>
+        Check out the <a href="introduction.html">introduction</a> page for a detailed presentation.
+      </p>
+    </section>
+
+    <section name="CLI 2?">
+      <p>Commons CLI 1.0 was formed from the merger of ideas and code from three different libraries -
+      Werken, Avalon and Optz. In dealing with the bugs and the feature requests a freshly designed and not
+      backwards compatible CLI 2 was created in 2004, but never finished or released. </p>
+
+      <p>The current plan is to continue to maintain the 1.x line. The CLI2 work may be found in the Commons Sandbox. </p>
+    </section>
+
+    <section name="Documentation">
+      <p>
+        A full <a href="introduction.html">User's Guide</a> is available
+        as are various <a href="project-reports.html">project reports</a>.
+      </p>
+      <p>
+        The Javadoc API documents are available online:
+      </p>
+      <ul>
+        <li><a href="javadocs/api-release/index.html">CLI 1.3.1 (current release)</a></li>
+        <li><a href="javadocs/api-1.3/index.html">CLI 1.3</a></li>
+        <li><a href="javadocs/api-1.2/index.html">CLI 1.2</a></li>
+        <li><a href="javadocs/api-1.1/index.html">CLI 1.1</a></li>
+        <li><a href="javadocs/api-1.0/index.html">CLI 1.0</a></li>
+      </ul>
+      <p>
+        The <a href="source-repository.html">Subversion repository</a> can be
+        <a href="http://svn.apache.org/viewvc/commons/proper/cli/trunk/">browsed</a>.
+      </p>
+    </section>
+
+    <section name="Releases">
+      <p>
+        The latest version is v1.3.1 -
+        <a href="http://commons.apache.org/cli/download_cli.cgi">Download now!</a>
+        <br/>
+        The <a href="release_1_3_1.html">release notes</a> are also available.
+      </p>
+      <p>
+        For previous releases, see the <a href="http://archive.apache.org/dist/commons/cli/">Apache Archive</a>.
+      </p>
+    </section>
+
+    <section name="Support">
+      <p>The <a href="mail-lists.html">commons mailing lists</a> act as the main support forum. The user list
+      is suitable for most library usage queries. The dev list is intended for the development discussion. Please
+      remember that the lists are shared between all commons components, so prefix your email subject by
+      <code>[cli]</code>.</p>
+
+      <p>Issues may be reported via the <a href="issue-tracking.html">ASF JIRA</a>.</p>
+    </section>
+
+  </body>
+
+</document>
diff --git a/src/site/xdoc/introduction.xml b/src/site/xdoc/introduction.xml
new file mode 100644
index 0000000..43d812f
--- /dev/null
+++ b/src/site/xdoc/introduction.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<document>
+
+  <properties>
+    <author email="dev at commons.apache.org">commons-dev</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="javadocs/api-release/org/apache/commons/cli/Options.html">
+        Options</a> class, as a container for 
+        <a href="javadocs/api-release/org/apache/commons/cli/Option.html">
+        Option</a> instances.  There are two ways to create
+        <code>Option</code>s in CLI.  One of them is via the constructors,
+        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="javadocs/api-release/org/apache/commons/cli/CommandLineParser.html">
+        CommandLineParser</a> takes an <code>Options</code>
+        instance and a <code>String[]</code> of arguments and 
+        returns a 
+        <a href="javadocs/api-release/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 queries the
+        <code>CommandLine</code> to decide what execution branch to
+        take depending on boolean options and uses 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 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/src/site/xdoc/issue-tracking.xml b/src/site/xdoc/issue-tracking.xml
new file mode 100644
index 0000000..c7e749c
--- /dev/null
+++ b/src/site/xdoc/issue-tracking.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0"?>
+<!--
+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.
+-->
+<!--
+ +======================================================================+
+ |****                                                              ****|
+ |****      THIS FILE IS GENERATED BY THE COMMONS BUILD PLUGIN      ****|
+ |****                    DO NOT EDIT DIRECTLY                      ****|
+ |****                                                              ****|
+ +======================================================================+
+ | TEMPLATE FILE: issue-tracking-template.xml                           |
+ | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
+ +======================================================================+
+ |                                                                      |
+ | 1) Re-generate using: mvn commons:jira-page                          |
+ |                                                                      |
+ | 2) Set the following properties in the component's pom:              |
+ |    - commons.jira.id  (required, alphabetic, upper case)             |
+ |    - commons.jira.pid (required, numeric)                            |
+ |                                                                      |
+ | 3) Example Properties                                                |
+ |                                                                      |
+ |  <properties>                                                        |
+ |    <commons.jira.id>MATH</commons.jira.id>                           |
+ |    <commons.jira.pid>12310485</commons.jira.pid>                     |
+ |  </properties>                                                       |
+ |                                                                      |
+ +======================================================================+
+-->
+<document>
+  <properties>
+    <title>Commons CLI Issue tracking</title>
+    <author email="dev at commons.apache.org">Commons Documentation Team</author>
+  </properties>
+  <body>
+
+    <section name="Commons CLI Issue tracking">
+      <p>
+      Commons CLI uses <a href="http://issues.apache.org/jira/">ASF JIRA</a> for tracking issues.
+      See the <a href="http://issues.apache.org/jira/browse/CLI">Commons CLI JIRA project page</a>.
+      </p>
+
+      <p>
+      To use JIRA you may need to <a href="http://issues.apache.org/jira/secure/Signup!default.jspa">create an account</a>
+      (if you have previously created/updated Commons issues using Bugzilla an account will have been automatically
+      created and you can use the <a href="http://issues.apache.org/jira/secure/ForgotPassword!default.jspa">Forgot Password</a>
+      page to get a new password).
+      </p>
+
+      <p>
+      If you would like to report a bug, or raise an enhancement request with
+      Commons CLI please do the following:
+      <ol>
+        <li><a href="http://issues.apache.org/jira/secure/IssueNavigator.jspa?reset=true&pid=12310463&sorter/field=issuekey&sorter/order=DESC&status=1&status=3&status=4">Search existing open bugs</a>.
+            If you find your issue listed then please add a comment with your details.</li>
+        <li><a href="mail-lists.html">Search the mailing list archive(s)</a>.
+            You may find your issue or idea has already been discussed.</li>
+        <li>Decide if your issue is a bug or an enhancement.</li>
+        <li>Submit either a <a href="http://issues.apache.org/jira/secure/CreateIssueDetails!init.jspa?pid=12310463&issuetype=1&priority=4&assignee=-1">bug report</a>
+            or <a href="http://issues.apache.org/jira/secure/CreateIssueDetails!init.jspa?pid=12310463&issuetype=4&priority=4&assignee=-1">enhancement request</a>.</li>
+      </ol>
+      </p>
+
+      <p>
+      Please also remember these points:
+      <ul>
+        <li>the more information you provide, the better we can help you</li>
+        <li>test cases are vital, particularly for any proposed enhancements</li>
+        <li>the developers of Commons CLI are all unpaid volunteers</li>
+      </ul>
+      </p>
+
+      <p>
+      For more information on subversion and creating patches see the
+      <a href="http://www.apache.org/dev/contributors.html">Apache Contributors Guide</a>.
+      </p>
+
+      <p>
+      You may also find these links useful:
+      <ul>
+        <li><a href="http://issues.apache.org/jira/secure/IssueNavigator.jspa?reset=true&pid=12310463&sorter/field=issuekey&sorter/order=DESC&status=1&status=3&status=4">All Open Commons CLI bugs</a></li>
+        <li><a href="http://issues.apache.org/jira/secure/IssueNavigator.jspa?reset=true&pid=12310463&sorter/field=issuekey&sorter/order=DESC&status=5&status=6">All Resolved Commons CLI bugs</a></li>
+        <li><a href="http://issues.apache.org/jira/secure/IssueNavigator.jspa?reset=true&pid=12310463&sorter/field=issuekey&sorter/order=DESC">All Commons CLI bugs</a></li>
+      </ul>
+      </p>
+    </section>
+  </body>
+</document>
diff --git a/src/site/xdoc/mail-lists.xml b/src/site/xdoc/mail-lists.xml
new file mode 100644
index 0000000..cfc89fd
--- /dev/null
+++ b/src/site/xdoc/mail-lists.xml
@@ -0,0 +1,202 @@
+<?xml version="1.0"?>
+<!--
+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.
+-->
+<!--
+ +======================================================================+
+ |****                                                              ****|
+ |****      THIS FILE IS GENERATED BY THE COMMONS BUILD PLUGIN      ****|
+ |****                    DO NOT EDIT DIRECTLY                      ****|
+ |****                                                              ****|
+ +======================================================================+
+ | TEMPLATE FILE: mail-lists-template.xml                               |
+ | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
+ +======================================================================+
+ |                                                                      |
+ | 1) Re-generate using: mvn commons:mail-page                          |
+ |                                                                      |
+ | 2) Set the following properties in the component's pom:              |
+ |    - commons.componentid (required, alphabetic, lower case)          |
+ |                                                                      |
+ | 3) Example Properties                                                |
+ |                                                                      |
+ |  <properties>                                                        |
+ |    <commons.componentid>math</commons.componentid>                   |
+ |  </properties>                                                       |
+ |                                                                      |
+ +======================================================================+
+-->
+<document>
+  <properties>
+    <title>Commons CLI Mailing Lists</title>
+    <author email="dev at commons.apache.org">Commons Documentation Team</author>
+  </properties>
+  <body>
+
+    <section name="Overview">
+      <p>
+        <a href="index.html">Commons CLI</a> shares mailing lists with all the other 
+        <a href="http://commons.apache.org/components.html">Commons Components</a>.
+        To make it easier for people to only read messages related to components they are interested in,
+        the convention in Commons is to prefix the subject line of messages with the component's name,
+        for example:
+        <ul>
+          <li>[cli] Problem with the ...</li>
+        </ul>
+      </p>
+      <p>
+        Questions related to the usage of Commons CLI should be posted to the
+        <a href="http://mail-archives.apache.org/mod_mbox/commons-user/">User List</a>.
+        <br />
+        The <a href="http://mail-archives.apache.org/mod_mbox/commons-dev/">Developer List</a>
+        is for questions and discussion related to the development of Commons CLI.
+        <br />
+        Please do not cross-post; developers are also subscribed to the user list.
+      </p>
+      <p>
+        <strong>Note:</strong> please don't send patches or attachments to any of the mailing lists.
+        Patches are best handled via the <a href="issue-tracking.html">Issue Tracking</a> system. 
+        Otherwise, please upload the file to a public server and include the URL in the mail. 
+      </p>
+    </section>
+
+    <section name="Commons CLI Mailing Lists">
+      <p>
+        <strong>Please prefix the subject line of any messages for <a href="index.html">Commons CLI</a>
+        with <i>[cli]</i></strong> - <i>thanks!</i>
+        <br />
+        <br />
+      </p>
+
+      <table>
+        <tr>
+          <th>Name</th>
+          <th>Subscribe</th>
+          <th>Unsubscribe</th>
+          <th>Post</th>
+          <th>Archive</th>
+          <th>Other Archives</th>
+        </tr>
+
+
+        <tr>
+          <td>
+            <strong>Commons User List</strong>
+            <br /><br />
+            Questions on using Commons CLI.
+            <br /><br />
+          </td>
+          <td><a href="mailto:user-subscribe at commons.apache.org">Subscribe</a></td>
+          <td><a href="mailto:user-unsubscribe at commons.apache.org">Unsubscribe</a></td>
+          <td><a href="mailto:user at commons.apache.org?subject=[cli]">Post</a></td>
+          <td><a href="http://mail-archives.apache.org/mod_mbox/commons-user/">mail-archives.apache.org</a></td>
+          <td><a href="http://markmail.org/list/org.apache.commons.users/">markmail.org</a><br />
+              <a href="http://www.mail-archive.com/user@commons.apache.org/">www.mail-archive.com</a><br />
+              <a href="http://news.gmane.org/gmane.comp.jakarta.commons.devel">news.gmane.org</a>
+          </td>
+        </tr>
+
+
+        <tr>
+          <td>
+            <strong>Commons Developer List</strong>
+            <br /><br />
+            Discussion of development of Commons CLI.
+            <br /><br />
+          </td>
+          <td><a href="mailto:dev-subscribe at commons.apache.org">Subscribe</a></td>
+          <td><a href="mailto:dev-unsubscribe at commons.apache.org">Unsubscribe</a></td>
+          <td><a href="mailto:dev at commons.apache.org?subject=[cli]">Post</a></td>
+          <td><a href="http://mail-archives.apache.org/mod_mbox/commons-dev/">mail-archives.apache.org</a></td>
+          <td><a href="http://markmail.org/list/org.apache.commons.dev/">markmail.org</a><br />
+              <a href="http://www.mail-archive.com/dev@commons.apache.org/">www.mail-archive.com</a><br />
+              <a href="http://news.gmane.org/gmane.comp.jakarta.commons.devel">news.gmane.org</a>
+          </td>
+        </tr>
+
+
+        <tr>
+          <td>
+            <strong>Commons Issues List</strong>
+            <br /><br />
+            Only for e-mails automatically generated by the <a href="issue-tracking.html">issue tracking</a> system.
+            <br /><br />
+          </td>
+          <td><a href="mailto:issues-subscribe at commons.apache.org">Subscribe</a></td>
+          <td><a href="mailto:issues-unsubscribe at commons.apache.org">Unsubscribe</a></td>
+          <td><i>read only</i></td>
+          <td><a href="http://mail-archives.apache.org/mod_mbox/commons-issues/">mail-archives.apache.org</a></td>
+          <td><a href="http://markmail.org/list/org.apache.commons.issues/">markmail.org</a><br />
+              <a href="http://www.mail-archive.com/issues@commons.apache.org/">www.mail-archive.com</a>
+          </td>
+        </tr>
+
+
+        <tr>
+          <td>
+            <strong>Commons Commits List</strong>
+            <br /><br />
+            Only for e-mails automatically generated by the <a href="source-repository.html">source control</a> sytem.
+            <br /><br />
+          </td>
+          <td><a href="mailto:commits-subscribe at commons.apache.org">Subscribe</a></td>
+          <td><a href="mailto:commits-unsubscribe at commons.apache.org">Unsubscribe</a></td>
+          <td><i>read only</i></td>
+          <td><a href="http://mail-archives.apache.org/mod_mbox/commons-commits/">mail-archives.apache.org</a></td>
+          <td><a href="http://markmail.org/list/org.apache.commons.commits/">markmail.org</a><br />
+              <a href="http://www.mail-archive.com/commits@commons.apache.org/">www.mail-archive.com</a>
+          </td>
+        </tr>
+
+      </table>
+
+    </section>
+    <section name="Apache Mailing Lists">
+      <p>
+        Other mailing lists which you may find useful include:
+      </p>
+
+      <table>
+        <tr>
+          <th>Name</th>
+          <th>Subscribe</th>
+          <th>Unsubscribe</th>
+          <th>Post</th>
+          <th>Archive</th>
+          <th>Other Archives</th>
+        </tr>
+        <tr>
+          <td>
+            <strong>Apache Announce List</strong>
+            <br /><br />
+            General announcements of Apache project releases.
+            <br /><br />
+          </td>
+          <td><a class="externalLink" href="mailto:announce-subscribe at apache.org">Subscribe</a></td> 
+          <td><a class="externalLink" href="mailto:announce-unsubscribe at apache.org">Unsubscribe</a></td> 
+          <td><i>read only</i></td>
+          <td><a class="externalLink" href="http://mail-archives.apache.org/mod_mbox/www-announce/">mail-archives.apache.org</a></td> 
+          <td><a class="externalLink" href="http://markmail.org/list/org.apache.announce/">markmail.org</a><br />
+              <a class="externalLink" href="http://old.nabble.com/Apache-News-and-Announce-f109.html">old.nabble.com</a><br />
+              <a class="externalLink" href="http://www.mail-archive.com/announce@apache.org/">www.mail-archive.com</a><br />
+              <a class="externalLink" href="http://news.gmane.org/gmane.comp.apache.announce">news.gmane.org</a>
+          </td>
+        </tr>
+      </table>
+
+    </section>
+  </body>
+</document>
diff --git a/src/site/xdoc/properties.xml b/src/site/xdoc/properties.xml
new file mode 100644
index 0000000..e5c1f81
--- /dev/null
+++ b/src/site/xdoc/properties.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<document>
+
+  <properties>
+    <author email="dev at commons.apache.org">commons-dev</author>
+    <title>Option Properties</title>
+  </properties>
+
+  <body>
+    <section name="Option Properties">
+      <p>
+        The following are the properties that each 
+        <a href="api-release/org/apache/commons/cli/Option.html">Option</a> has.  All of these
+        can be set using the accessors or using the methods
+        defined in the
+        <a href="api-release/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>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/src/java/org/apache/commons/cli/package.html b/src/site/xdoc/release_1_0.xml
similarity index 50%
rename from src/java/org/apache/commons/cli/package.html
rename to src/site/xdoc/release_1_0.xml
index 20ebdde..0ac1aa1 100644
--- a/src/java/org/apache/commons/cli/package.html
+++ b/src/site/xdoc/release_1_0.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0"?>
 <!--
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
@@ -14,8 +15,31 @@ 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.
 -->
+<document>
+ <properties>
+  <title>Release notes for CLI 1.0</title>
+  <author email="dev at commons.apache.org">Commons Documentation Team</author>
+ </properties>
 <body>
 
-    Commons CLI 1.2
+<section name="Release notes">
+<p>
+These are the release notes for Commons CLI 1.0.
+<source>
+INTRODUCTION:
+
+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.
+
+For more information, read the documentation on the project site at 
+http://commons.apache.org/cli/
+</source>
+</p>
+</section>
 
 </body>
+</document>
diff --git a/RELEASE-NOTES.txt b/src/site/xdoc/release_1_2.xml
similarity index 69%
copy from RELEASE-NOTES.txt
copy to src/site/xdoc/release_1_2.xml
index fe5dca0..24777c7 100644
--- a/RELEASE-NOTES.txt
+++ b/src/site/xdoc/release_1_2.xml
@@ -1,10 +1,32 @@
-$Id: RELEASE-NOTES.txt 695235 2008-09-14 15:26:10Z ebourg $
-
-            Commons CLI Package
-                Version 1.2
-               Release Notes
-
-
+<?xml version="1.0"?>
+<!--
+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.
+-->
+<document>
+ <properties>
+  <title>Release notes for CLI 1.2</title>
+  <author email="dev at commons.apache.org">Commons Documentation Team</author>
+ </properties>
+<body>
+
+<section name="Release notes">
+
+  <p>These are the release notes for Commons CLI 1.2.</p>
+
+<source>
 INTRODUCTION:
 
 This document contains the release notes for this version of the Commons CLI
@@ -71,3 +93,9 @@ CHANGES:
     CommandLine and Options. (CLI-140)
 
   * OptionValidator is no longer public, its methods were all private.
+</source>
+
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/release_1_3.xml b/src/site/xdoc/release_1_3.xml
new file mode 100644
index 0000000..efbd24d
--- /dev/null
+++ b/src/site/xdoc/release_1_3.xml
@@ -0,0 +1,154 @@
+<?xml version="1.0"?>
+<!--
+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.
+-->
+<document>
+ <properties>
+  <title>Release notes for CLI 1.3</title>
+  <author email="dev at commons.apache.org">Commons Documentation Team</author>
+ </properties>
+<body>
+
+<section name="Release notes">
+
+  <p>These are the release notes for Commons CLI 1.3.</p>
+
+<source>
+INTRODUCTION:
+
+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.
+
+Commons CLI 1.3 is a bugfix and feature release and binary compatible with the
+previous versions, except for the OptionValidator class that is no longer public
+(change introduced in v1.2). Commons CLI 1.3 at least requires Java 5.0.
+
+More information can be found on the project site at
+http://commons.apache.org/cli.
+
+NOTES
+=====
+
+A new parser is available: DefaultParser. It combines the features of the
+GnuParser and the PosixParser. It also provides additional features like
+partial matching for the long options, and long options without
+separator (i.e like the JVM memory settings: -Xmx512m). This new parser
+deprecates the previous ones.
+
+DEPRECATIONS
+============
+
+o org.apache.commons.cli.BasicParser
+    replaced by org.apache.commons.cli.DefaultParser
+
+o org.apache.commons.cli.GnuParser
+    replaced by org.apache.commons.cli.DefaultParser
+
+o org.apache.commons.cli.OptionBuilder
+    replaced by org.apache.commons.cli.Option.builder()
+                org.apache.commons.cli.Option.builder(String)
+                org.apache.commons.cli.Option.Builder
+
+o org.apache.commons.cli.Parser
+    replaced by org.apache.commons.cli.DefaultParser
+
+o org.apache.commons.cli.PosixParser
+    replaced by org.apache.commons.cli.DefaultParser
+
+
+NEW FEATURES
+============
+
+o CLI-161: PosixParser doesn't stop the parsing on "--" tokens following an
+           option with an argument
+o CLI-167: Support options like Java memory settings (-Xmx512M)
+o CLI-181: Unified Parser
+o CLI-224: Added new fluent API to create Option instances via builder class
+           Option.Builder. This replaces the now deprecated OptionBuilder.
+           Thanks to Duncan Jones, Brian Blount.
+o CLI-160: PosixParser now supports partial long options (--ver instead of
+           --version).
+o CLI-169: HelpFormatter now supports setting the displayed separator of long
+           options. Thanks to J. Lewis Muir.
+o CLI-214: Added new method Options.addOption(String, String). Thanks to
+           Alexandru Mocanu.
+
+
+BUG FIXES
+=========
+
+o CLI-248: Dead links on doc page.
+o CLI-234: Fixed code example in javadoc of
+           "Option#Builder#valueSeparator(char)". Thanks to Greg Thomas.
+o CLI-241: Clarified behavior of "OptionValidator#validateOption(String)"
+           in case of null input. Thanks to Beluga Behr.
+o CLI-202: Default options will now work correctly with required options that
+           are missing.
+o CLI-203: Default options will now work correctly together with option groups.
+o CLI-205: HelpFormatter.setArgName(String) now correctly sets the argument
+           name.
+o CLI-204: Passing default values for not defined options to a parser will now
+           trigger a ParseException instead of a NullPointerException.
+o CLI-201: Default properties provided as input to the Parser.parse() methods
+           are now correctly processed.
+o CLI-215: CommandLine.getParsedOptionValue() now returns a String object if no
+           option type has been explicitly set. Thanks to Manuel Müller.
+o CLI-212: HelpFormatter now prints command-line options in the same order as
+           they have been added. Thanks to Per Cederberg.
+o CLI-186: Standard help text now shows mandatory arguments also for the first
+           option. Thanks to Kristoff Kiefer.
+o CLI-207: HelpFormatter does not strip anymore leading whitespace in the
+           footer text. Thanks to Uri Moszkowicz.
+o CLI-185: Strip quotes contained in argument values only if there is exactly
+           one at the beginning and one at the end. Thanks to
+           Einar M. R. Rosenvinge.
+o CLI-184: Negative numerical arguments take precedence over numerical options.
+o CLI-193: Fix possible StringIndexOutOfBoundsException in HelpFormatter.
+           Thanks to Travis McLeskey.
+o CLI-183: OptionGroups no longer throw an AlreadySelectedException when reused
+           for several parsings.
+o CLI-182: OptionGroup now selects properly an option with no short name.
+
+
+CHANGES
+=======
+
+o CLI-240: Small cleanup of Option class. Thanks to Beluga Behr.
+o CLI-230: Options.getRequiredOptions() now returns an unmodifiable list.
+o CLI-218: Clarify javadoc for CommandLine.getOptionValue() that the first
+           specified argument will be returned. Thanks to Sven.
+o CLI-227: Changed unit tests to junit 4 annotation style. Thanks to
+           Duncan Jones.
+o CLI-209: The javadoc of OptionBuilder now states that the class is not
+           thread-safe. Thanks to Thomas Herre.
+o CLI-200: Fixed typo in javadoc of class CommandLine. Thanks to
+           Gerard Weatherby.
+o CLI-223: Source code now uses generic types instead of raw types where
+           possible. Thanks to Gerard Weatherby.
+o CLI-220  Corrected javadoc for return type of
+           MissingOptionException.getMissingOptions(). Thanks to Joe Casadonte.
+o CLI-197: Improve description of parameter "stopAtNonOption" in method
+           CommandLine.parse(Options, String[], boolean). Thanks to
+           Anders Larsson.
+o CLI-231: Removed DoubleCheckedLocking test from checkstyle configuration.
+           Thanks to Duncan Jones.
+</source>
+
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/release_1_3_1.xml b/src/site/xdoc/release_1_3_1.xml
new file mode 100644
index 0000000..9a97fea
--- /dev/null
+++ b/src/site/xdoc/release_1_3_1.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<!--
+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.
+-->
+<document>
+ <properties>
+  <title>Release notes for CLI 1.3.1</title>
+  <author email="dev at commons.apache.org">Commons Documentation Team</author>
+ </properties>
+<body>
+
+<section name="Release notes">
+
+  <p>These are the release notes for Commons CLI 1.3.1.</p>
+
+<source>
+INTRODUCTION:
+
+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.
+
+Commons CLI 1.3.1 is a bug fix release and binary compatible with the
+previous versions, except for the OptionValidator class that is no longer public
+(change introduced in v1.2). Commons CLI 1.3.1 at least requires Java 5.0.
+
+More information can be found on the project site at
+http://commons.apache.org/cli.
+
+BUG FIXES
+=========
+
+o CLI-252: LongOpt falsely detected as ambiguous. Thanks to Simon Harrer.
+</source>
+
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/upgrading-1.0-to-1.1.xml b/src/site/xdoc/upgrading-1.0-to-1.1.xml
new file mode 100644
index 0000000..866477f
--- /dev/null
+++ b/src/site/xdoc/upgrading-1.0-to-1.1.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<!--
+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.
+-->
+<document>
+ <properties>
+  <title>Upgrading from 1.0 to 1.1</title>
+  <author email="dev at commons.apache.org">Commons Documentation Team</author>
+ </properties>
+<body>
+<!-- ================================================== -->
+<section name="Upgrading from 1.0 to 1.1">
+  <p>CLI 1.1 is a bugfix release of CLI. The following changes notable API changes were made: </p>
+
+  <ul>
+    <li>The Parser abstract class has two additional parse methods that take a Properties parameter. </li>
+    <li>The HelpFormatter class had publicly accessible fields. These should now be accessed via
+        get/set methods and the public fields are deprecated. </li>
+    <li>The Option class addValue(String) method now throws UnsupportedOperationException. </li>
+    <li>OptionValidator is a newly added class. </li>
+    <li>Option's now have equals(Object) and hashCode() methods. </li>
+    <li>The Option class also received two new methods, setDescription(String) and hasValueSeparator();boolean. </li>
+  </ul>
+
+  <p>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. </p>
+
+</section>
+<section name="Bugs fixed in 1.1">
+  <p>The list of bugs fixed in 1.1 may be seen via the 
+    <a href="changes-report.html#1_1">changes report</a>. </p>
+</section>
+<!-- ================================================== -->
+</body>
+</document>
diff --git a/src/site/xdoc/usage.xml b/src/site/xdoc/usage.xml
new file mode 100644
index 0000000..85f9b89
--- /dev/null
+++ b/src/site/xdoc/usage.xml
@@ -0,0 +1,372 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<document>
+
+  <properties>
+    <author email="dev at commons.apache.org">commons-dev</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 <code>true</code>, otherwise the value is <code>false</code>.
+        </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="api-release/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. 
+            The second parameter 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
+            <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>CommandLineParser</code> are used 
+          to parse the command line arguments. There may be several implementations
+          of the <code>CommandLineParser</code> interface, the recommended one is the
+          <code>DefaultParser</code>.
+        </p>
+        <source>CommandLineParser parser = new DefaultParser();
+CommandLine cmd = parser.parse( options, 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="api-release/org/apache/commons/cli/CommandLine.html">CommandLine
+          </a> object.  The <code>hasOption</code> method takes a 
+          <code>java.lang.String</code> parameter and returns <code>true</code> if the option 
+          represented by the <code>java.lang.String</code> is present, otherwise 
+          it returns <code>false</code>.
+        </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 <code>true</code> 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>CommandLine</code> are
+          used to retrieve the argument values of options.
+        </p>
+        <source>// get c option value
+String countryCode = cmd.getOptionValue("c");
+
+if(countryCode == null) {
+    // print default date
+}
+else {
+    // print date for country specified by countryCode
+}</source>
+      </subsection>
+    </section>
+
+    <section name="Ant Example">
+      <p>
+        One of the most ubiquitous Java applications 
+        <a href="http://ant.apache.org/">Ant</a> will be used
+        here to illustrate how to create the <code>Options</code> 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 for
+          <code>Option</code> 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 <code>OptionBuilder</code>.
+        </p>
+        <source>Option logfile   = OptionBuilder.withArgName( "file" )
+                                .hasArg()
+                                .withDescription(  "use given file for log" )
+                                .create( "logfile" );
+
+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( "find" );</source>
+      </subsection>
+      <subsection name="Java Property Option">
+        <p>
+          The last option to create is the Java property and it is also created
+          using the OptionBuilder.
+        </p>
+        <source>Option property  = OptionBuilder.withArgName( "property=value" )
+                                .hasArgs(2)
+                                .withValueSeparator()
+                                .withDescription( "use value for given property" )
+                                .create( "D" );</source>
+
+          The map of properties specified by this option can later be retrieved by
+          calling <code>getOptionProperties("D")</code> on the <code>CommandLine</code>.
+
+      </subsection>
+      <subsection name="Create the Options">
+        <p>
+          Now that we have created each 
+          <a href="api-release/org/apache/commons/cli/Option.html">Option</a> we need
+          to create the 
+          <a href="api-release/org/apache/commons/cli/Options.html">Options</a>
+          instance.  This is achieved using the 
+          <a href="api-release/org/apache/commons/cli/CommandLine.html#addOption(org.apache.commons.cli.Option)">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 <code>CommandLineParser</code>. This will parse the command
+          line arguments, using the rules specified by the <code>Options</code> and
+          return an instance of <a href="api-release/org/apache/commons/cli/CommandLine.html">CommandLine</a>.
+        </p>
+        <source>public static void main( String[] args ) {
+    // create the parser
+    CommandLineParser parser = new DefaultParser();
+    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>getOptionValue</code> method.
+        </p>
+        <source>// has the buildfile argument been passed?
+if( line.hasOption( "buildfile" ) ) {
+    // initialise the member variable
+    this.buildfile = line.getOptionValue( "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="api-release/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>. 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="api-release/org/apache/commons/cli/Options.html">Options</a> for this example.
+      </p>
+      <source>// create the command line parser
+CommandLineParser parser = new DefaultParser();
+
+// 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" )
+                                .hasArg()
+                                .withArgName("SIZE")
+                                .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>
diff --git a/src/test/org/apache/commons/cli/ApplicationTest.java b/src/test/java/org/apache/commons/cli/ApplicationTest.java
similarity index 59%
rename from src/test/org/apache/commons/cli/ApplicationTest.java
rename to src/test/java/org/apache/commons/cli/ApplicationTest.java
index 673c2a6..7fffbb9 100644
--- a/src/test/org/apache/commons/cli/ApplicationTest.java
+++ b/src/test/java/org/apache/commons/cli/ApplicationTest.java
@@ -17,7 +17,13 @@
 
 package org.apache.commons.cli;
 
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.junit.Test;
 
 /**
  * This is a collection of tests that test real world applications command lines.
@@ -31,11 +37,11 @@ import junit.framework.TestCase;
  *   <li>man</li>
  * </ul>
  * </p>
- *
- * @author John Keyes (john at integralsource.com)
  */
-public class ApplicationTest extends TestCase {
-
+ at SuppressWarnings("deprecation") // tests some deprecated classes
+public class ApplicationTest
+{
+    @Test
     public void testLs() throws Exception {
         // create the command line parser
         CommandLineParser parser = new PosixParser();
@@ -62,6 +68,7 @@ public class ApplicationTest extends TestCase {
     /**
      * Ant test
      */
+    @Test
     public void testAnt() throws Exception {
         // use the GNU parser
         CommandLineParser parser = new GnuParser( );
@@ -103,6 +110,7 @@ public class ApplicationTest extends TestCase {
         assertTrue( line.hasOption( "projecthelp") );
     }
 
+    @Test
     public void testGroovy() throws Exception {
         Options options = new Options();
 
@@ -173,6 +181,7 @@ public class ApplicationTest extends TestCase {
     /**
      * author Slawek Zachcial
      */
+    @Test
     public void testMan()
     {
         String cmdLine =
@@ -214,8 +223,118 @@ public class ApplicationTest extends TestCase {
                 addOption("h", "help", false, "show this usage message.");
 
         HelpFormatter hf = new HelpFormatter();
-        //hf.printHelp(cmdLine, opts);
-        hf.printHelp(60, cmdLine, null, options, null);
+        final String EOL = System.getProperty("line.separator");
+        StringWriter out = new StringWriter();
+        hf.printHelp(new PrintWriter(out), 60, cmdLine, null, options, HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_DESC_PAD, null, false);
+        assertEquals("usage: man [-c|-f|-k|-w|-tZT device] [-adlhu7V] [-Mpath]" + EOL +
+                        "           [-Ppager] [-Slist] [-msystem] [-pstring]" + EOL +
+                        "           [-Llocale] [-eextension] [section] page ..." + EOL +
+                        " -7,--ascii                display ASCII translation or" + EOL +
+                        "                           certain latin1 chars." + EOL +
+                        " -a,--all                  find all matching manual pages." + EOL +
+                        " -c,--catman               used by catman to reformat out of" + EOL +
+                        "                           date cat pages." + EOL +
+                        " -d,--debug                emit debugging messages." + EOL +
+                        " -D,--default              reset all options to their" + EOL +
+                        "                           default values." + EOL +
+                        " -e,--extension            limit search to extension type" + EOL +
+                        "                           'extension'." + EOL +
+                        " -f,--whatis               equivalent to whatis." + EOL +
+                        " -h,--help                 show this usage message." + EOL +
+                        " -k,--apropos              equivalent to apropos." + EOL +
+                        " -l,--local-file           interpret 'page' argument(s) as" + EOL +
+                        "                           local filename(s)" + EOL +
+                        " -L,--locale <arg>         define the locale for this" + EOL +
+                        "                           particular man search." + EOL +
+                        " -M,--manpath <arg>        set search path for manual pages" + EOL +
+                        "                           to 'path'." + EOL +
+                        " -m,--systems <arg>        search for man pages from other" + EOL +
+                        "                           unix system(s)." + EOL +
+                        " -P,--pager <arg>          use program 'pager' to display" + EOL +
+                        "                           output." + EOL +
+                        " -p,--preprocessor <arg>   string indicates which" + EOL +
+                        "                           preprocessor to run." + EOL +
+                        "                           e - [n]eqn  p - pic     t - tbl" + EOL +
+                        "                           g - grap    r - refer   v -" + EOL +
+                        "                           vgrind" + EOL +
+                        " -r,--prompt <arg>         provide 'less' pager with prompt." + EOL +
+                        " -S,--sections <arg>       use colon separated section list." + EOL +
+                        " -t,--troff                use troff format pages." + EOL +
+                        " -T,--troff-device <arg>   use groff with selected device." + EOL +
+                        " -u,--update               force a cache consistency check." + EOL +
+                        " -V,--version              show version." + EOL +
+                        " -w,--location             print physical location of man" + EOL +
+                        "                           page(s)." + EOL +
+                        " -Z,--ditroff              use groff with selected device." + EOL,
+                out.toString());
     }
 
+
+    /**
+     * Real world test with long and short options.
+     */
+    @Test
+    public void testNLT() throws Exception {
+        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 minutes")
+                                        .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"
+            };
+
+        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");
+    }
 }
diff --git a/src/test/org/apache/commons/cli/ArgumentIsOptionTest.java b/src/test/java/org/apache/commons/cli/ArgumentIsOptionTest.java
similarity index 90%
rename from src/test/org/apache/commons/cli/ArgumentIsOptionTest.java
rename to src/test/java/org/apache/commons/cli/ArgumentIsOptionTest.java
index d71b0c4..cd716bd 100644
--- a/src/test/org/apache/commons/cli/ArgumentIsOptionTest.java
+++ b/src/test/java/org/apache/commons/cli/ArgumentIsOptionTest.java
@@ -17,13 +17,19 @@
 
 package org.apache.commons.cli;
 
-import junit.framework.TestCase;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
-public class ArgumentIsOptionTest extends TestCase
+import org.junit.Before;
+import org.junit.Test;
+
+ at SuppressWarnings("deprecation") // tests some deprecated classes
+public class ArgumentIsOptionTest
 {
     private Options options = null;
     private CommandLineParser parser = null;
 
+    @Before
     public void setUp()
     {
         options = new Options().addOption("p", false, "Option p").addOption("attr", true, "Option accepts argument");
@@ -31,6 +37,7 @@ public class ArgumentIsOptionTest extends TestCase
         parser = new PosixParser();
     }
 
+    @Test
     public void testOptionAndOptionWithArgument() throws Exception
     {
         String[] args = new String[]{
@@ -46,6 +53,7 @@ public class ArgumentIsOptionTest extends TestCase
         assertTrue("Confirm all arguments recognized", cl.getArgs().length == 0);
     }
 
+    @Test
     public void testOptionWithArgument() throws Exception
     {
         String[] args = new String[]{
@@ -61,6 +69,7 @@ public class ArgumentIsOptionTest extends TestCase
         assertTrue("Confirm all arguments recognized", cl.getArgs().length == 0);
     }
 
+    @Test
     public void testOption() throws Exception
     {
         String[] args = new String[]{
diff --git a/src/test/java/org/apache/commons/cli/BasicParserTest.java b/src/test/java/org/apache/commons/cli/BasicParserTest.java
new file mode 100644
index 0000000..53683eb
--- /dev/null
+++ b/src/test/java/org/apache/commons/cli/BasicParserTest.java
@@ -0,0 +1,175 @@
+/**
+ * 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 org.junit.Before;
+
+ at SuppressWarnings("deprecation") // tests some deprecated classes
+public class BasicParserTest extends ParserTestCase
+{
+    @Before
+    public void setUp()
+    {
+        super.setUp();
+        parser = new BasicParser();
+    }
+
+    @Override
+    public void testDoubleDash2() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+
+    @Override
+    public void testLongWithoutEqualSingleDash() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+    
+    @Override
+    public void testAmbiguousLongWithoutEqualSingleDash() throws Exception
+    {
+        // not supported by the basicParser
+    }
+    
+    @Override
+    public void testNegativeOption() throws Exception
+    {
+        // not supported by the BasicParser (CLI-184)
+    }
+
+    @Override
+    public void testPropertiesOption1() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+
+    @Override
+    public void testPropertiesOption2() throws Exception
+    {
+        // not supported by the BasicParser
+    }    
+
+    @Override
+    public void testShortWithEqual() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+
+    @Override
+    public void testShortWithoutEqual() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+
+    @Override
+    public void testLongWithEqualDoubleDash() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+
+    @Override
+    public void testLongWithEqualSingleDash() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+    
+    @Override
+    public void testUnambiguousPartialLongOption1() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+
+    @Override
+    public void testUnambiguousPartialLongOption2() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+
+    @Override
+    public void testUnambiguousPartialLongOption3() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+
+    @Override
+    public void testUnambiguousPartialLongOption4() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+
+    @Override
+    public void testAmbiguousPartialLongOption1() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+
+    @Override
+    public void testAmbiguousPartialLongOption2() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+
+    @Override
+    public void testAmbiguousPartialLongOption3() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+
+    @Override
+    public void testAmbiguousPartialLongOption4() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+
+    @Override
+    public void testPartialLongOptionSingleDash() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+
+    @Override
+    public void testBursting() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+
+    @Override
+    public void testUnrecognizedOptionWithBursting() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+
+    @Override
+    public void testMissingArgWithBursting() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+
+    @Override
+    public void testStopBursting() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+
+    @Override
+    public void testStopBursting2() throws Exception
+    {
+        // not supported by the BasicParser
+    }
+}
diff --git a/src/test/org/apache/commons/cli/CommandLineTest.java b/src/test/java/org/apache/commons/cli/CommandLineTest.java
similarity index 62%
rename from src/test/org/apache/commons/cli/CommandLineTest.java
rename to src/test/java/org/apache/commons/cli/CommandLineTest.java
index c6d1bbe..60a0c91 100644
--- a/src/test/org/apache/commons/cli/CommandLineTest.java
+++ b/src/test/java/org/apache/commons/cli/CommandLineTest.java
@@ -17,16 +17,17 @@
 
 package org.apache.commons.cli;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
 import java.util.Properties;
 
-import junit.framework.TestCase;
+import org.junit.Test;
 
-/**
- * @author Emmanuel Bourg
- * @version $Revision: 667595 $, $Date: 2008-06-13 10:03:31 -0700 (Fri, 13 Jun 2008) $
- */
-public class CommandLineTest extends TestCase
+ at SuppressWarnings("deprecation") // tests some deprecated classes
+public class CommandLineTest
 {
+    @Test
     public void testGetOptionProperties() throws Exception
     {
         String[] args = new String[] { "-Dparam1=value1", "-Dparam2=value2", "-Dparam3", "-Dparam4=value4", "-D", "--property", "foo=bar" };
@@ -48,4 +49,31 @@ public class CommandLineTest extends TestCase
 
         assertEquals("property with long format", "bar", cl.getOptionProperties("property").getProperty("foo"));
     }
+
+    @Test
+    public void testGetOptions()
+    {
+        CommandLine cmd = new CommandLine();
+        assertNotNull(cmd.getOptions());
+        assertEquals(0, cmd.getOptions().length);
+        
+        cmd.addOption(new Option("a", null));
+        cmd.addOption(new Option("b", null));
+        cmd.addOption(new Option("c", null));
+        
+        assertEquals(3, cmd.getOptions().length);
+    }
+
+    @Test
+    public void testGetParsedOptionValue() throws Exception {
+        Options options = new Options();
+        options.addOption(OptionBuilder.hasArg().withType(Number.class).create("i"));
+        options.addOption(OptionBuilder.hasArg().create("f"));
+        
+        CommandLineParser parser = new DefaultParser();
+        CommandLine cmd = parser.parse(options, new String[] { "-i", "123", "-f", "foo" });
+        
+        assertEquals(123, ((Number) cmd.getParsedOptionValue("i")).intValue());
+        assertEquals("foo", cmd.getParsedOptionValue("f"));
+    }
 }
diff --git a/src/test/org/apache/commons/cli/GnuParserTest.java b/src/test/java/org/apache/commons/cli/DefaultParserTest.java
similarity index 84%
rename from src/test/org/apache/commons/cli/GnuParserTest.java
rename to src/test/java/org/apache/commons/cli/DefaultParserTest.java
index 43f80fa..00a405d 100644
--- a/src/test/org/apache/commons/cli/GnuParserTest.java
+++ b/src/test/java/org/apache/commons/cli/DefaultParserTest.java
@@ -17,11 +17,13 @@
 
 package org.apache.commons.cli;
 
-public class GnuParserTest extends ParserTestCase
-{
-    public void setUp()
-    {
+import org.junit.Before;
+
+public class DefaultParserTest extends ParserTestCase {
+
+    @Before
+    public void setUp() {
         super.setUp();
-        parser = new GnuParser();
+        parser = new DefaultParser();
     }
 }
diff --git a/src/test/java/org/apache/commons/cli/GnuParserTest.java b/src/test/java/org/apache/commons/cli/GnuParserTest.java
new file mode 100644
index 0000000..86b187b
--- /dev/null
+++ b/src/test/java/org/apache/commons/cli/GnuParserTest.java
@@ -0,0 +1,157 @@
+/**
+ * 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 org.junit.Before;
+
+ at SuppressWarnings("deprecation") // tests some deprecated classes
+public class GnuParserTest extends ParserTestCase
+{
+    @Before
+    public void setUp()
+    {
+        super.setUp();
+        parser = new GnuParser();
+    }
+
+    @Override
+    public void testDoubleDash2() throws Exception
+    {
+        // not supported by the GnuParser
+    }
+    
+    @Override
+    public void testLongWithoutEqualSingleDash() throws Exception
+    {
+        // not supported by the GnuParser
+    }
+
+    @Override
+    public void testAmbiguousLongWithoutEqualSingleDash() throws Exception
+    {
+        // not supported by the GnuParser
+    }
+
+    @Override
+    public void testNegativeOption() throws Exception
+    {
+        // not supported by the GnuParser (CLI-184)
+    }
+
+    @Override
+    public void testLongWithUnexpectedArgument1() throws Exception 
+    {
+        // not supported by the GnuParser
+    }
+
+    @Override
+    public void testLongWithUnexpectedArgument2() throws Exception 
+    {
+        // not supported by the GnuParser
+    }
+
+    @Override
+    public void testShortWithUnexpectedArgument() throws Exception 
+    {
+        // not supported by the GnuParser
+    }
+
+    @Override
+    public void testUnambiguousPartialLongOption1() throws Exception
+    {
+        // not supported by the GnuParser
+    }
+
+    @Override
+    public void testUnambiguousPartialLongOption2() throws Exception
+    {
+        // not supported by the GnuParser
+    }
+
+    @Override
+    public void testUnambiguousPartialLongOption3() throws Exception
+    {
+        // not supported by the GnuParser
+    }
+
+    @Override
+    public void testUnambiguousPartialLongOption4() throws Exception
+    {
+        // not supported by the GnuParser
+    }
+
+    @Override
+    public void testAmbiguousPartialLongOption1() throws Exception
+    {
+        // not supported by the GnuParser
+    }
+
+    @Override
+    public void testAmbiguousPartialLongOption2() throws Exception
+    {
+        // not supported by the GnuParser
+    }
+
+    @Override
+    public void testAmbiguousPartialLongOption3() throws Exception
+    {
+        // not supported by the GnuParser
+    }
+
+    @Override
+    public void testAmbiguousPartialLongOption4() throws Exception
+    {
+        // not supported by the GnuParser
+    }
+
+    @Override
+    public void testPartialLongOptionSingleDash() throws Exception
+    {
+        // not supported by the GnuParser
+    }
+
+    @Override
+    public void testBursting() throws Exception
+    {
+        // not supported by the GnuParser
+    }
+
+    @Override
+    public void testUnrecognizedOptionWithBursting() throws Exception
+    {
+        // not supported by the GnuParser
+    }
+
+    @Override
+    public void testMissingArgWithBursting() throws Exception
+    {
+        // not supported by the GnuParser
+    }
+
+    @Override
+    public void testStopBursting() throws Exception
+    {
+        // not supported by the GnuParser
+    }
+
+    @Override
+    public void testStopBursting2() throws Exception
+    {
+        // not supported by the GnuParser
+    }
+}
diff --git a/src/test/org/apache/commons/cli/HelpFormatterTest.java b/src/test/java/org/apache/commons/cli/HelpFormatterTest.java
similarity index 59%
rename from src/test/org/apache/commons/cli/HelpFormatterTest.java
rename to src/test/java/org/apache/commons/cli/HelpFormatterTest.java
index 10ecab3..847a268 100644
--- a/src/test/org/apache/commons/cli/HelpFormatterTest.java
+++ b/src/test/java/org/apache/commons/cli/HelpFormatterTest.java
@@ -17,83 +17,146 @@
 
 package org.apache.commons.cli;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
 import java.io.ByteArrayOutputStream;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.Comparator;
 
-import junit.framework.TestCase;
+import org.junit.Test;
 
 /** 
- * Test case for the HelpFormatter class 
- *
- * @author Slawek Zachcial
- * @author John Keyes ( john at integralsource.com )
- * @author brianegge
+ * Test case for the HelpFormatter class.
  */
-public class HelpFormatterTest extends TestCase
+public class HelpFormatterTest
 {
     private static final String EOL = System.getProperty("line.separator");
 
+    @Test
     public void testFindWrapPos() throws Exception
     {
         HelpFormatter hf = new HelpFormatter();
 
         String text = "This is a test.";
-        //text width should be max 8; the wrap position is 7
+        // text width should be max 8; the wrap position is 7
         assertEquals("wrap position", 7, hf.findWrapPos(text, 8, 0));
-        //starting from 8 must give -1 - the wrap pos is after end
+        
+        // starting from 8 must give -1 - the wrap pos is after end
         assertEquals("wrap position 2", -1, hf.findWrapPos(text, 8, 8));
-        //if there is no a good position before width to make a wrapping look for the next one
+        
+        // words longer than the width are cut
         text = "aaaa aa";
-        assertEquals("wrap position 3", 4, hf.findWrapPos(text, 3, 0));
+        assertEquals("wrap position 3", 3, hf.findWrapPos(text, 3, 0));
+        
+        // last word length is equal to the width
+        text = "aaaaaa aaaaaa";
+        assertEquals("wrap position 4", 6, hf.findWrapPos(text, 6, 0));
+        assertEquals("wrap position 4", -1, hf.findWrapPos(text, 6, 7));
+        
+        text = "aaaaaa\n aaaaaa";
+        assertEquals("wrap position 5", 7, hf.findWrapPos(text, 6, 0));
+        
+        text = "aaaaaa\t aaaaaa";
+        assertEquals("wrap position 6", 7, hf.findWrapPos(text, 6, 0));
     }
 
-    public void testPrintWrapped() throws Exception
+    @Test
+    public void testRenderWrappedTextWordCut()
     {
+        int width = 7;
+        int padding = 0;
+        String text = "Thisisatest.";
+        String expected = "Thisisa" + EOL + 
+                          "test.";
+        
         StringBuffer sb = new StringBuffer();
-        HelpFormatter hf = new HelpFormatter();
+        new HelpFormatter().renderWrappedText(sb, width, padding, text);
+        assertEquals("cut and wrap", expected, sb.toString());
+    }
 
+    @Test
+    public void testRenderWrappedTextSingleLine()
+    {
+        // single line text
+        int width = 12;
+        int padding = 0;
         String text = "This is a test.";
-
-        String expected = "This is a" + hf.getNewLine() + "test.";
-        hf.renderWrappedText(sb, 12, 0, text);
+        String expected = "This is a" + EOL + 
+                          "test.";
+        
+        StringBuffer sb = new StringBuffer();
+        new HelpFormatter().renderWrappedText(sb, width, padding, text);
         assertEquals("single line text", expected, sb.toString());
+    }
 
-        sb.setLength(0);
-        expected = "This is a" + hf.getNewLine() + "    test.";
-        hf.renderWrappedText(sb, 12, 4, text);
+    @Test
+    public void testRenderWrappedTextSingleLinePadded()
+    {
+        // single line padded text
+        int width = 12;
+        int padding = 4;
+        String text = "This is a test.";
+        String expected = "This is a" + EOL + 
+                          "    test.";
+        
+        StringBuffer sb = new StringBuffer();
+        new HelpFormatter().renderWrappedText(sb, width, padding, text);
         assertEquals("single line padded text", expected, sb.toString());
+    }
 
-        text = "  -p,--period <PERIOD>  PERIOD is time duration of form " +
-               "DATE[-DATE] where DATE has form YYYY[MM[DD]]";
-
-        sb.setLength(0);
-        expected = "  -p,--period <PERIOD>  PERIOD is time duration of" +
-                hf.getNewLine() +
-                "                        form DATE[-DATE] where DATE" +
-                hf.getNewLine() +
-                "                        has form YYYY[MM[DD]]";
-        hf.renderWrappedText(sb, 53, 24, text);
+    @Test
+    public void testRenderWrappedTextSingleLinePadded2()
+    {
+        // single line padded text 2
+        int width = 53;
+        int padding = 24;
+        String text = "  -p,--period <PERIOD>  PERIOD is time duration of form " +
+                      "DATE[-DATE] where DATE has form YYYY[MM[DD]]";
+        String expected = "  -p,--period <PERIOD>  PERIOD is time duration of" + EOL +
+                          "                        form DATE[-DATE] where DATE" + EOL +
+                          "                        has form YYYY[MM[DD]]";
+        
+        StringBuffer sb = new StringBuffer();
+        new HelpFormatter().renderWrappedText(sb, width, padding, text);
         assertEquals("single line padded text 2", expected, sb.toString());
+    }
 
-        text = "aaaa aaaa aaaa" + hf.getNewLine() +
-               "aaaaaa" + hf.getNewLine() +
-               "aaaaa";
+    @Test
+    public void testRenderWrappedTextMultiLine()
+    {
+        // multi line text
+        int width = 16;
+        int padding = 0;
+        String expected = "aaaa aaaa aaaa" + EOL +
+                      "aaaaaa" + EOL +
+                      "aaaaa";
 
-        expected = text;
-        sb.setLength(0);
-        hf.renderWrappedText(sb, 16, 0, text);
+        StringBuffer sb = new StringBuffer();
+        new HelpFormatter().renderWrappedText(sb, width, padding, expected);
         assertEquals("multi line text", expected, sb.toString());
+    }
 
-        expected = "aaaa aaaa aaaa" + hf.getNewLine() +
-                   "    aaaaaa" + hf.getNewLine() +
-                   "    aaaaa";
-        sb.setLength(0);
-        hf.renderWrappedText(sb, 16, 4, text);
+    @Test
+    public void testRenderWrappedTextMultiLinePadded()
+    {
+        // multi-line padded text
+        int width = 16;
+        int padding = 4;
+        String text = "aaaa aaaa aaaa" + EOL +
+                      "aaaaaa" + EOL +
+                      "aaaaa";
+        String expected = "aaaa aaaa aaaa" + EOL +
+                          "    aaaaaa" + EOL +
+                          "    aaaaa";
+        
+        StringBuffer sb = new StringBuffer();
+        new HelpFormatter().renderWrappedText(sb, width, padding, text);
         assertEquals("multi-line padded text", expected, sb.toString());
     }
 
+    @Test
     public void testPrintOptions() throws Exception
     {
         StringBuffer sb = new StringBuffer();
@@ -111,7 +174,7 @@ public class HelpFormatterTest extends TestCase
         assertEquals("simple non-wrapped option", expected, sb.toString());
 
         int nextLineTabStop = leftPad + descPad + "-a".length();
-        expected = lpad + "-a" + dpad + "aaaa aaaa aaaa" + hf.getNewLine() +
+        expected = lpad + "-a" + dpad + "aaaa aaaa aaaa" + EOL +
                    hf.createPadding(nextLineTabStop) + "aaaa aaaa";
         sb.setLength(0);
         hf.renderOptions(sb, nextLineTabStop + 17, options, leftPad, descPad);
@@ -125,7 +188,7 @@ public class HelpFormatterTest extends TestCase
         assertEquals("long non-wrapped option", expected, sb.toString());
 
         nextLineTabStop = leftPad + descPad + "-a,--aaa".length();
-        expected = lpad + "-a,--aaa" + dpad + "dddd dddd" + hf.getNewLine() +
+        expected = lpad + "-a,--aaa" + dpad + "dddd dddd" + EOL +
                    hf.createPadding(nextLineTabStop) + "dddd dddd";
         sb.setLength(0);
         hf.renderOptions(sb, 25, options, leftPad, descPad);
@@ -134,15 +197,16 @@ public class HelpFormatterTest extends TestCase
         options = new Options().
                 addOption("a", "aaa", false, "dddd dddd dddd dddd").
                 addOption("b", false, "feeee eeee eeee eeee");
-        expected = lpad + "-a,--aaa" + dpad + "dddd dddd" + hf.getNewLine() +
-                   hf.createPadding(nextLineTabStop) + "dddd dddd" + hf.getNewLine() +
-                   lpad + "-b      " + dpad + "feeee eeee" + hf.getNewLine() +
+        expected = lpad + "-a,--aaa" + dpad + "dddd dddd" + EOL +
+                   hf.createPadding(nextLineTabStop) + "dddd dddd" + EOL +
+                   lpad + "-b      " + dpad + "feeee eeee" + EOL +
                    hf.createPadding(nextLineTabStop) + "eeee eeee";
         sb.setLength(0);
         hf.renderOptions(sb, 25, options, leftPad, descPad);
         assertEquals("multiple wrapped options", expected, sb.toString());
     }
 
+    @Test
     public void testPrintHelpWithEmptySyntax()
     {
         HelpFormatter formatter = new HelpFormatter();
@@ -167,6 +231,7 @@ public class HelpFormatterTest extends TestCase
         }
     }
 
+    @Test
     public void testAutomaticUsage() throws Exception
     {
         HelpFormatter hf = new HelpFormatter();
@@ -192,6 +257,7 @@ public class HelpFormatterTest extends TestCase
 
     // This test ensures the options are properly sorted
     // See https://issues.apache.org/jira/browse/CLI-131
+    @Test
     public void testPrintUsage()
     {
         Option optionA = new Option("a", "first");
@@ -210,6 +276,7 @@ public class HelpFormatterTest extends TestCase
     }
 
     // uses the test for CLI-131 to implement CLI-155
+    @Test
     public void testPrintSortedUsage()
     {
         Options opts = new Options();
@@ -218,13 +285,11 @@ public class HelpFormatterTest extends TestCase
         opts.addOption(new Option("c", "third"));
 
         HelpFormatter helpFormatter = new HelpFormatter();
-        helpFormatter.setOptionComparator(new Comparator()
+        helpFormatter.setOptionComparator(new Comparator<Option>()
         {
-            public int compare(Object o1, Object o2)
+            public int compare(Option opt1, Option opt2)
             {
-                // reverses the fuctionality of the default comparator
-                Option opt1 = (Option) o1;
-                Option opt2 = (Option) o2;
+                // reverses the functionality of the default comparator
                 return opt2.getKey().compareToIgnoreCase(opt1.getKey());
             }
         });
@@ -235,12 +300,13 @@ public class HelpFormatterTest extends TestCase
         assertEquals("usage: app [-c] [-b] [-a]" + EOL, out.toString());
     }
 
+    @Test
     public void testPrintSortedUsageWithNullComparator()
     {
         Options opts = new Options();
-        opts.addOption(new Option("a", "first"));
+        opts.addOption(new Option("c", "first"));
         opts.addOption(new Option("b", "second"));
-        opts.addOption(new Option("c", "third"));
+        opts.addOption(new Option("a", "third"));
 
         HelpFormatter helpFormatter = new HelpFormatter();
         helpFormatter.setOptionComparator(null);
@@ -248,15 +314,16 @@ public class HelpFormatterTest extends TestCase
         StringWriter out = new StringWriter();
         helpFormatter.printUsage(new PrintWriter(out), 80, "app", opts);
 
-        assertEquals("usage: app [-a] [-b] [-c]" + EOL, out.toString());
+        assertEquals("usage: app [-c] [-b] [-a]" + EOL, out.toString());
     }
 
+    @Test
     public void testPrintOptionGroupUsage()
     {
         OptionGroup group = new OptionGroup();
-        group.addOption(OptionBuilder.create("a"));
-        group.addOption(OptionBuilder.create("b"));
-        group.addOption(OptionBuilder.create("c"));
+        group.addOption(Option.builder("a").build());
+        group.addOption(Option.builder("b").build());
+        group.addOption(Option.builder("c").build());
 
         Options options = new Options();
         options.addOptionGroup(group);
@@ -269,12 +336,13 @@ public class HelpFormatterTest extends TestCase
         assertEquals("usage: app [-a | -b | -c]" + EOL, out.toString());
     }
 
+    @Test
     public void testPrintRequiredOptionGroupUsage()
     {
         OptionGroup group = new OptionGroup();
-        group.addOption(OptionBuilder.create("a"));
-        group.addOption(OptionBuilder.create("b"));
-        group.addOption(OptionBuilder.create("c"));
+        group.addOption(Option.builder("a").build());
+        group.addOption(Option.builder("b").build());
+        group.addOption(Option.builder("c").build());
         group.setRequired(true);
 
         Options options = new Options();
@@ -288,6 +356,7 @@ public class HelpFormatterTest extends TestCase
         assertEquals("usage: app -a | -b | -c" + EOL, out.toString());
     }
 
+    @Test
     public void testPrintOptionWithEmptyArgNameUsage()
     {
         Option option = new Option("f", true, null);
@@ -305,6 +374,24 @@ public class HelpFormatterTest extends TestCase
         assertEquals("usage: app -f" + EOL, out.toString());
     }
 
+    @Test
+    public void testDefaultArgName()
+    {
+        Option option = Option.builder("f").hasArg().required(true).build();
+        
+        Options options = new Options();
+        options.addOption(option);
+        
+        StringWriter out = new StringWriter();
+
+        HelpFormatter formatter = new HelpFormatter();
+        formatter.setArgName("argument");
+        formatter.printUsage(new PrintWriter(out), 80, "app", options);
+
+        assertEquals("usage: app -f <argument>" + EOL, out.toString());
+    }
+
+    @Test
     public void testRtrim()
     {
         HelpFormatter formatter = new HelpFormatter();
@@ -314,6 +401,7 @@ public class HelpFormatterTest extends TestCase
         assertEquals("  foo", formatter.rtrim("  foo  "));
     }
 
+    @Test
     public void testAccessors()
     {
         HelpFormatter formatter = new HelpFormatter();
@@ -343,6 +431,7 @@ public class HelpFormatterTest extends TestCase
         assertEquals("width", 80, formatter.getWidth());
     }
     
+    @Test
     public void testHeaderStartingWithLineSeparator()
     {
         // related to Bugzilla #21215
@@ -361,6 +450,28 @@ public class HelpFormatterTest extends TestCase
                 , out.toString());
     }
 
+    @Test
+    public void testIndentedHeaderAndFooter()
+    {
+        // related to CLI-207
+        Options options = new Options();
+        HelpFormatter formatter = new HelpFormatter();
+        String header = "  Header1\n  Header2";
+        String footer = "  Footer1\n  Footer2";
+        StringWriter out = new StringWriter();
+        formatter.printHelp(new PrintWriter(out), 80, "foobar", header, options, 2, 2, footer, true);
+
+        assertEquals(
+                "usage: foobar" + EOL +
+                "  Header1" + EOL +
+                "  Header2" + EOL +
+                "" + EOL +
+                "  Footer1" + EOL +
+                "  Footer2" + EOL
+                , out.toString());
+    }
+
+    @Test
     public void testOptionWithoutShortFormat()
     {
         // related to Bugzilla #19383 (CLI-67)
@@ -380,7 +491,7 @@ public class HelpFormatterTest extends TestCase
                 , out.toString());
     }
     
-
+    @Test
     public void testOptionWithoutShortFormat2()
     {
         // related to Bugzilla #27635 (CLI-26)
@@ -389,35 +500,36 @@ public class HelpFormatterTest extends TestCase
         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 timeLimit = Option.builder("l")
+                                 .longOpt("limit")
+                                 .hasArg()
+                                 .valueSeparator()
+                                 .desc("Set time limit for execution, in mintues")
+                                 .build();
         
-        Option age = OptionBuilder.withLongOpt("age")
+        Option age = Option.builder("a").longOpt("age")
                                         .hasArg()
-                                        .withValueSeparator()
-                                        .withDescription("Age (in days) of cache item before being recomputed")
-                                        .create("a");
+                                        .valueSeparator()
+                                        .desc("Age (in days) of cache item before being recomputed")
+                                        .build();
         
-        Option server = OptionBuilder.withLongOpt("server")
-                                        .hasArg()
-                                        .withValueSeparator()
-                                        .withDescription("The NLT server address")
-                                        .create("s");
+        Option server = Option.builder("s").longOpt("server")
+                                           .hasArg()
+                                           .valueSeparator()
+                                           .desc("The NLT server address")
+                                           .build();
         
-        Option numResults = OptionBuilder.withLongOpt("results")
-                                        .hasArg()
-                                        .withValueSeparator()
-                                        .withDescription("Number of results per item")
-                                        .create("r");
+        Option numResults = Option.builder("r").longOpt("results")
+                                               .hasArg()
+                                               .valueSeparator()
+                                               .desc("Number of results per item")
+                                               .build();
         
-        Option configFile = OptionBuilder.withLongOpt("config")
-                                        .hasArg()
-                                        .withValueSeparator()
-                                        .withDescription("Use the specified configuration file")
-                                        .create();
+        Option configFile = Option.builder().longOpt("config")
+                                            .hasArg()
+                                            .valueSeparator()
+                                            .desc("Use the specified configuration file")
+                                            .build();
         
         Options mOptions = new Options();
         mOptions.addOption(help);
@@ -450,4 +562,49 @@ public class HelpFormatterTest extends TestCase
                 "footer"+EOL
                 ,out.toString());
     }
+    
+    @Test
+    public void testHelpWithLongOptSeparator() throws Exception
+    {
+        Options options = new Options();
+        options.addOption( "f", true, "the file" );
+        options.addOption(Option.builder("s").longOpt("size").desc("the size").hasArg().argName("SIZE").build());
+        options.addOption(Option.builder().longOpt("age").desc("the age").hasArg().build());
+        
+        HelpFormatter formatter = new HelpFormatter();
+        assertEquals(HelpFormatter.DEFAULT_LONG_OPT_SEPARATOR, formatter.getLongOptSeparator());
+        formatter.setLongOptSeparator("=");
+        assertEquals("=", formatter.getLongOptSeparator());
+        
+        StringWriter out = new StringWriter();
+
+        formatter.printHelp(new PrintWriter(out), 80, "create", "header", options, 2, 2, "footer");
+
+        assertEquals(
+                "usage: create" + EOL +
+                "header" + EOL +
+                "     --age=<arg>    the age" + EOL +
+                "  -f <arg>          the file" + EOL +
+                "  -s,--size=<SIZE>  the size" + EOL +
+                "footer" + EOL,
+                out.toString());
+    }
+
+    @Test
+    public void testUsageWithLongOptSeparator() throws Exception
+    {
+        Options options = new Options();
+        options.addOption( "f", true, "the file" );
+        options.addOption(Option.builder("s").longOpt("size").desc("the size").hasArg().argName("SIZE").build());
+        options.addOption(Option.builder().longOpt("age").desc("the age").hasArg().build());
+        
+        HelpFormatter formatter = new HelpFormatter();
+        formatter.setLongOptSeparator("=");
+        
+        StringWriter out = new StringWriter();
+        
+        formatter.printUsage(new PrintWriter(out), 80, "create", options);
+        
+        assertEquals("usage: create [--age=<arg>] [-f <arg>] [-s <SIZE>]", out.toString().trim());
+    }
 }
diff --git a/src/test/org/apache/commons/cli/OptionBuilderTest.java b/src/test/java/org/apache/commons/cli/OptionBuilderTest.java
similarity index 85%
rename from src/test/org/apache/commons/cli/OptionBuilderTest.java
rename to src/test/java/org/apache/commons/cli/OptionBuilderTest.java
index b445a67..9d0585d 100644
--- a/src/test/org/apache/commons/cli/OptionBuilderTest.java
+++ b/src/test/java/org/apache/commons/cli/OptionBuilderTest.java
@@ -17,41 +17,49 @@
 
 package org.apache.commons.cli;
 
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
-public class OptionBuilderTest extends TestCase {
+import org.junit.Test;
 
+ at SuppressWarnings("deprecation") // OptionBuilder is marked deprecated
+public class OptionBuilderTest
+{
+    @Test
     public void testCompleteOption( ) {
         Option simple = OptionBuilder.withLongOpt( "simple option")
                                      .hasArg( )
                                      .isRequired( )
                                      .hasArgs( )
-                                     .withType( new Float( 10 ) )
+                                     .withType( Float.class )
                                      .withDescription( "this is a simple option" )
                                      .create( 's' );
 
         assertEquals( "s", simple.getOpt() );
         assertEquals( "simple option", simple.getLongOpt() );
         assertEquals( "this is a simple option", simple.getDescription() );
-        assertEquals( simple.getType().getClass(), Float.class );
+        assertEquals( simple.getType(), Float.class );
         assertTrue( simple.hasArg() );
         assertTrue( simple.isRequired() );
         assertTrue( simple.hasArgs() );
     }
 
+    @Test
     public void testTwoCompleteOptions( ) {
         Option simple = OptionBuilder.withLongOpt( "simple option")
                                      .hasArg( )
                                      .isRequired( )
                                      .hasArgs( )
-                                     .withType( new Float( 10 ) )
+                                     .withType( Float.class )
                                      .withDescription( "this is a simple option" )
                                      .create( 's' );
 
         assertEquals( "s", simple.getOpt() );
         assertEquals( "simple option", simple.getLongOpt() );
         assertEquals( "this is a simple option", simple.getDescription() );
-        assertEquals( simple.getType().getClass(), Float.class );
+        assertEquals( simple.getType(), Float.class );
         assertTrue( simple.hasArg() );
         assertTrue( simple.isRequired() );
         assertTrue( simple.hasArgs() );
@@ -64,12 +72,13 @@ public class OptionBuilderTest extends TestCase {
         assertEquals( "d", simple.getOpt() );
         assertEquals( "dimple option", simple.getLongOpt() );
         assertEquals( "this is a dimple option", simple.getDescription() );
-        assertNull( simple.getType() );
+        assertEquals( String.class, simple.getType() );
         assertTrue( simple.hasArg() );
         assertTrue( !simple.isRequired() );
         assertTrue( !simple.hasArgs() );
     }
 
+    @Test
     public void testBaseOptionCharOpt() {
         Option base = OptionBuilder.withDescription( "option description")
                                    .create( 'o' );
@@ -79,6 +88,7 @@ public class OptionBuilderTest extends TestCase {
         assertTrue( !base.hasArg() );
     }
 
+    @Test
     public void testBaseOptionStringOpt() {
         Option base = OptionBuilder.withDescription( "option description")
                                    .create( "o" );
@@ -88,6 +98,7 @@ public class OptionBuilderTest extends TestCase {
         assertTrue( !base.hasArg() );
     }
 
+    @Test
     public void testSpecialOptChars() throws Exception
     {
         // '?'
@@ -97,8 +108,17 @@ public class OptionBuilderTest extends TestCase {
         // '@'
         Option opt2 = OptionBuilder.withDescription("read from stdin").create('@');
         assertEquals("@", opt2.getOpt());
+        
+        // ' '
+        try {
+            OptionBuilder.create(' ');
+            fail( "IllegalArgumentException not caught" );
+        } catch (IllegalArgumentException e) {
+            // success
+        }
     }
 
+    @Test
     public void testOptionArgNumbers()
     {
         Option opt = OptionBuilder.withDescription( "option description" )
@@ -107,6 +127,7 @@ public class OptionBuilderTest extends TestCase {
         assertEquals( 2, opt.getArgs() );
     }
 
+    @Test
     public void testIllegalOptions() {
         // bad single character option
         try {
@@ -119,7 +140,7 @@ public class OptionBuilderTest extends TestCase {
 
         // bad character in option string
         try {
-            Option opt = OptionBuilder.create( "opt`" );
+            OptionBuilder.create( "opt`" );
             fail( "IllegalArgumentException not caught" );
         }
         catch( IllegalArgumentException exp ) {
@@ -128,7 +149,7 @@ public class OptionBuilderTest extends TestCase {
 
         // valid option 
         try {
-            Option opt = OptionBuilder.create( "opt" );
+            OptionBuilder.create( "opt" );
             // success
         }
         catch( IllegalArgumentException exp ) {
@@ -136,6 +157,7 @@ public class OptionBuilderTest extends TestCase {
         }
     }
 
+    @Test
     public void testCreateIncompleteOption() {
         try
         {
@@ -151,6 +173,7 @@ public class OptionBuilderTest extends TestCase {
         }
     }
 
+    @Test
     public void testBuilderIsResettedAlways() {
         try
         {
diff --git a/src/test/org/apache/commons/cli/OptionGroupTest.java b/src/test/java/org/apache/commons/cli/OptionGroupTest.java
similarity index 90%
rename from src/test/org/apache/commons/cli/OptionGroupTest.java
rename to src/test/java/org/apache/commons/cli/OptionGroupTest.java
index 7dcf219..2172042 100644
--- a/src/test/org/apache/commons/cli/OptionGroupTest.java
+++ b/src/test/java/org/apache/commons/cli/OptionGroupTest.java
@@ -17,17 +17,23 @@
 
 package org.apache.commons.cli;
 
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
-/**
- * @author John Keyes (john at integralsource.com)
- * @version $Revision: 751120 $
- */
-public class OptionGroupTest extends TestCase
+import java.util.Properties;
+
+import org.junit.Before;
+import org.junit.Test;
+
+ at SuppressWarnings("deprecation") // tests some deprecated classes
+public class OptionGroupTest
 {
     private Options _options = null;
-    private CommandLineParser parser = new PosixParser();
+    private final Parser parser = new PosixParser();
 
+    @Before
     public void setUp()
     {
         Option file = new Option( "f", "file", false, "file to process" );
@@ -55,6 +61,7 @@ public class OptionGroupTest extends TestCase
         _options.addOption( "r", "revision", false, "revision number" );
     }
 
+    @Test
     public void testSingleOptionFromGroup() throws Exception
     {
         String[] args = new String[] { "-f" };
@@ -69,6 +76,7 @@ public class OptionGroupTest extends TestCase
         assertTrue( "Confirm no extra args", cl.getArgList().size() == 0);
     }
 
+    @Test
     public void testSingleOption() throws Exception
     {
         String[] args = new String[] { "-r" };
@@ -83,6 +91,7 @@ public class OptionGroupTest extends TestCase
         assertTrue( "Confirm no extra args", cl.getArgList().size() == 0);
     }
 
+    @Test
     public void testTwoValidOptions() throws Exception
     {
         String[] args = new String[] { "-r", "-f" };
@@ -97,6 +106,7 @@ public class OptionGroupTest extends TestCase
         assertTrue( "Confirm no extra args", cl.getArgList().size() == 0);
     }
 
+    @Test
     public void testSingleLongOption() throws Exception
     {
         String[] args = new String[] { "--file" };
@@ -111,6 +121,7 @@ public class OptionGroupTest extends TestCase
         assertTrue( "Confirm no extra args", cl.getArgList().size() == 0);
     }
 
+    @Test
     public void testTwoValidLongOptions() throws Exception
     {
         String[] args = new String[] { "--revision", "--file" };
@@ -125,6 +136,7 @@ public class OptionGroupTest extends TestCase
         assertTrue( "Confirm no extra args", cl.getArgList().size() == 0);
     }
 
+    @Test
     public void testNoOptionsExtraArgs() throws Exception
     {
         String[] args = new String[] { "arg1", "arg2" };
@@ -139,6 +151,7 @@ public class OptionGroupTest extends TestCase
         assertTrue( "Confirm TWO extra args", cl.getArgList().size() == 2);
     }
 
+    @Test
     public void testTwoOptionsFromGroup() throws Exception
     {
         String[] args = new String[] { "-f", "-d" };
@@ -156,6 +169,7 @@ public class OptionGroupTest extends TestCase
         }
     }
 
+    @Test
     public void testTwoLongOptionsFromGroup() throws Exception
     {
         String[] args = new String[] { "--file", "--directory" };
@@ -173,6 +187,7 @@ public class OptionGroupTest extends TestCase
         }
     }
 
+    @Test
     public void testTwoOptionsFromDifferentGroup() throws Exception
     {
         String[] args = new String[] { "-f", "-s" };
@@ -186,6 +201,20 @@ public class OptionGroupTest extends TestCase
         assertTrue( "Confirm NO extra args", cl.getArgList().size() == 0);
     }
 
+    @Test
+    public void testTwoOptionsFromGroupWithProperties() throws Exception
+    {
+        String[] args = new String[] { "-f" };
+        
+        Properties properties = new Properties();
+        properties.put("d", "true");
+        
+        CommandLine cl = parser.parse( _options, args, properties);
+        assertTrue(cl.hasOption("f"));
+        assertTrue(!cl.hasOption("d"));
+    }
+
+    @Test
     public void testValidLongOnlyOptions() throws Exception
     {
         CommandLine cl1 = parser.parse(_options, new String[]{"--export"});
@@ -195,6 +224,7 @@ public class OptionGroupTest extends TestCase
         assertTrue("Confirm --import is set", cl2.hasOption("import"));
     }
 
+    @Test
     public void testToString()
     {
         OptionGroup group1 = new OptionGroup();
@@ -214,6 +244,7 @@ public class OptionGroupTest extends TestCase
         }
     }
 
+    @Test
     public void testGetNames()
     {
         OptionGroup group = new OptionGroup();
diff --git a/src/test/java/org/apache/commons/cli/OptionTest.java b/src/test/java/org/apache/commons/cli/OptionTest.java
new file mode 100644
index 0000000..bbb0c30
--- /dev/null
+++ b/src/test/java/org/apache/commons/cli/OptionTest.java
@@ -0,0 +1,219 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class OptionTest
+{
+    private static class TestOption extends Option
+    {
+        private static final long serialVersionUID = 1L;
+
+        public TestOption(String opt, boolean hasArg, String description) throws IllegalArgumentException
+        {
+            super(opt, hasArg, description);
+        }
+
+        @Override
+        public boolean addValue(String value)
+        {
+            addValueForProcessing(value);
+            return true;
+        }
+    }
+
+    @Test
+    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
+    @Test
+    public void testClone()
+    {
+        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 static final long serialVersionUID = 1L;
+
+        private final String defaultValue;
+
+        public DefaultOption(String opt, String description, String defaultValue) throws IllegalArgumentException
+        {
+            super(opt, true, description);
+            this.defaultValue = defaultValue;
+        }
+
+        @Override
+        public String getValue()
+        {
+            return super.getValue() != null ? super.getValue() : defaultValue;
+        }
+    }
+
+    @Test
+    public void testSubclass()
+    {
+        Option option = new DefaultOption("f", "file", "myfile.txt");
+        Option clone = (Option) option.clone();
+        assertEquals("myfile.txt", clone.getValue());
+        assertEquals(DefaultOption.class, clone.getClass());
+    }
+
+    @Test
+    public void testHasArgName()
+    {
+        Option option = new Option("f", null);
+
+        option.setArgName(null);
+        assertFalse(option.hasArgName());
+
+        option.setArgName("");
+        assertFalse(option.hasArgName());
+
+        option.setArgName("file");
+        assertTrue(option.hasArgName());
+    }
+
+    @Test
+    public void testHasArgs()
+    {
+        Option option = new Option("f", null);
+
+        option.setArgs(0);
+        assertFalse(option.hasArgs());
+
+        option.setArgs(1);
+        assertFalse(option.hasArgs());
+
+        option.setArgs(10);
+        assertTrue(option.hasArgs());
+
+        option.setArgs(Option.UNLIMITED_VALUES);
+        assertTrue(option.hasArgs());
+
+        option.setArgs(Option.UNINITIALIZED);
+        assertFalse(option.hasArgs());
+    }
+
+    @Test
+    public void testGetValue()
+    {
+        Option option = new Option("f", null);
+        option.setArgs(Option.UNLIMITED_VALUES);
+
+        assertEquals("default", option.getValue("default"));
+        assertEquals(null, option.getValue(0));
+
+        option.addValueForProcessing("foo");
+        
+        assertEquals("foo", option.getValue());
+        assertEquals("foo", option.getValue(0));
+        assertEquals("foo", option.getValue("default"));
+    }
+    
+    @Test
+    public void testBuilderMethods()
+    {
+        char defaultSeparator = (char) 0;
+
+        checkOption(Option.builder("a").desc("desc").build(),
+            "a", "desc", null, Option.UNINITIALIZED, null, false, false, defaultSeparator, String.class);
+        checkOption(Option.builder("a").desc("desc").build(),
+            "a", "desc", null, Option.UNINITIALIZED, null, false, false, defaultSeparator, String.class);
+        checkOption(Option.builder("a").desc("desc").longOpt("aaa").build(),
+            "a", "desc", "aaa", Option.UNINITIALIZED, null, false, false, defaultSeparator, String.class);
+        checkOption(Option.builder("a").desc("desc").hasArg(true).build(),
+            "a", "desc", null, 1, null, false, false, defaultSeparator, String.class);
+        checkOption(Option.builder("a").desc("desc").hasArg(false).build(),
+            "a", "desc", null, Option.UNINITIALIZED, null, false, false, defaultSeparator, String.class);
+        checkOption(Option.builder("a").desc("desc").hasArg(true).build(),
+            "a", "desc", null, 1, null, false, false, defaultSeparator, String.class);
+        checkOption(Option.builder("a").desc("desc").numberOfArgs(3).build(),
+            "a", "desc", null, 3, null, false, false, defaultSeparator, String.class);
+        checkOption(Option.builder("a").desc("desc").required(true).build(),
+            "a", "desc", null, Option.UNINITIALIZED, null, true, false, defaultSeparator, String.class);
+        checkOption(Option.builder("a").desc("desc").required(false).build(),
+            "a", "desc", null, Option.UNINITIALIZED, null, false, false, defaultSeparator, String.class);
+
+        checkOption(Option.builder("a").desc("desc").argName("arg1").build(),
+            "a", "desc", null, Option.UNINITIALIZED, "arg1", false, false, defaultSeparator, String.class);
+        checkOption(Option.builder("a").desc("desc").optionalArg(false).build(),
+            "a", "desc", null, Option.UNINITIALIZED, null, false, false, defaultSeparator, String.class);
+        checkOption(Option.builder("a").desc("desc").optionalArg(true).build(),
+            "a", "desc", null, Option.UNINITIALIZED, null, false, true, defaultSeparator, String.class);
+        checkOption(Option.builder("a").desc("desc").valueSeparator(':').build(),
+            "a", "desc", null, Option.UNINITIALIZED, null, false, false, ':', String.class);
+        checkOption(Option.builder("a").desc("desc").type(Integer.class).build(),
+            "a", "desc", null, Option.UNINITIALIZED, null, false, false, defaultSeparator, Integer.class);
+    }
+    
+    @Test(expected=IllegalArgumentException.class)
+    public void testBuilderInsufficientParams1()
+    {
+        Option.builder().desc("desc").build();
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testBuilderInsufficientParams2()
+    {
+        Option.builder(null).desc("desc").build();
+    }
+
+    private static void checkOption(Option option, String opt, String description, String longOpt, int numArgs,
+                                    String argName,  boolean required, boolean optionalArg,
+                                    char valueSeparator, Class<?> cls)
+    {
+        assertEquals(opt, option.getOpt());
+        assertEquals(description, option.getDescription());
+        assertEquals(longOpt, option.getLongOpt());
+        assertEquals(numArgs, option.getArgs());
+        assertEquals(argName, option.getArgName());
+        assertEquals(required, option.isRequired());
+
+        assertEquals(optionalArg, option.hasOptionalArg());
+        assertEquals(valueSeparator, option.getValueSeparator());
+        assertEquals(cls,  option.getType());
+    }
+    
+}
diff --git a/src/test/org/apache/commons/cli/OptionsTest.java b/src/test/java/org/apache/commons/cli/OptionsTest.java
similarity index 81%
rename from src/test/org/apache/commons/cli/OptionsTest.java
rename to src/test/java/org/apache/commons/cli/OptionsTest.java
index 24ec03e..0be0cc1 100644
--- a/src/test/org/apache/commons/cli/OptionsTest.java
+++ b/src/test/java/org/apache/commons/cli/OptionsTest.java
@@ -17,17 +17,20 @@
 
 package org.apache.commons.cli;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import java.util.ArrayList;
 import java.util.Collection;
 
-import junit.framework.TestCase;
+import org.junit.Test;
 
-/**
- * @author Rob Oxspring roxspring at apache.org
- * @version $Revision: 680311 $
- */
-public class OptionsTest extends TestCase
+ at SuppressWarnings("deprecation") // tests some deprecated classes
+public class OptionsTest
 {
+    @Test
     public void testSimple()
     {
         Options opts = new Options();
@@ -39,6 +42,7 @@ public class OptionsTest extends TestCase
         assertTrue(opts.hasOption("b"));
     }
 
+    @Test
     public void testDuplicateSimple()
     {
         Options opts = new Options();
@@ -48,6 +52,7 @@ public class OptionsTest extends TestCase
         assertEquals("last one in wins", "toggle -a*", opts.getOption("a").getDescription());
     }
 
+    @Test
     public void testLong()
     {
         Options opts = new Options();
@@ -59,6 +64,7 @@ public class OptionsTest extends TestCase
         assertTrue(opts.hasOption("b"));
     }
 
+    @Test
     public void testDuplicateLong()
     {
         Options opts = new Options();
@@ -67,6 +73,7 @@ public class OptionsTest extends TestCase
         assertEquals("last one in wins", "toggle -a*", opts.getOption("a").getDescription());
     }
 
+    @Test
     public void testHelpOptions()
     {
         Option longOnly1 = OptionBuilder.withLongOpt("long-only1").create();
@@ -84,7 +91,7 @@ public class OptionsTest extends TestCase
         options.addOption(bothA);
         options.addOption(bothB);
         
-        Collection allOptions = new ArrayList();
+        Collection<Option> allOptions = new ArrayList<Option>();
         allOptions.add(longOnly1);
         allOptions.add(longOnly2);
         allOptions.add(shortOnly1);
@@ -92,12 +99,13 @@ public class OptionsTest extends TestCase
         allOptions.add(bothA);
         allOptions.add(bothB);
         
-        Collection helpOptions = options.helpOptions();
+        Collection<Option> 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));        
     }
 
+    @Test
     public void testMissingOptionException() throws ParseException
     {
         Options options = new Options();
@@ -113,6 +121,7 @@ public class OptionsTest extends TestCase
         }
     }
 
+    @Test
     public void testMissingOptionsException() throws ParseException
     {
         Options options = new Options();
@@ -129,6 +138,7 @@ public class OptionsTest extends TestCase
         }
     }
 
+    @Test
     public void testToString()
     {
         Options options = new Options();
@@ -137,10 +147,11 @@ public class OptionsTest extends TestCase
 
         String s = options.toString();
         assertNotNull("null string returned", s);
-        assertTrue("foo option missing", s.toLowerCase().indexOf("foo") != -1);
-        assertTrue("bar option missing", s.toLowerCase().indexOf("bar") != -1);
+        assertTrue("foo option missing", s.toLowerCase().contains("foo"));
+        assertTrue("bar option missing", s.toLowerCase().contains("bar"));
     }
 
+    @Test
     public void testGetOptionsGroups()
     {
         Options options = new Options();
@@ -159,4 +170,16 @@ public class OptionsTest extends TestCase
         assertNotNull(options.getOptionGroups());
         assertEquals(2, options.getOptionGroups().size());
     }
+    
+    @Test
+    public void testGetMatchingOpts()
+    {
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("version").create());
+        options.addOption(OptionBuilder.withLongOpt("verbose").create());
+        
+        assertTrue(options.getMatchingOptions("foo").isEmpty());
+        assertEquals(1, options.getMatchingOptions("version").size());
+        assertEquals(2, options.getMatchingOptions("ver").size());
+    }
 }
diff --git a/src/test/java/org/apache/commons/cli/ParserTestCase.java b/src/test/java/org/apache/commons/cli/ParserTestCase.java
new file mode 100644
index 0000000..4d91b98
--- /dev/null
+++ b/src/test/java/org/apache/commons/cli/ParserTestCase.java
@@ -0,0 +1,1108 @@
+/**
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Abstract test case testing common parser features.
+ */
+public abstract class ParserTestCase
+{
+    protected CommandLineParser parser;
+
+    protected Options options;
+
+    @Before
+    public void setUp()
+    {
+        options = new Options()
+            .addOption("a", "enable-a", false, "turn [a] on or off")
+            .addOption("b", "bfile", true, "set the value of [b]")
+            .addOption("c", "copt", false, "turn [c] on or off");
+    }
+
+    @Test
+    public void testSimpleShort() throws Exception
+    {
+        String[] args = new String[] { "-a",
+                                       "-b", "toast",
+                                       "foo", "bar" };
+
+        CommandLine cl = parser.parse(options, args);
+
+        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 size of extra args", cl.getArgList().size() == 2);
+    }
+
+    @Test
+    public void testSimpleLong() throws Exception
+    {
+        String[] args = new String[] { "--enable-a",
+                                       "--bfile", "toast",
+                                       "foo", "bar" };
+
+        CommandLine cl = parser.parse(options, args);
+
+        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);
+    }
+
+    @Test
+    public void testMultiple() throws Exception
+    {
+        String[] args = new String[] { "-c",
+                                       "foobar",
+                                       "-b", "toast" };
+
+        CommandLine cl = parser.parse(options, args, true);
+        assertTrue("Confirm -c is set", cl.hasOption("c"));
+        assertTrue("Confirm  3 extra args: " + cl.getArgList().size(), cl.getArgList().size() == 3);
+
+        cl = parser.parse(options, cl.getArgs());
+
+        assertTrue("Confirm -c is not set", !cl.hasOption("c"));
+        assertTrue("Confirm -b is set", cl.hasOption("b"));
+        assertTrue("Confirm arg of -b", cl.getOptionValue("b").equals("toast"));
+        assertTrue("Confirm  1 extra arg: " + cl.getArgList().size(), cl.getArgList().size() == 1);
+        assertTrue("Confirm  value of extra arg: " + cl.getArgList().get(0), cl.getArgList().get(0).equals("foobar"));
+    }
+
+    @Test
+    public void testMultipleWithLong() throws Exception
+    {
+        String[] args = new String[] { "--copt",
+                                       "foobar",
+                                       "--bfile", "toast" };
+
+        CommandLine cl = parser.parse(options, args, true);
+        assertTrue("Confirm -c is set", cl.hasOption("c"));
+        assertTrue("Confirm  3 extra args: " + cl.getArgList().size(), cl.getArgList().size() == 3);
+
+        cl = parser.parse(options, cl.getArgs());
+
+        assertTrue("Confirm -c is not set", !cl.hasOption("c"));
+        assertTrue("Confirm -b is set", cl.hasOption("b"));
+        assertTrue("Confirm arg of -b", cl.getOptionValue("b").equals("toast"));
+        assertTrue("Confirm  1 extra arg: " + cl.getArgList().size(), cl.getArgList().size() == 1);
+        assertTrue("Confirm  value of extra arg: " + cl.getArgList().get(0), cl.getArgList().get(0).equals("foobar"));
+    }
+
+    @Test
+    public void testUnrecognizedOption() throws Exception
+    {
+        String[] args = new String[] { "-a", "-d", "-b", "toast", "foo", "bar" };
+
+        try
+        {
+            parser.parse(options, args);
+            fail("UnrecognizedOptionException wasn't thrown");
+        }
+        catch (UnrecognizedOptionException e)
+        {
+            assertEquals("-d", e.getOption());
+        }
+    }
+
+    @Test
+    public void testMissingArg() throws Exception
+    {
+        String[] args = new String[] { "-b" };
+
+        boolean caught = false;
+
+        try
+        {
+            parser.parse(options, args);
+        }
+        catch (MissingArgumentException e)
+        {
+            caught = true;
+            assertEquals("option missing an argument", "b", e.getOption().getOpt());
+        }
+
+        assertTrue( "Confirm MissingArgumentException caught", caught );
+    }
+
+    @Test
+    public void testDoubleDash1() throws Exception
+    {
+        String[] args = new String[] { "--copt",
+                                       "--",
+                                       "-b", "toast" };
+
+        CommandLine cl = parser.parse(options, args);
+
+        assertTrue("Confirm -c is set", cl.hasOption("c"));
+        assertTrue("Confirm -b is not set", !cl.hasOption("b"));
+        assertTrue("Confirm 2 extra args: " + cl.getArgList().size(), cl.getArgList().size() == 2);
+    }
+
+    @Test
+    public void testDoubleDash2() throws Exception
+    {
+        Options options = new Options();
+        options.addOption(OptionBuilder.hasArg().create('n'));
+        options.addOption(OptionBuilder.create('m'));
+
+        try
+        {
+            parser.parse(options, new String[]{"-n", "--", "-m"});
+            fail("MissingArgumentException not thrown for option -n");
+        }
+        catch (MissingArgumentException e)
+        {
+            assertNotNull("option null", e.getOption());
+            assertEquals("n", e.getOption().getOpt());
+        }
+    }
+    
+    @Test
+    public void testSingleDash() throws Exception
+    {
+        String[] args = new String[] { "--copt",
+                                       "-b", "-",
+                                       "-a",
+                                       "-" };
+
+        CommandLine cl = parser.parse(options, args);
+
+        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("-"));
+        assertTrue("Confirm 1 extra arg: " + cl.getArgList().size(), cl.getArgList().size() == 1);
+        assertTrue("Confirm value of extra arg: " + cl.getArgList().get(0), cl.getArgList().get(0).equals("-"));
+    }
+
+    @Test
+    public void testStopAtUnexpectedArg() throws Exception
+    {
+        String[] args = new String[] { "-c",
+                                       "foober",
+                                       "-b",
+                                       "toast" };
+
+        CommandLine cl = parser.parse(options, args, true);
+        assertTrue("Confirm -c is set", cl.hasOption("c"));
+        assertTrue("Confirm  3 extra args: " + cl.getArgList().size(), cl.getArgList().size() == 3);
+    }
+
+    @Test
+    public void testStopAtExpectedArg() throws Exception
+    {
+        String[] args = new String[]{"-b", "foo"};
+
+        CommandLine cl = parser.parse(options, args, true);
+
+        assertTrue("Confirm -b is set", cl.hasOption('b'));
+        assertEquals("Confirm -b is set", "foo", cl.getOptionValue('b'));
+        assertTrue("Confirm no extra args: " + cl.getArgList().size(), cl.getArgList().size() == 0);
+    }
+
+    @Test
+    public void testStopAtNonOptionShort() throws Exception
+    {
+        String[] args = new String[]{"-z",
+                                     "-a",
+                                     "-btoast"};
+
+        CommandLine cl = parser.parse(options, args, true);
+        assertFalse("Confirm -a is not set", cl.hasOption("a"));
+        assertTrue("Confirm  3 extra args: " + cl.getArgList().size(), cl.getArgList().size() == 3);
+    }
+
+    @Test
+    public void testStopAtNonOptionLong() throws Exception
+    {
+        String[] args = new String[]{"--zop==1",
+                                     "-abtoast",
+                                     "--b=bar"};
+
+        CommandLine cl = parser.parse(options, args, true);
+
+        assertFalse("Confirm -a is not set", cl.hasOption("a"));
+        assertFalse("Confirm -b is not set", cl.hasOption("b"));
+        assertTrue("Confirm  3 extra args: " + cl.getArgList().size(), cl.getArgList().size() == 3);
+    }
+
+    @Test
+    public void testNegativeArgument() throws Exception
+    {
+        String[] args = new String[] { "-b", "-1"} ;
+
+        CommandLine cl = parser.parse(options, args);
+        assertEquals("-1", cl.getOptionValue("b"));
+    }
+
+    @Test
+    public void testNegativeOption() throws Exception
+    {
+        String[] args = new String[] { "-b", "-1"} ;
+        
+        options.addOption("1", false, null);
+
+        CommandLine cl = parser.parse(options, args);
+        assertEquals("-1", cl.getOptionValue("b"));
+    }
+    
+    @Test
+    public void testArgumentStartingWithHyphen() throws Exception
+    {
+        String[] args = new String[]{"-b", "-foo"};
+
+        CommandLine cl = parser.parse(options, args);
+        assertEquals("-foo", cl.getOptionValue("b"));
+    }
+
+    @Test
+    public void testShortWithEqual() throws Exception
+    {
+        String[] args = new String[] { "-f=bar" };
+
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("foo").hasArg().create('f'));
+
+        CommandLine cl = parser.parse(options, args);
+
+        assertEquals("bar", cl.getOptionValue("foo"));
+    }
+
+    @Test
+    public void testShortWithoutEqual() throws Exception
+    {
+        String[] args = new String[] { "-fbar" };
+
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("foo").hasArg().create('f'));
+
+        CommandLine cl = parser.parse(options, args);
+
+        assertEquals("bar", cl.getOptionValue("foo"));
+    }
+
+    @Test
+    public void testLongWithEqualDoubleDash() throws Exception
+    {
+        String[] args = new String[] { "--foo=bar" };
+
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("foo").hasArg().create('f'));
+
+        CommandLine cl = parser.parse(options, args);
+
+        assertEquals("bar", cl.getOptionValue("foo"));
+    }
+
+    @Test
+    public void testLongWithEqualSingleDash() throws Exception
+    {
+        String[] args = new String[] { "-foo=bar" };
+
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("foo").hasArg().create('f'));
+
+        CommandLine cl = parser.parse(options, args);
+
+        assertEquals("bar", cl.getOptionValue("foo"));
+    }
+
+    @Test
+    public void testLongWithoutEqualSingleDash() throws Exception
+    {
+        String[] args = new String[] { "-foobar" };
+
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("foo").hasArg().create('f'));
+
+        CommandLine cl = parser.parse(options, args);
+
+        assertEquals("bar", cl.getOptionValue("foo"));
+    }
+    
+    @Test
+    public void testAmbiguousLongWithoutEqualSingleDash() throws Exception
+    {
+        String[] args = new String[] { "-b", "-foobar" };
+
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("foo").hasOptionalArg().create('f'));
+        options.addOption(OptionBuilder.withLongOpt("bar").hasOptionalArg().create('b'));
+
+        CommandLine cl = parser.parse(options, args);
+
+        assertTrue(cl.hasOption("b"));
+        assertTrue(cl.hasOption("f"));
+        assertEquals("bar", cl.getOptionValue("foo"));
+    }
+
+    @Test
+    public void testLongWithoutEqualDoubleDash() throws Exception
+    {
+        String[] args = new String[] { "--foobar" };
+
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("foo").hasArg().create('f'));
+
+        CommandLine cl = parser.parse(options, args, true);
+
+        assertFalse(cl.hasOption("foo")); // foo isn't expected to be recognized with a double dash
+    }
+
+    @Test
+    public void testLongWithUnexpectedArgument1() throws Exception
+    {
+        String[] args = new String[] { "--foo=bar" };
+
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("foo").create('f'));
+
+        try
+        {
+            parser.parse(options, args);
+        }
+        catch (UnrecognizedOptionException e)
+        {
+            assertEquals("--foo=bar", e.getOption());
+            return;
+        }
+
+        fail("UnrecognizedOptionException not thrown");
+    }
+
+    @Test
+    public void testLongWithUnexpectedArgument2() throws Exception
+    {
+        String[] args = new String[] { "-foobar" };
+
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("foo").create('f'));
+
+        try
+        {
+            parser.parse(options, args);
+        }
+        catch (UnrecognizedOptionException e)
+        {
+            assertEquals("-foobar", e.getOption());
+            return;
+        }
+
+        fail("UnrecognizedOptionException not thrown");
+    }
+
+    @Test
+    public void testShortWithUnexpectedArgument() throws Exception
+    {
+        String[] args = new String[] { "-f=bar" };
+
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("foo").create('f'));
+
+        try
+        {
+            parser.parse(options, args);
+        }
+        catch (UnrecognizedOptionException e)
+        {
+            assertEquals("-f=bar", e.getOption());
+            return;
+        }
+
+        fail("UnrecognizedOptionException not thrown");
+    }
+    
+    @Test
+    public void testPropertiesOption1() throws Exception
+    {
+        String[] args = new String[] { "-Jsource=1.5", "-J", "target", "1.5", "foo" };
+
+        Options options = new Options();
+        options.addOption(OptionBuilder.withValueSeparator().hasArgs(2).create('J'));
+
+        CommandLine cl = parser.parse(options, args);
+
+        List<String> values = Arrays.asList(cl.getOptionValues("J"));
+        assertNotNull("null values", values);
+        assertEquals("number of values", 4, values.size());
+        assertEquals("value 1", "source", values.get(0));
+        assertEquals("value 2", "1.5", values.get(1));
+        assertEquals("value 3", "target", values.get(2));
+        assertEquals("value 4", "1.5", values.get(3));
+        
+        List<?> argsleft = cl.getArgList();
+        assertEquals("Should be 1 arg left", 1, argsleft.size());
+        assertEquals("Expecting foo", "foo", argsleft.get(0));
+    }
+
+    @Test
+    public void testPropertiesOption2() throws Exception
+    {
+        String[] args = new String[] { "-Dparam1", "-Dparam2=value2", "-D"};
+
+        Options options = new Options();
+        options.addOption(OptionBuilder.withValueSeparator().hasOptionalArgs(2).create('D'));
+
+        CommandLine cl = parser.parse(options, args);
+        
+        Properties props = cl.getOptionProperties("D");
+        assertNotNull("null properties", props);
+        assertEquals("number of properties in " + props, 2, props.size());
+        assertEquals("property 1", "true", props.getProperty("param1"));
+        assertEquals("property 2", "value2", props.getProperty("param2"));
+        
+        List<?> argsleft = cl.getArgList();
+        assertEquals("Should be no arg left", 0, argsleft.size());
+    }
+
+    @Test
+    public void testUnambiguousPartialLongOption1() throws Exception
+    {
+        String[] args = new String[] { "--ver" };
+        
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("version").create());
+        options.addOption(OptionBuilder.withLongOpt("help").create());
+        
+        CommandLine cl = parser.parse(options, args);
+        
+        assertTrue("Confirm --version is set", cl.hasOption("version"));
+    }
+
+    @Test
+    public void testUnambiguousPartialLongOption2() throws Exception
+    {
+        String[] args = new String[] { "-ver" };
+        
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("version").create());
+        options.addOption(OptionBuilder.withLongOpt("help").create());
+        
+        CommandLine cl = parser.parse(options, args);
+        
+        assertTrue("Confirm --version is set", cl.hasOption("version"));
+    }
+
+    @Test
+    public void testUnambiguousPartialLongOption3() throws Exception
+    {
+        String[] args = new String[] { "--ver=1" };
+        
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("verbose").hasOptionalArg().create());
+        options.addOption(OptionBuilder.withLongOpt("help").create());
+        
+        CommandLine cl = parser.parse(options, args);
+        
+        assertTrue("Confirm --verbose is set", cl.hasOption("verbose"));
+        assertEquals("1", cl.getOptionValue("verbose"));
+    }
+
+    @Test
+    public void testUnambiguousPartialLongOption4() throws Exception
+    {
+        String[] args = new String[] { "-ver=1" };
+        
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("verbose").hasOptionalArg().create());
+        options.addOption(OptionBuilder.withLongOpt("help").create());
+        
+        CommandLine cl = parser.parse(options, args);
+        
+        assertTrue("Confirm --verbose is set", cl.hasOption("verbose"));
+        assertEquals("1", cl.getOptionValue("verbose"));
+    }
+    
+    @Test
+    public void testAmbiguousPartialLongOption1() throws Exception
+    {
+        String[] args = new String[] { "--ver" };
+        
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("version").create());
+        options.addOption(OptionBuilder.withLongOpt("verbose").create());
+        
+        boolean caught = false;
+        
+        try 
+        {
+            parser.parse(options, args);
+        }
+        catch (AmbiguousOptionException e) 
+        {
+            caught = true;
+            assertEquals("Partial option", "--ver", e.getOption());
+            assertNotNull("Matching options null", e.getMatchingOptions());
+            assertEquals("Matching options size", 2, e.getMatchingOptions().size());
+        }
+        
+        assertTrue( "Confirm MissingArgumentException caught", caught );
+    }
+    
+    @Test
+    public void testAmbiguousPartialLongOption2() throws Exception
+    {
+        String[] args = new String[] { "-ver" };
+        
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("version").create());
+        options.addOption(OptionBuilder.withLongOpt("verbose").create());
+        
+        boolean caught = false;
+        
+        try 
+        {
+            parser.parse(options, args);
+        }
+        catch (AmbiguousOptionException e) 
+        {
+            caught = true;
+            assertEquals("Partial option", "-ver", e.getOption());
+            assertNotNull("Matching options null", e.getMatchingOptions());
+            assertEquals("Matching options size", 2, e.getMatchingOptions().size());
+        }
+        
+        assertTrue( "Confirm MissingArgumentException caught", caught );
+    }
+
+    @Test
+    public void testAmbiguousPartialLongOption3() throws Exception
+    {
+        String[] args = new String[] { "--ver=1" };
+        
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("version").create());
+        options.addOption(OptionBuilder.withLongOpt("verbose").hasOptionalArg().create());
+        
+        boolean caught = false;
+        
+        try 
+        {
+            parser.parse(options, args);
+        }
+        catch (AmbiguousOptionException e) 
+        {
+            caught = true;
+            assertEquals("Partial option", "--ver", e.getOption());
+            assertNotNull("Matching options null", e.getMatchingOptions());
+            assertEquals("Matching options size", 2, e.getMatchingOptions().size());
+        }
+        
+        assertTrue( "Confirm MissingArgumentException caught", caught );
+    }
+
+    @Test
+    public void testAmbiguousPartialLongOption4() throws Exception
+    {
+        String[] args = new String[] { "-ver=1" };
+        
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("version").create());
+        options.addOption(OptionBuilder.withLongOpt("verbose").hasOptionalArg().create());
+        
+        boolean caught = false;
+        
+        try 
+        {
+            parser.parse(options, args);
+        }
+        catch (AmbiguousOptionException e) 
+        {
+            caught = true;
+            assertEquals("Partial option", "-ver", e.getOption());
+            assertNotNull("Matching options null", e.getMatchingOptions());
+            assertEquals("Matching options size", 2, e.getMatchingOptions().size());
+        }
+        
+        assertTrue( "Confirm MissingArgumentException caught", caught );
+    }
+    
+    @Test
+    public void testPartialLongOptionSingleDash() throws Exception
+    {
+        String[] args = new String[] { "-ver" };
+        
+        Options options = new Options();
+        options.addOption(OptionBuilder.withLongOpt("version").create());
+        options.addOption(OptionBuilder.hasArg().create('v'));
+        
+        CommandLine cl = parser.parse(options, args);
+        
+        assertTrue("Confirm --version is set", cl.hasOption("version"));
+        assertTrue("Confirm -v is not set", !cl.hasOption("v"));
+    }
+
+    @Test
+    public void testWithRequiredOption() throws Exception
+    {
+        String[] args = new String[] { "-b", "file" };
+        
+        Options options = new Options();
+        options.addOption("a", "enable-a", false, null);
+        options.addOption(OptionBuilder.withLongOpt("bfile").hasArg().isRequired().create('b'));
+
+        CommandLine cl = parser.parse(options,args);
+
+        assertTrue("Confirm -a is NOT set", !cl.hasOption("a"));
+        assertTrue("Confirm -b is set", cl.hasOption("b"));
+        assertTrue("Confirm arg of -b", cl.getOptionValue("b").equals("file"));
+        assertTrue("Confirm NO of extra args", cl.getArgList().size() == 0);
+    }
+
+    @Test
+    public void testOptionAndRequiredOption() throws Exception
+    {
+        String[] args = new String[] { "-a", "-b", "file" };
+        
+        Options options = new Options();
+        options.addOption("a", "enable-a", false, null);
+        options.addOption(OptionBuilder.withLongOpt("bfile").hasArg().isRequired().create('b'));
+
+        CommandLine cl = parser.parse(options,args);
+
+        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("file"));
+        assertTrue("Confirm NO of extra args", cl.getArgList().size() == 0);
+    }
+
+    @Test
+    public void testMissingRequiredOption()
+    {
+        String[] args = new String[] { "-a" };
+        
+        Options options = new Options();
+        options.addOption("a", "enable-a", false, null);
+        options.addOption(OptionBuilder.withLongOpt("bfile").hasArg().isRequired().create('b'));
+
+        try
+        {
+            parser.parse(options,args);
+            fail("exception should have been thrown");
+        }
+        catch (MissingOptionException e)
+        {
+            assertEquals( "Incorrect exception message", "Missing required option: b", e.getMessage() );
+            assertTrue(e.getMissingOptions().contains("b"));
+        }
+        catch (ParseException e)
+        {
+            fail("expected to catch MissingOptionException");
+        }
+    }
+
+    @Test
+    public void testMissingRequiredOptions()
+    {
+        String[] args = new String[] { "-a" };
+
+        Options options = new Options();
+        options.addOption("a", "enable-a", false, null);
+        options.addOption(OptionBuilder.withLongOpt("bfile").hasArg().isRequired().create('b'));
+        options.addOption(OptionBuilder.withLongOpt("cfile").hasArg().isRequired().create('c'));
+
+        try
+        {
+            parser.parse(options,args);
+            fail("exception should have been thrown");
+        }
+        catch (MissingOptionException e)
+        {
+            assertEquals("Incorrect exception message", "Missing required options: b, c", e.getMessage());
+            assertTrue(e.getMissingOptions().contains("b"));
+            assertTrue(e.getMissingOptions().contains("c"));
+        }
+        catch (ParseException e)
+        {
+            fail("expected to catch MissingOptionException");
+        }
+    }
+    
+    @Test
+    public void testMissingRequiredGroup() throws Exception
+    {
+        OptionGroup group = new OptionGroup();
+        group.addOption(OptionBuilder.create("a"));
+        group.addOption(OptionBuilder.create("b"));
+        group.setRequired(true);
+
+        Options options = new Options();
+        options.addOptionGroup(group);
+        options.addOption(OptionBuilder.isRequired().create("c"));
+
+        try
+        {
+            parser.parse(options, new String[] { "-c" });
+            fail("MissingOptionException not thrown");
+        }
+        catch (MissingOptionException e)
+        {
+            assertEquals(1, e.getMissingOptions().size());
+            assertTrue(e.getMissingOptions().get(0) instanceof OptionGroup);
+        }
+        catch (ParseException e)
+        {
+            fail("Expected to catch MissingOptionException");
+        }
+    }
+    
+    @Test
+    public void testOptionGroup() throws Exception
+    {
+        OptionGroup group = new OptionGroup();
+        group.addOption(OptionBuilder.create("a"));
+        group.addOption(OptionBuilder.create("b"));
+        
+        Options options = new Options();
+        options.addOptionGroup(group);
+        
+        parser.parse(options, new String[] { "-b" });
+        
+        assertEquals("selected option", "b", group.getSelected());
+    }
+
+    @Test
+    public void testOptionGroupLong() throws Exception
+    {
+        OptionGroup group = new OptionGroup();
+        group.addOption(OptionBuilder.withLongOpt("foo").create());
+        group.addOption(OptionBuilder.withLongOpt("bar").create());
+        
+        Options options = new Options();
+        options.addOptionGroup(group);
+        
+        CommandLine cl = parser.parse(options, new String[] { "--bar" });
+        
+        assertTrue(cl.hasOption("bar"));
+        assertEquals("selected option", "bar", group.getSelected());
+    }
+    
+    @Test
+    public void testReuseOptionsTwice() throws Exception
+    {
+        Options opts = new Options();
+        opts.addOption(OptionBuilder.isRequired().create('v'));
+
+        // first parsing
+        parser.parse(opts, new String[] { "-v" });
+
+        try
+        {
+            // second parsing, with the same Options instance and an invalid command line
+            parser.parse(opts, new String[0]);
+            fail("MissingOptionException not thrown");
+        }
+        catch (MissingOptionException e)
+        {
+            // expected
+        }
+    }
+
+    @Test
+    public void testBursting() throws Exception
+    {
+        String[] args = new String[] { "-acbtoast", "foo", "bar" };
+
+        CommandLine cl = parser.parse(options, args);
+
+        assertTrue( "Confirm -a is set", cl.hasOption("a") );
+        assertTrue( "Confirm -b is set", cl.hasOption("b") );
+        assertTrue( "Confirm -c is set", cl.hasOption("c") );
+        assertTrue( "Confirm arg of -b", cl.getOptionValue("b").equals("toast") );
+        assertTrue( "Confirm size of extra args", cl.getArgList().size() == 2);
+    }
+
+    @Test
+    public void testUnrecognizedOptionWithBursting() throws Exception
+    {
+        String[] args = new String[] { "-adbtoast", "foo", "bar" };
+
+        try
+        {
+            parser.parse(options, args);
+            fail("UnrecognizedOptionException wasn't thrown");
+        }
+        catch (UnrecognizedOptionException e)
+        {
+            assertEquals("-adbtoast", e.getOption());
+        }
+    }
+
+    @Test
+    public void testMissingArgWithBursting() throws Exception
+    {
+        String[] args = new String[] { "-acb" };
+
+        boolean caught = false;
+
+        try
+        {
+            parser.parse(options, args);
+        }
+        catch (MissingArgumentException e)
+        {
+            caught = true;
+            assertEquals("option missing an argument", "b", e.getOption().getOpt());
+        }
+
+        assertTrue( "Confirm MissingArgumentException caught", caught );
+    }
+
+    @Test
+    public void testStopBursting() throws Exception
+    {
+        String[] args = new String[] { "-azc" };
+
+        CommandLine cl = parser.parse(options, args, true);
+        assertTrue( "Confirm -a is set", cl.hasOption("a") );
+        assertFalse( "Confirm -c is not set", cl.hasOption("c") );
+
+        assertTrue( "Confirm  1 extra arg: " + cl.getArgList().size(), cl.getArgList().size() == 1);
+        assertTrue(cl.getArgList().contains("zc"));
+    }
+
+    @Test
+    public void testStopBursting2() throws Exception
+    {
+        String[] args = new String[] { "-c", "foobar", "-btoast" };
+
+        CommandLine cl = parser.parse(options, args, true);
+        assertTrue("Confirm -c is set", cl.hasOption("c"));
+        assertTrue("Confirm  2 extra args: " + cl.getArgList().size(), cl.getArgList().size() == 2);
+
+        cl = parser.parse(options, cl.getArgs());
+
+        assertTrue("Confirm -c is not set", !cl.hasOption("c"));
+        assertTrue("Confirm -b is set", cl.hasOption("b"));
+        assertTrue("Confirm arg of -b", cl.getOptionValue("b").equals("toast"));
+        assertTrue("Confirm  1 extra arg: " + cl.getArgList().size(), cl.getArgList().size() == 1);
+        assertTrue("Confirm  value of extra arg: " + cl.getArgList().get(0), cl.getArgList().get(0).equals("foobar"));
+    }
+
+    @Test
+    public void testUnlimitedArgs() throws Exception
+    {
+        String[] args = new String[]{"-e", "one", "two", "-f", "alpha"};
+
+        Options options = new Options();
+        options.addOption(OptionBuilder.hasArgs().create("e"));
+        options.addOption(OptionBuilder.hasArgs().create("f"));
+
+        CommandLine cl = parser.parse(options, args);
+
+        assertTrue("Confirm -e is set", cl.hasOption("e"));
+        assertEquals("number of arg for -e", 2, cl.getOptionValues("e").length);
+        assertTrue("Confirm -f is set", cl.hasOption("f"));
+        assertEquals("number of arg for -f", 1, cl.getOptionValues("f").length);
+    }
+
+    @SuppressWarnings("deprecation")
+    private CommandLine parse(CommandLineParser parser, Options opts, String[] args, Properties properties) throws ParseException {
+        if (parser instanceof Parser) {
+            return ((Parser) parser).parse(opts, args, properties);
+        } else if (parser instanceof DefaultParser) {
+            return ((DefaultParser) parser).parse(opts, args, properties);
+        } else {
+            throw new UnsupportedOperationException("Default options not supported by this parser");
+        }
+    }
+
+    @Test
+    public void testPropertyOptionSingularValue() throws Exception
+    {
+        Options opts = new Options();
+        opts.addOption(OptionBuilder.hasOptionalArgs(2).withLongOpt("hide").create());        
+        
+        Properties properties = new Properties();
+        properties.setProperty( "hide", "seek" );
+
+        CommandLine cmd = parse(parser, opts, null, properties);
+        assertTrue( cmd.hasOption("hide") );
+        assertEquals( "seek", cmd.getOptionValue("hide") );
+        assertTrue( !cmd.hasOption("fake") );
+    }
+
+    @Test
+    public void testPropertyOptionFlags() throws Exception
+    {
+        Options opts = new Options();
+        opts.addOption("a", false, "toggle -a");
+        opts.addOption("c", "c", false, "toggle -c");
+        opts.addOption(OptionBuilder.hasOptionalArg().create('e'));
+        
+        Properties properties = new Properties();
+        properties.setProperty("a", "true");
+        properties.setProperty("c", "yes");
+        properties.setProperty("e", "1");
+        
+        CommandLine cmd = parse(parser, opts, null, properties);
+        assertTrue(cmd.hasOption("a"));
+        assertTrue(cmd.hasOption("c"));
+        assertTrue(cmd.hasOption("e"));
+        
+        
+        properties = new Properties();
+        properties.setProperty("a", "false");
+        properties.setProperty("c", "no");
+        properties.setProperty("e", "0");
+        
+        cmd = parse(parser, opts, null, properties);
+        assertTrue(!cmd.hasOption("a"));
+        assertTrue(!cmd.hasOption("c"));
+        assertTrue(cmd.hasOption("e")); // this option accepts an argument
+        
+        
+        properties = new Properties();
+        properties.setProperty("a", "TRUE");
+        properties.setProperty("c", "nO");
+        properties.setProperty("e", "TrUe");
+        
+        cmd = parse(parser, opts, null, properties);
+        assertTrue(cmd.hasOption("a"));
+        assertTrue(!cmd.hasOption("c"));
+        assertTrue(cmd.hasOption("e"));
+        
+        
+        properties = new Properties();
+        properties.setProperty("a", "just a string");
+        properties.setProperty("e", "");
+        
+        cmd = parse(parser, opts, null, properties);
+        assertTrue(!cmd.hasOption("a"));
+        assertTrue(!cmd.hasOption("c"));
+        assertTrue(cmd.hasOption("e"));
+        
+        
+        properties = new Properties();
+        properties.setProperty("a", "0");
+        properties.setProperty("c", "1");
+        
+        cmd = parse(parser, opts, null, properties);
+        assertTrue(!cmd.hasOption("a"));
+        assertTrue(cmd.hasOption("c"));
+    } 
+
+    @Test
+    public void testPropertyOptionMultipleValues() throws Exception
+    {
+        Options opts = new Options();
+        opts.addOption(OptionBuilder.hasArgs().withValueSeparator(',').create('k'));
+        
+        Properties properties = new Properties();
+        properties.setProperty( "k", "one,two" );
+
+        String[] values = new String[] { "one", "two" };
+
+        CommandLine cmd = parse(parser, opts, null, properties);
+        assertTrue( cmd.hasOption("k") );
+        assertTrue( Arrays.equals( values, cmd.getOptionValues('k') ) );
+    }
+
+    @Test
+    public void testPropertyOverrideValues() throws Exception
+    {
+        Options opts = new Options();
+        opts.addOption(OptionBuilder.hasOptionalArgs(2).create('i'));
+        opts.addOption(OptionBuilder.hasOptionalArgs().create('j'));
+        
+        String[] args = new String[] { "-j", "found", "-i", "ink" };
+
+        Properties properties = new Properties();
+        properties.setProperty( "j", "seek" );
+
+        CommandLine cmd = parse(parser, 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") );
+    }
+
+    @Test
+    public void testPropertyOptionRequired() throws Exception
+    {
+        Options opts = new Options();
+        opts.addOption(OptionBuilder.isRequired().create("f"));
+        
+        Properties properties = new Properties();
+        properties.setProperty("f", "true");
+        
+        CommandLine cmd = parse(parser, opts, null, properties);
+        assertTrue(cmd.hasOption("f"));
+    }
+
+    @Test
+    public void testPropertyOptionUnexpected() throws Exception
+    {
+        Options opts = new Options();
+        
+        Properties properties = new Properties();
+        properties.setProperty("f", "true");
+        
+        try {
+            parse(parser, opts, null, properties);
+            fail("UnrecognizedOptionException expected");
+        } catch (UnrecognizedOptionException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testPropertyOptionGroup() throws Exception
+    {
+        Options opts = new Options();
+        
+        OptionGroup group1 = new OptionGroup();
+        group1.addOption(new Option("a", null));
+        group1.addOption(new Option("b", null));
+        opts.addOptionGroup(group1);
+        
+        OptionGroup group2 = new OptionGroup();
+        group2.addOption(new Option("x", null));
+        group2.addOption(new Option("y", null));
+        opts.addOptionGroup(group2);
+        
+        String[] args = new String[] { "-a" };
+        
+        Properties properties = new Properties();
+        properties.put("b", "true");
+        properties.put("x", "true");
+        
+        CommandLine cmd = parse(parser, opts, args, properties);
+        
+        assertTrue(cmd.hasOption("a"));
+        assertFalse(cmd.hasOption("b"));
+        assertTrue(cmd.hasOption("x"));
+        assertFalse(cmd.hasOption("y"));
+    }
+}
diff --git a/src/test/org/apache/commons/cli/PatternOptionBuilderTest.java b/src/test/java/org/apache/commons/cli/PatternOptionBuilderTest.java
similarity index 91%
rename from src/test/org/apache/commons/cli/PatternOptionBuilderTest.java
rename to src/test/java/org/apache/commons/cli/PatternOptionBuilderTest.java
index d2df17a..1b3bdfc 100644
--- a/src/test/org/apache/commons/cli/PatternOptionBuilderTest.java
+++ b/src/test/java/org/apache/commons/cli/PatternOptionBuilderTest.java
@@ -17,21 +17,27 @@
 
 package org.apache.commons.cli;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import java.io.File;
 import java.net.URL;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.Vector;
 
-import junit.framework.TestCase;
+import org.junit.Test;
 
 /** 
- * Test case for the PatternOptionBuilder class 
- *
- * @version $Revision: 741427 $, $Date: 2009-02-05 22:11:37 -0800 (Thu, 05 Feb 2009) $
+ * Test case for the PatternOptionBuilder class.
  */
-public class PatternOptionBuilderTest extends TestCase
+ at SuppressWarnings("deprecation") // tests some deprecated classes
+public class PatternOptionBuilderTest
 {
+    @Test
     public void testSimplePattern() throws Exception
     {
         Options options = PatternOptionBuilder.parsePattern("a:b at cde>f+n%t/m*z#");
@@ -42,7 +48,7 @@ public class PatternOptionBuilderTest extends TestCase
 
         assertEquals("flag a", "foo", line.getOptionValue("a"));
         assertEquals("string flag a", "foo", line.getOptionObject("a"));
-        assertEquals("object flag b", new Vector(), line.getOptionObject("b"));
+        assertEquals("object flag b", new Vector<Object>(), line.getOptionObject("b"));
         assertTrue("boolean true flag c", line.hasOption("c"));
         assertFalse("boolean false flag d", line.hasOption("d"));
         assertEquals("file flag e", new File("build.xml"), line.getOptionObject("e"));
@@ -53,7 +59,7 @@ public class PatternOptionBuilderTest extends TestCase
         // 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 Vector(), line.getOptionObject('b'));
+        assertEquals("object flag b", new Vector<Object>(), line.getOptionObject('b'));
         assertTrue("boolean true flag c", line.hasOption('c'));
         assertFalse("boolean false flag d", line.hasOption('d'));
         assertEquals("file flag e", new File("build.xml"), line.getOptionObject('e'));
@@ -78,12 +84,14 @@ public class PatternOptionBuilderTest extends TestCase
         }
     }
 
+    @Test
     public void testEmptyPattern() throws Exception
     {
         Options options = PatternOptionBuilder.parsePattern("");
         assertTrue(options.getOptions().isEmpty());
     }
 
+    @Test
     public void testUntypedPattern() throws Exception
     {
         Options options = PatternOptionBuilder.parsePattern("abc");
@@ -98,6 +106,7 @@ public class PatternOptionBuilderTest extends TestCase
         assertNull("value c", line.getOptionObject('c'));
     }
 
+    @Test
     public void testNumberPattern() throws Exception
     {
         Options options = PatternOptionBuilder.parsePattern("n%d%x%");
@@ -113,6 +122,7 @@ public class PatternOptionBuilderTest extends TestCase
         assertNull("x object", line.getOptionObject("x"));
     }
 
+    @Test
     public void testClassPattern() throws Exception
     {
         Options options = PatternOptionBuilder.parsePattern("c+d+");
@@ -123,6 +133,7 @@ public class PatternOptionBuilderTest extends TestCase
         assertNull("d value", line.getOptionObject("d"));
     }
 
+    @Test
     public void testObjectPattern() throws Exception
     {
         Options options = PatternOptionBuilder.parsePattern("o at i@n@");
@@ -134,6 +145,7 @@ public class PatternOptionBuilderTest extends TestCase
         assertNull("n value", line.getOptionObject("n"));
     }
 
+    @Test
     public void testURLPattern() throws Exception
     {
         Options options = PatternOptionBuilder.parsePattern("u/v/");
@@ -144,6 +156,7 @@ public class PatternOptionBuilderTest extends TestCase
         assertNull("v value", line.getOptionObject("v"));
     }
 
+    @Test
     public void testExistingFilePattern() throws Exception
     {
         Options options = PatternOptionBuilder.parsePattern("f<");
@@ -155,6 +168,7 @@ public class PatternOptionBuilderTest extends TestCase
         // todo test if an error is returned if the file doesn't exists (when it's implemented)
     }
 
+    @Test
     public void testRequiredOption() throws Exception
     {
         Options options = PatternOptionBuilder.parsePattern("!n%m%");
diff --git a/src/test/java/org/apache/commons/cli/PosixParserTest.java b/src/test/java/org/apache/commons/cli/PosixParserTest.java
new file mode 100644
index 0000000..3ca7872
--- /dev/null
+++ b/src/test/java/org/apache/commons/cli/PosixParserTest.java
@@ -0,0 +1,88 @@
+/**
+ * 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 org.junit.Before;
+
+/**
+ * Test case for the PosixParser.
+ */
+public class PosixParserTest extends ParserTestCase
+{
+    @SuppressWarnings("deprecation")
+    @Before
+    public void setUp()
+    {
+        super.setUp();
+        parser = new PosixParser();
+    }
+
+    @Override
+    public void testDoubleDash2() throws Exception
+    {
+        // not supported by the PosixParser
+    }
+    
+    @Override
+    public void testLongWithoutEqualSingleDash() throws Exception
+    {
+        // not supported by the PosixParser
+    }
+
+    @Override
+    public void testAmbiguousLongWithoutEqualSingleDash() throws Exception
+    {
+        // not supported by the PosixParser
+    }
+    
+    @Override
+    public void testNegativeOption() throws Exception
+    {
+        // not supported by the PosixParser (CLI-184)
+    }
+
+    @Override
+    public void testLongWithUnexpectedArgument1() throws Exception
+    {
+        // not supported by the PosixParser
+    }
+
+    @Override
+    public void testLongWithEqualSingleDash() throws Exception
+    {
+        // not supported by the PosixParser
+    }
+
+    @Override
+    public void testShortWithEqual() throws Exception
+    {
+        // not supported by the PosixParser
+    }
+
+    @Override
+    public void testUnambiguousPartialLongOption4() throws Exception
+    {
+        // not supported by the PosixParser
+    }
+
+    @Override
+    public void testAmbiguousPartialLongOption4() throws Exception
+    {
+        // not supported by the PosixParser
+    }
+}
diff --git a/src/test/org/apache/commons/cli/UtilTest.java b/src/test/java/org/apache/commons/cli/UtilTest.java
similarity index 71%
rename from src/test/org/apache/commons/cli/UtilTest.java
rename to src/test/java/org/apache/commons/cli/UtilTest.java
index c8c614a..46cb578 100644
--- a/src/test/org/apache/commons/cli/UtilTest.java
+++ b/src/test/java/org/apache/commons/cli/UtilTest.java
@@ -17,13 +17,14 @@
 
 package org.apache.commons.cli;
 
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
 
-/**
- * @author brianegge
- */
-public class UtilTest extends TestCase
+import org.junit.Test;
+
+public class UtilTest
 {
+    @Test
     public void testStripLeadingHyphens()
     {
         assertEquals("f", Util.stripLeadingHyphens("-f"));
@@ -32,8 +33,13 @@ public class UtilTest extends TestCase
         assertNull(Util.stripLeadingHyphens(null));
     }
 
+    @Test
     public void testStripLeadingAndTrailingQuotes()
     {
         assertEquals("foo", Util.stripLeadingAndTrailingQuotes("\"foo\""));
+        assertEquals("foo \"bar\"", Util.stripLeadingAndTrailingQuotes("foo \"bar\""));
+        assertEquals("\"foo\" bar", Util.stripLeadingAndTrailingQuotes("\"foo\" bar"));
+        assertEquals("\"foo\" and \"bar\"", Util.stripLeadingAndTrailingQuotes("\"foo\" and \"bar\""));
+        assertEquals("\"", Util.stripLeadingAndTrailingQuotes("\""));
     }
 }
diff --git a/src/test/org/apache/commons/cli/ValueTest.java b/src/test/java/org/apache/commons/cli/ValueTest.java
similarity index 63%
rename from src/test/org/apache/commons/cli/ValueTest.java
rename to src/test/java/org/apache/commons/cli/ValueTest.java
index c7d764a..14a8410 100644
--- a/src/test/org/apache/commons/cli/ValueTest.java
+++ b/src/test/java/org/apache/commons/cli/ValueTest.java
@@ -17,16 +17,21 @@
 
 package org.apache.commons.cli;
 
-import java.util.Arrays;
-import java.util.Properties;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
-import junit.framework.TestCase;
+import org.junit.Before;
+import org.junit.Test;
 
-public class ValueTest extends TestCase
+ at SuppressWarnings("deprecation") // tests some deprecated classes
+public class ValueTest
 {
     private CommandLine _cl = null;
-    private Options opts = new Options();
+    private final Options opts = new Options();
 
+    @Before
     public void setUp() throws Exception
     {
         opts.addOption("a", false, "toggle -a");
@@ -40,7 +45,6 @@ public class ValueTest extends TestCase
         opts.addOption(OptionBuilder.hasOptionalArgs(2).withLongOpt("hide").create());
         opts.addOption(OptionBuilder.hasOptionalArgs(2).create('i'));
         opts.addOption(OptionBuilder.hasOptionalArgs().create('j'));
-        opts.addOption(OptionBuilder.hasArgs().withValueSeparator(',').create('k'));
 
         String[] args = new String[] { "-a",
             "-b", "foo",
@@ -52,12 +56,14 @@ public class ValueTest extends TestCase
         _cl = parser.parse(opts,args);
     }
 
+    @Test
     public void testShortNoArg()
     {
         assertTrue( _cl.hasOption("a") );
         assertNull( _cl.getOptionValue("a") );
     }
 
+    @Test
     public void testShortWithArg()
     {
         assertTrue( _cl.hasOption("b") );
@@ -65,12 +71,14 @@ public class ValueTest extends TestCase
         assertEquals( _cl.getOptionValue("b"), "foo");
     }
 
+    @Test
     public void testLongNoArg()
     {
         assertTrue( _cl.hasOption("c") );
         assertNull( _cl.getOptionValue("c") );
     }
 
+    @Test
     public void testLongWithArg()
     {
         assertTrue( _cl.hasOption("d") );
@@ -78,6 +86,7 @@ public class ValueTest extends TestCase
         assertEquals( _cl.getOptionValue("d"), "bar");
     }
 
+    @Test
     public void testShortOptionalArgNoValue() throws Exception
     {
         String[] args = new String[] { "-e" };
@@ -88,6 +97,7 @@ public class ValueTest extends TestCase
         assertNull( cmd.getOptionValue("e") );
     }
 
+    @Test
     public void testShortOptionalArgValue() throws Exception
     {
         String[] args = new String[] { "-e", "everything" };
@@ -98,6 +108,7 @@ public class ValueTest extends TestCase
         assertEquals( "everything", cmd.getOptionValue("e") );
     }
 
+    @Test
     public void testLongOptionalNoValue() throws Exception
     {
         String[] args = new String[] { "--fish" };
@@ -108,6 +119,7 @@ public class ValueTest extends TestCase
         assertNull( cmd.getOptionValue("fish") );
     }
 
+    @Test
     public void testLongOptionalArgValue() throws Exception
     {
         String[] args = new String[] { "--fish", "face" };
@@ -118,6 +130,7 @@ public class ValueTest extends TestCase
         assertEquals( "face", cmd.getOptionValue("fish") );
     }
 
+    @Test
     public void testShortOptionalArgValues() throws Exception
     {
         String[] args = new String[] { "-j", "ink", "idea" };
@@ -131,6 +144,7 @@ public class ValueTest extends TestCase
         assertEquals( cmd.getArgs().length, 0 );
     }
 
+    @Test
     public void testLongOptionalArgValues() throws Exception
     {
         String[] args = new String[] { "--gravy", "gold", "garden" };
@@ -144,6 +158,7 @@ public class ValueTest extends TestCase
         assertEquals( cmd.getArgs().length, 0 );
     }
 
+    @Test
     public void testShortOptionalNArgValues() throws Exception
     {
         String[] args = new String[] { "-i", "ink", "idea", "isotope", "ice" };
@@ -159,6 +174,7 @@ public class ValueTest extends TestCase
         assertEquals( "ice", cmd.getArgs()[1] );
     }
 
+    @Test
     public void testLongOptionalNArgValues() throws Exception
     {
         String[] args = new String[] { 
@@ -175,102 +191,4 @@ public class ValueTest extends TestCase
         assertEquals( cmd.getArgs().length, 1 );
         assertEquals( "head", cmd.getArgs()[0] );
     }
-
-    public void testPropertyOptionSingularValue() throws Exception
-    {
-        Properties properties = new Properties();
-        properties.setProperty( "hide", "seek" );
-
-        Parser parser = new PosixParser();
-        
-        CommandLine cmd = parser.parse(opts, null, properties);
-        assertTrue( cmd.hasOption("hide") );
-        assertEquals( "seek", cmd.getOptionValue("hide") );
-        assertTrue( !cmd.hasOption("fake") );
-    }
-
-    public void testPropertyOptionFlags() throws Exception
-    {
-        Properties properties = new Properties();
-        properties.setProperty( "a", "true" );
-        properties.setProperty( "c", "yes" );
-        properties.setProperty( "e", "1" );
-
-        Parser parser = new PosixParser();
-
-        CommandLine cmd = parser.parse(opts, null, properties);
-        assertTrue( cmd.hasOption("a") );
-        assertTrue( cmd.hasOption("c") );
-        assertTrue( cmd.hasOption("e") );
-
-
-        properties = new Properties();
-        properties.setProperty( "a", "false" );
-        properties.setProperty( "c", "no" );
-        properties.setProperty( "e", "0" );
-
-        cmd = parser.parse(opts, null, properties);
-        assertTrue( !cmd.hasOption("a") );
-        assertTrue( !cmd.hasOption("c") );
-        assertTrue( !cmd.hasOption("e") );
-
-
-        properties = new Properties();
-        properties.setProperty( "a", "TRUE" );
-        properties.setProperty( "c", "nO" );
-        properties.setProperty( "e", "TrUe" );
-
-        cmd = parser.parse(opts, null, properties);
-        assertTrue( cmd.hasOption("a") );
-        assertTrue( !cmd.hasOption("c") );
-        assertTrue( cmd.hasOption("e") );
-
-        
-        properties = new Properties();
-        properties.setProperty( "a", "just a string" );
-        properties.setProperty( "e", "" );
-
-        cmd = parser.parse(opts, null, properties);
-        assertTrue( !cmd.hasOption("a") );
-        assertTrue( !cmd.hasOption("c") );
-        assertTrue( !cmd.hasOption("e") );
-    } 
-
-    public void testPropertyOptionMultipleValues() throws Exception
-    {
-        Properties properties = new Properties();
-        properties.setProperty( "k", "one,two" );
-
-        Parser parser = new PosixParser();
-        
-        String[] values = new String[] {
-            "one", "two"
-        };
-
-        CommandLine cmd = parser.parse(opts, null, properties);
-        assertTrue( cmd.hasOption("k") );
-        assertTrue( Arrays.equals( values, cmd.getOptionValues('k') ) );
-    }
-
-    public void testPropertyOverrideValues() throws Exception
-    {
-        String[] args = new String[] { 
-            "-j",
-            "found",
-            "-i",
-            "ink"
-        };
-
-        Properties properties = new Properties();
-        properties.setProperty( "j", "seek" );
-
-        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") );
-    }
-
 }
diff --git a/src/test/org/apache/commons/cli/ValuesTest.java b/src/test/java/org/apache/commons/cli/ValuesTest.java
similarity index 54%
rename from src/test/org/apache/commons/cli/ValuesTest.java
rename to src/test/java/org/apache/commons/cli/ValuesTest.java
index 83eeb98..d8c951a 100644
--- a/src/test/org/apache/commons/cli/ValuesTest.java
+++ b/src/test/java/org/apache/commons/cli/ValuesTest.java
@@ -17,15 +17,20 @@
 
 package org.apache.commons.cli;
 
-import java.util.Arrays;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
-import junit.framework.TestCase;
+import org.junit.Before;
+import org.junit.Test;
 
-public class ValuesTest extends TestCase
+ at SuppressWarnings("deprecation") // tests some deprecated classes
+public class ValuesTest
 {
-    /** CommandLine instance */
-    private CommandLine _cmdline = null;
+    private CommandLine cmd;
 
+    @Before
     public void setUp() throws Exception
     {
         Options options = new Options();
@@ -38,7 +43,7 @@ public class ValuesTest extends TestCase
         options.addOption(OptionBuilder.withLongOpt("e").hasArgs().withDescription("set -e ").create('e'));
         options.addOption("f", "f", false, "jk");
         options.addOption(OptionBuilder.withLongOpt("g").hasArgs(2).withDescription("set -g").create('g'));
-        options.addOption(OptionBuilder.withLongOpt("h").hasArgs(2).withDescription("set -h").create('h'));
+        options.addOption(OptionBuilder.withLongOpt("h").hasArg().withDescription("set -h").create('h'));
         options.addOption(OptionBuilder.withLongOpt("i").withDescription("set -i").create('i'));
         options.addOption(OptionBuilder.withLongOpt("j").hasArgs().withDescription("set -j").withValueSeparator('=').create('j'));
         options.addOption(OptionBuilder.withLongOpt("k").hasArgs().withDescription("set -k").withValueSeparator('=').create('k'));
@@ -62,91 +67,77 @@ public class ValuesTest extends TestCase
 
         CommandLineParser parser = new PosixParser();
 
-        _cmdline = parser.parse(options,args);
+        cmd = parser.parse(options,args);
     }
 
+    @Test
     public void testShortArgs()
     {
-        assertTrue( _cmdline.hasOption("a") );
-        assertTrue( _cmdline.hasOption("c") );
+        assertTrue("Option a is not set", cmd.hasOption("a"));
+        assertTrue("Option c is not set", cmd.hasOption("c"));
 
-        assertNull( _cmdline.getOptionValues("a") );
-        assertNull( _cmdline.getOptionValues("c") );
+        assertNull(cmd.getOptionValues("a"));
+        assertNull(cmd.getOptionValues("c"));
     }
 
+    @Test
     public void testShortArgsWithValue()
     {
-        assertTrue( _cmdline.hasOption("b") );
-        assertTrue( _cmdline.getOptionValue("b").equals("foo"));
-        assertEquals(1, _cmdline.getOptionValues("b").length);
+        assertTrue("Option b is not set", cmd.hasOption("b"));
+        assertTrue(cmd.getOptionValue("b").equals("foo"));
+        assertEquals(1, cmd.getOptionValues("b").length);
 
-        assertTrue( _cmdline.hasOption("d") );
-        assertTrue( _cmdline.getOptionValue("d").equals("bar"));
-        assertEquals(1, _cmdline.getOptionValues("d").length);
+        assertTrue("Option d is not set", cmd.hasOption("d"));
+        assertTrue(cmd.getOptionValue("d").equals("bar"));
+        assertEquals(1, cmd.getOptionValues("d").length);
     }
 
+    @Test
     public void testMultipleArgValues()
     {
-        String[] result = _cmdline.getOptionValues("e");
-        String[] values = new String[] { "one", "two" };
-        assertTrue( _cmdline.hasOption("e") );
-        assertEquals(2, _cmdline.getOptionValues("e").length);
-        assertTrue( Arrays.equals( values, _cmdline.getOptionValues("e") ) );
+        assertTrue("Option e is not set", cmd.hasOption("e"));
+        assertArrayEquals(new String[] { "one", "two" }, cmd.getOptionValues("e"));
     }
 
+    @Test
     public void testTwoArgValues()
     {
-        String[] result = _cmdline.getOptionValues("g");
-        String[] values = new String[] { "val1", "val2" };
-        assertTrue( _cmdline.hasOption("g") );
-        assertEquals(2, _cmdline.getOptionValues("g").length);
-        assertTrue( Arrays.equals( values, _cmdline.getOptionValues("g") ) );
+        assertTrue("Option g is not set", cmd.hasOption("g"));
+        assertArrayEquals(new String[] { "val1", "val2" }, cmd.getOptionValues("g"));
     }
 
+    @Test
     public void testComplexValues()
     {
-        String[] result = _cmdline.getOptionValues("h");
-        String[] values = new String[] { "val1", "val2" };
-        assertTrue( _cmdline.hasOption("i") );
-        assertTrue( _cmdline.hasOption("h") );
-        assertEquals(2, _cmdline.getOptionValues("h").length);
-        assertTrue( Arrays.equals( values, _cmdline.getOptionValues("h") ) );
+        assertTrue("Option i is not set", cmd.hasOption("i"));
+        assertTrue("Option h is not set", cmd.hasOption("h"));
+        assertArrayEquals(new String[] { "val1", "val2" }, cmd.getOptionValues("h"));
     }
 
+    @Test
     public void testExtraArgs()
     {
-        String[] args = new String[] { "arg1", "arg2", "arg3" };
-        assertEquals(3, _cmdline.getArgs().length);
-        assertTrue( Arrays.equals( args, _cmdline.getArgs() ) );
+        assertArrayEquals("Extra args", new String[] { "arg1", "arg2", "arg3" }, cmd.getArgs());
     }
 
+    @Test
     public void testCharSeparator()
     {
-        // tests the char methods of CommandLine that delegate to
-        // the String methods
-        String[] values = new String[] { "key", "value", "key", "value" };
-        assertTrue( _cmdline.hasOption( "j" ) );
-        assertTrue( _cmdline.hasOption( 'j' ) );
-        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' ) ) );
-
-        values = new String[] { "key1", "value1", "key2", "value2" };
-        assertTrue( _cmdline.hasOption( "k" ) );
-        assertTrue( _cmdline.hasOption( 'k' ) );
-        assertEquals(4, _cmdline.getOptionValues( "k" ).length);
-        assertEquals(4, _cmdline.getOptionValues( 'k' ).length);
-        assertTrue( Arrays.equals( values, _cmdline.getOptionValues( "k" ) ) );
-        assertTrue( Arrays.equals( values, _cmdline.getOptionValues( 'k' ) ) );
-
-        values = new String[] { "key", "value" };
-        assertTrue( _cmdline.hasOption( "m" ) );
-        assertTrue( _cmdline.hasOption( 'm' ) );
-        assertEquals(2, _cmdline.getOptionValues( "m" ).length);
-        assertEquals(2, _cmdline.getOptionValues( 'm' ).length);
-        assertTrue( Arrays.equals( values, _cmdline.getOptionValues( "m" ) ) );
-        assertTrue( Arrays.equals( values, _cmdline.getOptionValues( 'm' ) ) );
+        // tests the char methods of CommandLine that delegate to the String methods
+        assertTrue("Option j is not set", cmd.hasOption("j"));
+        assertTrue("Option j is not set", cmd.hasOption('j'));
+        assertArrayEquals(new String[] { "key", "value", "key", "value" }, cmd.getOptionValues("j"));
+        assertArrayEquals(new String[] { "key", "value", "key", "value" }, cmd.getOptionValues('j'));
+
+        assertTrue("Option k is not set", cmd.hasOption("k"));
+        assertTrue("Option k is not set", cmd.hasOption('k'));
+        assertArrayEquals(new String[] { "key1", "value1", "key2", "value2" }, cmd.getOptionValues("k"));
+        assertArrayEquals(new String[] { "key1", "value1", "key2", "value2" }, cmd.getOptionValues('k'));
+
+        assertTrue("Option m is not set", cmd.hasOption("m"));
+        assertTrue("Option m is not set", cmd.hasOption('m'));
+        assertArrayEquals(new String[] { "key", "value" }, cmd.getOptionValues("m"));
+        assertArrayEquals(new String[] { "key", "value" }, cmd.getOptionValues('m'));
     }
 
     /**
diff --git a/src/test/org/apache/commons/cli/bug/BugCLI133Test.java b/src/test/java/org/apache/commons/cli/bug/BugCLI133Test.java
similarity index 88%
copy from src/test/org/apache/commons/cli/bug/BugCLI133Test.java
copy to src/test/java/org/apache/commons/cli/bug/BugCLI133Test.java
index 42d13c1..8f6496a 100644
--- a/src/test/org/apache/commons/cli/bug/BugCLI133Test.java
+++ b/src/test/java/org/apache/commons/cli/bug/BugCLI133Test.java
@@ -17,18 +17,19 @@
 
 package org.apache.commons.cli.bug;
 
+import static org.junit.Assert.assertFalse;
+
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
 import org.apache.commons.cli.PosixParser;
+import org.junit.Test;
 
-import junit.framework.TestCase;
-
-/**
- * @author brianegge
- */
-public class BugCLI133Test extends TestCase {
+ at SuppressWarnings("deprecation") // tests some deprecated classes
+public class BugCLI133Test
+{    
+    @Test
     public void testOrder() throws ParseException {
         Option optionA = new Option("a", "first");
         Options opts = new Options();
diff --git a/src/test/org/apache/commons/cli/bug/BugCLI13Test.java b/src/test/java/org/apache/commons/cli/bug/BugCLI13Test.java
similarity index 87%
rename from src/test/org/apache/commons/cli/bug/BugCLI13Test.java
rename to src/test/java/org/apache/commons/cli/bug/BugCLI13Test.java
index bc94b2a..6f6c7cc 100644
--- a/src/test/org/apache/commons/cli/bug/BugCLI13Test.java
+++ b/src/test/java/org/apache/commons/cli/bug/BugCLI13Test.java
@@ -17,23 +17,25 @@
 
 package org.apache.commons.cli.bug;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
 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;
+import org.junit.Test;
 
-import junit.framework.TestCase;
-
-/**
- * @author brianegge
- */
-public class BugCLI13Test extends TestCase
+ at SuppressWarnings("deprecation") // tests some deprecated classes
+public class BugCLI13Test
 {
+    @Test
     public void testCLI13() throws ParseException
     {
         final String debugOpt = "debug";
+        @SuppressWarnings("static-access")
         Option debug = OptionBuilder
             .withArgName( debugOpt )
             .withDescription( "turn on debugging" )
diff --git a/src/test/org/apache/commons/cli/bug/BugCLI148Test.java b/src/test/java/org/apache/commons/cli/bug/BugCLI148Test.java
similarity index 57%
rename from src/test/org/apache/commons/cli/bug/BugCLI148Test.java
rename to src/test/java/org/apache/commons/cli/bug/BugCLI148Test.java
index 4668468..620569c 100644
--- a/src/test/org/apache/commons/cli/bug/BugCLI148Test.java
+++ b/src/test/java/org/apache/commons/cli/bug/BugCLI148Test.java
@@ -17,50 +17,49 @@
 
 package org.apache.commons.cli.bug;
 
+import static org.junit.Assert.assertEquals;
+
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.Option;
 import org.apache.commons.cli.OptionBuilder;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.PosixParser;
-
-import junit.framework.TestCase;
+import org.junit.Before;
+import org.junit.Test;
 
 /**
  * http://issues.apache.org/jira/browse/CLI-148
- *
- * @author brianegge
  */
-public class BugCLI148Test  extends TestCase {
+ at SuppressWarnings("deprecation") // tests some deprecated classes
+public class BugCLI148Test
+{    
+    private Options options;
+
+    @Before
+    public void setUp() throws Exception
+    {
+        options = new Options();
+        options.addOption(OptionBuilder.hasArg().create('t'));
+        options.addOption(OptionBuilder.hasArg().create('s'));
+    }
 
+    @Test
     public void testWorkaround1() 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'));
+        String[] args = new String[]{ "-t-something" };
+
+        CommandLine commandLine = parser.parse(options, args);
+        assertEquals("-something", commandLine.getOptionValue('t'));
     }
 
+    @Test
     public void testWorkaround2() 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'));
-    }
+        String[] args = new String[]{ "-t", "\"-something\"" };
 
-    private Options buildCommandLineOptions()
-    {
-        Option t = OptionBuilder.withArgName( "t").hasArg().create('t');
-        Option s = OptionBuilder.withArgName( "s").hasArg().create('s');
-        Options options = new Options();
-        options.addOption( t);
-        options.addOption( s);
-        return options;
+        CommandLine commandLine = parser.parse(options, args);
+        assertEquals("-something", commandLine.getOptionValue('t'));
     }
-
 }
diff --git a/src/test/org/apache/commons/cli/bug/BugCLI162Test.java b/src/test/java/org/apache/commons/cli/bug/BugCLI162Test.java
similarity index 65%
rename from src/test/org/apache/commons/cli/bug/BugCLI162Test.java
rename to src/test/java/org/apache/commons/cli/bug/BugCLI162Test.java
index 14e1a60..52e2c20 100644
--- a/src/test/org/apache/commons/cli/bug/BugCLI162Test.java
+++ b/src/test/java/org/apache/commons/cli/bug/BugCLI162Test.java
@@ -15,36 +15,56 @@
  * limitations under the License.
  */
 
-
 package org.apache.commons.cli.bug;
 
-import java.io.IOException;
+import static org.junit.Assert.assertEquals;
+
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.sql.ParameterMetaData;
 import java.sql.Types;
 
-import junit.framework.TestCase;
-
 import org.apache.commons.cli.HelpFormatter;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.OptionGroup;
 import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
+import org.junit.Before;
+import org.junit.Test;
 
-public class BugCLI162Test extends TestCase {
+public class BugCLI162Test
+{
     /** Constant for the line separator.*/
     private static final String CR = System.getProperty("line.separator");
+    
+    private HelpFormatter formatter;
+    private StringWriter sw;
+
+    @Before
+    public void setUp() throws Exception
+    {
+        formatter = new HelpFormatter();
+        sw = new StringWriter();
+    }
 
+    @Test
     public void testInfiniteLoop() {
         Options options = new Options();
         options.addOption("h", "help", false, "This is a looooong description");
-        HelpFormatter formatter = new HelpFormatter();
-        formatter.setWidth(20);
-        formatter.printHelp("app", options); // used to hang & crash
+        // used to hang & crash
+        formatter.printHelp(new PrintWriter(sw), 20, "app", null, options, HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_DESC_PAD, null);
+
+        String expected = "usage: app" + CR +
+                " -h,--help   This is" + CR +
+                "             a" + CR +
+                "             looooon" + CR +
+                "             g" + CR +
+                "             descrip" + CR +
+                "             tion" + CR;
+        assertEquals(expected, sw.toString());
     }
 
-    public void testPrintHelpLongLines() throws ParseException, IOException {
+    @Test
+    public void testPrintHelpLongLines() {
         // Constants used for options
         final String OPT = "-";
 
@@ -228,17 +248,76 @@ public class BugCLI162Test extends TestCase {
                 "Converts the JDBC file in the first argument to an SMFD file specified in the second argument.");
         option.setArgs(2);
         commandLineOptions.addOption(option);
-        new HelpFormatter().printHelp(this.getClass().getName(), commandLineOptions);
+
+        formatter.printHelp(new PrintWriter(sw), HelpFormatter.DEFAULT_WIDTH, this.getClass().getName(), null, commandLineOptions, HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_DESC_PAD, null);
+        String expected = "usage: org.apache.commons.cli.bug.BugCLI162Test" + CR +
+                " -2,--jdbc2sfmd <arg>        Converts the JDBC file in the first argument" + CR +
+                "                             to an SMFD file specified in the second" + CR +
+                "                             argument." + CR +
+                " -a,--paramNames <arg>       Parameter XML names; default names are" + CR +
+                "                             param1, param2, etc. Example: -a \"pname1" + CR +
+                "                             pname2\"" + CR +
+                " -b,--jdbc <arg>             Writes a JDBC binding node file for the given" + CR +
+                "                             SQL" + CR +
+                " -c,--url <arg>              Connection URL" + CR +
+                " -d,--driver <arg>           JDBC driver class name" + CR +
+                " -e,--description <arg>      SFMD description. A default description is" + CR +
+                "                             used if omited. Example: -e \"Runs such and" + CR +
+                "                             such\"" + CR +
+                " -f,--sfmd <arg>             Writes a SFMD file for the given SQL" + CR +
+                " -g,--printTiming            Prints timing information" + CR +
+                " -h,--help                   Prints help and quits" + CR +
+                " -i,--interactive            Runs in interactive mode, reading and writing" + CR +
+                "                             from the console, 'go' or '/' sends a" + CR +
+                "                             statement" + CR +
+                " -j,--node <arg>             Writes a JDBC node file for the given SQL" + CR +
+                "                             (internal debugging)" + CR +
+                " -l,--columnNames <arg>      Column XML names; default names column" + CR +
+                "                             labels. Example: -l \"cname1 cname2\"" + CR +
+                " -m,--printMetaData          Prints metadata information" + CR +
+                " -n,--info                   Prints driver information and properties. If" + CR +
+                "                             -c is not specified, all drivers on the" + CR +
+                "                             classpath are displayed." + CR +
+                " -o,--paramModes <arg>       Parameters modes (1=IN, 2=INOUT, 4=OUT," + CR +
+                "                             0=Unknown). -o and -O are mutually exclusive." + CR +
+                "                             Example for 2 parameters, OUT and IN: -o \"4" + CR +
+                "                             1\"" + CR +
+                " -O,--paramModeNames <arg>   Parameters mode names (IN, INOUT, OUT," + CR +
+                "                             Unknown). -o and -O are mutually exclusive." + CR +
+                "                             Example for 2 parameters, OUT and IN: -O \"OUT" + CR +
+                "                             IN\"" + CR +
+                " -p,--password <arg>         The database password for the user specified" + CR +
+                "                             with the -u option. You can obfuscate the" + CR +
+                "                             password with" + CR +
+                "                             org.mortbay.jetty.security.Password, see" + CR +
+                "                             http://docs.codehaus.org/display/JETTY/Securi" + CR +
+                "                             ng+Passwords" + CR +
+                " -s,--sql <arg>              Runs SQL or {call stored_procedure(?, ?)} or" + CR +
+                "                             {?=call function(?, ?)}" + CR +
+                " -t,--printStack             Prints stack traces on errors" + CR +
+                "    --trim <arg>             Trims leading and trailing spaces from all" + CR +
+                "                             column values. Column XML names can be" + CR +
+                "                             optionally specified to set which columns to" + CR +
+                "                             trim." + CR +
+                " -u,--user <arg>             A database user name" + CR +
+                " -w,--outfile <arg>          Writes the SQL output to the given file" + CR +
+                " -y,--paramTypes <arg>       Parameter types from java.sql.Types. -y and" + CR +
+                "                             -Y are mutually exclusive. Example: -y \"-10" + CR +
+                "                             12\"" + CR +
+                " -Y,--paramTypeNames <arg>   Parameter java.sql.Types names. -y and -Y are" + CR +
+                "                             mutually exclusive. Example: -Y \"CURSOR" + CR +
+                "                             VARCHAR\"" + CR;
+        assertEquals(expected, sw.toString());
     }
 
-    public void testLongLineChunking() throws ParseException, IOException {
+    @Test
+    public void testLongLineChunking() {
         Options options = new Options();
         options.addOption("x", "extralongarg", false,
                                      "This description has ReallyLongValuesThatAreLongerThanTheWidthOfTheColumns " +
                                      "and also other ReallyLongValuesThatAreHugerAndBiggerThanTheWidthOfTheColumnsBob, " +
                                      "yes. ");
-        HelpFormatter formatter = new HelpFormatter();
-        StringWriter sw = new StringWriter();
+        
         formatter.printHelp(new PrintWriter(sw), 35, this.getClass().getName(), "Header", options, 0, 5, "Footer");
         String expected = "usage:" + CR +
                           "       org.apache.commons.cli.bug.B" + CR +
@@ -263,13 +342,12 @@ public class BugCLI162Test extends TestCase {
         assertEquals( "Long arguments did not split as expected", expected, sw.toString() );
     }
 
-    public void testLongLineChunkingIndentIgnored() throws ParseException, IOException {
+    @Test
+    public void testLongLineChunkingIndentIgnored() {
         Options options = new Options();
         options.addOption("x", "extralongarg", false, "This description is Long." );
-        HelpFormatter formatter = new HelpFormatter();
-        StringWriter sw = new StringWriter();
+
         formatter.printHelp(new PrintWriter(sw), 22, this.getClass().getName(), "Header", options, 0, 5, "Footer");
-        System.err.println(sw.toString());
         String expected = "usage:" + CR +
                           "       org.apache.comm" + CR +
                           "       ons.cli.bug.Bug" + CR +
diff --git a/src/test/org/apache/commons/cli/bug/BugCLI18Test.java b/src/test/java/org/apache/commons/cli/bug/BugCLI18Test.java
similarity index 96%
rename from src/test/org/apache/commons/cli/bug/BugCLI18Test.java
rename to src/test/java/org/apache/commons/cli/bug/BugCLI18Test.java
index 7a04698..3d4eb88 100644
--- a/src/test/org/apache/commons/cli/bug/BugCLI18Test.java
+++ b/src/test/java/org/apache/commons/cli/bug/BugCLI18Test.java
@@ -23,14 +23,14 @@ import java.io.StringWriter;
 import org.apache.commons.cli.HelpFormatter;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
-
-import junit.framework.TestCase;
+import org.junit.Test;
 
 /**
  * http://issues.apache.org/jira/browse/CLI-18
  */
-public class BugCLI18Test extends TestCase
+public class BugCLI18Test
 {
+    @Test
     public void testCLI18()
     {
         Options options = new Options();
diff --git a/src/test/org/apache/commons/cli/bug/BugCLI133Test.java b/src/test/java/org/apache/commons/cli/bug/BugCLI252Test.java
similarity index 50%
rename from src/test/org/apache/commons/cli/bug/BugCLI133Test.java
rename to src/test/java/org/apache/commons/cli/bug/BugCLI252Test.java
index 42d13c1..4631085 100644
--- a/src/test/org/apache/commons/cli/bug/BugCLI133Test.java
+++ b/src/test/java/org/apache/commons/cli/bug/BugCLI252Test.java
@@ -1,4 +1,4 @@
-/**
+/*
  * 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.
@@ -6,7 +6,7 @@
  * (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
+ *      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,
@@ -17,24 +17,26 @@
 
 package org.apache.commons.cli.bug;
 
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.PosixParser;
+import org.apache.commons.cli.*;
+import org.junit.Test;
 
-import junit.framework.TestCase;
+public class BugCLI252Test extends DefaultParserTest {
 
-/**
- * @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));
+    @Test
+    public void testExactOptionNameMatch() throws ParseException {
+        new DefaultParser().parse(getOptions(), new String[]{"--prefix"});
+    }
+
+    @Test(expected = AmbiguousOptionException.class)
+    public void testAmbiquousOptionName() throws ParseException {
+        new DefaultParser().parse(getOptions(), new String[]{"--pref"});
     }
+
+    private Options getOptions() {
+        Options options = new Options();
+        options.addOption(Option.builder().longOpt("prefix").build());
+        options.addOption(Option.builder().longOpt("prefixplusplus").build());
+        return options;
+    }
+
 }
diff --git a/src/test/org/apache/commons/cli/bug/BugCLI71Test.java b/src/test/java/org/apache/commons/cli/bug/BugCLI71Test.java
similarity index 88%
rename from src/test/org/apache/commons/cli/bug/BugCLI71Test.java
rename to src/test/java/org/apache/commons/cli/bug/BugCLI71Test.java
index c0d8ec1..41ef600 100644
--- a/src/test/org/apache/commons/cli/bug/BugCLI71Test.java
+++ b/src/test/java/org/apache/commons/cli/bug/BugCLI71Test.java
@@ -15,23 +15,27 @@
  * limitations under the License.
  */
 
-
 package org.apache.commons.cli.bug;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.CommandLineParser;
 import org.apache.commons.cli.MissingArgumentException;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.PosixParser;
+import org.junit.Before;
+import org.junit.Test;
 
-import junit.framework.TestCase;
-
-public class BugCLI71Test extends TestCase {
-
+ at SuppressWarnings("deprecation") // tests some deprecated classes
+public class BugCLI71Test
+{
     private Options options;
     private CommandLineParser parser;
 
+    @Before
     public void setUp() {
         options = new Options();
 
@@ -46,6 +50,7 @@ public class BugCLI71Test extends TestCase {
         parser = new PosixParser();
     }
 
+    @Test
     public void testBasic() throws Exception {
         String[] args = new String[] { "-a", "Caesar", "-k", "A" };
         CommandLine line = parser.parse( options, args);
@@ -53,6 +58,7 @@ public class BugCLI71Test extends TestCase {
         assertEquals( "A", line.getOptionValue("k") );
     }
 
+    @Test
     public void testMistakenArgument() throws Exception {
         String[] args = new String[] { "-a", "Caesar", "-k", "A" };
         CommandLine line = parser.parse( options, args);
@@ -62,23 +68,25 @@ public class BugCLI71Test extends TestCase {
         assertEquals( "a", line.getOptionValue("k") );
     }
 
+    @Test
     public void testLackOfError() throws Exception {
         String[] args = new String[] { "-k", "-a",  "Caesar" };
         try {
-            CommandLine line = parser.parse( options, args);
+            parser.parse( options, args);
             fail("MissingArgumentException expected");
         } catch(MissingArgumentException e) {
             assertEquals("option missing an argument", "k", e.getOption().getOpt());
         }
     }
 
+    @Test
     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") );
+        assertEquals( "a", line.getOptionValue('k', "a") );
     }
 
 }
diff --git a/src/test/org/apache/commons/cli/BugsTest.java b/src/test/java/org/apache/commons/cli/bug/BugsTest.java
similarity index 87%
rename from src/test/org/apache/commons/cli/BugsTest.java
rename to src/test/java/org/apache/commons/cli/bug/BugsTest.java
index b246368..322fa74 100644
--- a/src/test/org/apache/commons/cli/BugsTest.java
+++ b/src/test/java/org/apache/commons/cli/bug/BugsTest.java
@@ -15,19 +15,36 @@
  * limitations under the License.
  */
 
-package org.apache.commons.cli;
+package org.apache.commons.cli.bug;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.util.Iterator;
 import java.util.Properties;
 
-import junit.framework.TestCase;
-
-public class BugsTest extends TestCase
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.MissingArgumentException;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.Parser;
+import org.apache.commons.cli.PosixParser;
+import org.junit.Test;
+
+ at SuppressWarnings("deprecation") // tests some deprecated classes
+public class BugsTest
 {
+    @Test
     public void test11457() throws Exception
     {
         Options options = new Options();
@@ -40,6 +57,7 @@ public class BugsTest extends TestCase
         assertTrue(cmd.hasOption("verbose"));
     }
 
+    @Test
     public void test11458() throws Exception
     {
         Options options = new Options();
@@ -62,10 +80,10 @@ public class BugsTest extends TestCase
         assertEquals(values[1], "file2");
         assertEquals(values[2], "file3");
 
-        Iterator iter = cmd.iterator();
+        Iterator<Option> iter = cmd.iterator();
         while (iter.hasNext())
         {
-            Option opt = (Option) iter.next();
+            Option opt = iter.next();
             switch (opt.getId())
             {
                 case 'D':
@@ -83,6 +101,7 @@ public class BugsTest extends TestCase
         }
     }
 
+    @Test
     public void test11680() throws Exception
     {
         Options options = new Options();
@@ -98,6 +117,7 @@ public class BugsTest extends TestCase
         cmd.getOptionValue("m", "default m");
     }
 
+    @Test
     public void test11456() throws Exception
     {
         // Posix 
@@ -123,6 +143,7 @@ public class BugsTest extends TestCase
         assertEquals( cmd.getOptionValue( 'b' ), "value" );
     }
 
+    @Test
     public void test12210() throws Exception
     {
         // create the main options object which will handle the first parameter
@@ -179,6 +200,7 @@ public class BugsTest extends TestCase
         }
     }
 
+    @Test
     public void test13425() throws Exception
     {
         Options options = new Options();
@@ -202,19 +224,14 @@ public class BugsTest extends TestCase
 
         Parser parser = new PosixParser();
 
-        try
-        {
+        try {
             parser.parse( options, args );
+            fail( "MissingArgumentException not caught." );
+        } catch( MissingArgumentException expected ) {
         }
-        // catch the exception and leave the method
-        catch( Exception exp )
-        {
-            assertTrue( exp != null );
-            return;
-        }
-        fail( "MissingArgumentException not caught." );
     }
 
+    @Test
     public void test13666() throws Exception
     {
         Options options = new Options();
@@ -245,6 +262,7 @@ public class BugsTest extends TestCase
         }
     }
 
+    @Test
     public void test13935() throws Exception
     {
         OptionGroup directions = new OptionGroup();
@@ -264,64 +282,34 @@ public class BugsTest extends TestCase
         opts.addOption( straight );
 
         CommandLineParser parser = new PosixParser();
-        boolean exception = false;
 
         String[] args = new String[] {  };
-        try
-        {
-            CommandLine line = parser.parse(opts, args);
-        }
-        catch (ParseException exp)
-        {
-            exception = true;
+        try {
+            parser.parse(opts, args);
+            fail("Expected ParseException");
         }
-
-        if (!exception)
-        {
-            fail("Expected exception not caught.");
+        catch (ParseException expected) {
         }
 
-        exception = false;
-
         args = new String[] { "-s" };
-        try
-        {
-            CommandLine line = parser.parse(opts, args);
-        }
-        catch (ParseException exp)
-        {
-            exception = true;
+        try {
+            parser.parse(opts, args);
+            fail("Expected ParseException");
         }
-
-        if (!exception)
-        {
-            fail("Expected exception not caught.");
+        catch (ParseException expected) {
         }
 
-        exception = false;
-
         args = new String[] { "-s", "-l" };
-        try
-        {
-            parser.parse(opts, args);
-        }
-        catch (ParseException exp)
-        {
-            fail("Unexpected exception: " + exp.getClass().getName() + ":" + exp.getMessage());
-        }
+        CommandLine line = parser.parse(opts, args);
+        assertNotNull(line);
 
         opts.addOption( forward );
         args = new String[] { "-s", "-l", "-f" };
-        try
-        {
-            parser.parse(opts, args);
-        }
-        catch (ParseException exp)
-        {
-            fail("Unexpected exception: " + exp.getClass().getName() + ":" + exp.getMessage());
-        }
+        line = parser.parse(opts, args);
+        assertNotNull(line);
     }
 
+    @Test
     public void test14786() throws Exception
     {
         Option o = OptionBuilder.isRequired().withDescription("test").create("test");
@@ -337,6 +325,7 @@ public class BugsTest extends TestCase
         assertTrue( line.hasOption( "test" ) );
     }
 
+    @Test
     public void test15046() throws Exception
     {
         CommandLineParser parser = new PosixParser();
@@ -354,6 +343,7 @@ public class BugsTest extends TestCase
         assertTrue( !line.hasOption("c") );
     }
 
+    @Test
     public void test15648() throws Exception
     {
         CommandLineParser parser = new PosixParser();
@@ -365,6 +355,7 @@ public class BugsTest extends TestCase
         assertEquals( "Two Words", line.getOptionValue( "m" ) );
     }
     
+    @Test
     public void test31148() throws ParseException
     {
         Option multiArgOption = new Option("o","option with multiple args");
diff --git a/src/test/org/apache/commons/cli/BasicParserTest.java b/src/test/org/apache/commons/cli/BasicParserTest.java
deleted file mode 100644
index 32db57e..0000000
--- a/src/test/org/apache/commons/cli/BasicParserTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * 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;
-
-/**
- * @author Emmanuel Bourg
- * @version $Revision: 695410 $, $Date: 2008-09-15 03:25:38 -0700 (Mon, 15 Sep 2008) $
- */
-public class BasicParserTest extends ParserTestCase
-{
-    public void setUp()
-    {
-        super.setUp();
-        parser = new BasicParser();
-    }
-
-    public void testPropertiesOption() throws Exception
-    {
-        // not supported by the BasicParser
-    }
-
-    public void testShortWithEqual() throws Exception
-    {
-        // not supported by the BasicParser
-    }
-
-    public void testShortWithoutEqual() throws Exception
-    {
-        // not supported by the BasicParser
-    }
-
-    public void testLongWithEqual() throws Exception
-    {
-        // not supported by the BasicParser
-    }
-
-    public void testLongWithEqualSingleDash() throws Exception
-    {
-        // not supported by the BasicParser
-    }
-}
diff --git a/src/test/org/apache/commons/cli/OptionTest.java b/src/test/org/apache/commons/cli/OptionTest.java
deleted file mode 100644
index d7b069b..0000000
--- a/src/test/org/apache/commons/cli/OptionTest.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * 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());
-    }
-
-    public void testHasArgName()
-    {
-        Option option = new Option("f", null);
-
-        option.setArgName(null);
-        assertFalse(option.hasArgName());
-
-        option.setArgName("");
-        assertFalse(option.hasArgName());
-
-        option.setArgName("file");
-        assertTrue(option.hasArgName());
-    }
-
-    public void testHasArgs()
-    {
-        Option option = new Option("f", null);
-
-        option.setArgs(0);
-        assertFalse(option.hasArgs());
-
-        option.setArgs(1);
-        assertFalse(option.hasArgs());
-
-        option.setArgs(10);
-        assertTrue(option.hasArgs());
-
-        option.setArgs(Option.UNLIMITED_VALUES);
-        assertTrue(option.hasArgs());
-
-        option.setArgs(Option.UNINITIALIZED);
-        assertFalse(option.hasArgs());
-    }
-
-    public void testGetValue()
-    {
-        Option option = new Option("f", null);
-        option.setArgs(Option.UNLIMITED_VALUES);
-
-        assertEquals("default", option.getValue("default"));
-        assertEquals(null, option.getValue(0));
-
-        option.addValueForProcessing("foo");
-        
-        assertEquals("foo", option.getValue());
-        assertEquals("foo", option.getValue(0));
-        assertEquals("foo", option.getValue("default"));
-    }
-}
diff --git a/src/test/org/apache/commons/cli/ParseRequiredTest.java b/src/test/org/apache/commons/cli/ParseRequiredTest.java
deleted file mode 100644
index 7f4d0ee..0000000
--- a/src/test/org/apache/commons/cli/ParseRequiredTest.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
- * 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 John Keyes (john at integralsource.com)
- * @version $Revision: 678662 $
- */
-public class ParseRequiredTest extends TestCase
-{
-    private Options _options = null;
-    private CommandLineParser parser = new PosixParser();
-
-    public void setUp()
-    {
-        _options = new Options()
-            .addOption("a",
-                       "enable-a",
-                       false,
-                       "turn [a] on or off")
-            .addOption( OptionBuilder.withLongOpt( "bfile" )
-                                     .hasArg()
-                                     .isRequired()
-                                     .withDescription( "set the value of [b]" )
-                                     .create( 'b' ) );
-    }
-
-    public void testWithRequiredOption() throws Exception
-    {
-        String[] args = new String[] {  "-b", "file" };
-
-        CommandLine cl = parser.parse(_options,args);
-
-        assertTrue( "Confirm -a is NOT set", !cl.hasOption("a") );
-        assertTrue( "Confirm -b is set", cl.hasOption("b") );
-        assertTrue( "Confirm arg of -b", cl.getOptionValue("b").equals("file") );
-        assertTrue( "Confirm NO of extra args", cl.getArgList().size() == 0);
-    }
-
-    public void testOptionAndRequiredOption() throws Exception
-    {
-        String[] args = new String[] {  "-a", "-b", "file" };
-
-        CommandLine cl = parser.parse(_options,args);
-
-        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("file") );
-        assertTrue( "Confirm NO of extra args", cl.getArgList().size() == 0);
-    }
-
-    public void testMissingRequiredOption()
-    {
-        String[] args = new String[] { "-a" };
-
-        try
-        {
-            CommandLine cl = parser.parse(_options,args);
-            fail( "exception should have been thrown" );
-        }
-        catch (MissingOptionException e)
-        {
-            assertEquals( "Incorrect exception message", "Missing required option: b", e.getMessage() );
-            assertTrue(e.getMissingOptions().contains("b"));
-        }
-        catch (ParseException e)
-        {
-            fail( "expected to catch MissingOptionException" );
-        }
-    }
-
-    public void testMissingRequiredOptions()
-    {
-        String[] args = new String[] { "-a" };
-
-        _options.addOption( OptionBuilder.withLongOpt( "cfile" )
-                                     .hasArg()
-                                     .isRequired()
-                                     .withDescription( "set the value of [c]" )
-                                     .create( 'c' ) );
-
-        try
-        {
-            CommandLine cl = parser.parse(_options,args);
-            fail( "exception should have been thrown" );
-        }
-        catch (MissingOptionException e)
-        {
-            assertEquals( "Incorrect exception message", "Missing required options: b, c", e.getMessage() );
-            assertTrue(e.getMissingOptions().contains("b"));
-            assertTrue(e.getMissingOptions().contains("c"));
-        }
-        catch (ParseException e)
-        {
-            fail( "expected to catch MissingOptionException" );
-        }
-    }
-
-    public void testReuseOptionsTwice() throws Exception
-    {
-        Options opts = new Options();
-		opts.addOption(OptionBuilder.isRequired().create('v'));
-
-		GnuParser parser = new GnuParser();
-
-        // first parsing
-        parser.parse(opts, new String[] { "-v" });
-
-        try
-        {
-            // second parsing, with the same Options instance and an invalid command line
-            parser.parse(opts, new String[0]);
-            fail("MissingOptionException not thrown");
-        }
-        catch (MissingOptionException e)
-        {
-            // expected
-        }
-    }
-
-}
diff --git a/src/test/org/apache/commons/cli/ParserTestCase.java b/src/test/org/apache/commons/cli/ParserTestCase.java
deleted file mode 100644
index ad83e3f..0000000
--- a/src/test/org/apache/commons/cli/ParserTestCase.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/**
- * 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.Arrays;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-/**
- * Abstract test case testing common parser features.
- *
- * @author Emmanuel Bourg
- * @version $Revision: 695672 $, $Date: 2008-09-15 15:19:11 -0700 (Mon, 15 Sep 2008) $
- */
-public abstract class ParserTestCase extends TestCase
-{
-    protected Parser parser;
-
-    protected Options options;
-
-    public void setUp()
-    {
-        options = new Options()
-            .addOption("a", "enable-a", false, "turn [a] on or off")
-            .addOption("b", "bfile", true, "set the value of [b]")
-            .addOption("c", "copt", false, "turn [c] on or off");
-    }
-
-    public void testSimpleShort() throws Exception
-    {
-        String[] args = new String[] { "-a",
-                                       "-b", "toast",
-                                       "foo", "bar" };
-
-        CommandLine cl = parser.parse(options, args);
-
-        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 size of extra args", cl.getArgList().size() == 2);
-    }
-
-    public void testSimpleLong() throws Exception
-    {
-        String[] args = new String[] { "--enable-a",
-                                       "--bfile", "toast",
-                                       "foo", "bar" };
-
-        CommandLine cl = parser.parse(options, args);
-
-        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);
-    }
-
-    public void testMultiple() throws Exception
-    {
-        String[] args = new String[] { "-c",
-                                       "foobar",
-                                       "-b", "toast" };
-
-        CommandLine cl = parser.parse(options, args, true);
-        assertTrue("Confirm -c is set", cl.hasOption("c"));
-        assertTrue("Confirm  3 extra args: " + cl.getArgList().size(), cl.getArgList().size() == 3);
-
-        cl = parser.parse(options, cl.getArgs());
-
-        assertTrue("Confirm -c is not set", !cl.hasOption("c"));
-        assertTrue("Confirm -b is set", cl.hasOption("b"));
-        assertTrue("Confirm arg of -b", cl.getOptionValue("b").equals("toast"));
-        assertTrue("Confirm  1 extra arg: " + cl.getArgList().size(), cl.getArgList().size() == 1);
-        assertTrue("Confirm  value of extra arg: " + cl.getArgList().get(0), cl.getArgList().get(0).equals("foobar"));
-    }
-
-    public void testMultipleWithLong() throws Exception
-    {
-        String[] args = new String[] { "--copt",
-                                       "foobar",
-                                       "--bfile", "toast" };
-
-        CommandLine cl = parser.parse(options, args, true);
-        assertTrue("Confirm -c is set", cl.hasOption("c"));
-        assertTrue("Confirm  3 extra args: " + cl.getArgList().size(), cl.getArgList().size() == 3);
-
-        cl = parser.parse(options, cl.getArgs());
-
-        assertTrue("Confirm -c is not set", !cl.hasOption("c"));
-        assertTrue("Confirm -b is set", cl.hasOption("b"));
-        assertTrue("Confirm arg of -b", cl.getOptionValue("b").equals("toast"));
-        assertTrue("Confirm  1 extra arg: " + cl.getArgList().size(), cl.getArgList().size() == 1);
-        assertTrue("Confirm  value of extra arg: " + cl.getArgList().get(0), cl.getArgList().get(0).equals("foobar"));
-    }
-
-    public void testUnrecognizedOption() throws Exception
-    {
-        String[] args = new String[] { "-a", "-d", "-b", "toast", "foo", "bar" };
-
-        try
-        {
-            parser.parse(options, args);
-            fail("UnrecognizedOptionException wasn't thrown");
-        }
-        catch (UnrecognizedOptionException e)
-        {
-            assertEquals("-d", e.getOption());
-        }
-    }    
-
-    public void testMissingArg() throws Exception
-    {
-        String[] args = new String[] { "-b" };
-
-        boolean caught = false;
-
-        try
-        {
-            parser.parse(options, args);
-        }
-        catch (MissingArgumentException e)
-        {
-            caught = true;
-            assertEquals("option missing an argument", "b", e.getOption().getOpt());
-        }
-
-        assertTrue( "Confirm MissingArgumentException caught", caught );
-    }
-
-    public void testDoubleDash() throws Exception
-    {
-        String[] args = new String[] { "--copt",
-                                       "--",
-                                       "-b", "toast" };
-
-        CommandLine cl = parser.parse(options, args);
-
-        assertTrue("Confirm -c is set", cl.hasOption("c"));
-        assertTrue("Confirm -b is not set", !cl.hasOption("b"));
-        assertTrue("Confirm 2 extra args: " + cl.getArgList().size(), cl.getArgList().size() == 2);
-    }
-
-    public void testSingleDash() throws Exception
-    {
-        String[] args = new String[] { "--copt",
-                                       "-b", "-",
-                                       "-a",
-                                       "-" };
-
-        CommandLine cl = parser.parse(options, args);
-
-        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("-"));
-        assertTrue("Confirm 1 extra arg: " + cl.getArgList().size(), cl.getArgList().size() == 1);
-        assertTrue("Confirm value of extra arg: " + cl.getArgList().get(0), cl.getArgList().get(0).equals("-"));
-    }
-
-    public void testStopAtUnexpectedArg() throws Exception
-    {
-        String[] args = new String[] { "-c",
-                                       "foober",
-                                       "-b",
-                                       "toast" };
-
-        CommandLine cl = parser.parse(options, args, true);
-        assertTrue("Confirm -c is set", cl.hasOption("c"));
-        assertTrue("Confirm  3 extra args: " + cl.getArgList().size(), cl.getArgList().size() == 3);
-    }
-
-   public void testStopAtExpectedArg() throws Exception
-    {
-        String[] args = new String[]{"-b", "foo"};
-
-        CommandLine cl = parser.parse(options, args, true);
-
-        assertTrue("Confirm -b is set", cl.hasOption('b'));
-        assertEquals("Confirm -b is set", "foo", cl.getOptionValue('b'));
-        assertTrue("Confirm no extra args: " + cl.getArgList().size(), cl.getArgList().size() == 0);
-    }
-
-    public void testStopAtNonOptionShort() throws Exception
-    {
-        String[] args = new String[]{"-z",
-                                     "-a",
-                                     "-btoast"};
-
-        CommandLine cl = parser.parse(options, args, true);
-        assertFalse("Confirm -a is not set", cl.hasOption("a"));
-        assertTrue("Confirm  3 extra args: " + cl.getArgList().size(), cl.getArgList().size() == 3);
-    }
-
-    public void testStopAtNonOptionLong() throws Exception
-    {
-        String[] args = new String[]{"--zop==1",
-                                     "-abtoast",
-                                     "--b=bar"};
-
-        CommandLine cl = parser.parse(options, args, true);
-
-        assertFalse("Confirm -a is not set", cl.hasOption("a"));
-        assertFalse("Confirm -b is not set", cl.hasOption("b"));
-        assertTrue("Confirm  3 extra args: " + cl.getArgList().size(), cl.getArgList().size() == 3);
-    }
-
-    public void testNegativeArgument() throws Exception
-    {
-        String[] args = new String[] { "-b", "-1"} ;
-
-        CommandLine cl = parser.parse(options, args);
-        assertEquals("-1", cl.getOptionValue("b"));
-    }
-
-    public void testArgumentStartingWithHyphen() throws Exception
-    {
-        String[] args = new String[]{"-b", "-foo"};
-
-        CommandLine cl = parser.parse(options, args);
-        assertEquals("-foo", cl.getOptionValue("b"));
-    }
-
-    public void testShortWithEqual() throws Exception
-    {
-        String[] args = new String[] { "-f=bar" };
-
-        Options options = new Options();
-        options.addOption(OptionBuilder.withLongOpt("foo").hasArg().create('f'));
-
-        CommandLine cl = parser.parse(options, args);
-
-        assertEquals("bar", cl.getOptionValue("foo"));
-    }
-
-    public void testShortWithoutEqual() throws Exception
-    {
-        String[] args = new String[] { "-fbar" };
-
-        Options options = new Options();
-        options.addOption(OptionBuilder.withLongOpt("foo").hasArg().create('f'));
-
-        CommandLine cl = parser.parse(options, args);
-
-        assertEquals("bar", cl.getOptionValue("foo"));
-    }
-
-    public void testLongWithEqual() throws Exception
-    {
-        String[] args = new String[] { "--foo=bar" };
-
-        Options options = new Options();
-        options.addOption(OptionBuilder.withLongOpt("foo").hasArg().create('f'));
-
-        CommandLine cl = parser.parse(options, args);
-
-        assertEquals("bar", cl.getOptionValue("foo"));
-    }
-
-    public void testLongWithEqualSingleDash() throws Exception
-    {
-        String[] args = new String[] { "-foo=bar" };
-
-        Options options = new Options();
-        options.addOption(OptionBuilder.withLongOpt("foo").hasArg().create('f'));
-
-        CommandLine cl = parser.parse(options, args);
-
-        assertEquals("bar", cl.getOptionValue("foo"));
-    }
-
-    public void testPropertiesOption() throws Exception
-    {
-        String[] args = new String[] { "-Jsource=1.5", "-J", "target", "1.5", "foo" };
-
-        Options options = new Options();
-        options.addOption(OptionBuilder.withValueSeparator().hasArgs(2).create('J'));
-
-        CommandLine cl = parser.parse(options, args);
-
-        List values = Arrays.asList(cl.getOptionValues("J"));
-        assertNotNull("null values", values);
-        assertEquals("number of values", 4, values.size());
-        assertEquals("value 1", "source", values.get(0));
-        assertEquals("value 2", "1.5", values.get(1));
-        assertEquals("value 3", "target", values.get(2));
-        assertEquals("value 4", "1.5", values.get(3));
-        List argsleft = cl.getArgList();
-        assertEquals("Should be 1 arg left",1,argsleft.size());
-        assertEquals("Expecting foo","foo",argsleft.get(0));
-    }
-}
diff --git a/src/test/org/apache/commons/cli/PosixParserTest.java b/src/test/org/apache/commons/cli/PosixParserTest.java
deleted file mode 100644
index be63f5d..0000000
--- a/src/test/org/apache/commons/cli/PosixParserTest.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/**
- * 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;
-
-/**
- * Test case for the PosixParser.
- *
- * @version $Revision: 695410 $, $Date: 2008-09-15 03:25:38 -0700 (Mon, 15 Sep 2008) $
- */
-public class PosixParserTest extends ParserTestCase
-{
-    public void setUp()
-    {
-        super.setUp();
-        parser = new PosixParser();
-    }
-
-    public void testBursting() throws Exception
-    {
-        String[] args = new String[] { "-acbtoast",
-                                       "foo", "bar" };
-
-        CommandLine cl = parser.parse(options, args);
-
-        assertTrue( "Confirm -a is set", cl.hasOption("a") );
-        assertTrue( "Confirm -b is set", cl.hasOption("b") );
-        assertTrue( "Confirm -c is set", cl.hasOption("c") );
-        assertTrue( "Confirm arg of -b", cl.getOptionValue("b").equals("toast") );
-        assertTrue( "Confirm size of extra args", cl.getArgList().size() == 2);
-    }
-
-    public void testUnrecognizedOptionWithBursting() throws Exception
-    {
-        String[] args = new String[] { "-adbtoast", "foo", "bar" };
-
-        try
-        {
-            parser.parse(options, args);
-            fail("UnrecognizedOptionException wasn't thrown");
-        }
-        catch (UnrecognizedOptionException e)
-        {
-            assertEquals("-adbtoast", e.getOption());
-        }
-    }
-
-    public void testMissingArgWithBursting() throws Exception
-    {
-        String[] args = new String[] { "-acb" };
-
-        boolean caught = false;
-
-        try
-        {
-            parser.parse(options, args);
-        }
-        catch (MissingArgumentException e)
-        {
-            caught = true;
-            assertEquals("option missing an argument", "b", e.getOption().getOpt());
-        }
-
-        assertTrue( "Confirm MissingArgumentException caught", caught );
-    }
-
-    public void testStopBursting() throws Exception
-    {
-        String[] args = new String[] { "-azc" };
-
-        CommandLine cl = parser.parse(options, args, true);
-        assertTrue( "Confirm -a is set", cl.hasOption("a") );
-        assertFalse( "Confirm -c is not set", cl.hasOption("c") );
-
-        assertTrue( "Confirm  1 extra arg: " + cl.getArgList().size(), cl.getArgList().size() == 1);
-        assertTrue(cl.getArgList().contains("zc"));
-    }
-
-    public void testStopBursting2() throws Exception
-    {
-        String[] args = new String[] { "-c",
-                                       "foobar",
-                                       "-btoast" };
-
-        CommandLine cl = parser.parse(options, args, true);
-        assertTrue("Confirm -c is set", cl.hasOption("c"));
-        assertTrue("Confirm  2 extra args: " + cl.getArgList().size(), cl.getArgList().size() == 2);
-
-        cl = parser.parse(options, cl.getArgs());
-
-        assertTrue("Confirm -c is not set", !cl.hasOption("c"));
-        assertTrue("Confirm -b is set", cl.hasOption("b"));
-        assertTrue("Confirm arg of -b", cl.getOptionValue("b").equals("toast"));
-        assertTrue("Confirm  1 extra arg: " + cl.getArgList().size(), cl.getArgList().size() == 1);
-        assertTrue("Confirm  value of extra arg: " + cl.getArgList().get(0), cl.getArgList().get(0).equals("foobar"));
-    }
-
-    /**
-     * Real world test with long and short options.
-     */
-    public void testLongOptionWithShort() throws Exception {
-        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 minutes")
-                                        .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"
-            };
-
-        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");
-    }
-
-    public void testLongWithEqualSingleDash() throws Exception
-    {
-        // not supported by the PosixParser
-    }
-
-    public void testShortWithEqual() throws Exception
-    {
-        // not supported by the PosixParser
-    }
-}

-- 
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