File: src/java/org/apache/commons/cli2/commandline/WriteableCommandLineImpl.java
Issue: deafult arguments only works if no arguments are submitted
When using multple arguments and defaults, the behaviour is counter-intuitive and will only pick up a default if no args are passed in.
For instance in the code below I have set up so 0, 1, or 2 args may bve accepted, with defaults 100 and 1000.
I expect it to behave as follows.
1. for 2 args, 1 and 2 the values should be 1 and 2. This works as expected.
2. for 0 args passed in the values should be 100 and 1000, picking up both of the defaults. This works as expected
3. for 1 arg passed in the values should be 1 and 1000, so the second argument picks up the second default value. The valuse become just 1, which is not as expected..
Currently, in the second case will only return 1 and ignore the defaults.
    public void testSingleOptionSingleArgument() throws Exception {
        String defaulValue1 = "100";
        String defaultValue2 = "1000";
        final DefaultOptionBuilder obuilder = new DefaultOptionBuilder();
        final ArgumentBuilder abuilder = new ArgumentBuilder();
        final GroupBuilder gbuilder = new GroupBuilder();
        DefaultOption bOption = obuilder.withShortName("b")
                .withLongName("b")
                .withArgument(abuilder.withName("b")
                        .withMinimum(0)
                        .withMaximum(2)
                        .withDefault(defaulValue1)
                        .withDefault(defaultValue2)
                        .create())
                .create();
        Group options = gbuilder
                .withName("options")
                .withOption(bOption)
                .create();
        Parser parser = new Parser();
        parser.setHelpTrigger("--help");
        parser.setGroup(options);
        String enteredValue1 = "1";
        String[] args = new String[]
{"-b", enteredValue1}
;
        CommandLine cl = parser.parse(args);
        CommandLine cmd = cl;
        assertNotNull(cmd);
        List b = cmd.getValues("-b");
        assertEquals("[" + enteredValue1 + "]", b + "");
    }

Buggy code:
public List getValues(final Option option,
                      List defaultValues) {
    // initialize the return list
    List valueList = (List) values.get(option);

    // grab the correct default values
    if ((valueList == null) || valueList.isEmpty()) {
        valueList = defaultValues;
    }

    // augment the list with the default values
    if ((valueList == null) || valueList.isEmpty()) {
        valueList = (List) this.defaultValues.get(option);
    }
            // if there are more default values as specified, add them to
            // the list.
                // copy the list first
    
    return valueList == null ? Collections.EMPTY_LIST : valueList;
}

Fixed code:
public List getValues(final Option option,
                      List defaultValues) {
    // initialize the return list
    List valueList = (List) values.get(option);

    // grab the correct default values
    if (defaultValues == null || defaultValues.isEmpty()) {
        defaultValues = (List) this.defaultValues.get(option);
    }

    // augment the list with the default values
    if (defaultValues != null && !defaultValues.isEmpty()) {
        if (valueList == null || valueList.isEmpty()) {
            valueList = defaultValues;
        } else {
            // if there are more default values as specified, add them to
            // the list.
            if (defaultValues.size() > valueList.size()) {
                // copy the list first
                valueList = new ArrayList(valueList);
                for (int i=valueList.size(); i<defaultValues.size(); i++) {
                    valueList.add(defaultValues.get(i));
                }
            }
        }
    }
    
    return valueList == null ? Collections.EMPTY_LIST : valueList;
}