001/*
002  Licensed to the Apache Software Foundation (ASF) under one or more
003  contributor license agreements.  See the NOTICE file distributed with
004  this work for additional information regarding copyright ownership.
005  The ASF licenses this file to You under the Apache License, Version 2.0
006  (the "License"); you may not use this file except in compliance with
007  the License.  You may obtain a copy of the License at
008
009      http://www.apache.org/licenses/LICENSE-2.0
010
011  Unless required by applicable law or agreed to in writing, software
012  distributed under the License is distributed on an "AS IS" BASIS,
013  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014  See the License for the specific language governing permissions and
015  limitations under the License.
016 */
017
018package org.apache.commons.cli;
019
020import java.io.Serializable;
021import java.util.ArrayList;
022import java.util.Iterator;
023import java.util.LinkedList;
024import java.util.List;
025import java.util.Objects;
026import java.util.Properties;
027import java.util.function.Consumer;
028import java.util.function.Supplier;
029
030/**
031 * Represents list of arguments parsed against a {@link Options} descriptor.
032 * <p>
033 * It allows querying of a boolean {@link #hasOption(String opt)}, in addition to retrieving the
034 * {@link #getOptionValue(String opt)} for options requiring arguments.
035 * </p>
036 * <p>
037 * Additionally, any left-over or unrecognized arguments, are available for further processing.
038 * </p>
039 */
040public class CommandLine implements Serializable {
041
042    /**
043     * A nested builder class to create {@code CommandLine} instance using descriptive methods.
044     *
045     * @since 1.4
046     */
047    public static final class Builder {
048
049        /**
050         * Prints an Option to {@link System#out}.
051         */
052        static final Consumer<Option> DEPRECATED_HANDLER = o -> System.out.println(o.toDeprecatedString());
053
054        /** The unrecognized options/arguments */
055        private final List<String> args = new LinkedList<>();
056
057        /** The processed options */
058        private final List<Option> options = new ArrayList<>();
059
060        /**
061         * Deprecated Option handler.
062         */
063        private Consumer<Option> deprecatedHandler = DEPRECATED_HANDLER;
064
065        /**
066         * Adds left-over unrecognized option/argument.
067         *
068         * @param arg the unrecognized option/argument.
069         *
070         * @return this Builder instance for method chaining.
071         */
072        public Builder addArg(final String arg) {
073            if (arg != null) {
074                args.add(arg);
075            }
076            return this;
077        }
078
079        /**
080         * Adds an option to the command line. The values of the option are stored.
081         *
082         * @param opt the processed option.
083         *
084         * @return this Builder instance for method chaining.
085         */
086        public Builder addOption(final Option opt) {
087            if (opt != null) {
088                options.add(opt);
089            }
090            return this;
091        }
092
093        /**
094         * Creates the new instance.
095         *
096         * @return the new instance.
097         */
098        public CommandLine build() {
099            return new CommandLine(args, options, deprecatedHandler);
100        }
101
102        /**
103         * Sets the deprecated option handler.
104         *
105         * @param deprecatedHandler the deprecated option handler.
106         * @return {@code this} instance.
107         * @since 1.7.0
108         */
109        public Builder setDeprecatedHandler(final Consumer<Option> deprecatedHandler) {
110            this.deprecatedHandler = deprecatedHandler;
111            return this;
112        }
113    }
114
115    /** The serial version UID. */
116    private static final long serialVersionUID = 1L;
117
118    /**
119     * Creates a new builder.
120     *
121     * @return a new builder.
122     * @since 1.7.0
123     */
124    public static Builder builder() {
125        return new Builder();
126    }
127
128    /** The unrecognized options/arguments */
129    private final List<String> args;
130
131    /** The processed options */
132    private final List<Option> options;
133
134    /**
135     * The deprecated option handler.
136     * <p>
137     * If you want to serialize this field, use a serialization proxy.
138     * </p>
139     */
140    private final transient Consumer<Option> deprecatedHandler;
141
142    /**
143     * Creates a command line.
144     */
145    protected CommandLine() {
146        this(new LinkedList<>(), new ArrayList<>(), Builder.DEPRECATED_HANDLER);
147    }
148
149    /**
150     * Creates a command line.
151     */
152    private CommandLine(final List<String> args, final List<Option> options, final Consumer<Option> deprecatedHandler) {
153        this.args = Objects.requireNonNull(args, "args");
154        this.options = Objects.requireNonNull(options, "options");
155        this.deprecatedHandler = deprecatedHandler;
156    }
157
158    /**
159     * Adds left-over unrecognized option/argument.
160     *
161     * @param arg the unrecognized option/argument.
162     */
163    protected void addArg(final String arg) {
164        if (arg != null) {
165            args.add(arg);
166        }
167    }
168
169    /**
170     * Adds an option to the command line. The values of the option are stored.
171     *
172     * @param opt the processed option.
173     */
174    protected void addOption(final Option opt) {
175        if (opt != null) {
176            options.add(opt);
177        }
178    }
179
180    private <T> T get(final Supplier<T> supplier) {
181        return supplier == null ? null : supplier.get();
182    }
183
184    /**
185     * Gets any left-over non-recognized options and arguments
186     *
187     * @return remaining items passed in but not parsed as a {@code List}.
188     */
189    public List<String> getArgList() {
190        return args;
191    }
192
193    /**
194     * Gets any left-over non-recognized options and arguments
195     *
196     * @return remaining items passed in but not parsed as an array.
197     */
198    public String[] getArgs() {
199        return args.toArray(Util.EMPTY_STRING_ARRAY);
200    }
201
202    /**
203     * Gets the {@code Object} type of this {@code Option}.
204     *
205     * @deprecated due to System.err message. Instead use getParsedOptionValue(char)
206     * @param opt the name of the option.
207     * @return the type of opt.
208     */
209    @Deprecated
210    public Object getOptionObject(final char opt) {
211        return getOptionObject(String.valueOf(opt));
212    }
213
214    /**
215     * Gets the {@code Object} type of this {@code Option}.
216     *
217     * @param opt the name of the option.
218     * @return the type of this {@code Option}.
219     * @deprecated due to System.err message. Instead use getParsedOptionValue(String)
220     */
221    @Deprecated
222    public Object getOptionObject(final String opt) {
223        try {
224            return getParsedOptionValue(opt);
225        } catch (final ParseException pe) {
226            System.err.println("Exception found converting " + opt + " to desired type: " + pe.getMessage());
227            return null;
228        }
229    }
230
231    /**
232     * Gets the map of values associated to the option. This is convenient for options specifying Java properties like
233     * <code>-Dparam1=value1
234     * -Dparam2=value2</code>. All odd numbered values are property keys
235     * and even numbered values are property values.  If there are an odd number of values
236     * the last value is assumed to be a boolean flag and the value is "true".
237     *
238     * @param option name of the option.
239     * @return The Properties mapped by the option, never {@code null} even if the option doesn't exists.
240     * @since 1.5.0
241     */
242    public Properties getOptionProperties(final Option option) {
243        final Properties props = new Properties();
244        for (final Option processedOption : options) {
245            if (processedOption.equals(option)) {
246                processPropertiesFromValues(props, processedOption.getValuesList());
247            }
248        }
249        return props;
250    }
251
252    /**
253     * Gets the map of values associated to the option. This is convenient for options specifying Java properties like
254     * <code>-Dparam1=value1
255     * -Dparam2=value2</code>. The first argument of the option is the key, and the 2nd argument is the value. If the option
256     * has only one argument ({@code -Dfoo}) it is considered as a boolean flag and the value is {@code "true"}.
257     *
258     * @param opt name of the option.
259     * @return The Properties mapped by the option, never {@code null} even if the option doesn't exists.
260     * @since 1.2
261     */
262    public Properties getOptionProperties(final String opt) {
263        final Properties props = new Properties();
264        for (final Option option : options) {
265            if (opt.equals(option.getOpt()) || opt.equals(option.getLongOpt())) {
266                processPropertiesFromValues(props, option.getValuesList());
267            }
268        }
269        return props;
270    }
271
272    /**
273     * Gets an array of the processed {@link Option}s.
274     *
275     * @return an array of the processed {@link Option}s.
276     */
277    public Option[] getOptions() {
278        return options.toArray(Option.EMPTY_ARRAY);
279    }
280
281    /**
282     * Gets the first argument, if any, of this option.
283     *
284     * @param opt the character name of the option.
285     * @return Value of the argument if option is set, and has an argument, otherwise null.
286     */
287    public String getOptionValue(final char opt) {
288        return getOptionValue(String.valueOf(opt));
289    }
290
291    /**
292     * Gets the argument, if any, of an option.
293     *
294     * @param opt character name of the option
295     * @param defaultValue is the default value to be returned if the option is not specified.
296     * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}.
297     */
298    public String getOptionValue(final char opt, final String defaultValue) {
299        return getOptionValue(String.valueOf(opt), () -> defaultValue);
300    }
301
302    /**
303     * Gets the argument, if any, of an option.
304     *
305     * @param opt character name of the option
306     * @param defaultValue is a supplier for the default value to be returned if the option is not specified.
307     * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}.
308     * @since 1.7.0
309     */
310    public String getOptionValue(final char opt, final Supplier<String> defaultValue) {
311        return getOptionValue(String.valueOf(opt), defaultValue);
312    }
313
314    /**
315     * Gets the first argument, if any, of this option.
316     *
317     * @param option the option.
318     * @return Value of the argument if option is set, and has an argument, otherwise null.
319     * @since 1.5.0
320     */
321    public String getOptionValue(final Option option) {
322        final String[] values = getOptionValues(option);
323        return values == null ? null : values[0];
324    }
325
326    /**
327     * Gets the first argument, if any, of an option.
328     *
329     * @param option the option.
330     * @param defaultValue is the default value to be returned if the option is not specified.
331     * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}.
332     * @since 1.5.0
333     */
334    public String getOptionValue(final Option option, final String defaultValue) {
335        return getOptionValue(option, () -> defaultValue);
336    }
337
338    /**
339     * Gets the first argument, if any, of an option.
340     *
341     * @param option the option.
342     * @param defaultValue is a supplier for the default value to be returned if the option is not specified.
343     * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}.
344     * @since 1.7.0
345     */
346    public String getOptionValue(final Option option, final Supplier<String> defaultValue) {
347        final String answer = getOptionValue(option);
348        return answer != null ? answer : get(defaultValue);
349    }
350
351    /**
352     * Gets the first argument, if any, of this option group.
353     *
354     * @param optionGroup the option group.
355     * @return Value of the argument if option group is selected, and has an argument, otherwise null.
356     * @since 1.9.0
357     */
358    public String getOptionValue(final OptionGroup optionGroup) {
359        final String[] values = getOptionValues(optionGroup);
360        return values == null ? null : values[0];
361    }
362
363    /**
364     * Gets the first argument, if any, of an option group.
365     *
366     * @param optionGroup the option group.
367     * @param defaultValue is the default value to be returned if the option group is not selected.
368     * @return Value of the argument if option group is selected, and has an argument, otherwise {@code defaultValue}.
369     * @since 1.9.0
370     */
371    public String getOptionValue(final OptionGroup optionGroup, final String defaultValue) {
372        return getOptionValue(optionGroup, () -> defaultValue);
373    }
374
375    /**
376     * Gets the first argument, if any, of an option group.
377     *
378     * @param optionGroup the option group..
379     * @param defaultValue is a supplier for the default value to be returned if the option group is not selected.
380     * @return Value of the argument if option group is selected, and has an argument, otherwise {@code defaultValue}.
381     * @since 1.9.0
382     */
383    public String getOptionValue(final OptionGroup optionGroup, final Supplier<String> defaultValue) {
384        final String answer = getOptionValue(optionGroup);
385        return answer != null ? answer : get(defaultValue);
386    }
387
388
389    /**
390     * Gets the first argument, if any, of this option.
391     *
392     * @param opt the name of the option.
393     * @return Value of the argument if option is set, and has an argument, otherwise null.
394     */
395    public String getOptionValue(final String opt) {
396        return getOptionValue(resolveOption(opt));
397    }
398
399    /**
400     * Gets the first argument, if any, of an option.
401     *
402     * @param opt name of the option.
403     * @param defaultValue is the default value to be returned if the option is not specified.
404     * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}.
405     */
406    public String getOptionValue(final String opt, final String defaultValue) {
407        return getOptionValue(resolveOption(opt), () -> defaultValue);
408    }
409
410    /**
411     * Gets the first argument, if any, of an option.
412     *
413     * @param opt name of the option.
414     * @param defaultValue is a supplier for the default value to be returned if the option is not specified.
415     * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}.
416     * @since 1.7.0
417     */
418    public String getOptionValue(final String opt, final Supplier<String> defaultValue) {
419        return getOptionValue(resolveOption(opt), defaultValue);
420    }
421
422
423    /**
424     * Gets the array of values, if any, of an option.
425     *
426     * @param opt character name of the option.
427     * @return Values of the argument if option is set, and has an argument, otherwise null.
428     */
429    public String[] getOptionValues(final char opt) {
430        return getOptionValues(String.valueOf(opt));
431    }
432
433    /**
434     * Gets the array of values, if any, of an option.
435     *
436     * @param option the option.
437     * @return Values of the argument if option is set, and has an argument, otherwise null.
438     * @since 1.5.0
439     */
440    public String[] getOptionValues(final Option option) {
441        if (option == null) {
442            return null;
443        }
444        final List<String> values = new ArrayList<>();
445        for (final Option processedOption : options) {
446            if (processedOption.equals(option)) {
447                if (option.isDeprecated()) {
448                    handleDeprecated(option);
449                }
450                values.addAll(processedOption.getValuesList());
451            }
452        }
453        return values.isEmpty() ? null : values.toArray(Util.EMPTY_STRING_ARRAY);
454    }
455
456    /**
457     * Gets the array of values, if any, of an option group.
458     *
459     * @param optionGroup the option group.
460     * @return Values of the argument if option group is selected, and has an argument, otherwise null.
461     * @since 1.9.0
462     */
463    public String[] getOptionValues(final OptionGroup optionGroup) {
464        if (optionGroup == null || !optionGroup.isSelected()) {
465            return null;
466        }
467        return getOptionValues(optionGroup.getSelected());
468    }
469
470    /**
471     * Gets the array of values, if any, of an option.
472     *
473     * @param opt string name of the option.
474     * @return Values of the argument if option is set, and has an argument, otherwise null.
475     */
476    public String[] getOptionValues(final String opt) {
477        return getOptionValues(resolveOption(opt));
478    }
479
480    /**
481     * Gets a version of this {@code Option} converted to a particular type.
482     *
483     * @param opt the name of the option.
484     * @param <T> The return type for the method.
485     * @return the value parsed into a particular object.
486     * @throws ParseException if there are problems turning the option value into the desired type
487     * @see PatternOptionBuilder
488     * @since 1.5.0
489     */
490    public <T> T getParsedOptionValue(final char opt) throws ParseException {
491        return getParsedOptionValue(String.valueOf(opt));
492    }
493
494    /**
495     * Gets a version of this {@code Option} converted to a particular type.
496     *
497     * @param opt the name of the option.
498     * @param defaultValue the default value to return if opt is not set.
499     * @param <T> The return type for the method.
500     * @return the value parsed into a particular object.
501     * @throws ParseException if there are problems turning the option value into the desired type
502     * @see PatternOptionBuilder
503     * @since 1.7.0
504     */
505    public <T> T getParsedOptionValue(final char opt, final Supplier<T> defaultValue) throws ParseException {
506        return getParsedOptionValue(String.valueOf(opt), defaultValue);
507    }
508
509    /**
510     * Gets a version of this {@code Option} converted to a particular type.
511     *
512     * @param opt the name of the option.
513     * @param defaultValue the default value to return if opt is not set.
514     * @param <T> The return type for the method.
515     * @return the value parsed into a particular object.
516     * @throws ParseException if there are problems turning the option value into the desired type
517     * @see PatternOptionBuilder
518     * @since 1.7.0
519     */
520    public <T> T getParsedOptionValue(final char opt, final T defaultValue) throws ParseException {
521        return getParsedOptionValue(String.valueOf(opt), defaultValue);
522    }
523
524    /**
525     * Gets a version of this {@code Option} converted to a particular type.
526     *
527     * @param option the option.
528     * @param <T> The return type for the method.
529     * @return the value parsed into a particular object.
530     * @throws ParseException if there are problems turning the option value into the desired type
531     * @see PatternOptionBuilder
532     * @since 1.5.0
533     */
534    public <T> T getParsedOptionValue(final Option option) throws ParseException {
535        return getParsedOptionValue(option, () -> null);
536    }
537
538    /**
539     * Gets a version of this {@code Option} converted to a particular type.
540     *
541     * @param option the option.
542     * @param defaultValue the default value to return if opt is not set.
543     * @param <T> The return type for the method.
544     * @return the value parsed into a particular object.
545     * @throws ParseException if there are problems turning the option value into the desired type
546     * @see PatternOptionBuilder
547     * @since 1.7.0
548     */
549    @SuppressWarnings("unchecked")
550    public <T> T getParsedOptionValue(final Option option, final Supplier<T> defaultValue) throws ParseException {
551        if (option == null) {
552            return get(defaultValue);
553        }
554        final String res = getOptionValue(option);
555        try {
556            if (res == null) {
557                return get(defaultValue);
558            }
559            return (T) option.getConverter().apply(res);
560        } catch (final Throwable e) {
561            throw ParseException.wrap(e);
562        }
563    }
564
565    /**
566     * Gets a version of this {@code Option} converted to a particular type.
567     *
568     * @param option the option.
569     * @param defaultValue the default value to return if opt is not set.
570     * @param <T> The return type for the method.
571     * @return the value parsed into a particular object.
572     * @throws ParseException if there are problems turning the option value into the desired type
573     * @see PatternOptionBuilder
574     * @since 1.7.0
575     */
576    public <T> T getParsedOptionValue(final Option option, final T defaultValue) throws ParseException {
577        return getParsedOptionValue(option, () -> defaultValue);
578    }
579
580    /**
581     * Gets a version of this {@code OptionGroup} converted to a particular type.
582     *
583     * @param optionGroup the option group.
584     * @param <T> The return type for the method.
585     * @return the value parsed into a particular object.
586     * @throws ParseException if there are problems turning the selected option value into the desired type
587     * @see PatternOptionBuilder
588     * @since 1.9.0
589     */
590    public <T> T getParsedOptionValue(final OptionGroup optionGroup) throws ParseException {
591        return getParsedOptionValue(optionGroup, () -> null);
592    }
593
594    /**
595     * Gets a version of this {@code OptionGroup} converted to a particular type.
596     *
597     * @param optionGroup the option group.
598     * @param defaultValue the default value to return if opt is not set.
599     * @param <T> The return type for the method.
600     * @return the value parsed into a particular object.
601     * @throws ParseException if there are problems turning the selected option value into the desired type
602     * @see PatternOptionBuilder
603     * @since 1.9.0
604     */
605    public <T> T getParsedOptionValue(final OptionGroup optionGroup, final Supplier<T> defaultValue) throws ParseException {
606        if (optionGroup == null || !optionGroup.isSelected()) {
607            return get(defaultValue);
608        }
609        return getParsedOptionValue(optionGroup.getSelected(), defaultValue);
610    }
611
612    /**
613     * Gets a version of this {@code OptionGroup} converted to a particular type.
614     *
615     * @param optionGroup the option group.
616     * @param defaultValue the default value to return if an option is not selected.
617     * @param <T> The return type for the method.
618     * @return the value parsed into a particular object.
619     * @throws ParseException if there are problems turning the option value into the desired type
620     * @see PatternOptionBuilder
621     * @since 1.9.0
622     */
623    public <T> T getParsedOptionValue(final OptionGroup optionGroup, final T defaultValue) throws ParseException {
624        return getParsedOptionValue(optionGroup, () -> defaultValue);
625    }
626
627    /**
628     * Gets a version of this {@code Option} converted to a particular type.
629     *
630     * @param opt the name of the option.
631     * @param <T> The return type for the method.
632     * @return the value parsed into a particular object.
633     * @throws ParseException if there are problems turning the option value into the desired type
634     * @see PatternOptionBuilder
635     * @since 1.2
636     */
637    public <T> T getParsedOptionValue(final String opt) throws ParseException {
638        return getParsedOptionValue(resolveOption(opt));
639    }
640
641    /**
642     * Gets a version of this {@code Option} converted to a particular type.
643     *
644     * @param opt the name of the option.
645     * @param defaultValue the default value to return if opt is not set.
646     * @param <T> The return type for the method.
647     * @return the value parsed into a particular object.
648     * @throws ParseException if there are problems turning the option value into the desired type
649     * @see PatternOptionBuilder
650     * @since 1.7.0
651     */
652    public <T> T getParsedOptionValue(final String opt, final Supplier<T> defaultValue) throws ParseException {
653        return getParsedOptionValue(resolveOption(opt), defaultValue);
654    }
655
656    /**
657     * Gets a version of this {@code Option} converted to a particular type.
658     *
659     * @param opt the name of the option.
660     * @param defaultValue the default value to return if opt is not set.
661     * @param <T> The return type for the method.
662     * @return the value parsed into a particular object.
663     * @throws ParseException if there are problems turning the option value into the desired type
664     * @see PatternOptionBuilder
665     * @since 1.7.0
666     */
667    public <T> T getParsedOptionValue(final String opt, final T defaultValue) throws ParseException {
668        return getParsedOptionValue(resolveOption(opt), defaultValue);
669    }
670
671    /**
672     * Handles deprecated options.
673     *
674     * @param option a deprecated option.
675     */
676    private void handleDeprecated(final Option option) {
677        if (deprecatedHandler != null) {
678            deprecatedHandler.accept(option);
679        }
680    }
681
682    /**
683     * jkeyes - commented out until it is implemented properly
684     * <p>
685     * Dump state, suitable for debugging.
686     * </p>
687     *
688     * @return Stringified form of this object.
689     */
690
691    /*
692     * public String toString() { StringBuilder buf = new StringBuilder();
693     *
694     * buf.append("[ CommandLine: [ options: "); buf.append(options.toString()); buf.append(" ] [ args: ");
695     * buf.append(args.toString()); buf.append(" ] ]");
696     *
697     * return buf.toString(); }
698     */
699
700    /**
701     * Tests to see if an option has been set.
702     *
703     * @param opt character name of the option.
704     * @return true if set, false if not.
705     */
706    public boolean hasOption(final char opt) {
707        return hasOption(String.valueOf(opt));
708    }
709
710    /**
711     * Tests to see if an option has been set.
712     *
713     * @param opt the option to check.
714     * @return true if set, false if not.
715     * @since 1.5.0
716     */
717    public boolean hasOption(final Option opt) {
718        final boolean result = options.contains(opt);
719        if (result && opt.isDeprecated()) {
720            handleDeprecated(opt);
721        }
722        return result;
723    }
724
725    /**
726     * Tests to see if an option has been set.
727     *
728     * @param optionGroup the option group to check.
729     * @return true if set, false if not.
730     * @since 1.9.0
731     */
732    public boolean hasOption(final OptionGroup optionGroup) {
733        if (optionGroup == null || !optionGroup.isSelected()) {
734            return false;
735        }
736        return hasOption(optionGroup.getSelected());
737    }
738
739    /**
740     * Tests to see if an option has been set.
741     *
742     * @param opt Short name of the option.
743     * @return true if set, false if not.
744     */
745    public boolean hasOption(final String opt) {
746        return hasOption(resolveOption(opt));
747    }
748
749    /**
750     * Returns an iterator over the Option members of CommandLine.
751     *
752     * @return an {@code Iterator} over the processed {@link Option} members of this {@link CommandLine}.
753     */
754    public Iterator<Option> iterator() {
755        return options.iterator();
756    }
757
758    /**
759     * Parses a list of values as properties.  All odd numbered values are property keys
760     * and even numbered values are property values.  If there are an odd number of values
761     * the last value is assumed to be a boolean with a value of "true".
762     * @param props the properties to update.
763     * @param values the list of values to parse.
764     */
765    private void processPropertiesFromValues(final Properties props, final List<String> values) {
766        for (int i = 0; i < values.size(); i += 2) {
767            if (i + 1 < values.size()) {
768                props.put(values.get(i), values.get(i + 1));
769            } else {
770                props.put(values.get(i), "true");
771            }
772        }
773    }
774
775    /**
776     * Retrieves the option object given the long or short option as a String
777     *
778     * @param opt short or long name of the option, may be null.
779     * @return Canonicalized option.
780     */
781    private Option resolveOption(final String opt) {
782        final String actual = Util.stripLeadingHyphens(opt);
783        if (actual != null) {
784            for (final Option option : options) {
785                if (actual.equals(option.getOpt()) || actual.equals(option.getLongOpt())) {
786                    return option;
787                }
788            }
789        }
790        return null;
791    }
792}