You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rp...@apache.org on 2018/03/21 11:07:47 UTC

[1/4] logging-log4j2 git commit: [BUILD] removed picocli tests from core tests; they do not add value here and occasionally fail when building Log4j on a console that supports ANSI colors

Repository: logging-log4j2
Updated Branches:
  refs/heads/release-2.x ec10b16ec -> dd8ded97a


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/dd8ded97/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/CustomLayoutDemo.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/CustomLayoutDemo.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/CustomLayoutDemo.java
deleted file mode 100644
index b0c505a..0000000
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/CustomLayoutDemo.java
+++ /dev/null
@@ -1,264 +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.logging.log4j.core.tools.picocli;
-
-import org.apache.logging.log4j.core.tools.picocli.CommandLine.Help.Ansi.Text;
-import org.apache.logging.log4j.core.tools.picocli.CommandLine.Help.Column;
-import org.apache.logging.log4j.core.tools.picocli.CommandLine.Help.IOptionRenderer;
-import org.apache.logging.log4j.core.tools.picocli.CommandLine.Help.IParameterRenderer;
-import org.apache.logging.log4j.core.tools.picocli.CommandLine.Help.Layout;
-import org.apache.logging.log4j.core.tools.picocli.CommandLine.Help.TextTable;
-
-import java.lang.reflect.Field;
-
-import static org.apache.logging.log4j.core.tools.picocli.CommandLine.*;
-import static org.apache.logging.log4j.core.tools.picocli.CommandLine.Help.Column.Overflow.SPAN;
-import static org.apache.logging.log4j.core.tools.picocli.CommandLine.Help.Column.Overflow.TRUNCATE;
-import static org.apache.logging.log4j.core.tools.picocli.CommandLine.Help.Column.Overflow.WRAP;
-
-/**
- * Demonstrates how the CommandLine.Help API can be used to create custom layouts for usage help messages.
- */
-@Command(name = "picocli.CustomLayoutDemo", description = "Demonstrates picocli custom layouts.",
-        footer = {
-        "Run with -Dpicocli.ansi=true  to force picocli to use ansi codes,",
-        "or  with -Dpicocli.ansi=false to force picocli to NOT use ansi codes.",
-        "By default picocli will use ansi codes if the platform supports it."
-        }
-)
-public class CustomLayoutDemo implements Runnable {
-    public static void main(String[] args) {
-        CommandLine.run(new CustomLayoutDemo(), System.err, args);
-    }
-
-    @Option(names = {"-z", "--zip"}, description = "Show usage help for a layout with 2 options per row.")
-    private boolean showZip;
-
-    @Option(names = {"-n", "--netstat"}, description = "Show usage help for a layout with a narrow options column and a wide description column. Descriptions that wrap to the next row are not indented.")
-    private boolean showNetstat;
-
-    @Override
-    public void run() {
-        if (!showZip && !showNetstat) {
-            CommandLine.usage(this, System.err);
-            return;
-        }
-        if (showZip)     { System.out.println(createZipUsageFormat(Help.Ansi.AUTO)); }
-        if (showNetstat) { System.out.println(createNetstatUsageFormat(Help.Ansi.AUTO)); }
-    }
-
-
-    public static String createZipUsageFormat(Help.Ansi ansi) {
-        @Command(description = {
-                "Copyright (c) 1990-2008 Info-ZIP - Type 'zip \"-L\"' for software license.",
-                "Zip 3.0 (July 5th 2008). Command:",
-                "@|bold zip|@ [@|yellow -options|@] [@|yellow -b|@ @|underline path|@] [@|yellow -t|@ @|underline mmddyyyy|@] [@|yellow -n|@ @|underline suffixes|@] [@|yellow zipfile|@ @|underline list|@] [@|yellow -xi|@ @|underline list|@]",
-                "  The default action is to add or replace zipfile entries from list, which",
-                "  can include the special name - to compress standard input.",
-                "  If @|yellow zipfile|@ and @|yellow list|@ are omitted, zip compresses stdin to stdout."}
-        )
-        class Zip {
-            @Option(names = "-f", description = "freshen: only changed files")
-            boolean freshen;
-            @Option(names = "-u", description = "update: only changed or new files")
-            boolean update;
-            @Option(names = "-d", description = "delete entries in zipfile")
-            boolean delete;
-            @Option(names = "-m", description = "move into zipfile (delete OS files)")
-            boolean move;
-            @Option(names = "-r", description = "recurse into directories")
-            boolean recurse;
-            @Option(names = "-j", description = "junk (don't record) directory names")
-            boolean junk;
-            @Option(names = "-0", description = "store only")
-            boolean store;
-            @Option(names = "-l", description = "convert LF to CR LF (@|yellow -ll|@ CR LF to LF)")
-            boolean lf2crlf;
-            @Option(names = "-1", description = "compress faster")
-            boolean faster;
-            @Option(names = "-9", description = "compress better")
-            boolean better;
-            @Option(names = "-q", description = "quiet operation")
-            boolean quiet;
-            @Option(names = "-v", description = "verbose operation/print version info")
-            boolean verbose;
-            @Option(names = "-c", description = "add one-line comments")
-            boolean comments;
-            @Option(names = "-z", description = "add zipfile comment")
-            boolean zipComment;
-            @Option(names = "-@", description = "read names from stdin")
-            boolean readFileList;
-            @Option(names = "-o", description = "make zipfile as old as latest entry")
-            boolean old;
-            @Option(names = "-x", description = "exclude the following names")
-            boolean exclude;
-            @Option(names = "-i", description = "include only the following names")
-            boolean include;
-            @Option(names = "-F", description = "fix zipfile (@|yellow -FF|@ try harder)")
-            boolean fix;
-            @Option(names = "-D", description = "do not add directory entries")
-            boolean directories;
-            @Option(names = "-A", description = "adjust self-extracting exe")
-            boolean adjust;
-            @Option(names = "-J", description = "junk zipfile prefix (unzipsfx)")
-            boolean junkPrefix;
-            @Option(names = "-T", description = "test zipfile integrity")
-            boolean test;
-            @Option(names = "-X", description = "eXclude eXtra file attributes")
-            boolean excludeAttribs;
-            @Option(names = "-y", description = "store symbolic links as the link instead of the referenced file")
-            boolean symbolic;
-            @Option(names = "-e", description = "encrypt")
-            boolean encrypt;
-            @Option(names = "-n", description = "don't compress these suffixes")
-            boolean dontCompress;
-            @Option(names = "-h2", description = "show more help")
-            boolean moreHelp;
-        }
-
-        class TwoOptionsPerRowLayout extends Layout { // define a custom layout
-            TextTable.Cell previous = new TextTable.Cell(0, 0);
-
-            private TwoOptionsPerRowLayout(Help.ColorScheme colorScheme, TextTable textTable,
-                                           IOptionRenderer optionRenderer,
-                                           IParameterRenderer parameterRenderer) {
-                super(colorScheme, textTable, optionRenderer, parameterRenderer);
-            }
-
-            @Override
-            public void layout(Field field, Text[][] values) {
-                Text[] columnValues = values[0]; // we know renderer creates a single row with two values
-
-                // We want to show two options on one row, next to each other,
-                // unless the first option spanned multiple columns (in which case there are not enough columns left)
-                int col = previous.column + 1;
-                if (col == 1 || col + columnValues.length > table.columns.length) { // if true, write into next row
-
-                    // table also adds an empty row if a text value spanned multiple columns
-                    if (table.rowCount() == 0 || table.rowCount() == previous.row + 1) { // avoid adding 2 empty rows
-                        table.addEmptyRow(); // create the slots to write the text values into
-                    }
-                    col = 0; // we are starting a new row, reset the column to write into
-                }
-                for (int i = 0; i < columnValues.length; i++) {
-                    // always write to the last row, column depends on what happened previously
-                    previous = table.putValue(table.rowCount() - 1, col + i, columnValues[i]);
-                }
-            }
-        }
-        TextTable textTable = new TextTable(ansi,
-                new Column(5, 2, TRUNCATE), // values should fit
-                new Column(30, 2, SPAN), // overflow into adjacent columns
-                new Column(4, 1, TRUNCATE), // values should fit again
-                new Column(39, 2, WRAP));
-        TwoOptionsPerRowLayout layout = new TwoOptionsPerRowLayout(
-                Help.defaultColorScheme(ansi),
-                textTable,
-                Help.createMinimalOptionRenderer(),
-                Help.createMinimalParameterRenderer());
-
-        Help help = new Help(new Zip(), ansi);
-        StringBuilder sb = new StringBuilder();
-        sb.append(help.description()); // show the first 6 lines, including copyright, description and usage
-
-        // Note that we don't sort the options, so they appear in the order the fields are declared in the Zip class.
-        layout.addOptions(help.optionFields, help.parameterLabelRenderer);
-        sb.append(layout); // finally, copy the options details help text into the StringBuilder
-
-        return sb.toString();
-    }
-
-    /** for Netstat test */
-    private enum Protocol {IP, IPv6, ICMP, ICMPv6, TCP, TCPv6, UDP, UDPv6}
-
-    public static String createNetstatUsageFormat(Help.Ansi ansi) {
-        @Command(name = "NETSTAT",
-                separator = " ",
-                abbreviateSynopsis = true,
-                header = "Displays protocol statistics and current TCP/IP network connections.%n")
-        class Netstat {
-            @Option(names="-a", description="Displays all connections and listening ports.")
-            boolean displayAll;
-            @Option(names="-b", description="Displays the executable involved in creating each connection or "
-                    + "listening port. In some cases well-known executables host "
-                    + "multiple independent components, and in these cases the "
-                    + "sequence of components involved in creating the connection "
-                    + "or listening port is displayed. In this case the executable "
-                    + "name is in [] at the bottom, on top is the component it called, "
-                    + "and so forth until TCP/IP was reached. Note that this option "
-                    + "can be time-consuming and will fail unless you have sufficient "
-                    + "permissions.")
-            boolean displayExecutable;
-            @Option(names="-e", description="Displays Ethernet statistics. This may be combined with the -s option.")
-            boolean displayEthernetStats;
-            @Option(names="-f", description="Displays Fully Qualified Domain Names (FQDN) for foreign addresses.")
-            boolean displayFQCN;
-            @Option(names="-n", description="Displays addresses and port numbers in numerical form.")
-            boolean displayNumerical;
-            @Option(names="-o", description="Displays the owning process ID associated with each connection.")
-            boolean displayOwningProcess;
-            @Option(names="-p", paramLabel = "proto",
-                    description="Shows connections for the protocol specified by proto; proto "
-                            + "may be any of: TCP, UDP, TCPv6, or UDPv6.  If used with the -s "
-                            + "option to display per-protocol statistics, proto may be any of: "
-                            + "IP, IPv6, ICMP, ICMPv6, TCP, TCPv6, UDP, or UDPv6.")
-            Protocol proto;
-            @Option(names="-q", description="Displays all connections, listening ports, and bound "
-                    + "nonlistening TCP ports. Bound nonlistening ports may or may not "
-                    + "be associated with an active connection.")
-            boolean query;
-            @Option(names="-r", description="Displays the routing table.")
-            boolean displayRoutingTable;
-            @Option(names="-s", description="Displays per-protocol statistics.  By default, statistics are "
-                    + "shown for IP, IPv6, ICMP, ICMPv6, TCP, TCPv6, UDP, and UDPv6; "
-                    + "the -p option may be used to specify a subset of the default.")
-            boolean displayStatistics;
-            @Option(names="-t", description="Displays the current connection offload state.")
-            boolean displayOffloadState;
-            @Option(names="-x", description="Displays NetworkDirect connections, listeners, and shared endpoints.")
-            boolean displayNetDirect;
-            @Option(names="-y", description="Displays the TCP connection template for all connections. "
-                    + "Cannot be combined with the other options.")
-            boolean displayTcpConnectionTemplate;
-            @Parameters(arity = "0..1", paramLabel = "interval", description = ""
-                    + "Redisplays selected statistics, pausing interval seconds "
-                    + "between each display.  Press CTRL+C to stop redisplaying "
-                    + "statistics.  If omitted, netstat will print the current "
-                    + "configuration information once.")
-            int interval;
-        }
-        StringBuilder sb = new StringBuilder();
-        Help help = new Help(new Netstat(), ansi);
-        help.synopsisHeading = "";
-        sb.append(help.header()).append(help.detailedSynopsis(0, null, false));
-        sb.append(System.getProperty("line.separator"));
-
-        TextTable textTable = new TextTable(ansi,
-                new Column(15, 2, TRUNCATE),
-                new Column(65, 1, WRAP));
-        textTable.indentWrappedLines = 0;
-        Layout layout = new Layout(
-                Help.defaultColorScheme(ansi),
-                textTable,
-                Help.createMinimalOptionRenderer(),
-                Help.createMinimalParameterRenderer());
-        layout.addOptions(help.optionFields, help.parameterLabelRenderer);
-        layout.addPositionalParameters(help.positionalParametersFields, Help.createMinimalParamLabelRenderer());
-        sb.append(layout);
-        return sb.toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/dd8ded97/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/Demo.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/Demo.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/Demo.java
deleted file mode 100644
index 084443f..0000000
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/Demo.java
+++ /dev/null
@@ -1,719 +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.logging.log4j.core.tools.picocli;
-
-import org.apache.logging.log4j.core.tools.picocli.CommandLine.Command;
-import org.apache.logging.log4j.core.tools.picocli.CommandLine.Option;
-import org.apache.logging.log4j.core.tools.picocli.CommandLine.Parameters;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Callable;
-
-/**
- * Demonstrates picocli subcommands.
- * <p>
- * Banner ascii art thanks to <a href="http://patorjk.com/software/taag/">http://patorjk.com/software/taag/</a>.
- * </p>
- */
-@Command(name = "picocli.Demo", sortOptions = false,
-        header = {
-                "@|green        .__                    .__  .__ |@",
-                "@|green ______ |__| ____  ____   ____ |  | |__||@",
-                "@|green \\____ \\|  |/ ___\\/  _ \\_/ ___\\|  | |  ||@",
-                "@|green |  |_> >  \\  \\__(  <_> )  \\___|  |_|  ||@",
-                "@|green |   __/|__|\\___  >____/ \\___  >____/__||@",
-                "@|green |__|           \\/           \\/         |@",
-                ""},
-        //descriptionHeading = "@|bold %nDescription|@:%n",
-        description = {
-                "",
-                "Demonstrates picocli subcommands parsing and usage help.", },
-        optionListHeading = "@|bold %nOptions|@:%n",
-        footer = {
-                "",
-                "@|bold VM Options|@:",
-                "Run with @|yellow -ea|@ to enable assertions used in the tests.",
-                "Run with @|yellow -Dpicocli.ansi|@=@|italic true|@ to force picocli to use ansi codes,",
-                " or with @|yellow -Dpicocli.ansi|@=@|italic false|@ to force picocli to NOT use ansi codes.",
-                "(By default picocli will use ansi codes if the platform supports it.)",
-                "",
-                "@|cyan If you would like to contribute or report an issue|@",
-                "@|cyan go to github: https://github.com/remkop/picocli|@",
-                "",
-                "@|cyan If you like the project star it on github and follow me on twitter!|@",
-                "@|cyan This project is created and maintained by Remko Popma (@remkopopma)|@",
-                ""})
-public class Demo implements Runnable {
-    public static void main(String[] args) {
-        CommandLine.run(new Demo(), System.err, args);
-    }
-
-    @Option(names = {"-a", "--autocomplete"}, description = "Generate sample autocomplete script for git")
-    private boolean autocomplete;
-
-    @Option(names = {"-1", "--showUsageForSubcommandGitCommit"}, description = "Shows usage help for the git-commit subcommand")
-    private boolean showUsageForSubcommandGitCommit;
-
-    @Option(names = {"-2", "--showUsageForMainCommand"}, description = "Shows usage help for a command with subcommands")
-    private boolean showUsageForMainCommand;
-
-    @Option(names = {"-3", "--showUsageForSubcommandGitStatus"}, description = "Shows usage help for the git-status subcommand")
-    private boolean showUsageForSubcommandGitStatus;
-
-    @Option(names = "--simple", description = "Show help for the first simple Example in the manual")
-    private boolean showSimpleExample;
-
-    @Option(names = "--mixed", hidden = true, description = "Show help with mixed Ansi colors and styles in description")
-    private boolean showAnsiInDescription;
-
-    @Option(names = {"-i", "--index"}, description = "" +
-            "@|fg(21) S|@" +
-            "@|fg(57) h|@" +
-            "@|fg(93) o|@" +
-            "@|fg(129) w|@" +
-            "@|fg(129)  |@" +
-            "@|fg(165) 2|@" +
-            "@|fg(201) 5|@" +
-            "@|fg(225) 6|@" +
-            "@|fg(123)  |@" +
-            "@|fg(122) c|@" +
-            "@|fg(120) o|@" +
-            "@|fg(118) l|@" +
-            "@|fg(148) o|@" +
-            "@|fg(142) r|@" +
-            "@|fg(136)  |@" +
-            "@|fg(136) p|@" +
-            "@|fg(130) a|@" +
-            "@|fg(124) l|@" +
-            "@|fg(160) e|@" +
-            "@|fg(196) t|@" +
-            "@|fg(198) t|@" +
-            "@|fg(199) e|@" +
-            "@|fg(200)  |@" +
-            "@|fg(201) i|@" +
-            "@|fg(213) n|@" +
-            "@|fg(219) d|@" +
-            "@|fg(225) e|@" +
-            "@|fg(231) x|@" +
-            "@|fg(230)  |@" +
-            "@|fg(229) v|@" +
-            "@|fg(228) a|@" +
-            "@|fg(227) l|@" +
-            "@|fg(226) u|@" +
-            "@|fg(190) e|@" +
-            "@|fg(154) s|@")
-    private boolean showIndexedColorPalette;
-
-    @Option(names = {"-r", "--rgb"}, description =  "" +
-            "@|fg(0;0;5) S|@" +
-            "@|fg(1;0;5) h|@" +
-            "@|fg(2;0;5) o|@" +
-            "@|fg(3;0;5) w|@" +
-            "@|fg(3;0;5)  |@" +
-            "@|fg(4;0;5) 2|@" +
-            "@|fg(5;0;5) 5|@" +
-            "@|fg(5;4;5) 6|@" +
-            "@|fg(2;5;5)  |@" +
-            "@|fg(2;5;4) c|@" +
-            "@|fg(2;5;2) o|@" +
-            "@|fg(2;5;0) l|@" +
-            "@|fg(3;4;0) o|@" +
-            "@|fg(3;3;0) r|@" +
-            "@|fg(3;2;0)  |@" +
-            "@|fg(3;2;0) p|@" +
-            "@|fg(3;1;0) a|@" +
-            "@|fg(3;0;0) l|@" +
-            "@|fg(4;0;0) e|@" +
-            "@|fg(5;0;0) t|@" +
-            "@|fg(5;0;2) t|@" +
-            "@|fg(5;0;3) e|@" +
-            "@|fg(5;0;4)  |@" +
-            "@|fg(5;0;5) R|@" +
-            "@|fg(5;2;5) G|@" +
-            "@|fg(5;3;5) B|@" +
-            "@|fg(5;4;5)  |@" +
-            "@|fg(5;5;5) c|@" +
-            "@|fg(5;5;4) o|@" +
-            "@|fg(5;5;3) m|@" +
-            "@|fg(5;5;2) p|@" +
-            "@|fg(5;5;1) o|@" +
-            "@|fg(5;5;0) n|@" +
-            "@|fg(4;5;0) e|@" +
-            "@|fg(3;5;0) n|@" +
-            "@|fg(2;5;0) t|@" +
-            "@|fg(1;5;0)  |@" +
-            "@|fg(1;5;0) v|@" +
-            "@|fg(0;5;0) a|@" +
-            "@|fg(0;4;0) l|@" +
-            "@|fg(0;3;0) u|@" +
-            "@|fg(0;2;0) e|@" +
-            "@|fg(0;1;0) s|@" +
-            "")
-    private boolean showRgbColorPalette;
-
-    @Option(names = {"-t", "--tests"}, description = "Runs all tests in this class")
-    private boolean runTests;
-
-    @Override
-    public void run() {
-        if (!runTests &&
-                !showSimpleExample &&
-                !showAnsiInDescription &&
-                !showIndexedColorPalette &&
-                !showRgbColorPalette &&
-                !showUsageForMainCommand &&
-                !showUsageForSubcommandGitCommit &&
-                !showUsageForSubcommandGitStatus &&
-                !autocomplete) {
-            CommandLine.usage(this, System.err);
-            return;
-        }
-        if (runTests)                        { testParseSubCommands(); System.out.println("Ran tests OK.");}
-        if (showSimpleExample)               { showSimpleExampleUsage(); }
-        if (showAnsiInDescription)           { showAnsiInDescription(); }
-        if (showIndexedColorPalette)         { showIndexedColorPalette(); }
-        if (showRgbColorPalette)             { showRgbColorPalette(); }
-        if (showUsageForMainCommand)         { testUsageMainCommand(); }
-        if (showUsageForSubcommandGitStatus) { testUsageSubCommandStatus(); }
-        if (showUsageForSubcommandGitCommit) { testUsageSubCommandCommit(); }
-    }
-
-    private void showSimpleExampleUsage() {
-        class Example {
-            @Option(names = { "-v", "--verbose" }, description = "Be verbose.")
-            private boolean verbose = false;
-
-            @Option(names = { "-h", "--help" }, help = true,
-                    description = "Displays this help message and quits.")
-            private boolean helpRequested = false;
-
-            @Parameters(arity = "1..*", paramLabel = "FILE", description = "File(s) to process.")
-            private File[] inputFiles;
-        }
-        CommandLine.usage(new Example(), System.out);
-    }
-
-    private void showAnsiInDescription() {
-        @Command(description = "Custom @|bold,underline styles|@ and @|fg(red) colors|@.")
-        class AnsiDescription { }
-        CommandLine.usage(new AnsiDescription(), System.out);
-    }
-
-    private void showIndexedColorPalette() {
-        int[] foregroundBackground = {38, 48};
-        for (int fbg : foregroundBackground) {
-            for (int r = 0; r < 2; r++) {
-                for (int g = 0; g < 6; g++) {
-                    for (int b = 0; b < 6; b++) {
-                        int col = 16 + 36 * (0 + 3 * r) + 6 * g + b;
-                        System.out.printf("\u001B[%d;5;%dm%3d \u001B[0m", fbg, col, col);
-                    }
-                    for (int b = 0; b < 6; b++) {
-                        int col = 16 + 36 * (1 + 3 * r) + 6 * g + b;
-                        System.out.printf("\u001B[%d;5;%dm%3d \u001B[0m", fbg, col, col);
-                    }
-                    for (int b = 0; b < 6; b++) {
-                        int col = 16 + 36 * (2 + 3 * r) + 6 * g + b;
-                        System.out.printf("\u001B[%d;5;%dm%3d \u001B[0m", fbg, col, col);
-                    }
-                    System.out.println();
-                }
-                System.out.println();
-            }
-            int r = 6;
-            for (int g = 0; g < 4; g++) {
-                for (int b = 0; b < 6; b++) {
-                    int col = 16 + 36 * r + 6 * g + b;
-                    System.out.printf("\u001B[%d;5;%dm%3d \u001B[0m", fbg, col, col);
-                }
-                System.out.println();
-            }
-            System.out.println();
-        }
-    }
-
-    private void showRgbColorPalette() {
-        int[] foregroundBackground = {38, 48};
-        for (int fbg : foregroundBackground) {
-            for (int r = 0; r < 2; r++) {
-                System.out.println("RGB RGB RGB RGB RGB RGB RGB RGB RGB RGB RGB RGB RGB RGB RGB RGB RGB RGB ");
-                for (int g = 0; g < 6; g++) {
-                    for (int b = 0; b < 6; b++) {
-                        int col = 16 + 36 * (0 + 3 * r) + 6 * g + b;
-                        System.out.printf("\u001B[%d;5;%dm%d%d%d \u001B[0m", fbg, col, (0 + 3 * r),g,b);
-                    }
-                    for (int b = 0; b < 6; b++) {
-                        int col = 16 + 36 * (1 + 3 * r) + 6 * g + b;
-                        System.out.printf("\u001B[%d;5;%dm%d%d%d \u001B[0m", fbg, col, (1 + 3 * r),g,b);
-                    }
-                    for (int b = 0; b < 6; b++) {
-                        int col = 16 + 36 * (2 + 3 * r) + 6 * g + b;
-                        System.out.printf("\u001B[%d;5;%dm%d%d%d \u001B[0m", fbg, col, (2 + 3 * r),g,b);
-                    }
-                    System.out.println();
-                }
-                System.out.println();
-            }
-            System.out.println("RGB RGB RGB RGB RGB RGB");
-            int r = 6;
-            for (int g = 0; g < 4; g++) {
-                for (int b = 0; b < 6; b++) {
-                    int col = 16 + 36 * r + 6 * g + b;
-                    System.out.printf("\u001B[%d;5;%dm%d%d%d \u001B[0m", fbg, col, r,g,b);
-                }
-                System.out.println();
-            }
-            System.out.println();
-        }
-    }
-
-    //------------------------------------------
-    static
-    // tag::Git[]
-    // tag::Git-declaration[]
-    @Command(name = "git", sortOptions = false,
-            description = "Git is a fast, scalable, distributed revision control " +
-                          "system with an unusually rich command set that provides both " +
-                          "high-level operations and full access to internals.",
-            commandListHeading = "%nCommands:%n%nThe most commonly used git commands are:%n")
-    class Git { // end::Git-declaration[]
-        @Option(names = {"-V", "--version"}, help = true, description = "Prints version information and exits")
-        boolean isVersionRequested;
-
-        @Option(names = {"-h", "--help"}, help = true, description = "Prints this help message and exits")
-        boolean isHelpRequested;
-
-        @Option(names = "--git-dir", description = "Set the path to the repository")
-        File gitDir;
-    }
-    // end::Git[]
-
-    // the "status" subcommand's has an option "mode" with a fixed number of values, modeled by this enum
-    enum GitStatusMode {all, no, normal};
-
-    static
-    @Command(name = "git-status",
-            header = "Show the working tree status.",
-            showDefaultValues = true,
-            customSynopsis = "@|bold git-status|@ [@|yellow <options>|@...] [--] [@|yellow <pathspec>|@...]",
-            description = "Displays paths that have differences between the index file and the current HEAD commit, " +
-                    "paths that have differences between the working tree and the index file, and paths in the " +
-                    "working tree that are not tracked by Git (and are not ignored by gitignore(5)). The first " +
-                    "are what you would commit by running git commit; the second and third are what you could " +
-                    "commit by running git add before running git commit."
-    )
-    class GitStatus {
-        @Option(names = {"-s", "--short"}, description = "Give the output in the short-format")
-        boolean shortFormat;
-
-        @Option(names = {"-b", "--branch"}, description = "Show the branch and tracking info even in short-format")
-        boolean branchInfo;
-
-        @Option(names = "--ignored", description = "Show ignored files as well") boolean showIgnored;
-
-        @Option(names = {"-u", "--untracked"}, paramLabel = "<mode>", description = {
-                "Show untracked files.",
-                "The mode parameter is optional (defaults to `all`), and is used to specify the handling of untracked files.",
-                "The possible options are:",
-                " * @|yellow no|@ - Show no untracked files.",
-                " * @|yellow normal|@ - Shows untracked files and directories.",
-                " * @|yellow all|@ - Also shows individual files in untracked directories."
-        })
-        GitStatusMode mode = GitStatusMode.all;
-    }
-
-    static
-    // tag::GitCommit[]
-    // tag::GitCommit-declaration[]
-    @Command(name = "git-commit",
-            sortOptions = false,
-            headerHeading = "@|bold,underline Usage:|@%n%n",
-            synopsisHeading = "%n",
-            descriptionHeading = "%n@|bold,underline Description:|@%n%n",
-            parameterListHeading = "%n@|bold,underline Parameters:|@%n",
-            optionListHeading = "%n@|bold,underline Options:|@%n",
-            header = "Record changes to the repository.",
-            description = "Stores the current contents of the index in a new commit " +
-                    "along with a log message from the user describing the changes.")
-    class GitCommit { // end::GitCommit-declaration[]
-        @Option(names = {"-a", "--all"},
-                description = "Tell the command to automatically stage files that have been modified " +
-                        "and deleted, but new files you have not told Git about are not affected.")
-        boolean all;
-
-        @Option(names = {"-p", "--patch"}, description = "Use the interactive patch selection interface to chose which changes to commit")
-        boolean patch;
-
-        @Option(names = {"-C", "--reuse-message"}, paramLabel = "<commit>",
-                description = "Take an existing commit object, and reuse the log message and the " +
-                        "authorship information (including the timestamp) when creating the commit.")
-        String reuseMessageCommit;
-
-        @Option(names = {"-c", "--reedit-message"}, paramLabel = "<commit>",
-                description = "Like -C, but with -c the editor is invoked, so that the user can" +
-                        "further edit the commit message.")
-        String reEditMessageCommit;
-
-        @Option(names = "--fixup", paramLabel = "<commit>",
-                description = "Construct a commit message for use with rebase --autosquash.")
-        String fixupCommit;
-
-        @Option(names = "--squash", paramLabel = "<commit>",
-                description = "Construct a commit message for use with rebase --autosquash. The commit" +
-                        "message subject line is taken from the specified commit with a prefix of " +
-                        "\"squash! \". Can be used with additional commit message options (-m/-c/-C/-F).")
-        String squashCommit;
-
-        @Option(names = {"-F", "--file"}, paramLabel = "<file>",
-                description = "Take the commit message from the given file. Use - to read the message from the standard input.")
-        File file;
-
-        @Option(names = {"-m", "--message"}, paramLabel = "<msg>",
-                description = "Use the given <msg> as the commit message. If multiple -m options" +
-                        " are given, their values are concatenated as separate paragraphs.")
-        List<String> message = new ArrayList<String>();
-
-        @Parameters(paramLabel = "<files>", description = "the files to commit")
-        List<File> files = new ArrayList<File>();
-    }
-    // end::GitCommit[]
-
-    // defines some commands to show in the list (option/parameters fields omitted for this demo)
-    @Command(name = "git-add", header = "Add file contents to the index.") static class GitAdd {}
-    @Command(name = "git-branch", header = "List, create, or delete branches.") static class GitBranch {}
-    @Command(name = "git-checkout", header = "Checkout a branch or paths to the working tree.") static class GitCheckout{}
-    @Command(name = "git-clone", header = "Clone a repository into a new directory.") static class GitClone{}
-    @Command(name = "git-diff", header = "Show changes between commits, commit and working tree, etc.") static class GitDiff{}
-    @Command(name = "git-merge", header = "Join two or more development histories together.") static class GitMerge{}
-    @Command(name = "git-push", header = "Update remote refs along with associated objects.") static class GitPush{}
-    @Command(name = "git-rebase", header = "Forward-port local commits to the updated upstream head.") static class GitRebase{}
-    @Command(name = "git-tag", header = "Create, list, delete or verify a tag object signed with GPG.") static class GitTag{}
-
-    /** @see CommandLineTest#testParseSubCommands() The JUnit test implementation of this test. */
-    public static void testParseSubCommands() {
-        CommandLine commandLine = mainCommand();
-
-        String[] args = { "--git-dir=/home/rpopma/picocli", "status", "-sbuno"};
-        List<CommandLine> parsed = commandLine.parse(args);
-        assert parsed.size() == 2 : "found 2 commands";
-
-        assert parsed.get(0).getCommand().getClass() == Git.class;
-        assert parsed.get(1).getCommand().getClass() == GitStatus.class;
-
-        Git git = (Git) parsed.get(0).getCommand();
-        assert git.gitDir.equals(new File("/home/rpopma/picocli"));
-
-        GitStatus status = (GitStatus) parsed.get(1).getCommand();
-        assert  status.shortFormat : "status -s";
-        assert  status.branchInfo  : "status -b";
-        assert !status.showIgnored : "status --showIgnored not specified";
-        assert  status.mode == GitStatusMode.no : "status -u=no";
-    }
-
-    static CommandLine mainCommand() {
-        CommandLine commandLine = new CommandLine(new Git());
-        commandLine.addSubcommand("status", new GitStatus());
-        commandLine.addSubcommand("commit", new GitCommit());
-        commandLine.addSubcommand("add", new GitAdd());
-        commandLine.addSubcommand("branch", new GitBranch());
-        commandLine.addSubcommand("checkout", new GitCheckout());
-        commandLine.addSubcommand("clone", new GitClone());
-        commandLine.addSubcommand("diff", new GitDiff());
-        commandLine.addSubcommand("merge", new GitMerge());
-        commandLine.addSubcommand("push", new GitPush());
-        commandLine.addSubcommand("rebase", new GitRebase());
-        commandLine.addSubcommand("tag", new GitTag());
-        return commandLine;
-    }
-
-    public void testUsageMainCommand()  {
-        CommandLine commandLine = mainCommand();
-        try {
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            commandLine.usage(new PrintStream(baos, true, "UTF8"));
-            String result = baos.toString("UTF8");
-            System.out.println(result);
-            assert String.format(EXPECTED_USAGE_MAIN).equals(result);
-        } catch (UnsupportedEncodingException ex) {
-            throw new InternalError(ex.toString());
-        }
-    }
-    static final String EXPECTED_USAGE_MAIN = "Usage: git [-hV] [--git-dir=<gitDir>]%n" +
-            "Git is a fast, scalable, distributed revision control system with an unusually%n" +
-            "rich command set that provides both high-level operations and full access to%n" +
-            "internals.%n" +
-            "  -V, --version               Prints version information and exits%n" +
-            "  -h, --help                  Prints this help message and exits%n" +
-            "      --git-dir=<gitDir>      Set the path to the repository%n" +
-            "%n" +
-            "Commands:%n" +
-            "%n" +
-            "The most commonly used git commands are:%n" +
-            "  status    Show the working tree status.%n" +
-            "  commit    Record changes to the repository.%n" +
-            "  add       Add file contents to the index.%n" +
-            "  branch    List, create, or delete branches.%n" +
-            "  checkout  Checkout a branch or paths to the working tree.%n" +
-            "  clone     Clone a repository into a new directory.%n" +
-            "  diff      Show changes between commits, commit and working tree, etc.%n" +
-            "  merge     Join two or more development histories together.%n" +
-            "  push      Update remote refs along with associated objects.%n" +
-            "  rebase    Forward-port local commits to the updated upstream head.%n" +
-            "  tag       Create, list, delete or verify a tag object signed with GPG.%n";
-
-    static final String EXPECTED_USAGE_MAIN_ANSI = "Usage: @|bold git|@ [@|yellow -hV|@] [@|yellow --git-dir|@=@|italic <gitDir>|@]%n" +
-            "Git is a fast, scalable, distributed revision control system with an unusually%n" +
-            "rich command set that provides both high-level operations and full access to%n" +
-            "internals.%n" +
-            "  @|yellow -V|@, @|yellow --version|@               Prints version information and exits%n" +
-            "  @|yellow -h|@, @|yellow --help|@                  Prints this help message and exits%n" +
-            "      @|yellow --git-dir|@=@|italic <gitDir>|@      Set the path to the repository%n" +
-            "%n" +
-            "Commands:%n" +
-            "%n" +
-            "The most commonly used git commands are:%n" +
-            "  @|bold status|@    Show the working tree status.%n" +
-            "  @|bold commit|@    Record changes to the repository.%n" +
-            "  @|bold add|@       Add file contents to the index.%n" +
-            "  @|bold branch|@    List, create, or delete branches.%n" +
-            "  @|bold checkout|@  Checkout a branch or paths to the working tree.%n" +
-            "  @|bold clone|@     Clone a repository into a new directory.%n" +
-            "  @|bold diff|@      Show changes between commits, commit and working tree, etc.%n" +
-            "  @|bold merge|@     Join two or more development histories together.%n" +
-            "  @|bold push|@      Update remote refs along with associated objects.%n" +
-            "  @|bold rebase|@    Forward-port local commits to the updated upstream head.%n" +
-            "  @|bold tag|@       Create, list, delete or verify a tag object signed with GPG.%n";
-
-    public void testUsageSubCommandStatus() {
-        try {
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            CommandLine.usage(new GitStatus(), new PrintStream(baos, true, "UTF8"));
-            String result = baos.toString("UTF8");
-            System.out.println(result);
-            assert String.format(EXPECTED_USAGE_GITSTATUS).equals(result);
-        } catch (UnsupportedEncodingException ex) {
-            throw new InternalError(ex.toString());
-        }
-    }
-    static final String EXPECTED_USAGE_GITSTATUS = "Show the working tree status.%n" +
-            "Usage: git-status [<options>...] [--] [<pathspec>...]%n" +
-            "Displays paths that have differences between the index file and the current%n" +
-            "HEAD commit, paths that have differences between the working tree and the index%n" +
-            "file, and paths in the working tree that are not tracked by Git (and are not%n" +
-            "ignored by gitignore(5)). The first are what you would commit by running git%n" +
-            "commit; the second and third are what you could commit by running git add%n" +
-            "before running git commit.%n" +
-            "      --ignored               Show ignored files as well%n" +
-            "  -b, --branch                Show the branch and tracking info even in%n" +
-            "                                short-format%n" +
-            "  -s, --short                 Give the output in the short-format%n" +
-            "  -u, --untracked=<mode>      Show untracked files.%n" +
-            "                              The mode parameter is optional (defaults to%n" +
-            "                                `all`), and is used to specify the handling of%n" +
-            "                                untracked files.%n" +
-            "                              The possible options are:%n" +
-            "                               * no - Show no untracked files.%n" +
-            "                               * normal - Shows untracked files and directories.%n" +
-            "                               * all - Also shows individual files in untracked%n" +
-            "                                directories.%n" +
-            "                                Default: all%n";
-
-    static final String EXPECTED_USAGE_GITSTATUS_ANSI = "Show the working tree status.%n" +
-            "Usage: @|bold git-status|@ [@|yellow <options>|@...] [--] [@|yellow <pathspec>|@...]%n" +
-            "Displays paths that have differences between the index file and the current%n" +
-            "HEAD commit, paths that have differences between the working tree and the index%n" +
-            "file, and paths in the working tree that are not tracked by Git (and are not%n" +
-            "ignored by gitignore(5)). The first are what you would commit by running git%n" +
-            "commit; the second and third are what you could commit by running git add%n" +
-            "before running git commit.%n" +
-            "      @|yellow --ignored|@               Show ignored files as well%n" +
-            "  @|yellow -b|@, @|yellow --branch|@                Show the branch and tracking info even in%n" +
-            "                                short-format%n" +
-            "  @|yellow -s|@, @|yellow --short|@                 Give the output in the short-format%n" +
-            "  @|yellow -u|@, @|yellow --untracked|@=@|italic <mode>|@      Show untracked files.%n" +
-            "                              The mode parameter is optional (defaults to%n" +
-            "                                `all`), and is used to specify the handling of%n" +
-            "                                untracked files.%n" +
-            "                              The possible options are:%n" +
-            "                               * @|yellow no|@ - Show no untracked files.%n" +
-            "                               * @|yellow normal|@ - Shows untracked files and directories.%n" +
-            "                               * @|yellow all|@ - Also shows individual files in untracked%n" +
-            "                                directories.%n" +
-            "                                Default: all%n";
-
-    public void testUsageSubCommandCommit() {
-        try {
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            CommandLine.usage(new GitCommit(), new PrintStream(baos, true, "UTF8"));
-            String result = baos.toString("UTF8");
-            System.out.println(result);
-            assert String.format(EXPECTED_USAGE_GITCOMMIT).equals(result);
-        } catch (UnsupportedEncodingException ex) {
-            throw new InternalError(ex.toString());
-        }
-    }
-    static final String EXPECTED_USAGE_GITCOMMIT = "Usage:%n" +
-            "%n" +
-            "Record changes to the repository.%n" +
-            "%n" +
-            "git-commit [-ap] [--fixup=<commit>] [--squash=<commit>] [-c=<commit>]%n" +
-            "           [-C=<commit>] [-F=<file>] [-m=<msg>]... [<files>]...%n" +
-            "%n" +
-            "Description:%n" +
-            "%n" +
-            "Stores the current contents of the index in a new commit along with a log%n" +
-            "message from the user describing the changes.%n" +
-            "%n" +
-            "Parameters:%n" +
-            "      [<files>]...            the files to commit%n" +
-            "%n" +
-            "Options:%n" +
-            "  -a, --all                   Tell the command to automatically stage files%n" +
-            "                                that have been modified and deleted, but new%n" +
-            "                                files you have not told Git about are not%n" +
-            "                                affected.%n" +
-            "  -p, --patch                 Use the interactive patch selection interface to%n" +
-            "                                chose which changes to commit%n" +
-            "  -C, --reuse-message=<commit>%n" +
-            "                              Take an existing commit object, and reuse the log%n" +
-            "                                message and the authorship information%n" +
-            "                                (including the timestamp) when creating the%n" +
-            "                                commit.%n" +
-            "  -c, --reedit-message=<commit>%n" +
-            "                              Like -C, but with -c the editor is invoked, so%n" +
-            "                                that the user canfurther edit the commit%n" +
-            "                                message.%n" +
-            "      --fixup=<commit>        Construct a commit message for use with rebase%n" +
-            "                                --autosquash.%n" +
-            "      --squash=<commit>       Construct a commit message for use with rebase%n" +
-            "                                --autosquash. The commitmessage subject line is%n" +
-            "                                taken from the specified commit with a prefix%n" +
-            "                                of \"squash! \". Can be used with additional%n" +
-            "                                commit message options (-m/-c/-C/-F).%n" +
-            "  -F, --file=<file>           Take the commit message from the given file. Use%n" +
-            "                                - to read the message from the standard input.%n" +
-            "  -m, --message=<msg>         Use the given <msg> as the commit message. If%n" +
-            "                                multiple -m options are given, their values are%n" +
-            "                                concatenated as separate paragraphs.%n";
-
-    static final String EXPECTED_USAGE_GITCOMMIT_ANSI = "@|bold,underline Usage:|@%n" +
-            "%n" +
-            "Record changes to the repository.%n" +
-            "%n" +
-            "@|bold git-commit|@ [@|yellow -ap|@] [@|yellow --fixup|@=@|italic <commit>|@] [@|yellow --squash|@=@|italic <commit>|@] [@|yellow -c|@=@|italic <commit>|@]%n" +
-            "           [@|yellow -C|@=@|italic <commit>|@] [@|yellow -F|@=@|italic <file>|@] [@|yellow -m|@=@|italic <msg>|@]... [@|yellow <files>|@]...%n" +
-            "%n" +
-            "@|bold,underline Description:|@%n" +
-            "%n" +
-            "Stores the current contents of the index in a new commit along with a log%n" +
-            "message from the user describing the changes.%n" +
-            "%n" +
-            "@|bold,underline Parameters:|@%n" +
-            "      [@|yellow <files>|@]...            the files to commit%n" +
-            "%n" +
-            "@|bold,underline Options:|@%n" +
-            "  @|yellow -a|@, @|yellow --all|@                   Tell the command to automatically stage files%n" +
-            "                                that have been modified and deleted, but new%n" +
-            "                                files you have not told Git about are not%n" +
-            "                                affected.%n" +
-            "  @|yellow -p|@, @|yellow --patch|@                 Use the interactive patch selection interface to%n" +
-            "                                chose which changes to commit%n" +
-            "  @|yellow -C|@, @|yellow --reuse-message|@=@|italic <commit|@@|italic >|@%n" +
-            "                              Take an existing commit object, and reuse the log%n" +
-            "                                message and the authorship information%n" +
-            "                                (including the timestamp) when creating the%n" +
-            "                                commit.%n" +
-            "  @|yellow -c|@, @|yellow --reedit-message|@=@|italic <commi|@@|italic t>|@%n" +
-            "                              Like -C, but with -c the editor is invoked, so%n" +
-            "                                that the user canfurther edit the commit%n" +
-            "                                message.%n" +
-            "      @|yellow --fixup|@=@|italic <commit>|@        Construct a commit message for use with rebase%n" +
-            "                                --autosquash.%n" +
-            "      @|yellow --squash|@=@|italic <commit>|@       Construct a commit message for use with rebase%n" +
-            "                                --autosquash. The commitmessage subject line is%n" +
-            "                                taken from the specified commit with a prefix%n" +
-            "                                of \"squash! \". Can be used with additional%n" +
-            "                                commit message options (-m/-c/-C/-F).%n" +
-            "  @|yellow -F|@, @|yellow --file|@=@|italic <file>|@           Take the commit message from the given file. Use%n" +
-            "                                - to read the message from the standard input.%n" +
-            "  @|yellow -m|@, @|yellow --message|@=@|italic <msg>|@         Use the given <msg> as the commit message. If%n" +
-            "                                multiple -m options are given, their values are%n" +
-            "                                concatenated as separate paragraphs.%n";
-
-    static
-    // tag::CheckSum[]
-    @Command(name = "checksum", description = "Prints the checksum (MD5 by default) of a file to STDOUT.")
-    class CheckSum implements Callable<Void> {
-
-        @Parameters(index = "0", description = "The file whose checksum to calculate.")
-        private File file;
-
-        @Option(names = {"-a", "--algorithm"}, description = "MD5, SHA-1, SHA-256, ...")
-        private String algorithm = "MD5";
-
-        @Option(names = {"-h", "--help"}, usageHelp = true, description = "Show this help message and exit.")
-        private boolean helpRequested;
-
-        public static void main(String[] args) throws Exception {
-            // CheckSum implements Callable,
-            // so parsing and error handling can be done in one line of code
-            CommandLine.call(new CheckSum(), System.err, args);
-        }
-
-        @Override
-        public Void call() throws Exception {
-            // business logic: do different things depending on options the user specified
-            if (helpRequested) {
-                CommandLine.usage(this, System.err);
-                return null;
-            }
-            byte[] digest = MessageDigest.getInstance(algorithm).digest(readBytes(file));
-            print(digest, System.out);
-            return null;
-        }
-
-        byte[] readBytes(File f) throws IOException {
-            int pos = 0;
-            int len = 0;
-            byte[] buffer = new byte[(int) f.length()];
-            FileInputStream fis = null;
-            try {
-                fis = new FileInputStream(f);
-                while ((len = fis.read(buffer, pos, buffer.length - pos)) > 0) { pos += len; }
-            } finally {
-                if (fis != null) { fis.close(); }
-            }
-            return buffer;
-        }
-        void print(byte[] digest, PrintStream out) {
-            for (int i = 0; i < digest.length; i++) {
-                if ((digest[i] & 0xFF) < 16) { out.print('0'); }
-                out.print(Integer.toHexString(digest[i] & 0xFF));
-            }
-            out.println();
-        }
-    }
-    // end::CheckSum[]
-}


[4/4] logging-log4j2 git commit: [BUILD] removed picocli tests from core tests; they do not add value here and occasionally fail when building Log4j on a console that supports ANSI colors

Posted by rp...@apache.org.
[BUILD] removed picocli tests from core tests; they do not add value here and occasionally fail when building Log4j on a console that supports ANSI colors


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/dd8ded97
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/dd8ded97
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/dd8ded97

Branch: refs/heads/release-2.x
Commit: dd8ded97adc3fb2422eadc6c67a2da9c327f4497
Parents: ec10b16
Author: rpopma <rp...@apache.org>
Authored: Wed Mar 21 20:07:40 2018 +0900
Committer: rpopma <rp...@apache.org>
Committed: Wed Mar 21 20:07:40 2018 +0900

----------------------------------------------------------------------
 .../tools/picocli/CommandLineArityTest.java     |  898 -----
 .../core/tools/picocli/CommandLineHelpTest.java | 2536 --------------
 .../core/tools/picocli/CommandLineTest.java     | 3188 ------------------
 .../core/tools/picocli/CustomLayoutDemo.java    |  264 --
 .../logging/log4j/core/tools/picocli/Demo.java  |  719 ----
 5 files changed, 7605 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/dd8ded97/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/CommandLineArityTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/CommandLineArityTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/CommandLineArityTest.java
deleted file mode 100644
index e35b593..0000000
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/CommandLineArityTest.java
+++ /dev/null
@@ -1,898 +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.logging.log4j.core.tools.picocli;
-
-import java.io.File;
-import java.net.InetAddress;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.apache.logging.log4j.core.tools.picocli.CommandLine.*;
-
-import static org.junit.Assert.*;
-
-public class CommandLineArityTest {
-    @Before public void setUp() { System.clearProperty("picocli.trace"); }
-    @After public void tearDown() { System.clearProperty("picocli.trace"); }
-
-    private static void setTraceLevel(String level) {
-        System.setProperty("picocli.trace", level);
-    }
-    @Test
-    public void testArityConstructor_fixedRange() {
-        Range arity = new Range(1, 23, false, false, null);
-        assertEquals("min", 1, arity.min);
-        assertEquals("max", 23, arity.max);
-        assertEquals("1..23", arity.toString());
-        assertEquals(Range.valueOf("1..23"), arity);
-    }
-    @Test
-    public void testArityConstructor_variableRange() {
-        Range arity = new Range(1, Integer.MAX_VALUE, true, false, null);
-        assertEquals("min", 1, arity.min);
-        assertEquals("max", Integer.MAX_VALUE, arity.max);
-        assertEquals("1..*", arity.toString());
-        assertEquals(Range.valueOf("1..*"), arity);
-    }
-    @Test
-    public void testArityForOption_booleanFieldImplicitArity0() throws Exception {
-        Range arity = Range.optionArity(CommandLineTest.SupportedTypes.class.getDeclaredField("booleanField"));
-        assertEquals(Range.valueOf("0"), arity);
-        assertEquals("0", arity.toString());
-    }
-    @Test
-    public void testArityForOption_intFieldImplicitArity1() throws Exception {
-        Range arity = Range.optionArity(CommandLineTest.SupportedTypes.class.getDeclaredField("intField"));
-        assertEquals(Range.valueOf("1"), arity);
-        assertEquals("1", arity.toString());
-    }
-    @Test
-    public void testArityForOption_isExplicitlyDeclaredValue() throws Exception {
-        class Params {
-            @Option(names = "-timeUnitList", type = TimeUnit.class, arity = "3") List<TimeUnit> timeUnitList;
-        }
-        Range arity = Range.optionArity(Params.class.getDeclaredField("timeUnitList"));
-        assertEquals(Range.valueOf("3"), arity);
-        assertEquals("3", arity.toString());
-    }
-    @Test
-    public void testArityForOption_listFieldImplicitArity1() throws Exception {
-        class ImplicitList { @Option(names = "-a") List<Integer> listIntegers; }
-        Range arity = Range.optionArity(ImplicitList.class.getDeclaredField("listIntegers"));
-        assertEquals(Range.valueOf("1"), arity);
-        assertEquals("1", arity.toString());
-    }
-    @Test
-    public void testArityForOption_arrayFieldImplicitArity1() throws Exception {
-        class ImplicitList { @Option(names = "-a") int[] intArray; }
-        Range arity = Range.optionArity(ImplicitList.class.getDeclaredField("intArray"));
-        assertEquals(Range.valueOf("1"), arity);
-        assertEquals("1", arity.toString());
-    }
-    @Test
-    public void testArityForParameters_booleanFieldImplicitArity1() throws Exception {
-        class ImplicitBoolField { @Parameters boolean boolSingleValue; }
-        Range arity = Range.parameterArity(ImplicitBoolField.class.getDeclaredField("boolSingleValue"));
-        assertEquals(Range.valueOf("1"), arity);
-        assertEquals("1", arity.toString());
-    }
-    @Test
-    public void testArityForParameters_intFieldImplicitArity1() throws Exception {
-        class ImplicitSingleField { @Parameters int intSingleValue; }
-        Range arity = Range.parameterArity(ImplicitSingleField.class.getDeclaredField("intSingleValue"));
-        assertEquals(Range.valueOf("1"), arity);
-        assertEquals("1", arity.toString());
-    }
-    @Test
-    public void testArityForParameters_listFieldImplicitArity0_1() throws Exception {
-        class Params {
-            @Parameters(type = Integer.class) List<Integer> list;
-        }
-        Range arity = Range.parameterArity(Params.class.getDeclaredField("list"));
-        assertEquals(Range.valueOf("0..1"), arity);
-        assertEquals("0..1", arity.toString());
-    }
-    @Test
-    public void testArityForParameters_arrayFieldImplicitArity0_1() throws Exception {
-        class Args {
-            @Parameters File[] inputFiles;
-        }
-        Range arity = Range.parameterArity(Args.class.getDeclaredField("inputFiles"));
-        assertEquals(Range.valueOf("0..1"), arity);
-        assertEquals("0..1", arity.toString());
-    }
-    @Test
-    public void testArrayOptionsWithArity0_nConsumeAllArguments() {
-        final double[] DEFAULT_PARAMS = new double[] {1, 2};
-        class ArrayOptionsArity0_nAndParameters {
-            @Parameters double[] doubleParams = DEFAULT_PARAMS;
-            @Option(names = "-doubles", arity = "0..*") double[] doubleOptions;
-        }
-        ArrayOptionsArity0_nAndParameters
-                params = CommandLine.populateCommand(new ArrayOptionsArity0_nAndParameters(), "-doubles 1.1 2.2 3.3 4.4".split(" "));
-        assertArrayEquals(Arrays.toString(params.doubleOptions),
-                new double[] {1.1, 2.2, 3.3, 4.4}, params.doubleOptions, 0.000001);
-        assertArrayEquals(DEFAULT_PARAMS, params.doubleParams, 0.000001);
-    }
-
-    @Test
-    public void testArrayOptionsWithArity1_nConsumeAllArguments() {
-        class ArrayOptionsArity1_nAndParameters {
-            @Parameters double[] doubleParams;
-            @Option(names = "-doubles", arity = "1..*") double[] doubleOptions;
-        }
-        ArrayOptionsArity1_nAndParameters
-                params = CommandLine.populateCommand(new ArrayOptionsArity1_nAndParameters(), "-doubles 1.1 2.2 3.3 4.4".split(" "));
-        assertArrayEquals(Arrays.toString(params.doubleOptions),
-                new double[] {1.1, 2.2, 3.3, 4.4}, params.doubleOptions, 0.000001);
-        assertArrayEquals(null, params.doubleParams, 0.000001);
-    }
-
-    @Test
-    public void testArrayOptionsWithArity2_nConsumeAllArguments() {
-        class ArrayOptionsArity2_nAndParameters {
-            @Parameters double[] doubleParams;
-            @Option(names = "-doubles", arity = "2..*") double[] doubleOptions;
-        }
-        ArrayOptionsArity2_nAndParameters
-                params = CommandLine.populateCommand(new ArrayOptionsArity2_nAndParameters(), "-doubles 1.1 2.2 3.3 4.4".split(" "));
-        assertArrayEquals(Arrays.toString(params.doubleOptions),
-                new double[] {1.1, 2.2, 3.3, 4.4}, params.doubleOptions, 0.000001);
-        assertArrayEquals(null, params.doubleParams, 0.000001);
-    }
-
-    @Test
-    public void testArrayOptionArity2_nConsumesAllArgumentsUpToClusteredOption() {
-        class ArrayOptionsArity2_nAndParameters {
-            @Parameters String[] stringParams;
-            @Option(names = "-s", arity = "2..*") String[] stringOptions;
-            @Option(names = "-v") boolean verbose;
-            @Option(names = "-f") File file;
-        }
-        ArrayOptionsArity2_nAndParameters
-                params = CommandLine.populateCommand(new ArrayOptionsArity2_nAndParameters(), "-s 1.1 2.2 3.3 4.4 -vfFILE 5.5".split(" "));
-        assertArrayEquals(Arrays.toString(params.stringOptions),
-                new String[] {"1.1", "2.2", "3.3", "4.4"}, params.stringOptions);
-        assertTrue(params.verbose);
-        assertEquals(new File("FILE"), params.file);
-        assertArrayEquals(new String[] {"5.5"}, params.stringParams);
-    }
-
-    @Test
-    public void testArrayOptionArity2_nConsumesAllArgumentIncludingQuotedSimpleOption() {
-        class ArrayOptionArity2_nAndParameters {
-            @Parameters String[] stringParams;
-            @Option(names = "-s", arity = "2..*") String[] stringOptions;
-            @Option(names = "-v") boolean verbose;
-            @Option(names = "-f") File file;
-        }
-        ArrayOptionArity2_nAndParameters
-                params = CommandLine.populateCommand(new ArrayOptionArity2_nAndParameters(), "-s 1.1 2.2 3.3 4.4 \"-v\" \"-f\" \"FILE\" 5.5".split(" "));
-        assertArrayEquals(Arrays.toString(params.stringOptions),
-                new String[] {"1.1", "2.2", "3.3", "4.4", "-v", "-f", "FILE", "5.5"}, params.stringOptions);
-        assertFalse("verbose", params.verbose);
-        assertNull("file", params.file);
-        assertArrayEquals(null, params.stringParams);
-    }
-
-    @Test
-    public void testArrayOptionArity2_nConsumesAllArgumentIncludingQuotedClusteredOption() {
-        class ArrayOptionArity2_nAndParameters {
-            @Parameters String[] stringParams;
-            @Option(names = "-s", arity = "2..*") String[] stringOptions;
-            @Option(names = "-v") boolean verbose;
-            @Option(names = "-f") File file;
-        }
-        ArrayOptionArity2_nAndParameters
-                params = CommandLine.populateCommand(new ArrayOptionArity2_nAndParameters(), "-s 1.1 2.2 3.3 4.4 \"-vfFILE\" 5.5".split(" "));
-        assertArrayEquals(Arrays.toString(params.stringOptions),
-                new String[] {"1.1", "2.2", "3.3", "4.4", "-vfFILE", "5.5"}, params.stringOptions);
-        assertFalse("verbose", params.verbose);
-        assertNull("file", params.file);
-        assertArrayEquals(null, params.stringParams);
-    }
-
-    @Test
-    public void testArrayOptionArity2_nConsumesAllArgumentsUpToNextSimpleOption() {
-        class ArrayOptionArity2_nAndParameters {
-            @Parameters double[] doubleParams;
-            @Option(names = "-s", arity = "2..*") String[] stringOptions;
-            @Option(names = "-v") boolean verbose;
-            @Option(names = "-f") File file;
-        }
-        ArrayOptionArity2_nAndParameters
-                params = CommandLine.populateCommand(new ArrayOptionArity2_nAndParameters(), "-s 1.1 2.2 3.3 4.4 -v -f=FILE 5.5".split(" "));
-        assertArrayEquals(Arrays.toString(params.stringOptions),
-                new String[] {"1.1", "2.2", "3.3", "4.4"}, params.stringOptions);
-        assertTrue(params.verbose);
-        assertEquals(new File("FILE"), params.file);
-        assertArrayEquals(new double[] {5.5}, params.doubleParams, 0.000001);
-    }
-
-    @Test
-    public void testArrayOptionArity2_nConsumesAllArgumentsUpToNextOptionWithAttachment() {
-        class ArrayOptionArity2_nAndParameters {
-            @Parameters double[] doubleParams;
-            @Option(names = "-s", arity = "2..*") String[] stringOptions;
-            @Option(names = "-v") boolean verbose;
-            @Option(names = "-f") File file;
-        }
-        ArrayOptionArity2_nAndParameters
-                params = CommandLine.populateCommand(new ArrayOptionArity2_nAndParameters(), "-s 1.1 2.2 3.3 4.4 -f=FILE -v 5.5".split(" "));
-        assertArrayEquals(Arrays.toString(params.stringOptions),
-                new String[] {"1.1", "2.2", "3.3", "4.4"}, params.stringOptions);
-        assertTrue(params.verbose);
-        assertEquals(new File("FILE"), params.file);
-        assertArrayEquals(new double[] {5.5}, params.doubleParams, 0.000001);
-    }
-
-    @Test
-    public void testArrayOptionArityNConsumeAllArguments() {
-        class ArrayOptionArityNAndParameters {
-            @Parameters char[] charParams;
-            @Option(names = "-chars", arity = "*") char[] charOptions;
-        }
-        ArrayOptionArityNAndParameters
-                params = CommandLine.populateCommand(new ArrayOptionArityNAndParameters(), "-chars a b c d".split(" "));
-        assertArrayEquals(Arrays.toString(params.charOptions),
-                new char[] {'a', 'b', 'c', 'd'}, params.charOptions);
-        assertArrayEquals(null, params.charParams);
-    }
-    @Test
-    public void testMissingRequiredParams() {
-        class Example {
-            @Parameters(index = "1", arity = "0..1") String optional;
-            @Parameters(index = "0") String mandatory;
-        }
-        try { CommandLine.populateCommand(new Example(), new String[] {"mandatory"}); }
-        catch (MissingParameterException ex) { fail(); }
-
-        try {
-            CommandLine.populateCommand(new Example(), new String[0]);
-            fail("Should not accept missing mandatory parameter");
-        } catch (MissingParameterException ex) {
-            assertEquals("Missing required parameter: <mandatory>", ex.getMessage());
-        }
-    }
-    @Test
-    public void testMissingRequiredParams1() {
-        class Tricky1 {
-            @Parameters(index = "2") String anotherMandatory;
-            @Parameters(index = "1", arity = "0..1") String optional;
-            @Parameters(index = "0") String mandatory;
-        }
-        try {
-            CommandLine.populateCommand(new Tricky1(), new String[0]);
-            fail("Should not accept missing mandatory parameter");
-        } catch (MissingParameterException ex) {
-            assertEquals("Missing required parameters: <mandatory>, <anotherMandatory>", ex.getMessage());
-        }
-        try {
-            CommandLine.populateCommand(new Tricky1(), new String[] {"firstonly"});
-            fail("Should not accept missing mandatory parameter");
-        } catch (MissingParameterException ex) {
-            assertEquals("Missing required parameter: <anotherMandatory>", ex.getMessage());
-        }
-    }
-    @Test
-    public void testMissingRequiredParams2() {
-        class Tricky2 {
-            @Parameters(index = "2", arity = "0..1") String anotherOptional;
-            @Parameters(index = "1", arity = "0..1") String optional;
-            @Parameters(index = "0") String mandatory;
-        }
-        try { CommandLine.populateCommand(new Tricky2(), new String[] {"mandatory"}); }
-        catch (MissingParameterException ex) { fail(); }
-
-        try {
-            CommandLine.populateCommand(new Tricky2(), new String[0]);
-            fail("Should not accept missing mandatory parameter");
-        } catch (MissingParameterException ex) {
-            assertEquals("Missing required parameter: <mandatory>", ex.getMessage());
-        }
-    }
-    @Test
-    public void testMissingRequiredParamsWithOptions() {
-        class Tricky3 {
-            @Option(names="-v") boolean more;
-            @Option(names="-t") boolean any;
-            @Parameters(index = "1") String alsoMandatory;
-            @Parameters(index = "0") String mandatory;
-        }
-        try {
-            CommandLine.populateCommand(new Tricky3(), new String[] {"-t", "-v", "mandatory"});
-            fail("Should not accept missing mandatory parameter");
-        } catch (MissingParameterException ex) {
-            assertEquals("Missing required parameter: <alsoMandatory>", ex.getMessage());
-        }
-
-        try {
-            CommandLine.populateCommand(new Tricky3(), new String[] { "-t", "-v"});
-            fail("Should not accept missing two mandatory parameters");
-        } catch (MissingParameterException ex) {
-            assertEquals("Missing required parameters: <mandatory>, <alsoMandatory>", ex.getMessage());
-        }
-    }
-    @Test
-    public void testMissingRequiredParamWithOption() {
-        class Tricky3 {
-            @Option(names="-t") boolean any;
-            @Parameters(index = "0") String mandatory;
-        }
-        try {
-            CommandLine.populateCommand(new Tricky3(), new String[] {"-t"});
-            fail("Should not accept missing mandatory parameter");
-        } catch (MissingParameterException ex) {
-            assertEquals("Missing required parameter: <mandatory>", ex.getMessage());
-        }
-    }
-    @Test
-    public void testNoMissingRequiredParamErrorIfHelpOptionSpecified() {
-        class App {
-            @Parameters(hidden = true)  // "hidden": don't show this parameter in usage help message
-                    List<String> allParameters; // no "index" attribute: captures _all_ arguments (as Strings)
-
-            @Parameters(index = "0")    InetAddress  host;
-            @Parameters(index = "1")    int          port;
-            @Parameters(index = "2..*") File[]       files;
-
-            @Option(names = "-?", help = true) boolean help;
-        }
-        CommandLine.populateCommand(new App(), new String[] {"-?"});
-        try {
-            CommandLine.populateCommand(new App(), new String[0]);
-            fail("Should not accept missing mandatory parameter");
-        } catch (MissingParameterException ex) {
-            assertEquals("Missing required parameters: <host>, <port>", ex.getMessage());
-        }
-    }
-    @Test
-    public void testNoMissingRequiredParamErrorWithLabelIfHelpOptionSpecified() {
-        class App {
-            @Parameters(hidden = true)  // "hidden": don't show this parameter in usage help message
-                    List<String> allParameters; // no "index" attribute: captures _all_ arguments (as Strings)
-
-            @Parameters(index = "0", paramLabel = "HOST")     InetAddress  host;
-            @Parameters(index = "1", paramLabel = "PORT")     int          port;
-            @Parameters(index = "2..*", paramLabel = "FILES") File[]       files;
-
-            @Option(names = "-?", help = true) boolean help;
-        }
-        CommandLine.populateCommand(new App(), new String[] {"-?"});
-        try {
-            CommandLine.populateCommand(new App(), new String[0]);
-            fail("Should not accept missing mandatory parameter");
-        } catch (MissingParameterException ex) {
-            assertEquals("Missing required parameters: HOST, PORT", ex.getMessage());
-        }
-    }
-
-    private static class BooleanOptionsArity0_nAndParameters {
-        @Parameters String[] params;
-        @Option(names = "-bool", arity = "0..*") boolean bool;
-        @Option(names = {"-v", "-other"}, arity="0..*") boolean vOrOther;
-        @Option(names = "-r") boolean rBoolean;
-    }
-    @Test
-    public void testBooleanOptionsArity0_nConsume1ArgumentIfPossible() { // ignores varargs
-        BooleanOptionsArity0_nAndParameters
-                params = CommandLine.populateCommand(new BooleanOptionsArity0_nAndParameters(), "-bool false false true".split(" "));
-        assertFalse(params.bool);
-        assertArrayEquals(new String[]{ "false", "true"}, params.params);
-    }
-    @Test
-    public void testBooleanOptionsArity0_nRequiresNoArgument() { // ignores varargs
-        BooleanOptionsArity0_nAndParameters
-                params = CommandLine.populateCommand(new BooleanOptionsArity0_nAndParameters(), "-bool".split(" "));
-        assertTrue(params.bool);
-    }
-    @Test
-    public void testBooleanOptionsArity0_nConsume0ArgumentsIfNextArgIsOption() { // ignores varargs
-        BooleanOptionsArity0_nAndParameters
-                params = CommandLine.populateCommand(new BooleanOptionsArity0_nAndParameters(), "-bool -other".split(" "));
-        assertTrue(params.bool);
-        assertTrue(params.vOrOther);
-    }
-    @Test
-    public void testBooleanOptionsArity0_nConsume0ArgumentsIfNextArgIsParameter() { // ignores varargs
-        BooleanOptionsArity0_nAndParameters
-                params = CommandLine.populateCommand(new BooleanOptionsArity0_nAndParameters(), "-bool 123 -other".split(" "));
-        assertTrue(params.bool);
-        assertTrue(params.vOrOther);
-        assertArrayEquals(new String[]{ "123"}, params.params);
-    }
-    @Test
-    public void testBooleanOptionsArity0_nFailsIfAttachedParamNotABoolean() { // ignores varargs
-        try {
-            CommandLine.populateCommand(new BooleanOptionsArity0_nAndParameters(), "-bool=123 -other".split(" "));
-            fail("was able to assign 123 to boolean");
-        } catch (CommandLine.ParameterException ex) {
-            assertEquals("'123' is not a boolean for option '-bool'", ex.getMessage());
-        }
-    }
-    @Test
-    public void testBooleanOptionsArity0_nShortFormFailsIfAttachedParamNotABoolean() { // ignores varargs
-        try {
-            CommandLine.populateCommand(new BooleanOptionsArity0_nAndParameters(), "-rv234 -bool".split(" "));
-            fail("Expected exception");
-        } catch (UnmatchedArgumentException ok) {
-            assertEquals("Unmatched argument [-234]", ok.getMessage());
-        }
-    }
-    @Test
-    public void testBooleanOptionsArity0_nShortFormFailsIfAttachedParamNotABooleanWithUnmatchedArgsAllowed() { // ignores varargs
-        setTraceLevel("OFF");
-        CommandLine cmd = new CommandLine(new BooleanOptionsArity0_nAndParameters()).setUnmatchedArgumentsAllowed(true);
-        cmd.parse("-rv234 -bool".split(" "));
-        assertEquals(Arrays.asList("-234"), cmd.getUnmatchedArguments());
-    }
-    @Test
-    public void testBooleanOptionsArity0_nShortFormFailsIfAttachedWithSepParamNotABoolean() { // ignores varargs
-        try {
-            CommandLine.populateCommand(new BooleanOptionsArity0_nAndParameters(), "-rv=234 -bool".split(" "));
-            fail("was able to assign 234 to boolean");
-        } catch (CommandLine.ParameterException ex) {
-            assertEquals("'234' is not a boolean for option '-v'", ex.getMessage());
-        }
-    }
-
-    private static class BooleanOptionsArity1_nAndParameters {
-        @Parameters boolean[] boolParams;
-        @Option(names = "-bool", arity = "1..*") boolean aBoolean;
-    }
-    @Test
-    public void testBooleanOptionsArity1_nConsume1Argument() { // ignores varargs
-        BooleanOptionsArity1_nAndParameters
-                params = CommandLine.populateCommand(new BooleanOptionsArity1_nAndParameters(), "-bool false false true".split(" "));
-        assertFalse(params.aBoolean);
-        assertArrayEquals(new boolean[]{ false, true}, params.boolParams);
-
-        params = CommandLine.populateCommand(new BooleanOptionsArity1_nAndParameters(), "-bool true false true".split(" "));
-        assertTrue(params.aBoolean);
-        assertArrayEquals(new boolean[]{ false, true}, params.boolParams);
-    }
-    @Test
-    public void testBooleanOptionsArity1_nCaseInsensitive() { // ignores varargs
-        BooleanOptionsArity1_nAndParameters
-                params = CommandLine.populateCommand(new BooleanOptionsArity1_nAndParameters(), "-bool fAlsE false true".split(" "));
-        assertFalse(params.aBoolean);
-        assertArrayEquals(new boolean[]{ false, true}, params.boolParams);
-
-        params = CommandLine.populateCommand(new BooleanOptionsArity1_nAndParameters(), "-bool FaLsE false true".split(" "));
-        assertFalse(params.aBoolean);
-        assertArrayEquals(new boolean[]{ false, true}, params.boolParams);
-
-        params = CommandLine.populateCommand(new BooleanOptionsArity1_nAndParameters(), "-bool tRuE false true".split(" "));
-        assertTrue(params.aBoolean);
-        assertArrayEquals(new boolean[]{ false, true}, params.boolParams);
-    }
-    @Test
-    public void testBooleanOptionsArity1_nErrorIfValueNotTrueOrFalse() { // ignores varargs
-        try {
-            CommandLine.populateCommand(new BooleanOptionsArity1_nAndParameters(), "-bool abc".split(" "));
-            fail("Invalid format abc was accepted for boolean");
-        } catch (CommandLine.ParameterException expected) {
-            assertEquals("'abc' is not a boolean for option '-bool'", expected.getMessage());
-        }
-    }
-    @Test
-    public void testBooleanOptionsArity1_nErrorIfValueMissing() {
-        try {
-            CommandLine.populateCommand(new BooleanOptionsArity1_nAndParameters(), "-bool".split(" "));
-            fail("Missing param was accepted for boolean with arity=1");
-        } catch (CommandLine.ParameterException expected) {
-            assertEquals("Missing required parameter for option '-bool' at index 0 (<aBoolean>)", expected.getMessage());
-        }
-    }
-
-    @Test
-    public void testBooleanOptionArity0Consumes0Arguments() {
-        class BooleanOptionArity0AndParameters {
-            @Parameters boolean[] boolParams;
-            @Option(names = "-bool", arity = "0") boolean aBoolean;
-        }
-        BooleanOptionArity0AndParameters
-                params = CommandLine.populateCommand(new BooleanOptionArity0AndParameters(), "-bool true false true".split(" "));
-        assertTrue(params.aBoolean);
-        assertArrayEquals(new boolean[]{true, false, true}, params.boolParams);
-    }
-    @Test(expected = MissingParameterException.class)
-    public void testSingleValueFieldDefaultMinArityIs1() {
-        CommandLine.populateCommand(new CommandLineTest.SupportedTypes(),  "-Long");
-    }
-    @Test
-    public void testSingleValueFieldDefaultMinArityIsOne() {
-        try {
-            CommandLine.populateCommand(new CommandLineTest.SupportedTypes(),  "-Long", "-boolean");
-            fail("should fail");
-        } catch (CommandLine.ParameterException ex) {
-            assertEquals("Could not convert '-boolean' to Long for option '-Long'" +
-                    ": java.lang.NumberFormatException: For input string: \"-boolean\"", ex.getMessage());
-        }
-    }
-
-    @Test
-    public void testIntOptionArity1_nConsumes1Argument() { // ignores varargs
-        class IntOptionArity1_nAndParameters {
-            @Parameters int[] intParams;
-            @Option(names = "-int", arity = "1..*") int anInt;
-        }
-        IntOptionArity1_nAndParameters
-                params = CommandLine.populateCommand(new IntOptionArity1_nAndParameters(), "-int 23 42 7".split(" "));
-        assertEquals(23, params.anInt);
-        assertArrayEquals(new int[]{ 42, 7}, params.intParams);
-    }
-
-    @Test
-    public void testArrayOptionsWithArity0Consume0Arguments() {
-        class OptionsArray0ArityAndParameters {
-            @Parameters double[] doubleParams;
-            @Option(names = "-doubles", arity = "0") double[] doubleOptions;
-        }
-        OptionsArray0ArityAndParameters
-                params = CommandLine.populateCommand(new OptionsArray0ArityAndParameters(), "-doubles 1.1 2.2 3.3 4.4".split(" "));
-        assertArrayEquals(Arrays.toString(params.doubleOptions),
-                new double[0], params.doubleOptions, 0.000001);
-        assertArrayEquals(new double[]{1.1, 2.2, 3.3, 4.4}, params.doubleParams, 0.000001);
-    }
-
-    @Test
-    public void testArrayOptionWithArity1Consumes1Argument() {
-        class Options1ArityAndParameters {
-            @Parameters double[] doubleParams;
-            @Option(names = "-doubles", arity = "1") double[] doubleOptions;
-        }
-        Options1ArityAndParameters
-                params = CommandLine.populateCommand(new Options1ArityAndParameters(), "-doubles 1.1 2.2 3.3 4.4".split(" "));
-        assertArrayEquals(Arrays.toString(params.doubleOptions),
-                new double[] {1.1}, params.doubleOptions, 0.000001);
-        assertArrayEquals(new double[]{2.2, 3.3, 4.4}, params.doubleParams, 0.000001);
-
-        // repeated occurrence
-        params = CommandLine.populateCommand(new Options1ArityAndParameters(), "-doubles 1.1 -doubles 2.2 -doubles 3.3 4.4".split(" "));
-        assertArrayEquals(Arrays.toString(params.doubleOptions),
-                new double[] {1.1, 2.2, 3.3}, params.doubleOptions, 0.000001);
-        assertArrayEquals(new double[]{4.4}, params.doubleParams, 0.000001);
-
-    }
-
-    private static class ArrayOptionArity2AndParameters {
-        @Parameters double[] doubleParams;
-        @Option(names = "-doubles", arity = "2") double[] doubleOptions;
-    }
-    @Test
-    public void testArrayOptionWithArity2Consumes2Arguments() {
-        ArrayOptionArity2AndParameters
-                params = CommandLine.populateCommand(new ArrayOptionArity2AndParameters(), "-doubles 1.1 2.2 3.3 4.4".split(" "));
-        assertArrayEquals(Arrays.toString(params.doubleOptions),
-                new double[] {1.1, 2.2, }, params.doubleOptions, 0.000001);
-        assertArrayEquals(new double[]{3.3, 4.4}, params.doubleParams, 0.000001);
-
-        // repeated occurrence
-        params = CommandLine.populateCommand(new ArrayOptionArity2AndParameters(), "-doubles 1.1 2.2 -doubles 3.3 4.4 0".split(" "));
-        assertArrayEquals(Arrays.toString(params.doubleOptions),
-                new double[] {1.1, 2.2, 3.3, 4.4 }, params.doubleOptions, 0.000001);
-        assertArrayEquals(new double[]{ 0.0 }, params.doubleParams, 0.000001);
-    }
-    @Test
-    public void testArrayOptionsWithArity2Consume2ArgumentsEvenIfFirstIsAttached() {
-        ArrayOptionArity2AndParameters
-                params = CommandLine.populateCommand(new ArrayOptionArity2AndParameters(), "-doubles=1.1 2.2 3.3 4.4".split(" "));
-        assertArrayEquals(Arrays.toString(params.doubleOptions),
-                new double[] {1.1, 2.2, }, params.doubleOptions, 0.000001);
-        assertArrayEquals(new double[]{3.3, 4.4}, params.doubleParams, 0.000001);
-
-        // repeated occurrence
-        params = CommandLine.populateCommand(new ArrayOptionArity2AndParameters(), "-doubles=1.1 2.2 -doubles=3.3 4.4 0".split(" "));
-        assertArrayEquals(Arrays.toString(params.doubleOptions),
-                new double[] {1.1, 2.2, 3.3, 4.4}, params.doubleOptions, 0.000001);
-        assertArrayEquals(new double[]{0}, params.doubleParams, 0.000001);
-    }
-    /** Arity should not limit the total number of values put in an array or collection #191 */
-    @Test
-    public void testArrayOptionsWithArity2MayContainMoreThan2Values() {
-        ArrayOptionArity2AndParameters
-                params = CommandLine.populateCommand(new ArrayOptionArity2AndParameters(), "-doubles=1 2 -doubles 3 4 -doubles 5 6".split(" "));
-        assertArrayEquals(Arrays.toString(params.doubleOptions),
-                new double[] {1, 2, 3, 4, 5, 6 }, params.doubleOptions, 0.000001);
-        assertArrayEquals(null, params.doubleParams, 0.000001);
-    }
-
-    @Test
-    public void testArrayOptionWithoutArityConsumesOneArgument() { // #192
-        class OptionsNoArityAndParameters {
-            @Parameters char[] charParams;
-            @Option(names = "-chars") char[] charOptions;
-        }
-        OptionsNoArityAndParameters
-                params = CommandLine.populateCommand(new OptionsNoArityAndParameters(), "-chars a b c d".split(" "));
-        assertArrayEquals(Arrays.toString(params.charOptions),
-                new char[] {'a', }, params.charOptions);
-        assertArrayEquals(Arrays.toString(params.charParams), new char[] {'b', 'c', 'd'}, params.charParams);
-
-        // repeated occurrence
-        params = CommandLine.populateCommand(new OptionsNoArityAndParameters(), "-chars a -chars b c d".split(" "));
-        assertArrayEquals(Arrays.toString(params.charOptions),
-                new char[] {'a', 'b', }, params.charOptions);
-        assertArrayEquals(Arrays.toString(params.charParams), new char[] {'c', 'd'}, params.charParams);
-
-        try {
-            CommandLine.populateCommand(new OptionsNoArityAndParameters(), "-chars".split(" "));
-            fail("expected MissingParameterException");
-        } catch (MissingParameterException ok) {
-            assertEquals("Missing required parameter for option '-chars' (<charOptions>)", ok.getMessage());
-        }
-    }
-
-    @Test
-    public void testArrayParametersWithDefaultArity() {
-        class ArrayParamsDefaultArity {
-            @Parameters
-            List<String> params;
-        }
-        ArrayParamsDefaultArity params = CommandLine.populateCommand(new ArrayParamsDefaultArity(), "a", "b", "c");
-        assertEquals(Arrays.asList("a", "b", "c"), params.params);
-
-        params = CommandLine.populateCommand(new ArrayParamsDefaultArity(), "a");
-        assertEquals(Arrays.asList("a"), params.params);
-
-        params = CommandLine.populateCommand(new ArrayParamsDefaultArity());
-        assertEquals(null, params.params);
-    }
-
-    @Test
-    public void testArrayParametersWithArityMinusOneToN() {
-        class ArrayParamsNegativeArity {
-            @Parameters(arity = "-1..*")
-            List<String> params;
-        }
-        ArrayParamsNegativeArity params = CommandLine.populateCommand(new ArrayParamsNegativeArity(), "a", "b", "c");
-        assertEquals(Arrays.asList("a", "b", "c"), params.params);
-
-        params = CommandLine.populateCommand(new ArrayParamsNegativeArity(), "a");
-        assertEquals(Arrays.asList("a"), params.params);
-
-        params = CommandLine.populateCommand(new ArrayParamsNegativeArity());
-        assertEquals(null, params.params);
-    }
-
-    @Test
-    public void testArrayParametersArity0_n() {
-        class ArrayParamsArity0_n {
-            @Parameters(arity = "0..*")
-            List<String> params;
-        }
-        ArrayParamsArity0_n params = CommandLine.populateCommand(new ArrayParamsArity0_n(), "a", "b", "c");
-        assertEquals(Arrays.asList("a", "b", "c"), params.params);
-
-        params = CommandLine.populateCommand(new ArrayParamsArity0_n(), "a");
-        assertEquals(Arrays.asList("a"), params.params);
-
-        params = CommandLine.populateCommand(new ArrayParamsArity0_n());
-        assertEquals(null, params.params);
-    }
-
-    @Test
-    public void testArrayParametersArity1_n() {
-        class ArrayParamsArity1_n {
-            @Parameters(arity = "1..*")
-            List<String> params;
-        }
-        ArrayParamsArity1_n params = CommandLine.populateCommand(new ArrayParamsArity1_n(), "a", "b", "c");
-        assertEquals(Arrays.asList("a", "b", "c"), params.params);
-
-        params = CommandLine.populateCommand(new ArrayParamsArity1_n(), "a");
-        assertEquals(Arrays.asList("a"), params.params);
-
-        try {
-            params = CommandLine.populateCommand(new ArrayParamsArity1_n());
-            fail("Should not accept input with missing parameter");
-        } catch (MissingParameterException ex) {
-            assertEquals("Missing required parameters at positions 0..*: <params>", ex.getMessage());
-        }
-    }
-
-    @Test
-    public void testArrayParametersArity2_n() {
-        class ArrayParamsArity2_n {
-            @Parameters(arity = "2..*")
-            List<String> params;
-        }
-        ArrayParamsArity2_n params = CommandLine.populateCommand(new ArrayParamsArity2_n(), "a", "b", "c");
-        assertEquals(Arrays.asList("a", "b", "c"), params.params);
-
-        try {
-            params = CommandLine.populateCommand(new ArrayParamsArity2_n(), "a");
-            fail("Should not accept input with missing parameter");
-        } catch (MissingParameterException ex) {
-            assertEquals("positional parameter at index 0..* (<params>) requires at least 2 values, but only 1 were specified: [a]", ex.getMessage());
-        }
-
-        try {
-            params = CommandLine.populateCommand(new ArrayParamsArity2_n());
-            fail("Should not accept input with missing parameter");
-        } catch (MissingParameterException ex) {
-            assertEquals("positional parameter at index 0..* (<params>) requires at least 2 values, but none were specified.", ex.getMessage());
-        }
-    }
-
-    @Test
-    public void testNonVarargArrayParametersWithNegativeArityConsumesZeroArguments() {
-        class NonVarArgArrayParamsNegativeArity {
-            @Parameters(arity = "-1")
-            List<String> params;
-        }
-        try {
-            CommandLine.populateCommand(new NonVarArgArrayParamsNegativeArity(), "a", "b", "c");
-            fail("Expected UnmatchedArgumentException");
-        } catch (UnmatchedArgumentException ex) {
-            assertEquals("Unmatched arguments [a, b, c]", ex.getMessage());
-        }
-        try {
-            CommandLine.populateCommand(new NonVarArgArrayParamsNegativeArity(), "a");
-            fail("Expected UnmatchedArgumentException");
-        } catch (UnmatchedArgumentException ex) {
-            assertEquals("Unmatched argument [a]", ex.getMessage());
-        }
-        NonVarArgArrayParamsNegativeArity params = CommandLine.populateCommand(new NonVarArgArrayParamsNegativeArity());
-        assertEquals(null, params.params);
-    }
-
-    @Test
-    public void testNonVarargArrayParametersWithArity0() {
-        class NonVarArgArrayParamsZeroArity {
-            @Parameters(arity = "0")
-            List<String> params;
-        }
-        try {
-            CommandLine.populateCommand(new NonVarArgArrayParamsZeroArity(), "a", "b", "c");
-            fail("Expected UnmatchedArgumentException");
-        } catch (UnmatchedArgumentException ex) {
-            assertEquals("Unmatched arguments [a, b, c]", ex.getMessage());
-        }
-        try {
-            CommandLine.populateCommand(new NonVarArgArrayParamsZeroArity(), "a");
-            fail("Expected UnmatchedArgumentException");
-        } catch (UnmatchedArgumentException ex) {
-            assertEquals("Unmatched argument [a]", ex.getMessage());
-        }
-        NonVarArgArrayParamsZeroArity params = CommandLine.populateCommand(new NonVarArgArrayParamsZeroArity());
-        assertEquals(null, params.params);
-    }
-
-    @Test
-    public void testNonVarargArrayParametersWithArity1() {
-        class NonVarArgArrayParamsArity1 {
-            @Parameters(arity = "1")
-            List<String> params;
-        }
-        NonVarArgArrayParamsArity1 actual = CommandLine.populateCommand(new NonVarArgArrayParamsArity1(), "a", "b", "c");
-        assertEquals(Arrays.asList("a", "b", "c"), actual.params);
-
-        NonVarArgArrayParamsArity1  params = CommandLine.populateCommand(new NonVarArgArrayParamsArity1(), "a");
-        assertEquals(Arrays.asList("a"), params.params);
-
-        try {
-            params = CommandLine.populateCommand(new NonVarArgArrayParamsArity1());
-            fail("Should not accept input with missing parameter");
-        } catch (MissingParameterException ex) {
-            assertEquals("Missing required parameter: <params>", ex.getMessage());
-        }
-    }
-
-    @Test
-    public void testNonVarargArrayParametersWithArity2() {
-        class NonVarArgArrayParamsArity2 {
-            @Parameters(arity = "2")
-            List<String> params;
-        }
-        NonVarArgArrayParamsArity2 params = null;
-        try {
-            CommandLine.populateCommand(new NonVarArgArrayParamsArity2(), "a", "b", "c");
-            fail("expected MissingParameterException");
-        } catch (MissingParameterException ex) {
-            assertEquals("positional parameter at index 0..* (<params>) requires at least 2 values, but only 1 were specified: [c]", ex.getMessage());
-        }
-
-        try {
-            params = CommandLine.populateCommand(new NonVarArgArrayParamsArity2(), "a");
-            fail("Should not accept input with missing parameter");
-        } catch (MissingParameterException ex) {
-            assertEquals("positional parameter at index 0..* (<params>) requires at least 2 values, but only 1 were specified: [a]", ex.getMessage());
-        }
-
-        try {
-            params = CommandLine.populateCommand(new NonVarArgArrayParamsArity2());
-            fail("Should not accept input with missing parameter");
-        } catch (MissingParameterException ex) {
-            assertEquals("positional parameter at index 0..* (<params>) requires at least 2 values, but none were specified.", ex.getMessage());
-        }
-    }
-    @Test
-    public void testMixPositionalParamsWithOptions_ParamsUnboundedArity_isGreedy() {
-        class Arg {
-            @Parameters(arity = "1..*") List<String> parameters;
-            @Option(names = "-o")    List<String> options;
-        }
-        Arg result = CommandLine.populateCommand(new Arg(), "-o", "v1", "p1", "p2", "-o", "v2", "p3", "p4");
-        assertEquals(Arrays.asList("p1", "p2", "-o", "v2", "p3", "p4"), result.parameters);
-        assertEquals(Arrays.asList("v1"), result.options);
-
-        Arg result2 = CommandLine.populateCommand(new Arg(), "-o", "v1", "p1", "-o", "v2", "p3");
-        assertEquals(Arrays.asList("p1", "-o", "v2", "p3"), result2.parameters);
-        assertEquals(Arrays.asList("v1"), result2.options);
-
-        try {
-            CommandLine.populateCommand(new Arg(), "-o", "v1", "-o", "v2");
-            fail("Expected MissingParameterException");
-        } catch (MissingParameterException ex) {
-            assertEquals("Missing required parameters at positions 0..*: <parameters>", ex.getMessage());
-        }
-    }
-
-    @Test
-    public void test130MixPositionalParamsWithOptions() {
-        @CommandLine.Command(name = "test-command", description = "tests help from a command script")
-        class Arg {
-
-            @Parameters(description = "some parameters")
-            List<String> parameters;
-
-            @Option(names = {"-cp", "--codepath"}, description = "the codepath")
-            List<String> codepath;
-        }
-        Arg result = CommandLine.populateCommand(new Arg(), "--codepath", "/usr/x.jar", "placeholder", "-cp", "/bin/y.jar", "another");
-        assertEquals(Arrays.asList("/usr/x.jar", "/bin/y.jar"), result.codepath);
-        assertEquals(Arrays.asList("placeholder", "another"), result.parameters);
-    }
-
-    @Test
-    public void test130MixPositionalParamsWithOptions1() {
-        class Arg {
-            @Parameters           List<String> parameters;
-            @Option(names = "-o") List<String> options;
-        }
-        Arg result = CommandLine.populateCommand(new Arg(), "-o", "v1", "p1", "p2", "-o", "v2", "p3");
-        assertEquals(Arrays.asList("v1", "v2"), result.options);
-        assertEquals(Arrays.asList("p1", "p2", "p3"), result.parameters);
-    }
-
-    @Test
-    public void test130MixPositionalParamsWithOptionsArity() {
-        class Arg {
-            @Parameters(arity = "2") List<String> parameters;
-            @Option(names = "-o")    List<String> options;
-        }
-        Arg result = CommandLine.populateCommand(new Arg(), "-o", "v1", "p1", "p2", "-o", "v2", "p3", "p4");
-        assertEquals(Arrays.asList("v1", "v2"), result.options);
-        assertEquals(Arrays.asList("p1", "p2", "p3", "p4"), result.parameters);
-
-        Arg result2 = CommandLine.populateCommand(new Arg(), "-o", "v1", "p1", "-o", "v2", "p3");
-        assertEquals(Arrays.asList("v1"), result2.options);
-        assertEquals(Arrays.asList("p1", "-o", "v2", "p3"), result2.parameters);
-
-        try {
-            CommandLine.populateCommand(new Arg(), "-o", "v1", "p1", "p2", "-o", "v2", "p3");
-            fail("Expected MissingParameterException");
-        } catch (MissingParameterException ex) {
-            assertEquals("positional parameter at index 0..* (<parameters>) requires at least 2 values, but only 1 were specified: [p3]", ex.getMessage());
-        }
-    }
-}


[2/4] logging-log4j2 git commit: [BUILD] removed picocli tests from core tests; they do not add value here and occasionally fail when building Log4j on a console that supports ANSI colors

Posted by rp...@apache.org.
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/dd8ded97/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/CommandLineTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/CommandLineTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/CommandLineTest.java
deleted file mode 100644
index 118a59f..0000000
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/CommandLineTest.java
+++ /dev/null
@@ -1,3188 +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.logging.log4j.core.tools.picocli;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.net.InetAddress;
-import java.net.MalformedURLException;
-import java.net.Socket;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.nio.charset.Charset;
-import java.sql.Time;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.UUID;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Pattern;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-
-import static java.util.concurrent.TimeUnit.*;
-import static org.junit.Assert.*;
-import static org.apache.logging.log4j.core.tools.picocli.CommandLine.*;
-
-/**
- * Tests for the CommandLine argument parsing interpreter functionality.
- */
-// DONE arrays
-// DONE collection fields
-// DONE all built-in types
-// DONE private fields, public fields (TODO methods?)
-// DONE arity 2, 3
-// DONE arity -1, -2, -3
-// TODO arity ignored for single-value types (non-array, non-collection)
-// DONE positional arguments with '--' separator (where positional arguments look like options)
-// DONE positional arguments without '--' separator (based on arity of last option?)
-// DONE positional arguments based on arity of last option
-// TODO ambiguous options: writing --input ARG (as opposed to --input=ARG) is ambiguous,
-// meaning it is not possible to tell whether ARG is option's argument or a positional argument.
-// In usage patterns this will be interpreted as an option with argument only if a description (covered below)
-// for that option is provided.
-// Otherwise it will be interpreted as an option and separate positional argument.
-// TODO ambiguous short options: ambiguity with the -f FILE and -fFILE notation.
-// In the latter case it is not possible to tell whether it is a number of stacked short options,
-// or an option with an argument. These notations will be interpreted as an option with argument only if a
-// description for the option is provided.
-// DONE compact flags
-// DONE compact flags where last option has an argument, separate by space
-// DONE compact flags where last option has an argument attached to the option character
-// DONE long options with argument separate by space
-// DONE long options with argument separated by '=' (no spaces)
-// TODO document that if arity>1 and args="-opt=val1 val2", arity overrules the "=": both values are assigned
-// TODO test superclass bean and child class bean where child class field shadows super class and have same annotation Option name
-// TODO test superclass bean and child class bean where child class field shadows super class and have different annotation Option name
-// DONE -vrx, -vro outputFile, -vrooutputFile, -vro=outputFile, -vro:outputFile, -vro=, -vro:, -vro
-// DONE --out outputFile, --out=outputFile, --out:outputFile, --out=, --out:, --out
-public class CommandLineTest {
-    @Before public void setUp() { System.clearProperty("picocli.trace"); }
-    @After public void tearDown() { System.clearProperty("picocli.trace"); }
-
-    private static void setTraceLevel(String level) {
-        System.setProperty("picocli.trace", level);
-    }
-    @Test
-    public void testVersion() {
-        assertEquals("2.0.3", CommandLine.VERSION);
-    }
-
-    static class SupportedTypes {
-        @Option(names = "-boolean")       boolean booleanField;
-        @Option(names = "-Boolean")       Boolean aBooleanField;
-        @Option(names = "-byte")          byte byteField;
-        @Option(names = "-Byte")          Byte aByteField;
-        @Option(names = "-char")          char charField;
-        @Option(names = "-Character")     Character aCharacterField;
-        @Option(names = "-short")         short shortField;
-        @Option(names = "-Short")         Short aShortField;
-        @Option(names = "-int")           int intField;
-        @Option(names = "-Integer")       Integer anIntegerField;
-        @Option(names = "-long")          long longField;
-        @Option(names = "-Long")          Long aLongField;
-        @Option(names = "-float")         float floatField;
-        @Option(names = "-Float")         Float aFloatField;
-        @Option(names = "-double")        double doubleField;
-        @Option(names = "-Double")        Double aDoubleField;
-        @Option(names = "-String")        String aStringField;
-        @Option(names = "-StringBuilder") StringBuilder aStringBuilderField;
-        @Option(names = "-CharSequence")  CharSequence aCharSequenceField;
-        @Option(names = "-File")          File aFileField;
-        @Option(names = "-URL")           URL anURLField;
-        @Option(names = "-URI")           URI anURIField;
-        @Option(names = "-Date")          Date aDateField;
-        @Option(names = "-Time")          Time aTimeField;
-        @Option(names = "-BigDecimal")    BigDecimal aBigDecimalField;
-        @Option(names = "-BigInteger")    BigInteger aBigIntegerField;
-        @Option(names = "-Charset")       Charset aCharsetField;
-        @Option(names = "-InetAddress")   InetAddress anInetAddressField;
-        @Option(names = "-Pattern")       Pattern aPatternField;
-        @Option(names = "-UUID")          UUID anUUIDField;
-    }
-    @Test
-    public void testDefaults() {
-        SupportedTypes bean = CommandLine.populateCommand(new SupportedTypes());
-        assertEquals("boolean", false, bean.booleanField);
-        assertEquals("Boolean", null, bean.aBooleanField);
-        assertEquals("byte", 0, bean.byteField);
-        assertEquals("Byte", null, bean.aByteField);
-        assertEquals("char", 0, bean.charField);
-        assertEquals("Character", null, bean.aCharacterField);
-        assertEquals("short", 0, bean.shortField);
-        assertEquals("Short", null, bean.aShortField);
-        assertEquals("int", 0, bean.intField);
-        assertEquals("Integer", null, bean.anIntegerField);
-        assertEquals("long", 0, bean.longField);
-        assertEquals("Long", null, bean.aLongField);
-        assertEquals("float", 0f, bean.floatField, Float.MIN_VALUE);
-        assertEquals("Float", null, bean.aFloatField);
-        assertEquals("double", 0d, bean.doubleField, Double.MIN_VALUE);
-        assertEquals("Double", null, bean.aDoubleField);
-        assertEquals("String", null, bean.aStringField);
-        assertEquals("StringBuilder", null, bean.aStringBuilderField);
-        assertEquals("CharSequence", null, bean.aCharSequenceField);
-        assertEquals("File", null, bean.aFileField);
-        assertEquals("URL", null, bean.anURLField);
-        assertEquals("URI", null, bean.anURIField);
-        assertEquals("Date", null, bean.aDateField);
-        assertEquals("Time", null, bean.aTimeField);
-        assertEquals("BigDecimal", null, bean.aBigDecimalField);
-        assertEquals("BigInteger", null, bean.aBigIntegerField);
-        assertEquals("Charset", null, bean.aCharsetField);
-        assertEquals("InetAddress", null, bean.anInetAddressField);
-        assertEquals("Pattern", null, bean.aPatternField);
-        assertEquals("UUID", null, bean.anUUIDField);
-    }
-    @Test
-    public void testTypeConversionSucceedsForValidInput()
-            throws MalformedURLException, URISyntaxException, UnknownHostException, ParseException {
-        SupportedTypes bean = CommandLine.populateCommand(new SupportedTypes(),
-                "-boolean", "-Boolean", //
-                "-byte", "12", "-Byte", "23", //
-                "-char", "p", "-Character", "i", //
-                "-short", "34", "-Short", "45", //
-                "-int", "56", "-Integer", "67", //
-                "-long", "78", "-Long", "89", //
-                "-float", "1.23", "-Float", "2.34", //
-                "-double", "3.45", "-Double", "4.56", //
-                "-String", "abc", "-StringBuilder", "bcd", "-CharSequence", "xyz", //
-                "-File", "abc.txt", //
-                "-URL", "http://pico-cli.github.io", //
-                "-URI", "http://pico-cli.github.io/index.html", //
-                "-Date", "2017-01-30", //
-                "-Time", "23:59:59", //
-                "-BigDecimal", "12345678901234567890.123", //
-                "-BigInteger", "123456789012345678901", //
-                "-Charset", "UTF8", //
-                "-InetAddress", InetAddress.getLocalHost().getHostName(), //
-                "-Pattern", "a*b", //
-                "-UUID", "c7d51423-bf9d-45dd-a30d-5b16fafe42e2"
-        );
-        assertEquals("boolean", true, bean.booleanField);
-        assertEquals("Boolean", Boolean.TRUE, bean.aBooleanField);
-        assertEquals("byte", 12, bean.byteField);
-        assertEquals("Byte", Byte.valueOf((byte) 23), bean.aByteField);
-        assertEquals("char", 'p', bean.charField);
-        assertEquals("Character", Character.valueOf('i'), bean.aCharacterField);
-        assertEquals("short", 34, bean.shortField);
-        assertEquals("Short", Short.valueOf((short) 45), bean.aShortField);
-        assertEquals("int", 56, bean.intField);
-        assertEquals("Integer", Integer.valueOf(67), bean.anIntegerField);
-        assertEquals("long", 78L, bean.longField);
-        assertEquals("Long", Long.valueOf(89L), bean.aLongField);
-        assertEquals("float", 1.23f, bean.floatField, Float.MIN_VALUE);
-        assertEquals("Float", Float.valueOf(2.34f), bean.aFloatField);
-        assertEquals("double", 3.45, bean.doubleField, Double.MIN_VALUE);
-        assertEquals("Double", Double.valueOf(4.56), bean.aDoubleField);
-        assertEquals("String", "abc", bean.aStringField);
-        assertEquals("StringBuilder type", StringBuilder.class, bean.aStringBuilderField.getClass());
-        assertEquals("StringBuilder", "bcd", bean.aStringBuilderField.toString());
-        assertEquals("CharSequence", "xyz", bean.aCharSequenceField);
-        assertEquals("File", new File("abc.txt"), bean.aFileField);
-        assertEquals("URL", new URL("http://pico-cli.github.io"), bean.anURLField);
-        assertEquals("URI", new URI("http://pico-cli.github.io/index.html"), bean.anURIField);
-        assertEquals("Date", new SimpleDateFormat("yyyy-MM-dd").parse("2017-01-30"), bean.aDateField);
-        assertEquals("Time", new Time(new SimpleDateFormat("HH:mm:ss").parse("23:59:59").getTime()), bean.aTimeField);
-        assertEquals("BigDecimal", new BigDecimal("12345678901234567890.123"), bean.aBigDecimalField);
-        assertEquals("BigInteger", new BigInteger("123456789012345678901"), bean.aBigIntegerField);
-        assertEquals("Charset", Charset.forName("UTF8"), bean.aCharsetField);
-        assertEquals("InetAddress", InetAddress.getByName(InetAddress.getLocalHost().getHostName()), bean.anInetAddressField);
-        assertEquals("Pattern", Pattern.compile("a*b").pattern(), bean.aPatternField.pattern());
-        assertEquals("UUID", UUID.fromString("c7d51423-bf9d-45dd-a30d-5b16fafe42e2"), bean.anUUIDField);
-    }
-    @Test
-    public void testByteFieldsAreDecimal() {
-        try {
-            CommandLine.populateCommand(new SupportedTypes(), "-byte", "0x1F", "-Byte", "0x0F");
-            fail("Should fail on hex input");
-        } catch (ParameterException expected) {
-            assertEquals("Could not convert '0x1F' to byte for option '-byte'" +
-                    ": java.lang.NumberFormatException: For input string: \"0x1F\"", expected.getMessage());
-        }
-    }
-    @Test
-    public void testCustomByteConverterAcceptsHexadecimalDecimalAndOctal() {
-        SupportedTypes bean = new SupportedTypes();
-        CommandLine commandLine = new CommandLine(bean);
-        ITypeConverter<Byte> converter = new ITypeConverter<Byte>() {
-            @Override
-            public Byte convert(String s) {
-                return Byte.decode(s);
-            }
-        };
-        commandLine.registerConverter(Byte.class, converter);
-        commandLine.registerConverter(Byte.TYPE, converter);
-        commandLine.parse("-byte", "0x1F", "-Byte", "0x0F");
-        assertEquals(0x1F, bean.byteField);
-        assertEquals(Byte.valueOf((byte) 0x0F), bean.aByteField);
-
-        commandLine.parse("-byte", "010", "-Byte", "010");
-        assertEquals(8, bean.byteField);
-        assertEquals(Byte.valueOf((byte) 8), bean.aByteField);
-
-        commandLine.parse("-byte", "34", "-Byte", "34");
-        assertEquals(34, bean.byteField);
-        assertEquals(Byte.valueOf((byte) 34), bean.aByteField);
-    }
-    @Test
-    public void testShortFieldsAreDecimal() {
-        try {
-            CommandLine.populateCommand(new SupportedTypes(), "-short", "0xFF", "-Short", "0x6FFE");
-            fail("Should fail on hex input");
-        } catch (ParameterException expected) {
-            assertEquals("Could not convert '0xFF' to short for option '-short'" +
-                    ": java.lang.NumberFormatException: For input string: \"0xFF\"", expected.getMessage());
-        }
-    }
-    @Test
-    public void testCustomShortConverterAcceptsHexadecimalDecimalAndOctal() {
-        SupportedTypes bean = new SupportedTypes();
-        CommandLine commandLine = new CommandLine(bean);
-        ITypeConverter<Short> shortConverter = new ITypeConverter<Short>() {
-            @Override
-            public Short convert(String s) {
-                return Short.decode(s);
-            }
-        };
-        commandLine.registerConverter(Short.class, shortConverter);
-        commandLine.registerConverter(Short.TYPE, shortConverter);
-        commandLine.parse("-short", "0xFF", "-Short", "0x6FFE");
-        assertEquals(0xFF, bean.shortField);
-        assertEquals(Short.valueOf((short) 0x6FFE), bean.aShortField);
-
-        commandLine.parse("-short", "010", "-Short", "010");
-        assertEquals(8, bean.shortField);
-        assertEquals(Short.valueOf((short) 8), bean.aShortField);
-
-        commandLine.parse("-short", "34", "-Short", "34");
-        assertEquals(34, bean.shortField);
-        assertEquals(Short.valueOf((short) 34), bean.aShortField);
-    }
-    @Test
-    public void testIntFieldsAreDecimal() {
-        try {
-            CommandLine.populateCommand(new SupportedTypes(), "-int", "0xFF", "-Integer", "0xFFFF");
-            fail("Should fail on hex input");
-        } catch (ParameterException expected) {
-            assertEquals("Could not convert '0xFF' to int for option '-int'" +
-                    ": java.lang.NumberFormatException: For input string: \"0xFF\"", expected.getMessage());
-        }
-    }
-    @Test
-    public void testCustomIntConverterAcceptsHexadecimalDecimalAndOctal() {
-        SupportedTypes bean = new SupportedTypes();
-        CommandLine commandLine = new CommandLine(bean);
-        ITypeConverter<Integer> intConverter = new ITypeConverter<Integer>() {
-            @Override
-            public Integer convert(String s) {
-                return Integer.decode(s);
-            }
-        };
-        commandLine.registerConverter(Integer.class, intConverter);
-        commandLine.registerConverter(Integer.TYPE, intConverter);
-        commandLine.parse("-int", "0xFF", "-Integer", "0xFFFF");
-        assertEquals(255, bean.intField);
-        assertEquals(Integer.valueOf(0xFFFF), bean.anIntegerField);
-
-        commandLine.parse("-int", "010", "-Integer", "010");
-        assertEquals(8, bean.intField);
-        assertEquals(Integer.valueOf(8), bean.anIntegerField);
-
-        commandLine.parse("-int", "34", "-Integer", "34");
-        assertEquals(34, bean.intField);
-        assertEquals(Integer.valueOf(34), bean.anIntegerField);
-    }
-    @Test
-    public void testLongFieldsAreDecimal() {
-        try {
-            CommandLine.populateCommand(new SupportedTypes(), "-long", "0xAABBCC", "-Long", "0xAABBCCDD");
-            fail("Should fail on hex input");
-        } catch (ParameterException expected) {
-            assertEquals("Could not convert '0xAABBCC' to long for option '-long'" +
-                    ": java.lang.NumberFormatException: For input string: \"0xAABBCC\"", expected.getMessage());
-        }
-    }
-    @Test
-    public void testCustomLongConverterAcceptsHexadecimalDecimalAndOctal() {
-        SupportedTypes bean = new SupportedTypes();
-        CommandLine commandLine = new CommandLine(bean);
-        ITypeConverter<Long> longConverter = new ITypeConverter<Long>() {
-            @Override
-            public Long convert(String s) {
-                return Long.decode(s);
-            }
-        };
-        commandLine.registerConverter(Long.class, longConverter);
-        commandLine.registerConverter(Long.TYPE, longConverter);
-        commandLine.parse("-long", "0xAABBCC", "-Long", "0xAABBCCDD");
-        assertEquals(0xAABBCC, bean.longField);
-        assertEquals(Long.valueOf(0xAABBCCDDL), bean.aLongField);
-
-        commandLine.parse("-long", "010", "-Long", "010");
-        assertEquals(8, bean.longField);
-        assertEquals(Long.valueOf(8), bean.aLongField);
-
-        commandLine.parse("-long", "34", "-Long", "34");
-        assertEquals(34, bean.longField);
-        assertEquals(Long.valueOf(34), bean.aLongField);
-    }
-    @Test
-    public void testTimeFormatHHmmSupported() throws ParseException {
-        SupportedTypes bean = CommandLine.populateCommand(new SupportedTypes(), "-Time", "23:59");
-        assertEquals("Time", new Time(new SimpleDateFormat("HH:mm").parse("23:59").getTime()), bean.aTimeField);
-    }
-    @Test
-    public void testTimeFormatHHmmssSupported() throws ParseException {
-        SupportedTypes bean = CommandLine.populateCommand(new SupportedTypes(), "-Time", "23:59:58");
-        assertEquals("Time", new Time(new SimpleDateFormat("HH:mm:ss").parse("23:59:58").getTime()), bean.aTimeField);
-    }
-    @Test
-    public void testTimeFormatHHmmssDotSSSSupported() throws ParseException {
-        SupportedTypes bean = CommandLine.populateCommand(new SupportedTypes(), "-Time", "23:59:58.123");
-        assertEquals("Time", new Time(new SimpleDateFormat("HH:mm:ss.SSS").parse("23:59:58.123").getTime()), bean.aTimeField);
-    }
-    @Test
-    public void testTimeFormatHHmmssCommaSSSSupported() throws ParseException {
-        SupportedTypes bean = CommandLine.populateCommand(new SupportedTypes(), "-Time", "23:59:58,123");
-        assertEquals("Time", new Time(new SimpleDateFormat("HH:mm:ss,SSS").parse("23:59:58,123").getTime()), bean.aTimeField);
-    }
-    @Test
-    public void testTimeFormatHHmmssSSSInvalidError() throws ParseException {
-        try {
-            CommandLine.populateCommand(new SupportedTypes(), "-Time", "23:59:58;123");
-            fail("Invalid format was accepted");
-        } catch (ParameterException expected) {
-            assertEquals("'23:59:58;123' is not a HH:mm[:ss[.SSS]] time for option '-Time'", expected.getMessage());
-        }
-    }
-    @Test
-    public void testTimeFormatHHmmssDotInvalidError() throws ParseException {
-        try {
-            CommandLine.populateCommand(new SupportedTypes(), "-Time", "23:59:58.");
-            fail("Invalid format was accepted");
-        } catch (ParameterException expected) {
-            assertEquals("'23:59:58.' is not a HH:mm[:ss[.SSS]] time for option '-Time'", expected.getMessage());
-        }
-    }
-    @Test
-    public void testTimeFormatHHmmsssInvalidError() throws ParseException {
-        try {
-            CommandLine.populateCommand(new SupportedTypes(), "-Time", "23:59:587");
-            fail("Invalid format was accepted");
-        } catch (ParameterException expected) {
-            assertEquals("'23:59:587' is not a HH:mm[:ss[.SSS]] time for option '-Time'", expected.getMessage());
-        }
-    }
-    @Test
-    public void testTimeFormatHHmmssColonInvalidError() throws ParseException {
-        try {
-            CommandLine.populateCommand(new SupportedTypes(), "-Time", "23:59:");
-            fail("Invalid format was accepted");
-        } catch (ParameterException expected) {
-            assertEquals("'23:59:' is not a HH:mm[:ss[.SSS]] time for option '-Time'", expected.getMessage());
-        }
-    }
-    @Test
-    public void testDateFormatYYYYmmddInvalidError() throws ParseException {
-        try {
-            CommandLine.populateCommand(new SupportedTypes(), "-Date", "20170131");
-            fail("Invalid format was accepted");
-        } catch (ParameterException expected) {
-            assertEquals("'20170131' is not a yyyy-MM-dd date for option '-Date'", expected.getMessage());
-        }
-    }
-    @Test
-    public void testCharConverterInvalidError() throws ParseException {
-        try {
-            CommandLine.populateCommand(new SupportedTypes(), "-Character", "aa");
-            fail("Invalid format was accepted");
-        } catch (ParameterException expected) {
-            assertEquals("'aa' is not a single character for option '-Character'", expected.getMessage());
-        }
-        try {
-            CommandLine.populateCommand(new SupportedTypes(), "-char", "aa");
-            fail("Invalid format was accepted");
-        } catch (ParameterException expected) {
-            assertEquals("'aa' is not a single character for option '-char'", expected.getMessage());
-        }
-    }
-    @Test
-    public void testNumberConvertersInvalidError() {
-        parseInvalidValue("-Byte", "aa", ": java.lang.NumberFormatException: For input string: \"aa\"");
-        parseInvalidValue("-byte", "aa", ": java.lang.NumberFormatException: For input string: \"aa\"");
-        parseInvalidValue("-Short", "aa", ": java.lang.NumberFormatException: For input string: \"aa\"");
-        parseInvalidValue("-short", "aa", ": java.lang.NumberFormatException: For input string: \"aa\"");
-        parseInvalidValue("-Integer", "aa", ": java.lang.NumberFormatException: For input string: \"aa\"");
-        parseInvalidValue("-int", "aa", ": java.lang.NumberFormatException: For input string: \"aa\"");
-        parseInvalidValue("-Long", "aa", ": java.lang.NumberFormatException: For input string: \"aa\"");
-        parseInvalidValue("-long", "aa", ": java.lang.NumberFormatException: For input string: \"aa\"");
-        parseInvalidValue("-Float", "aa", ": java.lang.NumberFormatException: For input string: \"aa\"");
-        parseInvalidValue("-float", "aa", ": java.lang.NumberFormatException: For input string: \"aa\"");
-        parseInvalidValue("-Double", "aa", ": java.lang.NumberFormatException: For input string: \"aa\"");
-        parseInvalidValue("-double", "aa", ": java.lang.NumberFormatException: For input string: \"aa\"");
-        parseInvalidValue("-BigDecimal", "aa", ": java.lang.NumberFormatException");
-        parseInvalidValue("-BigInteger", "aa", ": java.lang.NumberFormatException: For input string: \"aa\"");
-    }
-    @Test
-    public void testURLConvertersInvalidError() {
-        parseInvalidValue("-URL", ":::", ": java.net.MalformedURLException: no protocol: :::");
-    }
-    @Test
-    public void testURIConvertersInvalidError() {
-        parseInvalidValue("-URI", ":::", ": java.net.URISyntaxException: Expected scheme name at index 0: :::");
-    }
-    @Test
-    public void testCharsetConvertersInvalidError() {
-        parseInvalidValue("-Charset", "aa", ": java.nio.charset.UnsupportedCharsetException: aa");
-    }
-    @Test
-    public void testInetAddressConvertersInvalidError() {
-        parseInvalidValue("-InetAddress", "%$::a?*!a", ": java.net.UnknownHostException: %$::a?*!a");
-    }
-    @Test
-    public void testUUIDConvertersInvalidError() {
-        parseInvalidValue("-UUID", "aa", ": java.lang.IllegalArgumentException: Invalid UUID string: aa");
-    }
-    @Test
-    public void testRegexPatternConverterInvalidError() {
-        parseInvalidValue("-Pattern", "[[(aa", String.format(": java.util.regex.PatternSyntaxException: Unclosed character class near index 4%n" +
-                "[[(aa%n" +
-                "    ^"));
-    }
-
-    private void parseInvalidValue(String option, String value, String errorMessage) {
-        try {
-            CommandLine.populateCommand(new SupportedTypes(), option, value);
-            fail("Invalid format " + value + " was accepted for " + option);
-        } catch (ParameterException actual) {
-            String type = option.substring(1);
-            String expected = "Could not convert '" + value + "' to " + type + " for option '" + option + "'" + errorMessage;
-            assertTrue("expected:<" + expected + "> but was:<" + actual.getMessage() + ">",
-                    actual.getMessage().startsWith(actual.getMessage()));
-        }
-    }
-
-    @Test
-    public void testCustomConverter() {
-        class Glob {
-            public final String glob;
-            public Glob(String glob) { this.glob = glob; }
-        }
-        class App {
-            @Parameters Glob globField;
-        }
-        class GlobConverter implements ITypeConverter<Glob> {
-            @Override
-            public Glob convert(String value) throws Exception { return new Glob(value); }
-        }
-        CommandLine commandLine = new CommandLine(new App());
-        commandLine.registerConverter(Glob.class, new GlobConverter());
-
-        String[] args = {"a*glob*pattern"};
-        List<CommandLine> parsed = commandLine.parse(args);
-        assertEquals("not empty", 1, parsed.size());
-        assertTrue(parsed.get(0).getCommand() instanceof App);
-        App app = (App) parsed.get(0).getCommand();
-        assertEquals(args[0], app.globField.glob);
-    }
-
-    private static class EnumParams {
-        @Option(names = "-timeUnit") TimeUnit timeUnit;
-        @Option(names = "-timeUnitArray", arity = "2") TimeUnit[] timeUnitArray;
-        @Option(names = "-timeUnitList", type = TimeUnit.class, arity = "3") List<TimeUnit> timeUnitList;
-    }
-    @Test
-    public void testEnumTypeConversionSuceedsForValidInput() {
-        EnumParams params = CommandLine.populateCommand(new EnumParams(),
-                "-timeUnit SECONDS -timeUnitArray MILLISECONDS SECONDS -timeUnitList SECONDS MICROSECONDS NANOSECONDS".split(" "));
-        assertEquals(SECONDS, params.timeUnit);
-        assertArrayEquals(new TimeUnit[]{MILLISECONDS, TimeUnit.SECONDS}, params.timeUnitArray);
-        List<TimeUnit> expected = new ArrayList<TimeUnit>(Arrays.asList(TimeUnit.SECONDS, TimeUnit.MICROSECONDS, TimeUnit.NANOSECONDS));
-        assertEquals(expected, params.timeUnitList);
-    }
-    @Test
-    public void testEnumTypeConversionFailsForInvalidInput() {
-        try {
-            CommandLine.populateCommand(new EnumParams(), "-timeUnit", "xyz");
-            fail("Accepted invalid timeunit");
-        } catch (Exception ex) {
-            String prefix = "Could not convert 'xyz' to TimeUnit for option '-timeUnit'" +
-                    ": java.lang.IllegalArgumentException: No enum cons";
-            String suffix = " java.util.concurrent.TimeUnit.xyz";
-            assertEquals(prefix, ex.getMessage().substring(0, prefix.length()));
-            assertEquals(suffix, ex.getMessage().substring(ex.getMessage().length() - suffix.length(), ex.getMessage().length()));
-        }
-    }
-    @Ignore("Requires #14 case-insensitive enum parsing")
-    @Test
-    public void testEnumTypeConversionIsCaseInsensitive() {
-        EnumParams params = CommandLine.populateCommand(new EnumParams(),
-                "-timeUnit sEcONds -timeUnitArray milliSeconds miCroSeConds -timeUnitList SEConds MiCROsEconds nanoSEConds".split(" "));
-        assertEquals(SECONDS, params.timeUnit);
-        assertArrayEquals(new TimeUnit[]{MILLISECONDS, TimeUnit.MICROSECONDS}, params.timeUnitArray);
-        List<TimeUnit> expected = new ArrayList<TimeUnit>(Arrays.asList(TimeUnit.SECONDS, TimeUnit.MICROSECONDS, TimeUnit.NANOSECONDS));
-        assertEquals(expected, params.timeUnitList);
-    }
-    @Test
-    public void testEnumArrayTypeConversionFailsForInvalidInput() {
-        try {
-            CommandLine.populateCommand(new EnumParams(), "-timeUnitArray", "a", "b");
-            fail("Accepted invalid timeunit");
-        } catch (Exception ex) {
-            String prefix = "Could not convert 'a' to TimeUnit for option '-timeUnitArray' at index 0 (<timeUnitArray>)" +
-                    ": java.lang.IllegalArgumentException: No enum const";
-            String suffix = " java.util.concurrent.TimeUnit.a";
-            assertEquals(prefix, ex.getMessage().substring(0, prefix.length()));
-            assertEquals(suffix, ex.getMessage().substring(ex.getMessage().length() - suffix.length(), ex.getMessage().length()));
-        }
-    }
-    @Test
-    public void testEnumListTypeConversionFailsForInvalidInput() {
-        try {
-            CommandLine.populateCommand(new EnumParams(), "-timeUnitList", "SECONDS", "b", "c");
-            fail("Accepted invalid timeunit");
-        } catch (Exception ex) {
-            String prefix = "Could not convert 'b' to TimeUnit for option '-timeUnitList' at index 1 (<timeUnitList>)" +
-                    ": java.lang.IllegalArgumentException: No enum const";
-            String suffix = " java.util.concurrent.TimeUnit.b";
-            assertEquals(prefix, ex.getMessage().substring(0, prefix.length()));
-            assertEquals(suffix, ex.getMessage().substring(ex.getMessage().length() - suffix.length(), ex.getMessage().length()));
-        }
-    }
-
-    @Test
-    public void testArrayOptionParametersAreAlwaysInstantiated() {
-        EnumParams params = new EnumParams();
-        TimeUnit[] array = params.timeUnitArray;
-        new CommandLine(params).parse("-timeUnitArray", "SECONDS", "MILLISECONDS");
-        assertNotSame(array, params.timeUnitArray);
-    }
-    @Test
-    public void testListOptionParametersAreInstantiatedIfNull() {
-        EnumParams params = new EnumParams();
-        assertNull(params.timeUnitList);
-        new CommandLine(params).parse("-timeUnitList", "SECONDS", "MICROSECONDS", "MILLISECONDS");
-        assertEquals(Arrays.asList(SECONDS, MICROSECONDS, MILLISECONDS), params.timeUnitList);
-    }
-    @Test
-    public void testListOptionParametersAreReusedInstantiatedIfNonNull() {
-        EnumParams params = new EnumParams();
-        List<TimeUnit> list = new ArrayList<TimeUnit>();
-        params.timeUnitList = list;
-        new CommandLine(params).parse("-timeUnitList", "SECONDS", "MICROSECONDS", "SECONDS");
-        assertEquals(Arrays.asList(SECONDS, MICROSECONDS, SECONDS), params.timeUnitList);
-        assertSame(list, params.timeUnitList);
-    }
-    @Test
-    public void testArrayPositionalParametersAreAppendedNotReplaced() {
-        class ArrayPositionalParams {
-            @Parameters() int[] array;
-        }
-        ArrayPositionalParams params = new ArrayPositionalParams();
-        params.array = new int[3];
-        int[] array = params.array;
-        new CommandLine(params).parse("3", "2", "1");
-        assertNotSame(array, params.array);
-        assertArrayEquals(new int[]{0, 0, 0, 3, 2, 1}, params.array);
-    }
-    private class ListPositionalParams {
-        @Parameters(type = Integer.class) List<Integer> list;
-    }
-    @Test
-    public void testListPositionalParametersAreInstantiatedIfNull() {
-        ListPositionalParams params = new ListPositionalParams();
-        assertNull(params.list);
-        new CommandLine(params).parse("3", "2", "1");
-        assertNotNull(params.list);
-        assertEquals(Arrays.asList(3, 2, 1), params.list);
-    }
-    @Test
-    public void testListPositionalParametersAreReusedIfNonNull() {
-        ListPositionalParams params = new ListPositionalParams();
-        params.list = new ArrayList<Integer>();
-        List<Integer> list = params.list;
-        new CommandLine(params).parse("3", "2", "1");
-        assertSame(list, params.list);
-        assertEquals(Arrays.asList(3, 2, 1), params.list);
-    }
-    @Test
-    public void testListPositionalParametersAreAppendedToIfNonNull() {
-        ListPositionalParams params = new ListPositionalParams();
-        params.list = new ArrayList<Integer>();
-        params.list.add(234);
-        List<Integer> list = params.list;
-        new CommandLine(params).parse("3", "2", "1");
-        assertSame(list, params.list);
-        assertEquals(Arrays.asList(234, 3, 2, 1), params.list);
-    }
-    class SortedSetPositionalParams {
-        @Parameters(type = Integer.class) SortedSet<Integer> sortedSet;
-    }
-    @Test
-    public void testSortedSetPositionalParametersAreInstantiatedIfNull() {
-        SortedSetPositionalParams params = new SortedSetPositionalParams();
-        assertNull(params.sortedSet);
-        new CommandLine(params).parse("3", "2", "1");
-        assertNotNull(params.sortedSet);
-        assertEquals(Arrays.asList(1, 2, 3), new ArrayList<Integer>(params.sortedSet));
-    }
-    @Test
-    public void testSortedSetPositionalParametersAreReusedIfNonNull() {
-        SortedSetPositionalParams params = new SortedSetPositionalParams();
-        params.sortedSet = new TreeSet<Integer>();
-        SortedSet<Integer> list = params.sortedSet;
-        new CommandLine(params).parse("3", "2", "1");
-        assertSame(list, params.sortedSet);
-        assertEquals(Arrays.asList(1, 2, 3), new ArrayList<Integer>(params.sortedSet));
-    }
-    @Test
-    public void testSortedSetPositionalParametersAreAppendedToIfNonNull() {
-        SortedSetPositionalParams params = new SortedSetPositionalParams();
-        params.sortedSet = new TreeSet<Integer>();
-        params.sortedSet.add(234);
-        SortedSet<Integer> list = params.sortedSet;
-        new CommandLine(params).parse("3", "2", "1");
-        assertSame(list, params.sortedSet);
-        assertEquals(Arrays.asList(1, 2, 3, 234), new ArrayList<Integer>(params.sortedSet));
-    }
-    class SetPositionalParams {
-        @Parameters(type = Integer.class) Set<Integer> set;
-    }
-    @Test
-    public void testSetPositionalParametersAreInstantiatedIfNull() {
-        SetPositionalParams params = new SetPositionalParams();
-        assertNull(params.set);
-        new CommandLine(params).parse("3", "2", "1");
-        assertNotNull(params.set);
-        assertEquals(new HashSet(Arrays.asList(1, 2, 3)), params.set);
-    }
-    @Test
-    public void testSetPositionalParametersAreReusedIfNonNull() {
-        SetPositionalParams params = new SetPositionalParams();
-        params.set = new TreeSet<Integer>();
-        Set<Integer> list = params.set;
-        new CommandLine(params).parse("3", "2", "1");
-        assertSame(list, params.set);
-        assertEquals(new HashSet(Arrays.asList(1, 2, 3)), params.set);
-    }
-    @Test
-    public void testSetPositionalParametersAreAppendedToIfNonNull() {
-        SetPositionalParams params = new SetPositionalParams();
-        params.set = new TreeSet<Integer>();
-        params.set.add(234);
-        Set<Integer> list = params.set;
-        new CommandLine(params).parse("3", "2", "1");
-        assertSame(list, params.set);
-        assertEquals(new HashSet(Arrays.asList(1, 2, 3, 234)), params.set);
-    }
-    class QueuePositionalParams {
-        @Parameters(type = Integer.class) Queue<Integer> queue;
-    }
-    @Test
-    public void testQueuePositionalParametersAreInstantiatedIfNull() {
-        QueuePositionalParams params = new QueuePositionalParams();
-        assertNull(params.queue);
-        new CommandLine(params).parse("3", "2", "1");
-        assertNotNull(params.queue);
-        assertEquals(new LinkedList(Arrays.asList(3, 2, 1)), params.queue);
-    }
-    @Test
-    public void testQueuePositionalParametersAreReusedIfNonNull() {
-        QueuePositionalParams params = new QueuePositionalParams();
-        params.queue = new LinkedList<Integer>();
-        Queue<Integer> list = params.queue;
-        new CommandLine(params).parse("3", "2", "1");
-        assertSame(list, params.queue);
-        assertEquals(new LinkedList(Arrays.asList(3, 2, 1)), params.queue);
-    }
-    @Test
-    public void testQueuePositionalParametersAreAppendedToIfNonNull() {
-        QueuePositionalParams params = new QueuePositionalParams();
-        params.queue = new LinkedList<Integer>();
-        params.queue.add(234);
-        Queue<Integer> list = params.queue;
-        new CommandLine(params).parse("3", "2", "1");
-        assertSame(list, params.queue);
-        assertEquals(new LinkedList(Arrays.asList(234, 3, 2, 1)), params.queue);
-    }
-    class CollectionPositionalParams {
-        @Parameters(type = Integer.class) Collection<Integer> collection;
-    }
-    @Test
-    public void testCollectionPositionalParametersAreInstantiatedIfNull() {
-        CollectionPositionalParams params = new CollectionPositionalParams();
-        assertNull(params.collection);
-        new CommandLine(params).parse("3", "2", "1");
-        assertNotNull(params.collection);
-        assertEquals(Arrays.asList(3, 2, 1), params.collection);
-    }
-    @Test
-    public void testCollectionPositionalParametersAreReusedIfNonNull() {
-        CollectionPositionalParams params = new CollectionPositionalParams();
-        params.collection = new ArrayList<Integer>();
-        Collection<Integer> list = params.collection;
-        new CommandLine(params).parse("3", "2", "1");
-        assertSame(list, params.collection);
-        assertEquals(Arrays.asList(3, 2, 1), params.collection);
-    }
-    @Test
-    public void testCollectionPositionalParametersAreAppendedToIfNonNull() {
-        CollectionPositionalParams params = new CollectionPositionalParams();
-        params.collection = new ArrayList<Integer>();
-        params.collection.add(234);
-        Collection<Integer> list = params.collection;
-        new CommandLine(params).parse("3", "2", "1");
-        assertSame(list, params.collection);
-        assertEquals(Arrays.asList(234, 3, 2, 1), params.collection);
-    }
-
-    @Test(expected = DuplicateOptionAnnotationsException.class)
-    public void testDuplicateOptionsAreRejected() {
-        /** Duplicate parameter names are invalid. */
-        class DuplicateOptions {
-            @Option(names = "-duplicate") public int value1;
-            @Option(names = "-duplicate") public int value2;
-        }
-        new CommandLine(new DuplicateOptions());
-    }
-
-    @Test(expected = DuplicateOptionAnnotationsException.class)
-    public void testClashingAnnotationsAreRejected() {
-        class ClashingAnnotation {
-            @Option(names = "-o")
-            @Parameters
-            public String[] bothOptionAndParameters;
-        }
-        new CommandLine(new ClashingAnnotation());
-    }
-
-    private static class PrivateFinalOptionFields {
-        @Option(names = "-f") private final String field = null;
-        @Option(names = "-p") private final int primitive = 43;
-    }
-    @Test
-    public void testCanInitializePrivateFinalFields() {
-        PrivateFinalOptionFields ff = CommandLine.populateCommand(new PrivateFinalOptionFields(), "-f", "reference value");
-        assertEquals("reference value", ff.field);
-    }
-    @Ignore("Needs Reject final primitive fields annotated with @Option or @Parameters #68")
-    @Test
-    public void testCanInitializeFinalPrimitiveFields() {
-        PrivateFinalOptionFields ff = CommandLine.populateCommand(new PrivateFinalOptionFields(), "-p", "12");
-        assertEquals("primitive value", 12, ff.primitive);
-    }
-    @Test
-    public void testLastValueSelectedIfOptionSpecifiedMultipleTimes() {
-        setTraceLevel("OFF");
-        CommandLine cmd = new CommandLine(new PrivateFinalOptionFields()).setOverwrittenOptionsAllowed(true);
-        cmd.parse("-f", "111", "-f", "222");
-        PrivateFinalOptionFields ff = (PrivateFinalOptionFields) cmd.getCommand();
-        assertEquals("222", ff.field);
-    }
-
-    private static class PrivateFinalParameterFields {
-        @Parameters(index = "0") private final String field = null;
-        @Parameters(index = "1", arity = "0..1") private final int primitive = 43;
-    }
-    @Test
-    public void testCanInitializePrivateFinalParameterFields() {
-        PrivateFinalParameterFields ff = CommandLine.populateCommand(new PrivateFinalParameterFields(), "ref value");
-        assertEquals("ref value", ff.field);
-    }
-    @Ignore("Needs Reject final primitive fields annotated with @Option or @Parameters #68")
-    @Test
-    public void testCannotInitializePrivateFinalPrimitiveParameterFields() {
-        PrivateFinalParameterFields ff = CommandLine.populateCommand(new PrivateFinalParameterFields(), "ref value", "12");
-        assertEquals("ref value", ff.field);
-        assertEquals("primitive value", 12, ff.primitive);
-    }
-
-    private static class RequiredField {
-        @Option(names = {"-?", "/?"},        help = true)       boolean isHelpRequested;
-        @Option(names = {"-V", "--version"}, versionHelp= true) boolean versionHelp;
-        @Option(names = {"-h", "--help"},    usageHelp = true)  boolean usageHelp;
-        @Option(names = "--required", required = true) private String required;
-        @Parameters private String[] remainder;
-    }
-    @Test
-    public void testErrorIfRequiredOptionNotSpecified() {
-        try {
-            CommandLine.populateCommand(new RequiredField(), "arg1", "arg2");
-            fail("Missing required field should have thrown exception");
-        } catch (MissingParameterException ex) {
-            assertEquals("Missing required option '--required=<required>'", ex.getMessage());
-        }
-    }
-    @Test
-    public void testNoErrorIfRequiredOptionSpecified() {
-        CommandLine.populateCommand(new RequiredField(), "--required", "arg1", "arg2");
-    }
-    @Test
-    public void testNoErrorIfRequiredOptionNotSpecifiedWhenHelpRequested() {
-        RequiredField requiredField = CommandLine.populateCommand(new RequiredField(), "-?");
-        assertTrue("help requested", requiredField.isHelpRequested);
-    }
-    @Test
-    public void testNoErrorIfRequiredOptionNotSpecifiedWhenUsageHelpRequested() {
-        RequiredField requiredField = CommandLine.populateCommand(new RequiredField(), "--help");
-        assertTrue("usage help requested", requiredField.usageHelp);
-    }
-    @Test
-    public void testNoErrorIfRequiredOptionNotSpecifiedWhenVersionHelpRequested() {
-        RequiredField requiredField = CommandLine.populateCommand(new RequiredField(), "--version");
-        assertTrue("version info requested", requiredField.versionHelp);
-    }
-    @Test
-    public void testCommandLine_isUsageHelpRequested_trueWhenSpecified() {
-        List<CommandLine> parsedCommands = new CommandLine(new RequiredField()).parse("--help");
-        assertTrue("usage help requested", parsedCommands.get(0).isUsageHelpRequested());
-    }
-    @Test
-    public void testCommandLine_isVersionHelpRequested_trueWhenSpecified() {
-        List<CommandLine> parsedCommands = new CommandLine(new RequiredField()).parse("--version");
-        assertTrue("version info requested", parsedCommands.get(0).isVersionHelpRequested());
-    }
-    @Test
-    public void testCommandLine_isUsageHelpRequested_falseWhenNotSpecified() {
-        List<CommandLine> parsedCommands = new CommandLine(new RequiredField()).parse("--version");
-        assertFalse("usage help requested", parsedCommands.get(0).isUsageHelpRequested());
-    }
-    @Test
-    public void testCommandLine_isVersionHelpRequested_falseWhenNotSpecified() {
-        List<CommandLine> parsedCommands = new CommandLine(new RequiredField()).parse("--help");
-        assertFalse("version info requested", parsedCommands.get(0).isVersionHelpRequested());
-    }
-    @Test
-    public void testHelpRequestedFlagResetWhenParsing_staticMethod() {
-        RequiredField requiredField = CommandLine.populateCommand(new RequiredField(), "-?");
-        assertTrue("help requested", requiredField.isHelpRequested);
-
-        requiredField.isHelpRequested = false;
-
-        // should throw error again on second pass (no help was requested here...)
-        try {
-            CommandLine.populateCommand(requiredField, "arg1", "arg2");
-            fail("Missing required field should have thrown exception");
-        } catch (MissingParameterException ex) {
-            assertEquals("Missing required option '--required=<required>'", ex.getMessage());
-        }
-    }
-    @Test
-    public void testHelpRequestedFlagResetWhenParsing_instanceMethod() {
-        RequiredField requiredField = new RequiredField();
-        CommandLine commandLine = new CommandLine(requiredField);
-        commandLine.parse("-?");
-        assertTrue("help requested", requiredField.isHelpRequested);
-
-        requiredField.isHelpRequested = false;
-
-        // should throw error again on second pass (no help was requested here...)
-        try {
-            commandLine.parse("arg1", "arg2");
-            fail("Missing required field should have thrown exception");
-        } catch (MissingParameterException ex) {
-            assertEquals("Missing required option '--required=<required>'", ex.getMessage());
-        }
-    }
-
-    private class CompactFields {
-        @Option(names = "-v") boolean verbose;
-        @Option(names = "-r") boolean recursive;
-        @Option(names = "-o") File outputFile;
-        @Parameters File[] inputFiles;
-    }
-    @Test
-    public void testCompactFieldsAnyOrder() {
-        //cmd -a -o arg path path
-        //cmd -o arg -a path path
-        //cmd -a -o arg -- path path
-        //cmd -a -oarg path path
-        //cmd -aoarg path path
-        CompactFields compact = CommandLine.populateCommand(new CompactFields(), "-rvoout");
-        verifyCompact(compact, true, true, "out", null);
-
-        // change order within compact group
-        compact = CommandLine.populateCommand(new CompactFields(), "-vroout");
-        verifyCompact(compact, true, true, "out", null);
-
-        // compact group with separator
-        compact = CommandLine.populateCommand(new CompactFields(), "-vro=out");
-        verifyCompact(compact, true, true, "out", null);
-
-        compact = CommandLine.populateCommand(new CompactFields(), "-rv p1 p2".split(" "));
-        verifyCompact(compact, true, true, null, fileArray("p1", "p2"));
-
-        compact = CommandLine.populateCommand(new CompactFields(), "-voout p1 p2".split(" "));
-        verifyCompact(compact, true, false, "out", fileArray("p1", "p2"));
-
-        compact = CommandLine.populateCommand(new CompactFields(), "-voout -r p1 p2".split(" "));
-        verifyCompact(compact, true, true, "out", fileArray("p1", "p2"));
-
-        compact = CommandLine.populateCommand(new CompactFields(), "-r -v -oout p1 p2".split(" "));
-        verifyCompact(compact, true, true, "out", fileArray("p1", "p2"));
-
-        compact = CommandLine.populateCommand(new CompactFields(), "-rv -o out p1 p2".split(" ")); //#233
-        verifyCompact(compact, true, true, "out", fileArray("p1", "p2"));
-
-        compact = CommandLine.populateCommand(new CompactFields(), "-oout -r -v p1 p2".split(" "));
-        verifyCompact(compact, true, true, "out", fileArray("p1", "p2"));
-
-        compact = CommandLine.populateCommand(new CompactFields(), "-rvo out p1 p2".split(" "));
-        verifyCompact(compact, true, true, "out", fileArray("p1", "p2"));
-
-        try {
-            CommandLine.populateCommand(new CompactFields(), "-oout -r -vp1 p2".split(" "));
-            fail("should fail: -v does not take an argument");
-        } catch (UnmatchedArgumentException ex) {
-            assertEquals("Unmatched argument [-p1]", ex.getMessage());
-        }
-    }
-
-    @Test
-    public void testCompactFieldsWithUnmatchedArguments() {
-        setTraceLevel("OFF");
-        CommandLine cmd = new CommandLine(new CompactFields()).setUnmatchedArgumentsAllowed(true);
-        cmd.parse("-oout -r -vp1 p2".split(" "));
-        assertEquals(Arrays.asList("-p1"), cmd.getUnmatchedArguments());
-    }
-
-    @Test
-    public void testCompactWithOptionParamSeparatePlusParameters() {
-        CompactFields compact = CommandLine.populateCommand(new CompactFields(), "-r -v -o out p1 p2".split(" "));
-        verifyCompact(compact, true, true, "out", fileArray("p1", "p2"));
-    }
-
-    @Test
-    public void testCompactWithOptionParamAttachedEqualsSeparatorChar() {
-        CompactFields compact = CommandLine.populateCommand(new CompactFields(), "-rvo=out p1 p2".split(" "));
-        verifyCompact(compact, true, true, "out", fileArray("p1", "p2"));
-    }
-
-    @Test
-    public void testCompactWithOptionParamAttachedColonSeparatorChar() {
-        CompactFields compact = new CompactFields();
-        CommandLine cmd = new CommandLine(compact);
-        cmd.setSeparator(":");
-        cmd.parse("-rvo:out p1 p2".split(" "));
-        verifyCompact(compact, true, true, "out", fileArray("p1", "p2"));
-    }
-
-    /** See {@link #testGnuLongOptionsWithVariousSeparators()}  */
-    @Test
-    public void testDefaultSeparatorIsEquals() {
-        assertEquals("=", new CommandLine(new CompactFields()).getSeparator());
-    }
-
-    @Test
-    public void testOptionsMixedWithParameters() {
-        CompactFields compact = CommandLine.populateCommand(new CompactFields(), "-r -v p1 -o out p2".split(" "));
-        verifyCompact(compact, true, true, "out", fileArray("p1", "p2"));
-    }
-    @Test
-    public void testShortOptionsWithSeparatorButNoValueAssignsEmptyStringEvenIfNotLast() {
-        CompactFields compact = CommandLine.populateCommand(new CompactFields(), "-ro= -v".split(" "));
-        verifyCompact(compact, false, true, "-v", null);
-    }
-    @Test
-    public void testShortOptionsWithColonSeparatorButNoValueAssignsEmptyStringEvenIfNotLast() {
-        CompactFields compact = new CompactFields();
-        CommandLine cmd = new CommandLine(compact);
-        cmd.setSeparator(":");
-        cmd.parse("-ro: -v".split(" "));
-        verifyCompact(compact, false, true, "-v", null);
-    }
-    @Test
-    public void testShortOptionsWithSeparatorButNoValueFailsIfValueRequired() {
-        try {
-            CommandLine.populateCommand(new CompactFields(), "-rvo=".split(" "));
-            fail("Expected exception");
-        } catch (ParameterException ex) {
-            assertEquals("Missing required parameter for option '-o' (<outputFile>)", ex.getMessage());
-        }
-    }
-    @Test
-    public void testShortOptionsWithSeparatorButNoValueAssignsQuotedEmptyStringEvenIfNotLast() {
-        CompactFields compact = CommandLine.populateCommand(new CompactFields(), "-ro=\"\" -v".split(" "));
-        verifyCompact(compact, true, true, "", null);
-    }
-    @Test
-    public void testShortOptionsWithColonSeparatorButNoValueAssignsQuotedEmptyStringEvenIfNotLast() {
-        CompactFields compact = new CompactFields();
-        CommandLine cmd = new CommandLine(compact);
-        cmd.setSeparator(":");
-        cmd.parse("-ro:\"\" -v".split(" "));
-        verifyCompact(compact, true, true, "", null);
-    }
-    @Test
-    public void testShortOptionsWithSeparatorButNoValueAssignsEmptyQuotedStringIfLast() {
-        CompactFields compact = CommandLine.populateCommand(new CompactFields(), "-rvo=\"\"".split(" "));
-        verifyCompact(compact, true, true, "", null);
-    }
-
-    @Test
-    public void testDoubleDashSeparatesPositionalParameters() {
-        CompactFields compact = CommandLine.populateCommand(new CompactFields(), "-oout -- -r -v p1 p2".split(" "));
-        verifyCompact(compact, false, false, "out", fileArray("-r", "-v", "p1", "p2"));
-    }
-
-    @Test
-    public void testDebugOutputForDoubleDashSeparatesPositionalParameters() throws UnsupportedEncodingException {
-        PrintStream originalErr = System.err;
-        ByteArrayOutputStream baos = new ByteArrayOutputStream(2500);
-        System.setErr(new PrintStream(baos));
-        final String PROPERTY = "picocli.trace";
-        String old = System.getProperty(PROPERTY);
-        System.setProperty(PROPERTY, "DEBUG");
-        CommandLine.populateCommand(new CompactFields(), "-oout -- -r -v p1 p2".split(" "));
-        System.setErr(originalErr);
-        if (old == null) {
-            System.clearProperty(PROPERTY);
-        } else {
-            System.setProperty(PROPERTY, old);
-        }
-        String expected = String.format("" +
-                        "[picocli INFO] Parsing 6 command line args [-oout, --, -r, -v, p1, p2]%n" +
-                        "[picocli DEBUG] Initializing %1$s$CompactFields: 3 options, 1 positional parameters, 0 required, 0 subcommands.%n" +
-                        "[picocli DEBUG] Processing argument '-oout'. Remainder=[--, -r, -v, p1, p2]%n" +
-                        "[picocli DEBUG] '-oout' cannot be separated into <option>=<option-parameter>%n" +
-                        "[picocli DEBUG] Trying to process '-oout' as clustered short options%n" +
-                        "[picocli DEBUG] Found option '-o' in -oout: field java.io.File %1$s$CompactFields.outputFile, arity=1%n" +
-                        "[picocli DEBUG] Trying to process 'out' as option parameter%n" +
-                        "[picocli INFO] Setting File field 'CompactFields.outputFile' to 'out' (was 'null') for option -o%n" +
-                        "[picocli DEBUG] Processing argument '--'. Remainder=[-r, -v, p1, p2]%n" +
-                        "[picocli INFO] Found end-of-options delimiter '--'. Treating remainder as positional parameters.%n" +
-                        "[picocli DEBUG] Processing next arg as a positional parameter at index=0. Remainder=[-r, -v, p1, p2]%n" +
-                        "[picocli DEBUG] Position 0 is in index range 0..*. Trying to assign args to java.io.File[] %1$s$CompactFields.inputFiles, arity=0..1%n" +
-                        "[picocli INFO] Adding [-r] to File[] field 'CompactFields.inputFiles' for args[0..*] at position 0%n" +
-                        "[picocli DEBUG] Consumed 1 arguments, moving position to index 1.%n" +
-                        "[picocli DEBUG] Processing next arg as a positional parameter at index=1. Remainder=[-v, p1, p2]%n" +
-                        "[picocli DEBUG] Position 1 is in index range 0..*. Trying to assign args to java.io.File[] %1$s$CompactFields.inputFiles, arity=0..1%n" +
-                        "[picocli INFO] Adding [-v] to File[] field 'CompactFields.inputFiles' for args[0..*] at position 1%n" +
-                        "[picocli DEBUG] Consumed 1 arguments, moving position to index 2.%n" +
-                        "[picocli DEBUG] Processing next arg as a positional parameter at index=2. Remainder=[p1, p2]%n" +
-                        "[picocli DEBUG] Position 2 is in index range 0..*. Trying to assign args to java.io.File[] %1$s$CompactFields.inputFiles, arity=0..1%n" +
-                        "[picocli INFO] Adding [p1] to File[] field 'CompactFields.inputFiles' for args[0..*] at position 2%n" +
-                        "[picocli DEBUG] Consumed 1 arguments, moving position to index 3.%n" +
-                        "[picocli DEBUG] Processing next arg as a positional parameter at index=3. Remainder=[p2]%n" +
-                        "[picocli DEBUG] Position 3 is in index range 0..*. Trying to assign args to java.io.File[] %1$s$CompactFields.inputFiles, arity=0..1%n" +
-                        "[picocli INFO] Adding [p2] to File[] field 'CompactFields.inputFiles' for args[0..*] at position 3%n" +
-                        "[picocli DEBUG] Consumed 1 arguments, moving position to index 4.%n",
-                CommandLineTest.class.getName(), new File("/home/rpopma/picocli"));
-        String actual = new String(baos.toByteArray(), "UTF8");
-        //System.out.println(actual);
-        assertEquals(expected, actual);
-    }
-
-    private File[] fileArray(final String ... paths) {
-        File[] result = new File[paths.length];
-        for (int i = 0; i < result.length; i++) {
-            result[i] = new File(paths[i]);
-        }
-        return result;
-    }
-
-    private void verifyCompact(CompactFields compact, boolean verbose, boolean recursive, String out, File[] params) {
-        assertEquals("-v", verbose, compact.verbose);
-        assertEquals("-r", recursive, compact.recursive);
-        assertEquals("-o", out == null ? null : new File(out), compact.outputFile);
-        if (params == null) {
-            assertNull("args", compact.inputFiles);
-        } else {
-            assertArrayEquals("args=" + Arrays.toString(compact.inputFiles), params, compact.inputFiles);
-        }
-    }
-
-    @Test
-    public void testNonSpacedOptions() {
-        CompactFields compact = CommandLine.populateCommand(new CompactFields(), "-rvo arg path path".split(" "));
-        assertTrue("-r", compact.recursive);
-        assertTrue("-v", compact.verbose);
-        assertEquals("-o", new File("arg"), compact.outputFile);
-        assertArrayEquals("args", new File[]{new File("path"), new File("path")}, compact.inputFiles);
-    }
-
-    @Test
-    public void testPrimitiveParameters() {
-        class PrimitiveIntParameters {
-            @Parameters int[] intParams;
-        }
-        PrimitiveIntParameters params = CommandLine.populateCommand(new PrimitiveIntParameters(), "1 2 3 4".split(" "));
-        assertArrayEquals(new int[] {1, 2, 3, 4}, params.intParams);
-    }
-
-    @Test(expected = MissingTypeConverterException.class)
-    public void testMissingTypeConverter() {
-        class MissingConverter {
-            @Option(names = "--socket") Socket socket;
-        }
-        CommandLine.populateCommand(new MissingConverter(), "--socket anyString".split(" "));
-    }
-
-    @Test
-    public void testParametersDeclaredOutOfOrderWithNoArgs() {
-        class WithParams {
-            @Parameters(index = "1") String param1;
-            @Parameters(index = "0") String param0;
-        }
-        try {
-            CommandLine.populateCommand(new WithParams(), new String[0]);
-        } catch (MissingParameterException ex) {
-            assertEquals("Missing required parameters: <param0>, <param1>", ex.getMessage());
-        }
-    }
-
-    class VariousPrefixCharacters {
-        @Option(names = {"-d", "--dash"}) int dash;
-        @Option(names = {"/S"}) int slashS;
-        @Option(names = {"/T"}) int slashT;
-        @Option(names = {"/4"}) boolean fourDigit;
-        @Option(names = {"/Owner", "--owner"}) String owner;
-        @Option(names = {"-SingleDash"}) boolean singleDash;
-        @Option(names = {"[CPM"}) String cpm;
-        @Option(names = {"(CMS"}) String cms;
-    }
-    @Test
-    public void testOptionsMayDefineAnyPrefixChar() {
-        VariousPrefixCharacters params = CommandLine.populateCommand(new VariousPrefixCharacters(),
-                "-d 123 /4 /S 765 /T=98 /Owner=xyz -SingleDash [CPM CP/M (CMS=cmsVal".split(" "));
-        assertEquals("-d", 123, params.dash);
-        assertEquals("/S", 765, params.slashS);
-        assertEquals("/T", 98, params.slashT);
-        assertTrue("/4", params.fourDigit);
-        assertTrue("-SingleDash", params.singleDash);
-        assertEquals("/Owner", "xyz", params.owner);
-        assertEquals("[CPM", "CP/M", params.cpm);
-        assertEquals("(CMS", "cmsVal", params.cms);
-    }
-    @Test
-    public void testGnuLongOptionsWithVariousSeparators() {
-        VariousPrefixCharacters params = CommandLine.populateCommand(new VariousPrefixCharacters(), "--dash 123".split(" "));
-        assertEquals("--dash val", 123, params.dash);
-
-        params = CommandLine.populateCommand(new VariousPrefixCharacters(), "--dash=234 --owner=x".split(" "));
-        assertEquals("--dash=val", 234, params.dash);
-        assertEquals("--owner=x", "x", params.owner);
-
-        params = new VariousPrefixCharacters();
-        CommandLine cmd = new CommandLine(params);
-        cmd.setSeparator(":");
-        cmd.parse("--dash:345");
-        assertEquals("--dash:val", 345, params.dash);
-
-        params = new VariousPrefixCharacters();
-        cmd = new CommandLine(params);
-        cmd.setSeparator(":");
-        cmd.parse("--dash:345 --owner:y".split(" "));
-        assertEquals("--dash:val", 345, params.dash);
-        assertEquals("--owner:y", "y", params.owner);
-    }
-    @Test
-    public void testSeparatorCanBeSetDeclaratively() {
-        @Command(separator = ":")
-        class App {
-            @Option(names = "--opt", required = true) String opt;
-        }
-        try {
-            CommandLine.populateCommand(new App(), "--opt=abc");
-            fail("Expected failure with unknown separator");
-        } catch (MissingParameterException ok) {
-            assertEquals("Missing required option '--opt:<opt>'", ok.getMessage());
-        }
-    }
-    @Test
-    public void testIfSeparatorSetTheDefaultSeparatorIsNotRecognized() {
-        @Command(separator = ":")
-        class App {
-            @Option(names = "--opt", required = true) String opt;
-        }
-        try {
-            CommandLine.populateCommand(new App(), "--opt=abc");
-            fail("Expected failure with unknown separator");
-        } catch (MissingParameterException ok) {
-            assertEquals("Missing required option '--opt:<opt>'", ok.getMessage());
-        }
-    }
-    @Test
-    public void testIfSeparatorSetTheDefaultSeparatorIsNotRecognizedWithUnmatchedArgsAllowed() {
-        @Command(separator = ":")
-        class App {
-            @Option(names = "--opt", required = true) String opt;
-        }
-        setTraceLevel("OFF");
-        CommandLine cmd = new CommandLine(new App()).setUnmatchedArgumentsAllowed(true);
-        try {
-            cmd.parse("--opt=abc");
-            fail("Expected MissingParameterException");
-        } catch (MissingParameterException ok) {
-            assertEquals("Missing required option '--opt:<opt>'", ok.getMessage());
-            assertEquals(Arrays.asList("--opt=abc"), cmd.getUnmatchedArguments());
-        }
-    }
-    @Test
-    public void testGnuLongOptionsWithVariousSeparatorsOnlyAndNoValue() {
-        VariousPrefixCharacters params;
-        try {
-            params = CommandLine.populateCommand(new VariousPrefixCharacters(), "--dash".split(" "));
-            fail("int option needs arg");
-        } catch (ParameterException ex) {
-            assertEquals("Missing required parameter for option '-d' (<dash>)", ex.getMessage());
-        }
-
-        try {
-            params = CommandLine.populateCommand(new VariousPrefixCharacters(), "--owner".split(" "));
-        } catch (ParameterException ex) {
-            assertEquals("Missing required parameter for option '/Owner' (<owner>)", ex.getMessage());
-        }
-
-        params = CommandLine.populateCommand(new VariousPrefixCharacters(), "--owner=".split(" "));
-        assertEquals("--owner= (at end)", "", params.owner);
-
-        params = CommandLine.populateCommand(new VariousPrefixCharacters(), "--owner= /4".split(" "));
-        assertEquals("--owner= (in middle)", "", params.owner);
-        assertEquals("/4", true, params.fourDigit);
-
-        try {
-            params = CommandLine.populateCommand(new VariousPrefixCharacters(), "--dash=".split(" "));
-            fail("int option (with sep but no value) needs arg");
-        } catch (ParameterException ex) {
-            assertEquals("Could not convert '' to int for option '-d'" +
-                    ": java.lang.NumberFormatException: For input string: \"\"", ex.getMessage());
-        }
-
-        try {
-            params = CommandLine.populateCommand(new VariousPrefixCharacters(), "--dash= /4".split(" "));
-            fail("int option (with sep but no value, followed by other option) needs arg");
-        } catch (ParameterException ex) {
-            assertEquals("Could not convert '' to int for option '-d'" +
-                    ": java.lang.NumberFormatException: For input string: \"\"", ex.getMessage());
-        }
-    }
-
-    @Test
-    public void testOptionParameterSeparatorIsCustomizable() {
-        VariousPrefixCharacters params = new VariousPrefixCharacters();
-        CommandLine cmd = new CommandLine(params);
-        cmd.setSeparator(":");
-        cmd.parse("-d 123 /4 /S 765 /T:98 /Owner:xyz -SingleDash [CPM CP/M (CMS:cmsVal".split(" "));
-        assertEquals("-d", 123, params.dash);
-        assertEquals("/S", 765, params.slashS);
-        assertEquals("/T", 98, params.slashT);
-        assertTrue("/4", params.fourDigit);
-        assertTrue("-SingleDash", params.singleDash);
-        assertEquals("/Owner", "xyz", params.owner);
-        assertEquals("[CPM", "CP/M", params.cpm);
-        assertEquals("(CMS", "cmsVal", params.cms);
-    }
-    @Test(expected = NullPointerException.class)
-    public void testOptionParameterSeparatorCannotBeSetToNull() {
-        CommandLine cmd = new CommandLine(new VariousPrefixCharacters());
-        cmd.setSeparator(null);
-    }
-
-    @Test
-    public void testPotentiallyNestedOptionParsedCorrectly() {
-        class MyOption {
-            @CommandLine.Option(names = "-p") String path;
-        }
-        MyOption opt = CommandLine.populateCommand(new MyOption(), "-pa-p");
-        assertEquals("a-p", opt.path);
-
-        opt = CommandLine.populateCommand(new MyOption(), "-p-ap");
-        assertEquals("-ap", opt.path);
-    }
-
-    @Test
-    public void testArityGreaterThanOneForSingleValuedFields() {
-        class Arity2 {
-            @CommandLine.Option(names = "-p", arity="2") String path;
-            @CommandLine.Option(names = "-o", arity="2") String[] otherPath;
-        }
-        Arity2 opt = CommandLine.populateCommand(new Arity2(), "-o a b".split(" "));
-
-        try {
-            opt = CommandLine.populateCommand(new Arity2(), "-p a b".split(" "));
-            fail("expected exception");
-        } catch (UnmatchedArgumentException ex) {
-            assertEquals("Unmatched argument [b]", ex.getMessage());
-        }
-    }
-
-    @Test
-    public void testOptionParameterQuotesRemovedFromValue() {
-        class TextOption {
-            @CommandLine.Option(names = "-t") String text;
-        }
-        TextOption opt = CommandLine.populateCommand(new TextOption(), "-t", "\"a text\"");
-        assertEquals("a text", opt.text);
-    }
-
-    @Test
-    public void testLongOptionAttachedQuotedParameterQuotesRemovedFromValue() {
-        class TextOption {
-            @CommandLine.Option(names = "--text") String text;
-        }
-        TextOption opt = CommandLine.populateCommand(new TextOption(), "--text=\"a text\"");
-        assertEquals("a text", opt.text);
-    }
-
-    @Test
-    public void testShortOptionAttachedQuotedParameterQuotesRemovedFromValue() {
-        class TextOption {
-            @CommandLine.Option(names = "-t") String text;
-        }
-        TextOption opt = CommandLine.populateCommand(new TextOption(), "-t\"a text\"");
-        assertEquals("a text", opt.text);
-
-        opt = CommandLine.populateCommand(new TextOption(), "-t=\"a text\"");
-        assertEquals("a text", opt.text);
-    }
-
-    @Test
-    public void testShortOptionQuotedParameterTypeConversion() {
-        class TextOption {
-            @CommandLine.Option(names = "-t") int[] number;
-            @CommandLine.Option(names = "-v", arity = "1") boolean verbose;
-        }
-        TextOption opt = CommandLine.populateCommand(new TextOption(), "-t", "\"123\"", "-v", "\"true\"");
-        assertEquals(123, opt.number[0]);
-        assertTrue(opt.verbose);
-
-        opt = CommandLine.populateCommand(new TextOption(), "-t\"123\"", "-v\"true\"");
-        assertEquals(123, opt.number[0]);
-        assertTrue(opt.verbose);
-
-        opt = CommandLine.populateCommand(new TextOption(), "-t=\"345\"", "-v=\"true\"");
-        assertEquals(345, opt.number[0]);
-        assertTrue(opt.verbose);
-    }
-
-    @Test
-    public void testOptionMultiParameterQuotesRemovedFromValue() {
-        class TextOption {
-            @CommandLine.Option(names = "-t") String[] text;
-        }
-        TextOption opt = CommandLine.populateCommand(new TextOption(), "-t", "\"a text\"", "-t", "\"another text\"", "-t", "\"x z\"");
-        assertArrayEquals(new String[]{"a text", "another text", "x z"}, opt.text);
-
-        opt = CommandLine.populateCommand(new TextOption(), "-t\"a text\"", "-t\"another text\"", "-t\"x z\"");
-        assertArrayEquals(new String[]{"a text", "another text", "x z"}, opt.text);
-
-        opt = CommandLine.populateCommand(new TextOption(), "-t=\"a text\"", "-t=\"another text\"", "-t=\"x z\"");
-        assertArrayEquals(new String[]{"a text", "another text", "x z"}, opt.text);
-
-        try {
-            opt = CommandLine.populateCommand(new TextOption(), "-t=\"a text\"", "-t=\"another text\"", "\"x z\"");
-            fail("Expected UnmatchedArgumentException");
-        } catch (UnmatchedArgumentException ok) {
-            assertEquals("Unmatched argument [\"x z\"]", ok.getMessage());
-        }
-    }
-
-    @Test
-    public void testPositionalParameterQuotesRemovedFromValue() {
-        class TextParams {
-            @CommandLine.Parameters() String[] text;
-        }
-        TextParams opt = CommandLine.populateCommand(new TextParams(), "\"a text\"");
-        assertEquals("a text", opt.text[0]);
-    }
-
-    @Test
-    public void testPositionalMultiParameterQuotesRemovedFromValue() {
-        class TextParams {
-            @CommandLine.Parameters() String[] text;
-        }
-        TextParams opt = CommandLine.populateCommand(new TextParams(), "\"a text\"", "\"another text\"", "\"x z\"");
-        assertArrayEquals(new String[]{"a text", "another text", "x z"}, opt.text);
-    }
-
-    @Test
-    public void testPositionalMultiQuotedParameterTypeConversion() {
-        class TextParams {
-            @CommandLine.Parameters() int[] numbers;
-        }
-        TextParams opt = CommandLine.populateCommand(new TextParams(), "\"123\"", "\"456\"", "\"999\"");
-        assertArrayEquals(new int[]{123, 456, 999}, opt.numbers);
-    }
-
-    @Test
-    public void testSubclassedOptions() {
-        class ParentOption {
-            @CommandLine.Option(names = "-p") String path;
-        }
-        class ChildOption extends ParentOption {
-            @CommandLine.Option(names = "-t") String text;
-        }
-        ChildOption opt = CommandLine.populateCommand(new ChildOption(), "-p", "somePath", "-t", "\"a text\"");
-        assertEquals("somePath", opt.path);
-        assertEquals("a text", opt.text);
-    }
-
-    @Test
-    public void testSubclassedOptionsWithShadowedOptionNameThrowsDuplicateOptionAnnotationsException() {
-        class ParentOption {
-            @CommandLine.Option(names = "-p") String path;
-        }
-        class ChildOption extends ParentOption {
-            @CommandLine.Option(names = "-p") String text;
-        }
-        try {
-            CommandLine.populateCommand(new ChildOption(), "");
-            fail("expected CommandLine$DuplicateOptionAnnotationsException");
-        } catch (DuplicateOptionAnnotationsException ex) {
-            String expected = String.format("Option name '-p' is used by both %s.path and %s.text",
-                    ParentOption.class.getName(), ChildOption.class.getName());
-            assertEquals(expected, ex.getMessage());
-        }
-    }
-
-    @Test
-    public void testSubclassedOptionsWithShadowedFieldInitializesChildField() {
-        class ParentOption {
-            @CommandLine.Option(names = "-parentPath") String path;
-        }
-        class ChildOption extends ParentOption {
-            @CommandLine.Option(names = "-childPath") String path;
-        }
-        ChildOption opt = CommandLine.populateCommand(new ChildOption(), "-childPath", "somePath");
-        assertEquals("somePath", opt.path);
-
-        opt = CommandLine.populateCommand(new ChildOption(), "-parentPath", "somePath");
-        assertNull(opt.path);
-    }
-
-    @Test
-    public void testPositionalParamWithAbsoluteIndex() {
-        class App {
-            @Parameters(index = "0") File file0;
-            @Parameters(index = "1") File file1;
-            @Parameters(index = "2", arity = "0..1") File file2;
-            @Parameters List<String> all;
-        }
-        App app1 = CommandLine.populateCommand(new App(), "000", "111", "222", "333");
-        assertEquals("arg[0]", new File("000"), app1.file0);
-        assertEquals("arg[1]", new File("111"), app1.file1);
-        assertEquals("arg[2]", new File("222"), app1.file2);
-        assertEquals("args", Arrays.asList("000", "111", "222", "333"), app1.all);
-
-        App app2 = CommandLine.populateCommand(new App(), "000", "111");
-        assertEquals("arg[0]", new File("000"), app2.file0);
-        assertEquals("arg[1]", new File("111"), app2.file1);
-        assertEquals("arg[2]", null, app2.file2);
-        assertEquals("args", Arrays.asList("000", "111"), app2.all);
-
-        try {
-            CommandLine.populateCommand(new App(), "000");
-            fail("Should fail with missingParamException");
-        } catch (MissingParameterException ex) {
-            assertEquals("Missing required parameter: <file1>", ex.getMessage());
-        }
-    }
-
-    @Test
-    public void testPositionalParamWithFixedIndexRange() {
-        System.setProperty("picocli.trace", "OFF");
-        class App {
-            @Parameters(index = "0..1") File file0_1;
-            @Parameters(index = "1..2", type = File.class) List<File> fileList1_2;
-            @Parameters(index = "0..3") File[] fileArray0_3 = new File[4];
-            @Parameters List<String> all;
-        }
-        App app1 = new App();
-        new CommandLine(app1).setOverwrittenOptionsAllowed(true).parse("000", "111", "222", "333");
-        assertEquals("field initialized with arg[0]", new File("111"), app1.file0_1);
-        assertEquals("arg[1] and arg[2]", Arrays.asList(
-                new File("111"),
-                new File("222")), app1.fileList1_2);
-        assertArrayEquals("arg[0-3]", new File[]{
-                null, null, null, null, // existing values
-                new File("000"),
-                new File("111"),
-                new File("222"),
-                new File("333")}, app1.fileArray0_3);
-        assertEquals("args", Arrays.asList("000", "111", "222", "333"), app1.all);
-
-        App app2 = new App();
-        new CommandLine(app2).setOverwrittenOptionsAllowed(true).parse("000", "111");
-        assertEquals("field initialized with arg[0]", new File("111"), app2.file0_1);
-        assertEquals("arg[1]", Arrays.asList(new File("111")), app2.fileList1_2);
-        assertArrayEquals("arg[0-3]", new File[]{
-                null, null, null, null, // existing values
-                new File("000"),
-                new File("111"),}, app2.fileArray0_3);
-        assertEquals("args", Arrays.asList("000", "111"), app2.all);
-
-        App app3 = CommandLine.populateCommand(new App(), "000");
-        assertEquals("field initialized with arg[0]", new File("000"), app3.file0_1);
-        assertEquals("arg[1]", null, app3.fileList1_2);
-        assertArrayEquals("arg[0-3]", new File[]{
-                null, null, null, null, // existing values
-                new File("000")}, app3.fileArray0_3);
-        assertEquals("args", Arrays.asList("000"), app3.all);
-
-        try {
-            CommandLine.populateCommand(new App());
-            fail("Should fail with missingParamException");
-        } catch (MissingParameterException ex) {
-            assertEquals("Missing required parameter: <file0_1>", ex.getMessage());
-        }
-    }
-
-    @Test
-    public void testPositionalParamWithFixedAndVariableIndexRanges() throws Exception {
-        class App {
-            @Parameters(index = "0") InetAddress host1;
-            @Parameters(index = "1") int port1;
-            @Parameters(index = "2") InetAddress host2;
-            @Parameters(index = "3..4", arity = "1..2") int[] port2range;
-            @Parameters(index = "4..*") String[] files;
-        }
-        App app1 = CommandLine.populateCommand(new App(), "localhost", "1111", "localhost", "2222", "3333", "file1", "file2");
-        assertEquals(InetAddress.getByName("localhost"), app1.host1);
-        assertEquals(1111, app1.port1);
-        assertEquals(InetAddress.getByName("localhost"), app1.host2);
-        assertArrayEquals(new int[]{2222, 3333}, app1.port2range);
-        assertArrayEquals(new String[]{"file1", "file2"}, app1.files);
-    }
-
-    @Ignore("Requires #70 support for variable arity in positional parameters")
-    @Test
-    public void testPositionalParamWithFixedIndexRangeAndVariableArity() throws Exception {
-        class App {
-            @Parameters(index = "0") InetAddress host1;
-            @Parameters(index = "1") int port1;
-            @Parameters(index = "2") InetAddress host2;
-            @Parameters(index = "3..4", arity = "1..2") int[] port2range;
-            @Parameters(index = "4..*") String[] files;
-        }
-        // now with only one arg in port2range
-        App app2 = CommandLine.populateCommand(new App(), "localhost", "1111", "localhost", "2222", "file1", "file2");
-        assertEquals(InetAddress.getByName("localhost"), app2.host1);
-        assertEquals(1111, app2.port1);
-        assertEquals(InetAddress.getByName("localhost"), app2.host2);
-        assertArrayEquals(new int[]{2222}, app2.port2range);
-        assertArrayEquals(new String[]{"file1", "file2"}, app2.files);
-    }
-
-    @Test(expected = ParameterIndexGapException.class)
-    public void testPositionalParamWithIndexGap_SkipZero() throws Exception {
-        class SkipZero { @Parameters(index = "1") String str; }
-        CommandLine.populateCommand(new SkipZero(),"val1", "val2");
-    }
-
-    @Test(expected = ParameterIndexGapException.class)
-    public void testPositionalParamWithIndexGap_RangeSkipZero() throws Exception {
-        class SkipZero { @Parameters(index = "1..*") String str; }
-        CommandLine.populateCommand(new SkipZero(),"val1", "val2");
-    }
-
-    @Test(expected = ParameterIndexGapException.class)
-    public void testPositionalParamWithIndexGap_FixedIndexGap() throws Exception {
-        class SkipOne {
-            @Parameters(index = "0") String str0;
-            @Parameters(index = "2") String str2;
-        }
-        CommandLine.populateCommand(new SkipOne(),"val1", "val2");
-    }
-
-    @Test(expected = ParameterIndexGapException.class)
-    public void testPositionalParamWithIndexGap_RangeIndexGap() throws Exception {
-        class SkipTwo {
-            @Parameters(index = "0..1") String str0;
-            @Parameters(index = "3") String str2;
-        }
-        CommandLine.populateCommand(new SkipTwo(),"val0", "val1", "val2", "val3");
-    }
-
-    @Test
-    public void testPositionalParamWithIndexGap_VariableRangeIndexNoGap() throws Exception {
-        class NoGap {
-            @Parameters(index = "0..*") String[] str0;
-            @Parameters(index = "3") String str2;
-        }
-        NoGap noGap = CommandLine.populateCommand(new NoGap(),"val0", "val1", "val2", "val3");
-        assertArrayEquals(new String[] {"val0", "val1", "val2", "val3"}, noGap.str0);
-        assertEquals("val3", noGap.str2);
-    }
-
-    @Test
-    public void testPositionalParamWithIndexGap_RangeIndexNoGap() throws Exception {
-        class NoGap {
-            @Parameters(index = "0..1") String[] str0;
-            @Parameters(index = "2") String str2;
-        }
-        NoGap noGap = CommandLine.populateCommand(new NoGap(),"val0", "val1", "val2");
-        assertArrayEquals(new String[] {"val0", "val1"}, noGap.str0);
-        assertEquals("val2", noGap.str2);
-    }
-
-    @Test(expected = UnmatchedArgumentException.class)
-    public void testPositionalParamsDisallowUnknownArgumentSingleValue() throws Exception {
-        class SingleValue {
-            @Parameters(index = "0") String str;
-        }
-        SingleValue single = CommandLine.populateCommand(new SingleValue(),"val1", "val2");
-        assertEquals("val1", single.str);
-    }
-
-    @Test(expected = UnmatchedArgumentException.class)
-    public void testPositionalParamsDisallowUnknownArgumentMultiValue() throws Exception {
-        class SingleValue {
-            @Parameters(index = "0..2") String[] str;
-        }
-        CommandLine.populateCommand(new SingleValue(),"val0", "val1", "val2", "val3");
-    }
-    @Test
-    public void testPositionalParamsUnknownArgumentSingleValueWithUnmatchedArgsAllowed() throws Exception {
-        class SingleValue {
-            @Parameters(index = "0") String str;
-        }
-        setTraceLevel("OFF");
-        CommandLine cmd = new CommandLine(new SingleValue()).setUnmatchedArgumentsAllowed(true);
-        cmd.parse("val1", "val2");
-        assertEquals("val1", ((SingleValue)cmd.getCommand()).str);
-        assertEquals(Arrays.asList("val2"), cmd.getUnmatchedArguments());
-    }
-
-    @Test
-    public void testPositionalParamsUnknownArgumentMultiValueWithUnmatchedArgsAllowed() throws Exception {
-        class SingleValue {
-            @Parameters(index = "0..2") String[] str;
-        }
-        setTraceLevel("OFF");
-        CommandLine cmd = new CommandLine(new SingleValue()).setUnmatchedArgumentsAllowed(true);
-        cmd.parse("val0", "val1", "val2", "val3");
-        assertArrayEquals(new String[]{"val0", "val1", "val2"}, ((SingleValue)cmd.getCommand()).str);
-        assertEquals(Arrays.asList("val3"), cmd.getUnmatchedArguments());
-    }
-
-    @Test
-    public void testPositionalParamSingleValueButWithoutIndex() throws Exception {
-        class SingleValue {
-            @Parameters String str;
-        }
-        try {
-            CommandLine.populateCommand(new SingleValue(),"val1", "val2");
-            fail("Expected OverwrittenOptionException");
-        } catch (OverwrittenOptionException ex) {
-            assertEquals("positional parameter at index 0..* (<str>) should be specified only once", ex.getMessage());
-        }
-        setTraceLevel("OFF");
-        CommandLine cmd = new CommandLine(new SingleValue()).setOverwrittenOptionsAllowed(true);
-        cmd.parse("val1", "val2");
-        assertEquals("val2", ((SingleValue) cmd.getCommand()).str);
-    }
-
-    @Test
-    public void testSplitInOptionArray() {
-        class Args {
-            @Option(names = "-a", split = ",") String[] values;
-        }
-        Args args = CommandLine.populateCommand(new Args(), "-a=a,b,c");
-        assertArrayEquals(new String[] {"a", "b", "c"}, args.values);
-
-        args = CommandLine.populateCommand(new Args(), "-a=a,b,c", "-a=B", "-a", "C");
-        assertArrayEquals(new String[] {"a", "b", "c", "B", "C"}, args.values);
-
-        args = CommandLine.populateCommand(new Args(), "-a", "a,b,c", "-a", "B", "-a", "C");
-        assertArrayEquals(new String[] {"a", "b", "c", "B", "C"}, args.values);
-
-        args = CommandLine.populateCommand(new Args(), "-a=a,b,c", "-a", "B", "-a", "C", "-a", "D,E,F");
-        assertArrayEquals(new String[] {"a", "b", "c", "B", "C", "D", "E", "F"}, args.values);
-
-        try {
-            args = CommandLine.populateCommand(new Args(), "-a=a,b,c", "B", "C");
-            fail("Expected UnmatchedArgEx");
-        } catch (UnmatchedArgumentException ok) {
-            assertEquals("Unmatched arguments [B, C]", ok.getMessage());
-        }
-        try {
-            args = CommandLine.populateCommand(new Args(), "-a=a,b,c", "B", "-a=C");
-            fail("Expected UnmatchedArgEx");
-        } catch (UnmatchedArgumentException ok) {
-            assertEquals("Unmatched argument [B]", ok.getMessage());
-        }
-    }
-
-    @Test
-    public void testSplitInOptionArrayWithSpaces() {
-        class Args {
-            @Option(names = "-a", split = " ") String[] values;
-        }
-        Args args = CommandLine.populateCommand(new Args(), "-a=\"a b c\"");
-        assertArrayEquals(new String[] {"a", "b", "c"}, args.values);
-
-        args = CommandLine.populateCommand(new Args(), "-a=a b c", "-a", "B", "-a", "C");
-        assertArrayEquals(new String[] {"a", "b", "c", "B", "C"}, args.values);
-
-        args = CommandLine.populateCommand(new Args(), "-a", "\"a b c\"", "-a=B", "-a=C");
-        assertArrayEquals(new String[] {"a", "b", "c", "B", "C"}, args.values);
-
-        args = CommandLine.populateCommand(new Args(), "-a=\"a b c\"", "-a=B", "-a", "C", "-a=D E F");
-        assertArrayEquals(new String[] {"a", "b", "c", "B", "C", "D", "E", "F"}, args.values);
-
-        try {
-            args = CommandLine.populateCommand(new Args(), "-a=a b c", "B", "C");
-            fail("Expected UnmatchedArgEx");
-        } catch (UnmatchedArgumentException ok) {
-            assertEquals("Unmatched arguments [B, C]", ok.getMessage());
-        }
-        try {
-            args = CommandLine.populateCommand(new Args(), "-a=a b c", "B", "-a=C");
-            fail("Expected UnmatchedArgEx");
-        } catch (UnmatchedArgumentException ok) {
-            assertEquals("Unmatched argument [B]", ok.getMessage());
-        }
-    }
-
-    @Test
-    public void testSplitInOptionArrayWithArity() {
-        class Args {
-            @Option(names = "-a", split = ",", arity = "0..4") String[] values;
-            @Parameters() String[] params;
-        }
-        Args args = CommandLine.populateCommand(new Args(), "-a=a,b,c"); // 1 args
-        assertArrayEquals(new String[] {"a", "b", "c"}, args.values);
-
-        args = CommandLine.populateCommand(new Args(), "-a"); // 0 args
-        assertArrayEquals(new String[0], args.values);
-        assertNull(args.params);
-
-        args = CommandLine.populateCommand(new Args(), "-a=a,b,c", "B", "C"); // 3 args
-        assertArrayEquals(new String[] {"a", "b", "c", "B", "C"}, args.values);
-        assertNull(args.params);
-
-        args = CommandLine.populateCommand(new Args(), "-a", "a,b,c", "B", "C"); // 3 args
-        assertArrayEquals(new String[] {"a", "b", "c", "B", "C"}, args.values);
-        assertNull(args.params);
-
-        args = CommandLine.populateCommand(new Args(), "-a=a,b,c", "B", "C", "D,E,F"); // 4 args
-        assertArrayEquals(new String[] {"a", "b", "c", "B", "C", "D", "E", "F"}, args.values);
-        assertNull(args.params);
-
-        args = CommandLine.populateCommand(new Args(), "-a=a,b,c,d", "B", "C", "D", "E,F"); // 5 args
-        assertArrayEquals(new String[] {"a", "b", "c", "d", "B", "C", "D"}, args.values);
-        assertArrayEquals(new String[] {"E,F"}, args.params);
-    }
-
-    @Test
-    public void testSplitInOptionCollection() {
-        class Args {
-            @Option(names = "-a", split = ",") List<String> values;
-        }
-        Args args = CommandLine.populateCommand(new Args(), "-a=a,b,c");
-        assertEquals(Arrays.asList("a", "b", "c"), args.values);
-
-        args = CommandLine.populateCommand(new Args(), "-a=a,b,c", "-a", "B", "-a=C");
-        assertE

<TRUNCATED>

[3/4] logging-log4j2 git commit: [BUILD] removed picocli tests from core tests; they do not add value here and occasionally fail when building Log4j on a console that supports ANSI colors

Posted by rp...@apache.org.
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/dd8ded97/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/CommandLineHelpTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/CommandLineHelpTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/CommandLineHelpTest.java
deleted file mode 100644
index 3651b22..0000000
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/picocli/CommandLineHelpTest.java
+++ /dev/null
@@ -1,2536 +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.logging.log4j.core.tools.picocli;
-
-import org.junit.After;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.apache.logging.log4j.core.tools.picocli.CommandLine.Help;
-import org.apache.logging.log4j.core.tools.picocli.CommandLine.Help.Ansi.IStyle;
-import org.apache.logging.log4j.core.tools.picocli.CommandLine.Help.Ansi.Style;
-import org.apache.logging.log4j.core.tools.picocli.CommandLine.Help.Ansi.Text;
-import org.apache.logging.log4j.core.tools.picocli.CommandLine.Help.ColorScheme;
-import org.apache.logging.log4j.core.tools.picocli.CommandLine.Help.TextTable;
-import org.apache.logging.log4j.core.tools.picocli.CommandLine.Option;
-import org.apache.logging.log4j.core.tools.picocli.CommandLine.Parameters;
-import org.apache.logging.log4j.core.tools.picocli.CommandLine.Command;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
-import java.lang.String;
-import java.lang.reflect.Field;
-import java.net.InetAddress;
-import java.net.URI;
-import java.net.URL;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-
-import static java.lang.String.format;
-import static org.junit.Assert.*;
-
-/**
- * Tests for picoCLI's "Usage" help functionality.
- */
-public class CommandLineHelpTest {
-    private static final String LINESEP = System.getProperty("line.separator");
-
-    @After
-    public void after() {
-        System.getProperties().remove("picocli.color.commands");
-        System.getProperties().remove("picocli.color.options");
-        System.getProperties().remove("picocli.color.parameters");
-        System.getProperties().remove("picocli.color.optionParams");
-    }
-    private static String usageString(Object annotatedObject, Help.Ansi ansi) throws UnsupportedEncodingException {
-        return usageString(new CommandLine(annotatedObject), ansi);
-    }
-    private static String usageString(CommandLine commandLine, Help.Ansi ansi) throws UnsupportedEncodingException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        commandLine.usage(new PrintStream(baos, true, "UTF8"), ansi);
-        String result = baos.toString("UTF8");
-
-        if (ansi == Help.Ansi.AUTO) {
-            baos.reset();
-            commandLine.usage(new PrintStream(baos, true, "UTF8"));
-            assertEquals(result, baos.toString("UTF8"));
-        } else if (ansi == Help.Ansi.ON) {
-            baos.reset();
-            commandLine.usage(new PrintStream(baos, true, "UTF8"), Help.defaultColorScheme(Help.Ansi.ON));
-            assertEquals(result, baos.toString("UTF8"));
-        }
-        return result;
-    }
-    private static Field field(Class<?> cls, String fieldName) throws NoSuchFieldException {
-        return cls.getDeclaredField(fieldName);
-    }
-    private static Field[] fields(Class<?> cls, String... fieldNames) throws NoSuchFieldException {
-        Field[] result = new Field[fieldNames.length];
-        for (int i = 0; i < fieldNames.length; i++) {
-            result[i] = cls.getDeclaredField(fieldNames[i]);
-        }
-        return result;
-    }
-
-    @Test
-    public void testWithoutShowDefaultValues() throws Exception {
-        @CommandLine.Command()
-        class Params {
-            @Option(names = {"-f", "--file"}, required = true, description = "the file to use") File file;
-        }
-        String result = usageString(new Params(), Help.Ansi.OFF);
-        assertEquals(format("" +
-                        "Usage: <main class> -f=<file>%n" +
-                        "  -f, --file=<file>           the file to use%n",
-                ""), result);
-    }
-
-    @Test
-    public void testShowDefaultValues() throws Exception {
-        @CommandLine.Command(showDefaultValues = true)
-        class Params {
-            @Option(names = {"-f", "--file"}, required = true, description = "the file to use")
-            File file = new File("theDefault.txt");
-        }
-        String result = usageString(new Params(), Help.Ansi.OFF);
-        assertEquals(format("" +
-                "Usage: <main class> -f=<file>%n" +
-                "  -f, --file=<file>           the file to use%n" +
-                "                                Default: theDefault.txt%n"), result);
-    }
-
-    @Test
-    public void testShowDefaultValuesArrayField() throws Exception {
-        @CommandLine.Command(showDefaultValues = true)
-        class Params {
-            @Option(names = {"-x", "--array"}, required = true, description = "the array")
-            int[] array = {1, 5, 11, 23};
-        }
-        String result = usageString(new Params(), Help.Ansi.OFF);
-        assertEquals(format("" +
-                "Usage: <main class> -x=<array> [-x=<array>]...%n" +
-                "  -x, --array=<array>         the array%n" +
-                "                                Default: [1, 5, 11, 23]%n"), result);
-    }
-
-    @Test
-    public void testUsageSeparatorWithoutDefault() throws Exception {
-        @Command()
-        class Params {
-            @Option(names = {"-f", "--file"}, required = true, description = "the file to use") File file = new File("def.txt");
-        }
-        String result = usageString(new Params(), Help.Ansi.OFF);
-        assertEquals(format("" +
-                        "Usage: <main class> -f=<file>%n" +
-                        "  -f, --file=<file>           the file to use%n",
-                ""), result);
-    }
-
-    @Test
-    public void testUsageSeparator() throws Exception {
-        @Command(showDefaultValues = true)
-        class Params {
-            @Option(names = {"-f", "--file"}, required = true, description = "the file to use") File file = new File("def.txt");
-        }
-        String result = usageString(new Params(), Help.Ansi.OFF);
-        assertEquals(format("" +
-                        "Usage: <main class> -f=<file>%n" +
-                        "  -f, --file=<file>           the file to use%n" +
-                        "                                Default: def.txt%n",
-                ""), result);
-    }
-
-    @Test
-    public void testUsageParamLabels() throws Exception {
-        @Command()
-        class ParamLabels {
-            @Option(names = "-P",    paramLabel = "KEY=VALUE", type  = {String.class, String.class},
-                    description = "Project properties (key-value pairs)")              Map<String, String> props;
-            @Option(names = "-f",    paramLabel = "FILE", description = "files")      File[] f;
-            @Option(names = "-n",    description = "a number option")                  int number;
-            @Parameters(index = "0", paramLabel = "NUM", description = "number param") int n;
-            @Parameters(index = "1", description = "the host parameter")               InetAddress host;
-        }
-        String result = usageString(new ParamLabels(), Help.Ansi.OFF);
-        assertEquals(format("" +
-                        "Usage: <main class> [-n=<number>] [-f=FILE]... [-P=KEY=VALUE]... NUM <host>%n" +
-                        "      NUM                     number param%n" +
-                        "      <host>                  the host parameter%n" +
-                        "  -f= FILE                    files%n" +
-                        "  -n= <number>                a number option%n" +
-                        "  -P= KEY=VALUE               Project properties (key-value pairs)%n",
-                ""), result);
-    }
-
-    @Test
-    public void testUsageParamLabelsWithLongMapOptionName() throws Exception {
-        @Command()
-        class ParamLabels {
-            @Option(names = {"-P", "--properties"},
-                    paramLabel  = "KEY=VALUE", type  = {String.class, String.class},
-                    description = "Project properties (key-value pairs)")              Map<String, String> props;
-            @Option(names = "-f",    paramLabel = "FILE", description = "a file")      File f;
-            @Option(names = "-n",    description = "a number option")                  int number;
-            @Parameters(index = "0", paramLabel = "NUM", description = "number param") int n;
-            @Parameters(index = "1", description = "the host parameter")               InetAddress host;
-        }
-        String result = usageString(new ParamLabels(), Help.Ansi.OFF);
-        assertEquals(format("" +
-                        "Usage: <main class> [-f=FILE] [-n=<number>] [-P=KEY=VALUE]... NUM <host>%n" +
-                        "      NUM                     number param%n" +
-                        "      <host>                  the host parameter%n" +
-                        "  -f= FILE                    a file%n" +
-                        "  -n= <number>                a number option%n" +
-                        "  -P, --properties=KEY=VALUE  Project properties (key-value pairs)%n",
-                ""), result);
-    }
-
-    // ---------------
-    @Test
-    public void testUsageVariableArityRequiredShortOptionArray() throws UnsupportedEncodingException {
-        // if option is required at least once and can be specified multiple times:
-        // -f=ARG [-f=ARG]...
-        class Args {
-            @Option(names = "-a", required = true, paramLabel = "ARG") // default
-            String[] a;
-            @Option(names = "-b", required = true, paramLabel = "ARG", arity = "0..*")
-            List<String> b;
-            @Option(names = "-c", required = true, paramLabel = "ARG", arity = "1..*")
-            String[] c;
-            @Option(names = "-d", required = true, paramLabel = "ARG", arity = "2..*")
-            List<String> d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> -a=ARG [-a=ARG]... -b=[ARG]... [-b=[ARG]...]... -c=ARG...%n" +
-                "                    [-c=ARG...]... -d=ARG ARG... [-d=ARG ARG...]...%n" +
-                "  -a= ARG%n" +
-                "  -b= [ARG]...%n" +
-                "  -c= ARG...%n" +
-                "  -d= ARG ARG...%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageVariableArityShortOptionArray() throws UnsupportedEncodingException {
-        class Args {
-            @Option(names = "-a", paramLabel = "ARG") // default
-            List<String> a;
-            @Option(names = "-b", paramLabel = "ARG", arity = "0..*")
-            String[] b;
-            @Option(names = "-c", paramLabel = "ARG", arity = "1..*")
-            List<String> c;
-            @Option(names = "-d", paramLabel = "ARG", arity = "2..*")
-            String[] d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> [-a=ARG]... [-b=[ARG]...]... [-c=ARG...]... [-d=ARG%n" +
-                "                    ARG...]...%n" +
-                "  -a= ARG%n" +
-                "  -b= [ARG]...%n" +
-                "  -c= ARG...%n" +
-                "  -d= ARG ARG...%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageRangeArityRequiredShortOptionArray() throws UnsupportedEncodingException {
-        // if option is required at least once and can be specified multiple times:
-        // -f=ARG [-f=ARG]...
-        class Args {
-            @Option(names = "-a", required = true, paramLabel = "ARG", arity = "0..1")
-            List<String> a;
-            @Option(names = "-b", required = true, paramLabel = "ARG", arity = "1..2")
-            String[] b;
-            @Option(names = "-c", required = true, paramLabel = "ARG", arity = "1..3")
-            String[] c;
-            @Option(names = "-d", required = true, paramLabel = "ARG", arity = "2..4")
-            String[] d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> -a[=ARG] [-a[=ARG]]... -b=ARG [ARG] [-b=ARG [ARG]]...%n" +
-                "                    -c=ARG [ARG [ARG]] [-c=ARG [ARG [ARG]]]... -d=ARG ARG [ARG%n" +
-                "                    [ARG]] [-d=ARG ARG [ARG [ARG]]]...%n" +
-                "  -a= [ARG]%n" +
-                "  -b= ARG [ARG]%n" +
-                "  -c= ARG [ARG [ARG]]%n" +
-                "  -d= ARG ARG [ARG [ARG]]%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageRangeArityShortOptionArray() throws UnsupportedEncodingException {
-        class Args {
-            @Option(names = "-a", paramLabel = "ARG", arity = "0..1")
-            List<String> a;
-            @Option(names = "-b", paramLabel = "ARG", arity = "1..2")
-            String[] b;
-            @Option(names = "-c", paramLabel = "ARG", arity = "1..3")
-            String[] c;
-            @Option(names = "-d", paramLabel = "ARG", arity = "2..4")
-            String[] d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> [-a[=ARG]]... [-b=ARG [ARG]]... [-c=ARG [ARG [ARG]]]...%n" +
-                "                    [-d=ARG ARG [ARG [ARG]]]...%n" +
-                "  -a= [ARG]%n" +
-                "  -b= ARG [ARG]%n" +
-                "  -c= ARG [ARG [ARG]]%n" +
-                "  -d= ARG ARG [ARG [ARG]]%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageFixedArityRequiredShortOptionArray() throws UnsupportedEncodingException {
-        // if option is required at least once and can be specified multiple times:
-        // -f=ARG [-f=ARG]...
-        class Args {
-            @Option(names = "-a", required = true, paramLabel = "ARG") // default
-                    String[] a;
-            @Option(names = "-b", required = true, paramLabel = "ARG", arity = "0")
-            String[] b;
-            @Option(names = "-c", required = true, paramLabel = "ARG", arity = "1")
-            String[] c;
-            @Option(names = "-d", required = true, paramLabel = "ARG", arity = "2")
-            String[] d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> -b [-b]... -a=ARG [-a=ARG]... -c=ARG [-c=ARG]... -d=ARG ARG%n" +
-                "                    [-d=ARG ARG]...%n" +
-                "  -a= ARG%n" +
-                "  -b%n" +
-                "  -c= ARG%n" +
-                "  -d= ARG ARG%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageFixedArityShortOptionArray() throws UnsupportedEncodingException {
-        class Args {
-            @Option(names = "-a", paramLabel = "ARG") // default
-                    String[] a;
-            @Option(names = "-b", paramLabel = "ARG", arity = "0")
-            String[] b;
-            @Option(names = "-c", paramLabel = "ARG", arity = "1")
-            String[] c;
-            @Option(names = "-d", paramLabel = "ARG", arity = "2")
-            String[] d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> [-b]... [-a=ARG]... [-c=ARG]... [-d=ARG ARG]...%n" +
-                "  -a= ARG%n" +
-                "  -b%n" +
-                "  -c= ARG%n" +
-                "  -d= ARG ARG%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-    //--------------
-    @Test
-    public void testUsageVariableArityRequiredLongOptionArray() throws UnsupportedEncodingException {
-        // if option is required at least once and can be specified multiple times:
-        // -f=ARG [-f=ARG]...
-        class Args {
-            @Option(names = "--aa", required = true, paramLabel = "ARG") // default
-            String[] a;
-            @Option(names = "--bb", required = true, paramLabel = "ARG", arity = "0..*")
-            List<String> b;
-            @Option(names = "--cc", required = true, paramLabel = "ARG", arity = "1..*")
-            String[] c;
-            @Option(names = "--dd", required = true, paramLabel = "ARG", arity = "2..*")
-            List<String> d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> --aa=ARG [--aa=ARG]... --bb=[ARG]... [--bb=[ARG]...]...%n" +
-                "                    --cc=ARG... [--cc=ARG...]... --dd=ARG ARG... [--dd=ARG%n" +
-                "                    ARG...]...%n" +
-                "      --aa=ARG%n" +
-                "      --bb=[ARG]...%n" +
-                "      --cc=ARG...%n" +
-                "      --dd=ARG ARG...%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageVariableArityLongOptionArray() throws UnsupportedEncodingException {
-        class Args {
-            @Option(names = "--aa", paramLabel = "ARG") // default
-            List<String> a;
-            @Option(names = "--bb", paramLabel = "ARG", arity = "0..*")
-            String[] b;
-            @Option(names = "--cc", paramLabel = "ARG", arity = "1..*")
-            List<String> c;
-            @Option(names = "--dd", paramLabel = "ARG", arity = "2..*")
-            String[] d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> [--aa=ARG]... [--bb=[ARG]...]... [--cc=ARG...]... [--dd=ARG%n" +
-                "                    ARG...]...%n" +
-                "      --aa=ARG%n" +
-                "      --bb=[ARG]...%n" +
-                "      --cc=ARG...%n" +
-                "      --dd=ARG ARG...%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageRangeArityRequiredLongOptionArray() throws UnsupportedEncodingException {
-        // if option is required at least once and can be specified multiple times:
-        // -f=ARG [-f=ARG]...
-        class Args {
-            @Option(names = "--aa", required = true, paramLabel = "ARG", arity = "0..1")
-            List<String> a;
-            @Option(names = "--bb", required = true, paramLabel = "ARG", arity = "1..2")
-            String[] b;
-            @Option(names = "--cc", required = true, paramLabel = "ARG", arity = "1..3")
-            String[] c;
-            @Option(names = "--dd", required = true, paramLabel = "ARG", arity = "2..4", description = "foobar")
-            String[] d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> --aa[=ARG] [--aa[=ARG]]... --bb=ARG [ARG] [--bb=ARG%n" +
-                "                    [ARG]]... --cc=ARG [ARG [ARG]] [--cc=ARG [ARG [ARG]]]...%n" +
-                "                    --dd=ARG ARG [ARG [ARG]] [--dd=ARG ARG [ARG [ARG]]]...%n" +
-                "      --aa[=ARG]%n" +
-                "      --bb=ARG [ARG]%n" +
-                "      --cc=ARG [ARG [ARG]]%n" +
-                "      --dd=ARG ARG [ARG [ARG]]%n" +
-                "                              foobar%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageRangeArityLongOptionArray() throws UnsupportedEncodingException {
-        class Args {
-            @Option(names = "--aa", paramLabel = "ARG", arity = "0..1")
-            List<String> a;
-            @Option(names = "--bb", paramLabel = "ARG", arity = "1..2")
-            String[] b;
-            @Option(names = "--cc", paramLabel = "ARG", arity = "1..3")
-            String[] c;
-            @Option(names = "--dd", paramLabel = "ARG", arity = "2..4", description = "foobar")
-            String[] d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> [--aa[=ARG]]... [--bb=ARG [ARG]]... [--cc=ARG [ARG%n" +
-                "                    [ARG]]]... [--dd=ARG ARG [ARG [ARG]]]...%n" +
-                "      --aa[=ARG]%n" +
-                "      --bb=ARG [ARG]%n" +
-                "      --cc=ARG [ARG [ARG]]%n" +
-                "      --dd=ARG ARG [ARG [ARG]]%n" +
-                "                              foobar%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageFixedArityRequiredLongOptionArray() throws UnsupportedEncodingException {
-        // if option is required at least once and can be specified multiple times:
-        // -f=ARG [-f=ARG]...
-        class Args {
-            @Option(names = "--aa", required = true, paramLabel = "ARG") // default
-            String[] a;
-            @Option(names = "--bb", required = true, paramLabel = "ARG", arity = "0")
-            String[] b;
-            @Option(names = "--cc", required = true, paramLabel = "ARG", arity = "1")
-            String[] c;
-            @Option(names = "--dd", required = true, paramLabel = "ARG", arity = "2")
-            String[] d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> --bb [--bb]... --aa=ARG [--aa=ARG]... --cc=ARG%n" +
-                "                    [--cc=ARG]... --dd=ARG ARG [--dd=ARG ARG]...%n" +
-                "      --aa=ARG%n" +
-                "      --bb%n" +
-                "      --cc=ARG%n" +
-                "      --dd=ARG ARG%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageFixedArityLongOptionArray() throws UnsupportedEncodingException {
-        class Args {
-            @Option(names = "--aa", paramLabel = "ARG") // default
-            String[] a;
-            @Option(names = "--bb", paramLabel = "ARG", arity = "0")
-            String[] b;
-            @Option(names = "--cc", paramLabel = "ARG", arity = "1")
-            String[] c;
-            @Option(names = "--dd", paramLabel = "ARG", arity = "2")
-            String[] d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> [--bb]... [--aa=ARG]... [--cc=ARG]... [--dd=ARG ARG]...%n" +
-                "      --aa=ARG%n" +
-                "      --bb%n" +
-                "      --cc=ARG%n" +
-                "      --dd=ARG ARG%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    //------------------
-    @Test
-    public void testUsageVariableArityRequiredShortOptionMap() throws UnsupportedEncodingException {
-        // if option is required at least once and can be specified multiple times:
-        // -f=ARG [-f=ARG]...
-        class Args {
-            @Option(names = "-a", required = true, paramLabel = "KEY=VAL") // default
-            Map<String, String> a;
-            @Option(names = "-b", required = true, arity = "0..*")
-            @SuppressWarnings("unchecked")
-            Map b;
-            @Option(names = "-c", required = true, arity = "1..*", type = {String.class, TimeUnit.class})
-            Map<String, TimeUnit> c;
-            @Option(names = "-d", required = true, arity = "2..*", type = {Integer.class, URL.class}, description = "description")
-            Map<Integer, URL> d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> -a=KEY=VAL [-a=KEY=VAL]... -b=[<String=String>]... [-b=%n" +
-                "                    [<String=String>]...]... -c=<String=TimeUnit>...%n" +
-                "                    [-c=<String=TimeUnit>...]... -d=<Integer=URL>%n" +
-                "                    <Integer=URL>... [-d=<Integer=URL> <Integer=URL>...]...%n" +
-                "  -a= KEY=VAL%n" +
-                "  -b= [<String=String>]...%n" +
-                "  -c= <String=TimeUnit>...%n" +
-                "  -d= <Integer=URL> <Integer=URL>...%n" +
-                "                              description%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageVariableArityOptionMap() throws UnsupportedEncodingException {
-        class Args {
-            @Option(names = "-a") // default
-            Map<String, String> a;
-            @Option(names = "-b", arity = "0..*", type = {Integer.class, Integer.class})
-            Map<Integer, Integer> b;
-            @Option(names = "-c", paramLabel = "KEY=VALUE", arity = "1..*", type = {String.class, TimeUnit.class})
-            Map<String, TimeUnit> c;
-            @Option(names = "-d", arity = "2..*", type = {String.class, URL.class}, description = "description")
-            Map<String, URL> d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> [-a=<String=String>]... [-b=[<Integer=Integer>]...]...%n" +
-                "                    [-c=KEY=VALUE...]... [-d=<String=URL> <String=URL>...]...%n" +
-                "  -a= <String=String>%n" +
-                "  -b= [<Integer=Integer>]...%n" +
-                "  -c= KEY=VALUE...%n" +
-                "  -d= <String=URL> <String=URL>...%n" +
-                "                              description%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageRangeArityRequiredOptionMap() throws UnsupportedEncodingException {
-        // if option is required at least once and can be specified multiple times:
-        // -f=ARG [-f=ARG]...
-        class Args {
-            @Option(names = "-a", required = true, arity = "0..1", description = "a description")
-            Map<String, String> a;
-            @Option(names = "-b", required = true, arity = "1..2", type = {Integer.class, Integer.class}, description = "b description")
-            Map<Integer, Integer> b;
-            @Option(names = "-c", required = true, arity = "1..3", type = {String.class, URL.class}, description = "c description")
-            Map<String, URL> c;
-            @Option(names = "-d", required = true, paramLabel = "K=URL", arity = "2..4", description = "d description")
-            Map<String, URL> d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> -a[=<String=String>] [-a[=<String=String>]]...%n" +
-                "                    -b=<Integer=Integer> [<Integer=Integer>]%n" +
-                "                    [-b=<Integer=Integer> [<Integer=Integer>]]...%n" +
-                "                    -c=<String=URL> [<String=URL> [<String=URL>]]%n" +
-                "                    [-c=<String=URL> [<String=URL> [<String=URL>]]]... -d=K=URL%n" +
-                "                    K=URL [K=URL [K=URL]] [-d=K=URL K=URL [K=URL [K=URL]]]...%n" +
-                "  -a= [<String=String>]       a description%n" +
-                "  -b= <Integer=Integer> [<Integer=Integer>]%n" +
-                "                              b description%n" +
-                "  -c= <String=URL> [<String=URL> [<String=URL>]]%n" +
-                "                              c description%n" +
-                "  -d= K=URL K=URL [K=URL [K=URL]]%n" +
-                "                              d description%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageRangeArityOptionMap() throws UnsupportedEncodingException {
-        class Args {
-            @Option(names = "-a", arity = "0..1"/*, type = {UUID.class, URL.class}*/, description = "a description")
-            Map<UUID, URL> a;
-            @Option(names = "-b", arity = "1..2", type = {Long.class, UUID.class}, description = "b description")
-            Map<?, ?> b;
-            @Option(names = "-c", arity = "1..3", type = {Long.class}, description = "c description")
-            Map<?, ?> c;
-            @Option(names = "-d", paramLabel = "K=V", arity = "2..4", description = "d description")
-            Map<?, ?> d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> [-a[=<UUID=URL>]]... [-b=<Long=UUID> [<Long=UUID>]]...%n" +
-                "                    [-c=<String=String> [<String=String> [<String=String>]]]...%n" +
-                "                    [-d=K=V K=V [K=V [K=V]]]...%n" +
-                "  -a= [<UUID=URL>]            a description%n" +
-                "  -b= <Long=UUID> [<Long=UUID>]%n" +
-                "                              b description%n" +
-                "  -c= <String=String> [<String=String> [<String=String>]]%n" +
-                "                              c description%n" +
-                "  -d= K=V K=V [K=V [K=V]]     d description%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageFixedArityRequiredOptionMap() throws UnsupportedEncodingException {
-        // if option is required at least once and can be specified multiple times:
-        // -f=ARG [-f=ARG]...
-        class Args {
-            @Option(names = "-a", required = true, description = "a description")
-            Map<Short, Field> a;
-            @Option(names = "-b", required = true, paramLabel = "KEY=VAL", arity = "0", description = "b description")
-            @SuppressWarnings("unchecked")
-            Map b;
-            @Option(names = "-c", required = true, arity = "1", type = {Long.class, File.class}, description = "c description")
-            Map<Long, File> c;
-            @Option(names = "-d", required = true, arity = "2", type = {URI.class, URL.class}, description = "d description")
-            Map<URI, URL> d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> -b [-b]... -a=<Short=Field> [-a=<Short=Field>]...%n" +
-                "                    -c=<Long=File> [-c=<Long=File>]... -d=<URI=URL> <URI=URL>%n" +
-                "                    [-d=<URI=URL> <URI=URL>]...%n" +
-                "  -a= <Short=Field>           a description%n" +
-                "  -b                          b description%n" +
-                "  -c= <Long=File>             c description%n" +
-                "  -d= <URI=URL> <URI=URL>     d description%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageFixedArityOptionMap() throws UnsupportedEncodingException {
-        class Args {
-            @Option(names = "-a", type = {Short.class, Field.class}, description = "a description")
-            Map<Short, Field> a;
-            @Option(names = "-b", arity = "0", type = {UUID.class, Long.class}, description = "b description")
-            @SuppressWarnings("unchecked")
-            Map b;
-            @Option(names = "-c", arity = "1", description = "c description")
-            Map<Long, File> c;
-            @Option(names = "-d", arity = "2", type = {URI.class, URL.class}, description = "d description")
-            Map<URI, URL> d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> [-b]... [-a=<Short=Field>]... [-c=<Long=File>]...%n" +
-                "                    [-d=<URI=URL> <URI=URL>]...%n" +
-                "  -a= <Short=Field>           a description%n" +
-                "  -b                          b description%n" +
-                "  -c= <Long=File>             c description%n" +
-                "  -d= <URI=URL> <URI=URL>     d description%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-    //--------------
-    @Test
-    public void testUsageVariableArityParametersArray() throws UnsupportedEncodingException {
-        // if option is required at least once and can be specified multiple times:
-        // -f=ARG [-f=ARG]...
-        class Args {
-            @Parameters(paramLabel = "APARAM", description = "APARAM description")
-            String[] a;
-            @Parameters(arity = "0..*", description = "b description")
-            List<String> b;
-            @Parameters(arity = "1..*", description = "c description")
-            String[] c;
-            @Parameters(arity = "2..*", description = "d description")
-            List<String> d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> [APARAM]... [<b>]... <c>... <d> <d>...%n" +
-                "      [APARAM]...             APARAM description%n" +
-                "      [<b>]...                b description%n" +
-                "      <c>...                  c description%n" +
-                "      <d> <d>...              d description%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageRangeArityParameterArray() throws UnsupportedEncodingException {
-        class Args {
-            @Parameters(index = "0", paramLabel = "PARAMA", arity = "0..1", description = "PARAMA description")
-            List<String> a;
-            @Parameters(index = "0", paramLabel = "PARAMB", arity = "1..2", description = "PARAMB description")
-            String[] b;
-            @Parameters(index = "0", paramLabel = "PARAMC", arity = "1..3", description = "PARAMC description")
-            String[] c;
-            @Parameters(index = "0", paramLabel = "PARAMD", arity = "2..4", description = "PARAMD description")
-            String[] d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> [PARAMA] PARAMB [PARAMB] PARAMC [PARAMC [PARAMC]] PARAMD%n" +
-                "                    PARAMD [PARAMD [PARAMD]]%n" +
-                "      [PARAMA]                PARAMA description%n" +
-                "      PARAMB [PARAMB]         PARAMB description%n" +
-                "      PARAMC [PARAMC [PARAMC]]%n" +
-                "                              PARAMC description%n" +
-                "      PARAMD PARAMD [PARAMD [PARAMD]]%n" +
-                "                              PARAMD description%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageFixedArityParametersArray() throws UnsupportedEncodingException {
-        class Args {
-            @Parameters(description = "a description (default arity)")
-            String[] a;
-            @Parameters(index = "0", arity = "0", description = "b description (arity=0)")
-            String[] b;
-            @Parameters(index = "1", arity = "1", description = "b description (arity=1)")
-            String[] c;
-            @Parameters(index = "2", arity = "2", description = "b description (arity=2)")
-            String[] d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class>  [<a>]... <c> <d> <d>%n" +
-                "                              b description (arity=0)%n" +
-                "      [<a>]...                a description (default arity)%n" +
-                "      <c>                     b description (arity=1)%n" +
-                "      <d> <d>                 b description (arity=2)%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageVariableArityParametersMap() throws UnsupportedEncodingException {
-        class Args {
-            @Parameters()
-            Map<String, String> a;
-            @Parameters(arity = "0..*", description = "a description (arity=0..*)")
-            Map<Integer, Integer> b;
-            @Parameters(paramLabel = "KEY=VALUE", arity = "1..*", type = {String.class, TimeUnit.class})
-            Map<String, TimeUnit> c;
-            @Parameters(arity = "2..*", type = {String.class, URL.class}, description = "description")
-            Map<String, URL> d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> [<String=String>]... [<Integer=Integer>]... KEY=VALUE...%n" +
-                "                    <String=URL> <String=URL>...%n" +
-                "      [<String=String>]...%n" +
-                "      [<Integer=Integer>]...  a description (arity=0..*)%n" +
-                "      KEY=VALUE...%n" +
-                "      <String=URL> <String=URL>...%n" +
-                "                              description%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageRangeArityParametersMap() throws UnsupportedEncodingException {
-        class Args {
-            @Parameters(index = "0", arity = "0..1"/*, type = {UUID.class, URL.class}*/, description = "a description")
-            Map<UUID, URL> a;
-            @Parameters(index = "1", arity = "1..2", type = {Long.class, UUID.class}, description = "b description")
-            Map<?, ?> b;
-            @Parameters(index = "2", arity = "1..3", type = {Long.class}, description = "c description")
-            Map<?, ?> c;
-            @Parameters(index = "3", paramLabel = "K=V", arity = "2..4", description = "d description")
-            Map<?, ?> d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class> [<UUID=URL>] <Long=UUID> [<Long=UUID>] <String=String>%n" +
-                "                    [<String=String> [<String=String>]] K=V K=V [K=V [K=V]]%n" +
-                "      [<UUID=URL>]            a description%n" +
-                "      <Long=UUID> [<Long=UUID>]%n" +
-                "                              b description%n" +
-                "      <String=String> [<String=String> [<String=String>]]%n" +
-                "                              c description%n" +
-                "      K=V K=V [K=V [K=V]]     d description%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-
-    @Test
-    public void testUsageFixedArityParametersMap() throws UnsupportedEncodingException {
-        class Args {
-            @Parameters(type = {Short.class, Field.class}, description = "a description")
-            Map<Short, Field> a;
-            @Parameters(index = "0", arity = "0", type = {UUID.class, Long.class}, description = "b description (arity=0)")
-            @SuppressWarnings("unchecked")
-            Map b;
-            @Parameters(index = "1", arity = "1", description = "c description")
-            Map<Long, File> c;
-            @Parameters(index = "2", arity = "2", type = {URI.class, URL.class}, description = "d description")
-            Map<URI, URL> d;
-        }
-        String expected = String.format("" +
-                "Usage: <main class>  [<Short=Field>]... <Long=File> <URI=URL> <URI=URL>%n" +
-                "                              b description (arity=0)%n" +
-                "      [<Short=Field>]...      a description%n" +
-                "      <Long=File>             c description%n" +
-                "      <URI=URL> <URI=URL>     d description%n");
-        //CommandLine.usage(new Args(), System.out);
-        assertEquals(expected, usageString(new Args(), Help.Ansi.OFF));
-    }
-    //----------
-    @Test
-    public void testShortestFirstComparator_sortsShortestFirst() {
-        String[] values = {"12345", "12", "123", "123456", "1", "", "1234"};
-        Arrays.sort(values, new Help.ShortestFirst());
-        String[] expected = {"", "1", "12", "123", "1234", "12345", "123456"};
-        assertArrayEquals(expected, values);
-    }
-
-    @Test
-    public void testShortestFirstComparator_sortsDeclarationOrderIfEqualLength() {
-        String[] values = {"-d", "-", "-a", "--alpha", "--b", "--a", "--beta"};
-        Arrays.sort(values, new Help.ShortestFirst());
-        String[] expected = {"-", "-d", "-a", "--b", "--a", "--beta", "--alpha"};
-        assertArrayEquals(expected, values);
-    }
-
-    @Test
-    public void testSortByShortestOptionNameComparator() throws Exception {
-        class App {
-            @Option(names = {"-t", "--aaaa"}) boolean aaaa;
-            @Option(names = {"--bbbb", "-k"}) boolean bbbb;
-            @Option(names = {"-c", "--cccc"}) boolean cccc;
-        }
-        Field[] fields = fields(App.class, "aaaa", "bbbb", "cccc"); // -tkc
-        Arrays.sort(fields, new Help.SortByShortestOptionNameAlphabetically());
-        Field[] expected = fields(App.class, "cccc", "bbbb", "aaaa"); // -ckt
-        assertArrayEquals(expected, fields);
-    }
-
-    @Test
-    public void testSortByOptionArityAndNameComparator_sortsByMaxThenMinThenName() throws Exception {
-        class App {
-            @Option(names = {"-t", "--aaaa"}                ) boolean tImplicitArity0;
-            @Option(names = {"-e", "--EEE"}, arity = "1"    ) boolean explicitArity1;
-            @Option(names = {"--bbbb", "-k"}                ) boolean kImplicitArity0;
-            @Option(names = {"--AAAA", "-a"}                ) int aImplicitArity1;
-            @Option(names = {"--BBBB", "-z"}                ) String[] zImplicitArity1;
-            @Option(names = {"--ZZZZ", "-b"}, arity = "1..3") String[] bExplicitArity1_3;
-            @Option(names = {"-f", "--ffff"}                ) boolean fImplicitArity0;
-        }
-        Field[] fields = fields(App.class, "tImplicitArity0", "explicitArity1", "kImplicitArity0",
-                "aImplicitArity1", "zImplicitArity1", "bExplicitArity1_3", "fImplicitArity0");
-        Arrays.sort(fields, new Help.SortByOptionArityAndNameAlphabetically());
-        Field[] expected = fields(App.class,
-                "fImplicitArity0",
-                "kImplicitArity0",
-                "tImplicitArity0",
-                "aImplicitArity1",
-                "explicitArity1",
-                "zImplicitArity1",
-                "bExplicitArity1_3");
-        assertArrayEquals(expected, fields);
-    }
-
-    @Test
-    public void testCreateMinimalOptionRenderer_ReturnsMinimalOptionRenderer() {
-        assertEquals(Help.MinimalOptionRenderer.class, Help.createMinimalOptionRenderer().getClass());
-    }
-
-    @Test
-    public void testMinimalOptionRenderer_rendersFirstDeclaredOptionNameAndDescription() {
-        class Example {
-            @Option(names = {"---long", "-L"}, description = "long description") String longField;
-            @Option(names = {"-b", "-a", "--alpha"}, description = "other") String otherField;
-        }
-        Help.IOptionRenderer renderer = Help.createMinimalOptionRenderer();
-        Help help = new Help(new Example(), Help.defaultColorScheme(Help.Ansi.ON));
-        Help.IParamLabelRenderer parameterRenderer = help.createDefaultParamLabelRenderer();
-        Field field = help.optionFields.get(0);
-        Text[][] row1 = renderer.render(field.getAnnotation(Option.class), field, parameterRenderer, Help.defaultColorScheme(
-                help.ansi()));
-        assertEquals(1, row1.length);
-        //assertArrayEquals(new String[]{"---long=<longField>", "long description"}, row1[0]);
-        assertArrayEquals(new Text[]{
-                help.ansi().new Text(format("%s---long%s=%s<longField>%s", "@|fg(yellow) ", "|@", "@|italic ", "|@")),
-                help.ansi().new Text("long description")}, row1[0]);
-
-        field = help.optionFields.get(1);
-        Text[][] row2 = renderer.render(field.getAnnotation(Option.class), field, parameterRenderer, Help.defaultColorScheme(
-                help.ansi()));
-        assertEquals(1, row2.length);
-        //assertArrayEquals(new String[]{"-b=<otherField>", "other"}, row2[0]);
-        assertArrayEquals(new Text[]{
-                help.ansi().new Text(format("%s-b%s=%s<otherField>%s", "@|fg(yellow) ", "|@", "@|italic ", "|@")),
-                help.ansi().new Text("other")}, row2[0]);
-    }
-
-    @Test
-    public void testCreateDefaultOptionRenderer_ReturnsDefaultOptionRenderer() {
-        assertEquals(Help.DefaultOptionRenderer.class, new Help(new UsageDemo()).createDefaultOptionRenderer().getClass());
-    }
-
-    private static Text[] textArray(Help help, String... str) {
-        return textArray(help.ansi(), str);
-    }
-    private static Text[] textArray(Help.Ansi ansi, String... str) {
-        Text[] result = new Text[str.length];
-        for (int i = 0; i < str.length; i++) {
-            result[i] = str[i] == null ? Help.Ansi.EMPTY_TEXT : ansi.new Text(str[i]);
-        }
-        return result;
-    }
-
-    @Test
-    public void testDefaultOptionRenderer_rendersShortestOptionNameThenOtherOptionNamesAndDescription() {
-        @Command(showDefaultValues = true)
-        class Example {
-            @Option(names = {"---long", "-L"}, description = "long description") String longField;
-            @Option(names = {"-b", "-a", "--alpha"}, description = "other") String otherField = "abc";
-        }
-        Help help = new Help(new Example());
-        Help.IOptionRenderer renderer = help.createDefaultOptionRenderer();
-        Help.IParamLabelRenderer parameterRenderer = help.createDefaultParamLabelRenderer();
-        Field field = help.optionFields.get(0);
-        Text[][] row1 = renderer.render(field.getAnnotation(Option.class), field, parameterRenderer, help.colorScheme);
-        assertEquals(1, row1.length);
-        assertArrayEquals(Arrays.toString(row1[0]), textArray(help, "", "-L", ",", "---long=<longField>", "long description"), row1[0]);
-        //assertArrayEquals(Arrays.toString(row1[1]), textArray(help, "", "", "", "", "  Default: null"), row1[1]); // #201 don't show null defaults
-
-        field = help.optionFields.get(1);
-        Text[][] row2 = renderer.render(field.getAnnotation(Option.class), field, parameterRenderer, help.colorScheme);
-        assertEquals(2, row2.length);
-        assertArrayEquals(Arrays.toString(row2[0]), textArray(help, "", "-b", ",", "-a, --alpha=<otherField>", "other"), row2[0]);
-        assertArrayEquals(Arrays.toString(row2[1]), textArray(help, "", "", "", "", "  Default: abc"), row2[1]);
-    }
-
-    @Test
-    public void testDefaultOptionRenderer_rendersSpecifiedMarkerForRequiredOptionsWithDefault() {
-        @Command(requiredOptionMarker = '*', showDefaultValues = true)
-        class Example {
-            @Option(names = {"-b", "-a", "--alpha"}, required = true, description = "other") String otherField ="abc";
-        }
-        Help help = new Help(new Example());
-        Help.IOptionRenderer renderer = help.createDefaultOptionRenderer();
-        Help.IParamLabelRenderer parameterRenderer = help.createDefaultParamLabelRenderer();
-        Field field = help.optionFields.get(0);
-        Text[][] row = renderer.render(field.getAnnotation(Option.class), field, parameterRenderer, help.colorScheme);
-        assertEquals(2, row.length);
-        assertArrayEquals(Arrays.toString(row[0]), textArray(help, "*", "-b", ",", "-a, --alpha=<otherField>", "other"), row[0]);
-        assertArrayEquals(Arrays.toString(row[1]), textArray(help, "", "", "", "", "  Default: abc"), row[1]);
-    }
-
-    @Test
-    public void testDefaultOptionRenderer_rendersSpecifiedMarkerForRequiredOptionsWithoutDefault() {
-        @Command(requiredOptionMarker = '*')
-        class Example {
-            @Option(names = {"-b", "-a", "--alpha"}, required = true, description = "other") String otherField ="abc";
-        }
-        Help help = new Help(new Example());
-        Help.IOptionRenderer renderer = help.createDefaultOptionRenderer();
-        Help.IParamLabelRenderer parameterRenderer = help.createDefaultParamLabelRenderer();
-        Field field = help.optionFields.get(0);
-        Text[][] row = renderer.render(field.getAnnotation(Option.class), field, parameterRenderer, help.colorScheme);
-        assertEquals(1, row.length);
-        assertArrayEquals(Arrays.toString(row[0]), textArray(help, "*", "-b", ",", "-a, --alpha=<otherField>", "other"), row[0]);
-    }
-
-    @Test
-    public void testDefaultOptionRenderer_rendersSpacePrefixByDefaultForRequiredOptionsWithoutDefaultValue() {
-        class Example {
-            @Option(names = {"-b", "-a", "--alpha"}, required = true, description = "other") String otherField;
-        }
-        Help help = new Help(new Example());
-        Help.IOptionRenderer renderer = help.createDefaultOptionRenderer();
-        Help.IParamLabelRenderer parameterRenderer = help.createDefaultParamLabelRenderer();
-        Field field = help.optionFields.get(0);
-        Text[][] row = renderer.render(field.getAnnotation(Option.class), field, parameterRenderer, help.colorScheme);
-        assertEquals(1, row.length);
-        assertArrayEquals(Arrays.toString(row[0]), textArray(help, " ", "-b", ",", "-a, --alpha=<otherField>", "other"), row[0]);
-    }
-
-    @Test
-    public void testDefaultOptionRenderer_rendersSpacePrefixByDefaultForRequiredOptionsWithDefaultValue() {
-        //@Command(showDefaultValues = true) // set programmatically
-        class Example {
-            @Option(names = {"-b", "-a", "--alpha"}, required = true, description = "other") String otherField;
-        }
-        Help help = new Help(new Example());
-        help.showDefaultValues = true;
-        Help.IOptionRenderer renderer = help.createDefaultOptionRenderer();
-        Help.IParamLabelRenderer parameterRenderer = help.createDefaultParamLabelRenderer();
-        Field field = help.optionFields.get(0);
-        Text[][] row = renderer.render(field.getAnnotation(Option.class), field, parameterRenderer, help.colorScheme);
-        assertEquals(1, row.length);
-        assertArrayEquals(Arrays.toString(row[0]), textArray(help, " ", "-b", ",", "-a, --alpha=<otherField>", "other"), row[0]);
-        // assertArrayEquals(Arrays.toString(row[1]), textArray(help, "",    "", "",  "", "  Default: null"), row[1]); // #201 don't show null defaults
-    }
-
-    @Test
-    public void testDefaultParameterRenderer_rendersSpacePrefixByDefaultForParametersWithPositiveArity() {
-        class Required {
-            @Parameters(description = "required") String required;
-        }
-        Help help = new Help(new Required());
-        Help.IParameterRenderer renderer = help.createDefaultParameterRenderer();
-        Help.IParamLabelRenderer parameterRenderer = Help.createMinimalParamLabelRenderer();
-        Field field = help.positionalParametersFields.get(0);
-        Text[][] row1 = renderer.render(field.getAnnotation(Parameters.class), field, parameterRenderer, help.colorScheme);
-        assertEquals(1, row1.length);
-        assertArrayEquals(Arrays.toString(row1[0]), textArray(help, " ", "", "", "<required>", "required"), row1[0]);
-    }
-
-    @Test
-    public void testDefaultParameterRenderer_rendersSpecifiedMarkerForParametersWithPositiveArity() {
-        @Command(requiredOptionMarker = '*')
-        class Required {
-            @Parameters(description = "required") String required;
-        }
-        Help help = new Help(new Required());
-        Help.IParameterRenderer renderer = help.createDefaultParameterRenderer();
-        Help.IParamLabelRenderer parameterRenderer = Help.createMinimalParamLabelRenderer();
-        Field field = help.positionalParametersFields.get(0);
-        Text[][] row1 = renderer.render(field.getAnnotation(Parameters.class), field, parameterRenderer, help.colorScheme);
-        assertEquals(1, row1.length);
-        assertArrayEquals(Arrays.toString(row1[0]), textArray(help, "*", "", "", "<required>", "required"), row1[0]);
-    }
-
-    @Test
-    public void testDefaultParameterRenderer_rendersSpacePrefixForParametersWithZeroArity() {
-        @Command(requiredOptionMarker = '*')
-        class Optional {
-            @Parameters(arity = "0..1", description = "optional") String optional;
-        }
-        Help help = new Help(new Optional());
-        Help.IParameterRenderer renderer = help.createDefaultParameterRenderer();
-        Help.IParamLabelRenderer parameterRenderer = Help.createMinimalParamLabelRenderer();
-        Field field = help.positionalParametersFields.get(0);
-        Text[][] row1 = renderer.render(field.getAnnotation(Parameters.class), field, parameterRenderer, help.colorScheme);
-        assertEquals(1, row1.length);
-        assertArrayEquals(Arrays.toString(row1[0]), textArray(help, "", "", "", "<optional>", "optional"), row1[0]);
-    }
-
-    @Test
-    public void testDefaultOptionRenderer_rendersCommaOnlyIfBothShortAndLongOptionNamesExist() {
-        class Example {
-            @Option(names = {"-v"}, description = "shortBool") boolean shortBoolean;
-            @Option(names = {"--verbose"}, description = "longBool") boolean longBoolean;
-            @Option(names = {"-x", "--xeno"}, description = "combiBool") boolean combiBoolean;
-            @Option(names = {"-s"}, description = "shortOnly") String shortOnlyField;
-            @Option(names = {"--long"}, description = "longOnly") String longOnlyField;
-            @Option(names = {"-b", "--beta"}, description = "combi") String combiField;
-        }
-        Help help = new Help(new Example());
-        help.showDefaultValues = false; // omit default values from description column
-        Help.IOptionRenderer renderer = help.createDefaultOptionRenderer();
-        Help.IParamLabelRenderer parameterRenderer = help.createDefaultParamLabelRenderer();
-
-        String[][] expected = new String[][] {
-                {"", "-v", "",  "", "shortBool"},
-                {"", "",   "",  "--verbose", "longBool"},
-                {"", "-x", ",", "--xeno", "combiBool"},
-                {"", "-s", "=",  "<shortOnlyField>", "shortOnly"},
-                {"", "",   "",  "--long=<longOnlyField>", "longOnly"},
-                {"", "-b", ",", "--beta=<combiField>", "combi"},
-        };
-        int i = -1;
-        for (Field field : help.optionFields) {
-            Text[][] row = renderer.render(field.getAnnotation(Option.class), field, parameterRenderer, help.colorScheme);
-            assertEquals(1, row.length);
-            assertArrayEquals(Arrays.toString(row[0]), textArray(help, expected[++i]), row[0]);
-        }
-    }
-
-    @Test
-    public void testDefaultOptionRenderer_omitsDefaultValuesForBooleanFields() {
-        @Command(showDefaultValues = true)
-        class Example {
-            @Option(names = {"-v"}, description = "shortBool") boolean shortBoolean;
-            @Option(names = {"--verbose"}, description = "longBool") Boolean longBoolean;
-            @Option(names = {"-s"}, description = "shortOnly") String shortOnlyField = "short";
-            @Option(names = {"--long"}, description = "longOnly") String longOnlyField = "long";
-            @Option(names = {"-b", "--beta"}, description = "combi") int combiField = 123;
-        }
-        Help help = new Help(new Example());
-        Help.IOptionRenderer renderer = help.createDefaultOptionRenderer();
-        Help.IParamLabelRenderer parameterRenderer = help.createDefaultParamLabelRenderer();
-
-        String[][] expected = new String[][] {
-                {"", "-v", "",  "", "shortBool"},
-                {"", "",   "",  "--verbose", "longBool"},
-                {"", "-s", "=",  "<shortOnlyField>", "shortOnly"},
-                {"",   "", "",  "", "Default: short"},
-                {"", "",   "",  "--long=<longOnlyField>", "longOnly"},
-                {"", "",   "",  "", "Default: long"},
-                {"", "-b", ",", "--beta=<combiField>", "combi"},
-                {"", "",   "",  "", "Default: 123"},
-        };
-        int[] rowCount = {1, 1, 2, 2, 2};
-        int i = -1;
-        int rowIndex = 0;
-        for (Field field : help.optionFields) {
-            Text[][] row = renderer.render(field.getAnnotation(Option.class), field, parameterRenderer, help.colorScheme);
-            assertEquals(rowCount[++i], row.length);
-            assertArrayEquals(Arrays.toString(row[0]), textArray(help, expected[rowIndex]), row[0]);
-            rowIndex += rowCount[i];
-        }
-    }
-
-    @Test
-    public void testCreateDefaultParameterRenderer_ReturnsDefaultParameterRenderer() {
-        assertEquals(Help.DefaultParamLabelRenderer.class, new Help(new UsageDemo()).createDefaultParamLabelRenderer().getClass());
-    }
-
-    @Test
-    public void testDefaultParameterRenderer_showsParamLabelIfPresentOrFieldNameOtherwise() {
-        class Example {
-            @Option(names = "--without" ) String longField;
-            @Option(names = "--with", paramLabel = "LABEL") String otherField;
-        }
-        Help help = new Help(new Example());
-        Help.IParamLabelRenderer equalSeparatedParameterRenderer = help.createDefaultParamLabelRenderer();
-        help.separator = " ";
-        Help.IParamLabelRenderer spaceSeparatedParameterRenderer = help.createDefaultParamLabelRenderer();
-
-        String[] expected = new String[] {
-                "<longField>",
-                "LABEL",
-        };
-        int i = -1;
-        for (Field field : help.optionFields) {
-            i++;
-            Text withSpace = spaceSeparatedParameterRenderer.renderParameterLabel(field, help.ansi(), Collections.<IStyle>emptyList());
-            assertEquals(withSpace.toString(), " " + expected[i], withSpace.toString());
-            Text withEquals = equalSeparatedParameterRenderer.renderParameterLabel(field, help.ansi(), Collections.<IStyle>emptyList());
-            assertEquals(withEquals.toString(), "=" + expected[i], withEquals.toString());
-        }
-    }
-
-    @Test
-    public void testDefaultParameterRenderer_appliesToPositionalArgumentsIgnoresSeparator() {
-        class WithLabel    { @Parameters(paramLabel = "POSITIONAL_ARGS") String positional; }
-        class WithoutLabel { @Parameters()                               String positional; }
-
-        Help withLabel = new Help(new WithLabel());
-        Help.IParamLabelRenderer equals = withLabel.createDefaultParamLabelRenderer();
-        withLabel.separator = "=";
-        Help.IParamLabelRenderer spaced = withLabel.createDefaultParamLabelRenderer();
-
-        Text withSpace = spaced.renderParameterLabel(withLabel.positionalParametersFields.get(0), withLabel.ansi(), Collections.<IStyle>emptyList());
-        assertEquals(withSpace.toString(), "POSITIONAL_ARGS", withSpace.toString());
-        Text withEquals = equals.renderParameterLabel(withLabel.positionalParametersFields.get(0), withLabel.ansi(), Collections.<IStyle>emptyList());
-        assertEquals(withEquals.toString(), "POSITIONAL_ARGS", withEquals.toString());
-
-        Help withoutLabel = new Help(new WithoutLabel());
-        withSpace = spaced.renderParameterLabel(withoutLabel.positionalParametersFields.get(0), withoutLabel.ansi(), Collections.<IStyle>emptyList());
-        assertEquals(withSpace.toString(), "<positional>", withSpace.toString());
-        withEquals = equals.renderParameterLabel(withoutLabel.positionalParametersFields.get(0), withoutLabel.ansi(), Collections.<IStyle>emptyList());
-        assertEquals(withEquals.toString(), "<positional>", withEquals.toString());
-    }
-
-    @Test
-    public void testDefaultLayout_addsEachRowToTable() {
-        final Text[][] values = {
-                textArray(Help.Ansi.OFF, "a", "b", "c", "d"),
-                textArray(Help.Ansi.OFF, "1", "2", "3", "4")
-        };
-        final int[] count = {0};
-        TextTable tt = new TextTable(Help.Ansi.OFF) {
-            @Override public void addRowValues(Text[] columnValues) {
-                assertArrayEquals(values[count[0]], columnValues);
-                count[0]++;
-            }
-        };
-        Help.Layout layout = new Help.Layout(Help.defaultColorScheme(Help.Ansi.OFF), tt);
-        layout.layout(null, values);
-        assertEquals(2, count[0]);
-    }
-
-    @Test
-    public void testAbreviatedSynopsis_withoutParameters() {
-        @CommandLine.Command(abbreviateSynopsis = true)
-        class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}) int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-        }
-        Help help = new Help(new App(), Help.Ansi.OFF);
-        assertEquals("<main class> [OPTIONS]" + LINESEP, help.synopsis(0));
-    }
-
-    @Test
-    public void testAbreviatedSynopsis_withoutParameters_ANSI() {
-        @CommandLine.Command(abbreviateSynopsis = true)
-        class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}) int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-        }
-        Help help = new Help(new App(), Help.defaultColorScheme(Help.Ansi.ON));
-        assertEquals(Help.Ansi.ON.new Text("@|bold <main class>|@ [OPTIONS]" + LINESEP).toString(), help.synopsis(0));
-    }
-
-    @Test
-    public void testAbreviatedSynopsis_withParameters() {
-        @CommandLine.Command(abbreviateSynopsis = true)
-        class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}) int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-            @Parameters File[] files;
-        }
-        Help help = new Help(new App(), Help.Ansi.OFF);
-        assertEquals("<main class> [OPTIONS] [<files>]..." + LINESEP, help.synopsis(0));
-    }
-
-    @Test
-    public void testAbreviatedSynopsis_withParameters_ANSI() {
-        @CommandLine.Command(abbreviateSynopsis = true)
-        class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}) int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-            @Parameters File[] files;
-        }
-        Help help = new Help(new App(), Help.defaultColorScheme(Help.Ansi.ON));
-        assertEquals(Help.Ansi.ON.new Text("@|bold <main class>|@ [OPTIONS] [@|yellow <files>|@]..." + LINESEP).toString(), help.synopsis(0));
-    }
-
-    @Test
-    public void testAbreviatedSynopsis_commandNameCustomizableDeclaratively() throws UnsupportedEncodingException {
-        @CommandLine.Command(abbreviateSynopsis = true, name = "aprogram")
-        class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}) int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-            @Parameters File[] files;
-        }
-        String expected = "" +
-                "Usage: aprogram [OPTIONS] [<files>]...%n" +
-                "      [<files>]...%n" +
-                "  -c, --count=<count>%n" +
-                "  -v, --verbose%n";
-        String actual = usageString(new CommandLine(new App()), Help.Ansi.OFF);
-        assertEquals(String.format(expected), actual);
-    }
-
-    @Test
-    public void testAbreviatedSynopsis_commandNameCustomizableProgrammatically() throws UnsupportedEncodingException {
-        @CommandLine.Command(abbreviateSynopsis = true)
-        class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}) int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-            @Parameters File[] files;
-        }
-        String expected = "" +
-                "Usage: anotherProgram [OPTIONS] [<files>]...%n" +
-                "      [<files>]...%n" +
-                "  -c, --count=<count>%n" +
-                "  -v, --verbose%n";
-        String actual = usageString(new CommandLine(new App()).setCommandName("anotherProgram"), Help.Ansi.OFF);
-        assertEquals(String.format(expected), actual);
-    }
-
-    @Test
-    public void testSynopsis_commandNameCustomizableDeclaratively() throws UnsupportedEncodingException {
-        @CommandLine.Command(name = "aprogram")
-        class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}) int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-            @Parameters File[] files;
-        }
-        String expected = "" +
-                "Usage: aprogram [-v] [-c=<count>] [<files>]...%n" +
-                "      [<files>]...%n" +
-                "  -c, --count=<count>%n" +
-                "  -v, --verbose%n";
-        String actual = usageString(new CommandLine(new App()), Help.Ansi.OFF);
-        assertEquals(String.format(expected), actual);
-    }
-
-    @Test
-    public void testSynopsis_commandNameCustomizableProgrammatically() throws UnsupportedEncodingException {
-        class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}) int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-            @Parameters File[] files;
-        }
-        String expected = "" +
-                "Usage: anotherProgram [-v] [-c=<count>] [<files>]...%n" +
-                "      [<files>]...%n" +
-                "  -c, --count=<count>%n" +
-                "  -v, --verbose%n";
-        String actual = usageString(new CommandLine(new App()).setCommandName("anotherProgram"), Help.Ansi.OFF);
-        assertEquals(String.format(expected), actual);
-    }
-
-    @Test
-    public void testSynopsis_optionalOptionArity1_n_withDefaultSeparator() {
-        @Command() class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}, arity = "1..*") int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-        }
-        Help help = new Help(new App(), Help.Ansi.OFF);
-        assertEquals("<main class> [-v] [-c=<count>...]" + LINESEP, help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_optionalOptionArity1_n_withDefaultSeparator_ANSI() {
-        @Command() class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}, arity = "1..*") int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-        }
-        Help help = new Help(new App(), Help.defaultColorScheme(Help.Ansi.ON));
-        assertEquals(Help.Ansi.ON.new Text("@|bold <main class>|@ [@|yellow -v|@] [@|yellow -c|@=@|italic <count>|@...]" + LINESEP),
-                help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_optionalOptionArity0_1_withSpaceSeparator() {
-        @CommandLine.Command(separator = " ") class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}, arity = "0..1") int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-        }
-        Help help = new Help(new App(), Help.Ansi.OFF);
-        assertEquals("<main class> [-v] [-c [<count>]]" + LINESEP, help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_optionalOptionArity0_1_withSpaceSeparator_ANSI() {
-        @CommandLine.Command(separator = " ") class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}, arity = "0..1") int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-        }
-        Help help = new Help(new App(), Help.defaultColorScheme(Help.Ansi.ON));
-        assertEquals(Help.Ansi.ON.new Text("@|bold <main class>|@ [@|yellow -v|@] [@|yellow -c|@ [@|italic <count>|@]]" + LINESEP), help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_requiredOptionWithSeparator() {
-        @Command() class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}, required = true) int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-        }
-        Help help = new Help(new App(), Help.Ansi.OFF);
-        assertEquals("<main class> [-v] -c=<count>" + LINESEP, help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_requiredOptionWithSeparator_ANSI() {
-        @Command() class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}, required = true) int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-        }
-        Help help = new Help(new App(), Help.defaultColorScheme(Help.Ansi.ON));
-        assertEquals(Help.Ansi.ON.new Text("@|bold <main class>|@ [@|yellow -v|@] @|yellow -c|@=@|italic <count>|@" + LINESEP), help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_optionalOption_withSpaceSeparator() {
-        @CommandLine.Command(separator = " ") class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}) int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-        }
-        Help help = new Help(new App(), Help.Ansi.OFF);
-        assertEquals("<main class> [-v] [-c <count>]" + LINESEP, help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_optionalOptionArity0_1__withSeparator() {
-        class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}, arity = "0..1") int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-        }
-        Help help = new Help(new App(), Help.Ansi.OFF);
-        assertEquals("<main class> [-v] [-c[=<count>]]" + LINESEP, help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_optionalOptionArity0_n__withSeparator() {
-        @CommandLine.Command(separator = "=") class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}, arity = "0..*") int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-        }
-        Help help = new Help(new App(), Help.Ansi.OFF);
-        // NOTE Expected :<main class> [-v] [-c[=<count>]...] but arity=0 for int field is weird anyway...
-        assertEquals("<main class> [-v] [-c=[<count>]...]" + LINESEP, help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_optionalOptionArity1_n__withSeparator() {
-        @CommandLine.Command(separator = "=") class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}, arity = "1..*") int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-        }
-        Help help = new Help(new App(), Help.Ansi.OFF);
-        assertEquals("<main class> [-v] [-c=<count>...]" + LINESEP, help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_withProgrammaticallySetSeparator_withParameters() throws UnsupportedEncodingException {
-        class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}) int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-            @Parameters File[] files;
-        }
-        CommandLine commandLine = new CommandLine(new App()).setSeparator(":");
-        String actual = usageString(commandLine, Help.Ansi.OFF);
-        String expected = "" +
-                "Usage: <main class> [-v] [-c:<count>] [<files>]...%n" +
-                "      [<files>]...%n" +
-                "  -c, --count:<count>%n" +
-                "  -v, --verbose%n";
-        assertEquals(String.format(expected), actual);
-    }
-
-    @Test
-    public void testSynopsis_withSeparator_withParameters() {
-        @CommandLine.Command(separator = ":") class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}) int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-            @Parameters File[] files;
-        }
-        Help help = new Help(new App(), Help.Ansi.OFF);
-        assertEquals("<main class> [-v] [-c:<count>] [<files>]..." + LINESEP, help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_withSeparator_withParameters_ANSI() {
-        @CommandLine.Command(separator = ":") class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}) int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-            @Parameters File[] files;
-        }
-        Help help = new Help(new App(), Help.defaultColorScheme(Help.Ansi.ON));
-        assertEquals(Help.Ansi.ON.new Text("@|bold <main class>|@ [@|yellow -v|@] [@|yellow -c|@:@|italic <count>|@] [@|yellow <files>|@]..." + LINESEP),
-                help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_withSeparator_withLabeledParameters() {
-        @Command(separator = "=") class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}) int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-            @Parameters(paramLabel = "FILE") File[] files;
-        }
-        Help help = new Help(new App(), Help.Ansi.OFF);
-        assertEquals("<main class> [-v] [-c=<count>] [FILE]..." + LINESEP, help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_withSeparator_withLabeledParameters_ANSI() {
-        @Command(separator = "=") class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}) int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-            @Parameters(paramLabel = "FILE") File[] files;
-        }
-        Help help = new Help(new App(), Help.defaultColorScheme(Help.Ansi.ON));
-        assertEquals(Help.Ansi.ON.new Text("@|bold <main class>|@ [@|yellow -v|@] [@|yellow -c|@=@|italic <count>|@] [@|yellow FILE|@]..." + LINESEP),
-                help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_withSeparator_withLabeledRequiredParameters() {
-        @CommandLine.Command(separator = "=") class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}) int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-            @Parameters(paramLabel = "FILE", arity = "1..*") File[] files;
-        }
-        Help help = new Help(new App(), Help.Ansi.OFF);
-        assertEquals("<main class> [-v] [-c=<count>] FILE..." + LINESEP, help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_withSeparator_withLabeledRequiredParameters_ANSI() {
-        @CommandLine.Command(separator = "=") class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--count", "-c"}) int count;
-            @Option(names = {"--help", "-h"}, hidden = true) boolean helpRequested;
-            @Parameters(paramLabel = "FILE", arity = "1..*") File[] files;
-        }
-        Help help = new Help(new App(), Help.Ansi.ON);
-        assertEquals(Help.Ansi.ON.new Text("@|bold <main class>|@ [@|yellow -v|@] [@|yellow -c|@=@|italic <count>|@] @|yellow FILE|@..." + LINESEP),
-                help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_clustersBooleanOptions() {
-        @Command(separator = "=") class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--aaaa", "-a"}) boolean aBoolean;
-            @Option(names = {"--xxxx", "-x"}) Boolean xBoolean;
-            @Option(names = {"--count", "-c"}, paramLabel = "COUNT") int count;
-        }
-        Help help = new Help(new App(), Help.Ansi.OFF);
-        assertEquals("<main class> [-avx] [-c=COUNT]" + LINESEP, help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_clustersRequiredBooleanOptions() {
-        @CommandLine.Command(separator = "=") class App {
-            @Option(names = {"--verbose", "-v"}, required = true) boolean verbose;
-            @Option(names = {"--aaaa", "-a"}, required = true) boolean aBoolean;
-            @Option(names = {"--xxxx", "-x"}, required = true) Boolean xBoolean;
-            @Option(names = {"--count", "-c"}, paramLabel = "COUNT") int count;
-        }
-        Help help = new Help(new App(), Help.Ansi.OFF);
-        assertEquals("<main class> -avx [-c=COUNT]" + LINESEP, help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_clustersRequiredBooleanOptionsSeparately() {
-        @CommandLine.Command(separator = "=") class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--aaaa", "-a"}) boolean aBoolean;
-            @Option(names = {"--xxxx", "-x"}) Boolean xBoolean;
-            @Option(names = {"--Verbose", "-V"}, required = true) boolean requiredVerbose;
-            @Option(names = {"--Aaaa", "-A"}, required = true) boolean requiredABoolean;
-            @Option(names = {"--Xxxx", "-X"}, required = true) Boolean requiredXBoolean;
-            @Option(names = {"--count", "-c"}, paramLabel = "COUNT") int count;
-        }
-        Help help = new Help(new App(), Help.Ansi.OFF);
-        assertEquals("<main class> -AVX [-avx] [-c=COUNT]" + LINESEP, help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_clustersRequiredBooleanOptionsSeparately_ANSI() {
-        @CommandLine.Command(separator = "=") class App {
-            @Option(names = {"--verbose", "-v"}) boolean verbose;
-            @Option(names = {"--aaaa", "-a"}) boolean aBoolean;
-            @Option(names = {"--xxxx", "-x"}) Boolean xBoolean;
-            @Option(names = {"--Verbose", "-V"}, required = true) boolean requiredVerbose;
-            @Option(names = {"--Aaaa", "-A"}, required = true) boolean requiredABoolean;
-            @Option(names = {"--Xxxx", "-X"}, required = true) Boolean requiredXBoolean;
-            @Option(names = {"--count", "-c"}, paramLabel = "COUNT") int count;
-        }
-        Help help = new Help(new App(), Help.defaultColorScheme(Help.Ansi.ON));
-        assertEquals(Help.Ansi.ON.new Text("@|bold <main class>|@ @|yellow -AVX|@ [@|yellow -avx|@] [@|yellow -c|@=@|italic COUNT|@]" + LINESEP),
-                help.synopsis(0));
-    }
-
-    @Test
-    public void testSynopsis_firstLineLengthAdjustedForSynopsisHeading() throws Exception {
-        //Usage: small-test-program [-acorv!?] [--version] [-h <number>] [-p <file>|<folder>] [-d
-//                 <folder> [<folder>]] [-i <includePattern>
-//                 [<includePattern>...]]
-        @CommandLine.Command(name="small-test-program", sortOptions = false, separator = " ")
-        class App {
-            @Option(names = "-a") boolean a;
-            @Option(names = "-c") boolean c;
-            @Option(names = "-o") boolean o;
-            @Option(names = "-r") boolean r;
-            @Option(names = "-v") boolean v;
-            @Option(names = "-!") boolean exclamation;
-            @Option(names = "-?") boolean question;
-            @Option(names = {"--version"}) boolean version;
-            @Option(names = {"--handle", "-h"}) int number;
-            @Option(names = {"--ppp", "-p"}, paramLabel = "<file>|<folder>") File f;
-            @Option(names = {"--ddd", "-d"}, paramLabel = "<folder>", arity="1..2") File[] d;
-            @Option(names = {"--include", "-i"}, paramLabel = "<includePattern>") String pattern;
-        }
-        Help help = new Help(new App(), Help.Ansi.OFF);
-        String expected = "" +
-                "Usage: small-test-program [-!?acorv] [--version] [-h <number>] [-i" + LINESEP +
-                "                          <includePattern>] [-p <file>|<folder>] [-d <folder>" + LINESEP +
-                "                          [<folder>]]..." + LINESEP;
-        assertEquals(expected, help.synopsisHeading() + help.synopsis(help.synopsisHeadingLength()));
-
-        help.synopsisHeading = "Usage:%n";
-        expected = "" +
-                "Usage:" + LINESEP +
-                "small-test-program [-!?acorv] [--version] [-h <number>] [-i <includePattern>]" + LINESEP +
-                "                   [-p <file>|<folder>] [-d <folder> [<folder>]]..." + LINESEP;
-        assertEquals(expected, help.synopsisHeading() + help.synopsis(help.synopsisHeadingLength()));
-    }
-
-    @Test
-    public void testLongMultiLineSynopsisIndented() {
-        @Command(name = "<best-app-ever>")
-        class App {
-            @Option(names = "--long-option-name", paramLabel = "<long-option-value>") int a;
-            @Option(names = "--another-long-option-name", paramLabel = "<another-long-option-value>") int b;
-            @Option(names = "--third-long-option-name", paramLabel = "<third-long-option-value>") int c;
-            @Option(names = "--fourth-long-option-name", paramLabel = "<fourth-long-option-value>") int d;
-        }
-        Help help = new Help(new App(), Help.Ansi.OFF);
-        assertEquals(String.format(
-                "<best-app-ever> [--another-long-option-name=<another-long-option-value>]%n" +
-                "                [--fourth-long-option-name=<fourth-long-option-value>]%n" +
-                "                [--long-option-name=<long-option-value>]%n" +
-                "                [--third-long-option-name=<third-long-option-value>]%n"),
-                help.synopsis(0));
-    }
-
-    @Test
-    public void testLongMultiLineSynopsisWithAtMarkIndented() {
-        @Command(name = "<best-app-ever>")
-        class App {
-            @Option(names = "--long-option@-name", paramLabel = "<lo...@e>") int a;
-            @Option(names = "--another-long-option-name", paramLabel = "^[<another-long-option-value>]") int b;
-            @Option(names = "--third-long-option-name", paramLabel = "<third-long-option-value>") int c;
-            @Option(names = "--fourth-long-option-name", paramLabel = "<fourth-long-option-value>") int d;
-        }
-        Help help = new Help(new App(), Help.Ansi.OFF);
-        assertEquals(String.format(
-                "<best-app-ever> [--another-long-option-name=^[<another-long-option-value>]]%n" +
-                "                [--fourth-long-option-name=<fourth-long-option-value>]%n" +
-                "                [--long-option@-name=<lo...@e>]%n" +
-                "                [--third-long-option-name=<third-long-option-value>]%n"),
-                help.synopsis(0));
-    }
-
-    @Test
-    public void testLongMultiLineSynopsisWithAtMarkIndented_ANSI() {
-        @Command(name = "<best-app-ever>")
-        class App {
-            @Option(names = "--long-option@-name", paramLabel = "<lo...@e>") int a;
-            @Option(names = "--another-long-option-name", paramLabel = "^[<another-long-option-value>]") int b;
-            @Option(names = "--third-long-option-name", paramLabel = "<third-long-option-value>") int c;
-            @Option(names = "--fourth-long-option-name", paramLabel = "<fourth-long-option-value>") int d;
-        }
-        Help help = new Help(new App(), Help.defaultColorScheme(Help.Ansi.ON));
-        assertEquals(Help.Ansi.ON.new Text(String.format(
-                "@|bold <best-app-ever>|@ [@|yellow --another-long-option-name|@=@|italic ^[<another-long-option-value>]|@]%n" +
-                        "                [@|yellow --fourth-long-option-name|@=@|italic <fourth-long-option-value>|@]%n" +
-                        "                [@|yellow --long-option@-name|@=@|italic <lo...@e>|@]%n" +
-                        "                [@|yellow --third-long-option-name|@=@|italic <third-long-option-value>|@]%n")),
-                help.synopsis(0));
-    }
-
-    @Test
-    public void testCustomSynopsis() {
-        @Command(customSynopsis = {
-                "<the-app> --number=NUMBER --other-option=<aargh>",
-                "          --more=OTHER --and-other-option=<aargh>",
-                "<the-app> --number=NUMBER --and-other-option=<aargh>",
-        })
-        class App {@Option(names = "--ignored") boolean ignored;}
-        Help help = new Help(new App(), Help.Ansi.OFF);
-        assertEquals(String.format(
-                "<the-app> --number=NUMBER --other-option=<aargh>%n" +
-                "          --more=OTHER --and-other-option=<aargh>%n" +
-                "<the-app> --number=NUMBER --and-other-option=<aargh>%n"),
-                help.synopsis(0));
-    }
-    @Test
-    public void testTextTable() {
-        TextTable table = new TextTable(Help.Ansi.OFF);
-        table.addRowValues(textArray(Help.Ansi.OFF, "", "-v", ",", "--verbose", "show what you're doing while you are doing it"));
-        table.addRowValues(textArray(Help.Ansi.OFF, "", "-p", null, null, "the quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog."));
-        assertEquals(String.format(
-                "  -v, --verbose               show what you're doing while you are doing it%n" +
-                "  -p                          the quick brown fox jumped over the lazy dog. The%n" +
-                "                                quick brown fox jumped over the lazy dog.%n"
-                ,""), table.toString(new StringBuilder()).toString());
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testTextTableAddsNewRowWhenTooManyValuesSpecified() {
-        TextTable table = new TextTable(Help.Ansi.OFF);
-        table.addRowValues(textArray(Help.Ansi.OFF, "", "-c", ",", "--create", "description", "INVALID", "Row 3"));
-//        assertEquals(String.format("" +
-//                        "  -c, --create                description                                       %n" +
-//                        "                                INVALID                                         %n" +
-//                        "                                Row 3                                           %n"
-//                ,""), table.toString(new StringBuilder()).toString());
-    }
-
-    @Test
-    public void testTextTableAddsNewRowWhenAnyColumnTooLong() {
-        TextTable table = new TextTable(Help.Ansi.OFF);
-        table.addRowValues("*", "-c", ",",
-                "--create, --create2, --create3, --create4, --create5, --create6, --create7, --create8",
-                "description");
-        assertEquals(String.format("" +

<TRUNCATED>