<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 1.5.3">
<title>picocli - a mighty tiny command line interface</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<style>
/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
/* Remove comment around @import statement below when using as a custom stylesheet */
/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
audio,canvas,video{display:inline-block}
audio:not([controls]){display:none;height:0}
[hidden],template{display:none}
script{display:none!important}
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
body{margin:0}
a{background:transparent}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
abbr[title]{border-bottom:1px dotted}
b,strong{font-weight:bold}
dfn{font-style:italic}
hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}
input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
body{-webkit-font-smoothing:antialiased}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.center{margin-left:auto;margin-right:auto}
.spread{width:100%}
p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:none}
p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol,ul.no-bullet,ol.no-bullet{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
ul.square{list-style-type:square}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ul.no-bullet{list-style:none}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
abbr{text-transform:none}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
blockquote cite:before{content:"\2014 \0020"}
blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
table thead,table tfoot{background:#f7f8f7;font-weight:bold}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
body{tab-size:4}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}
.clearfix:after,.float-group:after{clear:both}
*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menu{color:rgba(0,0,0,.8)}
b.button:before,b.button:after{position:relative;top:-1px;font-weight:400}
b.button:before{content:"[";padding:0 3px 0 2px}
b.button:after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}
#header:after,#content:after,#footnotes:after,#footer:after{clear:both}
#content{margin-top:1.25em}
#content:before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}
#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span:before{content:"\00a0\2013\00a0"}
#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark:before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber:after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #efefed;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media only screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}
@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
.sect1{padding-bottom:.625em}
@media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}
.sect1+.sect1{border-top:1px solid #efefed}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0}
.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)}
table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}
.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}
.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}
@media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}
@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}
.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.listingblock>.content{position:relative}
.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}
.listingblock:hover code[data-lang]:before{display:block}
.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999}
.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}
table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}
table.pyhltable td.code{padding-left:.75em;padding-right:0}
pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}
pre.pygments .lineno{display:inline-block;margin-right:.25em}
table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right}
.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)}
.quoteblock .quoteblock blockquote{padding:0 0 0 .75em}
.quoteblock .quoteblock blockquote:before{display:none}
.verseblock{margin:0 1em 1.25em 1em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract{margin:0 0 1.25em 0;display:block}
.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}
.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}
table.tableblock{max-width:100%;border-collapse:separate}
table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all th.tableblock,table.grid-all td.tableblock{border-width:0 1px 1px 0}
table.grid-all tfoot>tr>th.tableblock,table.grid-all tfoot>tr>td.tableblock{border-width:1px 1px 0 0}
table.grid-cols th.tableblock,table.grid-cols td.tableblock{border-width:0 1px 0 0}
table.grid-all *>tr>.tableblock:last-child,table.grid-cols *>tr>.tableblock:last-child{border-right-width:0}
table.grid-rows th.tableblock,table.grid-rows td.tableblock{border-width:0 0 1px 0}
table.grid-all tbody>tr:last-child>th.tableblock,table.grid-all tbody>tr:last-child>td.tableblock,table.grid-all thead:last-child>tr>th.tableblock,table.grid-rows tbody>tr:last-child>th.tableblock,table.grid-rows tbody>tr:last-child>td.tableblock,table.grid-rows thead:last-child>tr>th.tableblock{border-bottom-width:0}
table.grid-rows tfoot>tr>th.tableblock,table.grid-rows tfoot>tr>td.tableblock{border-width:1px 0 0 0}
table.frame-all{border-width:1px}
table.frame-sides{border-width:0 1px}
table.frame-topbot{border-width:1px 0}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
td>div.verse{white-space:pre}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.unstyled,ol.unnumbered,ul.checklist,ul.none{list-style-type:none}
ul.unstyled,ol.unnumbered,ul.checklist{margin-left:.625em}
ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1em;font-size:.85em}
ul.checklist li>p:first-child>input[type="checkbox"]:first-child{width:1em;position:relative;top:1px}
ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}
ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}
ul.inline>li>*{display:block}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist>table tr>td:first-of-type{padding:0 .75em;line-height:1}
.colist>table tr>td:last-of-type{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
.imageblock.left,.imageblock[style*="float: left"]{margin:.25em .625em 1.25em 0}
.imageblock.right,.imageblock[style*="float: right"]{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
.gist .file-data>table td.line-data{width:99%}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background-color:#00fafa}
.black{color:#000}
.black-background{background-color:#000}
.blue{color:#0000bf}
.blue-background{background-color:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background-color:#fa00fa}
.gray{color:#606060}
.gray-background{background-color:#7d7d7d}
.green{color:#006000}
.green-background{background-color:#007d00}
.lime{color:#00bf00}
.lime-background{background-color:#00fa00}
.maroon{color:#600000}
.maroon-background{background-color:#7d0000}
.navy{color:#000060}
.navy-background{background-color:#00007d}
.olive{color:#606000}
.olive-background{background-color:#7d7d00}
.purple{color:#600060}
.purple-background{background-color:#7d007d}
.red{color:#bf0000}
.red-background{background-color:#fa0000}
.silver{color:#909090}
.silver-background{background-color:#bcbcbc}
.teal{color:#006060}
.teal-background{background-color:#007d7d}
.white{color:#bfbfbf}
.white-background{background-color:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background-color:#fafa00}
span.icon>.fa{cursor:default}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]:after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@media print{@page{margin:1.25cm .75cm}
*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]:after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important}
.sect1{padding-bottom:0!important}
.sect1+.sect1{border:0!important}
#header>h1:first-child{margin-top:1.25rem}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span:before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]:before{display:block}
#footer{background:none!important;padding:0 .9375em}
#footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.4.0/css/font-awesome.min.css">
<style>
/* Stylesheet for CodeRay to match GitHub theme | MIT License | http://foundation.zurb.com */
/*pre.CodeRay {background-color:#f7f7f8;}*/
.CodeRay .line-numbers{border-right:1px solid #d8d8d8;padding:0 0.5em 0 .25em}
.CodeRay span.line-numbers{display:inline-block;margin-right:.5em;color:rgba(0,0,0,.3)}
.CodeRay .line-numbers strong{color:rgba(0,0,0,.4)}
table.CodeRay{border-collapse:separate;border-spacing:0;margin-bottom:0;border:0;background:none}
table.CodeRay td{vertical-align: top;line-height:1.45}
table.CodeRay td.line-numbers{text-align:right}
table.CodeRay td.line-numbers>pre{padding:0;color:rgba(0,0,0,.3)}
table.CodeRay td.code{padding:0 0 0 .5em}
table.CodeRay td.code>pre{padding:0}
.CodeRay .debug{color:#fff !important;background:#000080 !important}
.CodeRay .annotation{color:#007}
.CodeRay .attribute-name{color:#000080}
.CodeRay .attribute-value{color:#700}
.CodeRay .binary{color:#509}
.CodeRay .comment{color:#998;font-style:italic}
.CodeRay .char{color:#04d}
.CodeRay .char .content{color:#04d}
.CodeRay .char .delimiter{color:#039}
.CodeRay .class{color:#458;font-weight:bold}
.CodeRay .complex{color:#a08}
.CodeRay .constant,.CodeRay .predefined-constant{color:#008080}
.CodeRay .color{color:#099}
.CodeRay .class-variable{color:#369}
.CodeRay .decorator{color:#b0b}
.CodeRay .definition{color:#099}
.CodeRay .delimiter{color:#000}
.CodeRay .doc{color:#970}
.CodeRay .doctype{color:#34b}
.CodeRay .doc-string{color:#d42}
.CodeRay .escape{color:#666}
.CodeRay .entity{color:#800}
.CodeRay .error{color:#808}
.CodeRay .exception{color:inherit}
.CodeRay .filename{color:#099}
.CodeRay .function{color:#900;font-weight:bold}
.CodeRay .global-variable{color:#008080}
.CodeRay .hex{color:#058}
.CodeRay .integer,.CodeRay .float{color:#099}
.CodeRay .include{color:#555}
.CodeRay .inline{color:#000}
.CodeRay .inline .inline{background:#ccc}
.CodeRay .inline .inline .inline{background:#bbb}
.CodeRay .inline .inline-delimiter{color:#d14}
.CodeRay .inline-delimiter{color:#d14}
.CodeRay .important{color:#555;font-weight:bold}
.CodeRay .interpreted{color:#b2b}
.CodeRay .instance-variable{color:#008080}
.CodeRay .label{color:#970}
.CodeRay .local-variable{color:#963}
.CodeRay .octal{color:#40e}
.CodeRay .predefined{color:#369}
.CodeRay .preprocessor{color:#579}
.CodeRay .pseudo-class{color:#555}
.CodeRay .directive{font-weight:bold}
.CodeRay .type{font-weight:bold}
.CodeRay .predefined-type{color:inherit}
.CodeRay .reserved,.CodeRay .keyword {color:#000;font-weight:bold}
.CodeRay .key{color:#808}
.CodeRay .key .delimiter{color:#606}
.CodeRay .key .char{color:#80f}
.CodeRay .value{color:#088}
.CodeRay .regexp .delimiter{color:#808}
.CodeRay .regexp .content{color:#808}
.CodeRay .regexp .modifier{color:#808}
.CodeRay .regexp .char{color:#d14}
.CodeRay .regexp .function{color:#404;font-weight:bold}
.CodeRay .string{color:#d20}
.CodeRay .string .string .string{background:#ffd0d0}
.CodeRay .string .content{color:#d14}
.CodeRay .string .char{color:#d14}
.CodeRay .string .delimiter{color:#d14}
.CodeRay .shell{color:#d14}
.CodeRay .shell .delimiter{color:#d14}
.CodeRay .symbol{color:#990073}
.CodeRay .symbol .content{color:#a60}
.CodeRay .symbol .delimiter{color:#630}
.CodeRay .tag{color:#008080}
.CodeRay .tag-special{color:#d70}
.CodeRay .variable{color:#036}
.CodeRay .insert{background:#afa}
.CodeRay .delete{background:#faa}
.CodeRay .change{color:#aaf;background:#007}
.CodeRay .head{color:#f8f;background:#505}
.CodeRay .insert .insert{color:#080}
.CodeRay .delete .delete{color:#800}
.CodeRay .change .change{color:#66f}
.CodeRay .head .head{color:#f4f}
</style>
</head>
<body class="article toc2 toc-left">
<div id="header">
<h1>picocli - a mighty tiny command line interface</h1>
<div class="details">
<span id="revnumber">version 2.3.0,</span>
<span id="revdate">2018-02-13</span>
</div>
<div id="toc" class="toc2">
<div id="toctitle">Features</div>
<ul class="sectlevel1">
<li><a href="#_introduction">1. Introduction</a></li>
<li><a href="#_options_and_parameters">2. Options and Parameters</a>
<ul class="sectlevel2">
<li><a href="#_options">2.1. Options</a></li>
<li><a href="#_short_options">2.2. Short Options</a></li>
<li><a href="#_positional_parameters">2.3. Positional Parameters</a></li>
<li><a href="#_mixing_options_and_positional_parameters">2.4. Mixing Options and Positional Parameters</a></li>
<li><a href="#_double_dash_code_code">2.5. Double dash (<code>--</code>)</a></li>
<li><a href="#AtFiles">2.6. @-files</a></li>
</ul>
</li>
<li><a href="#_strongly_typed_everything">3. Strongly Typed Everything</a>
<ul class="sectlevel2">
<li><a href="#_built_in_types">3.1. Built-in Types</a></li>
<li><a href="#_custom_type_converters">3.2. Custom Type Converters</a></li>
<li><a href="#_option_specific_type_converters">3.3. Option-specific Type Converters</a></li>
<li><a href="#_arrays_collections_maps">3.4. Arrays, Collections, Maps</a></li>
<li><a href="#_abstract_field_types">3.5. Abstract Field Types</a></li>
</ul>
</li>
<li><a href="#_multiple_values">4. Multiple Values</a>
<ul class="sectlevel2">
<li><a href="#_multiple_occurrences">4.1. Multiple Occurrences</a></li>
<li><a href="#_split_regex">4.2. Split Regex</a></li>
<li><a href="#_arity">4.3. Arity</a></li>
<li><a href="#_default_arity">4.4. Default Arity</a></li>
<li><a href="#_optional_values">4.5. Optional Values</a></li>
</ul>
</li>
<li><a href="#_required_arguments">5. Required Arguments</a>
<ul class="sectlevel2">
<li><a href="#_required_options">5.1. Required Options</a></li>
<li><a href="#_required_parameters">5.2. Required Parameters</a></li>
</ul>
</li>
<li><a href="#_strict_or_lenient_parsing">6. Strict or Lenient Parsing</a>
<ul class="sectlevel2">
<li><a href="#_too_many_values">6.1. Too Many Values</a></li>
<li><a href="#_stop_at_positional">6.2. Stop At Positional</a></li>
<li><a href="#_unmatched_input">6.3. Unmatched Input</a></li>
<li><a href="#_unknown_options">6.4. Unknown Options</a></li>
<li><a href="#_stop_at_unmatched">6.5. Stop At Unmatched</a></li>
</ul>
</li>
<li><a href="#_help_options">7. Help Options</a></li>
<li><a href="#_version_help">8. Version Help</a>
<ul class="sectlevel2">
<li><a href="#_static_version_information">8.1. Static Version Information</a></li>
<li><a href="#_dynamic_version_information">8.2. Dynamic Version Information</a></li>
</ul>
</li>
<li><a href="#_usage_help">9. Usage Help</a>
<ul class="sectlevel2">
<li><a href="#_compact_example">9.1. Compact Example</a></li>
<li><a href="#_command_name">9.2. Command Name</a></li>
<li><a href="#_parameter_labels">9.3. Parameter Labels</a></li>
<li><a href="#_unsorted_option_list">9.4. Unsorted Option List</a></li>
<li><a href="#_abbreviated_synopsis">9.5. Abbreviated Synopsis</a></li>
<li><a href="#_custom_synopsis">9.6. Custom Synopsis</a></li>
<li><a href="#_header_and_footer">9.7. Header and Footer</a></li>
<li><a href="#_section_headings">9.8. Section Headings</a></li>
<li><a href="#_expanded_example">9.9. Expanded Example</a></li>
<li><a href="#_option_parameter_separators">9.10. Option-Parameter Separators</a></li>
<li><a href="#_hidden_options_and_parameters">9.11. Hidden Options and Parameters</a></li>
<li><a href="#_show_default_values">9.12. Show Default Values</a></li>
<li><a href="#_required_option_marker">9.13. Required-Option Marker</a></li>
</ul>
</li>
<li><a href="#_ansi_colors_and_styles">10. ANSI Colors and Styles</a>
<ul class="sectlevel2">
<li><a href="#_colorized_example">10.1. Colorized Example</a></li>
<li><a href="#_usage_help_with_styles_and_colors">10.2. Usage Help with Styles and Colors</a></li>
<li><a href="#_more_colors">10.3. More Colors</a></li>
<li><a href="#_configuring_fixed_elements">10.4. Configuring Fixed Elements</a></li>
<li><a href="#_supported_platforms">10.5. Supported Platforms</a></li>
<li><a href="#_forcing_ansi_on_off">10.6. Forcing ANSI On/Off</a></li>
</ul>
</li>
<li><a href="#_usage_help_api">11. Usage Help API</a>
<ul class="sectlevel2">
<li><a href="#_reordering_sections">11.1. Reordering Sections</a></li>
<li><a href="#_custom_layout">11.2. Custom Layout</a></li>
</ul>
</li>
<li><a href="#_subcommands">12. Subcommands</a>
<ul class="sectlevel2">
<li><a href="#_registering_subcommands_programmatically">12.1. Registering Subcommands Programmatically</a></li>
<li><a href="#_registering_subcommands_declaratively">12.2. Registering Subcommands Declaratively</a></li>
<li><a href="#_parsing_subcommands">12.3. Parsing Subcommands</a></li>
<li><a href="#__code_parentcommand_code_annotation">12.4. <code>@ParentCommand</code> annotation</a></li>
<li><a href="#_usage_help_for_subcommands">12.5. Usage Help for Subcommands</a></li>
<li><a href="#_nested_sub_subcommands">12.6. Nested sub-subcommands</a></li>
</ul>
</li>
<li><a href="#_tips_tricks">13. Tips &amp; Tricks</a>
<ul class="sectlevel2">
<li><a href="#_less_boilerplate">13.1. Less Boilerplate</a></li>
<li><a href="#_convenience_methods_for_subcommands">13.2. Convenience Methods for Subcommands</a></li>
<li><a href="#_custom_factory">13.3. Custom Factory</a></li>
<li><a href="#_boolean_options_with_parameters">13.4. Boolean Options with Parameters</a></li>
<li><a href="#_hexadecimal_values">13.5. Hexadecimal Values</a></li>
<li><a href="#_option_parameter_separators_2">13.6. Option-Parameter Separators</a></li>
<li><a href="#_subclassing_for_reuse">13.7. Subclassing for Reuse</a></li>
<li><a href="#_best_practices_for_command_line_interfaces">13.8. Best Practices for Command Line Interfaces</a></li>
</ul>
</li>
<li><a href="#_tracing">14. Tracing</a></li>
<li><a href="#_tab_autocomplete">15. TAB Autocomplete</a></li>
<li><a href="#_picocli_in_other_languages">16. Picocli in Other Languages</a>
<ul class="sectlevel2">
<li><a href="#_groovy">16.1. Groovy</a></li>
<li><a href="#_kotlin">16.2. Kotlin</a></li>
<li><a href="#_scala">16.3. Scala</a></li>
</ul>
</li>
<li><a href="#_api_javadoc">17. API Javadoc</a></li>
<li><a href="#_github_project">18. GitHub Project</a></li>
<li><a href="#_issue_tracker">19. Issue Tracker</a></li>
<li><a href="#_license">20. License</a></li>
<li><a href="#_releases">21. Releases</a></li>
<li><a href="#_download">22. Download</a>
<ul class="sectlevel2">
<li><a href="#_gradle">22.1. Gradle</a></li>
<li><a href="#_maven">22.2. Maven</a></li>
<li><a href="#_scala_sbt">22.3. Scala SBT</a></li>
<li><a href="#_ivy">22.4. Ivy</a></li>
<li><a href="#_source">22.5. Source</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="imageblock" style="float: right">
<div class="content">
<a class="image" href="https://github.com/remkop/picocli"><img src="https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png" alt="Fork me on GitHub"></a>
</div>
</div>
<div class="quoteblock">
<blockquote>
Every main method deserves picocli!
</blockquote>
</div>
<div class="paragraph">
<p><span class="image"><img src="images/cli.jpg" alt="picocli the Mighty Tiny Command Line Interface"></span></p>
</div>
<div class="paragraph">
<p>The user manual for the latest release is at <a href="http://picocli.info" class="bare">http://picocli.info</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_introduction">1. Introduction</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Picocli is a one-file framework for creating Java command line applications with almost zero code.
Supports a variety of command line syntax styles including POSIX, GNU, MS-DOS and more.
Generates highly customizable usage help messages with <a href="#_ansi_colors_and_styles">ANSI colors and styles</a>.
Picocli-based applications can have <a href="autocomplete.html">command line TAB completion</a> showing available options, option parameters and subcommands, for any level of nested subcommands.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="images/ExampleUsageANSI.png" alt="Screenshot of usage help with Ansi codes enabled"></span></p>
</div>
<div class="paragraph">
<p><a href="autocomplete.html">Command line autocompletion</a> is in BETA. Comments, bug reports, pull requests welcome!</p>
</div>
<div class="paragraph">
<p>A distinguishing feature of picocli is how it aims
to let users run picocli-based applications without requiring picocli as an external dependency:
all the source code lives in a single file, to encourage application authors to include it <em>in source form</em>.</p>
</div>
<div class="paragraph">
<p>How it works: annotate your class and picocli initializes it from the command line arguments,
converting the input to strongly typed values in the fields of your class.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="keyword">import</span> <span class="include">picocli.CommandLine.Option</span>;
<span class="keyword">import</span> <span class="include">picocli.CommandLine.Parameters</span>;
<span class="keyword">import</span> <span class="include">java.io.File</span>;

<span class="directive">public</span> <span class="type">class</span> <span class="class">Example</span> {
    <span class="annotation">@Option</span>(names = { <span class="string"><span class="delimiter">&quot;</span><span class="content">-v</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--verbose</span><span class="delimiter">&quot;</span></span> }, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">Be verbose.</span><span class="delimiter">&quot;</span></span>)
    <span class="directive">private</span> <span class="type">boolean</span> verbose = <span class="predefined-constant">false</span>;

    <span class="annotation">@Parameters</span>(arity = <span class="string"><span class="delimiter">&quot;</span><span class="content">1..*</span><span class="delimiter">&quot;</span></span>, paramLabel = <span class="string"><span class="delimiter">&quot;</span><span class="content">FILE</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">File(s) to process.</span><span class="delimiter">&quot;</span></span>)
    <span class="directive">private</span> <span class="predefined-type">File</span><span class="type">[]</span> inputFiles;
    ...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then invoke <code>CommandLine.parse</code> or <code>CommandLine.populateCommand</code> with the command line parameters and an object you want to initialize.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">String</span><span class="type">[]</span> args = { <span class="string"><span class="delimiter">&quot;</span><span class="content">-v</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">inputFile1</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">inputFile2</span><span class="delimiter">&quot;</span></span> };
Example app = CommandLine.populateCommand(<span class="keyword">new</span> Example(), args);
<span class="keyword">assert</span>  app.verbose;
<span class="keyword">assert</span>  app.inputFiles != <span class="predefined-constant">null</span> &amp;&amp; app.inputFiles.length == <span class="integer">2</span>;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here is a small example application that uses the <code>CommandLine.call</code> <a href="#_less_boilerplate">convenience method</a>
to do parsing and error handling in one line of code.</p>
</div>
<div id="CheckSum-application" class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(name = <span class="string"><span class="delimiter">&quot;</span><span class="content">checksum</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">Prints the checksum (MD5 by default) of a file to STDOUT.</span><span class="delimiter">&quot;</span></span>)
<span class="type">class</span> <span class="class">CheckSum</span> <span class="directive">implements</span> <span class="predefined-type">Callable</span>&lt;<span class="predefined-type">Void</span>&gt; {

    <span class="annotation">@Parameters</span>(index = <span class="string"><span class="delimiter">&quot;</span><span class="content">0</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">The file whose checksum to calculate.</span><span class="delimiter">&quot;</span></span>)
    <span class="directive">private</span> <span class="predefined-type">File</span> file;

    <span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-a</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--algorithm</span><span class="delimiter">&quot;</span></span>}, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">MD5, SHA-1, SHA-256, ...</span><span class="delimiter">&quot;</span></span>)
    <span class="directive">private</span> <span class="predefined-type">String</span> algorithm = <span class="string"><span class="delimiter">&quot;</span><span class="content">MD5</span><span class="delimiter">&quot;</span></span>;

    <span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-h</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--help</span><span class="delimiter">&quot;</span></span>}, usageHelp = <span class="predefined-constant">true</span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">Show this help message and exit.</span><span class="delimiter">&quot;</span></span>)
    <span class="directive">private</span> <span class="type">boolean</span> helpRequested;

    <span class="directive">public</span> <span class="directive">static</span> <span class="type">void</span> main(<span class="predefined-type">String</span><span class="type">[]</span> args) <span class="directive">throws</span> <span class="exception">Exception</span> {
        <span class="comment">// CheckSum implements Callable, so parsing, error handling and handling user</span>
        <span class="comment">// requests for usage help or version help can be done with one line of code.</span>
        CommandLine.call(<span class="keyword">new</span> CheckSum(), <span class="predefined-type">System</span>.err, args);
    }

    <span class="annotation">@Override</span>
    <span class="directive">public</span> <span class="predefined-type">Void</span> call() <span class="directive">throws</span> <span class="exception">Exception</span> {
        <span class="comment">// your business logic goes here...</span>
        <span class="type">byte</span><span class="type">[]</span> fileContents = Files.readAllBytes(file.toPath());
        <span class="type">byte</span><span class="type">[]</span> digest = <span class="predefined-type">MessageDigest</span>.getInstance(algorithm).digest(fileContents);
        <span class="predefined-type">System</span>.out.println(javax.xml.bind.DatatypeConverter.printHexBinary(digest));
        <span class="keyword">return</span> <span class="predefined-constant">null</span>;
    }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_options_and_parameters">2. Options and Parameters</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Command line arguments can be separated into <em>options</em>  and <em>positional parameters</em>.
Options have a name, positional parameters are usually the values that follow the options,
but they may be mixed.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="images/OptionsAndParameters2.png" alt="Example command with annotated @Option and @Parameters"></span></p>
</div>
<div class="paragraph">
<p>Picocli has separate annotations for options and positional parameters.</p>
</div>
<div class="sect2">
<h3 id="_options">2.1. Options</h3>
<div class="paragraph">
<p>An option must have one or more <code>names</code>.
Picocli lets you use any option name you want.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
You may be interested in this <a href="http://catb.org/~esr/writings/taoup/html/ch10s05.html#id2948149">list of common option names</a>. Following these conventions may make your application more intuitive to use for experienced users.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>The below example shows options with one or more names, options that take an option parameter, and a <a href="#_help_options">help</a> option.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">Tar</span> {
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-c</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">create a new archive</span><span class="delimiter">&quot;</span></span>)
    <span class="type">boolean</span> create;

    <span class="annotation">@Option</span>(names = { <span class="string"><span class="delimiter">&quot;</span><span class="content">-f</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--file</span><span class="delimiter">&quot;</span></span> }, paramLabel = <span class="string"><span class="delimiter">&quot;</span><span class="content">ARCHIVE</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">the archive file</span><span class="delimiter">&quot;</span></span>)
    <span class="predefined-type">File</span> archive;

    <span class="annotation">@Parameters</span>(paramLabel = <span class="string"><span class="delimiter">&quot;</span><span class="content">FILE</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">one ore more files to archive</span><span class="delimiter">&quot;</span></span>)
    <span class="predefined-type">File</span><span class="type">[]</span> files;

    <span class="annotation">@Option</span>(names = { <span class="string"><span class="delimiter">&quot;</span><span class="content">-h</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--help</span><span class="delimiter">&quot;</span></span> }, usageHelp = <span class="predefined-constant">true</span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">display a help message</span><span class="delimiter">&quot;</span></span>)
    <span class="directive">private</span> <span class="type">boolean</span> helpRequested = <span class="predefined-constant">false</span>;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Picocli matches the option names to set the field values.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">String</span><span class="type">[]</span> args = { <span class="string"><span class="delimiter">&quot;</span><span class="content">-c</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--file</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">result.tar</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">file1.txt</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">file2.txt</span><span class="delimiter">&quot;</span></span> };
Tar tar = <span class="keyword">new</span> Tar();
<span class="keyword">new</span> CommandLine(tar).parse(args);

<span class="keyword">assert</span> !tar.helpRequested;
<span class="keyword">assert</span>  tar.create;
<span class="keyword">assert</span>  tar.archive.equals(<span class="keyword">new</span> <span class="predefined-type">File</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">result.tar</span><span class="delimiter">&quot;</span></span>));
<span class="keyword">assert</span>  <span class="predefined-type">Arrays</span>.equals(tar.files, <span class="keyword">new</span> <span class="predefined-type">File</span><span class="type">[]</span> {<span class="keyword">new</span> <span class="predefined-type">File</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">file1.txt</span><span class="delimiter">&quot;</span></span>), <span class="keyword">new</span> <span class="predefined-type">File</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">file2.txt</span><span class="delimiter">&quot;</span></span>)});</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_short_options">2.2. Short Options</h3>
<div class="paragraph">
<p>Picocli supports <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_02">POSIX clustered short options</a>:
one or more single-character options without option-arguments, followed by at most one option with an option-argument, can be grouped behind one '-' delimiter.</p>
</div>
<div class="paragraph">
<p>For example, given this annotated class:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">ClusteredShortOptions</span> {
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-a</span><span class="delimiter">&quot;</span></span>) <span class="type">boolean</span> aaa;
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-b</span><span class="delimiter">&quot;</span></span>) <span class="type">boolean</span> bbb;
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-c</span><span class="delimiter">&quot;</span></span>) <span class="type">boolean</span> ccc;
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-f</span><span class="delimiter">&quot;</span></span>) <span class="predefined-type">String</span>  file;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The following command line arguments are all equivalent and parsing them will give the same result:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">&lt;command&gt; -abcfInputFile.txt
&lt;command&gt; -abcf=InputFile.txt
&lt;command&gt; -abc -f=InputFile.txt
&lt;command&gt; -ab -cf=InputFile.txt
&lt;command&gt; -a -b -c -fInputFile.txt
&lt;command&gt; -a -b -c -f InputFile.txt
&lt;command&gt; -a -b -c -f=InputFile.txt
...</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_positional_parameters">2.3. Positional Parameters</h3>
<div class="paragraph">
<p>Any command line arguments that are not subcommands or options (or option parameters) are interpreted as positional parameters.
Positional parameters generally follow the options but from picocli v2.0, positional parameters can be mixed with options on the command line.</p>
</div>
<div class="paragraph">
<p>Use the (zero-based) <code>index</code> attribute to specify exactly which parameters to capture.
Omitting the <code>index</code> attribute means the field captures <em>all</em> positional parameters.
Array or collection fields can capture multiple values.</p>
</div>
<div class="paragraph">
<p>The <code>index</code> attribute accepts <em>range</em> values, so an annotation like <code>@Parameters(index="2..4")</code> captures the arguments at index 2, 3 and 4. Range values can be <em>open-ended</em>. For example, <code>@Parameters(index="3..*")</code> captures all arguments from index 3 and up.</p>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">PositionalParameters</span> {
    <span class="annotation">@Parameters</span>(hidden = <span class="predefined-constant">true</span>)  <span class="comment">// &quot;hidden&quot;: don't show this parameter in usage help message</span>
    <span class="predefined-type">List</span>&lt;<span class="predefined-type">String</span>&gt; allParameters; <span class="comment">// no &quot;index&quot; attribute: captures _all_ arguments (as Strings)</span>

    <span class="annotation">@Parameters</span>(index = <span class="string"><span class="delimiter">&quot;</span><span class="content">0</span><span class="delimiter">&quot;</span></span>)    <span class="predefined-type">InetAddress</span> host;
    <span class="annotation">@Parameters</span>(index = <span class="string"><span class="delimiter">&quot;</span><span class="content">1</span><span class="delimiter">&quot;</span></span>)    <span class="type">int</span> port;
    <span class="annotation">@Parameters</span>(index = <span class="string"><span class="delimiter">&quot;</span><span class="content">2..*</span><span class="delimiter">&quot;</span></span>) <span class="predefined-type">File</span><span class="type">[]</span> files;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Picocli initializes fields with the values at the specified index in the arguments array.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">String</span><span class="type">[]</span> args = { <span class="string"><span class="delimiter">&quot;</span><span class="content">localhost</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">12345</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">file1.txt</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">file2.txt</span><span class="delimiter">&quot;</span></span> };
PositionalParameters params = CommandLine.populateCommand(<span class="keyword">new</span> PositionalParameters(), args);

<span class="keyword">assert</span> params.host.getHostName().equals(<span class="string"><span class="delimiter">&quot;</span><span class="content">localhost</span><span class="delimiter">&quot;</span></span>);
<span class="keyword">assert</span> params.port == <span class="integer">12345</span>;
<span class="keyword">assert</span> <span class="predefined-type">Arrays</span>.equals(params.files, <span class="keyword">new</span> <span class="predefined-type">File</span><span class="type">[]</span> {<span class="keyword">new</span> <span class="predefined-type">File</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">file1.txt</span><span class="delimiter">&quot;</span></span>), <span class="keyword">new</span> <span class="predefined-type">File</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">file2.txt</span><span class="delimiter">&quot;</span></span>)});
<span class="keyword">assert</span> params.allParameters.equals(<span class="predefined-type">Arrays</span>.asList(<span class="string"><span class="delimiter">&quot;</span><span class="content">localhost</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">12345</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">file1.txt</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">file2.txt</span><span class="delimiter">&quot;</span></span>));</code></pre>
</div>
</div>
<div class="paragraph">
<p>See <a href="#_strongly_typed_everything">Strongly Typed Everything</a> for which types are supported out of the box and how to add custom types.</p>
</div>
</div>
<div class="sect2">
<h3 id="_mixing_options_and_positional_parameters">2.4. Mixing Options and Positional Parameters</h3>
<div class="paragraph">
<p>From picocli v2.0, positional parameters can be mixed with options on the command line.</p>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">Mixed</span> {
    <span class="annotation">@Parameters</span>
    <span class="predefined-type">List</span>&lt;<span class="predefined-type">String</span>&gt; positional;

    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-o</span><span class="delimiter">&quot;</span></span>)
    <span class="predefined-type">List</span>&lt;<span class="predefined-type">String</span>&gt; options;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Any command line argument that is not an option or subcommand is interpreted as a positional parameter.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">String</span><span class="type">[]</span> args = { <span class="string"><span class="delimiter">&quot;</span><span class="content">param0</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">-o</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">AAA</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">param1</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">param2</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">-o</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">BBB</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">param3</span><span class="delimiter">&quot;</span></span> };
Mixed mixed = <span class="keyword">new</span> Mixed();
<span class="keyword">new</span> CommandLine(mixed).parse(args);

<span class="keyword">assert</span> mixed.positional.equals(<span class="predefined-type">Arrays</span>.asList(<span class="string"><span class="delimiter">&quot;</span><span class="content">param0</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">param1</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">param2</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">param3</span><span class="delimiter">&quot;</span></span>);
<span class="keyword">assert</span> mixed.options.equals   (<span class="predefined-type">Arrays</span>.asList(<span class="string"><span class="delimiter">&quot;</span><span class="content">AAA</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">BBB</span><span class="delimiter">&quot;</span></span>));</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_double_dash_code_code">2.5. Double dash (<code>--</code>)</h3>
<div class="paragraph">
<p>When one of the command line arguments is just two dashes without any characters attached (<code>--</code>),
picocli interprets all following arguments as positional parameters, even arguments that match an option name.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">DoubleDashDemo</span> {
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-v</span><span class="delimiter">&quot;</span></span>)     <span class="type">boolean</span> verbose;
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-files</span><span class="delimiter">&quot;</span></span>) <span class="predefined-type">List</span>&lt;<span class="predefined-type">String</span>&gt; files;
    <span class="annotation">@Parameters</span>               <span class="predefined-type">List</span>&lt;<span class="predefined-type">String</span>&gt; params;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>--</code> end-of-options delimiter clarifies which of the arguments are positional parameters:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">String</span><span class="type">[]</span> args = { <span class="string"><span class="delimiter">&quot;</span><span class="content">-v</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">-files</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">file1</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">file2</span><span class="delimiter">&quot;</span></span> };
DoubleDashDemo demo = <span class="keyword">new</span> DoubleDashDemo();
<span class="keyword">new</span> CommandLine(demo).parse(args);

<span class="keyword">assert</span> demo.verbose;
<span class="keyword">assert</span> demo.files == <span class="predefined-constant">null</span>;
<span class="keyword">assert</span> demo.params.equals(<span class="predefined-type">Arrays</span>.asList(<span class="string"><span class="delimiter">&quot;</span><span class="content">-files</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">file1</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">file2</span><span class="delimiter">&quot;</span></span>));</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="AtFiles">2.6. @-files</h3>
<div class="paragraph">
<p>Users sometimes run into system limitations on the length of a command line when creating a
command line with lots of options or with long arguments for options.</p>
</div>
<div class="paragraph">
<p>Starting from v2.1.0, picocli supports "argument files" or "@-files".
Argument files are files that themselves contain arguments to the command.
When picocli encounters an argument beginning with the character `@',
it expands the contents of that file into the argument list.</p>
</div>
<div class="paragraph">
<p>An argument file can include options and positional parameters in any combination.
The arguments within a file can be space-separated or newline-separated.
If an argument contains embedded whitespace, put the whole argument in double or single quotes
(<code>"-f=My Files\Stuff.java"</code>).</p>
</div>
<div class="paragraph">
<p>Lines starting with <code>#</code> are comments and are ignored.
The file may itself contain additional @-file arguments; any such arguments will be processed recursively.</p>
</div>
<div class="paragraph">
<p>If the file does not exist, or cannot be read, then the argument will be treated literally, and not removed.
Multiple @-files may be specified on the command line. The specified path may be relative (to the current directory) or absolute.</p>
</div>
<div class="paragraph">
<p>For example, suppose a file with arguments exists at <code>/home/foo/args</code>, with these contents:</p>
</div>
<div class="listingblock">
<div class="content">
<pre># This line is a comment and is ignored.
ABC -option=123
'X Y Z'</pre>
</div>
</div>
<div class="paragraph">
<p>A command may be invoked with the @file argument, like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">java MyCommand @/home/foo/args</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above will be expanded to the contents of the file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">java MyCommand ABC -option=123 &quot;X Y Z&quot;</code></pre>
</div>
</div>
<div class="paragraph">
<p>@-file expansion can be switched off by calling <code>CommandLine::setExpandAtFiles</code> with <code>false</code>.
If turned on, you can still pass a real parameter with an initial '@' character by escaping it
with an additional '@' symbol, e.g. '@@somearg' will become '@somearg' and not be subject to expansion.</p>
</div>
<div class="paragraph">
<p>This feature is similar to the 'Command Line Argument File' processing supported by gcc, javadoc and javac.
The documentation for these tools shows further examples.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_strongly_typed_everything">3. Strongly Typed Everything</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When command line options and positional parameters are mapped to the annotated fields,
the text value is converted to the type of the annotated field.</p>
</div>
<div class="sect2">
<h3 id="_built_in_types">3.1. Built-in Types</h3>
<div class="paragraph">
<p>Out of the box, picocli can convert command line argument strings to a number of common data types.</p>
</div>
<div class="paragraph">
<p>Most of the built-in types work with Java 5, but picocli also has some default converters for Java 7 types like <code>Path</code> and Java 8 types like <code>Duration</code>, etc. These converters are only available when running on a Java version that supports them. See the below list for details.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>any Java primitive type or their wrapper</p>
</li>
<li>
<p>any <code>enum</code></p>
</li>
<li>
<p><code>String</code>, <code>StringBuilder</code>, <code>CharSequence</code></p>
</li>
<li>
<p><code>java.math.BigDecimal</code>, <code>java.math.BigInteger</code></p>
</li>
<li>
<p><code>java.nio.Charset</code></p>
</li>
<li>
<p><code>java.io.File</code></p>
</li>
<li>
<p><code>java.nio.file.Path</code> (from picocli 2.2, requires Java 7 or higher)</p>
</li>
<li>
<p><code>java.net.InetAddress</code></p>
</li>
<li>
<p><code>java.util.regex.Pattern</code></p>
</li>
<li>
<p><code>java.util.Date</code> (for values in <code>"yyyy-MM-dd"</code> format)</p>
</li>
<li>
<p><code>java.sql.Time</code> (for values in any of the <code>"HH:mm"</code>, <code>"HH:mm:ss"</code>, <code>"HH:mm:ss.SSS"</code>, or <code>"HH:mm:ss,SSS"</code> formats)</p>
</li>
<li>
<p><code>java.sql.Timestamp</code> (from picocli 2.2, for values in the <code>"yyyy-MM-dd HH:mm:ss"</code> or <code>"yyyy-MM-dd HH:mm:ss.fffffffff"</code> formats)</p>
</li>
<li>
<p><code>java.net.URL</code>, <code>java.net.URI</code></p>
</li>
<li>
<p><code>java.util.UUID</code></p>
</li>
<li>
<p><code>java.time</code> value objects: <code>Duration</code>, <code>Instant</code>, <code>LocalDate</code>, <code>LocalDateTime</code>, <code>LocalTime</code>, <code>MonthDay</code>, <code>OffsetDateTime</code>, <code>OffsetTime</code>, <code>Period</code>, <code>Year</code>, <code>YearMonth</code>, <code>ZonedDateTime</code>, <code>ZoneId</code>, <code>ZoneOffset</code>  (from picocli 2.2, requires Java 8 or higher, invokes the <code>parse</code> method of these classes)</p>
</li>
<li>
<p><code>java.lang.Class</code> (from picocli 2.2, for the fully qualified class name)</p>
</li>
<li>
<p><code>java.nio.ByteOrder</code> (from picocli 2.2, for the Strings <code>"BIG_ENDIAN"</code> or <code>"LITTLE_ENDIAN"</code>)</p>
</li>
<li>
<p><code>java.util.Currency</code> (from picocli 2.2, for the ISO 4217 code of the currency)</p>
</li>
<li>
<p><code>java.net.NetworkInterface</code> (from picocli 2.2, for the InetAddress or name of the network interface)</p>
</li>
<li>
<p><code>java.util.TimeZoneConverter</code> (from picocli 2.2, for the ID for a TimeZone)</p>
</li>
<li>
<p><code>java.sql.Connection</code> (from picocli 2.2, for a database url of the form <code>jdbc:subprotocol:subname</code>)</p>
</li>
<li>
<p><code>java.sql.Driver</code> (from picocli 2.2, for a database URL of the form <code>jdbc:subprotocol:subname</code>)</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_custom_type_converters">3.2. Custom Type Converters</h3>
<div class="paragraph">
<p>Register a custom type converter to handle data types other than the above built-in ones.</p>
</div>
<div class="paragraph">
<p>Custom converters need to implement the <code>picocli.CommandLine.ITypeConverter</code> interface:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">interface</span> <span class="class">ITypeConverter</span>&lt;K&gt; {
    <span class="comment">/**
     * Converts the specified command line argument value to some domain object.
     * @param value the command line argument String value
     * @return the resulting domain object
     * @throws Exception an exception detailing what went wrong during the conversion
     */</span>
    K convert(<span class="predefined-type">String</span> value) <span class="directive">throws</span> <span class="exception">Exception</span>;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Custom type converters can be registered with the <code>CommandLine.registerConverter(Class&lt;K&gt; cls, ITypeConverter&lt;K&gt; converter)</code> method. All options and positional parameters with the specified type will be converted by the specified converter.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Java 8 lambdas make it easy to register custom converters:
</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">CommandLine cl = <span class="keyword">new</span> CommandLine(app)
cl.registerConverter(<span class="predefined-type">Locale</span>.class, s -&gt; <span class="keyword">new</span> <span class="predefined-type">Locale</span>.Builder().setLanguageTag(s).build());
cl.registerConverter(<span class="predefined-type">Cipher</span>.class, s -&gt; <span class="predefined-type">Cipher</span>.getInstance(s));</code></pre>
</div>
</div>
<div class="paragraph">
<p>After registering custom converters, call the <code>parse(String&#8230;&#8203;)</code> method on the <code>CommandLine</code> instance where the converters are registered. (The static <code>populateCommand</code> method cannot be used.) For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">App</span> {
    <span class="annotation">@Parameters</span> java.util.Locale locale;
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-a</span><span class="delimiter">&quot;</span></span>) javax.crypto.Cipher cipher;
}</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">App app = <span class="keyword">new</span> App();
CommandLine commandLine = <span class="keyword">new</span> CommandLine(app)
    .registerConverter(<span class="predefined-type">Locale</span>.class, s -&gt; <span class="keyword">new</span> <span class="predefined-type">Locale</span>.Builder().setLanguageTag(s).build())
    .registerConverter(<span class="predefined-type">Cipher</span>.class, s -&gt; <span class="predefined-type">Cipher</span>.getInstance(s));

commandLine.parse(<span class="string"><span class="delimiter">&quot;</span><span class="content">-a</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">AES/CBC/NoPadding</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">en-GB</span><span class="delimiter">&quot;</span></span>);
<span class="keyword">assert</span> app.locale.toLanguageTag().equals(<span class="string"><span class="delimiter">&quot;</span><span class="content">en-GB</span><span class="delimiter">&quot;</span></span>);
<span class="keyword">assert</span> app.cipher.getAlgorithm().equals(<span class="string"><span class="delimiter">&quot;</span><span class="content">AES/CBC/NoPadding</span><span class="delimiter">&quot;</span></span>));</code></pre>
</div>
</div>
<div class="admonitionblock caution">
<table>
<tr>
<td class="icon">
<i class="fa icon-caution" title="Caution"></i>
</td>
<td class="content">
<em>Note on subcommands:</em> the specified converter will be registered with the <code>CommandLine</code> object
and all subcommands (and nested sub-subcommands) that were added <em>before</em> the converter was registered.
Subcommands added later will not have the converter added automatically.
To ensure a custom type converter is available to all subcommands, register the type converter last, after adding subcommands.
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_option_specific_type_converters">3.3. Option-specific Type Converters</h3>
<div class="paragraph">
<p>Picocli 2.2 added a <code>converter</code> attribute to the <code>@Option</code> and <code>@Parameter</code> annotations. This allows a specific option or positional parameter to use a different converter than would be used by default based on the type of the field.</p>
</div>
<div class="paragraph">
<p>For example, for a specific field you may want to use a converter that maps the constant names defined in <a href="https://docs.oracle.com/javase/9/docs/api/java/sql/Types.html"><code>java.sql.Types</code></a> to the <code>int</code> value of these constants, but any other <code>int</code> fields should not be affected by this and should continue to use the standard int converter that parses numeric values.</p>
</div>
<div class="paragraph">
<p>Example usage:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">App</span> {
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">--sqlType</span><span class="delimiter">&quot;</span></span>, converter = SqlTypeConverter.class)
    <span class="type">int</span> sqlType;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Example implementation:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">SqlTypeConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Integer</span>&gt; {
    <span class="directive">public</span> <span class="predefined-type">Integer</span> convert(<span class="predefined-type">String</span> value) <span class="directive">throws</span> <span class="exception">Exception</span> {
        <span class="keyword">switch</span> (value) {
            <span class="keyword">case</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">ARRAY</span><span class="delimiter">&quot;</span></span>  : <span class="keyword">return</span> <span class="predefined-type">Types</span>.ARRAY;
            <span class="keyword">case</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">BIGINT</span><span class="delimiter">&quot;</span></span> : <span class="keyword">return</span> <span class="predefined-type">Types</span>.BIGINT;
            <span class="keyword">case</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">BINARY</span><span class="delimiter">&quot;</span></span> : <span class="keyword">return</span> <span class="predefined-type">Types</span>.BINARY;
            <span class="keyword">case</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">BIT</span><span class="delimiter">&quot;</span></span>    : <span class="keyword">return</span> <span class="predefined-type">Types</span>.BIT;
            <span class="keyword">case</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">BLOB</span><span class="delimiter">&quot;</span></span>   : <span class="keyword">return</span> <span class="predefined-type">Types</span>.BLOB;
            ...
        }
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This may also be useful for applications that need a custom type converter but want to use the static convenience methods (<code>populateCommand</code>, <code>run</code>, <code>call</code>). The <code>converter</code> annotation does not require a <code>CommandLine</code> instance so it can be used with the static convenience methods.</p>
</div>
<div class="paragraph">
<p>Type converters declared with the <code>converter</code> attribute need to have a public no-argument constructor to be instantiated, unless a <a href="#_custom_factory">Custom Factory</a> is installed to instantiate classes.</p>
</div>
</div>
<div class="sect2">
<h3 id="_arrays_collections_maps">3.4. Arrays, Collections, Maps</h3>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Starting from picocli v2.0, the <code>type</code> attribute is no longer necessary for <code>Collection</code> and <code>Map</code> fields:
picocli will infer the collection element type from the generic type.
(The <code>type</code> attribute still works as before, it is just optional in most cases.)
</td>
</tr>
</table>
</div>
<div class="sect3">
<h4 id="_arrays_and_collections">3.4.1. Arrays and Collections</h4>
<div class="paragraph">
<p>Multiple parameters can be captured together in a single array or <code>Collection</code> field.
The array or collection elements can be any type for which a <a href="#_strongly_typed_everything">converter</a> is registered.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="keyword">import</span> <span class="include">java.util.regex.Pattern</span>;
<span class="keyword">import</span> <span class="include">java.io.File</span>;

<span class="type">class</span> <span class="class">Convert</span> {
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-patterns</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">the regex patterns to use</span><span class="delimiter">&quot;</span></span>);
    <span class="predefined-type">Pattern</span><span class="type">[]</span> patterns;

    <span class="annotation">@Parameters</span>(<span class="comment">/* type = File.class, */</span> description = <span class="string"><span class="delimiter">&quot;</span><span class="content">the files to convert</span><span class="delimiter">&quot;</span></span>)
    <span class="predefined-type">List</span>&lt;<span class="predefined-type">File</span>&gt; files; <span class="comment">// picocli infers type from the generic type</span>
}</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">String</span><span class="type">[]</span> args = { <span class="string"><span class="delimiter">&quot;</span><span class="content">-patterns</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">a*b</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">-patterns</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">[a-e][i-u]</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">file1.txt</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">file2.txt</span><span class="delimiter">&quot;</span></span> };
Convert convert = CommandLine.populateCommand(<span class="keyword">new</span> Convert(), args);

<span class="comment">// convert.patterns now has two Pattern objects</span>
<span class="comment">// convert.files now has two File objects</span></code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
If a collection is returned from a type converter, the <em>contents</em> of the collection are added to the field, not the collection itself.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If the field is <code>null</code>, picocli will instantiate it when the option or positional parameter is matched.
If the <code>Collection</code> type is not a concrete class, picocli will make a best effort to instantiate it based on the field type:
<code>List &#8594; ArrayList</code>, <code>OrderedSet &#8594; TreeSet</code>, <code>Set &#8594; LinkedHashSet</code>, <code>Queue &#8594; LinkedList</code>, otherwise, <code>ArrayList</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="_maps">3.4.2. Maps</h4>
<div class="paragraph">
<p>Picocli v1.0 introduced support for <code>Map</code> fields similar to Java&#8217;s system properties <code>-Dkey=value</code> or Gradle&#8217;s project properties <code>-Pmyprop=myvalue</code>.</p>
</div>
<div class="paragraph">
<p><code>Map</code> fields may have any type for their key and value
as long as a <a href="#_strongly_typed_everything">converter</a> is registered for both the key and the value type.
Key and value types are inferred from the map&#8217;s generic type parameters.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="keyword">import</span> <span class="include">java.net.InetAddress</span>;
<span class="keyword">import</span> <span class="include">java.net.Proxy.Type</span>;
<span class="keyword">import</span> <span class="include">java.util.concurrent.TimeUnit</span>;

<span class="type">class</span> <span class="class">MapDemo</span> {
    <span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-p</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--proxyHost</span><span class="delimiter">&quot;</span></span>});
    <span class="predefined-type">Map</span>&lt;<span class="predefined-type">Proxy</span>.Type, <span class="predefined-type">InetAddress</span>&gt; proxies;

    <span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-u</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--timeUnit</span><span class="delimiter">&quot;</span></span>});
    <span class="predefined-type">Map</span>&lt;<span class="predefined-type">TimeUnit</span>, <span class="predefined-type">Long</span>&gt; timeout;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Map options may be specified multiple times with different key-value pairs. (See <a href="#_multiple_values">Multiple Values</a>.)</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">&lt;command&gt; -p HTTP=123.123.123.123 --proxyHost SOCKS=212.212.212.212
&lt;command&gt; -uDAYS=3 -u HOURS=23 -u=MINUTES=59 --timeUnit=SECONDS=13</code></pre>
</div>
</div>
<div class="paragraph">
<p>If the field is <code>null</code>, picocli will instantiate it when the option or positional parameter is matched.
If the type is not a concrete class, picocli will instantiate a <code>LinkedHashMap</code> to preserve the input ordering.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
On the command line, the key and the value must be separated by a <code>=</code> character.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_abstract_field_types">3.5. Abstract Field Types</h3>
<div class="paragraph">
<p>The field&#8217;s type can be an interface or an abstract class.
The <code>type</code> attribute can be used to control for each field what concrete class the string value should be converted to.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">App</span> {
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">--big</span><span class="delimiter">&quot;</span></span>, type = <span class="predefined-type">BigDecimal</span>.class) <span class="comment">// concrete Number subclass</span>
    <span class="predefined-type">Number</span><span class="type">[]</span> big; <span class="comment">// array type with abstract component class</span>

    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">--small</span><span class="delimiter">&quot;</span></span>, type = <span class="predefined-type">Short</span>.class) <span class="comment">// other Number subclass</span>
    <span class="predefined-type">Number</span><span class="type">[]</span> small;

    <span class="annotation">@Parameters</span>(type = <span class="predefined-type">StringBuilder</span>.class) <span class="comment">// StringBuilder implements CharSequence</span>
    <span class="predefined-type">CharSequence</span> address; <span class="comment">// interface type</span>
}</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="_maps_and_collections_with_abstract_elements">3.5.1. Maps and Collections with Abstract Elements</h4>
<div class="paragraph">
<p>For raw maps and collections, or when using generics with unbounded wildcards like <code>Map&lt;?, ?&gt;</code>, or when the type parameters are themselves abstract classes like <code>List&lt;CharSequence&gt;</code> or <code>Map&lt;? extends Number, ? super Number&gt;</code>, there is not enough information to convert to a stronger type. By default, the raw String values are added as is to such collections.</p>
</div>
<div class="paragraph">
<p>The <code>type</code> attribute can be specified to convert to a stronger type than String. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">TypeDemo</span> {
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-x</span><span class="delimiter">&quot;</span></span>); <span class="comment">// not enough information to convert</span>
    <span class="predefined-type">Map</span>&lt;?, ?&gt; weaklyTyped; <span class="comment">// String keys and values are added as is</span>

    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-y</span><span class="delimiter">&quot;</span></span>, type = {<span class="predefined-type">Short</span>.class, <span class="predefined-type">BigDecimal</span>.class});
    <span class="predefined-type">Map</span>&lt;? <span class="directive">extends</span> <span class="predefined-type">Number</span>, ? <span class="local-variable">super</span> <span class="predefined-type">Number</span>&gt; stronglyTyped;

    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-s</span><span class="delimiter">&quot;</span></span>, type = <span class="predefined-type">CharBuffer</span>.class);
    <span class="predefined-type">List</span>&lt;<span class="predefined-type">CharSequence</span>&gt; text;
}</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_multiple_values">4. Multiple Values</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Multi-valued options and positional parameters are annotated fields that can capture multiple values from the command line.</p>
</div>
<div class="sect2">
<h3 id="_multiple_occurrences">4.1. Multiple Occurrences</h3>
<div class="sect3">
<h4 id="_repeated_options">4.1.1. Repeated Options</h4>
<div class="paragraph">
<p>The simplest way to create a multi-valued option is to declare an annotated field whose type is an array, collection or a map.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-option</span><span class="delimiter">&quot;</span></span>)
<span class="type">int</span><span class="type">[]</span> values;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Users may specify the same option multiple times. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>&lt;command&gt; -option 111 -option 222 -option 333</pre>
</div>
</div>
<div class="paragraph">
<p>Each value is appended to the array or collection.</p>
</div>
</div>
<div class="sect3">
<h4 id="_multiple_positional_parameters">4.1.2. Multiple Positional Parameters</h4>
<div class="paragraph">
<p>Similarly for multi-valued positional parameters:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Parameters</span>
<span class="predefined-type">List</span>&lt;<span class="predefined-type">TimeUnit</span>&gt; units;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Users may specify multiple positional parameters. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>&lt;command&gt; SECONDS HOURS DAYS</pre>
</div>
</div>
<div class="paragraph">
<p>Again, each value is appended to the array or collection.</p>
</div>
</div>
<div class="sect3">
<h4 id="_repeated_boolean_options">4.1.3. Repeated Boolean Options</h4>
<div class="paragraph">
<p>Boolean options with multiple values are supported from picocli v2.1.0.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-v</span><span class="delimiter">&quot;</span></span>, description = { <span class="string"><span class="delimiter">&quot;</span><span class="content">Specify multiple -v options to increase verbosity.</span><span class="delimiter">&quot;</span></span>,
                                      <span class="string"><span class="delimiter">&quot;</span><span class="content">For example, `-v -v -v` or `-vvv`</span><span class="delimiter">&quot;</span></span>})
<span class="type">boolean</span><span class="type">[]</span> verbosity;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Users may specify multiple boolean flag options without parameters. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>&lt;command&gt; -v -v -v -vvv</pre>
</div>
</div>
<div class="paragraph">
<p>The above example results in six <code>true</code> values being added to the <code>verbosity</code> array.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_split_regex">4.2. Split Regex</h3>
<div class="paragraph">
<p>Options and parameters may also specify a <code>split</code> regular expression used to split each option parameter into smaller substrings.
Each of these strings is converted to the type of the collection or array. See <a href="#_arrays_and_collections">Arrays and Collections</a>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-option</span><span class="delimiter">&quot;</span></span>, split = <span class="string"><span class="delimiter">&quot;</span><span class="content">,</span><span class="delimiter">&quot;</span></span>)
<span class="type">int</span><span class="type">[]</span> values;</code></pre>
</div>
</div>
<div class="paragraph">
<p>A single command line argument like the following will be split up and three <code>int</code> values are added to the array:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>-option 111,222,333</pre>
</div>
</div>
<div class="paragraph">
<p>Similarly for <a href="#_maps">Maps</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-fix</span><span class="delimiter">&quot;</span></span>, split = <span class="string"><span class="delimiter">&quot;</span><span class="char">\\</span><span class="content">|</span><span class="delimiter">&quot;</span></span>)
<span class="predefined-type">Map</span>&lt;<span class="predefined-type">Integer</span>, <span class="predefined-type">String</span>&gt; message;</code></pre>
</div>
</div>
<div class="paragraph">
<p>With the above option, command line arguments like the following are interpreted as a set of key-value pairs instead of a single string:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>-fix 8=FIX.4.4|9=69|35=A|49=MBT|56=TargetCompID|34=9|52=20130625-04:05:32.682|98=0|108=30|10=052</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_arity">4.3. Arity</h3>
<div class="paragraph">
<p>Sometimes you want to define an option that requires more than one option parameter <em>for each option occurrence</em> on the command line.</p>
</div>
<div class="paragraph">
<p>The <code>arity</code> attribute lets you control exactly how many parameters to consume for each option occurrence.</p>
</div>
<div class="paragraph">
<p>The <code>arity</code> attribute can specify an exact number of required parameters, or a <em>range</em> with a minimum and a maximum number of parameters.
The maximum can be an exact upper bound, or it can be <code>"*"</code> to denote <em>any number</em> of parameters. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">ArityDemo</span> {
    <span class="annotation">@Parameters</span>(arity = <span class="string"><span class="delimiter">&quot;</span><span class="content">1..3</span><span class="delimiter">&quot;</span></span>, descriptions = <span class="string"><span class="delimiter">&quot;</span><span class="content">one to three Files</span><span class="delimiter">&quot;</span></span>)
    <span class="predefined-type">File</span><span class="type">[]</span> files;

    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-f</span><span class="delimiter">&quot;</span></span>, arity = <span class="string"><span class="delimiter">&quot;</span><span class="content">2</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">exactly two floating point numbers</span><span class="delimiter">&quot;</span></span>)
    <span class="type">double</span><span class="type">[]</span> doubles;

    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-s</span><span class="delimiter">&quot;</span></span>, arity = <span class="string"><span class="delimiter">&quot;</span><span class="content">1..*</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">at least one string</span><span class="delimiter">&quot;</span></span>)
    <span class="predefined-type">String</span><span class="type">[]</span> strings;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>A <code>MissingParameterException</code> is thrown when fewer than the miminum number of parameters is specified on the command line.</p>
</div>
<div class="paragraph">
<p>Once the minimum number of parameters is consumed, picocli will check each subsequent command line argument to see whether it is an additional parameter, or a new option. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>ArityDemo -s A B C -f 1.0 2.0 /file1 /file2</pre>
</div>
</div>
<div class="paragraph">
<p>Option <code>-s</code> has arity <code>"1..*"</code> but instead of consuming all parameters,
the <code>-f</code> argument is recognized as a separate option.</p>
</div>
</div>
<div class="sect2">
<h3 id="_default_arity">4.4. Default Arity</h3>
<div class="paragraph">
<p>If no <code>arity</code> is specified, the number of parameters depends on the field&#8217;s type.</p>
</div>
<div class="sect3">
<h4 id="_option_arity">4.4.1. Option Arity</h4>
<table class="tableblock frame-all grid-cols spread">
<caption class="title">Table 1. Default <code>arity</code> for <code>@Option</code> fields</caption>
<colgroup>
<col style="width: 30%;">
<col style="width: 5%;">
<col style="width: 65%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">@Option Field Type</th>
<th class="tableblock halign-left valign-top">Default Arity</th>
<th class="tableblock halign-left valign-top">Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">boolean</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Boolean options by default don&#8217;t require an option parameter. The field is toggled to its logical negative when the option name is recognized.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Single-valued type (e.g., <code>int</code>, <code>String</code>, <code>File</code>)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The option name must be followed by a value.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Multi-valued type (arrays, collections or maps)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The option name must be followed by a value.</p></td>
</tr>
</tbody>
</table>
<div class="admonitionblock caution">
<table>
<tr>
<td class="icon">
<i class="fa icon-caution" title="Caution"></i>
</td>
<td class="content">
Prior to picocli v2.0, multi-valued options used to greedily consume as many arguments as possible until
encountering another option or subcommand.
If your application relies on the previous behaviour, you need to explicitly specify an option arity of <code>0..*</code> when migrating to picocli v2.0.
</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="_positional_parameter_arity">4.4.2. Positional Parameter Arity</h4>
<table class="tableblock frame-all grid-cols spread">
<caption class="title">Table 2. Default <code>arity</code> for <code>@Parameters</code> fields</caption>
<colgroup>
<col style="width: 30%;">
<col style="width: 5%;">
<col style="width: 65%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">@Parameters Field Type</th>
<th class="tableblock halign-left valign-top">Default Arity</th>
<th class="tableblock halign-left valign-top">Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">boolean</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Positional parameters of type <code>boolean</code> or <code>Boolean</code> require a value. Only <code>true</code> or <code>false</code> (case insensitive) are valid values.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Single-valued type (e.g., <code>int</code>, <code>String</code>, <code>File</code>)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">One parameter required for each position.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Multi-valued type (arrays, collections or maps)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0..1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">For multi-valued positional parameters (arrays, collections or maps), values are optional, not required.</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p><code>@Parameters</code> fields are applied to a command line argument if their index matches the argument&#8217;s position.
The default index is <code>*</code>, meaning all positions.
A <code>@Parameters</code> field with <code>index = "*"</code> is applied multiple times: once for each positional parameter on the command line.</p>
</div>
<div class="paragraph">
<p>When a <code>@Parameters</code> field is applied (because its index matches the index of the positional parameter), the field may consume zero, one or more arguments, depending on its arity.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_optional_values">4.5. Optional Values</h3>
<div class="paragraph">
<p>If an option is defined with <code>arity = "0..1"</code>, it may or not have a parameter value.
If such an option is specified without a value on the command line, it is assigned an empty String (starting from picocli 2.3).
If the option is not specified, it keeps its default value. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">OptionalValueDemo</span> <span class="directive">implements</span> <span class="predefined-type">Runnable</span> {
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-x</span><span class="delimiter">&quot;</span></span>, arity = <span class="string"><span class="delimiter">&quot;</span><span class="content">0..1</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">optional parameter</span><span class="delimiter">&quot;</span></span>)
    <span class="predefined-type">String</span> x;

    <span class="directive">public</span> <span class="type">void</span> run() { <span class="predefined-type">System</span>.out.printf(<span class="string"><span class="delimiter">&quot;</span><span class="content">x = '%s'%n</span><span class="delimiter">&quot;</span></span>, x); }

    <span class="directive">public</span> <span class="directive">static</span> <span class="type">void</span> main(<span class="predefined-type">String</span>... args) {
       CommandLine.run(<span class="keyword">new</span> OptionalValueDemo(), <span class="predefined-type">System</span>.out, args);
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Gives the following results:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">java OptionalValueDemo -x value
x = 'value'

java OptionalValueDemo -x
x = ''

java OptionalValueDemo
x = 'null'</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_required_arguments">5. Required Arguments</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_required_options">5.1. Required Options</h3>
<div class="paragraph">
<p>Options can be marked <code>required</code> to make it mandatory for the user to specify them on the command line. When a required option is not specified, a <code>MissingParameterException</code> is thrown from the <code>parse</code> method. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">MandatoryOption</span> {
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-n</span><span class="delimiter">&quot;</span></span>, required = <span class="predefined-constant">true</span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">mandatory number</span><span class="delimiter">&quot;</span></span>)
    <span class="type">int</span> number;

    <span class="annotation">@Parameters</span>
    <span class="predefined-type">File</span><span class="type">[]</span> files;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The following command line arguments would result in an exception complaining that <code>number</code> is missing:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>// invalid: missing option -n
&lt;command&gt; file1 file2 file3</pre>
</div>
</div>
<div class="paragraph">
<p>The following command line arguments would be accepted:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>// valid: required option -n has a value
&lt;command&gt; -n 123 file1 file2 file3</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_required_parameters">5.2. Required Parameters</h3>
<div class="paragraph">
<p>Use the <code>arity</code> attribute to make <code>@Parameters</code> mandatory:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">BothOptionAndParametersMandatory</span> {
    <span class="annotation">@Parameters</span>(arity = <span class="string"><span class="delimiter">&quot;</span><span class="content">1..*</span><span class="delimiter">&quot;</span></span>, descriptions = <span class="string"><span class="delimiter">&quot;</span><span class="content">at least one File</span><span class="delimiter">&quot;</span></span>)
    <span class="predefined-type">File</span><span class="type">[]</span> files;

    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-n</span><span class="delimiter">&quot;</span></span>, required = <span class="predefined-constant">true</span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">mandatory number</span><span class="delimiter">&quot;</span></span>)
    <span class="type">int</span> number;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The following command line arguments would result in an exception complaining that <code>files</code> are missing:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>// invalid: missing file parameters
&lt;command&gt; -n 123</pre>
</div>
</div>
<div class="paragraph">
<p>The following command line arguments would be accepted:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>// valid: both required fields have a value
&lt;command&gt; -n 123 file1</pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_strict_or_lenient_parsing">6. Strict or Lenient Parsing</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_too_many_values">6.1. Too Many Values</h3>
<div class="paragraph">
<p>When a single-value option is specified multiple times on the command line, the default parser behaviour is
to throw an <code>OverwrittenOptionException</code>. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Option</span>(name = <span class="string"><span class="delimiter">&quot;</span><span class="content">-p</span><span class="delimiter">&quot;</span></span>) <span class="type">int</span> port;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The following input results in an <code>OverwrittenOptionException</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>&lt;command&gt; -p 80 -p 8080</pre>
</div>
</div>
<div class="paragraph">
<p>Applications can change this by calling <code>CommandLine.setOverwrittenOptionsAllowed(true)</code> before parsing the input.
When overwritten options are allowed, the last specified value takes effect (the above input will set the <code>port</code> field to <code>8080</code>)
and a WARN level message is printed to the console. (See <a href="#_tracing">Tracing</a> for how to switch off the warnings.)</p>
</div>
</div>
<div class="sect2">
<h3 id="_stop_at_positional">6.2. Stop At Positional</h3>
<div class="paragraph">
<p>By default, positional parameters can be mixed with options on the command line, but this is not always desirable.
From picocli 2.3, applications can call <code>CommandLine.setStopAtPositional(true)</code>
to force the parser to treat all values following the first positional parameter as positional parameters.</p>
</div>
<div class="paragraph">
<p>When this flag is set, the first positional parameter effectively serves as an "<a href="#_double_dash_code_code">end of options</a>" marker.</p>
</div>
</div>
<div class="sect2">
<h3 id="_unmatched_input">6.3. Unmatched Input</h3>
<div class="paragraph">
<p>By default, an <code>UnmatchedArgumentException</code> is thrown when a command line argument cannot be assigned to
an option or positional parameter. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">OnlyThree</span> {
    <span class="annotation">@Parameters</span>(arity = <span class="string"><span class="delimiter">&quot;</span><span class="content">3</span><span class="delimiter">&quot;</span></span>) <span class="predefined-type">String</span><span class="type">[]</span> values;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The command has only one annotated field, <code>values</code>, and it expects exactly three arguments,
so the following input results in an <code>UnmatchedArgumentException</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>java OnlyThree 1 2 3 4 5</pre>
</div>
</div>
<div class="paragraph">
<p>Applications can change this by calling <code>CommandLine.setUnmatchedArgumentsAllowed(true)</code> before parsing the input.
When unmatched arguments are allowed, the above input will be accepted and a WARN level message is printed to the console.
(See <a href="#_tracing">Tracing</a> for how to switch off the warnings.)</p>
</div>
<div class="paragraph">
<p>The unmatched argument values can be obtained with the <code>CommandLine.getUnmatchedArguments()</code> method.</p>
</div>
</div>
<div class="sect2">
<h3 id="_unknown_options">6.4. Unknown Options</h3>
<div class="paragraph">
<p>A special case of unmatched input are arguments that look like options but don&#8217;t match any of the defined options.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-a</span><span class="delimiter">&quot;</span></span>) <span class="predefined-type">String</span> alpha;
<span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-b</span><span class="delimiter">&quot;</span></span>) <span class="predefined-type">String</span> beta;
<span class="annotation">@Parameters</span> <span class="predefined-type">String</span><span class="type">[]</span> remainder;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above defines options <code>-a</code> and <code>-b</code>, but what should the parser do with input like this?</p>
</div>
<div class="listingblock">
<div class="content">
<pre>&lt;command&gt; -x -a AAA</pre>
</div>
</div>
<div class="paragraph">
<p>The <code>-x</code> argument "looks like" an option but there is no <code>-x</code> option defined&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p>One possibility is to silently accept such values as positional parameters but this is often not desirable.
From version 1.0, picocli determines if the unmatched argument "looks like an option"
by comparing its leading characters to the prefix characters of the known options.</p>
</div>
<div class="paragraph">
<p>When the unmatched value is similar to the known options, picocli throws an <code>UnmatchedArgumentException</code>
rather than treating it as a positional parameter.</p>
</div>
<div class="paragraph">
<p>As usual, <code>CommandLine.setUnmatchedArgumentsAllowed(true)</code> will accept unmatched input and
display a WARN-level message on the console.</p>
</div>
<div class="paragraph">
<p>Arguments that are not considered similar to the known options are interpreted as positional parameters:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>&lt;command&gt; x -a AAA</pre>
</div>
</div>
<div class="paragraph">
<p>The above input is treated by the parser as one positional parameter (<code>x</code>) followed by the <code>-a</code> option and its value.</p>
</div>
<div class="paragraph">
<p>Use the <a href="#_double_dash_code_code">end-of-options delimiter</a> (<code>--</code>) to ensure that arguments resembling an option are treated as positional parameters without <code>UnmatchedArgumentException</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>&lt;command&gt; -- -x -a AAA</pre>
</div>
</div>
<div class="paragraph">
<p>Everything following the <code>--</code> end-of-options delimiter is treated as positional parameters by the parser, so
the above input is treated as three positional parameters.</p>
</div>
</div>
<div class="sect2">
<h3 id="_stop_at_unmatched">6.5. Stop At Unmatched</h3>
<div class="paragraph">
<p>From picocli 2.3, applications can call <code>CommandLine.setStopAtUnmatched(true)</code> to force the parser to stop interpreting
options and positional parameters as soon as it encounters an unmatched argument.</p>
</div>
<div class="paragraph">
<p>When this flag is set, the first unmatched argument and all subsequent command line arguments are added to the
unmatched arguments list returned by <code>CommandLine.getUnmatchedArguments()</code>.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_help_options">7. Help Options</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Options with the attribute <code>versionHelp = true</code>, <code>usageHelp = true</code> or <code>help = true</code> are special:
if one of the command line arguments is a "help" option, picocli will stop parsing the remaining arguments and will not check for required options.</p>
</div>
<div class="paragraph">
<p>Picocli v0.9.8 introduced two new option attributes, <code>versionHelp</code> and <code>usageHelp</code>, and from v2.0, the <code>help</code> attribute is deprecated.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-V</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--version</span><span class="delimiter">&quot;</span></span>}, versionHelp = <span class="predefined-constant">true</span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">display version info</span><span class="delimiter">&quot;</span></span>)
<span class="type">boolean</span> versionInfoRequested;

<span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-h</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--help</span><span class="delimiter">&quot;</span></span>}, usageHelp = <span class="predefined-constant">true</span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">display this help message</span><span class="delimiter">&quot;</span></span>)
<span class="type">boolean</span> usageHelpRequested;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Use these attributes for options that request the usage help message or version information to be shown on the console.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">App app = CommandLine.populateCommand(<span class="keyword">new</span> App(), args);
<span class="keyword">if</span> (app.usageHelpRequested) {
   CommandLine.usage(<span class="keyword">new</span> App(), <span class="predefined-type">System</span>.out);
   <span class="keyword">return</span>;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Since v0.9.8, the <code>CommandLine</code> class offers two methods that allow external components to detect whether
usage help or version information was requested (without inspecting the annotated domain object):</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>CommandLine.isUsageHelpRequested()</code> returns <code>true</code> if the parser matched an option annotated with <code>usageHelp=true</code></p>
</li>
<li>
<p><code>CommandLine.isVersionHelpRequested()</code> returns <code>true</code> if the parser matched an option annotated with <code>versionHelp=true</code></p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">CommandLine commandLine = <span class="keyword">new</span> CommandLine(<span class="keyword">new</span> App());
commandLine.parse(args);
<span class="keyword">if</span> (commandLine.isUsageHelpRequested()) {
   commandLine.usage(<span class="predefined-type">System</span>.out);
   <span class="keyword">return</span>;
} <span class="keyword">else</span> <span class="keyword">if</span> (commandLine.isVersionHelpRequested()) {
   commandLine.printVersionHelp(<span class="predefined-type">System</span>.out);
   <span class="keyword">return</span>;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>From picocli v2.0, the <a href="#_less_boilerplate">convenience methods</a> will automatically print usage help and version information
when requested with the <code>versionHelp</code> and <code>usageHelp</code> option attributes (but not for the <code>help</code> attribute).
From v2.0, the <code>help</code> attribute is deprecated.</p>
</div>
<div class="paragraph">
<p>Methods that automatically print help:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>CommandLine::call</code></p>
</li>
<li>
<p><code>CommandLine::run</code></p>
</li>
<li>
<p><code>CommandLine::parseWithHandler</code> (with the built-in <code>Run&#8230;&#8203;</code> handlers)</p>
</li>
<li>
<p><code>CommandLine::parseWithHandlers</code> (with the built-in <code>Run&#8230;&#8203;</code> handlers)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Methods that <strong>do not</strong> automatically print help:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>CommandLine::parse</code></p>
</li>
<li>
<p><code>CommandLine::populateCommand</code></p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_version_help">8. Version Help</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_static_version_information">8.1. Static Version Information</h3>
<div class="paragraph">
<p>Since v0.9.8, applications can specify version information in the <code>version</code> attribute of the <code>@Command</code> annotation.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(version = <span class="string"><span class="delimiter">&quot;</span><span class="content">1.0</span><span class="delimiter">&quot;</span></span>)
<span class="type">class</span> <span class="class">VersionedCommand</span> {
    <span class="annotation">@Option</span>(names = { <span class="string"><span class="delimiter">&quot;</span><span class="content">-V</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--version</span><span class="delimiter">&quot;</span></span> }, versionHelp = <span class="predefined-constant">true</span>,
            description = <span class="string"><span class="delimiter">&quot;</span><span class="content">print version information and exit</span><span class="delimiter">&quot;</span></span>)
    <span class="type">boolean</span> versionRequested;
    ...</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>CommandLine.printVersionHelp(PrintStream)</code> method extracts the version information from this
annotation and prints it to the specified <code>PrintStream</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">CommandLine commandLine = <span class="keyword">new</span> CommandLine(<span class="keyword">new</span> VersionedCommand());
commandLine.parse(args);
<span class="keyword">if</span> (commandLine.isVersionHelpRequested()) {
    commandLine.printVersionHelp(<span class="predefined-type">System</span>.out);
    <span class="keyword">return</span>;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>version</code> may specify multiple Strings. Each will be printed on a separate line.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(version = { <span class="string"><span class="delimiter">&quot;</span><span class="content">Versioned Command 1.0</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">Build 12345</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">(c) 2017</span><span class="delimiter">&quot;</span></span> })
<span class="type">class</span> <span class="class">VersionedCommand</span> { ... }</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>CommandLine.printVersionHelp(PrintStream)</code> method will print the above as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>Versioned Command 1.0
Build 12345
(c) 2017</pre>
</div>
</div>
<div class="paragraph">
<p>The version strings may contain <a href="#_usage_help_with_styles_and_colors">markup</a> to show ANSI styles and colors. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(version = {
        <span class="string"><span class="delimiter">&quot;</span><span class="content">@|yellow Versioned Command 1.0|@</span><span class="delimiter">&quot;</span></span>,
        <span class="string"><span class="delimiter">&quot;</span><span class="content">@|blue Build 12345|@</span><span class="delimiter">&quot;</span></span>,
        <span class="string"><span class="delimiter">&quot;</span><span class="content">@|red,bg(white) (c) 2017|@</span><span class="delimiter">&quot;</span></span> })
<span class="type">class</span> <span class="class">VersionedCommand</span> { ... }</code></pre>
</div>
</div>
<div class="paragraph">
<p>The markup will be rendered as ANSI escape codes on supported systems.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="images/VersionInfoWithColors.png" alt="Screenshot of version information containing markup with Ansi styles and colors"></span></p>
</div>
<div class="paragraph">
<p>From picocli v1.0, the <code>version</code> may contain <a href="https://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html">format specifiers</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(version = {
    <span class="string"><span class="delimiter">&quot;</span><span class="content">Versioned Command 1.0</span><span class="delimiter">&quot;</span></span>,
    <span class="string"><span class="delimiter">&quot;</span><span class="content">Build %1$s</span><span class="delimiter">&quot;</span></span>,
    <span class="string"><span class="delimiter">&quot;</span><span class="content">(c) 2017, licensed to %2$s</span><span class="delimiter">&quot;</span></span> })
<span class="type">class</span> <span class="class">VersionedCommand</span> { ... }</code></pre>
</div>
</div>
<div class="paragraph">
<p>Format argument values can be passed to the <code>printVersionHelp</code> method:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">String</span><span class="type">[]</span> args = {<span class="string"><span class="delimiter">&quot;</span><span class="content">1234</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">System</span>.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">user.name</span><span class="delimiter">&quot;</span></span>)};
<span class="keyword">new</span> CommandLine(<span class="keyword">new</span> VersionedCommand())
    .printVersionHelp(<span class="predefined-type">System</span>.out, Help.Ansi.AUTO, args);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_dynamic_version_information">8.2. Dynamic Version Information</h3>
<div class="paragraph">
<p>From picocli 2.2, the <code>@Command</code> annotation supports a <code>versionProvider</code> attribute.
Applications may specify a <code>IVersionProvider</code> implementation in this attribute, and picocli will instantiate this class
and invoke it to collect version information.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(versionProvider = com.my.custom.ManifestVersionProvider.class)
<span class="type">class</span> <span class="class">App</span> { ... }</code></pre>
</div>
</div>
<div class="paragraph">
<p>This is useful when the version of an application should be detected dynamically at runtime.
For example, an implementation may return version information obtained from the JAR manifest, a properties file or some other source.</p>
</div>
<div class="paragraph">
<p>Custom version providers need to implement the <code>picocli.CommandLine.IVersionProvider</code> interface:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">interface</span> <span class="class">IVersionProvider</span> {
    <span class="comment">/**
     * Returns version information for a command.
     * @return version information (each string in the array is displayed on a separate line)
     * @throws Exception an exception detailing what went wrong when obtaining version information
     */</span>
    <span class="predefined-type">String</span><span class="type">[]</span> getVersion() <span class="directive">throws</span> <span class="exception">Exception</span>;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Version providers declared with the <code>versionProvider</code> attribute need to have a public no-argument constructor to be instantiated, unless a <a href="#_custom_factory">Custom Factory</a> is installed to instantiate classes.</p>
</div>
<div class="paragraph">
<p>The GitHub project has a manifest file-based
<a href="https://github.com/remkop/picocli/blob/master/examples/src/main/java/picocli/examples/VersionProviderDemo2.java">example</a>
and a build-generated version properties file-based
<a href="https://github.com/remkop/picocli/blob/master/examples/src/main/java/picocli/examples/VersionProviderDemo1.java">example</a> version provider implementation.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_usage_help">9. Usage Help</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_compact_example">9.1. Compact Example</h3>
<div class="paragraph">
<p>A default picocli usage help message looks like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>Usage: cat [-AbeEnstTuv] [--help] [--version] [FILE...]
Concatenate FILE(s), or standard input, to standard output.
      FILE                    Files whose contents to display
  -A, --show-all              equivalent to -vET
  -b, --number-nonblank       number nonempty output lines, overrides -n
  -e                          equivalent to -vET
  -E, --show-ends             display $ at end of each line
  -n, --number                number all output lines
  -s, --squeeze-blank         suppress repeated empty output lines
  -t                          equivalent to -vT
  -T, --show-tabs             display TAB characters as ^I
  -u                          (ignored)
  -v, --show-nonprinting      use ^ and M- notation, except for LDF and TAB
      --help                  display this help and exit
      --version               output version information and exit
Copyright(c) 2017</pre>
</div>
</div>
<div class="paragraph">
<p>The usage help message is generated from annotation attributes, like below:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(name = <span class="string"><span class="delimiter">&quot;</span><span class="content">cat</span><span class="delimiter">&quot;</span></span>, footer = <span class="string"><span class="delimiter">&quot;</span><span class="content">Copyright(c) 2017</span><span class="delimiter">&quot;</span></span>,
         description = <span class="string"><span class="delimiter">&quot;</span><span class="content">Concatenate FILE(s), or standard input, to standard output.</span><span class="delimiter">&quot;</span></span>)
<span class="type">class</span> <span class="class">Cat</span> {

  <span class="annotation">@Parameters</span>(paramLabel = <span class="string"><span class="delimiter">&quot;</span><span class="content">FILE</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">Files whose contents to display</span><span class="delimiter">&quot;</span></span>)
  <span class="predefined-type">List</span>&lt;<span class="predefined-type">File</span>&gt; files;

  <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">--help</span><span class="delimiter">&quot;</span></span>, usageHelp = <span class="predefined-constant">true</span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">display this help and exit</span><span class="delimiter">&quot;</span></span>)
  <span class="type">boolean</span> help;

  <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-t</span><span class="delimiter">&quot;</span></span>,                 description = <span class="string"><span class="delimiter">&quot;</span><span class="content">equivalent to -vT</span><span class="delimiter">&quot;</span></span>)  <span class="type">boolean</span> t;
  <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-e</span><span class="delimiter">&quot;</span></span>,                 description = <span class="string"><span class="delimiter">&quot;</span><span class="content">equivalent to -vET</span><span class="delimiter">&quot;</span></span>) <span class="type">boolean</span> e;
  <span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-A</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--show-all</span><span class="delimiter">&quot;</span></span>}, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">equivalent to -vET</span><span class="delimiter">&quot;</span></span>) <span class="type">boolean</span> all;

  <span class="comment">// ...</span>
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_command_name">9.2. Command Name</h3>
<div class="paragraph">
<p>In the above example, the program name is taken from the <code>name</code> attribute of the <code>Command</code> annotation:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(name = <span class="string"><span class="delimiter">&quot;</span><span class="content">cat</span><span class="delimiter">&quot;</span></span>)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Without a <code>name</code> attribute, picocli will show a generic <code>&lt;main class&gt;</code> in the synopsis:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>Usage: &lt;main class&gt; [-AbeEnstTuv] [--help] [--version] [FILE...]</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_parameter_labels">9.3. Parameter Labels</h3>
<div class="paragraph">
<p>Non-boolean options require a value. The usage help should explain this, and picocli shows the option parameter
in the synopsis and in the option list. By default, the field name is shown in <code>&lt;</code> and <code>&gt;</code> fish brackets.
Use the <code>paramLabel</code> attribute to display a different name. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>Usage: &lt;main class&gt; [-f=FILE] [-n=&lt;number&gt;] NUM &lt;host&gt;
      NUM                     number param
      host                    the host parameter
  -f= FILE                    a file
  -n= &lt;number&gt;                a number option</pre>
</div>
</div>
<div class="paragraph">
<p>Some annotated fields in the below example class have a <code>paramLabel</code> attribute and others don&#8217;t:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>()
<span class="type">class</span> <span class="class">ParamLabels</span> {
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-f</span><span class="delimiter">&quot;</span></span>,    paramLabel = <span class="string"><span class="delimiter">&quot;</span><span class="content">FILE</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">a file</span><span class="delimiter">&quot;</span></span>)      <span class="predefined-type">File</span> f;
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-n</span><span class="delimiter">&quot;</span></span>,    description = <span class="string"><span class="delimiter">&quot;</span><span class="content">a number option</span><span class="delimiter">&quot;</span></span>)                  <span class="type">int</span> number;
    <span class="annotation">@Parameters</span>(index = <span class="string"><span class="delimiter">&quot;</span><span class="content">0</span><span class="delimiter">&quot;</span></span>, paramLabel = <span class="string"><span class="delimiter">&quot;</span><span class="content">NUM</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">number param</span><span class="delimiter">&quot;</span></span>) <span class="type">int</span> n;
    <span class="annotation">@Parameters</span>(index = <span class="string"><span class="delimiter">&quot;</span><span class="content">1</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">the host parameter</span><span class="delimiter">&quot;</span></span>)               <span class="predefined-type">InetAddress</span> host;
}</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
For demonstration purposes the above example mixes the all-uppercase (e.g., <code>NUM</code>) style label and the fish bracket (e.g., <code>&lt;number&gt;</code>) style labels. For real applications, mixing these label styles should be avoided. An application should consistently use only one style.
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_unsorted_option_list">9.4. Unsorted Option List</h3>
<div class="paragraph">
<p>By default the options list displays options in alphabetical order. Use the <code>sortOptions = false</code> attribute to display options in the order they are declared in your class.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(sortOptions = <span class="predefined-constant">false</span>)</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_abbreviated_synopsis">9.5. Abbreviated Synopsis</h3>
<div class="paragraph">
<p>If a command is very complex and has many options, it is sometimes desirable to suppress details from the synopsis with the <code>abbreviateSynopsis</code> attribute. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>Usage: &lt;main class&gt; [OPTIONS] [&lt;files&gt;...]</pre>
</div>
</div>
<div class="paragraph">
<p>Note that the positional parameters are not abbreviated.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(abbreviateSynopsis = <span class="predefined-constant">true</span>)
<span class="type">class</span> <span class="class">App</span> {
    <span class="annotation">@Parameters</span> <span class="predefined-type">File</span><span class="type">[]</span> files;
    <span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">--count</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">-c</span><span class="delimiter">&quot;</span></span>}) <span class="type">int</span> count;
    ....
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_custom_synopsis">9.6. Custom Synopsis</h3>
<div class="paragraph">
<p>For even more control of the synopsis, use the <code>customSynopsis</code> attribute to specify one ore more synopsis lines. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>Usage: ln [OPTION]... [-T] TARGET LINK_NAME   (1st form)
  or:  ln [OPTION]... TARGET                  (2nd form)
  or:  ln [OPTION]... TARGET... DIRECTORY     (3rd form)
  or:  ln [OPTION]... -t DIRECTORY TARGET...  (4th form)</pre>
</div>
</div>
<div class="paragraph">
<p>To produce a synopsis like the above, specify the literal text in the <code>customSynopsis</code> attribute:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(synopsisHeading = <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>, customSynopsis = {
        <span class="string"><span class="delimiter">&quot;</span><span class="content">Usage: ln [OPTION]... [-T] TARGET LINK_NAME   (1st form)</span><span class="delimiter">&quot;</span></span>,
        <span class="string"><span class="delimiter">&quot;</span><span class="content">  or:  ln [OPTION]... TARGET                  (2nd form)</span><span class="delimiter">&quot;</span></span>,
        <span class="string"><span class="delimiter">&quot;</span><span class="content">  or:  ln [OPTION]... TARGET... DIRECTORY     (3rd form)</span><span class="delimiter">&quot;</span></span>,
        <span class="string"><span class="delimiter">&quot;</span><span class="content">  or:  ln [OPTION]... -t DIRECTORY TARGET...  (4th form)</span><span class="delimiter">&quot;</span></span>,
})
<span class="type">class</span> <span class="class">Ln</span> { ... }</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_header_and_footer">9.7. Header and Footer</h3>
<div class="paragraph">
<p>The <code>header</code> will be shown at the top of the usage help message (before the synopsis). The first header line is also the line shown in the subcommand list if your command has subcommands (see <a href="#_usage_help_for_subcommands">Usage Help for Subcommands</a>).</p>
</div>
<div class="paragraph">
<p>Use the <code>footer</code> attribute to specify one or more lines to show below the generated usage help message.
Each element of the attribute String array is displayed on a separate line.</p>
</div>
<div class="paragraph">
<p>The <code>headerHeading</code> and <code>footerHeading</code> may contain format specifiers. See <a href="#_section_headings">Section Headings</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_section_headings">9.8. Section Headings</h3>
<div class="paragraph">
<p>Section headers can be used to make usage message layout appear more spacious. Section headings may contain embedded line separator (<code>%n</code>) format specifiers:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(name = <span class="string"><span class="delimiter">&quot;</span><span class="content">git-commit</span><span class="delimiter">&quot;</span></span>,
        sortOptions = <span class="predefined-constant">false</span>,
        headerHeading = <span class="string"><span class="delimiter">&quot;</span><span class="content">Usage:%n%n</span><span class="delimiter">&quot;</span></span>,
        synopsisHeading = <span class="string"><span class="delimiter">&quot;</span><span class="content">%n</span><span class="delimiter">&quot;</span></span>,
        descriptionHeading = <span class="string"><span class="delimiter">&quot;</span><span class="content">%nDescription:%n%n</span><span class="delimiter">&quot;</span></span>,
        parameterListHeading = <span class="string"><span class="delimiter">&quot;</span><span class="content">%nParameters:%n</span><span class="delimiter">&quot;</span></span>,
        optionListHeading = <span class="string"><span class="delimiter">&quot;</span><span class="content">%nOptions:%n</span><span class="delimiter">&quot;</span></span>,
        header = <span class="string"><span class="delimiter">&quot;</span><span class="content">Record changes to the repository.</span><span class="delimiter">&quot;</span></span>,
        description = <span class="string"><span class="delimiter">&quot;</span><span class="content">Stores the current contents of the index in a new commit </span><span class="delimiter">&quot;</span></span> +
                <span class="string"><span class="delimiter">&quot;</span><span class="content">along with a log message from the user describing the changes.</span><span class="delimiter">&quot;</span></span>)
<span class="type">class</span> <span class="class">GitCommit</span> { ... }</code></pre>
</div>
</div>
<div class="paragraph">
<p>The usage help message generated from this class is shown below in <a href="#_expanded_example">Expanded Example</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_expanded_example">9.9. Expanded Example</h3>
<div class="paragraph">
<p>The below example demonstrates what a customized usage message can look like.
Note how section headings with line separators can create a more spacious usage message,
and also that options are listed in declaration order (instead of in alphabetic order).</p>
</div>
<div class="listingblock">
<div class="content">
<pre>Usage:

Record changes to the repository.

git-commit [-ap] [--fixup=&lt;commit&gt;] [--squash=&lt;commit&gt;] [-c=&lt;commit&gt;]
           [-C=&lt;commit&gt;] [-F=&lt;file&gt;] [-m[=&lt;msg&gt;...]] [&lt;files&gt;...]

Description:

Stores the current contents of the index in a new commit along with a log
message from the user describing the changes.

Parameters:
      &lt;files&gt;                 the files to commit

Options:
  -a, --all                   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.
  -p, --patch                 Use the interactive patch selection interface to
                                chose which changes to commit
  -C, --reuse-message=&lt;commit&gt;
                              Take an existing commit object, and reuse the log
                                message and the authorship information
                                (including the timestamp) when creating the
                                commit.
  -c, --reedit-message=&lt;commit&gt;
                              Like -C, but with -c the editor is invoked, so
                                that the user canfurther edit the commit
                                message.
      --fixup=&lt;commit&gt;        Construct a commit message for use with rebase
                                --autosquash.
      --squash=&lt;commit&gt;        Construct a commit message for use with rebase
                                --autosquash. The commitmessage 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).
  -F, --file=&lt;file&gt;           Take the commit message from the given file. Use
                                - to read the message from the standard input.
  -m, --message[=&lt;msg&gt;...]     Use the given &lt;msg&gt; as the commit message. If
                                multiple -m options are given, their values are
                                concatenated as separate paragraphs.</pre>
</div>
</div>
<div class="paragraph">
<p>The annotated class that this usage help message is generated from is shown in <a href="#_section_headings">Section Headings</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_option_parameter_separators">9.10. Option-Parameter Separators</h3>
<div class="paragraph">
<p>The separator displayed between options and option parameters (<code>=</code> by default)
in the synopsis and the option list can be configured with the <code>separator</code> attribute.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(separator = <span class="string"><span class="delimiter">&quot;</span><span class="content"> </span><span class="delimiter">&quot;</span></span>)</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
the <code>@Command(separator = " ")</code> annotation also affects how picocli parses the command line.  See also <a href="#_custom_separators">Custom Separators</a>.
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_hidden_options_and_parameters">9.11. Hidden Options and Parameters</h3>
<div class="paragraph">
<p>Options and Parameters with the <code>hidden</code> attribute set to <code>true</code> will not be shown in the usage help message.
This is useful for example when a parameter at some index is captured into multiple fields:
by default each of these fields would be shown in the usage message, which would be confusing for users.</p>
</div>
<div class="paragraph">
<p>For example, the <code>all</code> field below is annotated as <code>hidden = true</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>()
<span class="type">class</span> <span class="class">App</span> {
    <span class="annotation">@Parameters</span>(index = <span class="string"><span class="delimiter">&quot;</span><span class="content">0</span><span class="delimiter">&quot;</span></span>,    description = <span class="string"><span class="delimiter">&quot;</span><span class="content">destination host</span><span class="delimiter">&quot;</span></span>)  <span class="predefined-type">InetAddress</span> host;
    <span class="annotation">@Parameters</span>(index = <span class="string"><span class="delimiter">&quot;</span><span class="content">1</span><span class="delimiter">&quot;</span></span>,    description = <span class="string"><span class="delimiter">&quot;</span><span class="content">destination port</span><span class="delimiter">&quot;</span></span>)  <span class="type">int</span> port;
    <span class="annotation">@Parameters</span>(index = <span class="string"><span class="delimiter">&quot;</span><span class="content">2..*</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">files to transfer</span><span class="delimiter">&quot;</span></span>) <span class="predefined-type">String</span><span class="type">[]</span> files;

    <span class="annotation">@Parameters</span>(hidden = <span class="predefined-constant">true</span>) <span class="predefined-type">String</span><span class="type">[]</span> all;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above will generate the following usage help message, where the <code>all</code> field is not shown:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>Usage: &lt;main class&gt; &lt;host&gt; &lt;port&gt; [&lt;files&gt;...]
      host                    destination host
      port                    destination port
      files                   files to transfer</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_show_default_values">9.12. Show Default Values</h3>
<div class="paragraph">
<p>Use the <code>showDefaultValues = true</code> attribute to append the default value of the options and positional parameters to the description column. Picocli uses reflection to get the default values from the annotated fields. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(showDefaultValues = <span class="predefined-constant">true</span>)
<span class="type">class</span> <span class="class">DefaultValues</span> {
    <span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-f</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--file</span><span class="delimiter">&quot;</span></span>}, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">the file to use</span><span class="delimiter">&quot;</span></span>)
    <span class="predefined-type">File</span> file = <span class="keyword">new</span> <span class="predefined-type">File</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">config.xml</span><span class="delimiter">&quot;</span></span>);
}

CommandLine.usage(<span class="keyword">new</span> DefaultValues(), <span class="predefined-type">System</span>.out);</code></pre>
</div>
</div>
<div class="paragraph">
<p>This produces the following usage help:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>Usage: &lt;main class&gt; -f=&lt;file&gt;
  -f, --file=&lt;file&gt;           the file to use
                              Default: config.xml</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_required_option_marker">9.13. Required-Option Marker</h3>
<div class="paragraph">
<p>Required options can be marked in the option list by the character specified with the <code>requiredOptionMarker</code> attribute. By default options are not marked because the synopsis shows users which options are required and which are optional. This feature may be useful in combination with <code>abbreviatedSynopsis</code>. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(requiredOptionMarker = <span class="string"><span class="delimiter">'</span><span class="content">*</span><span class="delimiter">'</span></span>, abbreviateSynopsis = <span class="predefined-constant">true</span>)
<span class="type">class</span> <span class="class">Example</span> {
    <span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-a</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--alpha</span><span class="delimiter">&quot;</span></span>}, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">optional alpha</span><span class="delimiter">&quot;</span></span>) <span class="predefined-type">String</span> alpha;
    <span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-b</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--beta</span><span class="delimiter">&quot;</span></span>}, required = <span class="predefined-constant">true</span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">mandatory beta</span><span class="delimiter">&quot;</span></span>) <span class="predefined-type">String</span> beta;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Produces the following usage help message:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>Usage: &lt;main class&gt; [OPTIONS]
  -a, --alpha=&lt;alpha&gt;         optional alpha
* -b, --beta=&lt;beta&gt;           mandatory beta</pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_ansi_colors_and_styles">10. ANSI Colors and Styles</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_colorized_example">10.1. Colorized Example</h3>
<div class="paragraph">
<p>Below shows the same usage help message as shown in <a href="#_expanded_example">Expanded Example</a>, with ANSI escape codes enabled.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="images/UsageHelpWithStyle.png" alt="Screenshot of usage help with Ansi codes enabled"></span></p>
</div>
</div>
<div class="sect2">
<h3 id="_usage_help_with_styles_and_colors">10.2. Usage Help with Styles and Colors</h3>
<div class="paragraph">
<p>You can use colors and styles in the descriptions, header and footer
of the usage help message.</p>
</div>
<div class="paragraph">
<p>Picocli supports a custom markup notation for mixing colors and styles in text,
following a convention introduced by <a href="https://github.com/fusesource/jansi">Jansi</a>, where
<code>@|</code> starts a styled section, and <code>|@</code> ends it.
Immediately following the <code>@|</code> is a comma-separated list of colors and styles, so <code>@|STYLE1[,STYLE2]&#8230;&#8203; text|@</code>.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(description = <span class="string"><span class="delimiter">&quot;</span><span class="content">Custom @|bold,underline styles|@ and @|fg(red) colors|@.</span><span class="delimiter">&quot;</span></span>)</code></pre>
</div>
</div>
<div class="paragraph">
<p><span class="image"><img src="images/DescriptionWithColors.png" alt="Description with Ansi styles and colors"></span></p>
</div>
<table class="tableblock frame-all grid-cols spread">
<caption class="title">Table 3. Pre-defined styles and colors that can be used in descriptions and headers using the <code>@|STYLE1[,STYLE2]&#8230;&#8203; text|@</code> notation</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Pre-defined Styles</th>
<th class="tableblock halign-left valign-top">Pre-defined Colors</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">bold</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">black</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">faint</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">red</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">underline</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">green</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">italic</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">yellow</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">blink</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">blue</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">reverse</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">magenta</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">reset</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">cyan</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">white</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Colors are applied as <em>foreground</em> colors by default.
You can set <em>background</em> colors by specifying <code>bg(&lt;color&gt;)</code>.
For example, <code>@|bg(red) text with red background|@</code>.
Similarly, <code>fg(&lt;color&gt;)</code> explicitly sets the foreground color.</p>
</div>
<div class="paragraph">
<p>The example below shows how this markup can be used to add colors and styles to the headings and descriptions of a usage help message:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@CommandLine</span>.Command(name = <span class="string"><span class="delimiter">&quot;</span><span class="content">git-commit</span><span class="delimiter">&quot;</span></span>,
        sortOptions = <span class="predefined-constant">false</span>,
        headerHeading = <span class="string"><span class="delimiter">&quot;</span><span class="content">@|bold,underline Usage|@:%n%n</span><span class="delimiter">&quot;</span></span>,
        synopsisHeading = <span class="string"><span class="delimiter">&quot;</span><span class="content">%n</span><span class="delimiter">&quot;</span></span>,
        descriptionHeading = <span class="string"><span class="delimiter">&quot;</span><span class="content">%n@|bold,underline Description|@:%n%n</span><span class="delimiter">&quot;</span></span>,
        parameterListHeading = <span class="string"><span class="delimiter">&quot;</span><span class="content">%n@|bold,underline Parameters|@:%n</span><span class="delimiter">&quot;</span></span>,
        optionListHeading = <span class="string"><span class="delimiter">&quot;</span><span class="content">%n@|bold,underline Options|@:%n</span><span class="delimiter">&quot;</span></span>,
        header = <span class="string"><span class="delimiter">&quot;</span><span class="content">Record changes to the repository.</span><span class="delimiter">&quot;</span></span>,
        description = <span class="string"><span class="delimiter">&quot;</span><span class="content">Stores the current contents of the index in a new commit </span><span class="delimiter">&quot;</span></span> +
                <span class="string"><span class="delimiter">&quot;</span><span class="content">along with a log message from the user describing the changes.</span><span class="delimiter">&quot;</span></span>)
<span class="type">class</span> <span class="class">GitCommit</span> { ... }</code></pre>
</div>
</div>
<div class="admonitionblock caution">
<table>
<tr>
<td class="icon">
<i class="fa icon-caution" title="Caution"></i>
</td>
<td class="content">
Markup styles cannot be nested, for example: <code>@|bold this @|underline that|@|@</code> will not work. You can achieve the same by combining styles, for example: <code>@|bold this|@ @|bold,underline that|@</code> will work fine.
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_more_colors">10.3. More Colors</h3>
<div class="paragraph">
<p>Most terminals support a <a href="https://en.wikipedia.org/wiki/ANSI_escape_code#Colors">256 color indexed palette</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>0x00-0x07:  standard colors (the named colors)
0x08-0x0F:  high intensity colors (often similar to named colors + bold style)
0x10-0xE7:  6 × 6 × 6 cube (216 colors): 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5)
0xE8-0xFF:  grayscale from black to white in 24 steps</pre>
</div>
</div>
<div class="paragraph">
<p>Colors from the 256 color palette can be specified by their index values or by their RGB components.
RGB components must be separated by a semicolon <code>;</code> and each component must be between <code>0</code> and <code>5</code>, inclusive.</p>
</div>
<div class="paragraph">
<p>For example, <code>@|bg(0;5;0) text with red=0, green=5, blue=0 background|@</code>,
or <code>@|fg(46) the same color by index, as foreground color|@</code>.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="images/256colors.png" alt="256 color indexed palette"></span></p>
</div>
</div>
<div class="sect2">
<h3 id="_configuring_fixed_elements">10.4. Configuring Fixed Elements</h3>
<div class="sect3">
<h4 id="_color_scheme">10.4.1. Color Scheme</h4>
<div class="paragraph">
<p>Picocli uses a default color scheme for options, parameters and commands.
There are no annotations to modify this color scheme, but it can be changed programmatically.</p>
</div>
<div class="paragraph">
<p>The below code snippet shows how a custom color scheme can be specified to configure the usage help message style:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="comment">// see also CommandLine.Help.defaultColorScheme()</span>
ColorScheme colorScheme = <span class="keyword">new</span> ColorScheme()
        .commands    (<span class="predefined-type">Style</span>.bold, <span class="predefined-type">Style</span>.underline)    <span class="comment">// combine multiple styles</span>
        .options     (<span class="predefined-type">Style</span>.fg_yellow)                <span class="comment">// yellow foreground color</span>
        .parameters  (<span class="predefined-type">Style</span>.fg_yellow)
        .optionParams(<span class="predefined-type">Style</span>.italic);

CommandLine.usage(annotatedObject, <span class="predefined-type">System</span>.out, colorScheme);
...</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_color_scheme_overrides">10.4.2. Color Scheme Overrides</h4>
<div class="paragraph">
<p>The following system properties override the color scheme styles. This allows end users to adjust for their individual terminal color setup.</p>
</div>
<div class="listingblock">
<div class="title">System Properties to Override the Color Scheme</div>
<div class="content">
<pre>picocli.color.commands
picocli.color.options
picocli.color.parameters
picocli.color.optionParams</pre>
</div>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>java -Dpicocli.color.options=blink,blue -Dpicocli.color.parameters=reverse com.app.Main</code></pre>
</div>
</div>
<div class="paragraph">
<p>System property values may specify multiple comma separated styles.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_supported_platforms">10.5. Supported Platforms</h3>
<div class="paragraph">
<p>Picocli will only emit ANSI escape codes on supported platforms.</p>
</div>
<div class="sect3">
<h4 id="_unix_and_linux">10.5.1. Unix and Linux</h4>
<div class="paragraph">
<p>Most Unix and Linux platforms support ANSI colors natively.
On Windows, when picocli detects it is running under a Unix variant like Cygwin or MSYS(2) on Windows
 it will display ANSI colors and styles, otherwise it will not emit ANSI codes.</p>
</div>
</div>
<div class="sect3">
<h4 id="_windows">10.5.2. Windows</h4>
<div class="paragraph">
<p>Starting from Windows 10 the Windows console <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/mt638032(v=vs.85).aspx">supports ANSI escape sequences</a>, but <a href="http://www.nivot.org/blog/post/2016/02/04/Windows-10-TH2-(v1511)-Console-Host-Enhancements">they may need to be enabled</a>.</p>
</div>
<div class="paragraph">
<p>For Windows version below 10, the Windows command console doesn&#8217;t support output coloring by default. One option is to install either <a href="http://cmder.net/">Cmder</a>, <a href="http://sourceforge.net/projects/conemu/">ConEmu</a>, <a href="https://github.com/adoxa/ansicon/">ANSICON</a> or <a href="https://mintty.github.io/">Mintty</a> (used by default in GitBash and Cygwin) to add coloring support to their Windows command console.</p>
</div>
<div class="paragraph">
<p>Another option is to use <a href="http://fusesource.github.io/jansi/">Jansi</a> in your application. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="keyword">import</span> <span class="include">org.fusesource.jansi.AnsiConsole</span>;
...
public <span class="directive">static</span> <span class="type">void</span> main(<span class="predefined-type">String</span><span class="type">[]</span> args) {
    AnsiConsole.systemInstall(); <span class="comment">// Jansi magic</span>
    CommandLine.run(<span class="keyword">new</span> WindowsJansiDemo(), <span class="predefined-type">System</span>.err, Ansi.ON, args);
    AnsiConsole.systemUninstall();
}</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
None of the above is mandatory. If not supported, picocli will simply not emit ANSI escape codes, and everything will work without colors.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_forcing_ansi_on_off">10.6. Forcing ANSI On/Off</h3>
<div class="paragraph">
<p>You can force picocli to either always use ANSI codes or never use ANSI codes regardless of the platform:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Setting system property <code>picocli.ansi</code> to <code>true</code> forces picocli to use ANSI codes; setting <code>picocli.ansi</code> to <code>false</code> forces picocli to <strong>not</strong> use ANSI codes. This may be a useful facility for users of your command line application.</p>
</li>
<li>
<p>You can decide to force disable or force enable ANSI escape codes programmatically by specifying <code>Ansi.ON</code> or <code>Ansi.OFF</code> when invoking <code>CommandLine.usage</code>.
This overrides the value of system property <code>picocli.ansi</code>. For example:</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="keyword">import</span> <span class="include">picocli.CommandLine.Help.Ansi</span>;

App app = CommandLine.usage(<span class="keyword">new</span> App(), <span class="predefined-type">System</span>.out, Ansi.OFF, args);</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_usage_help_api">11. Usage Help API</h2>
<div class="sectionbody">
<div class="paragraph">
<p>For further customization of the usage help message, picocli has a Help API.
The <code>Help</code> class provides a number of high-level operations, and a set of components like <code>Layout</code>, <code>TextTable</code>, <code>IOptionRenderer</code>, etc., that can be used to build custom help messages.
Details of the Help API are out of scope for this document, but the following sections give some idea of what is possible.</p>
</div>
<div class="sect2">
<h3 id="_reordering_sections">11.1. Reordering Sections</h3>
<div class="paragraph">
<p>One thing you may want to do is reorder sections of the usage message or add custom sections.</p>
</div>
<div class="paragraph">
<p>To reorder sections, you need to use the <code>CommandLine.Help</code> class directly. The <code>CommandLine.usage</code> method implementation looks like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">Help help = <span class="keyword">new</span> Help(annotatedObject);
<span class="predefined-type">StringBuilder</span> sb = <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>()
        .append(help.headerHeading())
        .append(help.header())
        .append(help.synopsisHeading())      <span class="comment">//e.g. Usage:</span>
        .append(help.synopsis())             <span class="comment">//e.g. &lt;main&gt; [OPTIONS] [ARGUMENTS]</span>
        .append(help.descriptionHeading())   <span class="comment">//e.g. %nDescription:%n%n</span>
        .append(help.description())          <span class="comment">//e.g. &quot;application description&quot;</span>
        .append(help.parameterListHeading()) <span class="comment">//e.g. %nPositional parameters:%n%n</span>
        .append(help.parameterList())        <span class="comment">//e.g. [FILE...] the files to convert</span>
        .append(help.optionListHeading())    <span class="comment">//e.g. %nOptions:%n%n</span>
        .append(help.optionList())           <span class="comment">//e.g. -h, --help   displays this help</span>
        .append(help.commandListHeading())   <span class="comment">//e.g. %nCommands:%n%n</span>
        .append(help.commandList())          <span class="comment">//e.g.    add       adds a to b</span>
        .append(help.footerHeading())
        .append(help.footer());</code></pre>
</div>
</div>
<div class="paragraph">
<p>In your application, instead of calling <code>CommandLine.usage(new MainClass(), System.err)</code>, you can alter the above code to, for example, list subcommands first, then global options and finally the parameters.</p>
</div>
</div>
<div class="sect2">
<h3 id="_custom_layout">11.2. Custom Layout</h3>
<div class="paragraph">
<p>Picocli also supports unconventional option list layouts. An example of an unconventional layout is the <code>zip</code> application, which shows multiple options per row:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">CommandLine.usage(<span class="keyword">new</span> ZipHelpDemo(), <span class="predefined-type">System</span>.out);</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>Copyright (c) 1990-2008 Info-ZIP - Type 'zip "-L"' for software license.
Zip 3.0 (July 5th 2008). Command:
zip [-options] [-b path] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]
  The default action is to add or replace zipfile entries from list, which
  can include the special name - to compress standard input.
  If zipfile and list are omitted, zip compresses stdin to stdout.
  -f   freshen: only changed files  -u   update: only changed or new files
  -d   delete entries in zipfile    -m   move into zipfile (delete OS files)
  -r   recurse into directories     -j   junk (don't record) directory names
  -0   store only                   -l   convert LF to CR LF (-ll CR LF to LF)
  -1   compress faster              -9   compress better
  -q   quiet operation              -v   verbose operation/print version info
  -c   add one-line comments        -z   add zipfile comment
  -@   read names from stdin        -o   make zipfile as old as latest entry
  -x   exclude the following names  -i   include only the following names
  -F   fix zipfile (-FF try harder) -D   do not add directory entries
  -A   adjust self-extracting exe   -J   junk zipfile prefix (unzipsfx)
  -T   test zipfile integrity       -X   eXclude eXtra file attributes
  -y   store symbolic links as the link instead of the referenced file
  -e   encrypt                      -n   don't compress these suffixes
  -h2  show more help</pre>
</div>
</div>
<div class="paragraph">
<p>This can be achieved in picocli by subclassing the Help.Layout class.
See the picocli tests for how to achieve this.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_subcommands">12. Subcommands</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_registering_subcommands_programmatically">12.1. Registering Subcommands Programmatically</h3>
<div class="paragraph">
<p>Subcommands can be registered with the <code>CommandLine.addSubcommand</code> method.
You pass in the name of the command and the annotated object to populate with the subcommand options.
The specified name is used by the parser to recognize subcommands in the command line arguments.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">CommandLine commandLine = <span class="keyword">new</span> CommandLine(<span class="keyword">new</span> Git())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">status</span><span class="delimiter">&quot;</span></span>,   <span class="keyword">new</span> GitStatus())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">commit</span><span class="delimiter">&quot;</span></span>,   <span class="keyword">new</span> GitCommit())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">add</span><span class="delimiter">&quot;</span></span>,      <span class="keyword">new</span> GitAdd())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">branch</span><span class="delimiter">&quot;</span></span>,   <span class="keyword">new</span> GitBranch())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">checkout</span><span class="delimiter">&quot;</span></span>, <span class="keyword">new</span> GitCheckout())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">clone</span><span class="delimiter">&quot;</span></span>,    <span class="keyword">new</span> GitClone())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">diff</span><span class="delimiter">&quot;</span></span>,     <span class="keyword">new</span> GitDiff())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">merge</span><span class="delimiter">&quot;</span></span>,    <span class="keyword">new</span> GitMerge())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">push</span><span class="delimiter">&quot;</span></span>,     <span class="keyword">new</span> GitPush())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">rebase</span><span class="delimiter">&quot;</span></span>,   <span class="keyword">new</span> GitRebase())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">tag</span><span class="delimiter">&quot;</span></span>,      <span class="keyword">new</span> GitTag());</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is strongly recommended that subcommands have a <code>@Command</code> annotation with <code>name</code> and <code>description</code> attributes.</p>
</div>
<div class="paragraph">
<p>Subcommands registered programmatically can have a <code>@Command name</code> attribute that is different from the command name they are registered with. The <code>name</code> attribute value is not used when parsing the command line but only in the usage help synopsis of the subcommand. For example, a git command line could be <code>git commit -m "message"</code>, but the usage help for the <code>commit</code> subcommand could show <code>Usage: git-commit &lt;options&gt;</code>.</p>
</div>
<div class="admonitionblock caution">
<table>
<tr>
<td class="icon">
<i class="fa icon-caution" title="Caution"></i>
</td>
<td class="content">
<em>Note on custom type converters:</em> custom type converters are registered only with the subcommands and nested
sub-subcommands that were added <em>before</em> the custom type was registered.
To ensure a custom type converter is available to all subcommands, register the type converter last, after
adding subcommands.
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_registering_subcommands_declaratively">12.2. Registering Subcommands Declaratively</h3>
<div class="paragraph">
<p>From v0.9.8, picocli supports registering subcommands declaratively with the <code>@Command</code> annotation&#8217;s <code>subcommands</code> attribute.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(subcommands = {
    GitStatus.class,
    GitCommit.class,
    GitAdd.class,
    GitBranch.class,
    GitCheckout.class,
    GitClone.class,
    GitDiff.class,
    GitMerge.class,
    GitPush.class,
    GitRebase.class,
    GitTag.class
})
<span class="directive">public</span> <span class="type">class</span> <span class="class">Git</span> { ... }</code></pre>
</div>
</div>
<div class="paragraph">
<p>The declared subcommands are automatically instantiated and added when the <code>new CommandLine(new Git())</code> instance is constructed. The result is the same as if subcommands were added <a href="#_registering_subcommands_programmatically">programmatically</a>.</p>
</div>
<div class="paragraph">
<p>Subcommands referenced in a <code>subcommands</code> attribute <em>must</em> have a <code>@Command</code> annotation with a <code>name</code> attribute, or an exception is thrown from the <code>CommandLine</code> constructor. This name will be used both for generating usage help and for recognizing subcommands when parsing the command line.</p>
</div>
<div class="paragraph">
<p>Custom type converters registered on a <code>CommandLine</code> instance will apply to all subcommands that were declared on the main command with the <code>subcommands</code> annotation.</p>
</div>
<div class="paragraph">
<p>Subcommands referenced in a <code>subcommands</code> attribute need to have a public no-argument constructor to be instantiated, unless a <a href="#_custom_factory">Custom Factory</a> is installed to instantiate classes.</p>
</div>
</div>
<div class="sect2">
<h3 id="_parsing_subcommands">12.3. Parsing Subcommands</h3>
<div class="paragraph">
<p>For this example, we assume we created an alias <code>git</code> that invokes our Java application. This could also be a script or a function that calls our Java program:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">alias git='java picocli.Demo$Git'</code></pre>
</div>
</div>
<div class="paragraph">
<p>Next, we call our command with some arguments like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">git --git-dir=/home/rpopma/picocli status -sb -uno</code></pre>
</div>
</div>
<div class="paragraph">
<p>Where <code>git</code> (actually <code>java picocli.Demo$Git</code>) is the top-level command, followed by a global option and a subcommand <code>status</code> with its own options.</p>
</div>
<div class="paragraph">
<p>Setting up the parser and parsing the command line could look like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="directive">static</span> <span class="type">void</span> main(<span class="predefined-type">String</span>... args) {
    <span class="comment">// Set up the parser</span>
    CommandLine commandLine = <span class="keyword">new</span> CommandLine(<span class="keyword">new</span> Git());

    <span class="comment">// add subcommands programmatically (not necessary if the parent command</span>
    <span class="comment">// declaratively registers the subcommands via annotation)</span>
    commandLine.addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">status</span><span class="delimiter">&quot;</span></span>,   <span class="keyword">new</span> GitStatus())
               .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">commit</span><span class="delimiter">&quot;</span></span>,   <span class="keyword">new</span> GitCommit())
                ...

    <span class="comment">// Invoke the parse method to parse the arguments</span>
    List&lt;CommandLine&gt; parsed = commandLine.parse(args);
    handleParseResult(parsed);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>CommandLine.parse</code> method returns a List with the recognized commands. The top-level command (the Java class invoked by <code>git</code> in this example) is always the first element in the returned list.</p>
</div>
<div class="paragraph">
<p>The returned List also contains all matched subcommands. Your application needs to inspect this list to see what subcommand was invoked and take appropriate action. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">private</span> <span class="type">void</span> handleParseResult(<span class="predefined-type">List</span>&lt;CommandLine&gt; parsed) {
    <span class="keyword">assert</span> parsed.size() == <span class="integer">2</span> : <span class="string"><span class="delimiter">&quot;</span><span class="content">1 command and 1 subcommand found</span><span class="delimiter">&quot;</span></span>

    <span class="keyword">assert</span> parsed.get(<span class="integer">0</span>).getCommand().getClass() == Git.class       : <span class="string"><span class="delimiter">&quot;</span><span class="content">main command</span><span class="delimiter">&quot;</span></span>
    <span class="keyword">assert</span> parsed.get(<span class="integer">1</span>).getCommand().getClass() == GitStatus.class : <span class="string"><span class="delimiter">&quot;</span><span class="content">subcommand</span><span class="delimiter">&quot;</span></span>

    Git git = (Git) parsed.get(<span class="integer">0</span>).getCommand();
    <span class="keyword">assert</span> git.gitDir.equals(<span class="keyword">new</span> <span class="predefined-type">File</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">/home/rpopma/picocli</span><span class="delimiter">&quot;</span></span>));

    GitStatus gitstatus = (GitStatus) parsed.get(<span class="integer">1</span>).getCommand();
    <span class="keyword">assert</span>  gitstatus.shortFormat              : <span class="string"><span class="delimiter">&quot;</span><span class="content">git status -s</span><span class="delimiter">&quot;</span></span>
    <span class="keyword">assert</span>  gitstatus.branchInfo               : <span class="string"><span class="delimiter">&quot;</span><span class="content">git status -b</span><span class="delimiter">&quot;</span></span>
    <span class="keyword">assert</span> !gitstatus.showIgnored              : <span class="string"><span class="delimiter">&quot;</span><span class="content">git status --showIgnored not specified</span><span class="delimiter">&quot;</span></span>
    <span class="keyword">assert</span>  gitstatus.mode == GitStatusMode.no : <span class="string"><span class="delimiter">&quot;</span><span class="content">git status -u=no</span><span class="delimiter">&quot;</span></span>
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>You may be interested in the <a href="#_convenience_methods_for_subcommands">convenience methods for subcommands</a> to reduce error handling and other boilerplate code in your application.</p>
</div>
</div>
<div class="sect2">
<h3 id="__code_parentcommand_code_annotation">12.4. <code>@ParentCommand</code> annotation</h3>
<div class="paragraph">
<p>In command line applications with subcommands, options of the top level command are often intended as "global" options that apply to all the subcommands. Prior to picocli 2.2, subcommands had no easy way to access their parent command options unless the parent command made these values available in a global variable.</p>
</div>
<div class="paragraph">
<p>The <code>@ParentCommand</code> annotation introduced in picocli 2.2 makes it easy for subcommands to access their parent command options: subcommand fields annotated with <code>@ParentCommand</code> are initialized with a reference to the parent command. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(name = <span class="string"><span class="delimiter">&quot;</span><span class="content">fileutils</span><span class="delimiter">&quot;</span></span>, subcommands = <span class="predefined-type">List</span>.class)
<span class="type">class</span> <span class="class">FileUtils</span> {

    <span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-d</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--directory</span><span class="delimiter">&quot;</span></span>},
            description = <span class="string"><span class="delimiter">&quot;</span><span class="content">this option applies to all subcommands</span><span class="delimiter">&quot;</span></span>)
    <span class="predefined-type">File</span> baseDirectory;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above top-level command has a <code>--directory</code> option that applies to its subcommands.
The <code>List</code> subcommand can use the <code>@ParentCommand</code> annotation to get a reference to the parent command, so it can easily access the parent command options.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(name = <span class="string"><span class="delimiter">&quot;</span><span class="content">list</span><span class="delimiter">&quot;</span></span>)
<span class="type">class</span> <span class="class">List</span> <span class="directive">implements</span> <span class="predefined-type">Runnable</span> {

    <span class="annotation">@ParentCommand</span>
    <span class="directive">private</span> FileUtils parent; <span class="comment">// picocli injects reference to parent command</span>

    <span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-r</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--recursive</span><span class="delimiter">&quot;</span></span>},
            description = <span class="string"><span class="delimiter">&quot;</span><span class="content">Recursively list subdirectories</span><span class="delimiter">&quot;</span></span>)
    <span class="directive">private</span> <span class="type">boolean</span> recursive;

    <span class="annotation">@Override</span>
    <span class="directive">public</span> <span class="type">void</span> run() {
        list(<span class="keyword">new</span> <span class="predefined-type">File</span>(parent.baseDirectory, <span class="string"><span class="delimiter">&quot;</span><span class="content">.</span><span class="delimiter">&quot;</span></span>));
    }

    <span class="directive">private</span> <span class="type">void</span> list(<span class="predefined-type">File</span> dir) {
        <span class="predefined-type">System</span>.out.println(dir.getAbsolutePath());
        <span class="keyword">if</span> (dir.isDirectory()) {
            <span class="keyword">for</span> (<span class="predefined-type">File</span> f : dir.listFiles()) {
                <span class="keyword">if</span> (f.isDirectory() &amp;&amp; recursive) {
                    list(f);
                } <span class="keyword">else</span> {
                    <span class="predefined-type">System</span>.out.println(f.getAbsolutePath());
                }
            }
        }
    }
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_usage_help_for_subcommands">12.5. Usage Help for Subcommands</h3>
<div class="paragraph">
<p>After registering subcommands, calling the <code>commandLine.usage</code> method will show a usage help message that includes all registered commands. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">CommandLine commandLine = <span class="keyword">new</span> CommandLine(<span class="keyword">new</span> Git());

<span class="comment">// add subcommands programmatically (not necessary if the parent command</span>
<span class="comment">// declaratively registers the subcommands via annotation)</span>
commandLine.addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">status</span><span class="delimiter">&quot;</span></span>,   <span class="keyword">new</span> GitStatus());
commandLine.addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">commit</span><span class="delimiter">&quot;</span></span>,   <span class="keyword">new</span> GitCommit());
...
commandLine.usage(<span class="predefined-type">System</span>.out);</code></pre>
</div>
</div>
<div class="paragraph">
<p>The usage help message shows the commands in the order they were registered:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>Usage: git [-hV] [--git-dir=&lt;gitDir&gt;]
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.
  -V, --version               Prints version information and exits
  -h, --help                  Prints this help message and exits
      --git-dir=&lt;gitDir&gt;      Set the path to the repository

Commands:

The most commonly used git commands are:
  status    Show the working tree status.
  commit    Record changes to the repository.
  add       Add file contents to the index.
  branch    List, create, or delete branches.
  checkout  Checkout a branch or paths to the working tree.
  clone     Clone a repository into a new directory.
  diff      Show changes between commits, commit and working tree, etc.
  merge     Join two or more development histories together.
  push      Update remote refs along with associated objects.
  rebase    Forward-port local commits to the updated upstream head.
  tag       Create, list, delete or verify a tag object signed with GPG.</pre>
</div>
</div>
<div class="paragraph">
<p>The above usage help message is produced from the annotations on the class below:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(name = <span class="string"><span class="delimiter">&quot;</span><span class="content">git</span><span class="delimiter">&quot;</span></span>, sortOptions = <span class="predefined-constant">false</span>,
        description = <span class="string"><span class="delimiter">&quot;</span><span class="content">Git is a fast, scalable, distributed revision control </span><span class="delimiter">&quot;</span></span> +
                      <span class="string"><span class="delimiter">&quot;</span><span class="content">system with an unusually rich command set that provides both </span><span class="delimiter">&quot;</span></span> +
                      <span class="string"><span class="delimiter">&quot;</span><span class="content">high-level operations and full access to internals.</span><span class="delimiter">&quot;</span></span>,
        commandListHeading = <span class="string"><span class="delimiter">&quot;</span><span class="content">%nCommands:%n%nThe most commonly used git commands are:%n</span><span class="delimiter">&quot;</span></span>)
<span class="type">class</span> <span class="class">Git</span> {
  <span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-V</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--version</span><span class="delimiter">&quot;</span></span>}, versionHelp = <span class="predefined-constant">true</span>,
          description = <span class="string"><span class="delimiter">&quot;</span><span class="content">Prints version information and exits</span><span class="delimiter">&quot;</span></span>)
  <span class="directive">private</span> <span class="type">boolean</span> versionRequested;

  <span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-h</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--help</span><span class="delimiter">&quot;</span></span>}, usageHelp = <span class="predefined-constant">true</span>,
          description = <span class="string"><span class="delimiter">&quot;</span><span class="content">Prints this help message and exits</span><span class="delimiter">&quot;</span></span>)
  <span class="directive">private</span> <span class="type">boolean</span> helpRequested;

  <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">--git-dir</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">Set the path to the repository</span><span class="delimiter">&quot;</span></span>)
  <span class="directive">private</span> <span class="predefined-type">File</span> gitDir;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The usage help message for each subcommand is produced by calling <code>CommandLine.usage(new SubCommand(), out)</code>.
For example, see <a href="#_section_headings">Section Headings</a> for an example subcommand (<code>git-commit</code>), which produces the help message shown
in <a href="#_expanded_example">Expanded Example</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_nested_sub_subcommands">12.6. Nested sub-subcommands</h3>
<div class="paragraph">
<p>The specified object can be an annotated object or a
<code>CommandLine</code> instance with its own nested subcommands. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">CommandLine commandLine = <span class="keyword">new</span> CommandLine(<span class="keyword">new</span> MainCommand())
    .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">cmd1</span><span class="delimiter">&quot;</span></span>,                 <span class="keyword">new</span> ChildCommand1())
    .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">cmd2</span><span class="delimiter">&quot;</span></span>,                 <span class="keyword">new</span> ChildCommand2())
    .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">cmd3</span><span class="delimiter">&quot;</span></span>, <span class="keyword">new</span> CommandLine(<span class="keyword">new</span> ChildCommand3())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">cmd3sub1</span><span class="delimiter">&quot;</span></span>,                 <span class="keyword">new</span> GrandChild3Command1())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">cmd3sub2</span><span class="delimiter">&quot;</span></span>,                 <span class="keyword">new</span> GrandChild3Command2())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">cmd3sub3</span><span class="delimiter">&quot;</span></span>, <span class="keyword">new</span> CommandLine(<span class="keyword">new</span> GrandChild3Command3())
            .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">cmd3sub3sub1</span><span class="delimiter">&quot;</span></span>, <span class="keyword">new</span> GreatGrandChild3Command3_1())
            .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">cmd3sub3sub2</span><span class="delimiter">&quot;</span></span>, <span class="keyword">new</span> GreatGrandChild3Command3_2())
        )
    );</code></pre>
</div>
</div>
<div class="paragraph">
<p>Declaratively, subcommands can be nested by specifying the <code>subcommands</code> attribute on subcommand classes:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(name = <span class="string"><span class="delimiter">&quot;</span><span class="content">main</span><span class="delimiter">&quot;</span></span>, subcommands = {
    ChildCommand1.class,
    ChildCommand2.class,
    ChildCommand3.class })
<span class="type">class</span> <span class="class">MainCommand</span> { }

<span class="annotation">@Command</span>(name = <span class="string"><span class="delimiter">&quot;</span><span class="content">cmd3</span><span class="delimiter">&quot;</span></span>, subcommands = {
    GrandChild3Command1.class,
    GrandChild3Command2.class,
    GrandChild3Command3.class })
<span class="type">class</span> <span class="class">ChildCommand3</span> { }

<span class="annotation">@Command</span>(name = <span class="string"><span class="delimiter">&quot;</span><span class="content">cmd3sub3</span><span class="delimiter">&quot;</span></span>, subcommands = {
    GreatGrandChild3Command3_1.class,
    GreatGrandChild3Command3_2.class })
<span class="type">class</span> <span class="class">GrandChild3Command3</span> { }
...</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_tips_tricks">13. Tips &amp; Tricks</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_less_boilerplate">13.1. Less Boilerplate</h3>
<div class="paragraph">
<p>You can omit some of the boilerplate code from your application when the annotated object implements <code>Runnable</code> or <code>Callable</code>:</p>
</div>
<div class="listingblock">
<div class="title">Before</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">Callable</span>&lt;<span class="predefined-type">Object</span>&gt; callable = <span class="keyword">new</span> MyCallable();
CommandLine cmd = <span class="keyword">new</span> CommandLine(callable);
<span class="keyword">try</span> {
    cmd.parse(args);
    <span class="keyword">if</span> (cmd.isUsageHelpRequested()) {
        cmd.usage(<span class="predefined-type">System</span>.out);
        <span class="keyword">return</span> <span class="predefined-constant">null</span>;
    } <span class="keyword">else</span> <span class="keyword">if</span> (cmd.isVersionHelpRequested()) {
        cmd.printVersionHelp(<span class="predefined-type">System</span>.out);
        <span class="keyword">return</span> <span class="predefined-constant">null</span>;
    }
    <span class="keyword">return</span> callable.call();
} <span class="keyword">catch</span> (ParameterException ex) {
    <span class="predefined-type">System</span>.err.println(ex.getMessage());
    ex.getCommandLine().usage(<span class="predefined-type">System</span>.err);
    <span class="keyword">return</span> <span class="predefined-constant">null</span>;
} <span class="keyword">catch</span> (<span class="exception">Exception</span> ex) {
    <span class="keyword">throw</span> <span class="keyword">new</span> <span class="exception">ExecutionException</span>(cmd, <span class="string"><span class="delimiter">&quot;</span><span class="content">Error while calling </span><span class="delimiter">&quot;</span></span> + callable, ex);
}</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">After</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">Object</span> result = CommandLine.call(<span class="keyword">new</span> MyCallable(), <span class="predefined-type">System</span>.err, args);</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>CommandLine.call</code> method returns the result of the <code>Callable</code>, or <code>null</code> if the command line options were invalid. An error message and a usage help message are printed when the command line options were invalid. Exceptions thrown from the <code>Callable.call</code> method are caught, wrapped in an <code>ExecutionException</code> and rethrown.</p>
</div>
<div class="paragraph">
<p>When the annotated object implements <code>Runnable</code>, use the <code>run</code> method. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">CommandLine.run(<span class="keyword">new</span> MyRunnable(), <span class="predefined-type">System</span>.err, args);</code></pre>
</div>
</div>
<div class="paragraph">
<p>If the command class has subcommands, the <code>CommandLine::call</code> and <code>CommandLine::run</code> convenience methods will execute the most specific subcommand on the command line. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>&lt;command&gt; -g global_option subcommand -x -y -z subsubcommand param1 param2</pre>
</div>
</div>
<div class="paragraph">
<p>In the above example, the <code>subsubcommand</code> is the most specific subcommand, and only the <code>Runnable</code> or <code>Callable</code> associated with that subcommand will be executed by the <code>CommandLine::call</code> and <code>CommandLine::run</code> convenience methods.</p>
</div>
</div>
<div class="sect2">
<h3 id="_convenience_methods_for_subcommands">13.2. Convenience Methods for Subcommands</h3>
<div class="paragraph">
<p>Picocli v2.0 introduced the <code>CommandLine::parseWithHandler</code> and <code>CommandLine::parseWithHandlers</code> convenience methods.
These methods are intended to offer the same ease of use as the <code>run</code> and <code>call</code> methods, but with more flexibility and better support for nested subcommands.</p>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">CommandLine cmd = <span class="keyword">new</span> CommandLine(MyTopLevelCommand())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">status</span><span class="delimiter">&quot;</span></span>,   <span class="keyword">new</span> GitStatus())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">commit</span><span class="delimiter">&quot;</span></span>,   <span class="keyword">new</span> GitCommit())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">add</span><span class="delimiter">&quot;</span></span>,      <span class="keyword">new</span> GitAdd());
<span class="predefined-type">List</span>&lt;<span class="predefined-type">Object</span>&gt; result = cmd.parseWithHandler(<span class="keyword">new</span> RunAll(), <span class="predefined-type">System</span>.err, args);</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>CommandLine::parseWithHandler</code> method will take care of the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>parse the specified command line arguments</p>
</li>
<li>
<p>if the input was invalid, delegate to <code>DefaultExceptionHandler</code>, which will print the error message followed by the usage help message</p>
</li>
<li>
<p>otherwise, if the command line arguments were parsed successfully, let the specified <code>IParseResultHandler</code> handle the parse result</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Picocli provides some default <code>IParseResultHandler</code> implementations for common tasks:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>the <code>RunLast</code> handler prints help if requested, and otherwise gets the last specified command or subcommand and tries to execute it as a <code>Runnable</code> or <code>Callable</code></p>
</li>
<li>
<p>the <code>RunFirst</code> handler prints help if requested, and otherwise executes the top-level command as a <code>Runnable</code> or <code>Callable</code></p>
</li>
<li>
<p>the <code>RunAll</code> handler prints help if requested, and otherwise executes all commands and subcommands that the user specified on the command line as <code>Runnable</code> or <code>Callable</code> tasks</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_custom_factory">13.3. Custom Factory</h3>
<div class="paragraph">
<p>Declaratively registered <a href="#_registering_subcommands_declaratively">subcommands</a>, <a href="#_option_specific_type_converters">type converters</a> and <a href="#_dynamic_version_information">version providers</a> must be instantiated somehow. From picocli 2.2, a custom factory can be specified when constructing a <code>CommandLine</code> instance. This allows full control over object creation and opens possibilities for Inversion of Control and Dependency Injection. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">IFactory myFactory = getCustomFactory();
CommandLine cmdLine = <span class="keyword">new</span> CommandLine(<span class="keyword">new</span> Git(), myFactory);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Custom factories need to implement the <code>picocli.CommandLine.IFactory</code> interface:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">interface</span> <span class="class">IFactory</span> {
    <span class="comment">/**
     * Creates and returns an instance of the specified class.
     * @param cls the class to instantiate
     * @param &lt;K&gt; the type to instantiate
     * @return the new instance
     * @throws Exception an exception detailing what went wrong when creating the instance
     */</span>
    &lt;K&gt; K create(<span class="predefined-type">Class</span>&lt;K&gt; clazz) <span class="directive">throws</span> <span class="exception">Exception</span>;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>If no factory is specified, a default factory is used. The default factory requires that the classes to instantiate have a public no-argument constructor: it instantiates the class by calling first calling <code>clazz.newInstance()</code>, and if that fails, <code>clazz.getDeclaredConstructor().newInstance()</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_boolean_options_with_parameters">13.4. Boolean Options with Parameters</h3>
<div class="paragraph">
<p>By default the value of a boolean field is toggled to its logical negative when the field&#8217;s option is specified on the command line.</p>
</div>
<div class="paragraph">
<p>It is possible to let end users explicitly specify "true" or "false" as a parameter for a boolean option by defining an explicit <a href="#_arity">Arity</a> attribute. A boolean option with <code>arity = "0..1"</code> accepts zero to one parameters, <code>arity = "1"</code> means the option <em>must</em> have one parameter. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">BooleanOptionWithParameters</span> {
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-x</span><span class="delimiter">&quot;</span></span>, arity = <span class="string"><span class="delimiter">&quot;</span><span class="content">1</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">1 mandatory parameter</span><span class="delimiter">&quot;</span></span>)
    <span class="type">boolean</span> x;

    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-y</span><span class="delimiter">&quot;</span></span>, arity = <span class="string"><span class="delimiter">&quot;</span><span class="content">0..1</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">min 0 and max 1 parameter</span><span class="delimiter">&quot;</span></span>)
    <span class="type">boolean</span> y;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The following ways to invoke the program will be accepted (values are not case sensitive):</p>
</div>
<div class="listingblock">
<div class="content">
<pre>&lt;command&gt; -x true
&lt;command&gt; -x FALSE
&lt;command&gt; -x TRUE -y
&lt;command&gt; -x True -y False</pre>
</div>
</div>
<div class="paragraph">
<p>But trying to specify the <code>-x</code> option without a parameter, or with a value other than "true" or "false" (case insensitive) will result in a <code>ParameterException</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_hexadecimal_values">13.5. Hexadecimal Values</h3>
<div class="paragraph">
<p>Numeric values are interpreted as decimal numbers by default. If you want picocli to be more flexible, you can
register a custom type converter that delegates to the <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#decode-java.lang.String-">decode</a> method to convert strings to numbers.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The <code>decode</code> method looks at the prefix to determine the radix, so numbers
starting with <code>0x</code>, <code>0X</code> or <code>#</code> are interpreted as hexadecimal numbers, numbers starting with <code>0</code> are interpreted
as octal numbers, and otherwise the number is interpreted as a decimal number.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Java 8-style lambdas:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="keyword">new</span> CommandLine(obj)
        .registerConverter(<span class="predefined-type">Byte</span>.class,    s -&gt; <span class="predefined-type">Byte</span>::decode)
        .registerConverter(<span class="predefined-type">Byte</span>.TYPE,     s -&gt; <span class="predefined-type">Byte</span>::decode)
        .registerConverter(<span class="predefined-type">Short</span>.class,   s -&gt; <span class="predefined-type">Short</span>::decode)
        .registerConverter(<span class="predefined-type">Short</span>.TYPE,    s -&gt; <span class="predefined-type">Short</span>::decode)
        .registerConverter(<span class="predefined-type">Integer</span>.class, s -&gt; <span class="predefined-type">Integer</span>::decode)
        .registerConverter(<span class="predefined-type">Integer</span>.TYPE,  s -&gt; <span class="predefined-type">Integer</span>::decode)
        .registerConverter(<span class="predefined-type">Long</span>.class,    s -&gt; <span class="predefined-type">Long</span>::decode)
        .registerConverter(<span class="predefined-type">Long</span>.TYPE,     s -&gt; <span class="predefined-type">Long</span>::decode);</code></pre>
</div>
</div>
<div class="paragraph">
<p>In Java 5:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">ITypeConverter&lt;<span class="predefined-type">Integer</span>&gt; intConverter = <span class="keyword">new</span> ITypeConverter&lt;<span class="predefined-type">Integer</span>&gt;() {
    <span class="directive">public</span> <span class="predefined-type">Integer</span> convert(<span class="predefined-type">String</span> s) {
        <span class="keyword">return</span> <span class="predefined-type">Integer</span>.decode(s);
    }
};
commandLine.registerConverter(<span class="predefined-type">Integer</span>.class, intConverter);
commandLine.registerConverter(<span class="predefined-type">Integer</span>.TYPE,  intConverter);
...</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_option_parameter_separators_2">13.6. Option-Parameter Separators</h3>
<div class="sect3">
<h4 id="_default_separators">13.6.1. Default Separators</h4>
<div class="paragraph">
<p>Options may take an <em>option parameter</em> (also called <em>option-argument</em>).
For POSIX-style short options (like <code>-f</code> or <code>-c</code>), the option parameter may be attached to the option,
or it may be separated by a space or the <em>separator string</em> (<code>=</code> by default).
That is, all of the below are equivalent:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">&lt;command&gt; -foutput.txt
&lt;command&gt; -f output.txt
&lt;command&gt; -f=output.txt</code></pre>
</div>
</div>
<div class="paragraph">
<p>Long option names (like <code>--file</code>) must be separated from their option parameter by a space or the
<em>separator string</em> (<code>=</code> by default). That is, the first two below examples are valid but the last example is invalid:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="comment">// valid (separator between --file and its parameter)</span>
&lt;command&gt; --file output.txt
&lt;command&gt; --file=output.txt

<span class="comment">// invalid (picocli will not recognize the --file option when attached to its parameter)</span>
&lt;command&gt; --fileoutput.txt</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_custom_separators">13.6.2. Custom Separators</h4>
<div class="paragraph">
<p>The separator string can be customized programmatically or declaratively.</p>
</div>
<div class="paragraph">
<p>Use the <code>separator</code> attribute of the <code>@Command</code> annotation to declaratively set a separator string:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(separator = <span class="string"><span class="delimiter">&quot;</span><span class="content">:</span><span class="delimiter">&quot;</span></span>)  <span class="comment">// declaratively set a separator</span>
<span class="type">class</span> <span class="class">OptionArg</span> {
    <span class="annotation">@Option</span>(names = { <span class="string"><span class="delimiter">&quot;</span><span class="content">-f</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--file</span><span class="delimiter">&quot;</span></span> }) <span class="predefined-type">String</span> file;
}</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">OptionArg optionArg = CommandLine.populateCommand(<span class="keyword">new</span> OptionArg(), <span class="string"><span class="delimiter">&quot;</span><span class="content">-f:output.txt</span><span class="delimiter">&quot;</span></span>);
<span class="keyword">assert</span> optionArg.file.equals(<span class="string"><span class="delimiter">&quot;</span><span class="content">output.txt</span><span class="delimiter">&quot;</span></span>);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Alternatively, the separator string can be changed programmatically with the <code>CommandLine.setSeparator(String separator)</code> method.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">OptionArg optionArg     = <span class="keyword">new</span> OptionArg();
CommandLine commandLine = <span class="keyword">new</span> CommandLine(optionArg);

commandLine.setSeparator(<span class="string"><span class="delimiter">&quot;</span><span class="content">:</span><span class="delimiter">&quot;</span></span>); <span class="comment">// programmatically set a separator</span>
commandLine.parse(<span class="string"><span class="delimiter">&quot;</span><span class="content">-f:output.txt</span><span class="delimiter">&quot;</span></span>);
<span class="keyword">assert</span> optionArg.file.equals(<span class="string"><span class="delimiter">&quot;</span><span class="content">output.txt</span><span class="delimiter">&quot;</span></span>);</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_subclassing_for_reuse">13.7. Subclassing for Reuse</h3>
<div class="paragraph">
<p>Picocli will walk the class hierarchy to check for annotations, so you can declare common @Options and @Command attributes on a superclass and override these fields or attributes on a subclass.</p>
</div>
<div class="paragraph">
<p>The below example shows how common options like <code>help</code> and <code>version</code> can be declared as fields in a superclass so they are available in all subclasses. Similarly, annotating the superclass with default <code>@Command</code> attributes means subclasses won&#8217;t need to set these attributes.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(synopsisHeading      = <span class="string"><span class="delimiter">&quot;</span><span class="content">%nUsage:%n%n</span><span class="delimiter">&quot;</span></span>,
         descriptionHeading   = <span class="string"><span class="delimiter">&quot;</span><span class="content">%nDescription:%n%n</span><span class="delimiter">&quot;</span></span>,
         parameterListHeading = <span class="string"><span class="delimiter">&quot;</span><span class="content">%nParameters:%n%n</span><span class="delimiter">&quot;</span></span>,
         optionListHeading    = <span class="string"><span class="delimiter">&quot;</span><span class="content">%nOptions:%n%n</span><span class="delimiter">&quot;</span></span>,
         commandListHeading   = <span class="string"><span class="delimiter">&quot;</span><span class="content">%nCommands:%n%n</span><span class="delimiter">&quot;</span></span>)
<span class="directive">public</span> <span class="directive">abstract</span> <span class="type">class</span> <span class="class">AbstractCommand</span> {

    <span class="annotation">@Option</span>(names = { <span class="string"><span class="delimiter">&quot;</span><span class="content">-h</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">-?</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--help</span><span class="delimiter">&quot;</span></span> }, usageHelp = <span class="predefined-constant">true</span>,
            description = <span class="string"><span class="delimiter">&quot;</span><span class="content">give this help list</span><span class="delimiter">&quot;</span></span>)
    <span class="directive">protected</span> <span class="type">boolean</span> helpRequested;

    <span class="annotation">@Option</span>(names = { <span class="string"><span class="delimiter">&quot;</span><span class="content">-V</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--version</span><span class="delimiter">&quot;</span></span> }, versionHelp = <span class="predefined-constant">true</span>,
            description = <span class="string"><span class="delimiter">&quot;</span><span class="content">print program version</span><span class="delimiter">&quot;</span></span>)
    <span class="directive">protected</span> <span class="type">boolean</span> versionRequested;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>All commands that extend <code>AbstractCommand</code> support the <code>--help</code> and <code>--version</code> options, and generate a usage help message in the same spacious style. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(name        = <span class="string"><span class="delimiter">&quot;</span><span class="content">zip</span><span class="delimiter">&quot;</span></span>,
         header      = <span class="string"><span class="delimiter">&quot;</span><span class="content">Compresses the specified FILE(s).</span><span class="delimiter">&quot;</span></span>,
         description = <span class="string"><span class="delimiter">&quot;</span><span class="content">The default action is to add or replace zipfile entries from list, </span><span class="delimiter">&quot;</span></span> +
                       <span class="string"><span class="delimiter">&quot;</span><span class="content">which can include the special name - to compress standard input.</span><span class="delimiter">&quot;</span></span>,
         footer      = <span class="string"><span class="delimiter">&quot;</span><span class="content">Copyright (c) 1990-2008 Info-ZIP - Type 'zip </span><span class="delimiter">&quot;</span></span>-L<span class="string"><span class="delimiter">&quot;</span><span class="content">' for software license.</span><span class="delimiter">&quot;</span></span>)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ZipCommand</span> <span class="directive">extends</span> AbstractCommand {
    <span class="annotation">@Option</span>(names = { <span class="string"><span class="delimiter">&quot;</span><span class="content">-o</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--output</span><span class="delimiter">&quot;</span></span> }, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">output file to write to</span><span class="delimiter">&quot;</span></span>)
    <span class="directive">private</span> <span class="predefined-type">File</span> output;

    <span class="annotation">@Parameter</span>(paramLabel = <span class="string"><span class="delimiter">&quot;</span><span class="content">FILE</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">FILEs to compress</span><span class="delimiter">&quot;</span></span>)
    <span class="directive">private</span> <span class="predefined-type">File</span><span class="type">[]</span> files;
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_best_practices_for_command_line_interfaces">13.8. Best Practices for Command Line Interfaces</h3>
<div class="paragraph">
<p>When designing your command line application,
the <a href="https://www.gnu.org/prep/standards/html_node/Command_002dLine-Interfaces.html#Command_002dLine-Interfaces">GNU recommendations</a> for command line interfaces and <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_02">POSIX Utility Guidelines</a> may be useful.</p>
</div>
<div class="paragraph">
<p>Generally, many applications use options for optional values and parameters for mandatory values.
However, picocli lets you make options required if you want to, see <a href="#_required_arguments">Required Arguments</a>.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_tracing">14. Tracing</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Picocli v1.0 introduced support for parser tracing to facilitate troubleshooting.</p>
</div>
<div class="paragraph">
<p>System property <code>picocli.trace</code> controls the trace level. Supported levels are <code>OFF</code>, <code>WARN</code>, <code>INFO</code>, and <code>DEBUG</code>. The default trace level is <code>WARN</code>.</p>
</div>
<div class="paragraph">
<p>Specifying system property <code>-Dpicocli.trace</code> without a value will set the trace level to <code>INFO</code>.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>DEBUG: Shows details of the decisions made by the parser during command line parsing.</p>
</li>
<li>
<p>INFO: Shows a high-level overview of what happens during command line parsing.</p>
</li>
<li>
<p>WARN: The default. Shows warnings instead of errors when lenient parsing is enabled:
when single-value options were specified multiple times (and <code>CommandLine.overwrittenOptionsAllowed</code> is <code>true</code>),
or when command line arguments could not be matched as an option or positional parameter
(and <code>CommandLine.unmatchedArgumentsAllowed</code> is <code>true</code>).</p>
</li>
<li>
<p>OFF: Suppresses all tracing including warnings.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash"># create a custom 'git' command that invokes picocli.Demo$Git with tracing switched on
alias git='java -Dpicocli.trace -cp picocli-all.jar picocli.Demo$Git'

# invoke our command with some parameters
git --git-dir=/home/rpopma/picocli commit -m &quot;Fixed typos&quot; -- src1.java src2.java src3.java

# remove our 'git' pseudonym from the current shell environment
unalias git</code></pre>
</div>
</div>
<div class="paragraph">
<p>Output:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>[picocli INFO] Parsing 8 command line args [--git-dir=/home/rpopma/picocli, commit, -m, "Fixed typos", --, src1.java, src2.java, src3.java]
[picocli INFO] Setting File field 'Git.gitDir' to '\home\rpopma\picocli' for option --git-dir
[picocli INFO] Adding [Fixed typos] to List&lt;String&gt; field 'GitCommit.message' for option -m
[picocli INFO] Found end-of-options delimiter '--'. Treating remainder as positional parameters.
[picocli INFO] Adding [src1.java] to List&lt;String&gt; field 'GitCommit.files' for args[0..*]
[picocli INFO] Adding [src2.java] to List&lt;String&gt; field 'GitCommit.files' for args[0..*]
[picocli INFO] Adding [src3.java] to List&lt;String&gt; field 'GitCommit.files' for args[0..*]</pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_tab_autocomplete">15. TAB Autocomplete</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Picocli-based applications can now have command line completion in Bash or Zsh Unix shells.
See the <a href="autocomplete.html">Autocomplete for Java Command Line Applications</a> manual for how to generate an autocompletion script tailored to your application.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_picocli_in_other_languages">16. Picocli in Other Languages</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Picocli may be used in other JVM languages that support annotations.</p>
</div>
<div class="sect2">
<h3 id="_groovy">16.1. Groovy</h3>
<div class="paragraph">
<p>In Groovy, use <code>[</code> and <code>]</code> to surround array values, instead of the <code>{</code> and <code>}</code> used in Java.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy"><span class="type">class</span> <span class="class">Args</span> {
    <span class="annotation">@Option</span>(names = [<span class="string"><span class="delimiter">&quot;</span><span class="content">-h</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--help</span><span class="delimiter">&quot;</span></span>], usageHelp=<span class="predefined-constant">true</span>,
      description = <span class="string"><span class="delimiter">&quot;</span><span class="content">Print this help and exit</span><span class="delimiter">&quot;</span></span>)
    <span class="type">boolean</span> helpRequested = <span class="predefined-constant">false</span>;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Picocli 2.0 introduces special support for Groovy scripts.</p>
</div>
<div class="paragraph">
<p>Scripts annotated with <code>@picocli.groovy.PicocliScript</code> are automatically transformed to use
<code>picocli.groovy.PicocliBaseScript</code> as their base class and can also use the <code>@Command</code> annotation to
customize parts of the usage message like command name, description, headers, footers etc.</p>
</div>
<div class="paragraph">
<p>Before the script body is executed, the <code>PicocliBaseScript</code> base class parses the command line and initializes
<code>@Field</code> variables annotated with <code>@Option</code> or <code>@Parameters</code>.
The script body is executed if the user input was valid and did not request usage help or version information.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy"><span class="annotation">@Grab</span>(<span class="string"><span class="delimiter">'</span><span class="content">info.picocli:picocli:2.3.0</span><span class="delimiter">'</span></span>)
<span class="annotation">@Command</span>(name = <span class="string"><span class="delimiter">&quot;</span><span class="content">myCommand</span><span class="delimiter">&quot;</span></span>,
  description = <span class="string"><span class="delimiter">&quot;</span><span class="content">@|bold Groovy script|@ @|underline picocli|@ example</span><span class="delimiter">&quot;</span></span>)
<span class="annotation">@picocli</span>.groovy.PicocliScript
<span class="keyword">import</span> <span class="include">groovy.transform.Field</span>
<span class="keyword">import</span> <span class="include">static</span> <span class="include">picocli.CommandLine.*</span>

<span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-x</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">number of repetitions</span><span class="delimiter">&quot;</span></span>)
<span class="annotation">@Field</span> <span class="type">int</span> count;

<span class="annotation">@Option</span>(names = [<span class="string"><span class="delimiter">&quot;</span><span class="content">-h</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--help</span><span class="delimiter">&quot;</span></span>], usageHelp = <span class="predefined-constant">true</span>,
  description = <span class="string"><span class="delimiter">&quot;</span><span class="content">print this help message and exit</span><span class="delimiter">&quot;</span></span>)
<span class="annotation">@Field</span> <span class="type">boolean</span> helpRequested;

<span class="comment">//if (helpRequested) { // not necessary: PicocliBaseScript takes care of this</span>
<span class="comment">//    CommandLine.usage(this, System.out); return 0;</span>
<span class="comment">//}</span>
count.times {
   println <span class="string"><span class="delimiter">&quot;</span><span class="content">hi</span><span class="delimiter">&quot;</span></span>
}
<span class="comment">// the CommandLine that parsed the args is available as a property</span>
<span class="keyword">assert</span> <span class="local-variable">this</span>.commandLine.commandName == <span class="string"><span class="delimiter">&quot;</span><span class="content">myCommand</span><span class="delimiter">&quot;</span></span></code></pre>
</div>
</div>
<div class="admonitionblock caution">
<table>
<tr>
<td class="icon">
<i class="fa icon-caution" title="Caution"></i>
</td>
<td class="content">
When using a Groovy version older than 2.4.7, use this workaround for the <a href="https://issues.apache.org/jira/browse/GROOVY-7613">Grape bug</a> that causes this error:
<code>java.lang.ClassNotFoundException: # Licensed to the Apache Software Foundation (ASF) under one or more</code>.
</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy"><span class="annotation">@Grab</span>(<span class="string"><span class="delimiter">'</span><span class="content">info.picocli:picocli:2.3.0</span><span class="delimiter">'</span></span>)
<span class="annotation">@GrabExclude</span>(<span class="string"><span class="delimiter">'</span><span class="content">org.codehaus.groovy:groovy-all</span><span class="delimiter">'</span></span>) <span class="comment">// work around GROOVY-7613</span>
...</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_kotlin">16.2. Kotlin</h3>
<div class="paragraph">
<p>Kotlin 1.2 (released Nov 28, 2017) officially supports <a href="http://kotlinlang.org/docs/reference/whatsnew12.html#array-literals-in-annotations">array literals in annotations</a>, allowing a more compact notation:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="kotlin">@Command(name = &quot;MyApp&quot;, version = [&quot;Kotlin picocli demo v1.0&quot;],
        description = [&quot;@|bold Kotlin|@ @|underline picocli|@ example&quot;])
class MyApp : Runnable {

    @Option(names = [&quot;-c&quot;, &quot;--count&quot;], paramLabel = &quot;COUNT&quot;,
            description = [&quot;the count&quot;])
    private var count: Int = 0

    @Option(names = [&quot;-h&quot;, &quot;--help&quot;], usageHelp = true,
            description = [&quot;print this help and exit&quot;])
    private var helpRequested: Boolean = false

    @Option(names = [&quot;-V&quot;, &quot;--version&quot;], versionHelp = true,
            description = [&quot;print version info and exit&quot;])
    private var versionRequested: Boolean = false

    override fun run() {
        for (i in 0 until count) {
            println(&quot;hello world $i...&quot;)
        }
    }
    companion object {
        @JvmStatic fun main(args: Array&lt;String&gt;) {
            CommandLine.run(MyApp(), System.err, *args)
        }
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Kotlin versions prior to 1.2 did not allow the <a href="https://kotlinlang.org/docs/reference/annotations.html">array literal syntax in annotations</a>, so with older versions of Kotlin you will have to write <code>arrayOf(&#8230;&#8203;)</code> for the <code>names</code>, <code>description</code> and <code>type</code> attributes.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="kotlin">@Command(name = &quot;MyApp&quot;, version = arrayOf(&quot;picocli demo for Kotlin v1.0 and Kotlin v1.1&quot;),
        description = arrayOf(&quot;@|bold Kotlin|@ @|underline picocli|@ example&quot;))
class MyApp : Runnable {

    @Option(names = arrayOf(&quot;-c&quot;, &quot;--count&quot;), paramLabel = &quot;COUNT&quot;,
            description = arrayOf(&quot;the count&quot;))
    private var count: Int = 0

    @Option(names = arrayOf(&quot;-h&quot;, &quot;--help&quot;), usageHelp = true,
            description = arrayOf(&quot;print this help and exit&quot;))
    private var helpRequested: Boolean = false

    @Option(names = arrayOf(&quot;-V&quot;, &quot;--version&quot;), versionHelp = true,
            description = arrayOf(&quot;print version info and exit&quot;))
    private var versionRequested: Boolean = false

    override fun run() {
        for (i in 0 until count) {
            println(&quot;hello world $i...&quot;)
        }
    }
    companion object {
        @JvmStatic fun main(args: Array&lt;String&gt;) {
            CommandLine.run(MyApp(), System.err, *args)
        }
    }
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_scala">16.3. Scala</h3>
<div class="paragraph">
<p>Scala does not allow specifying array annotation attribute as a single value,
so be aware that you will have to write <code>Array(&#8230;&#8203;)</code> for the <code>names</code>, <code>description</code> and <code>type</code> attributes.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="scala">@Command(name = &quot;MyApp&quot;, version = Array(&quot;Scala picocli demo v1.0&quot;),
  description = Array(&quot;@|bold Scala|@ @|underline picocli|@ example&quot;))
class MyApp extends Runnable {

  @Option(names = Array(&quot;-c&quot;, &quot;--count&quot;), paramLabel = &quot;COUNT&quot;,
    description = Array(&quot;the count&quot;))
  private val count: Int = 0

  @Option(names = Array(&quot;-h&quot;, &quot;--help&quot;), usageHelp = true,
    description = Array(&quot;print this help and exit&quot;))
  private val helpRequested: Boolean = false

  @Option(names = Array(&quot;-V&quot;, &quot;--version&quot;), versionHelp = true,
    description = Array(&quot;print version info and exit&quot;))
  private val versionRequested: Boolean = false

  def run() : Unit = {
    for (i &lt;- 0 until count) {
      println(s&quot;hello world $i...&quot;)
    }
  }
}
object MyApp {
  def main(args: Array[String]) {
    CommandLine.run(new MyApp(), System.err, args: _*)
  }
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_api_javadoc">17. API Javadoc</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Picocli API Javadoc can be found <a href="apidocs/">here</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_github_project">18. GitHub Project</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <a href="https://github.com/remkop/picocli">GitHub project</a> has the source code, tests, build scripts, etc.</p>
</div>
<div class="paragraph">
<p>Star <span class="icon"><i class="fa fa-star-o"></i></span> or fork <span class="icon"><i class="fa fa-code-fork"></i></span> this project on GitHub if you like it!
(Projects with many <span class="icon"><i class="fa fa-code-fork"></i></span> forks are easier to find on GitHub Search.)</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_issue_tracker">19. Issue Tracker</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Please use the <a href="https://github.com/remkop/picocli/issues">Issue Tracker</a> to report bugs or request features.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_license">20. License</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Picocli is licensed under the <a href="https://github.com/remkop/picocli/blob/master/LICENSE">Apache License 2.0</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_releases">21. Releases</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Previous versions are available from the GitHub project <a href="https://github.com/remkop/picocli/releases">Releases</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_download">22. Download</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can add picocli as an external dependency to your project, or you can include it as source.
See the <a href="#_source">source code</a> below. Copy and paste it into a file called <code>CommandLine.java</code>, add it to your project, and enjoy!</p>
</div>
<div class="sect2">
<h3 id="_gradle">22.1. Gradle</h3>
<div class="listingblock">
<div class="content">
<pre>compile 'info.picocli:picocli:2.3.0'</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_maven">22.2. Maven</h3>
<div class="listingblock">
<div class="content">
<pre>&lt;dependency&gt;
  &lt;groupId&gt;info.picocli&lt;/groupId&gt;
  &lt;artifactId&gt;picocli&lt;/artifactId&gt;
  &lt;version&gt;2.3.0&lt;/version&gt;
&lt;/dependency&gt;</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_scala_sbt">22.3. Scala SBT</h3>
<div class="listingblock">
<div class="content">
<pre>libraryDependencies += "info.picocli" % "picocli" % "2.3.0"</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_ivy">22.4. Ivy</h3>
<div class="listingblock">
<div class="content">
<pre>&lt;dependency org="info.picocli" name="picocli" rev="2.3.0" /&gt;</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_source">22.5. Source</h3>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="comment">/*
   Copyright 2017 Remko Popma

   Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
   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 &quot;AS IS&quot; 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.
 */</span>
<span class="keyword">package</span> <span class="namespace">picocli</span>;

<span class="keyword">import</span> <span class="include">java.io.File</span>;
<span class="keyword">import</span> <span class="include">java.io.FileReader</span>;
<span class="keyword">import</span> <span class="include">java.io.LineNumberReader</span>;
<span class="keyword">import</span> <span class="include">java.io.PrintStream</span>;
<span class="keyword">import</span> <span class="include">java.io.StreamTokenizer</span>;
<span class="keyword">import</span> <span class="include">java.lang.annotation.ElementType</span>;
<span class="keyword">import</span> <span class="include">java.lang.annotation.Retention</span>;
<span class="keyword">import</span> <span class="include">java.lang.annotation.RetentionPolicy</span>;
<span class="keyword">import</span> <span class="include">java.lang.annotation.Target</span>;
<span class="keyword">import</span> <span class="include">java.lang.reflect.Array</span>;
<span class="keyword">import</span> <span class="include">java.lang.reflect.Constructor</span>;
<span class="keyword">import</span> <span class="include">java.lang.reflect.Field</span>;
<span class="keyword">import</span> <span class="include">java.lang.reflect.Method</span>;
<span class="keyword">import</span> <span class="include">java.lang.reflect.Modifier</span>;
<span class="keyword">import</span> <span class="include">java.lang.reflect.ParameterizedType</span>;
<span class="keyword">import</span> <span class="include">java.lang.reflect.Type</span>;
<span class="keyword">import</span> <span class="include">java.lang.reflect.WildcardType</span>;
<span class="keyword">import</span> <span class="include">java.math.BigDecimal</span>;
<span class="keyword">import</span> <span class="include">java.math.BigInteger</span>;
<span class="keyword">import</span> <span class="include">java.net.InetAddress</span>;
<span class="keyword">import</span> <span class="include">java.net.MalformedURLException</span>;
<span class="keyword">import</span> <span class="include">java.net.NetworkInterface</span>;
<span class="keyword">import</span> <span class="include">java.net.URI</span>;
<span class="keyword">import</span> <span class="include">java.net.URISyntaxException</span>;
<span class="keyword">import</span> <span class="include">java.net.URL</span>;
<span class="keyword">import</span> <span class="include">java.nio.ByteOrder</span>;
<span class="keyword">import</span> <span class="include">java.nio.charset.Charset</span>;
<span class="keyword">import</span> <span class="include">java.sql.Connection</span>;
<span class="keyword">import</span> <span class="include">java.sql.Driver</span>;
<span class="keyword">import</span> <span class="include">java.sql.DriverManager</span>;
<span class="keyword">import</span> <span class="include">java.sql.Time</span>;
<span class="keyword">import</span> <span class="include">java.sql.Timestamp</span>;
<span class="keyword">import</span> <span class="include">java.text.BreakIterator</span>;
<span class="keyword">import</span> <span class="include">java.text.ParseException</span>;
<span class="keyword">import</span> <span class="include">java.text.SimpleDateFormat</span>;
<span class="keyword">import</span> <span class="include">java.util.ArrayList</span>;
<span class="keyword">import</span> <span class="include">java.util.Arrays</span>;
<span class="keyword">import</span> <span class="include">java.util.Collection</span>;
<span class="keyword">import</span> <span class="include">java.util.Collections</span>;
<span class="keyword">import</span> <span class="include">java.util.Comparator</span>;
<span class="keyword">import</span> <span class="include">java.util.Currency</span>;
<span class="keyword">import</span> <span class="include">java.util.Date</span>;
<span class="keyword">import</span> <span class="include">java.util.HashMap</span>;
<span class="keyword">import</span> <span class="include">java.util.HashSet</span>;
<span class="keyword">import</span> <span class="include">java.util.LinkedHashMap</span>;
<span class="keyword">import</span> <span class="include">java.util.LinkedHashSet</span>;
<span class="keyword">import</span> <span class="include">java.util.LinkedList</span>;
<span class="keyword">import</span> <span class="include">java.util.List</span>;
<span class="keyword">import</span> <span class="include">java.util.Map</span>;
<span class="keyword">import</span> <span class="include">java.util.Queue</span>;
<span class="keyword">import</span> <span class="include">java.util.Set</span>;
<span class="keyword">import</span> <span class="include">java.util.SortedSet</span>;
<span class="keyword">import</span> <span class="include">java.util.Stack</span>;
<span class="keyword">import</span> <span class="include">java.util.TimeZone</span>;
<span class="keyword">import</span> <span class="include">java.util.TreeSet</span>;
<span class="keyword">import</span> <span class="include">java.util.UUID</span>;
<span class="keyword">import</span> <span class="include">java.util.concurrent.Callable</span>;
<span class="keyword">import</span> <span class="include">java.util.regex.Pattern</span>;

<span class="keyword">import</span> <span class="include">picocli.CommandLine.Help.Ansi.IStyle</span>;
<span class="keyword">import</span> <span class="include">picocli.CommandLine.Help.Ansi.Style</span>;
<span class="keyword">import</span> <span class="include">picocli.CommandLine.Help.Ansi.Text</span>;

<span class="keyword">import</span> <span class="include">static</span> <span class="include">java.util.Locale.ENGLISH</span>;
<span class="keyword">import</span> <span class="include">static</span> <span class="include">picocli.CommandLine.Help.Column.Overflow.SPAN</span>;
<span class="keyword">import</span> <span class="include">static</span> <span class="include">picocli.CommandLine.Help.Column.Overflow.TRUNCATE</span>;
<span class="keyword">import</span> <span class="include">static</span> <span class="include">picocli.CommandLine.Help.Column.Overflow.WRAP</span>;

<span class="comment">/**
 * &lt;p&gt;
 * CommandLine interpreter that uses reflection to initialize an annotated domain object with values obtained from the
 * command line arguments.
 * &lt;/p&gt;&lt;h2&gt;Example&lt;/h2&gt;
 * &lt;pre&gt;import static picocli.CommandLine.*;
 *
 * &amp;#064;Command(header = &quot;Encrypt FILE(s), or standard input, to standard output or to the output file.&quot;,
 *          version = &quot;v1.2.3&quot;)
 * public class Encrypt {
 *
 *     &amp;#064;Parameters(type = File.class, description = &quot;Any number of input files&quot;)
 *     private List&amp;lt;File&amp;gt; files = new ArrayList&amp;lt;File&amp;gt;();
 *
 *     &amp;#064;Option(names = { &quot;-o&quot;, &quot;--out&quot; }, description = &quot;Output file (default: print to console)&quot;)
 *     private File outputFile;
 *
 *     &amp;#064;Option(names = { &quot;-v&quot;, &quot;--verbose&quot;}, description = &quot;Verbosely list files processed&quot;)
 *     private boolean verbose;
 *
 *     &amp;#064;Option(names = { &quot;-h&quot;, &quot;--help&quot;, &quot;-?&quot;, &quot;-help&quot;}, usageHelp = true, description = &quot;Display this help and exit&quot;)
 *     private boolean help;
 *
 *     &amp;#064;Option(names = { &quot;-V&quot;, &quot;--version&quot;}, versionHelp = true, description = &quot;Display version info and exit&quot;)
 *     private boolean versionHelp;
 * }
 * &lt;/pre&gt;
 * &lt;p&gt;
 * Use {@code CommandLine} to initialize a domain object as follows:
 * &lt;/p&gt;&lt;pre&gt;
 * public static void main(String... args) {
 *     Encrypt encrypt = new Encrypt();
 *     try {
 *         List&amp;lt;CommandLine&amp;gt; parsedCommands = new CommandLine(encrypt).parse(args);
 *         if (!CommandLine.printHelpIfRequested(parsedCommands, System.err, Help.Ansi.AUTO)) {
 *             runProgram(encrypt);
 *         }
 *     } catch (ParameterException ex) { // command line arguments could not be parsed
 *         System.err.println(ex.getMessage());
 *         ex.getCommandLine().usage(System.err);
 *     }
 * }
 * &lt;/pre&gt;&lt;p&gt;
 * Invoke the above program with some command line arguments. The below are all equivalent:
 * &lt;/p&gt;
 * &lt;pre&gt;
 * --verbose --out=outfile in1 in2
 * --verbose --out outfile in1 in2
 * -v --out=outfile in1 in2
 * -v -o outfile in1 in2
 * -v -o=outfile in1 in2
 * -vo outfile in1 in2
 * -vo=outfile in1 in2
 * -v -ooutfile in1 in2
 * -vooutfile in1 in2
 * &lt;/pre&gt;
 */</span>
<span class="directive">public</span> <span class="type">class</span> <span class="class">CommandLine</span> {
    <span class="comment">/** This is picocli version {@value}. */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="directive">final</span> <span class="predefined-type">String</span> VERSION = <span class="string"><span class="delimiter">&quot;</span><span class="content">2.3.0</span><span class="delimiter">&quot;</span></span>;

    <span class="directive">private</span> <span class="directive">final</span> Tracer tracer = <span class="keyword">new</span> Tracer();
    <span class="directive">private</span> <span class="directive">final</span> Interpreter interpreter;
    <span class="directive">private</span> <span class="predefined-type">String</span> commandName = Help.DEFAULT_COMMAND_NAME;
    <span class="directive">private</span> <span class="type">boolean</span> stopAtPositional = <span class="predefined-constant">false</span>;
    <span class="directive">private</span> <span class="type">boolean</span> stopAtUnmatched = <span class="predefined-constant">false</span>;
    <span class="directive">private</span> <span class="type">boolean</span> overwrittenOptionsAllowed = <span class="predefined-constant">false</span>;
    <span class="directive">private</span> <span class="type">boolean</span> expandAtFiles = <span class="predefined-constant">true</span>;
    <span class="directive">private</span> <span class="predefined-type">List</span>&lt;<span class="predefined-type">String</span>&gt; unmatchedArguments = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">String</span>&gt;();
    <span class="directive">private</span> <span class="type">boolean</span> unmatchedArgumentsAllowed = <span class="predefined-constant">false</span>;
    <span class="directive">private</span> CommandLine parent;
    <span class="directive">private</span> <span class="type">boolean</span> usageHelpRequested;
    <span class="directive">private</span> <span class="type">boolean</span> versionHelpRequested;
    <span class="directive">private</span> <span class="predefined-type">List</span>&lt;<span class="predefined-type">String</span>&gt; versionLines = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">String</span>&gt;();

    <span class="comment">/**
     * Constructs a new {@code CommandLine} interpreter with the specified annotated object and a default subcommand factory.
     * When the {@link #parse(String...)} method is called, fields of the specified object that are annotated
     * with {@code @Option} or {@code @Parameters} will be initialized based on command line arguments.
     * @param command the object to initialize from the command line arguments
     * @throws InitializationException if the specified command object does not have a {@link Command}, {@link Option} or {@link Parameters} annotation
     */</span>
    <span class="directive">public</span> CommandLine(<span class="predefined-type">Object</span> command) {
        <span class="local-variable">this</span>(command, <span class="keyword">new</span> DefaultFactory());
    }
    <span class="comment">/**
     * Constructs a new {@code CommandLine} interpreter with the specified annotated object and object factory.
     * When the {@link #parse(String...)} method is called, fields of the specified object that are annotated
     * with {@code @Option} or {@code @Parameters} will be initialized based on command line arguments.
     * @param command the object to initialize from the command line arguments
     * @param factory the factory used to create instances of {@linkplain Command#subcommands() subcommands} that are registered declaratively with annotation attributes
     * @throws InitializationException if the specified command object does not have a {@link Command}, {@link Option} or {@link Parameters} annotation
     */</span>
    <span class="directive">public</span> CommandLine(<span class="predefined-type">Object</span> command, IFactory factory) {
        interpreter = <span class="keyword">new</span> Interpreter(command, factory);
    }

    <span class="comment">/** Registers a subcommand with the specified name. For example:
     * &lt;pre&gt;
     * CommandLine commandLine = new CommandLine(new Git())
     *         .addSubcommand(&quot;status&quot;,   new GitStatus())
     *         .addSubcommand(&quot;commit&quot;,   new GitCommit();
     *         .addSubcommand(&quot;add&quot;,      new GitAdd())
     *         .addSubcommand(&quot;branch&quot;,   new GitBranch())
     *         .addSubcommand(&quot;checkout&quot;, new GitCheckout())
     *         //...
     *         ;
     * &lt;/pre&gt;
     *
     * &lt;p&gt;The specified object can be an annotated object or a
     * {@code CommandLine} instance with its own nested subcommands. For example:&lt;/p&gt;
     * &lt;pre&gt;
     * CommandLine commandLine = new CommandLine(new MainCommand())
     *         .addSubcommand(&quot;cmd1&quot;,                 new ChildCommand1()) // subcommand
     *         .addSubcommand(&quot;cmd2&quot;,                 new ChildCommand2())
     *         .addSubcommand(&quot;cmd3&quot;, new CommandLine(new ChildCommand3()) // subcommand with nested sub-subcommands
     *                 .addSubcommand(&quot;cmd3sub1&quot;,                 new GrandChild3Command1())
     *                 .addSubcommand(&quot;cmd3sub2&quot;,                 new GrandChild3Command2())
     *                 .addSubcommand(&quot;cmd3sub3&quot;, new CommandLine(new GrandChild3Command3()) // deeper nesting
     *                         .addSubcommand(&quot;cmd3sub3sub1&quot;, new GreatGrandChild3Command3_1())
     *                         .addSubcommand(&quot;cmd3sub3sub2&quot;, new GreatGrandChild3Command3_2())
     *                 )
     *         );
     * &lt;/pre&gt;
     * &lt;p&gt;The default type converters are available on all subcommands and nested sub-subcommands, but custom type
     * converters are registered only with the subcommand hierarchy as it existed when the custom type was registered.
     * To ensure a custom type converter is available to all subcommands, register the type converter last, after
     * adding subcommands.&lt;/p&gt;
     * &lt;p&gt;See also the {@link Command#subcommands()} annotation to register subcommands declaratively.&lt;/p&gt;
     *
     * @param name the string to recognize on the command line as a subcommand
     * @param command the object to initialize with command line arguments following the subcommand name.
     *          This may be a {@code CommandLine} instance with its own (nested) subcommands
     * @return this CommandLine object, to allow method chaining
     * @see #registerConverter(Class, ITypeConverter)
     * @since 0.9.7
     * @see Command#subcommands()
     */</span>
    <span class="directive">public</span> CommandLine addSubcommand(<span class="predefined-type">String</span> name, <span class="predefined-type">Object</span> command) {
        CommandLine subcommandLine = toCommandLine(command, interpreter.factory);
        subcommandLine.parent = <span class="local-variable">this</span>;
        interpreter.commands.put(name, subcommandLine);
        subcommandLine.interpreter.initParentCommand(<span class="local-variable">this</span>.interpreter.command);
        <span class="keyword">return</span> <span class="local-variable">this</span>;
    }
    <span class="comment">/** Returns a map with the subcommands {@linkplain #addSubcommand(String, Object) registered} on this instance.
     * @return a map with the registered subcommands
     * @since 0.9.7
     */</span>
    <span class="directive">public</span> <span class="predefined-type">Map</span>&lt;<span class="predefined-type">String</span>, CommandLine&gt; getSubcommands() {
        <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">LinkedHashMap</span>&lt;<span class="predefined-type">String</span>, CommandLine&gt;(interpreter.commands);
    }
    <span class="comment">/**
     * Returns the command that this is a subcommand of, or {@code null} if this is a top-level command.
     * @return the command that this is a subcommand of, or {@code null} if this is a top-level command
     * @see #addSubcommand(String, Object)
     * @see Command#subcommands()
     * @since 0.9.8
     */</span>
    <span class="directive">public</span> CommandLine getParent() {
        <span class="keyword">return</span> parent;
    }

    <span class="comment">/** Returns the annotated object that this {@code CommandLine} instance was constructed with.
     * @param &lt;T&gt; the type of the variable that the return value is being assigned to
     * @return the annotated object that this {@code CommandLine} instance was constructed with
     * @since 0.9.7
     */</span>
    <span class="directive">public</span> &lt;T&gt; T getCommand() {
        <span class="keyword">return</span> (T) interpreter.command;
    }

    <span class="comment">/** Returns {@code true} if an option annotated with {@link Option#usageHelp()} was specified on the command line.
     * @return whether the parser encountered an option annotated with {@link Option#usageHelp()}.
     * @since 0.9.8 */</span>
    <span class="directive">public</span> <span class="type">boolean</span> isUsageHelpRequested() { <span class="keyword">return</span> usageHelpRequested; }

    <span class="comment">/** Returns {@code true} if an option annotated with {@link Option#versionHelp()} was specified on the command line.
     * @return whether the parser encountered an option annotated with {@link Option#versionHelp()}.
     * @since 0.9.8 */</span>
    <span class="directive">public</span> <span class="type">boolean</span> isVersionHelpRequested() { <span class="keyword">return</span> versionHelpRequested; }

    <span class="comment">/** Returns whether options for single-value fields can be specified multiple times on the command line.
     * The default is {@code false} and a {@link OverwrittenOptionException} is thrown if this happens.
     * When {@code true}, the last specified value is retained.
     * @return {@code true} if options for single-value fields can be specified multiple times on the command line, {@code false} otherwise
     * @since 0.9.7
     */</span>
    <span class="directive">public</span> <span class="type">boolean</span> isOverwrittenOptionsAllowed() {
        <span class="keyword">return</span> overwrittenOptionsAllowed;
    }

    <span class="comment">/** Sets whether options for single-value fields can be specified multiple times on the command line without a {@link OverwrittenOptionException} being thrown.
     * &lt;p&gt;The specified setting will be registered with this {@code CommandLine} and the full hierarchy of its
     * subcommands and nested sub-subcommands &lt;em&gt;at the moment this method is called&lt;/em&gt;. Subcommands added
     * later will have the default setting. To ensure a setting is applied to all
     * subcommands, call the setter last, after adding subcommands.&lt;/p&gt;
     * @param newValue the new setting
     * @return this {@code CommandLine} object, to allow method chaining
     * @since 0.9.7
     */</span>
    <span class="directive">public</span> CommandLine setOverwrittenOptionsAllowed(<span class="type">boolean</span> newValue) {
        <span class="local-variable">this</span>.overwrittenOptionsAllowed = newValue;
        <span class="keyword">for</span> (CommandLine command : interpreter.commands.values()) {
            command.setOverwrittenOptionsAllowed(newValue);
        }
        <span class="keyword">return</span> <span class="local-variable">this</span>;
    }

    <span class="comment">/** Returns whether the parser interprets the first positional parameter as &quot;end of options&quot; so the remaining
     * arguments are all treated as positional parameters. The default is {@code false}.
     * @return {@code true} if all values following the first positional parameter should be treated as positional parameters, {@code false} otherwise
     * @since 2.3
     */</span>
    <span class="directive">public</span> <span class="type">boolean</span> isStopAtPositional() {
        <span class="keyword">return</span> stopAtPositional;
    }

    <span class="comment">/** Sets whether the parser interprets the first positional parameter as &quot;end of options&quot; so the remaining
     * arguments are all treated as positional parameters. The default is {@code false}.
     * &lt;p&gt;The specified setting will be registered with this {@code CommandLine} and the full hierarchy of its
     * subcommands and nested sub-subcommands &lt;em&gt;at the moment this method is called&lt;/em&gt;. Subcommands added
     * later will have the default setting. To ensure a setting is applied to all
     * subcommands, call the setter last, after adding subcommands.&lt;/p&gt;
     * @param newValue {@code true} if all values following the first positional parameter should be treated as positional parameters, {@code false} otherwise
     * @return this {@code CommandLine} object, to allow method chaining
     * @since 2.3
     */</span>
    <span class="directive">public</span> CommandLine setStopAtPositional(<span class="type">boolean</span> newValue) {
        <span class="local-variable">this</span>.stopAtPositional = newValue;
        <span class="keyword">for</span> (CommandLine command : interpreter.commands.values()) {
            command.setStopAtPositional(newValue);
        }
        <span class="keyword">return</span> <span class="local-variable">this</span>;
    }

    <span class="comment">/** Returns whether the parser should stop interpreting options and positional parameters as soon as it encounters an
     * unmatched option. Unmatched options are arguments that look like an option but are not one of the known options, or
     * positional arguments for which there is no available slots (the command has no positional parameters or their size is limited).
     * The default is {@code false}.
     * &lt;p&gt;Setting this flag to {@code true} automatically sets the {@linkplain #isUnmatchedArgumentsAllowed() unmatchedArgumentsAllowed} flag to {@code true} also.&lt;/p&gt;
     * @return {@code true} when an unmatched option should result in the remaining command line arguments to be added to the
     *      {@linkplain #getUnmatchedArguments() unmatchedArguments list}
     * @since 2.3
     */</span>
    <span class="directive">public</span> <span class="type">boolean</span> isStopAtUnmatched() {
        <span class="keyword">return</span> stopAtUnmatched;
    }

    <span class="comment">/** Sets whether the parser should stop interpreting options and positional parameters as soon as it encounters an
     * unmatched option. Unmatched options are arguments that look like an option but are not one of the known options, or
     * positional arguments for which there is no available slots (the command has no positional parameters or their size is limited).
     * The default is {@code false}.
     * &lt;p&gt;Setting this flag to {@code true} automatically sets the {@linkplain #setUnmatchedArgumentsAllowed(boolean) unmatchedArgumentsAllowed} flag to {@code true} also.&lt;/p&gt;
     * &lt;p&gt;The specified setting will be registered with this {@code CommandLine} and the full hierarchy of its
     * subcommands and nested sub-subcommands &lt;em&gt;at the moment this method is called&lt;/em&gt;. Subcommands added
     * later will have the default setting. To ensure a setting is applied to all
     * subcommands, call the setter last, after adding subcommands.&lt;/p&gt;
     * @param newValue {@code true} when an unmatched option should result in the remaining command line arguments to be added to the
     *      {@linkplain #getUnmatchedArguments() unmatchedArguments list}
     * @return this {@code CommandLine} object, to allow method chaining
     * @since 2.3
     */</span>
    <span class="directive">public</span> CommandLine setStopAtUnmatched(<span class="type">boolean</span> newValue) {
        <span class="local-variable">this</span>.stopAtUnmatched = newValue;
        <span class="keyword">for</span> (CommandLine command : interpreter.commands.values()) {
            command.setStopAtUnmatched(newValue);
        }
        <span class="keyword">if</span> (newValue) { setUnmatchedArgumentsAllowed(<span class="predefined-constant">true</span>); }
        <span class="keyword">return</span> <span class="local-variable">this</span>;
    }

    <span class="comment">/** Returns whether the end user may specify arguments on the command line that are not matched to any option or parameter fields.
     * The default is {@code false} and a {@link UnmatchedArgumentException} is thrown if this happens.
     * When {@code true}, the last unmatched arguments are available via the {@link #getUnmatchedArguments()} method.
     * @return {@code true} if the end use may specify unmatched arguments on the command line, {@code false} otherwise
     * @see #getUnmatchedArguments()
     * @since 0.9.7
     */</span>
    <span class="directive">public</span> <span class="type">boolean</span> isUnmatchedArgumentsAllowed() {
        <span class="keyword">return</span> unmatchedArgumentsAllowed;
    }

    <span class="comment">/** Sets whether the end user may specify unmatched arguments on the command line without a {@link UnmatchedArgumentException} being thrown.
     * &lt;p&gt;The specified setting will be registered with this {@code CommandLine} and the full hierarchy of its
     * subcommands and nested sub-subcommands &lt;em&gt;at the moment this method is called&lt;/em&gt;. Subcommands added
     * later will have the default setting. To ensure a setting is applied to all
     * subcommands, call the setter last, after adding subcommands.&lt;/p&gt;
     * @param newValue the new setting. When {@code true}, the last unmatched arguments are available via the {@link #getUnmatchedArguments()} method.
     * @return this {@code CommandLine} object, to allow method chaining
     * @since 0.9.7
     * @see #getUnmatchedArguments()
     */</span>
    <span class="directive">public</span> CommandLine setUnmatchedArgumentsAllowed(<span class="type">boolean</span> newValue) {
        <span class="local-variable">this</span>.unmatchedArgumentsAllowed = newValue;
        <span class="keyword">for</span> (CommandLine command : interpreter.commands.values()) {
            command.setUnmatchedArgumentsAllowed(newValue);
        }
        <span class="keyword">return</span> <span class="local-variable">this</span>;
    }

    <span class="comment">/** Returns the list of unmatched command line arguments, if any.
     * @return the list of unmatched command line arguments or an empty list
     * @see #isUnmatchedArgumentsAllowed()
     * @since 0.9.7
     */</span>
    <span class="directive">public</span> <span class="predefined-type">List</span>&lt;<span class="predefined-type">String</span>&gt; getUnmatchedArguments() {
        <span class="keyword">return</span> unmatchedArguments;
    }

    <span class="comment">/**
     * &lt;p&gt;
     * Convenience method that initializes the specified annotated object from the specified command line arguments.
     * &lt;/p&gt;&lt;p&gt;
     * This is equivalent to
     * &lt;/p&gt;&lt;pre&gt;
     * CommandLine cli = new CommandLine(command);
     * cli.parse(args);
     * return command;
     * &lt;/pre&gt;
     *
     * @param command the object to initialize. This object contains fields annotated with
     *          {@code @Option} or {@code @Parameters}.
     * @param args the command line arguments to parse
     * @param &lt;T&gt; the type of the annotated object
     * @return the specified annotated object
     * @throws InitializationException if the specified command object does not have a {@link Command}, {@link Option} or {@link Parameters} annotation
     * @throws ParameterException if the specified command line arguments are invalid
     * @since 0.9.7
     */</span>
    <span class="directive">public</span> <span class="directive">static</span> &lt;T&gt; T populateCommand(T command, <span class="predefined-type">String</span>... args) {
        CommandLine cli = toCommandLine(command, <span class="keyword">new</span> DefaultFactory());
        cli.parse(args);
        <span class="keyword">return</span> command;
    }

    <span class="comment">/** Parses the specified command line arguments and returns a list of {@code CommandLine} objects representing the
     * top-level command and any subcommands (if any) that were recognized and initialized during the parsing process.
     * &lt;p&gt;
     * If parsing succeeds, the first element in the returned list is always {@code this CommandLine} object. The
     * returned list may contain more elements if subcommands were {@linkplain #addSubcommand(String, Object) registered}
     * and these subcommands were initialized by matching command line arguments. If parsing fails, a
     * {@link ParameterException} is thrown.
     * &lt;/p&gt;
     *
     * @param args the command line arguments to parse
     * @return a list with the top-level command and any subcommands initialized by this method
     * @throws ParameterException if the specified command line arguments are invalid; use
     *      {@link ParameterException#getCommandLine()} to get the command or subcommand whose user input was invalid
     */</span>
    <span class="directive">public</span> <span class="predefined-type">List</span>&lt;CommandLine&gt; parse(<span class="predefined-type">String</span>... args) {
        <span class="keyword">return</span> interpreter.parse(args);
    }
    <span class="comment">/**
     * Represents a function that can process a List of {@code CommandLine} objects resulting from successfully
     * {@linkplain #parse(String...) parsing} the command line arguments. This is a
     * &lt;a href=&quot;https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html&quot;&gt;functional interface&lt;/a&gt;
     * whose functional method is {@link #handleParseResult(List, PrintStream, CommandLine.Help.Ansi)}.
     * &lt;p&gt;
     * Implementations of this functions can be passed to the {@link #parseWithHandlers(IParseResultHandler, PrintStream, Help.Ansi, IExceptionHandler, String...) CommandLine::parseWithHandler}
     * methods to take some next step after the command line was successfully parsed.
     * &lt;/p&gt;
     * @see RunFirst
     * @see RunLast
     * @see RunAll
     * @since 2.0 */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">interface</span> <span class="class">IParseResultHandler</span> {
        <span class="comment">/** Processes a List of {@code CommandLine} objects resulting from successfully
         * {@linkplain #parse(String...) parsing} the command line arguments and optionally returns a list of results.
         * @param parsedCommands the {@code CommandLine} objects that resulted from successfully parsing the command line arguments
         * @param out the {@code PrintStream} to print help to if requested
         * @param ansi for printing help messages using ANSI styles and colors
         * @return a list of results, or an empty list if there are no results
         * @throws ExecutionException if a problem occurred while processing the parse results; use
         *      {@link ExecutionException#getCommandLine()} to get the command or subcommand where processing failed
         */</span>
        <span class="predefined-type">List</span>&lt;<span class="predefined-type">Object</span>&gt; handleParseResult(<span class="predefined-type">List</span>&lt;CommandLine&gt; parsedCommands, <span class="predefined-type">PrintStream</span> out, Help.Ansi ansi) <span class="directive">throws</span> <span class="exception">ExecutionException</span>;
    }
    <span class="comment">/**
     * Represents a function that can handle a {@code ParameterException} that occurred while
     * {@linkplain #parse(String...) parsing} the command line arguments. This is a
     * &lt;a href=&quot;https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html&quot;&gt;functional interface&lt;/a&gt;
     * whose functional method is {@link #handleException(CommandLine.ParameterException, PrintStream, CommandLine.Help.Ansi, String...)}.
     * &lt;p&gt;
     * Implementations of this functions can be passed to the {@link #parseWithHandlers(IParseResultHandler, PrintStream, Help.Ansi, IExceptionHandler, String...) CommandLine::parseWithHandler}
     * methods to handle situations when the command line could not be parsed.
     * &lt;/p&gt;
     * @see DefaultExceptionHandler
     * @since 2.0 */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">interface</span> <span class="class">IExceptionHandler</span> {
        <span class="comment">/** Handles a {@code ParameterException} that occurred while {@linkplain #parse(String...) parsing} the command
         * line arguments and optionally returns a list of results.
         * @param ex the ParameterException describing the problem that occurred while parsing the command line arguments,
         *           and the CommandLine representing the command or subcommand whose input was invalid
         * @param out the {@code PrintStream} to print help to if requested
         * @param ansi for printing help messages using ANSI styles and colors
         * @param args the command line arguments that could not be parsed
         * @return a list of results, or an empty list if there are no results
         */</span>
        <span class="predefined-type">List</span>&lt;<span class="predefined-type">Object</span>&gt; handleException(ParameterException ex, <span class="predefined-type">PrintStream</span> out, Help.Ansi ansi, <span class="predefined-type">String</span>... args);
    }
    <span class="comment">/**
     * Default exception handler that prints the exception message to the specified {@code PrintStream}, followed by the
     * usage message for the command or subcommand whose input was invalid.
     * &lt;p&gt;Implementation roughly looks like this:&lt;/p&gt;
     * &lt;pre&gt;
     *     System.err.println(paramException.getMessage());
     *     paramException.getCommandLine().usage(System.err);
     * &lt;/pre&gt;
     * @since 2.0 */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">DefaultExceptionHandler</span> <span class="directive">implements</span> IExceptionHandler {
        <span class="directive">public</span> <span class="predefined-type">List</span>&lt;<span class="predefined-type">Object</span>&gt; handleException(ParameterException ex, <span class="predefined-type">PrintStream</span> out, Help.Ansi ansi, <span class="predefined-type">String</span>... args) {
            out.println(ex.getMessage());
            ex.getCommandLine().usage(out, ansi);
            <span class="keyword">return</span> <span class="predefined-type">Collections</span>.emptyList();
        }
    }
    <span class="comment">/**
     * Helper method that may be useful when processing the list of {@code CommandLine} objects that result from successfully
     * {@linkplain #parse(String...) parsing} command line arguments. This method prints out
     * {@linkplain #usage(PrintStream, Help.Ansi) usage help} if {@linkplain #isUsageHelpRequested() requested}
     * or {@linkplain #printVersionHelp(PrintStream, Help.Ansi) version help} if {@linkplain #isVersionHelpRequested() requested}
     * and returns {@code true}. Otherwise, if none of the specified {@code CommandLine} objects have help requested,
     * this method returns {@code false}.
     * &lt;p&gt;
     * Note that this method &lt;em&gt;only&lt;/em&gt; looks at the {@link Option#usageHelp() usageHelp} and
     * {@link Option#versionHelp() versionHelp} attributes. The {@link Option#help() help} attribute is ignored.
     * &lt;/p&gt;
     * @param parsedCommands the list of {@code CommandLine} objects to check if help was requested
     * @param out the {@code PrintStream} to print help to if requested
     * @param ansi for printing help messages using ANSI styles and colors
     * @return {@code true} if help was printed, {@code false} otherwise
     * @since 2.0 */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">boolean</span> printHelpIfRequested(<span class="predefined-type">List</span>&lt;CommandLine&gt; parsedCommands, <span class="predefined-type">PrintStream</span> out, Help.Ansi ansi) {
        <span class="keyword">for</span> (CommandLine parsed : parsedCommands) {
            <span class="keyword">if</span> (parsed.isUsageHelpRequested()) {
                parsed.usage(out, ansi);
                <span class="keyword">return</span> <span class="predefined-constant">true</span>;
            } <span class="keyword">else</span> <span class="keyword">if</span> (parsed.isVersionHelpRequested()) {
                parsed.printVersionHelp(out, ansi);
                <span class="keyword">return</span> <span class="predefined-constant">true</span>;
            }
        }
        <span class="keyword">return</span> <span class="predefined-constant">false</span>;
    }
    <span class="directive">private</span> <span class="directive">static</span> <span class="predefined-type">Object</span> execute(CommandLine parsed) {
        <span class="predefined-type">Object</span> command = parsed.getCommand();
        <span class="keyword">if</span> (command <span class="keyword">instanceof</span> <span class="predefined-type">Runnable</span>) {
            <span class="keyword">try</span> {
                ((<span class="predefined-type">Runnable</span>) command).run();
                <span class="keyword">return</span> <span class="predefined-constant">null</span>;
            } <span class="keyword">catch</span> (<span class="exception">Exception</span> ex) {
                <span class="keyword">throw</span> <span class="keyword">new</span> <span class="exception">ExecutionException</span>(parsed, <span class="string"><span class="delimiter">&quot;</span><span class="content">Error while running command (</span><span class="delimiter">&quot;</span></span> + command + <span class="string"><span class="delimiter">&quot;</span><span class="content">): </span><span class="delimiter">&quot;</span></span> + ex, ex);
            }
        } <span class="keyword">else</span> <span class="keyword">if</span> (command <span class="keyword">instanceof</span> <span class="predefined-type">Callable</span>) {
            <span class="keyword">try</span> {
                <span class="keyword">return</span> ((<span class="predefined-type">Callable</span>&lt;<span class="predefined-type">Object</span>&gt;) command).call();
            } <span class="keyword">catch</span> (<span class="exception">Exception</span> ex) {
                <span class="keyword">throw</span> <span class="keyword">new</span> <span class="exception">ExecutionException</span>(parsed, <span class="string"><span class="delimiter">&quot;</span><span class="content">Error while calling command (</span><span class="delimiter">&quot;</span></span> + command + <span class="string"><span class="delimiter">&quot;</span><span class="content">): </span><span class="delimiter">&quot;</span></span> + ex, ex);
            }
        }
        <span class="keyword">throw</span> <span class="keyword">new</span> <span class="exception">ExecutionException</span>(parsed, <span class="string"><span class="delimiter">&quot;</span><span class="content">Parsed command (</span><span class="delimiter">&quot;</span></span> + command + <span class="string"><span class="delimiter">&quot;</span><span class="content">) is not Runnable or Callable</span><span class="delimiter">&quot;</span></span>);
    }
    <span class="comment">/**
     * Command line parse result handler that prints help if requested, and otherwise executes the top-level
     * {@code Runnable} or {@code Callable} command.
     * For use in the {@link #parseWithHandlers(IParseResultHandler, PrintStream, Help.Ansi, IExceptionHandler, String...) parseWithHandler} methods.
     * &lt;p&gt;
     * From picocli v2.0, {@code RunFirst} is used to implement the {@link #run(Runnable, PrintStream, Help.Ansi, String...) run}
     * and {@link #call(Callable, PrintStream, Help.Ansi, String...) call} convenience methods.
     * &lt;/p&gt;
     * @since 2.0 */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">RunFirst</span> <span class="directive">implements</span> IParseResultHandler {
        <span class="comment">/** Prints help if requested, and otherwise executes the top-level {@code Runnable} or {@code Callable} command.
         * If the top-level command does not implement either {@code Runnable} or {@code Callable}, a {@code ExecutionException}
         * is thrown detailing the problem and capturing the offending {@code CommandLine} object.
         *
         * @param parsedCommands the {@code CommandLine} objects that resulted from successfully parsing the command line arguments
         * @param out the {@code PrintStream} to print help to if requested
         * @param ansi for printing help messages using ANSI styles and colors
         * @return an empty list if help was requested, or a list containing a single element: the result of calling the
         *      {@code Callable}, or a {@code null} element if the top-level command was a {@code Runnable}
         * @throws ExecutionException if a problem occurred while processing the parse results; use
         *      {@link ExecutionException#getCommandLine()} to get the command or subcommand where processing failed
         */</span>
        <span class="directive">public</span> <span class="predefined-type">List</span>&lt;<span class="predefined-type">Object</span>&gt; handleParseResult(<span class="predefined-type">List</span>&lt;CommandLine&gt; parsedCommands, <span class="predefined-type">PrintStream</span> out, Help.Ansi ansi) {
            <span class="keyword">if</span> (printHelpIfRequested(parsedCommands, out, ansi)) { <span class="keyword">return</span> <span class="predefined-type">Collections</span>.emptyList(); }
            <span class="keyword">return</span> <span class="predefined-type">Arrays</span>.asList(execute(parsedCommands.get(<span class="integer">0</span>)));
        }
    }
    <span class="comment">/**
     * Command line parse result handler that prints help if requested, and otherwise executes the most specific
     * {@code Runnable} or {@code Callable} subcommand.
     * For use in the {@link #parseWithHandlers(IParseResultHandler, PrintStream, Help.Ansi, IExceptionHandler, String...) parseWithHandler} methods.
     * &lt;p&gt;
     * Something like this:&lt;/p&gt;
     * &lt;pre&gt;
     *     // RunLast implementation: print help if requested, otherwise execute the most specific subcommand
     *     if (CommandLine.printHelpIfRequested(parsedCommands, System.err, Help.Ansi.AUTO)) {
     *         return emptyList();
     *     }
     *     CommandLine last = parsedCommands.get(parsedCommands.size() - 1);
     *     Object command = last.getCommand();
     *     if (command instanceof Runnable) {
     *         try {
     *             ((Runnable) command).run();
     *         } catch (Exception ex) {
     *             throw new ExecutionException(last, &quot;Error in runnable &quot; + command, ex);
     *         }
     *     } else if (command instanceof Callable) {
     *         Object result;
     *         try {
     *             result = ((Callable) command).call();
     *         } catch (Exception ex) {
     *             throw new ExecutionException(last, &quot;Error in callable &quot; + command, ex);
     *         }
     *         // ...do something with result
     *     } else {
     *         throw new ExecutionException(last, &quot;Parsed command (&quot; + command + &quot;) is not Runnable or Callable&quot;);
     *     }
     * &lt;/pre&gt;
     * @since 2.0 */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">RunLast</span> <span class="directive">implements</span> IParseResultHandler {
        <span class="comment">/** Prints help if requested, and otherwise executes the most specific {@code Runnable} or {@code Callable} subcommand.
         * If the last (sub)command does not implement either {@code Runnable} or {@code Callable}, a {@code ExecutionException}
         * is thrown detailing the problem and capturing the offending {@code CommandLine} object.
         *
         * @param parsedCommands the {@code CommandLine} objects that resulted from successfully parsing the command line arguments
         * @param out the {@code PrintStream} to print help to if requested
         * @param ansi for printing help messages using ANSI styles and colors
         * @return an empty list if help was requested, or a list containing a single element: the result of calling the
         *      {@code Callable}, or a {@code null} element if the last (sub)command was a {@code Runnable}
         * @throws ExecutionException if a problem occurred while processing the parse results; use
         *      {@link ExecutionException#getCommandLine()} to get the command or subcommand where processing failed
         */</span>
        <span class="directive">public</span> <span class="predefined-type">List</span>&lt;<span class="predefined-type">Object</span>&gt; handleParseResult(<span class="predefined-type">List</span>&lt;CommandLine&gt; parsedCommands, <span class="predefined-type">PrintStream</span> out, Help.Ansi ansi) {
            <span class="keyword">if</span> (printHelpIfRequested(parsedCommands, out, ansi)) { <span class="keyword">return</span> <span class="predefined-type">Collections</span>.emptyList(); }
            CommandLine last = parsedCommands.get(parsedCommands.size() - <span class="integer">1</span>);
            <span class="keyword">return</span> <span class="predefined-type">Arrays</span>.asList(execute(last));
        }
    }
    <span class="comment">/**
     * Command line parse result handler that prints help if requested, and otherwise executes the top-level command and
     * all subcommands as {@code Runnable} or {@code Callable}.
     * For use in the {@link #parseWithHandlers(IParseResultHandler, PrintStream, Help.Ansi, IExceptionHandler, String...) parseWithHandler} methods.
     * @since 2.0 */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">RunAll</span> <span class="directive">implements</span> IParseResultHandler {
        <span class="comment">/** Prints help if requested, and otherwise executes the top-level command and all subcommands as {@code Runnable}
         * or {@code Callable}. If any of the {@code CommandLine} commands does not implement either
         * {@code Runnable} or {@code Callable}, a {@code ExecutionException}
         * is thrown detailing the problem and capturing the offending {@code CommandLine} object.
         *
         * @param parsedCommands the {@code CommandLine} objects that resulted from successfully parsing the command line arguments
         * @param out the {@code PrintStream} to print help to if requested
         * @param ansi for printing help messages using ANSI styles and colors
         * @return an empty list if help was requested, or a list containing the result of executing all commands:
         *      the return values from calling the {@code Callable} commands, {@code null} elements for commands that implement {@code Runnable}
         * @throws ExecutionException if a problem occurred while processing the parse results; use
         *      {@link ExecutionException#getCommandLine()} to get the command or subcommand where processing failed
         */</span>
        <span class="directive">public</span> <span class="predefined-type">List</span>&lt;<span class="predefined-type">Object</span>&gt; handleParseResult(<span class="predefined-type">List</span>&lt;CommandLine&gt; parsedCommands, <span class="predefined-type">PrintStream</span> out, Help.Ansi ansi) {
            <span class="keyword">if</span> (printHelpIfRequested(parsedCommands, out, ansi)) {
                <span class="keyword">return</span> <span class="predefined-type">Collections</span>.emptyList();
            }
            <span class="predefined-type">List</span>&lt;<span class="predefined-type">Object</span>&gt; result = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">Object</span>&gt;();
            <span class="keyword">for</span> (CommandLine parsed : parsedCommands) {
                result.add(execute(parsed));
            }
            <span class="keyword">return</span> result;
        }
    }
    <span class="comment">/**
     * Returns the result of calling {@link #parseWithHandlers(IParseResultHandler, PrintStream, Help.Ansi, IExceptionHandler, String...)}
     * with {@code Help.Ansi.AUTO} and a new {@link DefaultExceptionHandler} in addition to the specified parse result handler,
     * {@code PrintStream}, and the specified command line arguments.
     * &lt;p&gt;
     * This is a convenience method intended to offer the same ease of use as the {@link #run(Runnable, PrintStream, Help.Ansi, String...) run}
     * and {@link #call(Callable, PrintStream, Help.Ansi, String...) call} methods, but with more flexibility and better
     * support for nested subcommands.
     * &lt;/p&gt;
     * &lt;p&gt;Calling this method roughly expands to:&lt;/p&gt;
     * &lt;pre&gt;
     * try {
     *     List&amp;lt;CommandLine&amp;gt; parsedCommands = parse(args);
     *     return parseResultsHandler.handleParseResult(parsedCommands, out, Help.Ansi.AUTO);
     * } catch (ParameterException ex) {
     *     return new DefaultExceptionHandler().handleException(ex, out, ansi, args);
     * }
     * &lt;/pre&gt;
     * &lt;p&gt;
     * Picocli provides some default handlers that allow you to accomplish some common tasks with very little code.
     * The following handlers are available:&lt;/p&gt;
     * &lt;ul&gt;
     *   &lt;li&gt;{@link RunLast} handler prints help if requested, and otherwise gets the last specified command or subcommand
     * and tries to execute it as a {@code Runnable} or {@code Callable}.&lt;/li&gt;
     *   &lt;li&gt;{@link RunFirst} handler prints help if requested, and otherwise executes the top-level command as a {@code Runnable} or {@code Callable}.&lt;/li&gt;
     *   &lt;li&gt;{@link RunAll} handler prints help if requested, and otherwise executes all recognized commands and subcommands as {@code Runnable} or {@code Callable} tasks.&lt;/li&gt;
     *   &lt;li&gt;{@link DefaultExceptionHandler} prints the error message followed by usage help&lt;/li&gt;
     * &lt;/ul&gt;
     * @param handler the function that will process the result of successfully parsing the command line arguments
     * @param out the {@code PrintStream} to print help to if requested
     * @param args the command line arguments
     * @return a list of results, or an empty list if there are no results
     * @throws ExecutionException if the command line arguments were parsed successfully but a problem occurred while processing the
     *      parse results; use {@link ExecutionException#getCommandLine()} to get the command or subcommand where processing failed
     * @see RunLast
     * @see RunAll
     * @since 2.0 */</span>
    <span class="directive">public</span> <span class="predefined-type">List</span>&lt;<span class="predefined-type">Object</span>&gt; parseWithHandler(IParseResultHandler handler, <span class="predefined-type">PrintStream</span> out, <span class="predefined-type">String</span>... args) {
        <span class="keyword">return</span> parseWithHandlers(handler, out, Help.Ansi.AUTO, <span class="keyword">new</span> DefaultExceptionHandler(), args);
    }
    <span class="comment">/**
     * Tries to {@linkplain #parse(String...) parse} the specified command line arguments, and if successful, delegates
     * the processing of the resulting list of {@code CommandLine} objects to the specified {@linkplain IParseResultHandler handler}.
     * If the command line arguments were invalid, the {@code ParameterException} thrown from the {@code parse} method
     * is caught and passed to the specified {@link IExceptionHandler}.
     * &lt;p&gt;
     * This is a convenience method intended to offer the same ease of use as the {@link #run(Runnable, PrintStream, Help.Ansi, String...) run}
     * and {@link #call(Callable, PrintStream, Help.Ansi, String...) call} methods, but with more flexibility and better
     * support for nested subcommands.
     * &lt;/p&gt;
     * &lt;p&gt;Calling this method roughly expands to:&lt;/p&gt;
     * &lt;pre&gt;
     * try {
     *     List&amp;lt;CommandLine&amp;gt; parsedCommands = parse(args);
     *     return parseResultsHandler.handleParseResult(parsedCommands, out, ansi);
     * } catch (ParameterException ex) {
     *     return new exceptionHandler.handleException(ex, out, ansi, args);
     * }
     * &lt;/pre&gt;
     * &lt;p&gt;
     * Picocli provides some default handlers that allow you to accomplish some common tasks with very little code.
     * The following handlers are available:&lt;/p&gt;
     * &lt;ul&gt;
     *   &lt;li&gt;{@link RunLast} handler prints help if requested, and otherwise gets the last specified command or subcommand
     * and tries to execute it as a {@code Runnable} or {@code Callable}.&lt;/li&gt;
     *   &lt;li&gt;{@link RunFirst} handler prints help if requested, and otherwise executes the top-level command as a {@code Runnable} or {@code Callable}.&lt;/li&gt;
     *   &lt;li&gt;{@link RunAll} handler prints help if requested, and otherwise executes all recognized commands and subcommands as {@code Runnable} or {@code Callable} tasks.&lt;/li&gt;
     *   &lt;li&gt;{@link DefaultExceptionHandler} prints the error message followed by usage help&lt;/li&gt;
     * &lt;/ul&gt;
     *
     * @param handler the function that will process the result of successfully parsing the command line arguments
     * @param out the {@code PrintStream} to print help to if requested
     * @param ansi for printing help messages using ANSI styles and colors
     * @param exceptionHandler the function that can handle the {@code ParameterException} thrown when the command line arguments are invalid
     * @param args the command line arguments
     * @return a list of results produced by the {@code IParseResultHandler} or the {@code IExceptionHandler}, or an empty list if there are no results
     * @throws ExecutionException if the command line arguments were parsed successfully but a problem occurred while processing the parse
     *      result {@code CommandLine} objects; use {@link ExecutionException#getCommandLine()} to get the command or subcommand where processing failed
     * @see RunLast
     * @see RunAll
     * @see DefaultExceptionHandler
     * @since 2.0 */</span>
    <span class="directive">public</span> <span class="predefined-type">List</span>&lt;<span class="predefined-type">Object</span>&gt; parseWithHandlers(IParseResultHandler handler, <span class="predefined-type">PrintStream</span> out, Help.Ansi ansi, IExceptionHandler exceptionHandler, <span class="predefined-type">String</span>... args) {
        <span class="keyword">try</span> {
            <span class="predefined-type">List</span>&lt;CommandLine&gt; result = parse(args);
            <span class="keyword">return</span> handler.handleParseResult(result, out, ansi);
        } <span class="keyword">catch</span> (ParameterException ex) {
            <span class="keyword">return</span> exceptionHandler.handleException(ex, out, ansi, args);
        }
    }
    <span class="comment">/**
     * Equivalent to {@code new CommandLine(command).usage(out)}. See {@link #usage(PrintStream)} for details.
     * @param command the object annotated with {@link Command}, {@link Option} and {@link Parameters}
     * @param out the print stream to print the help message to
     * @throws IllegalArgumentException if the specified command object does not have a {@link Command}, {@link Option} or {@link Parameters} annotation
     */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">void</span> usage(<span class="predefined-type">Object</span> command, <span class="predefined-type">PrintStream</span> out) {
        toCommandLine(command, <span class="keyword">new</span> DefaultFactory()).usage(out);
    }

    <span class="comment">/**
     * Equivalent to {@code new CommandLine(command).usage(out, ansi)}.
     * See {@link #usage(PrintStream, Help.Ansi)} for details.
     * @param command the object annotated with {@link Command}, {@link Option} and {@link Parameters}
     * @param out the print stream to print the help message to
     * @param ansi whether the usage message should contain ANSI escape codes or not
     * @throws IllegalArgumentException if the specified command object does not have a {@link Command}, {@link Option} or {@link Parameters} annotation
     */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">void</span> usage(<span class="predefined-type">Object</span> command, <span class="predefined-type">PrintStream</span> out, Help.Ansi ansi) {
        toCommandLine(command, <span class="keyword">new</span> DefaultFactory()).usage(out, ansi);
    }

    <span class="comment">/**
     * Equivalent to {@code new CommandLine(command).usage(out, colorScheme)}.
     * See {@link #usage(PrintStream, Help.ColorScheme)} for details.
     * @param command the object annotated with {@link Command}, {@link Option} and {@link Parameters}
     * @param out the print stream to print the help message to
     * @param colorScheme the {@code ColorScheme} defining the styles for options, parameters and commands when ANSI is enabled
     * @throws IllegalArgumentException if the specified command object does not have a {@link Command}, {@link Option} or {@link Parameters} annotation
     */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">void</span> usage(<span class="predefined-type">Object</span> command, <span class="predefined-type">PrintStream</span> out, Help.ColorScheme colorScheme) {
        toCommandLine(command, <span class="keyword">new</span> DefaultFactory()).usage(out, colorScheme);
    }

    <span class="comment">/**
     * Delegates to {@link #usage(PrintStream, Help.Ansi)} with the {@linkplain Help.Ansi#AUTO platform default}.
     * @param out the printStream to print to
     * @see #usage(PrintStream, Help.ColorScheme)
     */</span>
    <span class="directive">public</span> <span class="type">void</span> usage(<span class="predefined-type">PrintStream</span> out) {
        usage(out, Help.Ansi.AUTO);
    }

    <span class="comment">/**
     * Delegates to {@link #usage(PrintStream, Help.ColorScheme)} with the {@linkplain Help#defaultColorScheme(CommandLine.Help.Ansi) default color scheme}.
     * @param out the printStream to print to
     * @param ansi whether the usage message should include ANSI escape codes or not
     * @see #usage(PrintStream, Help.ColorScheme)
     */</span>
    <span class="directive">public</span> <span class="type">void</span> usage(<span class="predefined-type">PrintStream</span> out, Help.Ansi ansi) {
        usage(out, Help.defaultColorScheme(ansi));
    }
    <span class="comment">/**
     * Prints a usage help message for the annotated command class to the specified {@code PrintStream}.
     * Delegates construction of the usage help message to the {@link Help} inner class and is equivalent to:
     * &lt;pre&gt;
     * Help help = new Help(command).addAllSubcommands(getSubcommands());
     * StringBuilder sb = new StringBuilder()
     *         .append(help.headerHeading())
     *         .append(help.header())
     *         .append(help.synopsisHeading())      //e.g. Usage:
     *         .append(help.synopsis())             //e.g. &amp;lt;main class&amp;gt; [OPTIONS] &amp;lt;command&amp;gt; [COMMAND-OPTIONS] [ARGUMENTS]
     *         .append(help.descriptionHeading())   //e.g. %nDescription:%n%n
     *         .append(help.description())          //e.g. {&quot;Converts foos to bars.&quot;, &quot;Use options to control conversion mode.&quot;}
     *         .append(help.parameterListHeading()) //e.g. %nPositional parameters:%n%n
     *         .append(help.parameterList())        //e.g. [FILE...] the files to convert
     *         .append(help.optionListHeading())    //e.g. %nOptions:%n%n
     *         .append(help.optionList())           //e.g. -h, --help   displays this help and exits
     *         .append(help.commandListHeading())   //e.g. %nCommands:%n%n
     *         .append(help.commandList())          //e.g.    add       adds the frup to the frooble
     *         .append(help.footerHeading())
     *         .append(help.footer());
     * out.print(sb);
     * &lt;/pre&gt;
     * &lt;p&gt;Annotate your class with {@link Command} to control many aspects of the usage help message, including
     * the program name, text of section headings and section contents, and some aspects of the auto-generated sections
     * of the usage help message.
     * &lt;p&gt;To customize the auto-generated sections of the usage help message, like how option details are displayed,
     * instantiate a {@link Help} object and use a {@link Help.TextTable} with more of fewer columns, a custom
     * {@linkplain Help.Layout layout}, and/or a custom option {@linkplain Help.IOptionRenderer renderer}
     * for ultimate control over which aspects of an Option or Field are displayed where.&lt;/p&gt;
     * @param out the {@code PrintStream} to print the usage help message to
     * @param colorScheme the {@code ColorScheme} defining the styles for options, parameters and commands when ANSI is enabled
     */</span>
    <span class="directive">public</span> <span class="type">void</span> usage(<span class="predefined-type">PrintStream</span> out, Help.ColorScheme colorScheme) {
        Help help = <span class="keyword">new</span> Help(interpreter.command, colorScheme).addAllSubcommands(getSubcommands());
        <span class="keyword">if</span> (!Help.DEFAULT_SEPARATOR.equals(getSeparator())) {
            help.separator = getSeparator();
            help.parameterLabelRenderer = help.createDefaultParamLabelRenderer(); <span class="comment">// update for new separator</span>
        }
        <span class="keyword">if</span> (!Help.DEFAULT_COMMAND_NAME.equals(getCommandName())) {
            help.commandName = getCommandName();
        }
        <span class="predefined-type">StringBuilder</span> sb = <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>()
                .append(help.headerHeading())
                .append(help.header())
                .append(help.synopsisHeading())      <span class="comment">//e.g. Usage:</span>
                .append(help.synopsis(help.synopsisHeadingLength())) <span class="comment">//e.g. &amp;lt;main class&amp;gt; [OPTIONS] &amp;lt;command&amp;gt; [COMMAND-OPTIONS] [ARGUMENTS]</span>
                .append(help.descriptionHeading())   <span class="comment">//e.g. %nDescription:%n%n</span>
                .append(help.description())          <span class="comment">//e.g. {&quot;Converts foos to bars.&quot;, &quot;Use options to control conversion mode.&quot;}</span>
                .append(help.parameterListHeading()) <span class="comment">//e.g. %nPositional parameters:%n%n</span>
                .append(help.parameterList())        <span class="comment">//e.g. [FILE...] the files to convert</span>
                .append(help.optionListHeading())    <span class="comment">//e.g. %nOptions:%n%n</span>
                .append(help.optionList())           <span class="comment">//e.g. -h, --help   displays this help and exits</span>
                .append(help.commandListHeading())   <span class="comment">//e.g. %nCommands:%n%n</span>
                .append(help.commandList())          <span class="comment">//e.g.    add       adds the frup to the frooble</span>
                .append(help.footerHeading())
                .append(help.footer());
        out.print(sb);
    }

    <span class="comment">/**
     * Delegates to {@link #printVersionHelp(PrintStream, Help.Ansi)} with the {@linkplain Help.Ansi#AUTO platform default}.
     * @param out the printStream to print to
     * @see #printVersionHelp(PrintStream, Help.Ansi)
     * @since 0.9.8
     */</span>
    <span class="directive">public</span> <span class="type">void</span> printVersionHelp(<span class="predefined-type">PrintStream</span> out) { printVersionHelp(out, Help.Ansi.AUTO); }

    <span class="comment">/**
     * Prints version information from the {@link Command#version()} annotation to the specified {@code PrintStream}.
     * Each element of the array of version strings is printed on a separate line. Version strings may contain
     * &lt;a href=&quot;http://picocli.info/#_usage_help_with_styles_and_colors&quot;&gt;markup for colors and style&lt;/a&gt;.
     * @param out the printStream to print to
     * @param ansi whether the usage message should include ANSI escape codes or not
     * @see Command#version()
     * @see Option#versionHelp()
     * @see #isVersionHelpRequested()
     * @since 0.9.8
     */</span>
    <span class="directive">public</span> <span class="type">void</span> printVersionHelp(<span class="predefined-type">PrintStream</span> out, Help.Ansi ansi) {
        <span class="keyword">for</span> (<span class="predefined-type">String</span> versionInfo : versionLines) {
            out.println(ansi.new Text(versionInfo));
        }
    }
    <span class="comment">/**
     * Prints version information from the {@link Command#version()} annotation to the specified {@code PrintStream}.
     * Each element of the array of version strings is {@linkplain String#format(String, Object...) formatted} with the
     * specified parameters, and printed on a separate line. Both version strings and parameters may contain
     * &lt;a href=&quot;http://picocli.info/#_usage_help_with_styles_and_colors&quot;&gt;markup for colors and style&lt;/a&gt;.
     * @param out the printStream to print to
     * @param ansi whether the usage message should include ANSI escape codes or not
     * @param params Arguments referenced by the format specifiers in the version strings
     * @see Command#version()
     * @see Option#versionHelp()
     * @see #isVersionHelpRequested()
     * @since 1.0.0
     */</span>
    <span class="directive">public</span> <span class="type">void</span> printVersionHelp(<span class="predefined-type">PrintStream</span> out, Help.Ansi ansi, <span class="predefined-type">Object</span>... params) {
        <span class="keyword">for</span> (<span class="predefined-type">String</span> versionInfo : versionLines) {
            out.println(ansi.new Text(<span class="predefined-type">String</span>.format(versionInfo, params)));
        }
    }

    <span class="comment">/**
     * Delegates to {@link #call(Callable, PrintStream, Help.Ansi, String...)} with {@link Help.Ansi#AUTO}.
     * &lt;p&gt;
     * From picocli v2.0, this method prints usage help or version help if {@linkplain #printHelpIfRequested(List, PrintStream, Help.Ansi) requested},
     * and any exceptions thrown by the {@code Callable} are caught and rethrown wrapped in an {@code ExecutionException}.
     * &lt;/p&gt;
     * @param callable the command to call when {@linkplain #parse(String...) parsing} succeeds.
     * @param out the printStream to print to
     * @param args the command line arguments to parse
     * @param &lt;C&gt; the annotated object must implement Callable
     * @param &lt;T&gt; the return type of the most specific command (must implement {@code Callable})
     * @see #call(Callable, PrintStream, Help.Ansi, String...)
     * @throws InitializationException if the specified command object does not have a {@link Command}, {@link Option} or {@link Parameters} annotation
     * @throws ExecutionException if the Callable throws an exception
     * @return {@code null} if an error occurred while parsing the command line options, otherwise returns the result of calling the Callable
     * @see #parseWithHandlers(IParseResultHandler, PrintStream, Help.Ansi, IExceptionHandler, String...)
     * @see RunFirst
     */</span>
    <span class="directive">public</span> <span class="directive">static</span> &lt;C <span class="directive">extends</span> <span class="predefined-type">Callable</span>&lt;T&gt;, T&gt; T call(C callable, <span class="predefined-type">PrintStream</span> out, <span class="predefined-type">String</span>... args) {
        <span class="keyword">return</span> call(callable, out, Help.Ansi.AUTO, args);
    }
    <span class="comment">/**
     * Convenience method to allow command line application authors to avoid some boilerplate code in their application.
     * The annotated object needs to implement {@link Callable}. Calling this method is equivalent to:
     * &lt;pre&gt;
     * CommandLine cmd = new CommandLine(callable);
     * List&amp;lt;CommandLine&amp;gt; parsedCommands;
     * try {
     *     parsedCommands = cmd.parse(args);
     * } catch (ParameterException ex) {
     *     out.println(ex.getMessage());
     *     cmd.usage(out, ansi);
     *     return null;
     * }
     * if (CommandLine.printHelpIfRequested(parsedCommands, out, ansi)) {
     *     return null;
     * }
     * CommandLine last = parsedCommands.get(parsedCommands.size() - 1);
     * try {
     *     Callable&amp;lt;Object&amp;gt; subcommand = last.getCommand();
     *     return subcommand.call();
     * } catch (Exception ex) {
     *     throw new ExecutionException(last, &quot;Error calling &quot; + last.getCommand(), ex);
     * }
     * &lt;/pre&gt;
     * &lt;p&gt;
     * If the specified Callable command has subcommands, the {@linkplain RunLast last} subcommand specified on the
     * command line is executed.
     * Commands with subcommands may be interested in calling the {@link #parseWithHandler(IParseResultHandler, PrintStream, String...) parseWithHandler}
     * method with a {@link RunAll} handler or a custom handler.
     * &lt;/p&gt;&lt;p&gt;
     * From picocli v2.0, this method prints usage help or version help if {@linkplain #printHelpIfRequested(List, PrintStream, Help.Ansi) requested},
     * and any exceptions thrown by the {@code Callable} are caught and rethrown wrapped in an {@code ExecutionException}.
     * &lt;/p&gt;
     * @param callable the command to call when {@linkplain #parse(String...) parsing} succeeds.
     * @param out the printStream to print to
     * @param ansi whether the usage message should include ANSI escape codes or not
     * @param args the command line arguments to parse
     * @param &lt;C&gt; the annotated object must implement Callable
     * @param &lt;T&gt; the return type of the specified {@code Callable}
     * @throws InitializationException if the specified command object does not have a {@link Command}, {@link Option} or {@link Parameters} annotation
     * @throws ExecutionException if the Callable throws an exception
     * @return {@code null} if an error occurred while parsing the command line options, or if help was requested and printed. Otherwise returns the result of calling the Callable
     * @see #parseWithHandlers(IParseResultHandler, PrintStream, Help.Ansi, IExceptionHandler, String...)
     * @see RunLast
     */</span>
    <span class="directive">public</span> <span class="directive">static</span> &lt;C <span class="directive">extends</span> <span class="predefined-type">Callable</span>&lt;T&gt;, T&gt; T call(C callable, <span class="predefined-type">PrintStream</span> out, Help.Ansi ansi, <span class="predefined-type">String</span>... args) {
        CommandLine cmd = <span class="keyword">new</span> CommandLine(callable); <span class="comment">// validate command outside of try-catch</span>
        <span class="predefined-type">List</span>&lt;<span class="predefined-type">Object</span>&gt; results = cmd.parseWithHandlers(<span class="keyword">new</span> RunLast(), out, ansi, <span class="keyword">new</span> DefaultExceptionHandler(), args);
        <span class="keyword">return</span> results == <span class="predefined-constant">null</span> || results.isEmpty() ? <span class="predefined-constant">null</span> : (T) results.get(<span class="integer">0</span>);
    }

    <span class="comment">/**
     * Delegates to {@link #run(Runnable, PrintStream, Help.Ansi, String...)} with {@link Help.Ansi#AUTO}.
     * &lt;p&gt;
     * From picocli v2.0, this method prints usage help or version help if {@linkplain #printHelpIfRequested(List, PrintStream, Help.Ansi) requested},
     * and any exceptions thrown by the {@code Runnable} are caught and rethrown wrapped in an {@code ExecutionException}.
     * &lt;/p&gt;
     * @param runnable the command to run when {@linkplain #parse(String...) parsing} succeeds.
     * @param out the printStream to print to
     * @param args the command line arguments to parse
     * @param &lt;R&gt; the annotated object must implement Runnable
     * @see #run(Runnable, PrintStream, Help.Ansi, String...)
     * @throws InitializationException if the specified command object does not have a {@link Command}, {@link Option} or {@link Parameters} annotation
     * @throws ExecutionException if the Runnable throws an exception
     * @see #parseWithHandlers(IParseResultHandler, PrintStream, Help.Ansi, IExceptionHandler, String...)
     * @see RunFirst
     */</span>
    <span class="directive">public</span> <span class="directive">static</span> &lt;R <span class="directive">extends</span> <span class="predefined-type">Runnable</span>&gt; <span class="type">void</span> run(R runnable, <span class="predefined-type">PrintStream</span> out, <span class="predefined-type">String</span>... args) {
        run(runnable, out, Help.Ansi.AUTO, args);
    }
    <span class="comment">/**
     * Convenience method to allow command line application authors to avoid some boilerplate code in their application.
     * The annotated object needs to implement {@link Runnable}. Calling this method is equivalent to:
     * &lt;pre&gt;
     * CommandLine cmd = new CommandLine(runnable);
     * List&amp;lt;CommandLine&amp;gt; parsedCommands;
     * try {
     *     parsedCommands = cmd.parse(args);
     * } catch (ParameterException ex) {
     *     out.println(ex.getMessage());
     *     cmd.usage(out, ansi);
     *     return null;
     * }
     * if (CommandLine.printHelpIfRequested(parsedCommands, out, ansi)) {
     *     return null;
     * }
     * CommandLine last = parsedCommands.get(parsedCommands.size() - 1);
     * try {
     *     Runnable subcommand = last.getCommand();
     *     subcommand.run();
     * } catch (Exception ex) {
     *     throw new ExecutionException(last, &quot;Error running &quot; + last.getCommand(), ex);
     * }
     * &lt;/pre&gt;
     * &lt;p&gt;
     * If the specified Runnable command has subcommands, the {@linkplain RunLast last} subcommand specified on the
     * command line is executed.
     * Commands with subcommands may be interested in calling the {@link #parseWithHandler(IParseResultHandler, PrintStream, String...) parseWithHandler}
     * method with a {@link RunAll} handler or a custom handler.
     * &lt;/p&gt;&lt;p&gt;
     * From picocli v2.0, this method prints usage help or version help if {@linkplain #printHelpIfRequested(List, PrintStream, Help.Ansi) requested},
     * and any exceptions thrown by the {@code Runnable} are caught and rethrown wrapped in an {@code ExecutionException}.
     * &lt;/p&gt;
     * @param runnable the command to run when {@linkplain #parse(String...) parsing} succeeds.
     * @param out the printStream to print to
     * @param ansi whether the usage message should include ANSI escape codes or not
     * @param args the command line arguments to parse
     * @param &lt;R&gt; the annotated object must implement Runnable
     * @throws InitializationException if the specified command object does not have a {@link Command}, {@link Option} or {@link Parameters} annotation
     * @throws ExecutionException if the Runnable throws an exception
     * @see #parseWithHandlers(IParseResultHandler, PrintStream, Help.Ansi, IExceptionHandler, String...)
     * @see RunLast
     */</span>
    <span class="directive">public</span> <span class="directive">static</span> &lt;R <span class="directive">extends</span> <span class="predefined-type">Runnable</span>&gt; <span class="type">void</span> run(R runnable, <span class="predefined-type">PrintStream</span> out, Help.Ansi ansi, <span class="predefined-type">String</span>... args) {
        CommandLine cmd = <span class="keyword">new</span> CommandLine(runnable); <span class="comment">// validate command outside of try-catch</span>
        cmd.parseWithHandlers(<span class="keyword">new</span> RunLast(), out, ansi, <span class="keyword">new</span> DefaultExceptionHandler(), args);
    }

    <span class="comment">/**
     * Registers the specified type converter for the specified class. When initializing fields annotated with
     * {@link Option}, the field's type is used as a lookup key to find the associated type converter, and this
     * type converter converts the original command line argument string value to the correct type.
     * &lt;p&gt;
     * Java 8 lambdas make it easy to register custom type converters:
     * &lt;/p&gt;
     * &lt;pre&gt;
     * commandLine.registerConverter(java.nio.file.Path.class, s -&amp;gt; java.nio.file.Paths.get(s));
     * commandLine.registerConverter(java.time.Duration.class, s -&amp;gt; java.time.Duration.parse(s));&lt;/pre&gt;
     * &lt;p&gt;
     * Built-in type converters are pre-registered for the following java 1.5 types:
     * &lt;/p&gt;
     * &lt;ul&gt;
     *   &lt;li&gt;all primitive types&lt;/li&gt;
     *   &lt;li&gt;all primitive wrapper types: Boolean, Byte, Character, Double, Float, Integer, Long, Short&lt;/li&gt;
     *   &lt;li&gt;any enum&lt;/li&gt;
     *   &lt;li&gt;java.io.File&lt;/li&gt;
     *   &lt;li&gt;java.math.BigDecimal&lt;/li&gt;
     *   &lt;li&gt;java.math.BigInteger&lt;/li&gt;
     *   &lt;li&gt;java.net.InetAddress&lt;/li&gt;
     *   &lt;li&gt;java.net.URI&lt;/li&gt;
     *   &lt;li&gt;java.net.URL&lt;/li&gt;
     *   &lt;li&gt;java.nio.charset.Charset&lt;/li&gt;
     *   &lt;li&gt;java.sql.Time&lt;/li&gt;
     *   &lt;li&gt;java.util.Date&lt;/li&gt;
     *   &lt;li&gt;java.util.UUID&lt;/li&gt;
     *   &lt;li&gt;java.util.regex.Pattern&lt;/li&gt;
     *   &lt;li&gt;StringBuilder&lt;/li&gt;
     *   &lt;li&gt;CharSequence&lt;/li&gt;
     *   &lt;li&gt;String&lt;/li&gt;
     * &lt;/ul&gt;
     * &lt;p&gt;The specified converter will be registered with this {@code CommandLine} and the full hierarchy of its
     * subcommands and nested sub-subcommands &lt;em&gt;at the moment the converter is registered&lt;/em&gt;. Subcommands added
     * later will not have this converter added automatically. To ensure a custom type converter is available to all
     * subcommands, register the type converter last, after adding subcommands.&lt;/p&gt;
     *
     * @param cls the target class to convert parameter string values to
     * @param converter the class capable of converting string values to the specified target type
     * @param &lt;K&gt; the target type
     * @return this CommandLine object, to allow method chaining
     * @see #addSubcommand(String, Object)
     */</span>
    <span class="directive">public</span> &lt;K&gt; CommandLine registerConverter(<span class="predefined-type">Class</span>&lt;K&gt; cls, ITypeConverter&lt;K&gt; converter) {
        interpreter.converterRegistry.put(Assert.notNull(cls, <span class="string"><span class="delimiter">&quot;</span><span class="content">class</span><span class="delimiter">&quot;</span></span>), Assert.notNull(converter, <span class="string"><span class="delimiter">&quot;</span><span class="content">converter</span><span class="delimiter">&quot;</span></span>));
        <span class="keyword">for</span> (CommandLine command : interpreter.commands.values()) {
            command.registerConverter(cls, converter);
        }
        <span class="keyword">return</span> <span class="local-variable">this</span>;
    }

    <span class="comment">/** Returns the String that separates option names from option values when parsing command line options. {@value Help#DEFAULT_SEPARATOR} by default.
     * @return the String the parser uses to separate option names from option values */</span>
    <span class="directive">public</span> <span class="predefined-type">String</span> getSeparator() {
        <span class="keyword">return</span> interpreter.separator;
    }

    <span class="comment">/** Sets the String the parser uses to separate option names from option values to the specified value.
     * The separator may also be set declaratively with the {@link CommandLine.Command#separator()} annotation attribute.
     * @param separator the String that separates option names from option values
     * @return this {@code CommandLine} object, to allow method chaining */</span>
    <span class="directive">public</span> CommandLine setSeparator(<span class="predefined-type">String</span> separator) {
        interpreter.separator = Assert.notNull(separator, <span class="string"><span class="delimiter">&quot;</span><span class="content">separator</span><span class="delimiter">&quot;</span></span>);
        <span class="keyword">return</span> <span class="local-variable">this</span>;
    }

    <span class="comment">/** Returns the command name (also called program name) displayed in the usage help synopsis. {@value Help#DEFAULT_COMMAND_NAME} by default.
     * @return the command name (also called program name) displayed in the usage
     * @since 2.0 */</span>
    <span class="directive">public</span> <span class="predefined-type">String</span> getCommandName() {
        <span class="keyword">return</span> commandName;
    }

    <span class="comment">/** Sets the command name (also called program name) displayed in the usage help synopsis to the specified value.
     * Note that this method only modifies the usage help message, it does not impact parsing behaviour.
     * The command name may also be set declaratively with the {@link CommandLine.Command#name()} annotation attribute.
     * @param commandName command name (also called program name) displayed in the usage help synopsis
     * @return this {@code CommandLine} object, to allow method chaining
     * @since 2.0 */</span>
    <span class="directive">public</span> CommandLine setCommandName(<span class="predefined-type">String</span> commandName) {
        <span class="local-variable">this</span>.commandName = Assert.notNull(commandName, <span class="string"><span class="delimiter">&quot;</span><span class="content">commandName</span><span class="delimiter">&quot;</span></span>);
        <span class="keyword">return</span> <span class="local-variable">this</span>;
    }

    <span class="comment">/** Returns whether arguments starting with {@code '@'} should be treated as the path to an argument file and its
     * contents should be expanded into separate arguments for each line in the specified file.
     * This property is {@code true} by default.
     * @return whether &quot;argument files&quot; or {@code @files} should be expanded into their content
     * @since 2.1 */</span>
    <span class="directive">public</span> <span class="type">boolean</span> isExpandAtFiles() {
        <span class="keyword">return</span> expandAtFiles;
    }

    <span class="comment">/** Sets whether arguments starting with {@code '@'} should be treated as the path to an argument file and its
     * contents should be expanded into separate arguments for each line in the specified file. ({@code true} by default.)
     * @param expandAtFiles whether &quot;argument files&quot; or {@code @files} should be expanded into their content
     * @return this {@code CommandLine} object, to allow method chaining
     * @since 2.1 */</span>
    <span class="directive">public</span> CommandLine setExpandAtFiles(<span class="type">boolean</span> expandAtFiles) {
        <span class="local-variable">this</span>.expandAtFiles = expandAtFiles;
        <span class="keyword">return</span> <span class="local-variable">this</span>;
    }
    <span class="directive">private</span> <span class="directive">static</span> <span class="type">boolean</span> empty(<span class="predefined-type">String</span> str) { <span class="keyword">return</span> str == <span class="predefined-constant">null</span> || str.trim().length() == <span class="integer">0</span>; }
    <span class="directive">private</span> <span class="directive">static</span> <span class="type">boolean</span> empty(<span class="predefined-type">Object</span><span class="type">[]</span> array) { <span class="keyword">return</span> array == <span class="predefined-constant">null</span> || array.length == <span class="integer">0</span>; }
    <span class="directive">private</span> <span class="directive">static</span> <span class="type">boolean</span> empty(Text txt) { <span class="keyword">return</span> txt == <span class="predefined-constant">null</span> || txt.plain.toString().trim().length() == <span class="integer">0</span>; }
    <span class="directive">private</span> <span class="directive">static</span> <span class="predefined-type">String</span> str(<span class="predefined-type">String</span><span class="type">[]</span> arr, <span class="type">int</span> i) { <span class="keyword">return</span> (arr == <span class="predefined-constant">null</span> || arr.length == <span class="integer">0</span>) ? <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span> : arr[i]; }
    <span class="directive">private</span> <span class="directive">static</span> <span class="type">boolean</span> isBoolean(<span class="predefined-type">Class</span>&lt;?&gt; type) { <span class="keyword">return</span> type == <span class="predefined-type">Boolean</span>.class || type == <span class="predefined-type">Boolean</span>.TYPE; }
    <span class="directive">private</span> <span class="directive">static</span> CommandLine toCommandLine(<span class="predefined-type">Object</span> obj, IFactory factory) { <span class="keyword">return</span> obj <span class="keyword">instanceof</span> CommandLine ? (CommandLine) obj : <span class="keyword">new</span> CommandLine(obj, factory);}
    <span class="directive">private</span> <span class="directive">static</span> <span class="type">boolean</span> isMultiValue(<span class="predefined-type">Field</span> field) {  <span class="keyword">return</span> isMultiValue(field.getType()); }
    <span class="directive">private</span> <span class="directive">static</span> <span class="type">boolean</span> isMultiValue(<span class="predefined-type">Class</span>&lt;?&gt; cls) { <span class="keyword">return</span> cls.isArray() || <span class="predefined-type">Collection</span>.class.isAssignableFrom(cls) || <span class="predefined-type">Map</span>.class.isAssignableFrom(cls); }
    <span class="directive">private</span> <span class="directive">static</span> <span class="predefined-type">Class</span>&lt;?&gt;<span class="type">[]</span> getTypeAttribute(<span class="predefined-type">Field</span> field) {
        <span class="predefined-type">Class</span>&lt;?&gt;<span class="type">[]</span> explicit = field.isAnnotationPresent(Parameters.class) ? field.getAnnotation(Parameters.class).type() : field.getAnnotation(<span class="predefined-type">Option</span>.class).type();
        <span class="keyword">if</span> (explicit.length &gt; <span class="integer">0</span>) { <span class="keyword">return</span> explicit; }
        <span class="keyword">if</span> (field.getType().isArray()) { <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">Class</span>&lt;?&gt;<span class="type">[]</span> { field.getType().getComponentType() }; }
        <span class="keyword">if</span> (isMultiValue(field)) {
            <span class="predefined-type">Type</span> type = field.getGenericType(); <span class="comment">// e.g. Map&lt;Long, ? extends Number&gt;</span>
            <span class="keyword">if</span> (type <span class="keyword">instanceof</span> <span class="predefined-type">ParameterizedType</span>) {
                <span class="predefined-type">ParameterizedType</span> parameterizedType = (<span class="predefined-type">ParameterizedType</span>) type;
                <span class="predefined-type">Type</span><span class="type">[]</span> paramTypes = parameterizedType.getActualTypeArguments(); <span class="comment">// e.g. ? extends Number</span>
                <span class="predefined-type">Class</span>&lt;?&gt;<span class="type">[]</span> result = <span class="keyword">new</span> <span class="predefined-type">Class</span>&lt;?&gt;[paramTypes.length];
                <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">0</span>; i &lt; paramTypes.length; i++) {
                    <span class="keyword">if</span> (paramTypes[i] <span class="keyword">instanceof</span> <span class="predefined-type">Class</span>) { result[i] = (<span class="predefined-type">Class</span>&lt;?&gt;) paramTypes[i]; <span class="keyword">continue</span>; } <span class="comment">// e.g. Long</span>
                    <span class="keyword">if</span> (paramTypes[i] <span class="keyword">instanceof</span> <span class="predefined-type">WildcardType</span>) { <span class="comment">// e.g. ? extends Number</span>
                        <span class="predefined-type">WildcardType</span> wildcardType = (<span class="predefined-type">WildcardType</span>) paramTypes[i];
                        <span class="predefined-type">Type</span><span class="type">[]</span> lower = wildcardType.getLowerBounds(); <span class="comment">// e.g. []</span>
                        <span class="keyword">if</span> (lower.length &gt; <span class="integer">0</span> &amp;&amp; lower[<span class="integer">0</span>] <span class="keyword">instanceof</span> <span class="predefined-type">Class</span>) { result[i] = (<span class="predefined-type">Class</span>&lt;?&gt;) lower[<span class="integer">0</span>]; <span class="keyword">continue</span>; }
                        <span class="predefined-type">Type</span><span class="type">[]</span> upper = wildcardType.getUpperBounds(); <span class="comment">// e.g. Number</span>
                        <span class="keyword">if</span> (upper.length &gt; <span class="integer">0</span> &amp;&amp; upper[<span class="integer">0</span>] <span class="keyword">instanceof</span> <span class="predefined-type">Class</span>) { result[i] = (<span class="predefined-type">Class</span>&lt;?&gt;) upper[<span class="integer">0</span>]; <span class="keyword">continue</span>; }
                    }
                    <span class="predefined-type">Arrays</span>.fill(result, <span class="predefined-type">String</span>.class); <span class="keyword">return</span> result; <span class="comment">// too convoluted generic type, giving up</span>
                }
                <span class="keyword">return</span> result; <span class="comment">// we inferred all types from ParameterizedType</span>
            }
            <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">Class</span>&lt;?&gt;<span class="type">[]</span> {<span class="predefined-type">String</span>.class, <span class="predefined-type">String</span>.class}; <span class="comment">// field is multi-value but not ParameterizedType</span>
        }
        <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">Class</span>&lt;?&gt;<span class="type">[]</span> {field.getType()}; <span class="comment">// not a multi-value field</span>
    }
    <span class="comment">/**
     * &lt;p&gt;
     * Annotate fields in your class with {@code @Option} and picocli will initialize these fields when matching
     * arguments are specified on the command line.
     * &lt;/p&gt;&lt;p&gt;
     * For example:
     * &lt;/p&gt;
     * &lt;pre&gt;
     * import static picocli.CommandLine.*;
     *
     * public class MyClass {
     *     &amp;#064;Parameters(description = &quot;Any number of input files&quot;)
     *     private List&amp;lt;File&amp;gt; files = new ArrayList&amp;lt;File&amp;gt;();
     *
     *     &amp;#064;Option(names = { &quot;-o&quot;, &quot;--out&quot; }, description = &quot;Output file (default: print to console)&quot;)
     *     private File outputFile;
     *
     *     &amp;#064;Option(names = { &quot;-v&quot;, &quot;--verbose&quot;}, description = &quot;Verbose mode. Helpful for troubleshooting. Multiple -v options increase the verbosity.&quot;)
     *     private boolean[] verbose;
     *
     *     &amp;#064;Option(names = { &quot;-h&quot;, &quot;--help&quot;, &quot;-?&quot;, &quot;-help&quot;}, usageHelp = true, description = &quot;Display this help and exit&quot;)
     *     private boolean help;
     * }
     * &lt;/pre&gt;
     * &lt;p&gt;
     * A field cannot be annotated with both {@code @Parameters} and {@code @Option} or a
     * {@code ParameterException} is thrown.
     * &lt;/p&gt;
     */</span>
    <span class="annotation">@Retention</span>(<span class="predefined-type">RetentionPolicy</span>.RUNTIME)
    <span class="annotation">@Target</span>(<span class="predefined-type">ElementType</span>.FIELD)
    <span class="directive">public</span> <span class="annotation">@interface</span> <span class="predefined-type">Option</span> {
        <span class="comment">/**
         * One or more option names. At least one option name is required.
         * &lt;p&gt;
         * Different environments have different conventions for naming options, but usually options have a prefix
         * that sets them apart from parameters.
         * Picocli supports all of the below styles. The default separator is {@code '='}, but this can be configured.
         * &lt;/p&gt;&lt;p&gt;
         * &lt;b&gt;*nix&lt;/b&gt;
         * &lt;/p&gt;&lt;p&gt;
         * In Unix and Linux, options have a short (single-character) name, a long name or both.
         * Short options
         * (&lt;a href=&quot;http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_02&quot;&gt;POSIX
         * style&lt;/a&gt; are single-character and are preceded by the {@code '-'} character, e.g., {@code `-v'}.
         * &lt;a href=&quot;https://www.gnu.org/software/tar/manual/html_node/Long-Options.html&quot;&gt;GNU-style&lt;/a&gt; long
         * (or &lt;em&gt;mnemonic&lt;/em&gt;) options start with two dashes in a row, e.g., {@code `--file'}.
         * &lt;/p&gt;&lt;p&gt;Picocli supports the POSIX convention that short options can be grouped, with the last option
         * optionally taking a parameter, which may be attached to the option name or separated by a space or
         * a {@code '='} character. The below examples are all equivalent:
         * &lt;/p&gt;&lt;pre&gt;
         * -xvfFILE
         * -xvf FILE
         * -xvf=FILE
         * -xv --file FILE
         * -xv --file=FILE
         * -x -v --file FILE
         * -x -v --file=FILE
         * &lt;/pre&gt;&lt;p&gt;
         * &lt;b&gt;DOS&lt;/b&gt;
         * &lt;/p&gt;&lt;p&gt;
         * DOS options mostly have upper case single-character names and start with a single slash {@code '/'} character.
         * Option parameters are separated by a {@code ':'} character. Options cannot be grouped together but
         * must be specified separately. For example:
         * &lt;/p&gt;&lt;pre&gt;
         * DIR /S /A:D /T:C
         * &lt;/pre&gt;&lt;p&gt;
         * &lt;b&gt;PowerShell&lt;/b&gt;
         * &lt;/p&gt;&lt;p&gt;
         * Windows PowerShell options generally are a word preceded by a single {@code '-'} character, e.g., {@code `-Help'}.
         * Option parameters are separated by a space or by a {@code ':'} character.
         * &lt;/p&gt;
         * @return one or more option names
         */</span>
        <span class="predefined-type">String</span><span class="type">[]</span> names();

        <span class="comment">/**
         * Indicates whether this option is required. By default this is false.
         * If an option is required, but a user invokes the program without specifying the required option,
         * a {@link MissingParameterException} is thrown from the {@link #parse(String...)} method.
         * @return whether this option is required
         */</span>
        <span class="type">boolean</span> required() <span class="keyword">default</span> <span class="predefined-constant">false</span>;

        <span class="comment">/**
         * Set {@code help=true} if this option should disable validation of the remaining arguments:
         * If the {@code help} option is specified, no error message is generated for missing required options.
         * &lt;p&gt;
         * This attribute is useful for special options like help ({@code -h} and {@code --help} on unix,
         * {@code -?} and {@code -Help} on Windows) or version ({@code -V} and {@code --version} on unix,
         * {@code -Version} on Windows).
         * &lt;/p&gt;
         * &lt;p&gt;
         * Note that the {@link #parse(String...)} method will not print help documentation. It will only set
         * the value of the annotated field. It is the responsibility of the caller to inspect the annotated fields
         * and take the appropriate action.
         * &lt;/p&gt;
         * @return whether this option disables validation of the other arguments
         * @deprecated Use {@link #usageHelp()} and {@link #versionHelp()} instead. See {@link #printHelpIfRequested(List, PrintStream, CommandLine.Help.Ansi)}
         */</span>
        <span class="type">boolean</span> help() <span class="keyword">default</span> <span class="predefined-constant">false</span>;

        <span class="comment">/**
         * Set {@code usageHelp=true} if this option allows the user to request usage help. If this option is
         * specified on the command line, picocli will not validate the remaining arguments (so no &quot;missing required
         * option&quot; errors) and the {@link CommandLine#isUsageHelpRequested()} method will return {@code true}.
         * &lt;p&gt;
         * This attribute is useful for special options like help ({@code -h} and {@code --help} on unix,
         * {@code -?} and {@code -Help} on Windows).
         * &lt;/p&gt;
         * &lt;p&gt;
         * Note that the {@link #parse(String...)} method will not print usage help documentation. It will only set
         * the value of the annotated field. It is the responsibility of the caller to inspect the annotated fields
         * and take the appropriate action.
         * &lt;/p&gt;
         * @return whether this option allows the user to request usage help
         * @since 0.9.8
         */</span>
        <span class="type">boolean</span> usageHelp() <span class="keyword">default</span> <span class="predefined-constant">false</span>;

        <span class="comment">/**
         * Set {@code versionHelp=true} if this option allows the user to request version information. If this option is
         * specified on the command line, picocli will not validate the remaining arguments (so no &quot;missing required
         * option&quot; errors) and the {@link CommandLine#isVersionHelpRequested()} method will return {@code true}.
         * &lt;p&gt;
         * This attribute is useful for special options like version ({@code -V} and {@code --version} on unix,
         * {@code -Version} on Windows).
         * &lt;/p&gt;
         * &lt;p&gt;
         * Note that the {@link #parse(String...)} method will not print version information. It will only set
         * the value of the annotated field. It is the responsibility of the caller to inspect the annotated fields
         * and take the appropriate action.
         * &lt;/p&gt;
         * @return whether this option allows the user to request version information
         * @since 0.9.8
         */</span>
        <span class="type">boolean</span> versionHelp() <span class="keyword">default</span> <span class="predefined-constant">false</span>;

        <span class="comment">/**
         * Description of this option, used when generating the usage documentation.
         * @return the description of this option
         */</span>
        <span class="predefined-type">String</span><span class="type">[]</span> description() <span class="keyword">default</span> {};

        <span class="comment">/**
         * Specifies the minimum number of required parameters and the maximum number of accepted parameters.
         * If an option declares a positive arity, and the user specifies an insufficient number of parameters on the
         * command line, a {@link MissingParameterException} is thrown by the {@link #parse(String...)} method.
         * &lt;p&gt;
         * In many cases picocli can deduce the number of required parameters from the field's type.
         * By default, flags (boolean options) have arity zero,
         * and single-valued type fields (String, int, Integer, double, Double, File, Date, etc) have arity one.
         * Generally, fields with types that cannot hold multiple values can omit the {@code arity} attribute.
         * &lt;/p&gt;&lt;p&gt;
         * Fields used to capture options with arity two or higher should have a type that can hold multiple values,
         * like arrays or Collections. See {@link #type()} for strongly-typed Collection fields.
         * &lt;/p&gt;&lt;p&gt;
         * For example, if an option has 2 required parameters and any number of optional parameters,
         * specify {@code @Option(names = &quot;-example&quot;, arity = &quot;2..*&quot;)}.
         * &lt;/p&gt;
         * &lt;b&gt;A note on boolean options&lt;/b&gt;
         * &lt;p&gt;
         * By default picocli does not expect boolean options (also called &quot;flags&quot; or &quot;switches&quot;) to have a parameter.
         * You can make a boolean option take a required parameter by annotating your field with {@code arity=&quot;1&quot;}.
         * For example: &lt;/p&gt;
         * &lt;pre&gt;&amp;#064;Option(names = &quot;-v&quot;, arity = &quot;1&quot;) boolean verbose;&lt;/pre&gt;
         * &lt;p&gt;
         * Because this boolean field is defined with arity 1, the user must specify either {@code &lt;program&gt; -v false}
         * or {@code &lt;program&gt; -v true}
         * on the command line, or a {@link MissingParameterException} is thrown by the {@link #parse(String...)}
         * method.
         * &lt;/p&gt;&lt;p&gt;
         * To make the boolean parameter possible but optional, define the field with {@code arity = &quot;0..1&quot;}.
         * For example: &lt;/p&gt;
         * &lt;pre&gt;&amp;#064;Option(names=&quot;-v&quot;, arity=&quot;0..1&quot;) boolean verbose;&lt;/pre&gt;
         * &lt;p&gt;This will accept any of the below without throwing an exception:&lt;/p&gt;
         * &lt;pre&gt;
         * -v
         * -v true
         * -v false
         * &lt;/pre&gt;
         * @return how many arguments this option requires
         */</span>
        <span class="predefined-type">String</span> arity() <span class="keyword">default</span> <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;

        <span class="comment">/**
         * Specify a {@code paramLabel} for the option parameter to be used in the usage help message. If omitted,
         * picocli uses the field name in fish brackets ({@code '&lt;'} and {@code '&gt;'}) by default. Example:
         * &lt;pre&gt;class Example {
         *     &amp;#064;Option(names = {&quot;-o&quot;, &quot;--output&quot;}, paramLabel=&quot;FILE&quot;, description=&quot;path of the output file&quot;)
         *     private File out;
         *     &amp;#064;Option(names = {&quot;-j&quot;, &quot;--jobs&quot;}, arity=&quot;0..1&quot;, description=&quot;Allow N jobs at once; infinite jobs with no arg.&quot;)
         *     private int maxJobs = -1;
         * }&lt;/pre&gt;
         * &lt;p&gt;By default, the above gives a usage help message like the following:&lt;/p&gt;&lt;pre&gt;
         * Usage: &amp;lt;main class&amp;gt; [OPTIONS]
         * -o, --output FILE       path of the output file
         * -j, --jobs [&amp;lt;maxJobs&amp;gt;]  Allow N jobs at once; infinite jobs with no arg.
         * &lt;/pre&gt;
         * @return name of the option parameter used in the usage help message
         */</span>
        <span class="predefined-type">String</span> paramLabel() <span class="keyword">default</span> <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;

        <span class="comment">/** &lt;p&gt;
         * Optionally specify a {@code type} to control exactly what Class the option parameter should be converted
         * to. This may be useful when the field type is an interface or an abstract class. For example, a field can
         * be declared to have type {@code java.lang.Number}, and annotating {@code @Option(type=Short.class)}
         * ensures that the option parameter value is converted to a {@code Short} before setting the field value.
         * &lt;/p&gt;&lt;p&gt;
         * For array fields whose &lt;em&gt;component&lt;/em&gt; type is an interface or abstract class, specify the concrete &lt;em&gt;component&lt;/em&gt; type.
         * For example, a field with type {@code Number[]} may be annotated with {@code @Option(type=Short.class)}
         * to ensure that option parameter values are converted to {@code Short} before adding an element to the array.
         * &lt;/p&gt;&lt;p&gt;
         * Picocli will use the {@link ITypeConverter} that is
         * {@linkplain #registerConverter(Class, ITypeConverter) registered} for the specified type to convert
         * the raw String values before modifying the field value.
         * &lt;/p&gt;&lt;p&gt;
         * Prior to 2.0, the {@code type} attribute was necessary for {@code Collection} and {@code Map} fields,
         * but starting from 2.0 picocli will infer the component type from the generic type's type arguments.
         * For example, for a field of type {@code Map&lt;TimeUnit, Long&gt;} picocli will know the option parameter
         * should be split up in key=value pairs, where the key should be converted to a {@code java.util.concurrent.TimeUnit}
         * enum value, and the value should be converted to a {@code Long}. No {@code @Option(type=...)} type attribute
         * is required for this. For generic types with wildcards, picocli will take the specified upper or lower bound
         * as the Class to convert to, unless the {@code @Option} annotation specifies an explicit {@code type} attribute.
         * &lt;/p&gt;&lt;p&gt;
         * If the field type is a raw collection or a raw map, and you want it to contain other values than Strings,
         * or if the generic type's type arguments are interfaces or abstract classes, you may
         * specify a {@code type} attribute to control the Class that the option parameter should be converted to.
         * @return the type(s) to convert the raw String values
         */</span>
        <span class="predefined-type">Class</span>&lt;?&gt;<span class="type">[]</span> type() <span class="keyword">default</span> {};

        <span class="comment">/**
         * Optionally specify one or more {@link ITypeConverter} classes to use to convert the command line argument into
         * a strongly typed value (or key-value pair for map fields). This is useful when a particular field should
         * use a custom conversion that is different from the normal conversion for the field's type.
         * &lt;p&gt;For example, for a specific field you may want to use a converter that maps the constant names defined
         * in {@link java.sql.Types java.sql.Types} to the {@code int} value of these constants, but any other {@code int} fields should
         * not be affected by this and should continue to use the standard int converter that parses numeric values.&lt;/p&gt;
         * @return the type converter(s) to use to convert String values to strongly typed values for this field
         * @see CommandLine#registerConverter(Class, ITypeConverter)
         */</span>
        <span class="predefined-type">Class</span>&lt;? <span class="directive">extends</span> ITypeConverter&lt;?&gt;&gt;<span class="type">[]</span> converter() <span class="keyword">default</span> {};

        <span class="comment">/**
         * Specify a regular expression to use to split option parameter values before applying them to the field.
         * All elements resulting from the split are added to the array or Collection. Ignored for single-value fields.
         * @return a regular expression to split option parameter values or {@code &quot;&quot;} if the value should not be split
         * @see String#split(String)
         */</span>
        <span class="predefined-type">String</span> split() <span class="keyword">default</span> <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;

        <span class="comment">/**
         * Set {@code hidden=true} if this option should not be included in the usage documentation.
         * @return whether this option should be excluded from the usage message
         */</span>
        <span class="type">boolean</span> hidden() <span class="keyword">default</span> <span class="predefined-constant">false</span>;
    }
    <span class="comment">/**
     * &lt;p&gt;
     * Fields annotated with {@code @Parameters} will be initialized with positional parameters. By specifying the
     * {@link #index()} attribute you can pick the exact position or a range of positional parameters to apply. If no
     * index is specified, the field will get all positional parameters (and so it should be an array or a collection).
     * &lt;/p&gt;&lt;p&gt;
     * For example:
     * &lt;/p&gt;
     * &lt;pre&gt;
     * import static picocli.CommandLine.*;
     *
     * public class MyCalcParameters {
     *     &amp;#064;Parameters(description = &quot;Any number of input numbers&quot;)
     *     private List&amp;lt;BigDecimal&amp;gt; files = new ArrayList&amp;lt;BigDecimal&amp;gt;();
     *
     *     &amp;#064;Option(names = { &quot;-h&quot;, &quot;--help&quot; }, usageHelp = true, description = &quot;Display this help and exit&quot;)
     *     private boolean help;
     * }
     * &lt;/pre&gt;&lt;p&gt;
     * A field cannot be annotated with both {@code @Parameters} and {@code @Option} or a {@code ParameterException}
     * is thrown.&lt;/p&gt;
     */</span>
    <span class="annotation">@Retention</span>(<span class="predefined-type">RetentionPolicy</span>.RUNTIME)
    <span class="annotation">@Target</span>(<span class="predefined-type">ElementType</span>.FIELD)
    <span class="directive">public</span> <span class="annotation">@interface</span> Parameters {
        <span class="comment">/** Specify an index (&quot;0&quot;, or &quot;1&quot;, etc.) to pick which of the command line arguments should be assigned to this
         * field. For array or Collection fields, you can also specify an index range (&quot;0..3&quot;, or &quot;2..*&quot;, etc.) to assign
         * a subset of the command line arguments to this field. The default is &quot;*&quot;, meaning all command line arguments.
         * @return an index or range specifying which of the command line arguments should be assigned to this field
         */</span>
        <span class="predefined-type">String</span> index() <span class="keyword">default</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">*</span><span class="delimiter">&quot;</span></span>;

        <span class="comment">/** Description of the parameter(s), used when generating the usage documentation.
         * @return the description of the parameter(s)
         */</span>
        <span class="predefined-type">String</span><span class="type">[]</span> description() <span class="keyword">default</span> {};

        <span class="comment">/**
         * Specifies the minimum number of required parameters and the maximum number of accepted parameters. If a
         * positive arity is declared, and the user specifies an insufficient number of parameters on the command line,
         * {@link MissingParameterException} is thrown by the {@link #parse(String...)} method.
         * &lt;p&gt;The default depends on the type of the parameter: booleans require no parameters, arrays and Collections
         * accept zero to any number of parameters, and any other type accepts one parameter.&lt;/p&gt;
         * @return the range of minimum and maximum parameters accepted by this command
         */</span>
        <span class="predefined-type">String</span> arity() <span class="keyword">default</span> <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;

        <span class="comment">/**
         * Specify a {@code paramLabel} for the parameter to be used in the usage help message. If omitted,
         * picocli uses the field name in fish brackets ({@code '&lt;'} and {@code '&gt;'}) by default. Example:
         * &lt;pre&gt;class Example {
         *     &amp;#064;Parameters(paramLabel=&quot;FILE&quot;, description=&quot;path of the input FILE(s)&quot;)
         *     private File[] inputFiles;
         * }&lt;/pre&gt;
         * &lt;p&gt;By default, the above gives a usage help message like the following:&lt;/p&gt;&lt;pre&gt;
         * Usage: &amp;lt;main class&amp;gt; [FILE...]
         * [FILE...]       path of the input FILE(s)
         * &lt;/pre&gt;
         * @return name of the positional parameter used in the usage help message
         */</span>
        <span class="predefined-type">String</span> paramLabel() <span class="keyword">default</span> <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;

        <span class="comment">/**
         * &lt;p&gt;
         * Optionally specify a {@code type} to control exactly what Class the positional parameter should be converted
         * to. This may be useful when the field type is an interface or an abstract class. For example, a field can
         * be declared to have type {@code java.lang.Number}, and annotating {@code @Parameters(type=Short.class)}
         * ensures that the positional parameter value is converted to a {@code Short} before setting the field value.
         * &lt;/p&gt;&lt;p&gt;
         * For array fields whose &lt;em&gt;component&lt;/em&gt; type is an interface or abstract class, specify the concrete &lt;em&gt;component&lt;/em&gt; type.
         * For example, a field with type {@code Number[]} may be annotated with {@code @Parameters(type=Short.class)}
         * to ensure that positional parameter values are converted to {@code Short} before adding an element to the array.
         * &lt;/p&gt;&lt;p&gt;
         * Picocli will use the {@link ITypeConverter} that is
         * {@linkplain #registerConverter(Class, ITypeConverter) registered} for the specified type to convert
         * the raw String values before modifying the field value.
         * &lt;/p&gt;&lt;p&gt;
         * Prior to 2.0, the {@code type} attribute was necessary for {@code Collection} and {@code Map} fields,
         * but starting from 2.0 picocli will infer the component type from the generic type's type arguments.
         * For example, for a field of type {@code Map&lt;TimeUnit, Long&gt;} picocli will know the positional parameter
         * should be split up in key=value pairs, where the key should be converted to a {@code java.util.concurrent.TimeUnit}
         * enum value, and the value should be converted to a {@code Long}. No {@code @Parameters(type=...)} type attribute
         * is required for this. For generic types with wildcards, picocli will take the specified upper or lower bound
         * as the Class to convert to, unless the {@code @Parameters} annotation specifies an explicit {@code type} attribute.
         * &lt;/p&gt;&lt;p&gt;
         * If the field type is a raw collection or a raw map, and you want it to contain other values than Strings,
         * or if the generic type's type arguments are interfaces or abstract classes, you may
         * specify a {@code type} attribute to control the Class that the positional parameter should be converted to.
         * @return the type(s) to convert the raw String values
         */</span>
        <span class="predefined-type">Class</span>&lt;?&gt;<span class="type">[]</span> type() <span class="keyword">default</span> {};

        <span class="comment">/**
         * Optionally specify one or more {@link ITypeConverter} classes to use to convert the command line argument into
         * a strongly typed value (or key-value pair for map fields). This is useful when a particular field should
         * use a custom conversion that is different from the normal conversion for the field's type.
         * &lt;p&gt;For example, for a specific field you may want to use a converter that maps the constant names defined
         * in {@link java.sql.Types java.sql.Types} to the {@code int} value of these constants, but any other {@code int} fields should
         * not be affected by this and should continue to use the standard int converter that parses numeric values.&lt;/p&gt;
         * @return the type converter(s) to use to convert String values to strongly typed values for this field
         * @see CommandLine#registerConverter(Class, ITypeConverter)
         */</span>
        <span class="predefined-type">Class</span>&lt;? <span class="directive">extends</span> ITypeConverter&lt;?&gt;&gt;<span class="type">[]</span> converter() <span class="keyword">default</span> {};

        <span class="comment">/**
         * Specify a regular expression to use to split positional parameter values before applying them to the field.
         * All elements resulting from the split are added to the array or Collection. Ignored for single-value fields.
         * @return a regular expression to split operand values or {@code &quot;&quot;} if the value should not be split
         * @see String#split(String)
         */</span>
        <span class="predefined-type">String</span> split() <span class="keyword">default</span> <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;

        <span class="comment">/**
         * Set {@code hidden=true} if this parameter should not be included in the usage message.
         * @return whether this parameter should be excluded from the usage message
         */</span>
        <span class="type">boolean</span> hidden() <span class="keyword">default</span> <span class="predefined-constant">false</span>;
    }

    <span class="comment">/**
     * &lt;p&gt;
     * Fields annotated with {@code @ParentCommand} will be initialized with the parent command of the current subcommand.
     * If the current command does not have a parent command, this annotation has no effect.
     * &lt;/p&gt;&lt;p&gt;
     * Parent commands often define options that apply to all the subcommands.
     * This annotation offers a convenient way to inject a reference to the parent command into a subcommand, so the
     * subcommand can access its parent options. For example:
     * &lt;/p&gt;&lt;pre&gt;
     * &amp;#064;Command(name = &quot;top&quot;, subcommands = Sub.class)
     * class Top implements Runnable {
     *
     *     &amp;#064;Option(names = {&quot;-d&quot;, &quot;--directory&quot;}, description = &quot;this option applies to all subcommands&quot;)
     *     File baseDirectory;
     *
     *     public void run() { System.out.println(&quot;Hello from top&quot;); }
     * }
     *
     * &amp;#064;Command(name = &quot;sub&quot;)
     * class Sub implements Runnable {
     *
     *     &amp;#064;ParentCommand
     *     private Top parent;
     *
     *     public void run() {
     *         System.out.println(&quot;Subcommand: parent command 'directory' is &quot; + parent.baseDirectory);
     *     }
     * }
     * &lt;/pre&gt;
     * @since 2.2
     */</span>
    <span class="annotation">@Retention</span>(<span class="predefined-type">RetentionPolicy</span>.RUNTIME)
    <span class="annotation">@Target</span>(<span class="predefined-type">ElementType</span>.FIELD)
    <span class="directive">public</span> <span class="annotation">@interface</span> ParentCommand { }

    <span class="comment">/**
     * &lt;p&gt;Annotate your class with {@code @Command} when you want more control over the format of the generated help
     * message.
     * &lt;/p&gt;&lt;pre&gt;
     * &amp;#064;Command(name      = &quot;Encrypt&quot;,
     *        description = &quot;Encrypt FILE(s), or standard input, to standard output or to the output file.&quot;,
     *        version     = &quot;Encrypt version 1.0&quot;,
     *        footer      = &quot;Copyright (c) 2017&quot;)
     * public class Encrypt {
     *     &amp;#064;Parameters(paramLabel = &quot;FILE&quot;, description = &quot;Any number of input files&quot;)
     *     private List&amp;lt;File&amp;gt; files = new ArrayList&amp;lt;File&amp;gt;();
     *
     *     &amp;#064;Option(names = { &quot;-o&quot;, &quot;--out&quot; }, description = &quot;Output file (default: print to console)&quot;)
     *     private File outputFile;
     *
     *     &amp;#064;Option(names = { &quot;-v&quot;, &quot;--verbose&quot;}, description = &quot;Verbose mode. Helpful for troubleshooting. Multiple -v options increase the verbosity.&quot;)
     *     private boolean[] verbose;
     *
     *     &amp;#064;Option(names = { &quot;-h&quot;, &quot;--help&quot; }, usageHelp = true, description = &quot;Display this help and exit&quot;)
     *     private boolean help;
     *
     *     &amp;#064;Option(names = { &quot;-V&quot;, &quot;--version&quot;}, versionHelp = true, description = &quot;Display version information and exit&quot;)
     *     private boolean version;
     * }&lt;/pre&gt;
     * &lt;p&gt;
     * The structure of a help message looks like this:
     * &lt;/p&gt;&lt;ul&gt;
     *   &lt;li&gt;[header]&lt;/li&gt;
     *   &lt;li&gt;[synopsis]: {@code Usage: &lt;commandName&gt; [OPTIONS] [FILE...]}&lt;/li&gt;
     *   &lt;li&gt;[description]&lt;/li&gt;
     *   &lt;li&gt;[parameter list]: {@code      [FILE...]   Any number of input files}&lt;/li&gt;
     *   &lt;li&gt;[option list]: {@code   -h, --help   prints this help message and exits}&lt;/li&gt;
     *   &lt;li&gt;[footer]&lt;/li&gt;
     * &lt;/ul&gt; */</span>
    <span class="annotation">@Retention</span>(<span class="predefined-type">RetentionPolicy</span>.RUNTIME)
    <span class="annotation">@Target</span>({<span class="predefined-type">ElementType</span>.TYPE, <span class="predefined-type">ElementType</span>.LOCAL_VARIABLE, <span class="predefined-type">ElementType</span>.PACKAGE})
    <span class="directive">public</span> <span class="annotation">@interface</span> Command {
        <span class="comment">/** Program name to show in the synopsis. If omitted, {@code &quot;&lt;main class&gt;&quot;} is used.
         * For {@linkplain #subcommands() declaratively added} subcommands, this attribute is also used
         * by the parser to recognize subcommands in the command line arguments.
         * @return the program name to show in the synopsis
         * @see Help#commandName */</span>
        <span class="predefined-type">String</span> name() <span class="keyword">default</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">&lt;main class&gt;</span><span class="delimiter">&quot;</span></span>;

        <span class="comment">/** A list of classes to instantiate and register as subcommands. When registering subcommands declaratively
         * like this, you don't need to call the {@link CommandLine#addSubcommand(String, Object)} method. For example, this:
         * &lt;pre&gt;
         * &amp;#064;Command(subcommands = {
         *         GitStatus.class,
         *         GitCommit.class,
         *         GitBranch.class })
         * public class Git { ... }
         *
         * CommandLine commandLine = new CommandLine(new Git());
         * &lt;/pre&gt; is equivalent to this:
         * &lt;pre&gt;
         * // alternative: programmatically add subcommands.
         * // NOTE: in this case there should be no `subcommands` attribute on the @Command annotation.
         * &amp;#064;Command public class Git { ... }
         *
         * CommandLine commandLine = new CommandLine(new Git())
         *         .addSubcommand(&quot;status&quot;,   new GitStatus())
         *         .addSubcommand(&quot;commit&quot;,   new GitCommit())
         *         .addSubcommand(&quot;branch&quot;,   new GitBranch());
         * &lt;/pre&gt;
         * @return the declaratively registered subcommands of this command, or an empty array if none
         * @see CommandLine#addSubcommand(String, Object)
         * @since 0.9.8
         */</span>
        <span class="predefined-type">Class</span>&lt;?&gt;<span class="type">[]</span> subcommands() <span class="keyword">default</span> {};

        <span class="comment">/** String that separates options from option parameters. Default is {@code &quot;=&quot;}. Spaces are also accepted.
         * @return the string that separates options from option parameters, used both when parsing and when generating usage help
         * @see Help#separator
         * @see CommandLine#setSeparator(String) */</span>
        <span class="predefined-type">String</span> separator() <span class="keyword">default</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">=</span><span class="delimiter">&quot;</span></span>;

        <span class="comment">/** Version information for this command, to print to the console when the user specifies an
         * {@linkplain Option#versionHelp() option} to request version help. This is not part of the usage help message.
         *
         * @return a string or an array of strings with version information about this command (each string in the array is displayed on a separate line).
         * @since 0.9.8
         * @see CommandLine#printVersionHelp(PrintStream)
         */</span>
        <span class="predefined-type">String</span><span class="type">[]</span> version() <span class="keyword">default</span> {};

        <span class="comment">/** Class that can provide version information dynamically at runtime. An implementation may return version
         * information obtained from the JAR manifest, a properties file or some other source.
         * @return a Class that can provide version information dynamically at runtime
         */</span>
        <span class="predefined-type">Class</span>&lt;? <span class="directive">extends</span> IVersionProvider&gt; versionProvider() <span class="keyword">default</span> NoVersionProvider.class;

        <span class="comment">/** Set the heading preceding the header section. May contain embedded {@linkplain java.util.Formatter format specifiers}.
         * @return the heading preceding the header section
         * @see Help#headerHeading(Object...)  */</span>
        <span class="predefined-type">String</span> headerHeading() <span class="keyword">default</span> <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;

        <span class="comment">/** Optional summary description of the command, shown before the synopsis.
         * @return summary description of the command
         * @see Help#header
         * @see Help#header(Object...)  */</span>
        <span class="predefined-type">String</span><span class="type">[]</span> header() <span class="keyword">default</span> {};

        <span class="comment">/** Set the heading preceding the synopsis text. May contain embedded
         * {@linkplain java.util.Formatter format specifiers}. The default heading is {@code &quot;Usage: &quot;} (without a line
         * break between the heading and the synopsis text).
         * @return the heading preceding the synopsis text
         * @see Help#synopsisHeading(Object...)  */</span>
        <span class="predefined-type">String</span> synopsisHeading() <span class="keyword">default</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">Usage: </span><span class="delimiter">&quot;</span></span>;

        <span class="comment">/** Specify {@code true} to generate an abbreviated synopsis like {@code &quot;&lt;main&gt; [OPTIONS] [PARAMETERS...]&quot;}.
         * By default, a detailed synopsis with individual option names and parameters is generated.
         * @return whether the synopsis should be abbreviated
         * @see Help#abbreviateSynopsis
         * @see Help#abbreviatedSynopsis()
         * @see Help#detailedSynopsis(Comparator, boolean) */</span>
        <span class="type">boolean</span> abbreviateSynopsis() <span class="keyword">default</span> <span class="predefined-constant">false</span>;

        <span class="comment">/** Specify one or more custom synopsis lines to display instead of an auto-generated synopsis.
         * @return custom synopsis text to replace the auto-generated synopsis
         * @see Help#customSynopsis
         * @see Help#customSynopsis(Object...) */</span>
        <span class="predefined-type">String</span><span class="type">[]</span> customSynopsis() <span class="keyword">default</span> {};

        <span class="comment">/** Set the heading preceding the description section. May contain embedded {@linkplain java.util.Formatter format specifiers}.
         * @return the heading preceding the description section
         * @see Help#descriptionHeading(Object...)  */</span>
        <span class="predefined-type">String</span> descriptionHeading() <span class="keyword">default</span> <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;

        <span class="comment">/** Optional text to display between the synopsis line(s) and the list of options.
         * @return description of this command
         * @see Help#description
         * @see Help#description(Object...) */</span>
        <span class="predefined-type">String</span><span class="type">[]</span> description() <span class="keyword">default</span> {};

        <span class="comment">/** Set the heading preceding the parameters list. May contain embedded {@linkplain java.util.Formatter format specifiers}.
         * @return the heading preceding the parameters list
         * @see Help#parameterListHeading(Object...)  */</span>
        <span class="predefined-type">String</span> parameterListHeading() <span class="keyword">default</span> <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;

        <span class="comment">/** Set the heading preceding the options list. May contain embedded {@linkplain java.util.Formatter format specifiers}.
         * @return the heading preceding the options list
         * @see Help#optionListHeading(Object...)  */</span>
        <span class="predefined-type">String</span> optionListHeading() <span class="keyword">default</span> <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;

        <span class="comment">/** Specify {@code false} to show Options in declaration order. The default is to sort alphabetically.
         * @return whether options should be shown in alphabetic order.
         * @see Help#sortOptions */</span>
        <span class="type">boolean</span> sortOptions() <span class="keyword">default</span> <span class="predefined-constant">true</span>;

        <span class="comment">/** Prefix required options with this character in the options list. The default is no marker: the synopsis
         * indicates which options and parameters are required.
         * @return the character to show in the options list to mark required options
         * @see Help#requiredOptionMarker */</span>
        <span class="type">char</span> requiredOptionMarker() <span class="keyword">default</span> <span class="string"><span class="delimiter">'</span><span class="content"> </span><span class="delimiter">'</span></span>;

        <span class="comment">/** Specify {@code true} to show default values in the description column of the options list (except for
         * boolean options). False by default.
         * @return whether the default values for options and parameters should be shown in the description column
         * @see Help#showDefaultValues */</span>
        <span class="type">boolean</span> showDefaultValues() <span class="keyword">default</span> <span class="predefined-constant">false</span>;

        <span class="comment">/** Set the heading preceding the subcommands list. May contain embedded {@linkplain java.util.Formatter format specifiers}.
         * The default heading is {@code &quot;Commands:%n&quot;} (with a line break at the end).
         * @return the heading preceding the subcommands list
         * @see Help#commandListHeading(Object...)  */</span>
        <span class="predefined-type">String</span> commandListHeading() <span class="keyword">default</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">Commands:%n</span><span class="delimiter">&quot;</span></span>;

        <span class="comment">/** Set the heading preceding the footer section. May contain embedded {@linkplain java.util.Formatter format specifiers}.
         * @return the heading preceding the footer section
         * @see Help#footerHeading(Object...)  */</span>
        <span class="predefined-type">String</span> footerHeading() <span class="keyword">default</span> <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;

        <span class="comment">/** Optional text to display after the list of options.
         * @return text to display after the list of options
         * @see Help#footer
         * @see Help#footer(Object...) */</span>
        <span class="predefined-type">String</span><span class="type">[]</span> footer() <span class="keyword">default</span> {};
    }
    <span class="comment">/**
     * &lt;p&gt;
     * When parsing command line arguments and initializing
     * fields annotated with {@link Option @Option} or {@link Parameters @Parameters},
     * String values can be converted to any type for which a {@code ITypeConverter} is registered.
     * &lt;/p&gt;&lt;p&gt;
     * This interface defines the contract for classes that know how to convert a String into some domain object.
     * Custom converters can be registered with the {@link #registerConverter(Class, ITypeConverter)} method.
     * &lt;/p&gt;&lt;p&gt;
     * Java 8 lambdas make it easy to register custom type converters:
     * &lt;/p&gt;
     * &lt;pre&gt;
     * commandLine.registerConverter(java.nio.file.Path.class, s -&amp;gt; java.nio.file.Paths.get(s));
     * commandLine.registerConverter(java.time.Duration.class, s -&amp;gt; java.time.Duration.parse(s));&lt;/pre&gt;
     * &lt;p&gt;
     * Built-in type converters are pre-registered for the following java 1.5 types:
     * &lt;/p&gt;
     * &lt;ul&gt;
     *   &lt;li&gt;all primitive types&lt;/li&gt;
     *   &lt;li&gt;all primitive wrapper types: Boolean, Byte, Character, Double, Float, Integer, Long, Short&lt;/li&gt;
     *   &lt;li&gt;any enum&lt;/li&gt;
     *   &lt;li&gt;java.io.File&lt;/li&gt;
     *   &lt;li&gt;java.math.BigDecimal&lt;/li&gt;
     *   &lt;li&gt;java.math.BigInteger&lt;/li&gt;
     *   &lt;li&gt;java.net.InetAddress&lt;/li&gt;
     *   &lt;li&gt;java.net.URI&lt;/li&gt;
     *   &lt;li&gt;java.net.URL&lt;/li&gt;
     *   &lt;li&gt;java.nio.charset.Charset&lt;/li&gt;
     *   &lt;li&gt;java.sql.Time&lt;/li&gt;
     *   &lt;li&gt;java.util.Date&lt;/li&gt;
     *   &lt;li&gt;java.util.UUID&lt;/li&gt;
     *   &lt;li&gt;java.util.regex.Pattern&lt;/li&gt;
     *   &lt;li&gt;StringBuilder&lt;/li&gt;
     *   &lt;li&gt;CharSequence&lt;/li&gt;
     *   &lt;li&gt;String&lt;/li&gt;
     * &lt;/ul&gt;
     * @param &lt;K&gt; the type of the object that is the result of the conversion
     */</span>
    <span class="directive">public</span> <span class="type">interface</span> <span class="class">ITypeConverter</span>&lt;K&gt; {
        <span class="comment">/**
         * Converts the specified command line argument value to some domain object.
         * @param value the command line argument String value
         * @return the resulting domain object
         * @throws Exception an exception detailing what went wrong during the conversion
         */</span>
        K convert(<span class="predefined-type">String</span> value) <span class="directive">throws</span> <span class="exception">Exception</span>;
    }

    <span class="comment">/**
     * Provides version information for a command. Commands may configure a provider with the
     * {@link Command#versionProvider()} annotation attribute.
     */</span>
    <span class="directive">public</span> <span class="type">interface</span> <span class="class">IVersionProvider</span> {
        <span class="comment">/**
         * Returns version information for a command.
         * @return version information (each string in the array is displayed on a separate line)
         * @throws Exception an exception detailing what went wrong when obtaining version information
         */</span>
        <span class="predefined-type">String</span><span class="type">[]</span> getVersion() <span class="directive">throws</span> <span class="exception">Exception</span>;
    }
    <span class="directive">private</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">NoVersionProvider</span> <span class="directive">implements</span> IVersionProvider {
        <span class="directive">public</span> <span class="predefined-type">String</span><span class="type">[]</span> getVersion() <span class="directive">throws</span> <span class="exception">Exception</span> { <span class="keyword">throw</span> <span class="keyword">new</span> <span class="exception">UnsupportedOperationException</span>(); }
    }

    <span class="comment">/**
     * Factory for instantiating classes that are registered declaratively with annotation attributes, like
     * {@link Command#subcommands()}, {@link Option#converter()}, {@link Parameters#converter()} and {@link Command#versionProvider()}.
     */</span>
    <span class="directive">public</span> <span class="type">interface</span> <span class="class">IFactory</span> {
        <span class="comment">/**
         * Creates and returns an instance of the specified class.
         * @param cls the class to instantiate
         * @param &lt;K&gt; the type to instantiate
         * @return the new instance
         * @throws Exception an exception detailing what went wrong when creating the instance
         */</span>
        &lt;K&gt; K create(<span class="predefined-type">Class</span>&lt;K&gt; cls) <span class="directive">throws</span> <span class="exception">Exception</span>;
    }
    <span class="directive">private</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">DefaultFactory</span> <span class="directive">implements</span> IFactory {
        <span class="directive">public</span> &lt;T&gt; T create(<span class="predefined-type">Class</span>&lt;T&gt; cls) <span class="directive">throws</span> <span class="exception">Exception</span> {
            <span class="keyword">try</span> {
                <span class="keyword">return</span> cls.newInstance();
            } <span class="keyword">catch</span> (<span class="exception">Exception</span> ex) {
                <span class="predefined-type">Constructor</span>&lt;T&gt; constructor = cls.getDeclaredConstructor();
                constructor.setAccessible(<span class="predefined-constant">true</span>);
                <span class="keyword">return</span> constructor.newInstance();
            }
        }
    }
    <span class="comment">/** Describes the number of parameters required and accepted by an option or a positional parameter.
     * @since 0.9.7
     */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">Range</span> <span class="directive">implements</span> <span class="predefined-type">Comparable</span>&lt;Range&gt; {
        <span class="comment">/** Required number of parameters for an option or positional parameter. */</span>
        <span class="directive">public</span> <span class="directive">final</span> <span class="type">int</span> min;
        <span class="comment">/** Maximum accepted number of parameters for an option or positional parameter. */</span>
        <span class="directive">public</span> <span class="directive">final</span> <span class="type">int</span> max;
        <span class="directive">public</span> <span class="directive">final</span> <span class="type">boolean</span> isVariable;
        <span class="directive">private</span> <span class="directive">final</span> <span class="type">boolean</span> isUnspecified;
        <span class="directive">private</span> <span class="directive">final</span> <span class="predefined-type">String</span> originalValue;

        <span class="comment">/** Constructs a new Range object with the specified parameters.
         * @param min minimum number of required parameters
         * @param max maximum number of allowed parameters (or Integer.MAX_VALUE if variable)
         * @param variable {@code true} if any number or parameters is allowed, {@code false} otherwise
         * @param unspecified {@code true} if no arity was specified on the option/parameter (value is based on type)
         * @param originalValue the original value that was specified on the option or parameter
         */</span>
        <span class="directive">public</span> Range(<span class="type">int</span> min, <span class="type">int</span> max, <span class="type">boolean</span> variable, <span class="type">boolean</span> unspecified, <span class="predefined-type">String</span> originalValue) {
            <span class="local-variable">this</span>.min = min;
            <span class="local-variable">this</span>.max = max;
            <span class="local-variable">this</span>.isVariable = variable;
            <span class="local-variable">this</span>.isUnspecified = unspecified;
            <span class="local-variable">this</span>.originalValue = originalValue;
        }
        <span class="comment">/** Returns a new {@code Range} based on the {@link Option#arity()} annotation on the specified field,
         * or the field type's default arity if no arity was specified.
         * @param field the field whose Option annotation to inspect
         * @return a new {@code Range} based on the Option arity annotation on the specified field */</span>
        <span class="directive">public</span> <span class="directive">static</span> Range optionArity(<span class="predefined-type">Field</span> field) {
            <span class="keyword">return</span> field.isAnnotationPresent(<span class="predefined-type">Option</span>.class)
                    ? adjustForType(Range.valueOf(field.getAnnotation(<span class="predefined-type">Option</span>.class).arity()), field)
                    : <span class="keyword">new</span> Range(<span class="integer">0</span>, <span class="integer">0</span>, <span class="predefined-constant">false</span>, <span class="predefined-constant">true</span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">0</span><span class="delimiter">&quot;</span></span>);
        }
        <span class="comment">/** Returns a new {@code Range} based on the {@link Parameters#arity()} annotation on the specified field,
         * or the field type's default arity if no arity was specified.
         * @param field the field whose Parameters annotation to inspect
         * @return a new {@code Range} based on the Parameters arity annotation on the specified field */</span>
        <span class="directive">public</span> <span class="directive">static</span> Range parameterArity(<span class="predefined-type">Field</span> field) {
            <span class="keyword">return</span> field.isAnnotationPresent(Parameters.class)
                    ? adjustForType(Range.valueOf(field.getAnnotation(Parameters.class).arity()), field)
                    : <span class="keyword">new</span> Range(<span class="integer">0</span>, <span class="integer">0</span>, <span class="predefined-constant">false</span>, <span class="predefined-constant">true</span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">0</span><span class="delimiter">&quot;</span></span>);
        }
        <span class="comment">/** Returns a new {@code Range} based on the {@link Parameters#index()} annotation on the specified field.
         * @param field the field whose Parameters annotation to inspect
         * @return a new {@code Range} based on the Parameters index annotation on the specified field */</span>
        <span class="directive">public</span> <span class="directive">static</span> Range parameterIndex(<span class="predefined-type">Field</span> field) {
            <span class="keyword">return</span> field.isAnnotationPresent(Parameters.class)
                    ? Range.valueOf(field.getAnnotation(Parameters.class).index())
                    : <span class="keyword">new</span> Range(<span class="integer">0</span>, <span class="integer">0</span>, <span class="predefined-constant">false</span>, <span class="predefined-constant">true</span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">0</span><span class="delimiter">&quot;</span></span>);
        }
        <span class="directive">static</span> Range adjustForType(Range result, <span class="predefined-type">Field</span> field) {
            <span class="keyword">return</span> result.isUnspecified ? defaultArity(field) : result;
        }
        <span class="comment">/** Returns the default arity {@code Range}: for {@link Option options} this is 0 for booleans and 1 for
         * other types, for {@link Parameters parameters} booleans have arity 0, arrays or Collections have
         * arity &quot;0..*&quot;, and other types have arity 1.
         * @param field the field whose default arity to return
         * @return a new {@code Range} indicating the default arity of the specified field
         * @since 2.0 */</span>
        <span class="directive">public</span> <span class="directive">static</span> Range defaultArity(<span class="predefined-type">Field</span> field) {
            <span class="predefined-type">Class</span>&lt;?&gt; type = field.getType();
            <span class="keyword">if</span> (field.isAnnotationPresent(<span class="predefined-type">Option</span>.class)) {
                <span class="type">boolean</span> zeroArgs = isBoolean(type) || (isMultiValue(type) &amp;&amp; isBoolean(getTypeAttribute(field)[<span class="integer">0</span>]));
                <span class="keyword">return</span> zeroArgs ? Range.valueOf(<span class="string"><span class="delimiter">&quot;</span><span class="content">0</span><span class="delimiter">&quot;</span></span>) : Range.valueOf(<span class="string"><span class="delimiter">&quot;</span><span class="content">1</span><span class="delimiter">&quot;</span></span>);
            }
            <span class="keyword">if</span> (isMultiValue(type)) {
                <span class="keyword">return</span> Range.valueOf(<span class="string"><span class="delimiter">&quot;</span><span class="content">0..1</span><span class="delimiter">&quot;</span></span>);
            }
            <span class="keyword">return</span> Range.valueOf(<span class="string"><span class="delimiter">&quot;</span><span class="content">1</span><span class="delimiter">&quot;</span></span>);<span class="comment">// for single-valued fields (incl. boolean positional parameters)</span>
        }
        <span class="comment">/** Returns the default arity {@code Range} for {@link Option options}: booleans have arity 0, other types have arity 1.
         * @param type the type whose default arity to return
         * @return a new {@code Range} indicating the default arity of the specified type
         * @deprecated use {@link #defaultArity(Field)} instead */</span>
        <span class="annotation">@Deprecated</span> <span class="directive">public</span> <span class="directive">static</span> Range defaultArity(<span class="predefined-type">Class</span>&lt;?&gt; type) {
            <span class="keyword">return</span> isBoolean(type) ? Range.valueOf(<span class="string"><span class="delimiter">&quot;</span><span class="content">0</span><span class="delimiter">&quot;</span></span>) : Range.valueOf(<span class="string"><span class="delimiter">&quot;</span><span class="content">1</span><span class="delimiter">&quot;</span></span>);
        }
        <span class="directive">private</span> <span class="type">int</span> size() { <span class="keyword">return</span> <span class="integer">1</span> + max - min; }
        <span class="directive">static</span> Range parameterCapacity(<span class="predefined-type">Field</span> field) {
            Range arity = parameterArity(field);
            <span class="keyword">if</span> (!isMultiValue(field)) { <span class="keyword">return</span> arity; }
            Range index = parameterIndex(field);
            <span class="keyword">if</span> (arity.max == <span class="integer">0</span>)    { <span class="keyword">return</span> arity; }
            <span class="keyword">if</span> (index.size() == <span class="integer">1</span>) { <span class="keyword">return</span> arity; }
            <span class="keyword">if</span> (index.isVariable)  { <span class="keyword">return</span> Range.valueOf(arity.min + <span class="string"><span class="delimiter">&quot;</span><span class="content">..*</span><span class="delimiter">&quot;</span></span>); }
            <span class="keyword">if</span> (arity.size() == <span class="integer">1</span>) { <span class="keyword">return</span> Range.valueOf(arity.min * index.size() + <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>); }
            <span class="keyword">if</span> (arity.isVariable)  { <span class="keyword">return</span> Range.valueOf(arity.min * index.size() + <span class="string"><span class="delimiter">&quot;</span><span class="content">..*</span><span class="delimiter">&quot;</span></span>); }
            <span class="keyword">return</span> Range.valueOf(arity.min * index.size() + <span class="string"><span class="delimiter">&quot;</span><span class="content">..</span><span class="delimiter">&quot;</span></span> + arity.max * index.size());
        }
        <span class="comment">/** Leniently parses the specified String as an {@code Range} value and return the result. A range string can
         * be a fixed integer value or a range of the form {@code MIN_VALUE + &quot;..&quot; + MAX_VALUE}. If the
         * {@code MIN_VALUE} string is not numeric, the minimum is zero. If the {@code MAX_VALUE} is not numeric, the
         * range is taken to be variable and the maximum is {@code Integer.MAX_VALUE}.
         * @param range the value range string to parse
         * @return a new {@code Range} value */</span>
        <span class="directive">public</span> <span class="directive">static</span> Range valueOf(<span class="predefined-type">String</span> range) {
            range = range.trim();
            <span class="type">boolean</span> unspecified = range.length() == <span class="integer">0</span> || range.startsWith(<span class="string"><span class="delimiter">&quot;</span><span class="content">..</span><span class="delimiter">&quot;</span></span>); <span class="comment">// || range.endsWith(&quot;..&quot;);</span>
            <span class="type">int</span> min = -<span class="integer">1</span>, max = -<span class="integer">1</span>;
            <span class="type">boolean</span> variable = <span class="predefined-constant">false</span>;
            <span class="type">int</span> dots = -<span class="integer">1</span>;
            <span class="keyword">if</span> ((dots = range.indexOf(<span class="string"><span class="delimiter">&quot;</span><span class="content">..</span><span class="delimiter">&quot;</span></span>)) &gt;= <span class="integer">0</span>) {
                min = parseInt(range.substring(<span class="integer">0</span>, dots), <span class="integer">0</span>);
                max = parseInt(range.substring(dots + <span class="integer">2</span>), <span class="predefined-type">Integer</span>.MAX_VALUE);
                variable = max == <span class="predefined-type">Integer</span>.MAX_VALUE;
            } <span class="keyword">else</span> {
                max = parseInt(range, <span class="predefined-type">Integer</span>.MAX_VALUE);
                variable = max == <span class="predefined-type">Integer</span>.MAX_VALUE;
                min = variable ? <span class="integer">0</span> : max;
            }
            Range result = <span class="keyword">new</span> Range(min, max, variable, unspecified, range);
            <span class="keyword">return</span> result;
        }
        <span class="directive">private</span> <span class="directive">static</span> <span class="type">int</span> parseInt(<span class="predefined-type">String</span> str, <span class="type">int</span> defaultValue) {
            <span class="keyword">try</span> {
                <span class="keyword">return</span> <span class="predefined-type">Integer</span>.parseInt(str);
            } <span class="keyword">catch</span> (<span class="exception">Exception</span> ex) {
                <span class="keyword">return</span> defaultValue;
            }
        }
        <span class="comment">/** Returns a new Range object with the {@code min} value replaced by the specified value.
         * The {@code max} of the returned Range is guaranteed not to be less than the new {@code min} value.
         * @param newMin the {@code min} value of the returned Range object
         * @return a new Range object with the specified {@code min} value */</span>
        <span class="directive">public</span> Range min(<span class="type">int</span> newMin) { <span class="keyword">return</span> <span class="keyword">new</span> Range(newMin, <span class="predefined-type">Math</span>.max(newMin, max), isVariable, isUnspecified, originalValue); }

        <span class="comment">/** Returns a new Range object with the {@code max} value replaced by the specified value.
         * The {@code min} of the returned Range is guaranteed not to be greater than the new {@code max} value.
         * @param newMax the {@code max} value of the returned Range object
         * @return a new Range object with the specified {@code max} value */</span>
        <span class="directive">public</span> Range max(<span class="type">int</span> newMax) { <span class="keyword">return</span> <span class="keyword">new</span> Range(<span class="predefined-type">Math</span>.min(min, newMax), newMax, isVariable, isUnspecified, originalValue); }

        <span class="comment">/**
         * Returns {@code true} if this Range includes the specified value, {@code false} otherwise.
         * @param value the value to check
         * @return {@code true} if the specified value is not less than the minimum and not greater than the maximum of this Range
         */</span>
        <span class="directive">public</span> <span class="type">boolean</span> contains(<span class="type">int</span> value) { <span class="keyword">return</span> min &lt;= value &amp;&amp; max &gt;= value; }

        <span class="directive">public</span> <span class="type">boolean</span> equals(<span class="predefined-type">Object</span> object) {
            <span class="keyword">if</span> (!(object <span class="keyword">instanceof</span> Range)) { <span class="keyword">return</span> <span class="predefined-constant">false</span>; }
            Range other = (Range) object;
            <span class="keyword">return</span> other.max == <span class="local-variable">this</span>.max &amp;&amp; other.min == <span class="local-variable">this</span>.min &amp;&amp; other.isVariable == <span class="local-variable">this</span>.isVariable;
        }
        <span class="directive">public</span> <span class="type">int</span> hashCode() {
            <span class="keyword">return</span> ((<span class="integer">17</span> * <span class="integer">37</span> + max) * <span class="integer">37</span> + min) * <span class="integer">37</span> + (isVariable ? <span class="integer">1</span> : <span class="integer">0</span>);
        }
        <span class="directive">public</span> <span class="predefined-type">String</span> toString() {
            <span class="keyword">return</span> min == max ? <span class="predefined-type">String</span>.valueOf(min) : min + <span class="string"><span class="delimiter">&quot;</span><span class="content">..</span><span class="delimiter">&quot;</span></span> + (isVariable ? <span class="string"><span class="delimiter">&quot;</span><span class="content">*</span><span class="delimiter">&quot;</span></span> : max);
        }
        <span class="directive">public</span> <span class="type">int</span> compareTo(Range other) {
            <span class="type">int</span> result = min - other.min;
            <span class="keyword">return</span> (result == <span class="integer">0</span>) ? max - other.max : result;
        }
    }
    <span class="directive">static</span> <span class="type">void</span> init(<span class="predefined-type">Class</span>&lt;?&gt; cls,
                              <span class="predefined-type">List</span>&lt;<span class="predefined-type">Field</span>&gt; requiredFields,
                              <span class="predefined-type">Map</span>&lt;<span class="predefined-type">String</span>, <span class="predefined-type">Field</span>&gt; optionName2Field,
                              <span class="predefined-type">Map</span>&lt;<span class="predefined-type">Character</span>, <span class="predefined-type">Field</span>&gt; singleCharOption2Field,
                              <span class="predefined-type">List</span>&lt;<span class="predefined-type">Field</span>&gt; positionalParametersFields) {
        <span class="predefined-type">Field</span><span class="type">[]</span> declaredFields = cls.getDeclaredFields();
        <span class="keyword">for</span> (<span class="predefined-type">Field</span> field : declaredFields) {
            <span class="type">boolean</span> isOption = field.isAnnotationPresent(<span class="predefined-type">Option</span>.class);
            <span class="type">boolean</span> isPositional = field.isAnnotationPresent(Parameters.class);
            <span class="keyword">if</span> (isOption &amp;&amp; isPositional) {
                <span class="keyword">throw</span> <span class="keyword">new</span> DuplicateOptionAnnotationsException(<span class="string"><span class="delimiter">&quot;</span><span class="content">A field can be either @Option or @Parameters, but '</span><span class="delimiter">&quot;</span></span>
                        + field + <span class="string"><span class="delimiter">&quot;</span><span class="content">' is both.</span><span class="delimiter">&quot;</span></span>);
            }
            <span class="keyword">if</span> (!isOption &amp;&amp; !isPositional) { <span class="keyword">continue</span>; }
            <span class="keyword">if</span> (<span class="predefined-type">Modifier</span>.isFinal(field.getModifiers()) &amp;&amp; (field.getType().isPrimitive() || <span class="predefined-type">String</span>.class.isAssignableFrom(field.getType()))) {
                <span class="keyword">throw</span> <span class="keyword">new</span> InitializationException(<span class="string"><span class="delimiter">&quot;</span><span class="content">Constant (final) primitive and String fields like </span><span class="delimiter">&quot;</span></span> + field + <span class="string"><span class="delimiter">&quot;</span><span class="content"> cannot be used as </span><span class="delimiter">&quot;</span></span> +
                        (isOption ? <span class="string"><span class="delimiter">&quot;</span><span class="content">an @Option</span><span class="delimiter">&quot;</span></span> : <span class="string"><span class="delimiter">&quot;</span><span class="content">a @Parameter</span><span class="delimiter">&quot;</span></span>) + <span class="string"><span class="delimiter">&quot;</span><span class="content">: compile-time constant inlining may hide new values written to it.</span><span class="delimiter">&quot;</span></span>);
            }
            field.setAccessible(<span class="predefined-constant">true</span>);
            <span class="keyword">if</span> (isOption) {
                <span class="predefined-type">Option</span> option = field.getAnnotation(<span class="predefined-type">Option</span>.class);
                <span class="keyword">if</span> (option.required()) {
                    requiredFields.add(field);
                }
                <span class="keyword">for</span> (<span class="predefined-type">String</span> name : option.names()) { <span class="comment">// cannot be null or empty</span>
                    <span class="predefined-type">Field</span> existing = optionName2Field.put(name, field);
                    <span class="keyword">if</span> (existing != <span class="predefined-constant">null</span> &amp;&amp; existing != field) {
                        <span class="keyword">throw</span> DuplicateOptionAnnotationsException.create(name, field, existing);
                    }
                    <span class="keyword">if</span> (name.length() == <span class="integer">2</span> &amp;&amp; name.startsWith(<span class="string"><span class="delimiter">&quot;</span><span class="content">-</span><span class="delimiter">&quot;</span></span>)) {
                        <span class="type">char</span> flag = name.charAt(<span class="integer">1</span>);
                        <span class="predefined-type">Field</span> existing2 = singleCharOption2Field.put(flag, field);
                        <span class="keyword">if</span> (existing2 != <span class="predefined-constant">null</span> &amp;&amp; existing2 != field) {
                            <span class="keyword">throw</span> DuplicateOptionAnnotationsException.create(name, field, existing2);
                        }
                    }
                }
            }
            <span class="keyword">if</span> (isPositional) {
                positionalParametersFields.add(field);
                Range arity = Range.parameterArity(field);
                <span class="keyword">if</span> (arity.min &gt; <span class="integer">0</span>) {
                    requiredFields.add(field);
                }
            }
        }
    }
    <span class="directive">static</span> <span class="type">void</span> validatePositionalParameters(<span class="predefined-type">List</span>&lt;<span class="predefined-type">Field</span>&gt; positionalParametersFields) {
        <span class="type">int</span> min = <span class="integer">0</span>;
        <span class="keyword">for</span> (<span class="predefined-type">Field</span> field : positionalParametersFields) {
            Range index = Range.parameterIndex(field);
            <span class="keyword">if</span> (index.min &gt; min) {
                <span class="keyword">throw</span> <span class="keyword">new</span> ParameterIndexGapException(<span class="string"><span class="delimiter">&quot;</span><span class="content">Missing field annotated with @Parameter(index=</span><span class="delimiter">&quot;</span></span> + min +
                        <span class="string"><span class="delimiter">&quot;</span><span class="content">). Nearest field '</span><span class="delimiter">&quot;</span></span> + field.getName() + <span class="string"><span class="delimiter">&quot;</span><span class="content">' has index=</span><span class="delimiter">&quot;</span></span> + index.min);
            }
            min = <span class="predefined-type">Math</span>.max(min, index.max);
            min = min == <span class="predefined-type">Integer</span>.MAX_VALUE ? min : min + <span class="integer">1</span>;
        }
    }
    <span class="directive">private</span> <span class="directive">static</span> &lt;T&gt; <span class="predefined-type">Stack</span>&lt;T&gt; reverse(<span class="predefined-type">Stack</span>&lt;T&gt; stack) {
        <span class="predefined-type">Collections</span>.reverse(stack);
        <span class="keyword">return</span> stack;
    }
    <span class="directive">private</span> <span class="directive">static</span> &lt;T&gt; <span class="predefined-type">List</span>&lt;T&gt; reverseList(<span class="predefined-type">List</span>&lt;T&gt; list) {
        <span class="predefined-type">Collections</span>.reverse(list);
        <span class="keyword">return</span> list;
    }
    <span class="comment">/**
     * Helper class responsible for processing command line arguments.
     */</span>
    <span class="directive">private</span> <span class="type">class</span> <span class="class">Interpreter</span> {
        <span class="directive">private</span> <span class="directive">final</span> <span class="predefined-type">Map</span>&lt;<span class="predefined-type">String</span>, CommandLine&gt; commands                  = <span class="keyword">new</span> <span class="predefined-type">LinkedHashMap</span>&lt;<span class="predefined-type">String</span>, CommandLine&gt;();
        <span class="directive">private</span> <span class="directive">final</span> <span class="predefined-type">Map</span>&lt;<span class="predefined-type">Class</span>&lt;?&gt;, ITypeConverter&lt;?&gt;&gt; converterRegistry = <span class="keyword">new</span> <span class="predefined-type">HashMap</span>&lt;<span class="predefined-type">Class</span>&lt;?&gt;, ITypeConverter&lt;?&gt;&gt;();
        <span class="directive">private</span> <span class="directive">final</span> <span class="predefined-type">Map</span>&lt;<span class="predefined-type">String</span>, <span class="predefined-type">Field</span>&gt; optionName2Field                = <span class="keyword">new</span> <span class="predefined-type">HashMap</span>&lt;<span class="predefined-type">String</span>, <span class="predefined-type">Field</span>&gt;();
        <span class="directive">private</span> <span class="directive">final</span> <span class="predefined-type">Map</span>&lt;<span class="predefined-type">Character</span>, <span class="predefined-type">Field</span>&gt; singleCharOption2Field       = <span class="keyword">new</span> <span class="predefined-type">HashMap</span>&lt;<span class="predefined-type">Character</span>, <span class="predefined-type">Field</span>&gt;();
        <span class="directive">private</span> <span class="directive">final</span> <span class="predefined-type">List</span>&lt;<span class="predefined-type">Field</span>&gt; requiredFields                         = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">Field</span>&gt;();
        <span class="directive">private</span> <span class="directive">final</span> <span class="predefined-type">List</span>&lt;<span class="predefined-type">Field</span>&gt; positionalParametersFields             = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">Field</span>&gt;();
        <span class="directive">private</span> <span class="directive">final</span> <span class="predefined-type">Object</span> command;
        <span class="directive">private</span> <span class="directive">final</span> IFactory factory;
        <span class="directive">private</span> <span class="type">boolean</span> isHelpRequested;
        <span class="directive">private</span> <span class="predefined-type">String</span> separator = Help.DEFAULT_SEPARATOR;
        <span class="directive">private</span> <span class="type">int</span> position;
        <span class="directive">private</span> <span class="type">boolean</span> endOfOptions;

        Interpreter(<span class="predefined-type">Object</span> command, IFactory factory) {
            <span class="local-variable">this</span>.command                 = Assert.notNull(command, <span class="string"><span class="delimiter">&quot;</span><span class="content">command</span><span class="delimiter">&quot;</span></span>);
            <span class="local-variable">this</span>.factory                 = Assert.notNull(factory, <span class="string"><span class="delimiter">&quot;</span><span class="content">factory</span><span class="delimiter">&quot;</span></span>);
            <span class="predefined-type">Class</span>&lt;?&gt; cls                 = command.getClass();
            <span class="predefined-type">String</span> declaredName          = <span class="predefined-constant">null</span>;
            <span class="predefined-type">String</span> declaredSeparator     = <span class="predefined-constant">null</span>;
            <span class="type">boolean</span> hasCommandAnnotation = <span class="predefined-constant">false</span>;
            <span class="keyword">while</span> (cls != <span class="predefined-constant">null</span>) {
                init(cls, requiredFields, optionName2Field, singleCharOption2Field, positionalParametersFields);
                <span class="keyword">if</span> (cls.isAnnotationPresent(Command.class)) {
                    hasCommandAnnotation = <span class="predefined-constant">true</span>;
                    Command cmd = cls.getAnnotation(Command.class);
                    declaredSeparator = (declaredSeparator == <span class="predefined-constant">null</span>) ? cmd.separator() : declaredSeparator;
                    declaredName = (declaredName == <span class="predefined-constant">null</span>) ? cmd.name() : declaredName;

                    <span class="keyword">if</span> (cmd.versionProvider() != <span class="predefined-constant">null</span> &amp;&amp; cmd.versionProvider() != NoVersionProvider.class) {
                        <span class="keyword">try</span> {
                            IVersionProvider provider = factory.create(cmd.versionProvider());
                            CommandLine.this.versionLines.addAll(<span class="predefined-type">Arrays</span>.asList(provider.getVersion()));
                        } <span class="keyword">catch</span> (InitializationException ex) {
                            <span class="keyword">throw</span> ex;
                        } <span class="keyword">catch</span> (<span class="exception">Exception</span> ex) {
                            <span class="keyword">throw</span> <span class="keyword">new</span> InitializationException(<span class="string"><span class="delimiter">&quot;</span><span class="content">Could not get version info from </span><span class="delimiter">&quot;</span></span> + cmd.versionProvider() + <span class="string"><span class="delimiter">&quot;</span><span class="content">: </span><span class="delimiter">&quot;</span></span> + ex, ex);
                        }
                    } <span class="keyword">else</span> {
                        CommandLine.this.versionLines.addAll(<span class="predefined-type">Arrays</span>.asList(cmd.version()));
                    }

                    <span class="keyword">for</span> (<span class="predefined-type">Class</span>&lt;?&gt; sub : cmd.subcommands()) {
                        Command subCommand = sub.getAnnotation(Command.class);
                        <span class="keyword">if</span> (subCommand == <span class="predefined-constant">null</span> || Help.DEFAULT_COMMAND_NAME.equals(subCommand.name())) {
                            <span class="keyword">throw</span> <span class="keyword">new</span> InitializationException(<span class="string"><span class="delimiter">&quot;</span><span class="content">Subcommand </span><span class="delimiter">&quot;</span></span> + sub.getName() +
                                    <span class="string"><span class="delimiter">&quot;</span><span class="content"> is missing the mandatory @Command annotation with a 'name' attribute</span><span class="delimiter">&quot;</span></span>);
                        }
                        <span class="keyword">try</span> {
                            CommandLine commandLine = toCommandLine(factory.create(sub), factory);
                            commandLine.parent = CommandLine.this;
                            commands.put(subCommand.name(), commandLine);
                            commandLine.interpreter.initParentCommand(command);
                        }
                        <span class="keyword">catch</span> (InitializationException ex) { <span class="keyword">throw</span> ex; }
                        <span class="keyword">catch</span> (<span class="exception">NoSuchMethodException</span> ex) { <span class="keyword">throw</span> <span class="keyword">new</span> InitializationException(<span class="string"><span class="delimiter">&quot;</span><span class="content">Cannot instantiate subcommand </span><span class="delimiter">&quot;</span></span> +
                                sub.getName() + <span class="string"><span class="delimiter">&quot;</span><span class="content">: the class has no constructor</span><span class="delimiter">&quot;</span></span>, ex); }
                        <span class="keyword">catch</span> (<span class="exception">Exception</span> ex) {
                            <span class="keyword">throw</span> <span class="keyword">new</span> InitializationException(<span class="string"><span class="delimiter">&quot;</span><span class="content">Could not instantiate and add subcommand </span><span class="delimiter">&quot;</span></span> +
                                    sub.getName() + <span class="string"><span class="delimiter">&quot;</span><span class="content">: </span><span class="delimiter">&quot;</span></span> + ex, ex);
                        }
                    }
                }
                cls = cls.getSuperclass();
            }
            separator = declaredSeparator != <span class="predefined-constant">null</span> ? declaredSeparator : separator;
            CommandLine.this.commandName = declaredName != <span class="predefined-constant">null</span> ? declaredName : CommandLine.this.commandName;
            <span class="predefined-type">Collections</span>.sort(positionalParametersFields, <span class="keyword">new</span> PositionalParametersSorter());
            validatePositionalParameters(positionalParametersFields);

            <span class="keyword">if</span> (positionalParametersFields.isEmpty() &amp;&amp; optionName2Field.isEmpty() &amp;&amp; !hasCommandAnnotation) {
                <span class="keyword">throw</span> <span class="keyword">new</span> InitializationException(command + <span class="string"><span class="delimiter">&quot;</span><span class="content"> (</span><span class="delimiter">&quot;</span></span> + command.getClass() +
                        <span class="string"><span class="delimiter">&quot;</span><span class="content">) is not a command: it has no @Command, @Option or @Parameters annotations</span><span class="delimiter">&quot;</span></span>);
            }
            registerBuiltInConverters();
        }

        <span class="directive">private</span> <span class="type">void</span> registerBuiltInConverters() {
            converterRegistry.put(<span class="predefined-type">Object</span>.class,        <span class="keyword">new</span> BuiltIn.StringConverter());
            converterRegistry.put(<span class="predefined-type">String</span>.class,        <span class="keyword">new</span> BuiltIn.StringConverter());
            converterRegistry.put(<span class="predefined-type">StringBuilder</span>.class, <span class="keyword">new</span> BuiltIn.StringBuilderConverter());
            converterRegistry.put(<span class="predefined-type">CharSequence</span>.class,  <span class="keyword">new</span> BuiltIn.CharSequenceConverter());
            converterRegistry.put(<span class="predefined-type">Byte</span>.class,          <span class="keyword">new</span> BuiltIn.ByteConverter());
            converterRegistry.put(<span class="predefined-type">Byte</span>.TYPE,           <span class="keyword">new</span> BuiltIn.ByteConverter());
            converterRegistry.put(<span class="predefined-type">Boolean</span>.class,       <span class="keyword">new</span> BuiltIn.BooleanConverter());
            converterRegistry.put(<span class="predefined-type">Boolean</span>.TYPE,        <span class="keyword">new</span> BuiltIn.BooleanConverter());
            converterRegistry.put(<span class="predefined-type">Character</span>.class,     <span class="keyword">new</span> BuiltIn.CharacterConverter());
            converterRegistry.put(<span class="predefined-type">Character</span>.TYPE,      <span class="keyword">new</span> BuiltIn.CharacterConverter());
            converterRegistry.put(<span class="predefined-type">Short</span>.class,         <span class="keyword">new</span> BuiltIn.ShortConverter());
            converterRegistry.put(<span class="predefined-type">Short</span>.TYPE,          <span class="keyword">new</span> BuiltIn.ShortConverter());
            converterRegistry.put(<span class="predefined-type">Integer</span>.class,       <span class="keyword">new</span> BuiltIn.IntegerConverter());
            converterRegistry.put(<span class="predefined-type">Integer</span>.TYPE,        <span class="keyword">new</span> BuiltIn.IntegerConverter());
            converterRegistry.put(<span class="predefined-type">Long</span>.class,          <span class="keyword">new</span> BuiltIn.LongConverter());
            converterRegistry.put(<span class="predefined-type">Long</span>.TYPE,           <span class="keyword">new</span> BuiltIn.LongConverter());
            converterRegistry.put(<span class="predefined-type">Float</span>.class,         <span class="keyword">new</span> BuiltIn.FloatConverter());
            converterRegistry.put(<span class="predefined-type">Float</span>.TYPE,          <span class="keyword">new</span> BuiltIn.FloatConverter());
            converterRegistry.put(<span class="predefined-type">Double</span>.class,        <span class="keyword">new</span> BuiltIn.DoubleConverter());
            converterRegistry.put(<span class="predefined-type">Double</span>.TYPE,         <span class="keyword">new</span> BuiltIn.DoubleConverter());
            converterRegistry.put(<span class="predefined-type">File</span>.class,          <span class="keyword">new</span> BuiltIn.FileConverter());
            converterRegistry.put(<span class="predefined-type">URI</span>.class,           <span class="keyword">new</span> BuiltIn.URIConverter());
            converterRegistry.put(<span class="predefined-type">URL</span>.class,           <span class="keyword">new</span> BuiltIn.URLConverter());
            converterRegistry.put(<span class="predefined-type">Date</span>.class,          <span class="keyword">new</span> BuiltIn.ISO8601DateConverter());
            converterRegistry.put(<span class="predefined-type">Time</span>.class,          <span class="keyword">new</span> BuiltIn.ISO8601TimeConverter());
            converterRegistry.put(<span class="predefined-type">BigDecimal</span>.class,    <span class="keyword">new</span> BuiltIn.BigDecimalConverter());
            converterRegistry.put(<span class="predefined-type">BigInteger</span>.class,    <span class="keyword">new</span> BuiltIn.BigIntegerConverter());
            converterRegistry.put(<span class="predefined-type">Charset</span>.class,       <span class="keyword">new</span> BuiltIn.CharsetConverter());
            converterRegistry.put(<span class="predefined-type">InetAddress</span>.class,   <span class="keyword">new</span> BuiltIn.InetAddressConverter());
            converterRegistry.put(<span class="predefined-type">Pattern</span>.class,       <span class="keyword">new</span> BuiltIn.PatternConverter());
            converterRegistry.put(<span class="predefined-type">UUID</span>.class,          <span class="keyword">new</span> BuiltIn.UUIDConverter());
            converterRegistry.put(<span class="predefined-type">Currency</span>.class,      <span class="keyword">new</span> BuiltIn.CurrencyConverter());
            converterRegistry.put(<span class="predefined-type">TimeZone</span>.class,      <span class="keyword">new</span> BuiltIn.TimeZoneConverter());
            converterRegistry.put(<span class="predefined-type">ByteOrder</span>.class,     <span class="keyword">new</span> BuiltIn.ByteOrderConverter());
            converterRegistry.put(<span class="predefined-type">Class</span>.class,         <span class="keyword">new</span> BuiltIn.ClassConverter());
            converterRegistry.put(<span class="predefined-type">Connection</span>.class,    <span class="keyword">new</span> BuiltIn.ConnectionConverter());
            converterRegistry.put(<span class="predefined-type">Driver</span>.class,        <span class="keyword">new</span> BuiltIn.DriverConverter());
            converterRegistry.put(<span class="predefined-type">Timestamp</span>.class,     <span class="keyword">new</span> BuiltIn.TimestampConverter());
            converterRegistry.put(<span class="predefined-type">NetworkInterface</span>.class, <span class="keyword">new</span> BuiltIn.NetworkInterfaceConverter());

            BuiltIn.registerIfAvailable(converterRegistry, tracer, <span class="string"><span class="delimiter">&quot;</span><span class="content">java.time.Duration</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">parse</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">CharSequence</span>.class);
            BuiltIn.registerIfAvailable(converterRegistry, tracer, <span class="string"><span class="delimiter">&quot;</span><span class="content">java.time.Instant</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">parse</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">CharSequence</span>.class);
            BuiltIn.registerIfAvailable(converterRegistry, tracer, <span class="string"><span class="delimiter">&quot;</span><span class="content">java.time.LocalDate</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">parse</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">CharSequence</span>.class);
            BuiltIn.registerIfAvailable(converterRegistry, tracer, <span class="string"><span class="delimiter">&quot;</span><span class="content">java.time.LocalDateTime</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">parse</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">CharSequence</span>.class);
            BuiltIn.registerIfAvailable(converterRegistry, tracer, <span class="string"><span class="delimiter">&quot;</span><span class="content">java.time.LocalTime</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">parse</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">CharSequence</span>.class);
            BuiltIn.registerIfAvailable(converterRegistry, tracer, <span class="string"><span class="delimiter">&quot;</span><span class="content">java.time.MonthDay</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">parse</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">CharSequence</span>.class);
            BuiltIn.registerIfAvailable(converterRegistry, tracer, <span class="string"><span class="delimiter">&quot;</span><span class="content">java.time.OffsetDateTime</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">parse</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">CharSequence</span>.class);
            BuiltIn.registerIfAvailable(converterRegistry, tracer, <span class="string"><span class="delimiter">&quot;</span><span class="content">java.time.OffsetTime</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">parse</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">CharSequence</span>.class);
            BuiltIn.registerIfAvailable(converterRegistry, tracer, <span class="string"><span class="delimiter">&quot;</span><span class="content">java.time.Period</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">parse</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">CharSequence</span>.class);
            BuiltIn.registerIfAvailable(converterRegistry, tracer, <span class="string"><span class="delimiter">&quot;</span><span class="content">java.time.Year</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">parse</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">CharSequence</span>.class);
            BuiltIn.registerIfAvailable(converterRegistry, tracer, <span class="string"><span class="delimiter">&quot;</span><span class="content">java.time.YearMonth</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">parse</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">CharSequence</span>.class);
            BuiltIn.registerIfAvailable(converterRegistry, tracer, <span class="string"><span class="delimiter">&quot;</span><span class="content">java.time.ZonedDateTime</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">parse</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">CharSequence</span>.class);
            BuiltIn.registerIfAvailable(converterRegistry, tracer, <span class="string"><span class="delimiter">&quot;</span><span class="content">java.time.ZoneId</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">of</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">String</span>.class);
            BuiltIn.registerIfAvailable(converterRegistry, tracer, <span class="string"><span class="delimiter">&quot;</span><span class="content">java.time.ZoneOffset</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">of</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">String</span>.class);

            BuiltIn.registerIfAvailable(converterRegistry, tracer, <span class="string"><span class="delimiter">&quot;</span><span class="content">java.nio.file.Path</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">java.nio.file.Paths</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">get</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">String</span>.class, <span class="predefined-type">String</span><span class="type">[]</span>.class);
        }

        <span class="directive">private</span> <span class="type">void</span> initParentCommand(<span class="predefined-type">Object</span> parent) {
            <span class="keyword">try</span> {
                <span class="predefined-type">Class</span>&lt;?&gt; cls = <span class="local-variable">this</span>.command.getClass();
                <span class="keyword">while</span> (cls != <span class="predefined-constant">null</span>) {
                    <span class="keyword">for</span> (<span class="predefined-type">Field</span> f : cls.getDeclaredFields()) {
                        <span class="keyword">if</span> (f.isAnnotationPresent(ParentCommand.class)) {
                            f.setAccessible(<span class="predefined-constant">true</span>);
                            f.set(command, parent);
                        }
                    }
                    cls = cls.getSuperclass();
                }
            } <span class="keyword">catch</span> (<span class="exception">Exception</span> ex) {
                <span class="keyword">throw</span> <span class="keyword">new</span> InitializationException(<span class="string"><span class="delimiter">&quot;</span><span class="content">Unable to initialize @ParentCommand field: </span><span class="delimiter">&quot;</span></span> + ex, ex);
            }
        }

        <span class="comment">/**
         * Entry point into parsing command line arguments.
         * @param args the command line arguments
         * @return a list with all commands and subcommands initialized by this method
         * @throws ParameterException if the specified command line arguments are invalid
         */</span>
        <span class="predefined-type">List</span>&lt;CommandLine&gt; parse(<span class="predefined-type">String</span>... args) {
            Assert.notNull(args, <span class="string"><span class="delimiter">&quot;</span><span class="content">argument array</span><span class="delimiter">&quot;</span></span>);
            <span class="keyword">if</span> (tracer.isInfo()) {tracer.info(<span class="string"><span class="delimiter">&quot;</span><span class="content">Parsing %d command line args %s%n</span><span class="delimiter">&quot;</span></span>, args.length, <span class="predefined-type">Arrays</span>.toString(args));}
            <span class="predefined-type">List</span>&lt;<span class="predefined-type">String</span>&gt; expanded = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">String</span>&gt;();
            <span class="keyword">for</span> (<span class="predefined-type">String</span> arg : args) { addOrExpand(arg, expanded, <span class="keyword">new</span> <span class="predefined-type">LinkedHashSet</span>&lt;<span class="predefined-type">String</span>&gt;()); }
            <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; arguments = <span class="keyword">new</span> <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt;();
            arguments.addAll(reverseList(expanded));
            <span class="predefined-type">List</span>&lt;CommandLine&gt; result = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;CommandLine&gt;();
            parse(result, arguments, args);
            <span class="keyword">return</span> result;
        }

        <span class="directive">private</span> <span class="type">void</span> addOrExpand(<span class="predefined-type">String</span> arg, <span class="predefined-type">List</span>&lt;<span class="predefined-type">String</span>&gt; arguments, <span class="predefined-type">Set</span>&lt;<span class="predefined-type">String</span>&gt; visited) {
            <span class="keyword">if</span> (expandAtFiles &amp;&amp; !arg.equals(<span class="string"><span class="delimiter">&quot;</span><span class="content">@</span><span class="delimiter">&quot;</span></span>) &amp;&amp; arg.startsWith(<span class="string"><span class="delimiter">&quot;</span><span class="content">@</span><span class="delimiter">&quot;</span></span>)) {
                arg = arg.substring(<span class="integer">1</span>);
                <span class="keyword">if</span> (arg.startsWith(<span class="string"><span class="delimiter">&quot;</span><span class="content">@</span><span class="delimiter">&quot;</span></span>)) {
                    <span class="keyword">if</span> (tracer.isInfo()) { tracer.info(<span class="string"><span class="delimiter">&quot;</span><span class="content">Not expanding @-escaped argument %s (trimmed leading '@' char)%n</span><span class="delimiter">&quot;</span></span>, arg); }
                } <span class="keyword">else</span> {
                    <span class="keyword">if</span> (tracer.isInfo()) { tracer.info(<span class="string"><span class="delimiter">&quot;</span><span class="content">Expanding argument file @%s%n</span><span class="delimiter">&quot;</span></span>, arg); }
                    expandArgumentFile(arg, arguments, visited);
                    <span class="keyword">return</span>;
                }
            }
            arguments.add(arg);
        }
        <span class="directive">private</span> <span class="type">void</span> expandArgumentFile(<span class="predefined-type">String</span> fileName, <span class="predefined-type">List</span>&lt;<span class="predefined-type">String</span>&gt; arguments, <span class="predefined-type">Set</span>&lt;<span class="predefined-type">String</span>&gt; visited) {
            <span class="predefined-type">File</span> file = <span class="keyword">new</span> <span class="predefined-type">File</span>(fileName);
            <span class="keyword">if</span> (!file.canRead()) {
                <span class="keyword">if</span> (tracer.isInfo()) {tracer.info(<span class="string"><span class="delimiter">&quot;</span><span class="content">File %s does not exist or cannot be read; treating argument literally%n</span><span class="delimiter">&quot;</span></span>, fileName);}
                arguments.add(<span class="string"><span class="delimiter">&quot;</span><span class="content">@</span><span class="delimiter">&quot;</span></span> + fileName);
            } <span class="keyword">else</span> <span class="keyword">if</span> (visited.contains(file.getAbsolutePath())) {
                <span class="keyword">if</span> (tracer.isInfo()) {tracer.info(<span class="string"><span class="delimiter">&quot;</span><span class="content">Already visited file %s; ignoring...%n</span><span class="delimiter">&quot;</span></span>, file.getAbsolutePath());}
            } <span class="keyword">else</span> {
                expandValidArgumentFile(fileName, file, arguments, visited);
            }
        }
        <span class="directive">private</span> <span class="type">void</span> expandValidArgumentFile(<span class="predefined-type">String</span> fileName, <span class="predefined-type">File</span> file, <span class="predefined-type">List</span>&lt;<span class="predefined-type">String</span>&gt; arguments, <span class="predefined-type">Set</span>&lt;<span class="predefined-type">String</span>&gt; visited) {
            visited.add(file.getAbsolutePath());
            <span class="predefined-type">List</span>&lt;<span class="predefined-type">String</span>&gt; result = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">String</span>&gt;();
            <span class="predefined-type">LineNumberReader</span> reader = <span class="predefined-constant">null</span>;
            <span class="keyword">try</span> {
                reader = <span class="keyword">new</span> <span class="predefined-type">LineNumberReader</span>(<span class="keyword">new</span> <span class="predefined-type">FileReader</span>(file));
                <span class="predefined-type">StreamTokenizer</span> tok = <span class="keyword">new</span> <span class="predefined-type">StreamTokenizer</span>(reader);
                tok.resetSyntax();
                tok.wordChars(<span class="string"><span class="delimiter">'</span><span class="content"> </span><span class="delimiter">'</span></span>, <span class="integer">255</span>);
                tok.whitespaceChars(<span class="integer">0</span>, <span class="string"><span class="delimiter">'</span><span class="content"> </span><span class="delimiter">'</span></span>);
                tok.commentChar(<span class="string"><span class="delimiter">'</span><span class="content">#</span><span class="delimiter">'</span></span>);
                tok.quoteChar(<span class="string"><span class="delimiter">'</span><span class="content">&quot;</span><span class="delimiter">'</span></span>);
                tok.quoteChar(<span class="string"><span class="delimiter">'</span><span class="char">\'</span><span class="delimiter">'</span></span>);
                <span class="keyword">while</span> (tok.nextToken() != <span class="predefined-type">StreamTokenizer</span>.TT_EOF) {
                    addOrExpand(tok.sval, result, visited);
                }
            } <span class="keyword">catch</span> (<span class="exception">Exception</span> ex) {
                <span class="keyword">throw</span> <span class="keyword">new</span> InitializationException(<span class="string"><span class="delimiter">&quot;</span><span class="content">Could not read argument file @</span><span class="delimiter">&quot;</span></span> + fileName, ex);
            } <span class="keyword">finally</span> {
                <span class="keyword">if</span> (reader != <span class="predefined-constant">null</span>) { <span class="keyword">try</span> {reader.close();} <span class="keyword">catch</span> (<span class="exception">Exception</span> ignored) {} }
            }
            <span class="keyword">if</span> (tracer.isInfo()) {tracer.info(<span class="string"><span class="delimiter">&quot;</span><span class="content">Expanded file @%s to arguments %s%n</span><span class="delimiter">&quot;</span></span>, fileName, result);}
            arguments.addAll(result);
        }

        <span class="directive">private</span> <span class="type">void</span> clear() {
            position = <span class="integer">0</span>;
            endOfOptions = <span class="predefined-constant">false</span>;
            isHelpRequested = <span class="predefined-constant">false</span>;
            CommandLine.this.versionHelpRequested = <span class="predefined-constant">false</span>;
            CommandLine.this.usageHelpRequested = <span class="predefined-constant">false</span>;
            CommandLine.this.unmatchedArguments.clear();
        }

        <span class="directive">private</span> <span class="type">void</span> parse(<span class="predefined-type">List</span>&lt;CommandLine&gt; parsedCommands, <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; argumentStack, <span class="predefined-type">String</span><span class="type">[]</span> originalArgs) {
            clear(); <span class="comment">// first reset any state in case this CommandLine instance is being reused</span>
            <span class="predefined-type">Class</span>&lt;?&gt; cmdClass = <span class="local-variable">this</span>.command.getClass();
            <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">Initializing %s: %d options, %d positional parameters, %d required, %d subcommands.%n</span><span class="delimiter">&quot;</span></span>, cmdClass.getName(), <span class="keyword">new</span> <span class="predefined-type">HashSet</span>&lt;<span class="predefined-type">Field</span>&gt;(optionName2Field.values()).size(), positionalParametersFields.size(), requiredFields.size(), commands.size());}
            parsedCommands.add(CommandLine.this);
            <span class="predefined-type">List</span>&lt;<span class="predefined-type">Field</span>&gt; required = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">Field</span>&gt;(requiredFields);
            <span class="predefined-type">Set</span>&lt;<span class="predefined-type">Field</span>&gt; initialized = <span class="keyword">new</span> <span class="predefined-type">HashSet</span>&lt;<span class="predefined-type">Field</span>&gt;();
            <span class="predefined-type">Collections</span>.sort(required, <span class="keyword">new</span> PositionalParametersSorter());
            <span class="keyword">try</span> {
                processArguments(parsedCommands, argumentStack, required, initialized, originalArgs);
            } <span class="keyword">catch</span> (ParameterException ex) {
                <span class="keyword">throw</span> ex;
            } <span class="keyword">catch</span> (<span class="exception">Exception</span> ex) {
                <span class="type">int</span> offendingArgIndex = originalArgs.length - argumentStack.size() - <span class="integer">1</span>;
                <span class="predefined-type">String</span> arg = offendingArgIndex &gt;= <span class="integer">0</span> &amp;&amp; offendingArgIndex &lt; originalArgs.length ? originalArgs[offendingArgIndex] : <span class="string"><span class="delimiter">&quot;</span><span class="content">?</span><span class="delimiter">&quot;</span></span>;
                <span class="keyword">throw</span> ParameterException.create(CommandLine.this, ex, arg, offendingArgIndex, originalArgs);
            }
            <span class="keyword">if</span> (!isAnyHelpRequested() &amp;&amp; !required.isEmpty()) {
                <span class="keyword">for</span> (<span class="predefined-type">Field</span> missing : required) {
                    <span class="keyword">if</span> (missing.isAnnotationPresent(<span class="predefined-type">Option</span>.class)) {
                        <span class="keyword">throw</span> MissingParameterException.create(CommandLine.this, required, separator);
                    } <span class="keyword">else</span> {
                        assertNoMissingParameters(missing, Range.parameterArity(missing).min, argumentStack);
                    }
                }
            }
            <span class="keyword">if</span> (!unmatchedArguments.isEmpty()) {
                <span class="keyword">if</span> (!isUnmatchedArgumentsAllowed()) { <span class="keyword">throw</span> <span class="keyword">new</span> UnmatchedArgumentException(CommandLine.this, unmatchedArguments); }
                <span class="keyword">if</span> (tracer.isWarn()) { tracer.warn(<span class="string"><span class="delimiter">&quot;</span><span class="content">Unmatched arguments: %s%n</span><span class="delimiter">&quot;</span></span>, unmatchedArguments); }
            }
        }

        <span class="directive">private</span> <span class="type">void</span> processArguments(<span class="predefined-type">List</span>&lt;CommandLine&gt; parsedCommands,
                                      <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; args,
                                      <span class="predefined-type">Collection</span>&lt;<span class="predefined-type">Field</span>&gt; required,
                                      <span class="predefined-type">Set</span>&lt;<span class="predefined-type">Field</span>&gt; initialized,
                                      <span class="predefined-type">String</span><span class="type">[]</span> originalArgs) <span class="directive">throws</span> <span class="exception">Exception</span> {
            <span class="comment">// arg must be one of:</span>
            <span class="comment">// 1. the &quot;--&quot; double dash separating options from positional arguments</span>
            <span class="comment">// 1. a stand-alone flag, like &quot;-v&quot; or &quot;--verbose&quot;: no value required, must map to boolean or Boolean field</span>
            <span class="comment">// 2. a short option followed by an argument, like &quot;-f file&quot; or &quot;-ffile&quot;: may map to any type of field</span>
            <span class="comment">// 3. a long option followed by an argument, like &quot;-file out.txt&quot; or &quot;-file=out.txt&quot;</span>
            <span class="comment">// 3. one or more remaining arguments without any associated options. Must be the last in the list.</span>
            <span class="comment">// 4. a combination of stand-alone options, like &quot;-vxr&quot;. Equivalent to &quot;-v -x -r&quot;, &quot;-v true -x true -r true&quot;</span>
            <span class="comment">// 5. a combination of stand-alone options and one option with an argument, like &quot;-vxrffile&quot;</span>

            <span class="keyword">while</span> (!args.isEmpty()) {
                <span class="keyword">if</span> (endOfOptions) {
                    processRemainderAsPositionalParameters(required, initialized, args);
                    <span class="keyword">return</span>;
                }
                <span class="predefined-type">String</span> arg = args.pop();
                <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">Processing argument '%s'. Remainder=%s%n</span><span class="delimiter">&quot;</span></span>, arg, reverse((<span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt;) args.clone()));}

                <span class="comment">// Double-dash separates options from positional arguments.</span>
                <span class="comment">// If found, then interpret the remaining args as positional parameters.</span>
                <span class="keyword">if</span> (<span class="string"><span class="delimiter">&quot;</span><span class="content">--</span><span class="delimiter">&quot;</span></span>.equals(arg)) {
                    tracer.info(<span class="string"><span class="delimiter">&quot;</span><span class="content">Found end-of-options delimiter '--'. Treating remainder as positional parameters.%n</span><span class="delimiter">&quot;</span></span>);
                    endOfOptions = <span class="predefined-constant">true</span>;
                    processRemainderAsPositionalParameters(required, initialized, args);
                    <span class="keyword">return</span>; <span class="comment">// we are done</span>
                }

                <span class="comment">// if we find another command, we are done with the current command</span>
                <span class="keyword">if</span> (commands.containsKey(arg)) {
                    <span class="keyword">if</span> (!isAnyHelpRequested() &amp;&amp; !required.isEmpty()) { <span class="comment">// ensure current command portion is valid</span>
                        <span class="keyword">throw</span> MissingParameterException.create(CommandLine.this, required, separator);
                    }
                    <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">Found subcommand '%s' (%s)%n</span><span class="delimiter">&quot;</span></span>, arg, commands.get(arg).interpreter.command.getClass().getName());}
                    commands.get(arg).interpreter.parse(parsedCommands, args, originalArgs);
                    <span class="keyword">return</span>; <span class="comment">// remainder done by the command</span>
                }

                <span class="comment">// First try to interpret the argument as a single option (as opposed to a compact group of options).</span>
                <span class="comment">// A single option may be without option parameters, like &quot;-v&quot; or &quot;--verbose&quot; (a boolean value),</span>
                <span class="comment">// or an option may have one or more option parameters.</span>
                <span class="comment">// A parameter may be attached to the option.</span>
                <span class="type">boolean</span> paramAttachedToOption = <span class="predefined-constant">false</span>;
                <span class="type">int</span> separatorIndex = arg.indexOf(separator);
                <span class="keyword">if</span> (separatorIndex &gt; <span class="integer">0</span>) {
                    <span class="predefined-type">String</span> key = arg.substring(<span class="integer">0</span>, separatorIndex);
                    <span class="comment">// be greedy. Consume the whole arg as an option if possible.</span>
                    <span class="keyword">if</span> (optionName2Field.containsKey(key) &amp;&amp; !optionName2Field.containsKey(arg)) {
                        paramAttachedToOption = <span class="predefined-constant">true</span>;
                        <span class="predefined-type">String</span> optionParam = arg.substring(separatorIndex + separator.length());
                        args.push(optionParam);
                        arg = key;
                        <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">Separated '%s' option from '%s' option parameter%n</span><span class="delimiter">&quot;</span></span>, key, optionParam);}
                    } <span class="keyword">else</span> {
                        <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">'%s' contains separator '%s' but '%s' is not a known option%n</span><span class="delimiter">&quot;</span></span>, arg, separator, key);}
                    }
                } <span class="keyword">else</span> {
                    <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">'%s' cannot be separated into &lt;option&gt;%s&lt;option-parameter&gt;%n</span><span class="delimiter">&quot;</span></span>, arg, separator);}
                }
                <span class="keyword">if</span> (optionName2Field.containsKey(arg)) {
                    processStandaloneOption(required, initialized, arg, args, paramAttachedToOption);
                }
                <span class="comment">// Compact (single-letter) options can be grouped with other options or with an argument.</span>
                <span class="comment">// only single-letter options can be combined with other options or with an argument</span>
                <span class="keyword">else</span> <span class="keyword">if</span> (arg.length() &gt; <span class="integer">2</span> &amp;&amp; arg.startsWith(<span class="string"><span class="delimiter">&quot;</span><span class="content">-</span><span class="delimiter">&quot;</span></span>)) {
                    <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">Trying to process '%s' as clustered short options%n</span><span class="delimiter">&quot;</span></span>, arg, args);}
                    processClusteredShortOptions(required, initialized, arg, args);
                }
                <span class="comment">// The argument could not be interpreted as an option.</span>
                <span class="comment">// We take this to mean that the remainder are positional arguments</span>
                <span class="keyword">else</span> {
                    args.push(arg);
                    <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">Could not find option '%s', deciding whether to treat as unmatched option or positional parameter...%n</span><span class="delimiter">&quot;</span></span>, arg);}
                    <span class="keyword">if</span> (resemblesOption(arg)) { handleUnmatchedArgument(args); <span class="keyword">continue</span>; } <span class="comment">// #149</span>
                    <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">No option named '%s' found. Processing remainder as positional parameters%n</span><span class="delimiter">&quot;</span></span>, arg);}
                    processPositionalParameter(required, initialized, args);
                }
            }
        }
        <span class="directive">private</span> <span class="type">boolean</span> resemblesOption(<span class="predefined-type">String</span> arg) {
            <span class="keyword">if</span> (optionName2Field.isEmpty()) {
                <span class="type">boolean</span> result = arg.startsWith(<span class="string"><span class="delimiter">&quot;</span><span class="content">-</span><span class="delimiter">&quot;</span></span>);
                <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">%s %s an option%n</span><span class="delimiter">&quot;</span></span>, arg, (result ? <span class="string"><span class="delimiter">&quot;</span><span class="content">resembles</span><span class="delimiter">&quot;</span></span> : <span class="string"><span class="delimiter">&quot;</span><span class="content">doesn't resemble</span><span class="delimiter">&quot;</span></span>));}
                <span class="keyword">return</span> result;
            }
            <span class="type">int</span> count = <span class="integer">0</span>;
            <span class="keyword">for</span> (<span class="predefined-type">String</span> optionName : optionName2Field.keySet()) {
                <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">0</span>; i &lt; arg.length(); i++) {
                    <span class="keyword">if</span> (optionName.length() &gt; i &amp;&amp; arg.charAt(i) == optionName.charAt(i)) { count++; } <span class="keyword">else</span> { <span class="keyword">break</span>; }
                }
            }
            <span class="type">boolean</span> result = count &gt; <span class="integer">0</span> &amp;&amp; count * <span class="integer">10</span> &gt;= optionName2Field.size() * <span class="integer">9</span>; <span class="comment">// at least one prefix char in common with 9 out of 10 options</span>
            <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">%s %s an option: %d matching prefix chars out of %d option names%n</span><span class="delimiter">&quot;</span></span>, arg, (result ? <span class="string"><span class="delimiter">&quot;</span><span class="content">resembles</span><span class="delimiter">&quot;</span></span> : <span class="string"><span class="delimiter">&quot;</span><span class="content">doesn't resemble</span><span class="delimiter">&quot;</span></span>), count, optionName2Field.size());}
            <span class="keyword">return</span> result;
        }
        <span class="directive">private</span> <span class="type">void</span> handleUnmatchedArgument(<span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; args) {
            <span class="keyword">if</span> (!args.isEmpty()) { unmatchedArguments.add(args.pop()); }
            <span class="keyword">if</span> (stopAtUnmatched) {
                <span class="comment">// addAll would give args in reverse order</span>
                <span class="keyword">while</span> (!args.isEmpty()) { unmatchedArguments.add(args.pop()); }
            }
        }

        <span class="directive">private</span> <span class="type">void</span> processRemainderAsPositionalParameters(<span class="predefined-type">Collection</span>&lt;<span class="predefined-type">Field</span>&gt; required, <span class="predefined-type">Set</span>&lt;<span class="predefined-type">Field</span>&gt; initialized, <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; args) <span class="directive">throws</span> <span class="exception">Exception</span> {
            <span class="keyword">while</span> (!args.empty()) {
                processPositionalParameter(required, initialized, args);
            }
        }
        <span class="directive">private</span> <span class="type">void</span> processPositionalParameter(<span class="predefined-type">Collection</span>&lt;<span class="predefined-type">Field</span>&gt; required, <span class="predefined-type">Set</span>&lt;<span class="predefined-type">Field</span>&gt; initialized, <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; args) <span class="directive">throws</span> <span class="exception">Exception</span> {
            <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">Processing next arg as a positional parameter at index=%d. Remainder=%s%n</span><span class="delimiter">&quot;</span></span>, position, reverse((<span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt;) args.clone()));}
            <span class="keyword">if</span> (stopAtPositional) {
                <span class="keyword">if</span> (!endOfOptions &amp;&amp; tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">Parser was configured with stopAtPositional=true, treating remaining arguments as positional parameters.%n</span><span class="delimiter">&quot;</span></span>);}
                endOfOptions = <span class="predefined-constant">true</span>;
            }
            <span class="type">int</span> consumed = <span class="integer">0</span>;
            <span class="keyword">for</span> (<span class="predefined-type">Field</span> positionalParam : positionalParametersFields) {
                Range indexRange = Range.parameterIndex(positionalParam);
                <span class="keyword">if</span> (!indexRange.contains(position)) {
                    <span class="keyword">continue</span>;
                }
                <span class="annotation">@SuppressWarnings</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">unchecked</span><span class="delimiter">&quot;</span></span>)
                <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; argsCopy = (<span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt;) args.clone();
                Range arity = Range.parameterArity(positionalParam);
                <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">Position %d is in index range %s. Trying to assign args to %s, arity=%s%n</span><span class="delimiter">&quot;</span></span>, position, indexRange, positionalParam, arity);}
                assertNoMissingParameters(positionalParam, arity.min, argsCopy);
                <span class="type">int</span> originalSize = argsCopy.size();
                applyOption(positionalParam, Parameters.class, arity, <span class="predefined-constant">false</span>, argsCopy, initialized, <span class="string"><span class="delimiter">&quot;</span><span class="content">args[</span><span class="delimiter">&quot;</span></span> + indexRange + <span class="string"><span class="delimiter">&quot;</span><span class="content">] at position </span><span class="delimiter">&quot;</span></span> + position);
                <span class="type">int</span> count = originalSize - argsCopy.size();
                <span class="keyword">if</span> (count &gt; <span class="integer">0</span>) { required.remove(positionalParam); }
                consumed = <span class="predefined-type">Math</span>.max(consumed, count);
            }
            <span class="comment">// remove processed args from the stack</span>
            <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">0</span>; i &lt; consumed; i++) { args.pop(); }
            position += consumed;
            <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">Consumed %d arguments, moving position to index %d.%n</span><span class="delimiter">&quot;</span></span>, consumed, position);}
            <span class="keyword">if</span> (consumed == <span class="integer">0</span> &amp;&amp; !args.isEmpty()) {
                handleUnmatchedArgument(args);
            }
        }

        <span class="directive">private</span> <span class="type">void</span> processStandaloneOption(<span class="predefined-type">Collection</span>&lt;<span class="predefined-type">Field</span>&gt; required,
                                             <span class="predefined-type">Set</span>&lt;<span class="predefined-type">Field</span>&gt; initialized,
                                             <span class="predefined-type">String</span> arg,
                                             <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; args,
                                             <span class="type">boolean</span> paramAttachedToKey) <span class="directive">throws</span> <span class="exception">Exception</span> {
            <span class="predefined-type">Field</span> field = optionName2Field.get(arg);
            required.remove(field);
            Range arity = Range.optionArity(field);
            <span class="keyword">if</span> (paramAttachedToKey) {
                arity = arity.min(<span class="predefined-type">Math</span>.max(<span class="integer">1</span>, arity.min)); <span class="comment">// if key=value, minimum arity is at least 1</span>
            }
            <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">Found option named '%s': field %s, arity=%s%n</span><span class="delimiter">&quot;</span></span>, arg, field, arity);}
            applyOption(field, <span class="predefined-type">Option</span>.class, arity, paramAttachedToKey, args, initialized, <span class="string"><span class="delimiter">&quot;</span><span class="content">option </span><span class="delimiter">&quot;</span></span> + arg);
        }

        <span class="directive">private</span> <span class="type">void</span> processClusteredShortOptions(<span class="predefined-type">Collection</span>&lt;<span class="predefined-type">Field</span>&gt; required,
                                                  <span class="predefined-type">Set</span>&lt;<span class="predefined-type">Field</span>&gt; initialized,
                                                  <span class="predefined-type">String</span> arg,
                                                  <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; args)
                <span class="directive">throws</span> <span class="exception">Exception</span> {
            <span class="predefined-type">String</span> prefix = arg.substring(<span class="integer">0</span>, <span class="integer">1</span>);
            <span class="predefined-type">String</span> cluster = arg.substring(<span class="integer">1</span>);
            <span class="type">boolean</span> paramAttachedToOption = <span class="predefined-constant">true</span>;
            <span class="keyword">do</span> {
                <span class="keyword">if</span> (cluster.length() &gt; <span class="integer">0</span> &amp;&amp; singleCharOption2Field.containsKey(cluster.charAt(<span class="integer">0</span>))) {
                    <span class="predefined-type">Field</span> field = singleCharOption2Field.get(cluster.charAt(<span class="integer">0</span>));
                    Range arity = Range.optionArity(field);
                    <span class="predefined-type">String</span> argDescription = <span class="string"><span class="delimiter">&quot;</span><span class="content">option </span><span class="delimiter">&quot;</span></span> + prefix + cluster.charAt(<span class="integer">0</span>);
                    <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">Found option '%s%s' in %s: field %s, arity=%s%n</span><span class="delimiter">&quot;</span></span>, prefix, cluster.charAt(<span class="integer">0</span>), arg, field, arity);}
                    required.remove(field);
                    cluster = cluster.length() &gt; <span class="integer">0</span> ? cluster.substring(<span class="integer">1</span>) : <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;
                    paramAttachedToOption = cluster.length() &gt; <span class="integer">0</span>;
                    <span class="keyword">if</span> (cluster.startsWith(separator)) {<span class="comment">// attached with separator, like -f=FILE or -v=true</span>
                        cluster = cluster.substring(separator.length());
                        arity = arity.min(<span class="predefined-type">Math</span>.max(<span class="integer">1</span>, arity.min)); <span class="comment">// if key=value, minimum arity is at least 1</span>
                    }
                    <span class="keyword">if</span> (arity.min &gt; <span class="integer">0</span> &amp;&amp; !empty(cluster)) {
                        <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">Trying to process '%s' as option parameter%n</span><span class="delimiter">&quot;</span></span>, cluster);}
                    }
                    <span class="comment">// arity may be &gt;= 1, or</span>
                    <span class="comment">// arity &lt;= 0 &amp;&amp; !cluster.startsWith(separator)</span>
                    <span class="comment">// e.g., boolean @Option(&quot;-v&quot;, arity=0, varargs=true); arg &quot;-rvTRUE&quot;, remainder cluster=&quot;TRUE&quot;</span>
                    <span class="keyword">if</span> (!empty(cluster)) {
                        args.push(cluster); <span class="comment">// interpret remainder as option parameter (CAUTION: may be empty string!)</span>
                    }
                    <span class="type">int</span> argCount = args.size();
                    <span class="type">int</span> consumed = applyOption(field, <span class="predefined-type">Option</span>.class, arity, paramAttachedToOption, args, initialized, argDescription);
                    <span class="comment">// if cluster was consumed as a parameter or if this field was the last in the cluster we're done; otherwise continue do-while loop</span>
                    <span class="keyword">if</span> (empty(cluster) || args.isEmpty() || args.size() &lt; argCount) {
                        <span class="keyword">return</span>;
                    }
                    cluster = args.pop();
                } <span class="keyword">else</span> { <span class="comment">// cluster is empty || cluster.charAt(0) is not a short option key</span>
                    <span class="keyword">if</span> (cluster.length() == <span class="integer">0</span>) { <span class="comment">// we finished parsing a group of short options like -rxv</span>
                        <span class="keyword">return</span>; <span class="comment">// return normally and parse the next arg</span>
                    }
                    <span class="comment">// We get here when the remainder of the cluster group is neither an option,</span>
                    <span class="comment">// nor a parameter that the last option could consume.</span>
                    <span class="keyword">if</span> (arg.endsWith(cluster)) {
                        args.push(paramAttachedToOption ? prefix + cluster : cluster);
                        <span class="keyword">if</span> (args.peek().equals(arg)) { <span class="comment">// #149 be consistent between unmatched short and long options</span>
                            <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">Could not match any short options in %s, deciding whether to treat as unmatched option or positional parameter...%n</span><span class="delimiter">&quot;</span></span>, arg);}
                            <span class="keyword">if</span> (resemblesOption(arg)) { handleUnmatchedArgument(args); <span class="keyword">return</span>; } <span class="comment">// #149</span>
                            processPositionalParameter(required, initialized, args);
                            <span class="keyword">return</span>;
                        }
                        <span class="comment">// remainder was part of a clustered group that could not be completely parsed</span>
                        <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">No option found for %s in %s%n</span><span class="delimiter">&quot;</span></span>, cluster, arg);}
                        handleUnmatchedArgument(args);
                    } <span class="keyword">else</span> {
                        args.push(cluster);
                        <span class="keyword">if</span> (tracer.isDebug()) {tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">%s is not an option parameter for %s%n</span><span class="delimiter">&quot;</span></span>, cluster, arg);}
                        processPositionalParameter(required, initialized, args);
                    }
                    <span class="keyword">return</span>;
                }
            } <span class="keyword">while</span> (<span class="predefined-constant">true</span>);
        }

        <span class="directive">private</span> <span class="type">int</span> applyOption(<span class="predefined-type">Field</span> field,
                                <span class="predefined-type">Class</span>&lt;?&gt; annotation,
                                Range arity,
                                <span class="type">boolean</span> valueAttachedToOption,
                                <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; args,
                                <span class="predefined-type">Set</span>&lt;<span class="predefined-type">Field</span>&gt; initialized,
                                <span class="predefined-type">String</span> argDescription) <span class="directive">throws</span> <span class="exception">Exception</span> {
            updateHelpRequested(field);
            <span class="type">int</span> length = args.size();
            assertNoMissingParameters(field, arity.min, args);

            <span class="predefined-type">Class</span>&lt;?&gt; cls = field.getType();
            <span class="keyword">if</span> (cls.isArray()) {
                <span class="keyword">return</span> applyValuesToArrayField(field, annotation, arity, args, cls, argDescription);
            }
            <span class="keyword">if</span> (<span class="predefined-type">Collection</span>.class.isAssignableFrom(cls)) {
                <span class="keyword">return</span> applyValuesToCollectionField(field, annotation, arity, args, cls, argDescription);
            }
            <span class="keyword">if</span> (<span class="predefined-type">Map</span>.class.isAssignableFrom(cls)) {
                <span class="keyword">return</span> applyValuesToMapField(field, annotation, arity, args, cls, argDescription);
            }
            cls = getTypeAttribute(field)[<span class="integer">0</span>]; <span class="comment">// field may be interface/abstract type, use annotation to get concrete type</span>
            <span class="keyword">return</span> applyValueToSingleValuedField(field, arity, args, cls, initialized, argDescription);
        }

        <span class="directive">private</span> <span class="type">int</span> applyValueToSingleValuedField(<span class="predefined-type">Field</span> field,
                                                  Range arity,
                                                  <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; args,
                                                  <span class="predefined-type">Class</span>&lt;?&gt; cls,
                                                  <span class="predefined-type">Set</span>&lt;<span class="predefined-type">Field</span>&gt; initialized,
                                                  <span class="predefined-type">String</span> argDescription) <span class="directive">throws</span> <span class="exception">Exception</span> {
            <span class="type">boolean</span> noMoreValues = args.isEmpty();
            <span class="predefined-type">String</span> value = args.isEmpty() ? <span class="predefined-constant">null</span> : trim(args.pop()); <span class="comment">// unquote the value</span>
            <span class="type">int</span> result = arity.min; <span class="comment">// the number or args we need to consume</span>

            <span class="keyword">if</span> (arity.min &lt;= <span class="integer">0</span>) { <span class="comment">// value is optional</span>

                <span class="comment">// special logic for booleans: BooleanConverter accepts only &quot;true&quot; or &quot;false&quot;.</span>
                <span class="keyword">if</span> (cls == <span class="predefined-type">Boolean</span>.class || cls == <span class="predefined-type">Boolean</span>.TYPE) {

                    <span class="comment">// boolean option with arity = 0..1 or 0..*: value MAY be a param</span>
                    <span class="keyword">if</span> (arity.max &gt; <span class="integer">0</span> &amp;&amp; (<span class="string"><span class="delimiter">&quot;</span><span class="content">true</span><span class="delimiter">&quot;</span></span>.equalsIgnoreCase(value) || <span class="string"><span class="delimiter">&quot;</span><span class="content">false</span><span class="delimiter">&quot;</span></span>.equalsIgnoreCase(value))) {
                        result = <span class="integer">1</span>;            <span class="comment">// if it is a varargs we only consume 1 argument if it is a boolean value</span>
                    } <span class="keyword">else</span> {
                        <span class="keyword">if</span> (value != <span class="predefined-constant">null</span>) {
                            args.push(value); <span class="comment">// we don't consume the value</span>
                        }
                        <span class="predefined-type">Boolean</span> currentValue = (<span class="predefined-type">Boolean</span>) field.get(command);
                        value = <span class="predefined-type">String</span>.valueOf(currentValue == <span class="predefined-constant">null</span> ? <span class="predefined-constant">true</span> : !currentValue); <span class="comment">// #147 toggle existing boolean value</span>
                    }
                } <span class="keyword">else</span> <span class="keyword">if</span> (<span class="predefined-type">CharSequence</span>.class.isAssignableFrom(cls)) { <span class="comment">// String option with optional value</span>
                    <span class="comment">// #279 track empty string value if no command line argumen</span>
                    <span class="keyword">if</span> (isOption(value)) {
                        args.push(value); <span class="comment">// we don't consume the value</span>
                        value = <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;
                    } <span class="keyword">else</span> <span class="keyword">if</span> (value == <span class="predefined-constant">null</span>) {
                        value = <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;
                    }
                }
            }
            <span class="keyword">if</span> (noMoreValues &amp;&amp; value == <span class="predefined-constant">null</span>) {
                <span class="keyword">return</span> <span class="integer">0</span>;
            }
            ITypeConverter&lt;?&gt; converter = getTypeConverter(cls, field, <span class="integer">0</span>);
            <span class="predefined-type">Object</span> newValue = tryConvert(field, -<span class="integer">1</span>, converter, value, cls);
            <span class="predefined-type">Object</span> oldValue = field.get(command);
            TraceLevel level = TraceLevel.INFO;
            <span class="predefined-type">String</span> traceMessage = <span class="string"><span class="delimiter">&quot;</span><span class="content">Setting %s field '%s.%s' to '%5$s' (was '%4$s') for %6$s%n</span><span class="delimiter">&quot;</span></span>;
            <span class="keyword">if</span> (initialized != <span class="predefined-constant">null</span>) {
                <span class="keyword">if</span> (initialized.contains(field)) {
                    <span class="keyword">if</span> (!isOverwrittenOptionsAllowed()) {
                        <span class="keyword">throw</span> <span class="keyword">new</span> OverwrittenOptionException(CommandLine.this, optionDescription(<span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>, field, <span class="integer">0</span>) +  <span class="string"><span class="delimiter">&quot;</span><span class="content"> should be specified only once</span><span class="delimiter">&quot;</span></span>);
                    }
                    level = TraceLevel.WARN;
                    traceMessage = <span class="string"><span class="delimiter">&quot;</span><span class="content">Overwriting %s field '%s.%s' value '%s' with '%s' for %s%n</span><span class="delimiter">&quot;</span></span>;
                }
                initialized.add(field);
            }
            <span class="keyword">if</span> (tracer.level.isEnabled(level)) { level.print(tracer, traceMessage, field.getType().getSimpleName(),
                        field.getDeclaringClass().getSimpleName(), field.getName(), <span class="predefined-type">String</span>.valueOf(oldValue), <span class="predefined-type">String</span>.valueOf(newValue), argDescription);
            }
            field.set(command, newValue);
            <span class="keyword">return</span> result;
        }
        <span class="directive">private</span> <span class="type">int</span> applyValuesToMapField(<span class="predefined-type">Field</span> field,
                                          <span class="predefined-type">Class</span>&lt;?&gt; annotation,
                                          Range arity,
                                          <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; args,
                                          <span class="predefined-type">Class</span>&lt;?&gt; cls,
                                          <span class="predefined-type">String</span> argDescription) <span class="directive">throws</span> <span class="exception">Exception</span> {
            <span class="predefined-type">Class</span>&lt;?&gt;<span class="type">[]</span> classes = getTypeAttribute(field);
            <span class="keyword">if</span> (classes.length &lt; <span class="integer">2</span>) { <span class="keyword">throw</span> <span class="keyword">new</span> ParameterException(CommandLine.this, <span class="string"><span class="delimiter">&quot;</span><span class="content">Field </span><span class="delimiter">&quot;</span></span> + field + <span class="string"><span class="delimiter">&quot;</span><span class="content"> needs two types (one for the map key, one for the value) but only has </span><span class="delimiter">&quot;</span></span> + classes.length + <span class="string"><span class="delimiter">&quot;</span><span class="content"> types configured.</span><span class="delimiter">&quot;</span></span>); }
            ITypeConverter&lt;?&gt; keyConverter   = getTypeConverter(classes[<span class="integer">0</span>], field, <span class="integer">0</span>);
            ITypeConverter&lt;?&gt; valueConverter = getTypeConverter(classes[<span class="integer">1</span>], field, <span class="integer">1</span>);
            <span class="predefined-type">Map</span>&lt;<span class="predefined-type">Object</span>, <span class="predefined-type">Object</span>&gt; result = (<span class="predefined-type">Map</span>&lt;<span class="predefined-type">Object</span>, <span class="predefined-type">Object</span>&gt;) field.get(command);
            <span class="keyword">if</span> (result == <span class="predefined-constant">null</span>) {
                result = createMap(cls);
                field.set(command, result);
            }
            <span class="type">int</span> originalSize = result.size();
            consumeMapArguments(field, arity, args, classes, keyConverter, valueConverter, result, argDescription);
            <span class="keyword">return</span> result.size() - originalSize;
        }

        <span class="directive">private</span> <span class="type">void</span> consumeMapArguments(<span class="predefined-type">Field</span> field,
                                         Range arity,
                                         <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; args,
                                         <span class="predefined-type">Class</span>&lt;?&gt;<span class="type">[]</span> classes,
                                         ITypeConverter&lt;?&gt; keyConverter,
                                         ITypeConverter&lt;?&gt; valueConverter,
                                         <span class="predefined-type">Map</span>&lt;<span class="predefined-type">Object</span>, <span class="predefined-type">Object</span>&gt; result,
                                         <span class="predefined-type">String</span> argDescription) <span class="directive">throws</span> <span class="exception">Exception</span> {
            <span class="comment">// first do the arity.min mandatory parameters</span>
            <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">0</span>; i &lt; arity.min; i++) {
                consumeOneMapArgument(field, arity, args, classes, keyConverter, valueConverter, result, i, argDescription);
            }
            <span class="comment">// now process the varargs if any</span>
            <span class="keyword">for</span> (<span class="type">int</span> i = arity.min; i &lt; arity.max &amp;&amp; !args.isEmpty(); i++) {
                <span class="keyword">if</span> (!varargCanConsumeNextValue(field, args.peek())) {
                    <span class="keyword">break</span>;
                }
                consumeOneMapArgument(field, arity, args, classes, keyConverter, valueConverter, result, i, argDescription);
            }
        }

        <span class="directive">private</span> <span class="type">void</span> consumeOneMapArgument(<span class="predefined-type">Field</span> field,
                                           Range arity,
                                           <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; args,
                                           <span class="predefined-type">Class</span>&lt;?&gt;<span class="type">[]</span> classes,
                                           ITypeConverter&lt;?&gt; keyConverter, ITypeConverter&lt;?&gt; valueConverter,
                                           <span class="predefined-type">Map</span>&lt;<span class="predefined-type">Object</span>, <span class="predefined-type">Object</span>&gt; result,
                                           <span class="type">int</span> index,
                                           <span class="predefined-type">String</span> argDescription) <span class="directive">throws</span> <span class="exception">Exception</span> {
            <span class="predefined-type">String</span><span class="type">[]</span> values = split(trim(args.pop()), field);
            <span class="keyword">for</span> (<span class="predefined-type">String</span> value : values) {
                <span class="predefined-type">String</span><span class="type">[]</span> keyValue = value.split(<span class="string"><span class="delimiter">&quot;</span><span class="content">=</span><span class="delimiter">&quot;</span></span>);
                <span class="keyword">if</span> (keyValue.length &lt; <span class="integer">2</span>) {
                    <span class="predefined-type">String</span> splitRegex = splitRegex(field);
                    <span class="keyword">if</span> (splitRegex.length() == <span class="integer">0</span>) {
                        <span class="keyword">throw</span> <span class="keyword">new</span> ParameterException(CommandLine.this, <span class="string"><span class="delimiter">&quot;</span><span class="content">Value for option </span><span class="delimiter">&quot;</span></span> + optionDescription(<span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>, field,
                                <span class="integer">0</span>) + <span class="string"><span class="delimiter">&quot;</span><span class="content"> should be in KEY=VALUE format but was </span><span class="delimiter">&quot;</span></span> + value);
                    } <span class="keyword">else</span> {
                        <span class="keyword">throw</span> <span class="keyword">new</span> ParameterException(CommandLine.this, <span class="string"><span class="delimiter">&quot;</span><span class="content">Value for option </span><span class="delimiter">&quot;</span></span> + optionDescription(<span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>, field,
                                <span class="integer">0</span>) + <span class="string"><span class="delimiter">&quot;</span><span class="content"> should be in KEY=VALUE[</span><span class="delimiter">&quot;</span></span> + splitRegex + <span class="string"><span class="delimiter">&quot;</span><span class="content">KEY=VALUE]... format but was </span><span class="delimiter">&quot;</span></span> + value);
                    }
                }
                <span class="predefined-type">Object</span> mapKey =   tryConvert(field, index, keyConverter,   keyValue[<span class="integer">0</span>], classes[<span class="integer">0</span>]);
                <span class="predefined-type">Object</span> mapValue = tryConvert(field, index, valueConverter, keyValue[<span class="integer">1</span>], classes[<span class="integer">1</span>]);
                result.put(mapKey, mapValue);
                <span class="keyword">if</span> (tracer.isInfo()) {tracer.info(<span class="string"><span class="delimiter">&quot;</span><span class="content">Putting [%s : %s] in %s&lt;%s, %s&gt; field '%s.%s' for %s%n</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">String</span>.valueOf(mapKey), <span class="predefined-type">String</span>.valueOf(mapValue),
                        result.getClass().getSimpleName(), classes[<span class="integer">0</span>].getSimpleName(), classes[<span class="integer">1</span>].getSimpleName(), field.getDeclaringClass().getSimpleName(), field.getName(), argDescription);}
            }
        }

        <span class="directive">private</span> <span class="type">void</span> checkMaxArityExceeded(Range arity, <span class="type">int</span> remainder, <span class="predefined-type">Field</span> field, <span class="predefined-type">String</span><span class="type">[]</span> values) {
            <span class="keyword">if</span> (values.length &lt;= remainder) { <span class="keyword">return</span>; }
            <span class="predefined-type">String</span> desc = arity.max == remainder ? <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span> + remainder : arity + <span class="string"><span class="delimiter">&quot;</span><span class="content">, remainder=</span><span class="delimiter">&quot;</span></span> + remainder;
            <span class="keyword">throw</span> <span class="keyword">new</span> MaxValuesforFieldExceededException(CommandLine.this, optionDescription(<span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>, field, -<span class="integer">1</span>) +
                    <span class="string"><span class="delimiter">&quot;</span><span class="content"> max number of values (</span><span class="delimiter">&quot;</span></span> + arity.max + <span class="string"><span class="delimiter">&quot;</span><span class="content">) exceeded: remainder is </span><span class="delimiter">&quot;</span></span> + remainder + <span class="string"><span class="delimiter">&quot;</span><span class="content"> but </span><span class="delimiter">&quot;</span></span> +
                    values.length + <span class="string"><span class="delimiter">&quot;</span><span class="content"> values were specified: </span><span class="delimiter">&quot;</span></span> + <span class="predefined-type">Arrays</span>.toString(values));
        }

        <span class="directive">private</span> <span class="type">int</span> applyValuesToArrayField(<span class="predefined-type">Field</span> field,
                                            <span class="predefined-type">Class</span>&lt;?&gt; annotation,
                                            Range arity,
                                            <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; args,
                                            <span class="predefined-type">Class</span>&lt;?&gt; cls,
                                            <span class="predefined-type">String</span> argDescription) <span class="directive">throws</span> <span class="exception">Exception</span> {
            <span class="predefined-type">Object</span> existing = field.get(command);
            <span class="type">int</span> length = existing == <span class="predefined-constant">null</span> ? <span class="integer">0</span> : <span class="predefined-type">Array</span>.getLength(existing);
            <span class="predefined-type">Class</span>&lt;?&gt; type = getTypeAttribute(field)[<span class="integer">0</span>];
            <span class="predefined-type">List</span>&lt;<span class="predefined-type">Object</span>&gt; converted = consumeArguments(field, annotation, arity, args, type, length, argDescription);
            <span class="predefined-type">List</span>&lt;<span class="predefined-type">Object</span>&gt; newValues = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">Object</span>&gt;();
            <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">0</span>; i &lt; length; i++) {
                newValues.add(<span class="predefined-type">Array</span>.get(existing, i));
            }
            <span class="keyword">for</span> (<span class="predefined-type">Object</span> obj : converted) {
                <span class="keyword">if</span> (obj <span class="keyword">instanceof</span> <span class="predefined-type">Collection</span>&lt;?&gt;) {
                    newValues.addAll((<span class="predefined-type">Collection</span>&lt;?&gt;) obj);
                } <span class="keyword">else</span> {
                    newValues.add(obj);
                }
            }
            <span class="predefined-type">Object</span> array = <span class="predefined-type">Array</span>.newInstance(type, newValues.size());
            field.set(command, array);
            <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">0</span>; i &lt; newValues.size(); i++) {
                <span class="predefined-type">Array</span>.set(array, i, newValues.get(i));
            }
            <span class="keyword">return</span> converted.size(); <span class="comment">// return how many args were consumed</span>
        }

        <span class="annotation">@SuppressWarnings</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">unchecked</span><span class="delimiter">&quot;</span></span>)
        <span class="directive">private</span> <span class="type">int</span> applyValuesToCollectionField(<span class="predefined-type">Field</span> field,
                                                 <span class="predefined-type">Class</span>&lt;?&gt; annotation,
                                                 Range arity,
                                                 <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; args,
                                                 <span class="predefined-type">Class</span>&lt;?&gt; cls,
                                                 <span class="predefined-type">String</span> argDescription) <span class="directive">throws</span> <span class="exception">Exception</span> {
            <span class="predefined-type">Collection</span>&lt;<span class="predefined-type">Object</span>&gt; collection = (<span class="predefined-type">Collection</span>&lt;<span class="predefined-type">Object</span>&gt;) field.get(command);
            <span class="predefined-type">Class</span>&lt;?&gt; type = getTypeAttribute(field)[<span class="integer">0</span>];
            <span class="type">int</span> length = collection == <span class="predefined-constant">null</span> ? <span class="integer">0</span> : collection.size();
            <span class="predefined-type">List</span>&lt;<span class="predefined-type">Object</span>&gt; converted = consumeArguments(field, annotation, arity, args, type, length, argDescription);
            <span class="keyword">if</span> (collection == <span class="predefined-constant">null</span>) {
                collection = createCollection(cls);
                field.set(command, collection);
            }
            <span class="keyword">for</span> (<span class="predefined-type">Object</span> element : converted) {
                <span class="keyword">if</span> (element <span class="keyword">instanceof</span> <span class="predefined-type">Collection</span>&lt;?&gt;) {
                    collection.addAll((<span class="predefined-type">Collection</span>&lt;?&gt;) element);
                } <span class="keyword">else</span> {
                    collection.add(element);
                }
            }
            <span class="keyword">return</span> converted.size();
        }

        <span class="directive">private</span> <span class="predefined-type">List</span>&lt;<span class="predefined-type">Object</span>&gt; consumeArguments(<span class="predefined-type">Field</span> field,
                                              <span class="predefined-type">Class</span>&lt;?&gt; annotation,
                                              Range arity,
                                              <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; args,
                                              <span class="predefined-type">Class</span>&lt;?&gt; type,
                                              <span class="type">int</span> originalSize,
                                              <span class="predefined-type">String</span> argDescription) <span class="directive">throws</span> <span class="exception">Exception</span> {
            <span class="predefined-type">List</span>&lt;<span class="predefined-type">Object</span>&gt; result = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">Object</span>&gt;();

            <span class="comment">// first do the arity.min mandatory parameters</span>
            <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">0</span>; i &lt; arity.min; i++) {
                consumeOneArgument(field, arity, args, type, result, i, originalSize, argDescription);
            }
            <span class="comment">// now process the varargs if any</span>
            <span class="keyword">for</span> (<span class="type">int</span> i = arity.min; i &lt; arity.max &amp;&amp; !args.isEmpty(); i++) {
                <span class="keyword">if</span> (!varargCanConsumeNextValue(field, args.peek())) {
                    <span class="keyword">break</span>;
                }
                consumeOneArgument(field, arity, args, type, result, i, originalSize, argDescription);
            }
            <span class="keyword">if</span> (result.isEmpty() &amp;&amp; arity.min == <span class="integer">0</span> &amp;&amp; arity.max &lt;= <span class="integer">1</span> &amp;&amp; isBoolean(type)) {
                <span class="keyword">return</span> <span class="predefined-type">Arrays</span>.asList((<span class="predefined-type">Object</span>) <span class="predefined-type">Boolean</span>.TRUE);
            }
            <span class="keyword">return</span> result;
        }

        <span class="directive">private</span> <span class="type">int</span> consumeOneArgument(<span class="predefined-type">Field</span> field,
                                       Range arity,
                                       <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; args,
                                       <span class="predefined-type">Class</span>&lt;?&gt; type,
                                       <span class="predefined-type">List</span>&lt;<span class="predefined-type">Object</span>&gt; result,
                                       <span class="type">int</span> index,
                                       <span class="type">int</span> originalSize,
                                       <span class="predefined-type">String</span> argDescription) <span class="directive">throws</span> <span class="exception">Exception</span> {
            <span class="predefined-type">String</span><span class="type">[]</span> values = split(trim(args.pop()), field);
            ITypeConverter&lt;?&gt; converter = getTypeConverter(type, field, <span class="integer">0</span>);

            <span class="keyword">for</span> (<span class="type">int</span> j = <span class="integer">0</span>; j &lt; values.length; j++) {
                result.add(tryConvert(field, index, converter, values[j], type));
                <span class="keyword">if</span> (tracer.isInfo()) {
                    <span class="keyword">if</span> (field.getType().isArray()) {
                        tracer.info(<span class="string"><span class="delimiter">&quot;</span><span class="content">Adding [%s] to %s[] field '%s.%s' for %s%n</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">String</span>.valueOf(result.get(result.size() - <span class="integer">1</span>)), type.getSimpleName(), field.getDeclaringClass().getSimpleName(), field.getName(), argDescription);
                    } <span class="keyword">else</span> {
                        tracer.info(<span class="string"><span class="delimiter">&quot;</span><span class="content">Adding [%s] to %s&lt;%s&gt; field '%s.%s' for %s%n</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">String</span>.valueOf(result.get(result.size() - <span class="integer">1</span>)), field.getType().getSimpleName(), type.getSimpleName(), field.getDeclaringClass().getSimpleName(), field.getName(), argDescription);
                    }
                }
            }
            <span class="comment">//checkMaxArityExceeded(arity, max, field, values);</span>
            <span class="keyword">return</span> ++index;
        }

        <span class="directive">private</span> <span class="predefined-type">String</span> splitRegex(<span class="predefined-type">Field</span> field) {
            <span class="keyword">if</span> (field.isAnnotationPresent(<span class="predefined-type">Option</span>.class))     { <span class="keyword">return</span> field.getAnnotation(<span class="predefined-type">Option</span>.class).split(); }
            <span class="keyword">if</span> (field.isAnnotationPresent(Parameters.class)) { <span class="keyword">return</span> field.getAnnotation(Parameters.class).split(); }
            <span class="keyword">return</span> <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;
        }
        <span class="directive">private</span> <span class="predefined-type">String</span><span class="type">[]</span> split(<span class="predefined-type">String</span> value, <span class="predefined-type">Field</span> field) {
            <span class="predefined-type">String</span> regex = splitRegex(field);
            <span class="keyword">return</span> regex.length() == <span class="integer">0</span> ? <span class="keyword">new</span> <span class="predefined-type">String</span><span class="type">[]</span>{value} : value.split(regex);
        }
        <span class="comment">/** Returns whether the next argument can be assigned to a vararg option/positional parameter.
         * &lt;p&gt;
         * Usually, we stop if we encounter '--', a command, or another option.
         * However, if end-of-options has been reached, positional parameters may consume all remaining arguments. &lt;/p&gt;*/</span>
        <span class="directive">private</span> <span class="type">boolean</span> varargCanConsumeNextValue(<span class="predefined-type">Field</span> field, <span class="predefined-type">String</span> nextValue) {
            <span class="keyword">if</span> (endOfOptions &amp;&amp; field.isAnnotationPresent(Parameters.class)) { <span class="keyword">return</span> <span class="predefined-constant">true</span>; }
            <span class="type">boolean</span> isCommand = commands.containsKey(nextValue);
            <span class="keyword">return</span> !isCommand &amp;&amp; !isOption(nextValue);
        }

        <span class="comment">/**
         * Called when parsing varargs parameters for a multi-value option.
         * When an option is encountered, the remainder should not be interpreted as vararg elements.
         * @param arg the string to determine whether it is an option or not
         * @return true if it is an option, false otherwise
         */</span>
        <span class="directive">private</span> <span class="type">boolean</span> isOption(<span class="predefined-type">String</span> arg) {
            <span class="keyword">if</span> (arg == <span class="predefined-constant">null</span>)      { <span class="keyword">return</span> <span class="predefined-constant">false</span>; }
            <span class="keyword">if</span> (<span class="string"><span class="delimiter">&quot;</span><span class="content">--</span><span class="delimiter">&quot;</span></span>.equals(arg)) { <span class="keyword">return</span> <span class="predefined-constant">true</span>; }

            <span class="comment">// not just arg prefix: we may be in the middle of parsing -xrvfFILE</span>
            <span class="keyword">if</span> (optionName2Field.containsKey(arg)) { <span class="comment">// -v or -f or --file (not attached to param or other option)</span>
                <span class="keyword">return</span> <span class="predefined-constant">true</span>;
            }
            <span class="type">int</span> separatorIndex = arg.indexOf(separator);
            <span class="keyword">if</span> (separatorIndex &gt; <span class="integer">0</span>) { <span class="comment">// -f=FILE or --file==FILE (attached to param via separator)</span>
                <span class="keyword">if</span> (optionName2Field.containsKey(arg.substring(<span class="integer">0</span>, separatorIndex))) {
                    <span class="keyword">return</span> <span class="predefined-constant">true</span>;
                }
            }
            <span class="keyword">return</span> (arg.length() &gt; <span class="integer">2</span> &amp;&amp; arg.startsWith(<span class="string"><span class="delimiter">&quot;</span><span class="content">-</span><span class="delimiter">&quot;</span></span>) &amp;&amp; singleCharOption2Field.containsKey(arg.charAt(<span class="integer">1</span>)));
        }
        <span class="directive">private</span> <span class="predefined-type">Object</span> tryConvert(<span class="predefined-type">Field</span> field, <span class="type">int</span> index, ITypeConverter&lt;?&gt; converter, <span class="predefined-type">String</span> value, <span class="predefined-type">Class</span>&lt;?&gt; type)
                <span class="directive">throws</span> <span class="exception">Exception</span> {
            <span class="keyword">try</span> {
                <span class="keyword">return</span> converter.convert(value);
            } <span class="keyword">catch</span> (TypeConversionException ex) {
                <span class="keyword">throw</span> <span class="keyword">new</span> ParameterException(CommandLine.this, ex.getMessage() + optionDescription(<span class="string"><span class="delimiter">&quot;</span><span class="content"> for </span><span class="delimiter">&quot;</span></span>, field, index));
            } <span class="keyword">catch</span> (<span class="exception">Exception</span> other) {
                <span class="predefined-type">String</span> desc = optionDescription(<span class="string"><span class="delimiter">&quot;</span><span class="content"> for </span><span class="delimiter">&quot;</span></span>, field, index) + <span class="string"><span class="delimiter">&quot;</span><span class="content">: </span><span class="delimiter">&quot;</span></span> + other;
                <span class="keyword">throw</span> <span class="keyword">new</span> ParameterException(CommandLine.this, <span class="string"><span class="delimiter">&quot;</span><span class="content">Could not convert '</span><span class="delimiter">&quot;</span></span> + value + <span class="string"><span class="delimiter">&quot;</span><span class="content">' to </span><span class="delimiter">&quot;</span></span> + type.getSimpleName() + desc, other);
            }
        }

        <span class="directive">private</span> <span class="predefined-type">String</span> optionDescription(<span class="predefined-type">String</span> prefix, <span class="predefined-type">Field</span> field, <span class="type">int</span> index) {
            Help.IParamLabelRenderer labelRenderer = Help.createMinimalParamLabelRenderer();
            <span class="predefined-type">String</span> desc = <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;
            <span class="keyword">if</span> (field.isAnnotationPresent(<span class="predefined-type">Option</span>.class)) {
                desc = prefix + <span class="string"><span class="delimiter">&quot;</span><span class="content">option '</span><span class="delimiter">&quot;</span></span> + field.getAnnotation(<span class="predefined-type">Option</span>.class).names()[<span class="integer">0</span>] + <span class="string"><span class="delimiter">&quot;</span><span class="content">'</span><span class="delimiter">&quot;</span></span>;
                <span class="keyword">if</span> (index &gt;= <span class="integer">0</span>) {
                    Range arity = Range.optionArity(field);
                    <span class="keyword">if</span> (arity.max &gt; <span class="integer">1</span>) {
                        desc += <span class="string"><span class="delimiter">&quot;</span><span class="content"> at index </span><span class="delimiter">&quot;</span></span> + index;
                    }
                    desc += <span class="string"><span class="delimiter">&quot;</span><span class="content"> (</span><span class="delimiter">&quot;</span></span> + labelRenderer.renderParameterLabel(field, Help.Ansi.OFF, <span class="predefined-type">Collections</span>.&lt;IStyle&gt;emptyList()) + <span class="string"><span class="delimiter">&quot;</span><span class="content">)</span><span class="delimiter">&quot;</span></span>;
                }
            } <span class="keyword">else</span> <span class="keyword">if</span> (field.isAnnotationPresent(Parameters.class)) {
                Range indexRange = Range.parameterIndex(field);
                Text label = labelRenderer.renderParameterLabel(field, Help.Ansi.OFF, <span class="predefined-type">Collections</span>.&lt;IStyle&gt;emptyList());
                desc = prefix + <span class="string"><span class="delimiter">&quot;</span><span class="content">positional parameter at index </span><span class="delimiter">&quot;</span></span> + indexRange + <span class="string"><span class="delimiter">&quot;</span><span class="content"> (</span><span class="delimiter">&quot;</span></span> + label + <span class="string"><span class="delimiter">&quot;</span><span class="content">)</span><span class="delimiter">&quot;</span></span>;
            }
            <span class="keyword">return</span> desc;
        }

        <span class="directive">private</span> <span class="type">boolean</span> isAnyHelpRequested() { <span class="keyword">return</span> isHelpRequested || versionHelpRequested || usageHelpRequested; }

        <span class="directive">private</span> <span class="type">void</span> updateHelpRequested(<span class="predefined-type">Field</span> field) {
            <span class="keyword">if</span> (field.isAnnotationPresent(<span class="predefined-type">Option</span>.class)) {
                isHelpRequested                       |= is(field, <span class="string"><span class="delimiter">&quot;</span><span class="content">help</span><span class="delimiter">&quot;</span></span>, field.getAnnotation(<span class="predefined-type">Option</span>.class).help());
                CommandLine.this.versionHelpRequested |= is(field, <span class="string"><span class="delimiter">&quot;</span><span class="content">versionHelp</span><span class="delimiter">&quot;</span></span>, field.getAnnotation(<span class="predefined-type">Option</span>.class).versionHelp());
                CommandLine.this.usageHelpRequested   |= is(field, <span class="string"><span class="delimiter">&quot;</span><span class="content">usageHelp</span><span class="delimiter">&quot;</span></span>, field.getAnnotation(<span class="predefined-type">Option</span>.class).usageHelp());
            }
        }
        <span class="directive">private</span> <span class="type">boolean</span> is(<span class="predefined-type">Field</span> f, <span class="predefined-type">String</span> description, <span class="type">boolean</span> value) {
            <span class="keyword">if</span> (value) { <span class="keyword">if</span> (tracer.isInfo()) {tracer.info(<span class="string"><span class="delimiter">&quot;</span><span class="content">Field '%s.%s' has '%s' annotation: not validating required fields%n</span><span class="delimiter">&quot;</span></span>, f.getDeclaringClass().getSimpleName(), f.getName(), description); }}
            <span class="keyword">return</span> value;
        }
        <span class="annotation">@SuppressWarnings</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">unchecked</span><span class="delimiter">&quot;</span></span>)
        <span class="directive">private</span> <span class="predefined-type">Collection</span>&lt;<span class="predefined-type">Object</span>&gt; createCollection(<span class="predefined-type">Class</span>&lt;?&gt; collectionClass) <span class="directive">throws</span> <span class="exception">Exception</span> {
            <span class="keyword">if</span> (collectionClass.isInterface()) {
                <span class="keyword">if</span> (<span class="predefined-type">List</span>.class.isAssignableFrom(collectionClass)) {
                    <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">Object</span>&gt;();
                } <span class="keyword">else</span> <span class="keyword">if</span> (<span class="predefined-type">SortedSet</span>.class.isAssignableFrom(collectionClass)) {
                    <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">TreeSet</span>&lt;<span class="predefined-type">Object</span>&gt;();
                } <span class="keyword">else</span> <span class="keyword">if</span> (<span class="predefined-type">Set</span>.class.isAssignableFrom(collectionClass)) {
                    <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">LinkedHashSet</span>&lt;<span class="predefined-type">Object</span>&gt;();
                } <span class="keyword">else</span> <span class="keyword">if</span> (<span class="predefined-type">Queue</span>.class.isAssignableFrom(collectionClass)) {
                    <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">LinkedList</span>&lt;<span class="predefined-type">Object</span>&gt;(); <span class="comment">// ArrayDeque is only available since 1.6</span>
                }
                <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">Object</span>&gt;();
            }
            <span class="comment">// custom Collection implementation class must have default constructor</span>
            <span class="keyword">return</span> (<span class="predefined-type">Collection</span>&lt;<span class="predefined-type">Object</span>&gt;) collectionClass.newInstance();
        }
        <span class="directive">private</span> <span class="predefined-type">Map</span>&lt;<span class="predefined-type">Object</span>, <span class="predefined-type">Object</span>&gt; createMap(<span class="predefined-type">Class</span>&lt;?&gt; mapClass) <span class="directive">throws</span> <span class="exception">Exception</span> {
            <span class="keyword">try</span> { <span class="comment">// if it is an implementation class, instantiate it</span>
                <span class="keyword">return</span> (<span class="predefined-type">Map</span>&lt;<span class="predefined-type">Object</span>, <span class="predefined-type">Object</span>&gt;) mapClass.newInstance();
            } <span class="keyword">catch</span> (<span class="exception">Exception</span> ignored) {}
            <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">LinkedHashMap</span>&lt;<span class="predefined-type">Object</span>, <span class="predefined-type">Object</span>&gt;();
        }
        <span class="directive">private</span> ITypeConverter&lt;?&gt; getTypeConverter(<span class="directive">final</span> <span class="predefined-type">Class</span>&lt;?&gt; type, <span class="predefined-type">Field</span> field, <span class="type">int</span> index) {
            <span class="predefined-type">Class</span>&lt;? <span class="directive">extends</span> ITypeConverter&lt;?&gt;&gt;<span class="type">[]</span> specific = field.isAnnotationPresent(<span class="predefined-type">Option</span>.class) ? field.getAnnotation(<span class="predefined-type">Option</span>.class).converter()
                    : field.isAnnotationPresent(Parameters.class) ? field.getAnnotation(Parameters.class).converter() : <span class="predefined-constant">null</span>;
            <span class="keyword">if</span> (specific.length &gt; index) {
                <span class="keyword">try</span> {
                    <span class="keyword">return</span> (ITypeConverter&lt;?&gt;) factory.create(specific[index]);
                } <span class="keyword">catch</span> (<span class="exception">Exception</span> e) {
                    <span class="keyword">throw</span> <span class="keyword">new</span> MissingTypeConverterException(CommandLine.this, <span class="string"><span class="delimiter">&quot;</span><span class="content">Could not instantiate </span><span class="delimiter">&quot;</span></span> + specific[index] + <span class="string"><span class="delimiter">&quot;</span><span class="content">: </span><span class="delimiter">&quot;</span></span> + e.toString());
                }
            }
            ITypeConverter&lt;?&gt; result = converterRegistry.get(type);
            <span class="keyword">if</span> (result != <span class="predefined-constant">null</span>) {
                <span class="keyword">return</span> result;
            }
            <span class="keyword">if</span> (type.isEnum()) {
                <span class="keyword">return</span> <span class="keyword">new</span> ITypeConverter&lt;<span class="predefined-type">Object</span>&gt;() {
                    <span class="annotation">@SuppressWarnings</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">unchecked</span><span class="delimiter">&quot;</span></span>)
                    <span class="directive">public</span> <span class="predefined-type">Object</span> convert(<span class="predefined-type">String</span> value) <span class="directive">throws</span> <span class="exception">Exception</span> {
                        <span class="keyword">return</span> <span class="predefined-type">Enum</span>.valueOf((<span class="predefined-type">Class</span>&lt;<span class="predefined-type">Enum</span>&gt;) type, value);
                    }
                };
            }
            <span class="keyword">throw</span> <span class="keyword">new</span> MissingTypeConverterException(CommandLine.this, <span class="string"><span class="delimiter">&quot;</span><span class="content">No TypeConverter registered for </span><span class="delimiter">&quot;</span></span> + type.getName() + <span class="string"><span class="delimiter">&quot;</span><span class="content"> of field </span><span class="delimiter">&quot;</span></span> + field);
        }

        <span class="directive">private</span> <span class="type">void</span> assertNoMissingParameters(<span class="predefined-type">Field</span> field, <span class="type">int</span> arity, <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; args) {
            <span class="keyword">if</span> (arity &gt; args.size()) {
                <span class="keyword">if</span> (arity == <span class="integer">1</span>) {
                    <span class="keyword">if</span> (field.isAnnotationPresent(<span class="predefined-type">Option</span>.class)) {
                        <span class="keyword">throw</span> <span class="keyword">new</span> MissingParameterException(CommandLine.this, <span class="string"><span class="delimiter">&quot;</span><span class="content">Missing required parameter for </span><span class="delimiter">&quot;</span></span> +
                                optionDescription(<span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>, field, <span class="integer">0</span>));
                    }
                    Range indexRange = Range.parameterIndex(field);
                    Help.IParamLabelRenderer labelRenderer = Help.createMinimalParamLabelRenderer();
                    <span class="predefined-type">String</span> sep = <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;
                    <span class="predefined-type">String</span> names = <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;
                    <span class="type">int</span> count = <span class="integer">0</span>;
                    <span class="keyword">for</span> (<span class="type">int</span> i = indexRange.min; i &lt; positionalParametersFields.size(); i++) {
                        <span class="keyword">if</span> (Range.parameterArity(positionalParametersFields.get(i)).min &gt; <span class="integer">0</span>) {
                            names += sep + labelRenderer.renderParameterLabel(positionalParametersFields.get(i),
                                    Help.Ansi.OFF, <span class="predefined-type">Collections</span>.&lt;IStyle&gt;emptyList());
                            sep = <span class="string"><span class="delimiter">&quot;</span><span class="content">, </span><span class="delimiter">&quot;</span></span>;
                            count++;
                        }
                    }
                    <span class="predefined-type">String</span> msg = <span class="string"><span class="delimiter">&quot;</span><span class="content">Missing required parameter</span><span class="delimiter">&quot;</span></span>;
                    Range paramArity = Range.parameterArity(field);
                    <span class="keyword">if</span> (paramArity.isVariable) {
                        msg += <span class="string"><span class="delimiter">&quot;</span><span class="content">s at positions </span><span class="delimiter">&quot;</span></span> + indexRange + <span class="string"><span class="delimiter">&quot;</span><span class="content">: </span><span class="delimiter">&quot;</span></span>;
                    } <span class="keyword">else</span> {
                        msg += (count &gt; <span class="integer">1</span> ? <span class="string"><span class="delimiter">&quot;</span><span class="content">s: </span><span class="delimiter">&quot;</span></span> : <span class="string"><span class="delimiter">&quot;</span><span class="content">: </span><span class="delimiter">&quot;</span></span>);
                    }
                    <span class="keyword">throw</span> <span class="keyword">new</span> MissingParameterException(CommandLine.this, msg + names);
                }
                <span class="keyword">if</span> (args.isEmpty()) {
                    <span class="keyword">throw</span> <span class="keyword">new</span> MissingParameterException(CommandLine.this, optionDescription(<span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>, field, <span class="integer">0</span>) +
                            <span class="string"><span class="delimiter">&quot;</span><span class="content"> requires at least </span><span class="delimiter">&quot;</span></span> + arity + <span class="string"><span class="delimiter">&quot;</span><span class="content"> values, but none were specified.</span><span class="delimiter">&quot;</span></span>);
                }
                <span class="keyword">throw</span> <span class="keyword">new</span> MissingParameterException(CommandLine.this, optionDescription(<span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>, field, <span class="integer">0</span>) +
                        <span class="string"><span class="delimiter">&quot;</span><span class="content"> requires at least </span><span class="delimiter">&quot;</span></span> + arity + <span class="string"><span class="delimiter">&quot;</span><span class="content"> values, but only </span><span class="delimiter">&quot;</span></span> + args.size() + <span class="string"><span class="delimiter">&quot;</span><span class="content"> were specified: </span><span class="delimiter">&quot;</span></span> + reverse(args));
            }
        }
        <span class="directive">private</span> <span class="predefined-type">String</span> trim(<span class="predefined-type">String</span> value) {
            <span class="keyword">return</span> unquote(value);
        }

        <span class="directive">private</span> <span class="predefined-type">String</span> unquote(<span class="predefined-type">String</span> value) {
            <span class="keyword">return</span> value == <span class="predefined-constant">null</span>
                    ? <span class="predefined-constant">null</span>
                    : (value.length() &gt; <span class="integer">1</span> &amp;&amp; value.startsWith(<span class="string"><span class="delimiter">&quot;</span><span class="char">\&quot;</span><span class="delimiter">&quot;</span></span>) &amp;&amp; value.endsWith(<span class="string"><span class="delimiter">&quot;</span><span class="char">\&quot;</span><span class="delimiter">&quot;</span></span>))
                        ? value.substring(<span class="integer">1</span>, value.length() - <span class="integer">1</span>)
                        : value;
        }
    }
    <span class="directive">private</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">PositionalParametersSorter</span> <span class="directive">implements</span> <span class="predefined-type">Comparator</span>&lt;<span class="predefined-type">Field</span>&gt; {
        <span class="directive">public</span> <span class="type">int</span> compare(<span class="predefined-type">Field</span> o1, <span class="predefined-type">Field</span> o2) {
            <span class="type">int</span> result = Range.parameterIndex(o1).compareTo(Range.parameterIndex(o2));
            <span class="keyword">return</span> (result == <span class="integer">0</span>) ? Range.parameterArity(o1).compareTo(Range.parameterArity(o2)) : result;
        }
    }
    <span class="comment">/**
     * Inner class to group the built-in {@link ITypeConverter} implementations.
     */</span>
    <span class="directive">private</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">BuiltIn</span> {
        <span class="directive">static</span> <span class="type">class</span> <span class="class">StringConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">String</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">String</span> convert(<span class="predefined-type">String</span> value) { <span class="keyword">return</span> value; }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">StringBuilderConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">StringBuilder</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">StringBuilder</span> convert(<span class="predefined-type">String</span> value) { <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>(value); }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">CharSequenceConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">CharSequence</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">String</span> convert(<span class="predefined-type">String</span> value) { <span class="keyword">return</span> value; }
        }
        <span class="comment">/** Converts text to a {@code Byte} by delegating to {@link Byte#valueOf(String)}.*/</span>
        <span class="directive">static</span> <span class="type">class</span> <span class="class">ByteConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Byte</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">Byte</span> convert(<span class="predefined-type">String</span> value) { <span class="keyword">return</span> <span class="predefined-type">Byte</span>.valueOf(value); }
        }
        <span class="comment">/** Converts {@code &quot;true&quot;} or {@code &quot;false&quot;} to a {@code Boolean}. Other values result in a ParameterException.*/</span>
        <span class="directive">static</span> <span class="type">class</span> <span class="class">BooleanConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Boolean</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">Boolean</span> convert(<span class="predefined-type">String</span> value) {
                <span class="keyword">if</span> (<span class="string"><span class="delimiter">&quot;</span><span class="content">true</span><span class="delimiter">&quot;</span></span>.equalsIgnoreCase(value) || <span class="string"><span class="delimiter">&quot;</span><span class="content">false</span><span class="delimiter">&quot;</span></span>.equalsIgnoreCase(value)) {
                    <span class="keyword">return</span> <span class="predefined-type">Boolean</span>.parseBoolean(value);
                } <span class="keyword">else</span> {
                    <span class="keyword">throw</span> <span class="keyword">new</span> TypeConversionException(<span class="string"><span class="delimiter">&quot;</span><span class="content">'</span><span class="delimiter">&quot;</span></span> + value + <span class="string"><span class="delimiter">&quot;</span><span class="content">' is not a boolean</span><span class="delimiter">&quot;</span></span>);
                }
            }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">CharacterConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Character</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">Character</span> convert(<span class="predefined-type">String</span> value) {
                <span class="keyword">if</span> (value.length() &gt; <span class="integer">1</span>) {
                    <span class="keyword">throw</span> <span class="keyword">new</span> TypeConversionException(<span class="string"><span class="delimiter">&quot;</span><span class="content">'</span><span class="delimiter">&quot;</span></span> + value + <span class="string"><span class="delimiter">&quot;</span><span class="content">' is not a single character</span><span class="delimiter">&quot;</span></span>);
                }
                <span class="keyword">return</span> value.charAt(<span class="integer">0</span>);
            }
        }
        <span class="comment">/** Converts text to a {@code Short} by delegating to {@link Short#valueOf(String)}.*/</span>
        <span class="directive">static</span> <span class="type">class</span> <span class="class">ShortConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Short</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">Short</span> convert(<span class="predefined-type">String</span> value) { <span class="keyword">return</span> <span class="predefined-type">Short</span>.valueOf(value); }
        }
        <span class="comment">/** Converts text to an {@code Integer} by delegating to {@link Integer#valueOf(String)}.*/</span>
        <span class="directive">static</span> <span class="type">class</span> <span class="class">IntegerConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Integer</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">Integer</span> convert(<span class="predefined-type">String</span> value) { <span class="keyword">return</span> <span class="predefined-type">Integer</span>.valueOf(value); }
        }
        <span class="comment">/** Converts text to a {@code Long} by delegating to {@link Long#valueOf(String)}.*/</span>
        <span class="directive">static</span> <span class="type">class</span> <span class="class">LongConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Long</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">Long</span> convert(<span class="predefined-type">String</span> value) { <span class="keyword">return</span> <span class="predefined-type">Long</span>.valueOf(value); }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">FloatConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Float</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">Float</span> convert(<span class="predefined-type">String</span> value) { <span class="keyword">return</span> <span class="predefined-type">Float</span>.valueOf(value); }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">DoubleConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Double</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">Double</span> convert(<span class="predefined-type">String</span> value) { <span class="keyword">return</span> <span class="predefined-type">Double</span>.valueOf(value); }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">FileConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">File</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">File</span> convert(<span class="predefined-type">String</span> value) { <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">File</span>(value); }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">URLConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">URL</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">URL</span> convert(<span class="predefined-type">String</span> value) <span class="directive">throws</span> <span class="exception">MalformedURLException</span> { <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">URL</span>(value); }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">URIConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">URI</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">URI</span> convert(<span class="predefined-type">String</span> value) <span class="directive">throws</span> <span class="exception">URISyntaxException</span> { <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">URI</span>(value); }
        }
        <span class="comment">/** Converts text in {@code yyyy-mm-dd} format to a {@code java.util.Date}. ParameterException on failure. */</span>
        <span class="directive">static</span> <span class="type">class</span> <span class="class">ISO8601DateConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Date</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">Date</span> convert(<span class="predefined-type">String</span> value) {
                <span class="keyword">try</span> {
                    <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">SimpleDateFormat</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">yyyy-MM-dd</span><span class="delimiter">&quot;</span></span>).parse(value);
                } <span class="keyword">catch</span> (<span class="exception">ParseException</span> e) {
                    <span class="keyword">throw</span> <span class="keyword">new</span> TypeConversionException(<span class="string"><span class="delimiter">&quot;</span><span class="content">'</span><span class="delimiter">&quot;</span></span> + value + <span class="string"><span class="delimiter">&quot;</span><span class="content">' is not a yyyy-MM-dd date</span><span class="delimiter">&quot;</span></span>);
                }
            }
        }
        <span class="comment">/** Converts text in any of the following formats to a {@code java.sql.Time}: {@code HH:mm}, {@code HH:mm:ss},
         * {@code HH:mm:ss.SSS}, {@code HH:mm:ss,SSS}. Other formats result in a ParameterException. */</span>
        <span class="directive">static</span> <span class="type">class</span> <span class="class">ISO8601TimeConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Time</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">Time</span> convert(<span class="predefined-type">String</span> value) {
                <span class="keyword">try</span> {
                    <span class="keyword">if</span> (value.length() &lt;= <span class="integer">5</span>) {
                        <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">Time</span>(<span class="keyword">new</span> <span class="predefined-type">SimpleDateFormat</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">HH:mm</span><span class="delimiter">&quot;</span></span>).parse(value).getTime());
                    } <span class="keyword">else</span> <span class="keyword">if</span> (value.length() &lt;= <span class="integer">8</span>) {
                        <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">Time</span>(<span class="keyword">new</span> <span class="predefined-type">SimpleDateFormat</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">HH:mm:ss</span><span class="delimiter">&quot;</span></span>).parse(value).getTime());
                    } <span class="keyword">else</span> <span class="keyword">if</span> (value.length() &lt;= <span class="integer">12</span>) {
                        <span class="keyword">try</span> {
                            <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">Time</span>(<span class="keyword">new</span> <span class="predefined-type">SimpleDateFormat</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">HH:mm:ss.SSS</span><span class="delimiter">&quot;</span></span>).parse(value).getTime());
                        } <span class="keyword">catch</span> (<span class="exception">ParseException</span> e2) {
                            <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">Time</span>(<span class="keyword">new</span> <span class="predefined-type">SimpleDateFormat</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">HH:mm:ss,SSS</span><span class="delimiter">&quot;</span></span>).parse(value).getTime());
                        }
                    }
                } <span class="keyword">catch</span> (<span class="exception">ParseException</span> ignored) {
                    <span class="comment">// ignored because we throw a ParameterException below</span>
                }
                <span class="keyword">throw</span> <span class="keyword">new</span> TypeConversionException(<span class="string"><span class="delimiter">&quot;</span><span class="content">'</span><span class="delimiter">&quot;</span></span> + value + <span class="string"><span class="delimiter">&quot;</span><span class="content">' is not a HH:mm[:ss[.SSS]] time</span><span class="delimiter">&quot;</span></span>);
            }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">BigDecimalConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">BigDecimal</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">BigDecimal</span> convert(<span class="predefined-type">String</span> value) { <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">BigDecimal</span>(value); }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">BigIntegerConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">BigInteger</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">BigInteger</span> convert(<span class="predefined-type">String</span> value) { <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">BigInteger</span>(value); }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">CharsetConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Charset</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">Charset</span> convert(<span class="predefined-type">String</span> s) { <span class="keyword">return</span> <span class="predefined-type">Charset</span>.forName(s); }
        }
        <span class="comment">/** Converts text to a {@code InetAddress} by delegating to {@link InetAddress#getByName(String)}. */</span>
        <span class="directive">static</span> <span class="type">class</span> <span class="class">InetAddressConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">InetAddress</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">InetAddress</span> convert(<span class="predefined-type">String</span> s) <span class="directive">throws</span> <span class="exception">Exception</span> { <span class="keyword">return</span> <span class="predefined-type">InetAddress</span>.getByName(s); }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">PatternConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Pattern</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">Pattern</span> convert(<span class="predefined-type">String</span> s) { <span class="keyword">return</span> <span class="predefined-type">Pattern</span>.compile(s); }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">UUIDConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">UUID</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">UUID</span> convert(<span class="predefined-type">String</span> s) <span class="directive">throws</span> <span class="exception">Exception</span> { <span class="keyword">return</span> <span class="predefined-type">UUID</span>.fromString(s); }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">CurrencyConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Currency</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">Currency</span> convert(<span class="predefined-type">String</span> s) <span class="directive">throws</span> <span class="exception">Exception</span> { <span class="keyword">return</span> <span class="predefined-type">Currency</span>.getInstance(s); }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">TimeZoneConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">TimeZone</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">TimeZone</span> convert(<span class="predefined-type">String</span> s) <span class="directive">throws</span> <span class="exception">Exception</span> { <span class="keyword">return</span> <span class="predefined-type">TimeZone</span>.getTimeZone(s); }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">ByteOrderConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">ByteOrder</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">ByteOrder</span> convert(<span class="predefined-type">String</span> s) <span class="directive">throws</span> <span class="exception">Exception</span> {
                <span class="keyword">if</span> (s.equalsIgnoreCase(<span class="predefined-type">ByteOrder</span>.BIG_ENDIAN.toString())) { <span class="keyword">return</span> <span class="predefined-type">ByteOrder</span>.BIG_ENDIAN; }
                <span class="keyword">if</span> (s.equalsIgnoreCase(<span class="predefined-type">ByteOrder</span>.LITTLE_ENDIAN.toString())) { <span class="keyword">return</span> <span class="predefined-type">ByteOrder</span>.LITTLE_ENDIAN; }
                <span class="keyword">throw</span> <span class="keyword">new</span> TypeConversionException(<span class="string"><span class="delimiter">&quot;</span><span class="content">'</span><span class="delimiter">&quot;</span></span> + s + <span class="string"><span class="delimiter">&quot;</span><span class="content">' is not a valid ByteOrder</span><span class="delimiter">&quot;</span></span>);
            }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">ClassConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Class</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">Class</span>&lt;?&gt; convert(<span class="predefined-type">String</span> s) <span class="directive">throws</span> <span class="exception">Exception</span> { <span class="keyword">return</span> <span class="predefined-type">Class</span>.forName(s); }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">NetworkInterfaceConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">NetworkInterface</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">NetworkInterface</span> convert(<span class="predefined-type">String</span> s) <span class="directive">throws</span> <span class="exception">Exception</span> {
                <span class="keyword">try</span> {
                    <span class="predefined-type">InetAddress</span> addr = <span class="keyword">new</span> InetAddressConverter().convert(s);
                    <span class="keyword">return</span> <span class="predefined-type">NetworkInterface</span>.getByInetAddress(addr);
                } <span class="keyword">catch</span> (<span class="exception">Exception</span> ex) {
                    <span class="keyword">try</span> { <span class="keyword">return</span> <span class="predefined-type">NetworkInterface</span>.getByName(s);
                    } <span class="keyword">catch</span> (<span class="exception">Exception</span> ex2) {
                        <span class="keyword">throw</span> <span class="keyword">new</span> TypeConversionException(<span class="string"><span class="delimiter">&quot;</span><span class="content">'</span><span class="delimiter">&quot;</span></span> + s + <span class="string"><span class="delimiter">&quot;</span><span class="content">' is not an InetAddress or NetworkInterface name</span><span class="delimiter">&quot;</span></span>);
                    }
                }
            }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">ConnectionConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Connection</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">Connection</span> convert(<span class="predefined-type">String</span> s) <span class="directive">throws</span> <span class="exception">Exception</span> { <span class="keyword">return</span> <span class="predefined-type">DriverManager</span>.getConnection(s); }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">DriverConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Driver</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">Driver</span> convert(<span class="predefined-type">String</span> s) <span class="directive">throws</span> <span class="exception">Exception</span> { <span class="keyword">return</span> <span class="predefined-type">DriverManager</span>.getDriver(s); }
        }
        <span class="directive">static</span> <span class="type">class</span> <span class="class">TimestampConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Timestamp</span>&gt; {
            <span class="directive">public</span> <span class="predefined-type">Timestamp</span> convert(<span class="predefined-type">String</span> s) <span class="directive">throws</span> <span class="exception">Exception</span> { <span class="keyword">return</span> <span class="predefined-type">Timestamp</span>.valueOf(s); }
        }
        <span class="directive">static</span> <span class="type">void</span> registerIfAvailable(<span class="predefined-type">Map</span>&lt;<span class="predefined-type">Class</span>&lt;?&gt;, ITypeConverter&lt;?&gt;&gt; registry, Tracer tracer, <span class="predefined-type">String</span> fqcn, <span class="predefined-type">String</span> factoryMethodName, <span class="predefined-type">Class</span>&lt;?&gt;... paramTypes) {
            registerIfAvailable(registry, tracer, fqcn, fqcn, factoryMethodName, paramTypes);
        }
        <span class="directive">static</span> <span class="type">void</span> registerIfAvailable(<span class="predefined-type">Map</span>&lt;<span class="predefined-type">Class</span>&lt;?&gt;, ITypeConverter&lt;?&gt;&gt; registry, Tracer tracer, <span class="predefined-type">String</span> fqcn, <span class="predefined-type">String</span> factoryClass, <span class="predefined-type">String</span> factoryMethodName, <span class="predefined-type">Class</span>&lt;?&gt;... paramTypes) {
            <span class="keyword">try</span> {
                <span class="predefined-type">Class</span>&lt;?&gt; cls = <span class="predefined-type">Class</span>.forName(fqcn);
                <span class="predefined-type">Class</span>&lt;?&gt; factory = <span class="predefined-type">Class</span>.forName(factoryClass);
                <span class="predefined-type">Method</span> method = factory.getDeclaredMethod(factoryMethodName, paramTypes);
                registry.put(cls, <span class="keyword">new</span> ReflectionConverter(method, paramTypes));
            } <span class="keyword">catch</span> (<span class="exception">Exception</span> e) {
                <span class="keyword">if</span> (!traced.contains(fqcn)) {
                    tracer.debug(<span class="string"><span class="delimiter">&quot;</span><span class="content">Could not register converter for %s: %s%n</span><span class="delimiter">&quot;</span></span>, fqcn, e.toString());
                }
                traced.add(fqcn);
            }
        }
        <span class="directive">static</span> <span class="predefined-type">Set</span>&lt;<span class="predefined-type">String</span>&gt; traced = <span class="keyword">new</span> <span class="predefined-type">HashSet</span>&lt;<span class="predefined-type">String</span>&gt;();
        <span class="directive">static</span> <span class="type">class</span> <span class="class">ReflectionConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Object</span>&gt; {
            <span class="directive">private</span> <span class="directive">final</span> <span class="predefined-type">Method</span> method;
            <span class="directive">private</span> <span class="predefined-type">Class</span>&lt;?&gt;<span class="type">[]</span> paramTypes;

            <span class="directive">public</span> ReflectionConverter(<span class="predefined-type">Method</span> method, <span class="predefined-type">Class</span>&lt;?&gt;... paramTypes) {
                <span class="local-variable">this</span>.method = Assert.notNull(method, <span class="string"><span class="delimiter">&quot;</span><span class="content">method</span><span class="delimiter">&quot;</span></span>);
                <span class="local-variable">this</span>.paramTypes = Assert.notNull(paramTypes, <span class="string"><span class="delimiter">&quot;</span><span class="content">paramTypes</span><span class="delimiter">&quot;</span></span>);
            }

            <span class="directive">public</span> <span class="predefined-type">Object</span> convert(<span class="predefined-type">String</span> s) {
                <span class="keyword">try</span> {
                    <span class="keyword">if</span> (paramTypes.length &gt; <span class="integer">1</span>) {
                        <span class="keyword">return</span> method.invoke(<span class="predefined-constant">null</span>, s, <span class="keyword">new</span> <span class="predefined-type">String</span>[<span class="integer">0</span>]);
                    } <span class="keyword">else</span> {
                        <span class="keyword">return</span> method.invoke(<span class="predefined-constant">null</span>, s);
                    }
                } <span class="keyword">catch</span> (<span class="exception">Exception</span> e) {
                    <span class="keyword">throw</span> <span class="keyword">new</span> TypeConversionException(<span class="string"><span class="delimiter">&quot;</span><span class="content">Unable to convert </span><span class="delimiter">&quot;</span></span> + s + <span class="string"><span class="delimiter">&quot;</span><span class="content"> to </span><span class="delimiter">&quot;</span></span> + method.getReturnType() + <span class="string"><span class="delimiter">&quot;</span><span class="content">: </span><span class="delimiter">&quot;</span></span> + e.getMessage());
                }
            }
        }
        <span class="directive">private</span> BuiltIn() {} <span class="comment">// private constructor: never instantiate</span>
    }

    <span class="comment">/**
     * A collection of methods and inner classes that provide fine-grained control over the contents and layout of
     * the usage help message to display to end users when help is requested or invalid input values were specified.
     * &lt;h3&gt;Layered API&lt;/h3&gt;
     * &lt;p&gt;The {@link Command} annotation provides the easiest way to customize usage help messages. See
     * the &lt;a href=&quot;https://remkop.github.io/picocli/index.html#_usage_help&quot;&gt;Manual&lt;/a&gt; for details.&lt;/p&gt;
     * &lt;p&gt;This Help class provides high-level functions to create sections of the usage help message and headings
     * for these sections. Instead of calling the {@link CommandLine#usage(PrintStream, CommandLine.Help.ColorScheme)}
     * method, application authors may want to create a custom usage help message by reorganizing sections in a
     * different order and/or adding custom sections.&lt;/p&gt;
     * &lt;p&gt;Finally, the Help class contains inner classes and interfaces that can be used to create custom help messages.&lt;/p&gt;
     * &lt;h4&gt;IOptionRenderer and IParameterRenderer&lt;/h4&gt;
     * &lt;p&gt;Renders a field annotated with {@link Option} or {@link Parameters} to an array of {@link Text} values.
     * By default, these values are&lt;/p&gt;&lt;ul&gt;
     * &lt;li&gt;mandatory marker character (if the option/parameter is {@link Option#required() required})&lt;/li&gt;
     * &lt;li&gt;short option name (empty for parameters)&lt;/li&gt;
     * &lt;li&gt;comma or empty (empty for parameters)&lt;/li&gt;
     * &lt;li&gt;long option names (the parameter {@link IParamLabelRenderer label} for parameters)&lt;/li&gt;
     * &lt;li&gt;description&lt;/li&gt;
     * &lt;/ul&gt;
     * &lt;p&gt;Other components rely on this ordering.&lt;/p&gt;
     * &lt;h4&gt;Layout&lt;/h4&gt;
     * &lt;p&gt;Delegates to the renderers to create {@link Text} values for the annotated fields, and uses a
     * {@link TextTable} to display these values in tabular format. Layout is responsible for deciding which values
     * to display where in the table. By default, Layout shows one option or parameter per table row.&lt;/p&gt;
     * &lt;h4&gt;TextTable&lt;/h4&gt;
     * &lt;p&gt;Responsible for spacing out {@link Text} values according to the {@link Column} definitions the table was
     * created with. Columns have a width, indentation, and an overflow policy that decides what to do if a value is
     * longer than the column's width.&lt;/p&gt;
     * &lt;h4&gt;Text&lt;/h4&gt;
     * &lt;p&gt;Encapsulates rich text with styles and colors in a way that other components like {@link TextTable} are
     * unaware of the embedded ANSI escape codes.&lt;/p&gt;
     */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">Help</span> {
        <span class="comment">/** Constant String holding the default program name: {@value} */</span>
        <span class="directive">protected</span> <span class="directive">static</span> <span class="directive">final</span> <span class="predefined-type">String</span> DEFAULT_COMMAND_NAME = <span class="string"><span class="delimiter">&quot;</span><span class="content">&lt;main class&gt;</span><span class="delimiter">&quot;</span></span>;

        <span class="comment">/** Constant String holding the default string that separates options from option parameters: {@value} */</span>
        <span class="directive">protected</span> <span class="directive">static</span> <span class="directive">final</span> <span class="predefined-type">String</span> DEFAULT_SEPARATOR = <span class="string"><span class="delimiter">&quot;</span><span class="content">=</span><span class="delimiter">&quot;</span></span>;

        <span class="directive">private</span> <span class="directive">final</span> <span class="directive">static</span> <span class="type">int</span> usageHelpWidth = <span class="integer">80</span>;
        <span class="directive">private</span> <span class="directive">final</span> <span class="directive">static</span> <span class="type">int</span> optionsColumnWidth = <span class="integer">2</span> + <span class="integer">2</span> + <span class="integer">1</span> + <span class="integer">24</span>;
        <span class="directive">private</span> <span class="directive">final</span> <span class="predefined-type">Object</span> command;
        <span class="directive">private</span> <span class="directive">final</span> <span class="predefined-type">Map</span>&lt;<span class="predefined-type">String</span>, Help&gt; commands = <span class="keyword">new</span> <span class="predefined-type">LinkedHashMap</span>&lt;<span class="predefined-type">String</span>, Help&gt;();
        <span class="directive">final</span> ColorScheme colorScheme;

        <span class="comment">/** Immutable list of fields annotated with {@link Option}, in declaration order. */</span>
        <span class="directive">public</span> <span class="directive">final</span> <span class="predefined-type">List</span>&lt;<span class="predefined-type">Field</span>&gt; optionFields;

        <span class="comment">/** Immutable list of fields annotated with {@link Parameters}, or an empty list if no such field exists. */</span>
        <span class="directive">public</span> <span class="directive">final</span> <span class="predefined-type">List</span>&lt;<span class="predefined-type">Field</span>&gt; positionalParametersFields;

        <span class="comment">/** The String to use as the separator between options and option parameters. {@code &quot;=&quot;} by default,
         * initialized from {@link Command#separator()} if defined.
         * @see #parameterLabelRenderer */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> separator;

        <span class="comment">/** The String to use as the program name in the synopsis line of the help message.
         * {@link #DEFAULT_COMMAND_NAME} by default, initialized from {@link Command#name()} if defined. */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> commandName = DEFAULT_COMMAND_NAME;

        <span class="comment">/** Optional text lines to use as the description of the help message, displayed between the synopsis and the
         * options list. Initialized from {@link Command#description()} if the {@code Command} annotation is present,
         * otherwise this is an empty array and the help message has no description.
         * Applications may programmatically set this field to create a custom help message. */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span><span class="type">[]</span> description = {};

        <span class="comment">/** Optional custom synopsis lines to use instead of the auto-generated synopsis.
         * Initialized from {@link Command#customSynopsis()} if the {@code Command} annotation is present,
         * otherwise this is an empty array and the synopsis is generated.
         * Applications may programmatically set this field to create a custom help message. */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span><span class="type">[]</span> customSynopsis = {};

        <span class="comment">/** Optional header lines displayed at the top of the help message. For subcommands, the first header line is
         * displayed in the list of commands. Values are initialized from {@link Command#header()}
         * if the {@code Command} annotation is present, otherwise this is an empty array and the help message has no
         * header. Applications may programmatically set this field to create a custom help message. */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span><span class="type">[]</span> header = {};

        <span class="comment">/** Optional footer text lines displayed at the bottom of the help message. Initialized from
         * {@link Command#footer()} if the {@code Command} annotation is present, otherwise this is an empty array and
         * the help message has no footer.
         * Applications may programmatically set this field to create a custom help message. */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span><span class="type">[]</span> footer = {};

        <span class="comment">/** Option and positional parameter value label renderer used for the synopsis line(s) and the option list.
         * By default initialized to the result of {@link #createDefaultParamLabelRenderer()}, which takes a snapshot
         * of the {@link #separator} at construction time. If the separator is modified after Help construction, you
         * may need to re-initialize this field by calling {@link #createDefaultParamLabelRenderer()} again. */</span>
        <span class="directive">public</span> IParamLabelRenderer parameterLabelRenderer;

        <span class="comment">/** If {@code true}, the synopsis line(s) will show an abbreviated synopsis without detailed option names. */</span>
        <span class="directive">public</span> <span class="predefined-type">Boolean</span> abbreviateSynopsis;

        <span class="comment">/** If {@code true}, the options list is sorted alphabetically. */</span>
        <span class="directive">public</span> <span class="predefined-type">Boolean</span> sortOptions;

        <span class="comment">/** If {@code true}, the options list will show default values for all options except booleans. */</span>
        <span class="directive">public</span> <span class="predefined-type">Boolean</span> showDefaultValues;

        <span class="comment">/** Character used to prefix required options in the options list. */</span>
        <span class="directive">public</span> <span class="predefined-type">Character</span> requiredOptionMarker;

        <span class="comment">/** Optional heading preceding the header section. Initialized from {@link Command#headerHeading()}, or null. */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> headerHeading;

        <span class="comment">/** Optional heading preceding the synopsis. Initialized from {@link Command#synopsisHeading()}, {@code &quot;Usage: &quot;} by default. */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> synopsisHeading;

        <span class="comment">/** Optional heading preceding the description section. Initialized from {@link Command#descriptionHeading()}, or null. */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> descriptionHeading;

        <span class="comment">/** Optional heading preceding the parameter list. Initialized from {@link Command#parameterListHeading()}, or null. */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> parameterListHeading;

        <span class="comment">/** Optional heading preceding the options list. Initialized from {@link Command#optionListHeading()}, or null. */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> optionListHeading;

        <span class="comment">/** Optional heading preceding the subcommand list. Initialized from {@link Command#commandListHeading()}. {@code &quot;Commands:%n&quot;} by default. */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> commandListHeading;

        <span class="comment">/** Optional heading preceding the footer section. Initialized from {@link Command#footerHeading()}, or null. */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> footerHeading;

        <span class="comment">/** Constructs a new {@code Help} instance with a default color scheme, initialized from annotatations
         * on the specified class and superclasses.
         * @param command the annotated object to create usage help for */</span>
        <span class="directive">public</span> Help(<span class="predefined-type">Object</span> command) {
            <span class="local-variable">this</span>(command, Ansi.AUTO);
        }

        <span class="comment">/** Constructs a new {@code Help} instance with a default color scheme, initialized from annotatations
         * on the specified class and superclasses.
         * @param command the annotated object to create usage help for
         * @param ansi whether to emit ANSI escape codes or not */</span>
        <span class="directive">public</span> Help(<span class="predefined-type">Object</span> command, Ansi ansi) {
            <span class="local-variable">this</span>(command, defaultColorScheme(ansi));
        }

        <span class="comment">/** Constructs a new {@code Help} instance with the specified color scheme, initialized from annotatations
         * on the specified class and superclasses.
         * @param command the annotated object to create usage help for
         * @param colorScheme the color scheme to use */</span>
        <span class="directive">public</span> Help(<span class="predefined-type">Object</span> command, ColorScheme colorScheme) {
            <span class="local-variable">this</span>.command = Assert.notNull(command, <span class="string"><span class="delimiter">&quot;</span><span class="content">command</span><span class="delimiter">&quot;</span></span>);
            <span class="local-variable">this</span>.colorScheme = Assert.notNull(colorScheme, <span class="string"><span class="delimiter">&quot;</span><span class="content">colorScheme</span><span class="delimiter">&quot;</span></span>).applySystemProperties();
            <span class="predefined-type">List</span>&lt;<span class="predefined-type">Field</span>&gt; options = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">Field</span>&gt;();
            <span class="predefined-type">List</span>&lt;<span class="predefined-type">Field</span>&gt; operands = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">Field</span>&gt;();
            <span class="predefined-type">Class</span>&lt;?&gt; cls = command.getClass();
            <span class="keyword">while</span> (cls != <span class="predefined-constant">null</span>) {
                <span class="keyword">for</span> (<span class="predefined-type">Field</span> field : cls.getDeclaredFields()) {
                    field.setAccessible(<span class="predefined-constant">true</span>);
                    <span class="keyword">if</span> (field.isAnnotationPresent(<span class="predefined-type">Option</span>.class)) {
                        <span class="predefined-type">Option</span> option = field.getAnnotation(<span class="predefined-type">Option</span>.class);
                        <span class="keyword">if</span> (!option.hidden()) { <span class="comment">// hidden options should not appear in usage help</span>
                            <span class="comment">// TODO remember longest concatenated option string length (issue #45)</span>
                            options.add(field);
                        }
                    }
                    <span class="keyword">if</span> (field.isAnnotationPresent(Parameters.class)) {
                        operands.add(field);
                    }
                }
                <span class="comment">// superclass values should not overwrite values if both class and superclass have a @Command annotation</span>
                <span class="keyword">if</span> (cls.isAnnotationPresent(Command.class)) {
                    Command cmd = cls.getAnnotation(Command.class);
                    <span class="keyword">if</span> (DEFAULT_COMMAND_NAME.equals(commandName)) {
                        commandName = cmd.name();
                    }
                    separator = (separator == <span class="predefined-constant">null</span>) ? cmd.separator() : separator;
                    abbreviateSynopsis = (abbreviateSynopsis == <span class="predefined-constant">null</span>) ? cmd.abbreviateSynopsis() : abbreviateSynopsis;
                    sortOptions = (sortOptions == <span class="predefined-constant">null</span>) ? cmd.sortOptions() : sortOptions;
                    requiredOptionMarker = (requiredOptionMarker == <span class="predefined-constant">null</span>) ? cmd.requiredOptionMarker() : requiredOptionMarker;
                    showDefaultValues = (showDefaultValues == <span class="predefined-constant">null</span>) ? cmd.showDefaultValues() : showDefaultValues;
                    customSynopsis = empty(customSynopsis) ? cmd.customSynopsis() : customSynopsis;
                    description = empty(description) ? cmd.description() : description;
                    header = empty(header) ? cmd.header() : header;
                    footer = empty(footer) ? cmd.footer() : footer;
                    headerHeading = empty(headerHeading) ? cmd.headerHeading() : headerHeading;
                    synopsisHeading = empty(synopsisHeading) || <span class="string"><span class="delimiter">&quot;</span><span class="content">Usage: </span><span class="delimiter">&quot;</span></span>.equals(synopsisHeading) ? cmd.synopsisHeading() : synopsisHeading;
                    descriptionHeading = empty(descriptionHeading) ? cmd.descriptionHeading() : descriptionHeading;
                    parameterListHeading = empty(parameterListHeading) ? cmd.parameterListHeading() : parameterListHeading;
                    optionListHeading = empty(optionListHeading) ? cmd.optionListHeading() : optionListHeading;
                    commandListHeading = empty(commandListHeading) || <span class="string"><span class="delimiter">&quot;</span><span class="content">Commands:%n</span><span class="delimiter">&quot;</span></span>.equals(commandListHeading) ? cmd.commandListHeading() : commandListHeading;
                    footerHeading = empty(footerHeading) ? cmd.footerHeading() : footerHeading;
                }
                cls = cls.getSuperclass();
            }
            sortOptions =          (sortOptions == <span class="predefined-constant">null</span>)          ? <span class="predefined-constant">true</span> : sortOptions;
            abbreviateSynopsis =   (abbreviateSynopsis == <span class="predefined-constant">null</span>)   ? <span class="predefined-constant">false</span> : abbreviateSynopsis;
            requiredOptionMarker = (requiredOptionMarker == <span class="predefined-constant">null</span>) ? <span class="string"><span class="delimiter">'</span><span class="content"> </span><span class="delimiter">'</span></span> : requiredOptionMarker;
            showDefaultValues =    (showDefaultValues == <span class="predefined-constant">null</span>)    ? <span class="predefined-constant">false</span> : showDefaultValues;
            synopsisHeading =      (synopsisHeading == <span class="predefined-constant">null</span>)      ? <span class="string"><span class="delimiter">&quot;</span><span class="content">Usage: </span><span class="delimiter">&quot;</span></span> : synopsisHeading;
            commandListHeading =   (commandListHeading == <span class="predefined-constant">null</span>)   ? <span class="string"><span class="delimiter">&quot;</span><span class="content">Commands:%n</span><span class="delimiter">&quot;</span></span> : commandListHeading;
            separator =            (separator == <span class="predefined-constant">null</span>)            ? DEFAULT_SEPARATOR : separator;
            parameterLabelRenderer = createDefaultParamLabelRenderer(); <span class="comment">// uses help separator</span>
            <span class="predefined-type">Collections</span>.sort(operands, <span class="keyword">new</span> PositionalParametersSorter());
            positionalParametersFields = <span class="predefined-type">Collections</span>.unmodifiableList(operands);
            optionFields                 = <span class="predefined-type">Collections</span>.unmodifiableList(options);
        }

        <span class="comment">/** Registers all specified subcommands with this Help.
         * @param commands maps the command names to the associated CommandLine object
         * @return this Help instance (for method chaining)
         * @see CommandLine#getSubcommands()
         */</span>
        <span class="directive">public</span> Help addAllSubcommands(<span class="predefined-type">Map</span>&lt;<span class="predefined-type">String</span>, CommandLine&gt; commands) {
            <span class="keyword">if</span> (commands != <span class="predefined-constant">null</span>) {
                <span class="keyword">for</span> (<span class="predefined-type">Map</span>.Entry&lt;<span class="predefined-type">String</span>, CommandLine&gt; entry : commands.entrySet()) {
                    addSubcommand(entry.getKey(), entry.getValue().getCommand());
                }
            }
            <span class="keyword">return</span> <span class="local-variable">this</span>;
        }

        <span class="comment">/** Registers the specified subcommand with this Help.
         * @param commandName the name of the subcommand to display in the usage message
         * @param command the annotated object to get more information from
         * @return this Help instance (for method chaining)
         */</span>
        <span class="directive">public</span> Help addSubcommand(<span class="predefined-type">String</span> commandName, <span class="predefined-type">Object</span> command) {
            commands.put(commandName, <span class="keyword">new</span> Help(command));
            <span class="keyword">return</span> <span class="local-variable">this</span>;
        }

        <span class="comment">/** Returns a synopsis for the command without reserving space for the synopsis heading.
         * @return a synopsis
         * @see #abbreviatedSynopsis()
         * @see #detailedSynopsis(Comparator, boolean)
         * @deprecated use {@link #synopsis(int)} instead
         */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> synopsis() { <span class="keyword">return</span> synopsis(<span class="integer">0</span>); }

        <span class="comment">/**
         * Returns a synopsis for the command, reserving the specified space for the synopsis heading.
         * @param synopsisHeadingLength the length of the synopsis heading that will be displayed on the same line
         * @return a synopsis
         * @see #abbreviatedSynopsis()
         * @see #detailedSynopsis(Comparator, boolean)
         * @see #synopsisHeading
         */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> synopsis(<span class="type">int</span> synopsisHeadingLength) {
            <span class="keyword">if</span> (!empty(customSynopsis)) { <span class="keyword">return</span> customSynopsis(); }
            <span class="keyword">return</span> abbreviateSynopsis ? abbreviatedSynopsis()
                    : detailedSynopsis(synopsisHeadingLength, createShortOptionArityAndNameComparator(), <span class="predefined-constant">true</span>);
        }

        <span class="comment">/** Generates a generic synopsis like {@code &lt;command name&gt; [OPTIONS] [PARAM1 [PARAM2]...]}, omitting parts
         * that don't apply to the command (e.g., does not show [OPTIONS] if the command has no options).
         * @return a generic synopsis */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> abbreviatedSynopsis() {
            <span class="predefined-type">StringBuilder</span> sb = <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>();
            <span class="keyword">if</span> (!optionFields.isEmpty()) { <span class="comment">// only show if annotated object actually has options</span>
                sb.append(<span class="string"><span class="delimiter">&quot;</span><span class="content"> [OPTIONS]</span><span class="delimiter">&quot;</span></span>);
            }
            <span class="comment">// sb.append(&quot; [--] &quot;); // implied</span>
            <span class="keyword">for</span> (<span class="predefined-type">Field</span> positionalParam : positionalParametersFields) {
                <span class="keyword">if</span> (!positionalParam.getAnnotation(Parameters.class).hidden()) {
                    sb.append(<span class="string"><span class="delimiter">'</span><span class="content"> </span><span class="delimiter">'</span></span>).append(parameterLabelRenderer.renderParameterLabel(positionalParam, ansi(), colorScheme.parameterStyles));
                }
            }
            <span class="keyword">return</span> colorScheme.commandText(commandName).toString()
                    + (sb.toString()) + <span class="predefined-type">System</span>.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">line.separator</span><span class="delimiter">&quot;</span></span>);
        }
        <span class="comment">/** Generates a detailed synopsis message showing all options and parameters. Follows the unix convention of
         * showing optional options and parameters in square brackets ({@code [ ]}).
         * @param optionSort comparator to sort options or {@code null} if options should not be sorted
         * @param clusterBooleanOptions {@code true} if boolean short options should be clustered into a single string
         * @return a detailed synopsis
         * @deprecated use {@link #detailedSynopsis(int, Comparator, boolean)} instead. */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> detailedSynopsis(<span class="predefined-type">Comparator</span>&lt;<span class="predefined-type">Field</span>&gt; optionSort, <span class="type">boolean</span> clusterBooleanOptions) {
            <span class="keyword">return</span> detailedSynopsis(<span class="integer">0</span>, optionSort, clusterBooleanOptions);
        }

        <span class="comment">/** Generates a detailed synopsis message showing all options and parameters. Follows the unix convention of
         * showing optional options and parameters in square brackets ({@code [ ]}).
         * @param synopsisHeadingLength the length of the synopsis heading that will be displayed on the same line
         * @param optionSort comparator to sort options or {@code null} if options should not be sorted
         * @param clusterBooleanOptions {@code true} if boolean short options should be clustered into a single string
         * @return a detailed synopsis */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> detailedSynopsis(<span class="type">int</span> synopsisHeadingLength, <span class="predefined-type">Comparator</span>&lt;<span class="predefined-type">Field</span>&gt; optionSort, <span class="type">boolean</span> clusterBooleanOptions) {
            Text optionText = ansi().new Text(<span class="integer">0</span>);
            <span class="predefined-type">List</span>&lt;<span class="predefined-type">Field</span>&gt; fields = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">Field</span>&gt;(optionFields); <span class="comment">// iterate in declaration order</span>
            <span class="keyword">if</span> (optionSort != <span class="predefined-constant">null</span>) {
                <span class="predefined-type">Collections</span>.sort(fields, optionSort);<span class="comment">// iterate in specified sort order</span>
            }
            <span class="keyword">if</span> (clusterBooleanOptions) { <span class="comment">// cluster all short boolean options into a single string</span>
                <span class="predefined-type">List</span>&lt;<span class="predefined-type">Field</span>&gt; booleanOptions = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">Field</span>&gt;();
                <span class="predefined-type">StringBuilder</span> clusteredRequired = <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">-</span><span class="delimiter">&quot;</span></span>);
                <span class="predefined-type">StringBuilder</span> clusteredOptional = <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">-</span><span class="delimiter">&quot;</span></span>);
                <span class="keyword">for</span> (<span class="predefined-type">Field</span> field : fields) {
                    <span class="keyword">if</span> (field.getType() == <span class="type">boolean</span>.class || field.getType() == <span class="predefined-type">Boolean</span>.class) {
                        <span class="predefined-type">Option</span> option = field.getAnnotation(<span class="predefined-type">Option</span>.class);
                        <span class="predefined-type">String</span> shortestName = ShortestFirst.sort(option.names())[<span class="integer">0</span>];
                        <span class="keyword">if</span> (shortestName.length() == <span class="integer">2</span> &amp;&amp; shortestName.startsWith(<span class="string"><span class="delimiter">&quot;</span><span class="content">-</span><span class="delimiter">&quot;</span></span>)) {
                            booleanOptions.add(field);
                            <span class="keyword">if</span> (option.required()) {
                                clusteredRequired.append(shortestName.substring(<span class="integer">1</span>));
                            } <span class="keyword">else</span> {
                                clusteredOptional.append(shortestName.substring(<span class="integer">1</span>));
                            }
                        }
                    }
                }
                fields.removeAll(booleanOptions);
                <span class="keyword">if</span> (clusteredRequired.length() &gt; <span class="integer">1</span>) { <span class="comment">// initial length was 1</span>
                    optionText = optionText.append(<span class="string"><span class="delimiter">&quot;</span><span class="content"> </span><span class="delimiter">&quot;</span></span>).append(colorScheme.optionText(clusteredRequired.toString()));
                }
                <span class="keyword">if</span> (clusteredOptional.length() &gt; <span class="integer">1</span>) { <span class="comment">// initial length was 1</span>
                    optionText = optionText.append(<span class="string"><span class="delimiter">&quot;</span><span class="content"> [</span><span class="delimiter">&quot;</span></span>).append(colorScheme.optionText(clusteredOptional.toString())).append(<span class="string"><span class="delimiter">&quot;</span><span class="content">]</span><span class="delimiter">&quot;</span></span>);
                }
            }
            <span class="keyword">for</span> (<span class="predefined-type">Field</span> field : fields) {
                <span class="predefined-type">Option</span> option = field.getAnnotation(<span class="predefined-type">Option</span>.class);
                <span class="keyword">if</span> (!option.hidden()) {
                    <span class="keyword">if</span> (option.required()) {
                        optionText = appendOptionSynopsis(optionText, field, ShortestFirst.sort(option.names())[<span class="integer">0</span>], <span class="string"><span class="delimiter">&quot;</span><span class="content"> </span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>);
                        <span class="keyword">if</span> (isMultiValue(field)) {
                            optionText = appendOptionSynopsis(optionText, field, ShortestFirst.sort(option.names())[<span class="integer">0</span>], <span class="string"><span class="delimiter">&quot;</span><span class="content"> [</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">]...</span><span class="delimiter">&quot;</span></span>);
                        }
                    } <span class="keyword">else</span> {
                        optionText = appendOptionSynopsis(optionText, field, ShortestFirst.sort(option.names())[<span class="integer">0</span>], <span class="string"><span class="delimiter">&quot;</span><span class="content"> [</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">]</span><span class="delimiter">&quot;</span></span>);
                        <span class="keyword">if</span> (isMultiValue(field)) {
                            optionText = optionText.append(<span class="string"><span class="delimiter">&quot;</span><span class="content">...</span><span class="delimiter">&quot;</span></span>);
                        }
                    }
                }
            }
            <span class="keyword">for</span> (<span class="predefined-type">Field</span> positionalParam : positionalParametersFields) {
                <span class="keyword">if</span> (!positionalParam.getAnnotation(Parameters.class).hidden()) {
                    optionText = optionText.append(<span class="string"><span class="delimiter">&quot;</span><span class="content"> </span><span class="delimiter">&quot;</span></span>);
                    Text label = parameterLabelRenderer.renderParameterLabel(positionalParam, colorScheme.ansi(), colorScheme.parameterStyles);
                    optionText = optionText.append(label);
                }
            }
            <span class="comment">// Fix for #142: first line of synopsis overshoots max. characters</span>
            <span class="type">int</span> firstColumnLength = commandName.length() + synopsisHeadingLength;

            <span class="comment">// synopsis heading (&quot;Usage: &quot;) may be on the same line, so adjust column width</span>
            TextTable textTable = <span class="keyword">new</span> TextTable(ansi(), firstColumnLength, usageHelpWidth - firstColumnLength);
            textTable.indentWrappedLines = <span class="integer">1</span>; <span class="comment">// don't worry about first line: options (2nd column) always start with a space</span>

            <span class="comment">// right-adjust the command name by length of synopsis heading</span>
            Text PADDING = Ansi.OFF.new Text(stringOf(<span class="string"><span class="delimiter">'</span><span class="content">X</span><span class="delimiter">'</span></span>, synopsisHeadingLength));
            textTable.addRowValues(<span class="keyword">new</span> Text<span class="type">[]</span> {PADDING.append(colorScheme.commandText(commandName)), optionText});
            <span class="keyword">return</span> textTable.toString().substring(synopsisHeadingLength); <span class="comment">// cut off leading synopsis heading spaces</span>
        }

        <span class="directive">private</span> Text appendOptionSynopsis(Text optionText, <span class="predefined-type">Field</span> field, <span class="predefined-type">String</span> optionName, <span class="predefined-type">String</span> prefix, <span class="predefined-type">String</span> suffix) {
            Text optionParamText = parameterLabelRenderer.renderParameterLabel(field, colorScheme.ansi(), colorScheme.optionParamStyles);
            <span class="keyword">return</span> optionText.append(prefix)
                    .append(colorScheme.optionText(optionName))
                    .append(optionParamText)
                    .append(suffix);
        }

        <span class="comment">/** Returns the number of characters the synopsis heading will take on the same line as the synopsis.
         * @return the number of characters the synopsis heading will take on the same line as the synopsis.
         * @see #detailedSynopsis(int, Comparator, boolean)
         */</span>
        <span class="directive">public</span> <span class="type">int</span> synopsisHeadingLength() {
            <span class="predefined-type">String</span><span class="type">[]</span> lines = Ansi.OFF.new Text(synopsisHeading).toString().split(<span class="string"><span class="delimiter">&quot;</span><span class="char">\\</span><span class="content">r?</span><span class="char">\\</span><span class="content">n|</span><span class="char">\\</span><span class="content">r|%n</span><span class="delimiter">&quot;</span></span>, -<span class="integer">1</span>);
            <span class="keyword">return</span> lines[lines.length - <span class="integer">1</span>].length();
        }
        <span class="comment">/**
         * &lt;p&gt;Returns a description of the {@linkplain Option options} supported by the application.
         * This implementation {@linkplain #createShortOptionNameComparator() sorts options alphabetically}, and shows
         * only the {@linkplain Option#hidden() non-hidden} options in a {@linkplain TextTable tabular format}
         * using the {@linkplain #createDefaultOptionRenderer() default renderer} and {@linkplain Layout default layout}.&lt;/p&gt;
         * @return the fully formatted option list
         * @see #optionList(Layout, Comparator, IParamLabelRenderer)
         */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> optionList() {
            <span class="predefined-type">Comparator</span>&lt;<span class="predefined-type">Field</span>&gt; sortOrder = sortOptions == <span class="predefined-constant">null</span> || sortOptions.booleanValue()
                    ? createShortOptionNameComparator()
                    : <span class="predefined-constant">null</span>;
            <span class="keyword">return</span> optionList(createDefaultLayout(), sortOrder, parameterLabelRenderer);
        }

        <span class="comment">/** Sorts all {@code Options} with the specified {@code comparator} (if the comparator is non-{@code null}),
         * then {@linkplain Layout#addOption(Field, CommandLine.Help.IParamLabelRenderer) adds} all non-hidden options to the
         * specified TextTable and returns the result of TextTable.toString().
         * @param layout responsible for rendering the option list
         * @param optionSort determines in what order {@code Options} should be listed. Declared order if {@code null}
         * @param valueLabelRenderer used for options with a parameter
         * @return the fully formatted option list
         */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> optionList(Layout layout, <span class="predefined-type">Comparator</span>&lt;<span class="predefined-type">Field</span>&gt; optionSort, IParamLabelRenderer valueLabelRenderer) {
            <span class="predefined-type">List</span>&lt;<span class="predefined-type">Field</span>&gt; fields = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">Field</span>&gt;(optionFields); <span class="comment">// options are stored in order of declaration</span>
            <span class="keyword">if</span> (optionSort != <span class="predefined-constant">null</span>) {
                <span class="predefined-type">Collections</span>.sort(fields, optionSort); <span class="comment">// default: sort options ABC</span>
            }
            layout.addOptions(fields, valueLabelRenderer);
            <span class="keyword">return</span> layout.toString();
        }

        <span class="comment">/**
         * Returns the section of the usage help message that lists the parameters with their descriptions.
         * @return the section of the usage help message that lists the parameters
         */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> parameterList() {
            <span class="keyword">return</span> parameterList(createDefaultLayout(), parameterLabelRenderer);
        }
        <span class="comment">/**
         * Returns the section of the usage help message that lists the parameters with their descriptions.
         * @param layout the layout to use
         * @param paramLabelRenderer for rendering parameter names
         * @return the section of the usage help message that lists the parameters
         */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> parameterList(Layout layout, IParamLabelRenderer paramLabelRenderer) {
            layout.addPositionalParameters(positionalParametersFields, paramLabelRenderer);
            <span class="keyword">return</span> layout.toString();
        }

        <span class="directive">private</span> <span class="directive">static</span> <span class="predefined-type">String</span> heading(Ansi ansi, <span class="predefined-type">String</span> values, <span class="predefined-type">Object</span>... params) {
            <span class="predefined-type">StringBuilder</span> sb = join(ansi, <span class="keyword">new</span> <span class="predefined-type">String</span><span class="type">[]</span> {values}, <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>(), params);
            <span class="predefined-type">String</span> result = sb.toString();
            result = result.endsWith(<span class="predefined-type">System</span>.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">line.separator</span><span class="delimiter">&quot;</span></span>))
                    ? result.substring(<span class="integer">0</span>, result.length() - <span class="predefined-type">System</span>.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">line.separator</span><span class="delimiter">&quot;</span></span>).length()) : result;
            <span class="keyword">return</span> result + <span class="keyword">new</span> <span class="predefined-type">String</span>(spaces(countTrailingSpaces(values)));
        }
        <span class="directive">private</span> <span class="directive">static</span> <span class="type">char</span><span class="type">[]</span> spaces(<span class="type">int</span> length) { <span class="type">char</span><span class="type">[]</span> result = <span class="keyword">new</span> <span class="type">char</span>[length]; <span class="predefined-type">Arrays</span>.fill(result, <span class="string"><span class="delimiter">'</span><span class="content"> </span><span class="delimiter">'</span></span>); <span class="keyword">return</span> result; }
        <span class="directive">private</span> <span class="directive">static</span> <span class="type">int</span> countTrailingSpaces(<span class="predefined-type">String</span> str) {
            <span class="keyword">if</span> (str == <span class="predefined-constant">null</span>) {<span class="keyword">return</span> <span class="integer">0</span>;}
            <span class="type">int</span> trailingSpaces = <span class="integer">0</span>;
            <span class="keyword">for</span> (<span class="type">int</span> i = str.length() - <span class="integer">1</span>; i &gt;= <span class="integer">0</span> &amp;&amp; str.charAt(i) == <span class="string"><span class="delimiter">'</span><span class="content"> </span><span class="delimiter">'</span></span>; i--) { trailingSpaces++; }
            <span class="keyword">return</span> trailingSpaces;
        }

        <span class="comment">/** Formats each of the specified values and appends it to the specified StringBuilder.
         * @param ansi whether the result should contain ANSI escape codes or not
         * @param values the values to format and append to the StringBuilder
         * @param sb the StringBuilder to collect the formatted strings
         * @param params the parameters to pass to the format method when formatting each value
         * @return the specified StringBuilder */</span>
        <span class="directive">public</span> <span class="directive">static</span> <span class="predefined-type">StringBuilder</span> join(Ansi ansi, <span class="predefined-type">String</span><span class="type">[]</span> values, <span class="predefined-type">StringBuilder</span> sb, <span class="predefined-type">Object</span>... params) {
            <span class="keyword">if</span> (values != <span class="predefined-constant">null</span>) {
                TextTable table = <span class="keyword">new</span> TextTable(ansi, usageHelpWidth);
                table.indentWrappedLines = <span class="integer">0</span>;
                <span class="keyword">for</span> (<span class="predefined-type">String</span> summaryLine : values) {
                    Text<span class="type">[]</span> lines = ansi.new Text(format(summaryLine, params)).splitLines();
                    <span class="keyword">for</span> (Text line : lines) {  table.addRowValues(line); }
                }
                table.toString(sb);
            }
            <span class="keyword">return</span> sb;
        }
        <span class="directive">private</span> <span class="directive">static</span> <span class="predefined-type">String</span> format(<span class="predefined-type">String</span> formatString,  <span class="predefined-type">Object</span>... params) {
            <span class="keyword">return</span> formatString == <span class="predefined-constant">null</span> ? <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span> : <span class="predefined-type">String</span>.format(formatString, params);
        }
        <span class="comment">/** Returns command custom synopsis as a string. A custom synopsis can be zero or more lines, and can be
         * specified declaratively with the {@link Command#customSynopsis()} annotation attribute or programmatically
         * by setting the Help instance's {@link Help#customSynopsis} field.
         * @param params Arguments referenced by the format specifiers in the synopsis strings
         * @return the custom synopsis lines combined into a single String (which may be empty)
         */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> customSynopsis(<span class="predefined-type">Object</span>... params) {
            <span class="keyword">return</span> join(ansi(), customSynopsis, <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>(), params).toString();
        }
        <span class="comment">/** Returns command description text as a string. Description text can be zero or more lines, and can be specified
         * declaratively with the {@link Command#description()} annotation attribute or programmatically by
         * setting the Help instance's {@link Help#description} field.
         * @param params Arguments referenced by the format specifiers in the description strings
         * @return the description lines combined into a single String (which may be empty)
         */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> description(<span class="predefined-type">Object</span>... params) {
            <span class="keyword">return</span> join(ansi(), description, <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>(), params).toString();
        }
        <span class="comment">/** Returns the command header text as a string. Header text can be zero or more lines, and can be specified
         * declaratively with the {@link Command#header()} annotation attribute or programmatically by
         * setting the Help instance's {@link Help#header} field.
         * @param params Arguments referenced by the format specifiers in the header strings
         * @return the header lines combined into a single String (which may be empty)
         */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> header(<span class="predefined-type">Object</span>... params) {
            <span class="keyword">return</span> join(ansi(), header, <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>(), params).toString();
        }
        <span class="comment">/** Returns command footer text as a string. Footer text can be zero or more lines, and can be specified
         * declaratively with the {@link Command#footer()} annotation attribute or programmatically by
         * setting the Help instance's {@link Help#footer} field.
         * @param params Arguments referenced by the format specifiers in the footer strings
         * @return the footer lines combined into a single String (which may be empty)
         */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> footer(<span class="predefined-type">Object</span>... params) {
            <span class="keyword">return</span> join(ansi(), footer, <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>(), params).toString();
        }

        <span class="comment">/** Returns the text displayed before the header text; the result of {@code String.format(headerHeading, params)}.
         * @param params the parameters to use to format the header heading
         * @return the formatted header heading */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> headerHeading(<span class="predefined-type">Object</span>... params) {
            <span class="keyword">return</span> heading(ansi(), headerHeading, params);
        }

        <span class="comment">/** Returns the text displayed before the synopsis text; the result of {@code String.format(synopsisHeading, params)}.
         * @param params the parameters to use to format the synopsis heading
         * @return the formatted synopsis heading */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> synopsisHeading(<span class="predefined-type">Object</span>... params) {
            <span class="keyword">return</span> heading(ansi(), synopsisHeading, params);
        }

        <span class="comment">/** Returns the text displayed before the description text; an empty string if there is no description,
         * otherwise the result of {@code String.format(descriptionHeading, params)}.
         * @param params the parameters to use to format the description heading
         * @return the formatted description heading */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> descriptionHeading(<span class="predefined-type">Object</span>... params) {
            <span class="keyword">return</span> empty(descriptionHeading) ? <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span> : heading(ansi(), descriptionHeading, params);
        }

        <span class="comment">/** Returns the text displayed before the positional parameter list; an empty string if there are no positional
         * parameters, otherwise the result of {@code String.format(parameterListHeading, params)}.
         * @param params the parameters to use to format the parameter list heading
         * @return the formatted parameter list heading */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> parameterListHeading(<span class="predefined-type">Object</span>... params) {
            <span class="keyword">return</span> positionalParametersFields.isEmpty() ? <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span> : heading(ansi(), parameterListHeading, params);
        }

        <span class="comment">/** Returns the text displayed before the option list; an empty string if there are no options,
         * otherwise the result of {@code String.format(optionListHeading, params)}.
         * @param params the parameters to use to format the option list heading
         * @return the formatted option list heading */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> optionListHeading(<span class="predefined-type">Object</span>... params) {
            <span class="keyword">return</span> optionFields.isEmpty() ? <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span> : heading(ansi(), optionListHeading, params);
        }

        <span class="comment">/** Returns the text displayed before the command list; an empty string if there are no commands,
         * otherwise the result of {@code String.format(commandListHeading, params)}.
         * @param params the parameters to use to format the command list heading
         * @return the formatted command list heading */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> commandListHeading(<span class="predefined-type">Object</span>... params) {
            <span class="keyword">return</span> commands.isEmpty() ? <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span> : heading(ansi(), commandListHeading, params);
        }

        <span class="comment">/** Returns the text displayed before the footer text; the result of {@code String.format(footerHeading, params)}.
         * @param params the parameters to use to format the footer heading
         * @return the formatted footer heading */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> footerHeading(<span class="predefined-type">Object</span>... params) {
            <span class="keyword">return</span> heading(ansi(), footerHeading, params);
        }
        <span class="comment">/** Returns a 2-column list with command names and the first line of their header or (if absent) description.
         * @return a usage help section describing the added commands */</span>
        <span class="directive">public</span> <span class="predefined-type">String</span> commandList() {
            <span class="keyword">if</span> (commands.isEmpty()) { <span class="keyword">return</span> <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>; }
            <span class="type">int</span> commandLength = maxLength(commands.keySet());
            Help.TextTable textTable = <span class="keyword">new</span> Help.TextTable(ansi(),
                    <span class="keyword">new</span> Help.Column(commandLength + <span class="integer">2</span>, <span class="integer">2</span>, Help.Column.Overflow.SPAN),
                    <span class="keyword">new</span> Help.Column(usageHelpWidth - (commandLength + <span class="integer">2</span>), <span class="integer">2</span>, Help.Column.Overflow.WRAP));

            <span class="keyword">for</span> (<span class="predefined-type">Map</span>.Entry&lt;<span class="predefined-type">String</span>, Help&gt; entry : commands.entrySet()) {
                Help command = entry.getValue();
                <span class="predefined-type">String</span> header = command.header != <span class="predefined-constant">null</span> &amp;&amp; command.header.length &gt; <span class="integer">0</span> ? command.header[<span class="integer">0</span>]
                        : (command.description != <span class="predefined-constant">null</span> &amp;&amp; command.description.length &gt; <span class="integer">0</span> ? command.description[<span class="integer">0</span>] : <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>);
                textTable.addRowValues(colorScheme.commandText(entry.getKey()), ansi().new Text(header));
            }
            <span class="keyword">return</span> textTable.toString();
        }
        <span class="directive">private</span> <span class="directive">static</span> <span class="type">int</span> maxLength(<span class="predefined-type">Collection</span>&lt;<span class="predefined-type">String</span>&gt; any) {
            <span class="predefined-type">List</span>&lt;<span class="predefined-type">String</span>&gt; strings = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">String</span>&gt;(any);
            <span class="predefined-type">Collections</span>.sort(strings, <span class="predefined-type">Collections</span>.reverseOrder(Help.shortestFirst()));
            <span class="keyword">return</span> strings.get(<span class="integer">0</span>).length();
        }
        <span class="directive">private</span> <span class="directive">static</span> <span class="predefined-type">String</span> join(<span class="predefined-type">String</span><span class="type">[]</span> names, <span class="type">int</span> offset, <span class="type">int</span> length, <span class="predefined-type">String</span> separator) {
            <span class="keyword">if</span> (names == <span class="predefined-constant">null</span>) { <span class="keyword">return</span> <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>; }
            <span class="predefined-type">StringBuilder</span> result = <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>();
            <span class="keyword">for</span> (<span class="type">int</span> i = offset; i &lt; offset + length; i++) {
                result.append((i &gt; offset) ? separator : <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>).append(names[i]);
            }
            <span class="keyword">return</span> result.toString();
        }
        <span class="directive">private</span> <span class="directive">static</span> <span class="predefined-type">String</span> stringOf(<span class="type">char</span> chr, <span class="type">int</span> length) {
            <span class="type">char</span><span class="type">[]</span> buff = <span class="keyword">new</span> <span class="type">char</span>[length];
            <span class="predefined-type">Arrays</span>.fill(buff, chr);
            <span class="keyword">return</span> <span class="keyword">new</span> <span class="predefined-type">String</span>(buff);
        }

        <span class="comment">/** Returns a {@code Layout} instance configured with the user preferences captured in this Help instance.
         * @return a Layout */</span>
        <span class="directive">public</span> Layout createDefaultLayout() {
            <span class="keyword">return</span> <span class="keyword">new</span> Layout(colorScheme, <span class="keyword">new</span> TextTable(colorScheme.ansi()), createDefaultOptionRenderer(), createDefaultParameterRenderer());
        }
        <span class="comment">/** Returns a new default OptionRenderer which converts {@link Option Options} to five columns of text to match
         *  the default {@linkplain TextTable TextTable} column layout. The first row of values looks like this:
         * &lt;ol&gt;
         * &lt;li&gt;the required option marker&lt;/li&gt;
         * &lt;li&gt;2-character short option name (or empty string if no short option exists)&lt;/li&gt;
         * &lt;li&gt;comma separator (only if both short option and long option exist, empty string otherwise)&lt;/li&gt;
         * &lt;li&gt;comma-separated string with long option name(s)&lt;/li&gt;
         * &lt;li&gt;first element of the {@link Option#description()} array&lt;/li&gt;
         * &lt;/ol&gt;
         * &lt;p&gt;Following this, there will be one row for each of the remaining elements of the {@link
         *   Option#description()} array, and these rows look like {@code {&quot;&quot;, &quot;&quot;, &quot;&quot;, &quot;&quot;, option.description()[i]}}.&lt;/p&gt;
         * &lt;p&gt;If configured, this option renderer adds an additional row to display the default field value.&lt;/p&gt;
         * @return a new default OptionRenderer
         */</span>
        <span class="directive">public</span> IOptionRenderer createDefaultOptionRenderer() {
            DefaultOptionRenderer result = <span class="keyword">new</span> DefaultOptionRenderer();
            result.requiredMarker = <span class="predefined-type">String</span>.valueOf(requiredOptionMarker);
            <span class="keyword">if</span> (showDefaultValues != <span class="predefined-constant">null</span> &amp;&amp; showDefaultValues.booleanValue()) {
                result.command = <span class="local-variable">this</span>.command;
            }
            <span class="keyword">return</span> result;
        }
        <span class="comment">/** Returns a new minimal OptionRenderer which converts {@link Option Options} to a single row with two columns
         * of text: an option name and a description. If multiple names or descriptions exist, the first value is used.
         * @return a new minimal OptionRenderer */</span>
        <span class="directive">public</span> <span class="directive">static</span> IOptionRenderer createMinimalOptionRenderer() {
            <span class="keyword">return</span> <span class="keyword">new</span> MinimalOptionRenderer();
        }

        <span class="comment">/** Returns a new default ParameterRenderer which converts {@link Parameters Parameters} to four columns of
         * text to match the default {@linkplain TextTable TextTable} column layout. The first row of values looks like this:
         * &lt;ol&gt;
         * &lt;li&gt;empty string &lt;/li&gt;
         * &lt;li&gt;empty string &lt;/li&gt;
         * &lt;li&gt;parameter(s) label as rendered by the {@link IParamLabelRenderer}&lt;/li&gt;
         * &lt;li&gt;first element of the {@link Parameters#description()} array&lt;/li&gt;
         * &lt;/ol&gt;
         * &lt;p&gt;Following this, there will be one row for each of the remaining elements of the {@link
         *   Parameters#description()} array, and these rows look like {@code {&quot;&quot;, &quot;&quot;, &quot;&quot;, param.description()[i]}}.&lt;/p&gt;
         * &lt;p&gt;If configured, this parameter renderer adds an additional row to display the default field value.&lt;/p&gt;
         * @return a new default ParameterRenderer
         */</span>
        <span class="directive">public</span> IParameterRenderer createDefaultParameterRenderer() {
            DefaultParameterRenderer result = <span class="keyword">new</span> DefaultParameterRenderer();
            result.requiredMarker = <span class="predefined-type">String</span>.valueOf(requiredOptionMarker);
            <span class="keyword">return</span> result;
        }
        <span class="comment">/** Returns a new minimal ParameterRenderer which converts {@link Parameters Parameters} to a single row with
         * two columns of text: an option name and a description. If multiple descriptions exist, the first value is used.
         * @return a new minimal ParameterRenderer */</span>
        <span class="directive">public</span> <span class="directive">static</span> IParameterRenderer createMinimalParameterRenderer() {
            <span class="keyword">return</span> <span class="keyword">new</span> MinimalParameterRenderer();
        }

        <span class="comment">/** Returns a value renderer that returns the {@code paramLabel} if defined or the field name otherwise.
         * @return a new minimal ParamLabelRenderer */</span>
        <span class="directive">public</span> <span class="directive">static</span> IParamLabelRenderer createMinimalParamLabelRenderer() {
            <span class="keyword">return</span> <span class="keyword">new</span> IParamLabelRenderer() {
                <span class="directive">public</span> Text renderParameterLabel(<span class="predefined-type">Field</span> field, Ansi ansi, <span class="predefined-type">List</span>&lt;IStyle&gt; styles) {
                    <span class="predefined-type">String</span> text = DefaultParamLabelRenderer.renderParameterName(field);
                    <span class="keyword">return</span> ansi.apply(text, styles);
                }
                <span class="directive">public</span> <span class="predefined-type">String</span> separator() { <span class="keyword">return</span> <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>; }
            };
        }
        <span class="comment">/** Returns a new default value renderer that separates option parameters from their {@linkplain Option
         * options} with the specified separator string, surrounds optional parameters with {@code '['} and {@code ']'}
         * characters and uses ellipses (&quot;...&quot;) to indicate that any number of a parameter are allowed.
         * @return a new default ParamLabelRenderer
         */</span>
        <span class="directive">public</span> IParamLabelRenderer createDefaultParamLabelRenderer() {
            <span class="keyword">return</span> <span class="keyword">new</span> DefaultParamLabelRenderer(separator);
        }
        <span class="comment">/** Sorts Fields annotated with {@code Option} by their option name in case-insensitive alphabetic order. If an
         * Option has multiple names, the shortest name is used for the sorting. Help options follow non-help options.
         * @return a comparator that sorts fields by their option name in case-insensitive alphabetic order */</span>
        <span class="directive">public</span> <span class="directive">static</span> <span class="predefined-type">Comparator</span>&lt;<span class="predefined-type">Field</span>&gt; createShortOptionNameComparator() {
            <span class="keyword">return</span> <span class="keyword">new</span> SortByShortestOptionNameAlphabetically();
        }
        <span class="comment">/** Sorts Fields annotated with {@code Option} by their option {@linkplain Range#max max arity} first, by
         * {@linkplain Range#min min arity} next, and by {@linkplain #createShortOptionNameComparator() option name} last.
         * @return a comparator that sorts fields by arity first, then their option name */</span>
        <span class="directive">public</span> <span class="directive">static</span> <span class="predefined-type">Comparator</span>&lt;<span class="predefined-type">Field</span>&gt; createShortOptionArityAndNameComparator() {
            <span class="keyword">return</span> <span class="keyword">new</span> SortByOptionArityAndNameAlphabetically();
        }
        <span class="comment">/** Sorts short strings before longer strings.
         * @return a comparators that sorts short strings before longer strings */</span>
        <span class="directive">public</span> <span class="directive">static</span> <span class="predefined-type">Comparator</span>&lt;<span class="predefined-type">String</span>&gt; shortestFirst() {
            <span class="keyword">return</span> <span class="keyword">new</span> ShortestFirst();
        }

        <span class="comment">/** Returns whether ANSI escape codes are enabled or not.
         * @return whether ANSI escape codes are enabled or not
         */</span>
        <span class="directive">public</span> Ansi ansi() {
            <span class="keyword">return</span> colorScheme.ansi;
        }

        <span class="comment">/** When customizing online help for {@link Option Option} details, a custom {@code IOptionRenderer} can be
         * used to create textual representation of an Option in a tabular format: one or more rows, each containing
         * one or more columns. The {@link Layout Layout} is responsible for placing these text values in the
         * {@link TextTable TextTable}. */</span>
        <span class="directive">public</span> <span class="type">interface</span> <span class="class">IOptionRenderer</span> {
            <span class="comment">/**
             * Returns a text representation of the specified Option and the Field that captures the option value.
             * @param option the command line option to show online usage help for
             * @param field the field that will hold the value for the command line option
             * @param parameterLabelRenderer responsible for rendering option parameters to text
             * @param scheme color scheme for applying ansi color styles to options and option parameters
             * @return a 2-dimensional array of text values: one or more rows, each containing one or more columns
             */</span>
            Text<span class="type">[]</span><span class="type">[]</span> render(<span class="predefined-type">Option</span> option, <span class="predefined-type">Field</span> field, IParamLabelRenderer parameterLabelRenderer, ColorScheme scheme);
        }
        <span class="comment">/** The DefaultOptionRenderer converts {@link Option Options} to five columns of text to match the default
         * {@linkplain TextTable TextTable} column layout. The first row of values looks like this:
         * &lt;ol&gt;
         * &lt;li&gt;the required option marker (if the option is required)&lt;/li&gt;
         * &lt;li&gt;2-character short option name (or empty string if no short option exists)&lt;/li&gt;
         * &lt;li&gt;comma separator (only if both short option and long option exist, empty string otherwise)&lt;/li&gt;
         * &lt;li&gt;comma-separated string with long option name(s)&lt;/li&gt;
         * &lt;li&gt;first element of the {@link Option#description()} array&lt;/li&gt;
         * &lt;/ol&gt;
         * &lt;p&gt;Following this, there will be one row for each of the remaining elements of the {@link
         *   Option#description()} array, and these rows look like {@code {&quot;&quot;, &quot;&quot;, &quot;&quot;, option.description()[i]}}.&lt;/p&gt;
         */</span>
        <span class="directive">static</span> <span class="type">class</span> <span class="class">DefaultOptionRenderer</span> <span class="directive">implements</span> IOptionRenderer {
            <span class="directive">public</span> <span class="predefined-type">String</span> requiredMarker = <span class="string"><span class="delimiter">&quot;</span><span class="content"> </span><span class="delimiter">&quot;</span></span>;
            <span class="directive">public</span> <span class="predefined-type">Object</span> command;
            <span class="directive">private</span> <span class="predefined-type">String</span> sep;
            <span class="directive">private</span> <span class="type">boolean</span> showDefault;
            <span class="directive">public</span> Text<span class="type">[]</span><span class="type">[]</span> render(<span class="predefined-type">Option</span> option, <span class="predefined-type">Field</span> field, IParamLabelRenderer paramLabelRenderer, ColorScheme scheme) {
                <span class="predefined-type">String</span><span class="type">[]</span> names = ShortestFirst.sort(option.names());
                <span class="type">int</span> shortOptionCount = names[<span class="integer">0</span>].length() == <span class="integer">2</span> ? <span class="integer">1</span> : <span class="integer">0</span>;
                <span class="predefined-type">String</span> shortOption = shortOptionCount &gt; <span class="integer">0</span> ? names[<span class="integer">0</span>] : <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;
                sep = shortOptionCount &gt; <span class="integer">0</span> &amp;&amp; names.length &gt; <span class="integer">1</span> ? <span class="string"><span class="delimiter">&quot;</span><span class="content">,</span><span class="delimiter">&quot;</span></span> : <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;

                <span class="predefined-type">String</span> longOption = join(names, shortOptionCount, names.length - shortOptionCount, <span class="string"><span class="delimiter">&quot;</span><span class="content">, </span><span class="delimiter">&quot;</span></span>);
                Text longOptionText = createLongOptionText(field, paramLabelRenderer, scheme, longOption);

                showDefault = command != <span class="predefined-constant">null</span> &amp;&amp; !option.help() &amp;&amp; !isBoolean(field.getType());
                <span class="predefined-type">Object</span> defaultValue = createDefaultValue(field);

                <span class="predefined-type">String</span> requiredOption = option.required() ? requiredMarker : <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;
                <span class="keyword">return</span> renderDescriptionLines(option, scheme, requiredOption, shortOption, longOptionText, defaultValue);
            }

            <span class="directive">private</span> <span class="predefined-type">Object</span> createDefaultValue(<span class="predefined-type">Field</span> field) {
                <span class="predefined-type">Object</span> defaultValue = <span class="predefined-constant">null</span>;
                <span class="keyword">try</span> {
                    defaultValue = field.get(command);
                    <span class="keyword">if</span> (defaultValue == <span class="predefined-constant">null</span>) { showDefault = <span class="predefined-constant">false</span>; } <span class="comment">// #201 don't show null default values</span>
                    <span class="keyword">else</span> <span class="keyword">if</span> (field.getType().isArray()) {
                        <span class="predefined-type">StringBuilder</span> sb = <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>();
                        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">0</span>; i &lt; <span class="predefined-type">Array</span>.getLength(defaultValue); i++) {
                            sb.append(i &gt; <span class="integer">0</span> ? <span class="string"><span class="delimiter">&quot;</span><span class="content">, </span><span class="delimiter">&quot;</span></span> : <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>).append(<span class="predefined-type">Array</span>.get(defaultValue, i));
                        }
                        defaultValue = sb.insert(<span class="integer">0</span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">[</span><span class="delimiter">&quot;</span></span>).append(<span class="string"><span class="delimiter">&quot;</span><span class="content">]</span><span class="delimiter">&quot;</span></span>).toString();
                    }
                } <span class="keyword">catch</span> (<span class="exception">Exception</span> ex) {
                    showDefault = <span class="predefined-constant">false</span>;
                }
                <span class="keyword">return</span> defaultValue;
            }

            <span class="directive">private</span> Text createLongOptionText(<span class="predefined-type">Field</span> field, IParamLabelRenderer renderer, ColorScheme scheme, <span class="predefined-type">String</span> longOption) {
                Text paramLabelText = renderer.renderParameterLabel(field, scheme.ansi(), scheme.optionParamStyles);

                <span class="comment">// if no long option, fill in the space between the short option name and the param label value</span>
                <span class="keyword">if</span> (paramLabelText.length &gt; <span class="integer">0</span> &amp;&amp; longOption.length() == <span class="integer">0</span>) {
                    sep = renderer.separator();
                    <span class="comment">// #181 paramLabelText may be =LABEL or [=LABEL...]</span>
                    <span class="type">int</span> sepStart = paramLabelText.plainString().indexOf(sep);
                    Text prefix = paramLabelText.substring(<span class="integer">0</span>, sepStart);
                    paramLabelText = prefix.append(paramLabelText.substring(sepStart + sep.length()));
                }
                Text longOptionText = scheme.optionText(longOption);
                longOptionText = longOptionText.append(paramLabelText);
                <span class="keyword">return</span> longOptionText;
            }

            <span class="directive">private</span> Text<span class="type">[]</span><span class="type">[]</span> renderDescriptionLines(<span class="predefined-type">Option</span> option,
                                                    ColorScheme scheme,
                                                    <span class="predefined-type">String</span> requiredOption,
                                                    <span class="predefined-type">String</span> shortOption,
                                                    Text longOptionText,
                                                    <span class="predefined-type">Object</span> defaultValue) {
                Text EMPTY = Ansi.EMPTY_TEXT;
                <span class="predefined-type">List</span>&lt;Text<span class="type">[]</span>&gt; result = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;Text<span class="type">[]</span>&gt;();
                Text<span class="type">[]</span> descriptionFirstLines = scheme.ansi().new Text(str(option.description(), <span class="integer">0</span>)).splitLines();
                <span class="keyword">if</span> (descriptionFirstLines.length == <span class="integer">0</span> || (descriptionFirstLines.length == <span class="integer">1</span> &amp;&amp; descriptionFirstLines[<span class="integer">0</span>].plain.length() == <span class="integer">0</span>)) {
                    <span class="keyword">if</span> (showDefault) {
                        descriptionFirstLines = <span class="keyword">new</span> Text<span class="type">[]</span>{scheme.ansi().new Text(<span class="string"><span class="delimiter">&quot;</span><span class="content">  Default: </span><span class="delimiter">&quot;</span></span> + defaultValue)};
                        showDefault = <span class="predefined-constant">false</span>; <span class="comment">// don't show the default value twice</span>
                    } <span class="keyword">else</span> {
                        descriptionFirstLines = <span class="keyword">new</span> Text<span class="type">[]</span>{ EMPTY };
                    }
                }
                result.add(<span class="keyword">new</span> Text<span class="type">[]</span> { scheme.optionText(requiredOption), scheme.optionText(shortOption),
                        scheme.ansi().new Text(sep), longOptionText, descriptionFirstLines[<span class="integer">0</span>] });
                <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">1</span>; i &lt; descriptionFirstLines.length; i++) {
                    result.add(<span class="keyword">new</span> Text<span class="type">[]</span> { EMPTY, EMPTY, EMPTY, EMPTY, descriptionFirstLines[i] });
                }
                <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">1</span>; i &lt; option.description().length; i++) {
                    Text<span class="type">[]</span> descriptionNextLines = scheme.ansi().new Text(option.description()[i]).splitLines();
                    <span class="keyword">for</span> (Text line : descriptionNextLines) {
                        result.add(<span class="keyword">new</span> Text<span class="type">[]</span> { EMPTY, EMPTY, EMPTY, EMPTY, line });
                    }
                }
                <span class="keyword">if</span> (showDefault) {
                    result.add(<span class="keyword">new</span> Text<span class="type">[]</span> { EMPTY, EMPTY, EMPTY, EMPTY, scheme.ansi().new Text(<span class="string"><span class="delimiter">&quot;</span><span class="content">  Default: </span><span class="delimiter">&quot;</span></span> + defaultValue) });
                }
                <span class="keyword">return</span> result.toArray(<span class="keyword">new</span> Text[result.size()]<span class="type">[]</span>);
            }
        }
        <span class="comment">/** The MinimalOptionRenderer converts {@link Option Options} to a single row with two columns of text: an
         * option name and a description. If multiple names or description lines exist, the first value is used. */</span>
        <span class="directive">static</span> <span class="type">class</span> <span class="class">MinimalOptionRenderer</span> <span class="directive">implements</span> IOptionRenderer {
            <span class="directive">public</span> Text<span class="type">[]</span><span class="type">[]</span> render(<span class="predefined-type">Option</span> option, <span class="predefined-type">Field</span> field, IParamLabelRenderer parameterLabelRenderer, ColorScheme scheme) {
                Text optionText = scheme.optionText(option.names()[<span class="integer">0</span>]);
                Text paramLabelText = parameterLabelRenderer.renderParameterLabel(field, scheme.ansi(), scheme.optionParamStyles);
                optionText = optionText.append(paramLabelText);
                <span class="keyword">return</span> <span class="keyword">new</span> Text<span class="type">[]</span><span class="type">[]</span> {{ optionText,
                                        scheme.ansi().new Text(option.description().length == <span class="integer">0</span> ? <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span> : option.description()[<span class="integer">0</span>]) }};
            }
        }
        <span class="comment">/** The MinimalParameterRenderer converts {@link Parameters Parameters} to a single row with two columns of
         * text: the parameters label and a description. If multiple description lines exist, the first value is used. */</span>
        <span class="directive">static</span> <span class="type">class</span> <span class="class">MinimalParameterRenderer</span> <span class="directive">implements</span> IParameterRenderer {
            <span class="directive">public</span> Text<span class="type">[]</span><span class="type">[]</span> render(Parameters param, <span class="predefined-type">Field</span> field, IParamLabelRenderer parameterLabelRenderer, ColorScheme scheme) {
                <span class="keyword">return</span> <span class="keyword">new</span> Text<span class="type">[]</span><span class="type">[]</span> {{ parameterLabelRenderer.renderParameterLabel(field, scheme.ansi(), scheme.parameterStyles),
                        scheme.ansi().new Text(param.description().length == <span class="integer">0</span> ? <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span> : param.description()[<span class="integer">0</span>]) }};
            }
        }
        <span class="comment">/** When customizing online help for {@link Parameters Parameters} details, a custom {@code IParameterRenderer}
         * can be used to create textual representation of a Parameters field in a tabular format: one or more rows,
         * each containing one or more columns. The {@link Layout Layout} is responsible for placing these text
         * values in the {@link TextTable TextTable}. */</span>
        <span class="directive">public</span> <span class="type">interface</span> <span class="class">IParameterRenderer</span> {
            <span class="comment">/**
             * Returns a text representation of the specified Parameters and the Field that captures the parameter values.
             * @param parameters the command line parameters to show online usage help for
             * @param field the field that will hold the value for the command line parameters
             * @param parameterLabelRenderer responsible for rendering parameter labels to text
             * @param scheme color scheme for applying ansi color styles to positional parameters
             * @return a 2-dimensional array of text values: one or more rows, each containing one or more columns
             */</span>
            Text<span class="type">[]</span><span class="type">[]</span> render(Parameters parameters, <span class="predefined-type">Field</span> field, IParamLabelRenderer parameterLabelRenderer, ColorScheme scheme);
        }
        <span class="comment">/** The DefaultParameterRenderer converts {@link Parameters Parameters} to five columns of text to match the
         * default {@linkplain TextTable TextTable} column layout. The first row of values looks like this:
         * &lt;ol&gt;
         * &lt;li&gt;the required option marker (if the parameter's arity is to have at least one value)&lt;/li&gt;
         * &lt;li&gt;empty string &lt;/li&gt;
         * &lt;li&gt;empty string &lt;/li&gt;
         * &lt;li&gt;parameter(s) label as rendered by the {@link IParamLabelRenderer}&lt;/li&gt;
         * &lt;li&gt;first element of the {@link Parameters#description()} array&lt;/li&gt;
         * &lt;/ol&gt;
         * &lt;p&gt;Following this, there will be one row for each of the remaining elements of the {@link
         *   Parameters#description()} array, and these rows look like {@code {&quot;&quot;, &quot;&quot;, &quot;&quot;, param.description()[i]}}.&lt;/p&gt;
         */</span>
        <span class="directive">static</span> <span class="type">class</span> <span class="class">DefaultParameterRenderer</span> <span class="directive">implements</span> IParameterRenderer {
            <span class="directive">public</span> <span class="predefined-type">String</span> requiredMarker = <span class="string"><span class="delimiter">&quot;</span><span class="content"> </span><span class="delimiter">&quot;</span></span>;
            <span class="directive">public</span> Text<span class="type">[]</span><span class="type">[]</span> render(Parameters params, <span class="predefined-type">Field</span> field, IParamLabelRenderer paramLabelRenderer, ColorScheme scheme) {
                Text label = paramLabelRenderer.renderParameterLabel(field, scheme.ansi(), scheme.parameterStyles);
                Text requiredParameter = scheme.parameterText(Range.parameterArity(field).min &gt; <span class="integer">0</span> ? requiredMarker : <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>);

                Text EMPTY = Ansi.EMPTY_TEXT;
                <span class="predefined-type">List</span>&lt;Text<span class="type">[]</span>&gt; result = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;Text<span class="type">[]</span>&gt;();
                Text<span class="type">[]</span> descriptionFirstLines = scheme.ansi().new Text(str(params.description(), <span class="integer">0</span>)).splitLines();
                <span class="keyword">if</span> (descriptionFirstLines.length == <span class="integer">0</span>) { descriptionFirstLines = <span class="keyword">new</span> Text<span class="type">[]</span>{ EMPTY }; }
                result.add(<span class="keyword">new</span> Text<span class="type">[]</span> { requiredParameter, EMPTY, EMPTY, label, descriptionFirstLines[<span class="integer">0</span>] });
                <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">1</span>; i &lt; descriptionFirstLines.length; i++) {
                    result.add(<span class="keyword">new</span> Text<span class="type">[]</span> { EMPTY, EMPTY, EMPTY, EMPTY, descriptionFirstLines[i] });
                }
                <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">1</span>; i &lt; params.description().length; i++) {
                    Text<span class="type">[]</span> descriptionNextLines = scheme.ansi().new Text(params.description()[i]).splitLines();
                    <span class="keyword">for</span> (Text line : descriptionNextLines) {
                        result.add(<span class="keyword">new</span> Text<span class="type">[]</span> { EMPTY, EMPTY, EMPTY, EMPTY, line });
                    }
                }
                <span class="keyword">return</span> result.toArray(<span class="keyword">new</span> Text[result.size()]<span class="type">[]</span>);
            }
        }
        <span class="comment">/** When customizing online usage help for an option parameter or a positional parameter, a custom
         * {@code IParamLabelRenderer} can be used to render the parameter name or label to a String. */</span>
        <span class="directive">public</span> <span class="type">interface</span> <span class="class">IParamLabelRenderer</span> {

            <span class="comment">/** Returns a text rendering of the Option parameter or positional parameter; returns an empty string
             * {@code &quot;&quot;} if the option is a boolean and does not take a parameter.
             * @param field the annotated field with a parameter label
             * @param ansi determines whether ANSI escape codes should be emitted or not
             * @param styles the styles to apply to the parameter label
             * @return a text rendering of the Option parameter or positional parameter */</span>
            Text renderParameterLabel(<span class="predefined-type">Field</span> field, Ansi ansi, <span class="predefined-type">List</span>&lt;IStyle&gt; styles);

            <span class="comment">/** Returns the separator between option name and param label.
             * @return the separator between option name and param label */</span>
            <span class="predefined-type">String</span> separator();
        }
        <span class="comment">/**
         * DefaultParamLabelRenderer separates option parameters from their {@linkplain Option options} with a
         * {@linkplain DefaultParamLabelRenderer#separator separator} string, surrounds optional values
         * with {@code '['} and {@code ']'} characters and uses ellipses (&quot;...&quot;) to indicate that any number of
         * values is allowed for options or parameters with variable arity.
         */</span>
        <span class="directive">static</span> <span class="type">class</span> <span class="class">DefaultParamLabelRenderer</span> <span class="directive">implements</span> IParamLabelRenderer {
            <span class="comment">/** The string to use to separate option parameters from their options. */</span>
            <span class="directive">public</span> <span class="directive">final</span> <span class="predefined-type">String</span> separator;
            <span class="comment">/** Constructs a new DefaultParamLabelRenderer with the specified separator string. */</span>
            <span class="directive">public</span> DefaultParamLabelRenderer(<span class="predefined-type">String</span> separator) {
                <span class="local-variable">this</span>.separator = Assert.notNull(separator, <span class="string"><span class="delimiter">&quot;</span><span class="content">separator</span><span class="delimiter">&quot;</span></span>);
            }
            <span class="directive">public</span> <span class="predefined-type">String</span> separator() { <span class="keyword">return</span> separator; }
            <span class="directive">public</span> Text renderParameterLabel(<span class="predefined-type">Field</span> field, Ansi ansi, <span class="predefined-type">List</span>&lt;IStyle&gt; styles) {
                <span class="type">boolean</span> isOptionParameter = field.isAnnotationPresent(<span class="predefined-type">Option</span>.class);
                Range arity = isOptionParameter ? Range.optionArity(field) : Range.parameterCapacity(field);
                <span class="predefined-type">String</span> split = isOptionParameter ? field.getAnnotation(<span class="predefined-type">Option</span>.class).split() : field.getAnnotation(Parameters.class).split();
                Text result = ansi.new Text(<span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>);
                <span class="predefined-type">String</span> sep = isOptionParameter ? separator : <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>;
                Text paramName = ansi.apply(renderParameterName(field), styles);
                <span class="keyword">if</span> (!empty(split)) { paramName = paramName.append(<span class="string"><span class="delimiter">&quot;</span><span class="content">[</span><span class="delimiter">&quot;</span></span> + split).append(paramName).append(<span class="string"><span class="delimiter">&quot;</span><span class="content">]...</span><span class="delimiter">&quot;</span></span>); } <span class="comment">// #194</span>
                <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">0</span>; i &lt; arity.min; i++) {
                    result = result.append(sep).append(paramName);
                    sep = <span class="string"><span class="delimiter">&quot;</span><span class="content"> </span><span class="delimiter">&quot;</span></span>;
                }
                <span class="keyword">if</span> (arity.isVariable) {
                    <span class="keyword">if</span> (result.length == <span class="integer">0</span>) { <span class="comment">// arity=&quot;*&quot; or arity=&quot;0..*&quot;</span>
                        result = result.append(sep + <span class="string"><span class="delimiter">&quot;</span><span class="content">[</span><span class="delimiter">&quot;</span></span>).append(paramName).append(<span class="string"><span class="delimiter">&quot;</span><span class="content">]...</span><span class="delimiter">&quot;</span></span>);
                    } <span class="keyword">else</span> <span class="keyword">if</span> (!result.plainString().endsWith(<span class="string"><span class="delimiter">&quot;</span><span class="content">...</span><span class="delimiter">&quot;</span></span>)) { <span class="comment">// split param may already end with &quot;...&quot;</span>
                        result = result.append(<span class="string"><span class="delimiter">&quot;</span><span class="content">...</span><span class="delimiter">&quot;</span></span>);
                    }
                } <span class="keyword">else</span> {
                    sep = result.length == <span class="integer">0</span> ? (isOptionParameter ? separator : <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>) : <span class="string"><span class="delimiter">&quot;</span><span class="content"> </span><span class="delimiter">&quot;</span></span>;
                    <span class="keyword">for</span> (<span class="type">int</span> i = arity.min; i &lt; arity.max; i++) {
                        <span class="keyword">if</span> (sep.trim().length() == <span class="integer">0</span>) {
                            result = result.append(sep + <span class="string"><span class="delimiter">&quot;</span><span class="content">[</span><span class="delimiter">&quot;</span></span>).append(paramName);
                        } <span class="keyword">else</span> {
                            result = result.append(<span class="string"><span class="delimiter">&quot;</span><span class="content">[</span><span class="delimiter">&quot;</span></span> + sep).append(paramName);
                        }
                        sep  = <span class="string"><span class="delimiter">&quot;</span><span class="content"> </span><span class="delimiter">&quot;</span></span>;
                    }
                    <span class="keyword">for</span> (<span class="type">int</span> i = arity.min; i &lt; arity.max; i++) { result = result.append(<span class="string"><span class="delimiter">&quot;</span><span class="content">]</span><span class="delimiter">&quot;</span></span>); }
                }
                <span class="keyword">return</span> result;
            }
            <span class="directive">private</span> <span class="directive">static</span> <span class="predefined-type">String</span> renderParameterName(<span class="predefined-type">Field</span> field) {
                <span class="predefined-type">String</span> result = <span class="predefined-constant">null</span>;
                <span class="keyword">if</span> (field.isAnnotationPresent(<span class="predefined-type">Option</span>.class)) {
                    result = field.getAnnotation(<span class="predefined-type">Option</span>.class).paramLabel();
                } <span class="keyword">else</span> <span class="keyword">if</span> (field.isAnnotationPresent(Parameters.class)) {
                    result = field.getAnnotation(Parameters.class).paramLabel();
                }
                <span class="keyword">if</span> (result != <span class="predefined-constant">null</span> &amp;&amp; result.trim().length() &gt; <span class="integer">0</span>) {
                    <span class="keyword">return</span> result.trim();
                }
                <span class="predefined-type">String</span> name = field.getName();
                <span class="keyword">if</span> (<span class="predefined-type">Map</span>.class.isAssignableFrom(field.getType())) { <span class="comment">// #195 better param labels for map fields</span>
                    <span class="predefined-type">Class</span>&lt;?&gt;<span class="type">[]</span> paramTypes = getTypeAttribute(field);
                    <span class="keyword">if</span> (paramTypes.length &lt; <span class="integer">2</span> || paramTypes[<span class="integer">0</span>] == <span class="predefined-constant">null</span> || paramTypes[<span class="integer">1</span>] == <span class="predefined-constant">null</span>) {
                        name = <span class="string"><span class="delimiter">&quot;</span><span class="content">String=String</span><span class="delimiter">&quot;</span></span>;
                    } <span class="keyword">else</span> { name = paramTypes[<span class="integer">0</span>].getSimpleName() + <span class="string"><span class="delimiter">&quot;</span><span class="content">=</span><span class="delimiter">&quot;</span></span> + paramTypes[<span class="integer">1</span>].getSimpleName(); }
                }
                <span class="keyword">return</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">&lt;</span><span class="delimiter">&quot;</span></span> + name + <span class="string"><span class="delimiter">&quot;</span><span class="content">&gt;</span><span class="delimiter">&quot;</span></span>;
            }
        }
        <span class="comment">/** Use a Layout to format usage help text for options and parameters in tabular format.
         * &lt;p&gt;Delegates to the renderers to create {@link Text} values for the annotated fields, and uses a
         * {@link TextTable} to display these values in tabular format. Layout is responsible for deciding which values
         * to display where in the table. By default, Layout shows one option or parameter per table row.&lt;/p&gt;
         * &lt;p&gt;Customize by overriding the {@link #layout(Field, CommandLine.Help.Ansi.Text[][])} method.&lt;/p&gt;
         * @see IOptionRenderer rendering options to text
         * @see IParameterRenderer rendering parameters to text
         * @see TextTable showing values in a tabular format
         */</span>
        <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">Layout</span> {
            <span class="directive">protected</span> <span class="directive">final</span> ColorScheme colorScheme;
            <span class="directive">protected</span> <span class="directive">final</span> TextTable table;
            <span class="directive">protected</span> IOptionRenderer optionRenderer;
            <span class="directive">protected</span> IParameterRenderer parameterRenderer;

            <span class="comment">/** Constructs a Layout with the specified color scheme, a new default TextTable, the
             * {@linkplain Help#createDefaultOptionRenderer() default option renderer}, and the
             * {@linkplain Help#createDefaultParameterRenderer() default parameter renderer}.
             * @param colorScheme the color scheme to use for common, auto-generated parts of the usage help message */</span>
            <span class="directive">public</span> Layout(ColorScheme colorScheme) { <span class="local-variable">this</span>(colorScheme, <span class="keyword">new</span> TextTable(colorScheme.ansi())); }

            <span class="comment">/** Constructs a Layout with the specified color scheme, the specified TextTable, the
             * {@linkplain Help#createDefaultOptionRenderer() default option renderer}, and the
             * {@linkplain Help#createDefaultParameterRenderer() default parameter renderer}.
             * @param colorScheme the color scheme to use for common, auto-generated parts of the usage help message
             * @param textTable the TextTable to lay out parts of the usage help message in tabular format */</span>
            <span class="directive">public</span> Layout(ColorScheme colorScheme, TextTable textTable) {
                <span class="local-variable">this</span>(colorScheme, textTable, <span class="keyword">new</span> DefaultOptionRenderer(), <span class="keyword">new</span> DefaultParameterRenderer());
            }
            <span class="comment">/** Constructs a Layout with the specified color scheme, the specified TextTable, the
             * specified option renderer and the specified parameter renderer.
             * @param colorScheme the color scheme to use for common, auto-generated parts of the usage help message
             * @param optionRenderer the object responsible for rendering Options to Text
             * @param parameterRenderer the object responsible for rendering Parameters to Text
             * @param textTable the TextTable to lay out parts of the usage help message in tabular format */</span>
            <span class="directive">public</span> Layout(ColorScheme colorScheme, TextTable textTable, IOptionRenderer optionRenderer, IParameterRenderer parameterRenderer) {
                <span class="local-variable">this</span>.colorScheme       = Assert.notNull(colorScheme, <span class="string"><span class="delimiter">&quot;</span><span class="content">colorScheme</span><span class="delimiter">&quot;</span></span>);
                <span class="local-variable">this</span>.table             = Assert.notNull(textTable, <span class="string"><span class="delimiter">&quot;</span><span class="content">textTable</span><span class="delimiter">&quot;</span></span>);
                <span class="local-variable">this</span>.optionRenderer    = Assert.notNull(optionRenderer, <span class="string"><span class="delimiter">&quot;</span><span class="content">optionRenderer</span><span class="delimiter">&quot;</span></span>);
                <span class="local-variable">this</span>.parameterRenderer = Assert.notNull(parameterRenderer, <span class="string"><span class="delimiter">&quot;</span><span class="content">parameterRenderer</span><span class="delimiter">&quot;</span></span>);
            }
            <span class="comment">/**
             * Copies the specified text values into the correct cells in the {@link TextTable}. This implementation
             * delegates to {@link TextTable#addRowValues(CommandLine.Help.Ansi.Text...)} for each row of values.
             * &lt;p&gt;Subclasses may override.&lt;/p&gt;
             * @param field the field annotated with the specified Option or Parameters
             * @param cellValues the text values representing the Option/Parameters, to be displayed in tabular form
             */</span>
            <span class="directive">public</span> <span class="type">void</span> layout(<span class="predefined-type">Field</span> field, Text<span class="type">[]</span><span class="type">[]</span> cellValues) {
                <span class="keyword">for</span> (Text<span class="type">[]</span> oneRow : cellValues) {
                    table.addRowValues(oneRow);
                }
            }
            <span class="comment">/** Calls {@link #addOption(Field, CommandLine.Help.IParamLabelRenderer)} for all non-hidden Options in the list.
             * @param fields fields annotated with {@link Option} to add usage descriptions for
             * @param paramLabelRenderer object that knows how to render option parameters */</span>
            <span class="directive">public</span> <span class="type">void</span> addOptions(<span class="predefined-type">List</span>&lt;<span class="predefined-type">Field</span>&gt; fields, IParamLabelRenderer paramLabelRenderer) {
                <span class="keyword">for</span> (<span class="predefined-type">Field</span> field : fields) {
                    <span class="predefined-type">Option</span> option = field.getAnnotation(<span class="predefined-type">Option</span>.class);
                    <span class="keyword">if</span> (!option.hidden()) {
                        addOption(field, paramLabelRenderer);
                    }
                }
            }
            <span class="comment">/**
             * Delegates to the {@link #optionRenderer option renderer} of this layout to obtain
             * text values for the specified {@link Option}, and then calls the {@link #layout(Field, CommandLine.Help.Ansi.Text[][])}
             * method to write these text values into the correct cells in the TextTable.
             * @param field the field annotated with the specified Option
             * @param paramLabelRenderer knows how to render option parameters
             */</span>
            <span class="directive">public</span> <span class="type">void</span> addOption(<span class="predefined-type">Field</span> field, IParamLabelRenderer paramLabelRenderer) {
                <span class="predefined-type">Option</span> option = field.getAnnotation(<span class="predefined-type">Option</span>.class);
                Text<span class="type">[]</span><span class="type">[]</span> values = optionRenderer.render(option, field, paramLabelRenderer, colorScheme);
                layout(field, values);
            }
            <span class="comment">/** Calls {@link #addPositionalParameter(Field, CommandLine.Help.IParamLabelRenderer)} for all non-hidden Parameters in the list.
             * @param fields fields annotated with {@link Parameters} to add usage descriptions for
             * @param paramLabelRenderer knows how to render option parameters */</span>
            <span class="directive">public</span> <span class="type">void</span> addPositionalParameters(<span class="predefined-type">List</span>&lt;<span class="predefined-type">Field</span>&gt; fields, IParamLabelRenderer paramLabelRenderer) {
                <span class="keyword">for</span> (<span class="predefined-type">Field</span> field : fields) {
                    Parameters parameters = field.getAnnotation(Parameters.class);
                    <span class="keyword">if</span> (!parameters.hidden()) {
                        addPositionalParameter(field, paramLabelRenderer);
                    }
                }
            }
            <span class="comment">/**
             * Delegates to the {@link #parameterRenderer parameter renderer} of this layout
             * to obtain text values for the specified {@link Parameters}, and then calls
             * {@link #layout(Field, CommandLine.Help.Ansi.Text[][])} to write these text values into the correct cells in the TextTable.
             * @param field the field annotated with the specified Parameters
             * @param paramLabelRenderer knows how to render option parameters
             */</span>
            <span class="directive">public</span> <span class="type">void</span> addPositionalParameter(<span class="predefined-type">Field</span> field, IParamLabelRenderer paramLabelRenderer) {
                Parameters option = field.getAnnotation(Parameters.class);
                Text<span class="type">[]</span><span class="type">[]</span> values = parameterRenderer.render(option, field, paramLabelRenderer, colorScheme);
                layout(field, values);
            }
            <span class="comment">/** Returns the section of the usage help message accumulated in the TextTable owned by this layout. */</span>
            <span class="annotation">@Override</span> <span class="directive">public</span> <span class="predefined-type">String</span> toString() {
                <span class="keyword">return</span> table.toString();
            }
        }
        <span class="comment">/** Sorts short strings before longer strings. */</span>
        <span class="directive">static</span> <span class="type">class</span> <span class="class">ShortestFirst</span> <span class="directive">implements</span> <span class="predefined-type">Comparator</span>&lt;<span class="predefined-type">String</span>&gt; {
            <span class="directive">public</span> <span class="type">int</span> compare(<span class="predefined-type">String</span> o1, <span class="predefined-type">String</span> o2) {
                <span class="keyword">return</span> o1.length() - o2.length();
            }
            <span class="comment">/** Sorts the specified array of Strings shortest-first and returns it. */</span>
            <span class="directive">public</span> <span class="directive">static</span> <span class="predefined-type">String</span><span class="type">[]</span> sort(<span class="predefined-type">String</span><span class="type">[]</span> names) {
                <span class="predefined-type">Arrays</span>.sort(names, <span class="keyword">new</span> ShortestFirst());
                <span class="keyword">return</span> names;
            }
        }
        <span class="comment">/** Sorts {@code Option} instances by their name in case-insensitive alphabetic order. If an Option has
         * multiple names, the shortest name is used for the sorting. Help options follow non-help options. */</span>
        <span class="directive">static</span> <span class="type">class</span> <span class="class">SortByShortestOptionNameAlphabetically</span> <span class="directive">implements</span> <span class="predefined-type">Comparator</span>&lt;<span class="predefined-type">Field</span>&gt; {
            <span class="directive">public</span> <span class="type">int</span> compare(<span class="predefined-type">Field</span> f1, <span class="predefined-type">Field</span> f2) {
                <span class="predefined-type">Option</span> o1 = f1.getAnnotation(<span class="predefined-type">Option</span>.class);
                <span class="predefined-type">Option</span> o2 = f2.getAnnotation(<span class="predefined-type">Option</span>.class);
                <span class="keyword">if</span> (o1 == <span class="predefined-constant">null</span>) { <span class="keyword">return</span> <span class="integer">1</span>; } <span class="keyword">else</span> <span class="keyword">if</span> (o2 == <span class="predefined-constant">null</span>) { <span class="keyword">return</span> -<span class="integer">1</span>; } <span class="comment">// options before params</span>
                <span class="predefined-type">String</span><span class="type">[]</span> names1 = ShortestFirst.sort(o1.names());
                <span class="predefined-type">String</span><span class="type">[]</span> names2 = ShortestFirst.sort(o2.names());
                <span class="type">int</span> result = names1[<span class="integer">0</span>].toUpperCase().compareTo(names2[<span class="integer">0</span>].toUpperCase()); <span class="comment">// case insensitive sort</span>
                result = result == <span class="integer">0</span> ? -names1[<span class="integer">0</span>].compareTo(names2[<span class="integer">0</span>]) : result; <span class="comment">// lower case before upper case</span>
                <span class="keyword">return</span> o1.help() == o2.help() ? result : o2.help() ? -<span class="integer">1</span> : <span class="integer">1</span>; <span class="comment">// help options come last</span>
            }
        }
        <span class="comment">/** Sorts {@code Option} instances by their max arity first, then their min arity, then delegates to super class. */</span>
        <span class="directive">static</span> <span class="type">class</span> <span class="class">SortByOptionArityAndNameAlphabetically</span> <span class="directive">extends</span> SortByShortestOptionNameAlphabetically {
            <span class="directive">public</span> <span class="type">int</span> compare(<span class="predefined-type">Field</span> f1, <span class="predefined-type">Field</span> f2) {
                <span class="predefined-type">Option</span> o1 = f1.getAnnotation(<span class="predefined-type">Option</span>.class);
                <span class="predefined-type">Option</span> o2 = f2.getAnnotation(<span class="predefined-type">Option</span>.class);
                Range arity1 = Range.optionArity(f1);
                Range arity2 = Range.optionArity(f2);
                <span class="type">int</span> result = arity1.max - arity2.max;
                <span class="keyword">if</span> (result == <span class="integer">0</span>) {
                    result = arity1.min - arity2.min;
                }
                <span class="keyword">if</span> (result == <span class="integer">0</span>) { <span class="comment">// arity is same</span>
                    <span class="keyword">if</span> (isMultiValue(f1) &amp;&amp; !isMultiValue(f2)) { result = <span class="integer">1</span>; } <span class="comment">// f1 &gt; f2</span>
                    <span class="keyword">if</span> (!isMultiValue(f1) &amp;&amp; isMultiValue(f2)) { result = -<span class="integer">1</span>; } <span class="comment">// f1 &lt; f2</span>
                }
                <span class="keyword">return</span> result == <span class="integer">0</span> ? <span class="local-variable">super</span>.compare(f1, f2) : result;
            }
        }
        <span class="comment">/**
         * &lt;p&gt;Responsible for spacing out {@link Text} values according to the {@link Column} definitions the table was
         * created with. Columns have a width, indentation, and an overflow policy that decides what to do if a value is
         * longer than the column's width.&lt;/p&gt;
         */</span>
        <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">TextTable</span> {
            <span class="comment">/**
             * Helper class to index positions in a {@code Help.TextTable}.
             * @since 2.0
             */</span>
            <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">Cell</span> {
                <span class="comment">/** Table column index (zero based). */</span>
                <span class="directive">public</span> <span class="directive">final</span> <span class="type">int</span> column;
                <span class="comment">/** Table row index (zero based). */</span>
                <span class="directive">public</span> <span class="directive">final</span> <span class="type">int</span> row;
                <span class="comment">/** Constructs a new Cell with the specified coordinates in the table.
                 * @param column the zero-based table column
                 * @param row the zero-based table row */</span>
                <span class="directive">public</span> Cell(<span class="type">int</span> column, <span class="type">int</span> row) { <span class="local-variable">this</span>.column = column; <span class="local-variable">this</span>.row = row; }
            }

            <span class="comment">/** The column definitions of this table. */</span>
            <span class="directive">public</span> <span class="directive">final</span> Column<span class="type">[]</span> columns;

            <span class="comment">/** The {@code char[]} slots of the {@code TextTable} to copy text values into. */</span>
            <span class="directive">protected</span> <span class="directive">final</span> <span class="predefined-type">List</span>&lt;Text&gt; columnValues = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;Text&gt;();

            <span class="comment">/** By default, indent wrapped lines by 2 spaces. */</span>
            <span class="directive">public</span> <span class="type">int</span> indentWrappedLines = <span class="integer">2</span>;

            <span class="directive">private</span> <span class="directive">final</span> Ansi ansi;

            <span class="comment">/** Constructs a TextTable with five columns as follows:
             * &lt;ol&gt;
             * &lt;li&gt;required option/parameter marker (width: 2, indent: 0, TRUNCATE on overflow)&lt;/li&gt;
             * &lt;li&gt;short option name (width: 2, indent: 0, TRUNCATE on overflow)&lt;/li&gt;
             * &lt;li&gt;comma separator (width: 1, indent: 0, TRUNCATE on overflow)&lt;/li&gt;
             * &lt;li&gt;long option name(s) (width: 24, indent: 1, SPAN multiple columns on overflow)&lt;/li&gt;
             * &lt;li&gt;description line(s) (width: 51, indent: 1, WRAP to next row on overflow)&lt;/li&gt;
             * &lt;/ol&gt;
             * @param ansi whether to emit ANSI escape codes or not
             */</span>
            <span class="directive">public</span> TextTable(Ansi ansi) {
                <span class="comment">// &quot;* -c, --create                Creates a ....&quot;</span>
                <span class="local-variable">this</span>(ansi, <span class="keyword">new</span> Column<span class="type">[]</span> {
                            <span class="keyword">new</span> Column(<span class="integer">2</span>,                                        <span class="integer">0</span>, TRUNCATE), <span class="comment">// &quot;*&quot;</span>
                            <span class="keyword">new</span> Column(<span class="integer">2</span>,                                        <span class="integer">0</span>, TRUNCATE), <span class="comment">// &quot;-c&quot;</span>
                            <span class="keyword">new</span> Column(<span class="integer">1</span>,                                        <span class="integer">0</span>, TRUNCATE), <span class="comment">// &quot;,&quot;</span>
                            <span class="keyword">new</span> Column(optionsColumnWidth - <span class="integer">2</span> - <span class="integer">2</span> - <span class="integer">1</span>       , <span class="integer">1</span>, SPAN),  <span class="comment">// &quot; --create&quot;</span>
                            <span class="keyword">new</span> Column(usageHelpWidth - optionsColumnWidth, <span class="integer">1</span>, WRAP) <span class="comment">// &quot; Creates a ...&quot;</span>
                    });
            }

            <span class="comment">/** Constructs a new TextTable with columns with the specified width, all SPANning  multiple columns on
             * overflow except the last column which WRAPS to the next row.
             * @param ansi whether to emit ANSI escape codes or not
             * @param columnWidths the width of the table columns (all columns have zero indent)
             */</span>
            <span class="directive">public</span> TextTable(Ansi ansi, <span class="type">int</span>... columnWidths) {
                <span class="local-variable">this</span>.ansi = Assert.notNull(ansi, <span class="string"><span class="delimiter">&quot;</span><span class="content">ansi</span><span class="delimiter">&quot;</span></span>);
                columns = <span class="keyword">new</span> Column[columnWidths.length];
                <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">0</span>; i &lt; columnWidths.length; i++) {
                    columns[i] = <span class="keyword">new</span> Column(columnWidths[i], <span class="integer">0</span>, i == columnWidths.length - <span class="integer">1</span> ? SPAN: WRAP);
                }
            }
            <span class="comment">/** Constructs a {@code TextTable} with the specified columns.
             * @param ansi whether to emit ANSI escape codes or not
             * @param columns columns to construct this TextTable with */</span>
            <span class="directive">public</span> TextTable(Ansi ansi, Column... columns) {
                <span class="local-variable">this</span>.ansi = Assert.notNull(ansi, <span class="string"><span class="delimiter">&quot;</span><span class="content">ansi</span><span class="delimiter">&quot;</span></span>);
                <span class="local-variable">this</span>.columns = Assert.notNull(columns, <span class="string"><span class="delimiter">&quot;</span><span class="content">columns</span><span class="delimiter">&quot;</span></span>);
                <span class="keyword">if</span> (columns.length == <span class="integer">0</span>) { <span class="keyword">throw</span> <span class="keyword">new</span> <span class="exception">IllegalArgumentException</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">At least one column is required</span><span class="delimiter">&quot;</span></span>); }
            }
            <span class="comment">/** Returns the {@code Text} slot at the specified row and column to write a text value into.
             * @param row the row of the cell whose Text to return
             * @param col the column of the cell whose Text to return
             * @return the Text object at the specified row and column
             * @since 2.0 */</span>
            <span class="directive">public</span> Text textAt(<span class="type">int</span> row, <span class="type">int</span> col) { <span class="keyword">return</span> columnValues.get(col + (row * columns.length)); }

            <span class="comment">/** Returns the {@code Text} slot at the specified row and column to write a text value into.
             * @param row the row of the cell whose Text to return
             * @param col the column of the cell whose Text to return
             * @return the Text object at the specified row and column
             * @deprecated use {@link #textAt(int, int)} instead */</span>
            <span class="directive">public</span> Text cellAt(<span class="type">int</span> row, <span class="type">int</span> col) { <span class="keyword">return</span> textAt(row, col); }

            <span class="comment">/** Returns the current number of rows of this {@code TextTable}.
             * @return the current number of rows in this TextTable */</span>
            <span class="directive">public</span> <span class="type">int</span> rowCount() { <span class="keyword">return</span> columnValues.size() / columns.length; }

            <span class="comment">/** Adds the required {@code char[]} slots for a new row to the {@link #columnValues} field. */</span>
            <span class="directive">public</span> <span class="type">void</span> addEmptyRow() {
                <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">0</span>; i &lt; columns.length; i++) {
                    columnValues.add(ansi.new Text(columns[i].width));
                }
            }

            <span class="comment">/** Delegates to {@link #addRowValues(CommandLine.Help.Ansi.Text...)}.
             * @param values the text values to display in each column of the current row */</span>
            <span class="directive">public</span> <span class="type">void</span> addRowValues(<span class="predefined-type">String</span>... values) {
                Text<span class="type">[]</span> array = <span class="keyword">new</span> Text[values.length];
                <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">0</span>; i &lt; array.length; i++) {
                    array[i] = values[i] == <span class="predefined-constant">null</span> ? Ansi.EMPTY_TEXT : ansi.new Text(values[i]);
                }
                addRowValues(array);
            }
            <span class="comment">/**
             * Adds a new {@linkplain TextTable#addEmptyRow() empty row}, then calls {@link
             * TextTable#putValue(int, int, CommandLine.Help.Ansi.Text) putValue} for each of the specified values, adding more empty rows
             * if the return value indicates that the value spanned multiple columns or was wrapped to multiple rows.
             * @param values the values to write into a new row in this TextTable
             * @throws IllegalArgumentException if the number of values exceeds the number of Columns in this table
             */</span>
            <span class="directive">public</span> <span class="type">void</span> addRowValues(Text... values) {
                <span class="keyword">if</span> (values.length &gt; columns.length) {
                    <span class="keyword">throw</span> <span class="keyword">new</span> <span class="exception">IllegalArgumentException</span>(values.length + <span class="string"><span class="delimiter">&quot;</span><span class="content"> values don't fit in </span><span class="delimiter">&quot;</span></span> +
                            columns.length + <span class="string"><span class="delimiter">&quot;</span><span class="content"> columns</span><span class="delimiter">&quot;</span></span>);
                }
                addEmptyRow();
                <span class="keyword">for</span> (<span class="type">int</span> col = <span class="integer">0</span>; col &lt; values.length; col++) {
                    <span class="type">int</span> row = rowCount() - <span class="integer">1</span>;<span class="comment">// write to last row: previous value may have wrapped to next row</span>
                    Cell cell = putValue(row, col, values[col]);

                    <span class="comment">// add row if a value spanned/wrapped and there are still remaining values</span>
                    <span class="keyword">if</span> ((cell.row != row || cell.column != col) &amp;&amp; col != values.length - <span class="integer">1</span>) {
                        addEmptyRow();
                    }
                }
            }
            <span class="comment">/**
             * Writes the specified value into the cell at the specified row and column and returns the last row and
             * column written to. Depending on the Column's {@link Column#overflow Overflow} policy, the value may span
             * multiple columns or wrap to multiple rows when larger than the column width.
             * @param row the target row in the table
             * @param col the target column in the table to write to
             * @param value the value to write
             * @return a Cell indicating the position in the table that was last written to (since 2.0)
             * @throws IllegalArgumentException if the specified row exceeds the table's {@linkplain
             *          TextTable#rowCount() row count}
             * @since 2.0 (previous versions returned a {@code java.awt.Point} object)
             */</span>
            <span class="directive">public</span> Cell putValue(<span class="type">int</span> row, <span class="type">int</span> col, Text value) {
                <span class="keyword">if</span> (row &gt; rowCount() - <span class="integer">1</span>) {
                    <span class="keyword">throw</span> <span class="keyword">new</span> <span class="exception">IllegalArgumentException</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">Cannot write to row </span><span class="delimiter">&quot;</span></span> + row + <span class="string"><span class="delimiter">&quot;</span><span class="content">: rowCount=</span><span class="delimiter">&quot;</span></span> + rowCount());
                }
                <span class="keyword">if</span> (value == <span class="predefined-constant">null</span> || value.plain.length() == <span class="integer">0</span>) { <span class="keyword">return</span> <span class="keyword">new</span> Cell(col, row); }
                Column column = columns[col];
                <span class="type">int</span> indent = column.indent;
                <span class="keyword">switch</span> (column.overflow) {
                    <span class="keyword">case</span> TRUNCATE:
                        copy(value, textAt(row, col), indent);
                        <span class="keyword">return</span> <span class="keyword">new</span> Cell(col, row);
                    <span class="keyword">case</span> SPAN:
                        <span class="type">int</span> startColumn = col;
                        <span class="keyword">do</span> {
                            <span class="type">boolean</span> lastColumn = col == columns.length - <span class="integer">1</span>;
                            <span class="type">int</span> charsWritten = lastColumn
                                    ? copy(<span class="predefined-type">BreakIterator</span>.getLineInstance(), value, textAt(row, col), indent)
                                    : copy(value, textAt(row, col), indent);
                            value = value.substring(charsWritten);
                            indent = <span class="integer">0</span>;
                            <span class="keyword">if</span> (value.length &gt; <span class="integer">0</span>) { <span class="comment">// value did not fit in column</span>
                                ++col;                <span class="comment">// write remainder of value in next column</span>
                            }
                            <span class="keyword">if</span> (value.length &gt; <span class="integer">0</span> &amp;&amp; col &gt;= columns.length) { <span class="comment">// we filled up all columns on this row</span>
                                addEmptyRow();
                                row++;
                                col = startColumn;
                                indent = column.indent + indentWrappedLines;
                            }
                        } <span class="keyword">while</span> (value.length &gt; <span class="integer">0</span>);
                        <span class="keyword">return</span> <span class="keyword">new</span> Cell(col, row);
                    <span class="keyword">case</span> WRAP:
                        <span class="predefined-type">BreakIterator</span> lineBreakIterator = <span class="predefined-type">BreakIterator</span>.getLineInstance();
                        <span class="keyword">do</span> {
                            <span class="type">int</span> charsWritten = copy(lineBreakIterator, value, textAt(row, col), indent);
                            value = value.substring(charsWritten);
                            indent = column.indent + indentWrappedLines;
                            <span class="keyword">if</span> (value.length &gt; <span class="integer">0</span>) {  <span class="comment">// value did not fit in column</span>
                                ++row;                 <span class="comment">// write remainder of value in next row</span>
                                addEmptyRow();
                            }
                        } <span class="keyword">while</span> (value.length &gt; <span class="integer">0</span>);
                        <span class="keyword">return</span> <span class="keyword">new</span> Cell(col, row);
                }
                <span class="keyword">throw</span> <span class="keyword">new</span> <span class="exception">IllegalStateException</span>(column.overflow.toString());
            }
            <span class="directive">private</span> <span class="directive">static</span> <span class="type">int</span> length(Text str) {
                <span class="keyword">return</span> str.length; <span class="comment">// TODO count some characters as double length</span>
            }

            <span class="directive">private</span> <span class="type">int</span> copy(<span class="predefined-type">BreakIterator</span> line, Text text, Text columnValue, <span class="type">int</span> offset) {
                <span class="comment">// Deceive the BreakIterator to ensure no line breaks after '-' character</span>
                line.setText(text.plainString().replace(<span class="string"><span class="delimiter">&quot;</span><span class="content">-</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="char">\u00ff</span><span class="delimiter">&quot;</span></span>));
                <span class="type">int</span> done = <span class="integer">0</span>;
                <span class="keyword">for</span> (<span class="type">int</span> start = line.first(), end = line.next(); end != <span class="predefined-type">BreakIterator</span>.DONE; start = end, end = line.next()) {
                    Text word = text.substring(start, end); <span class="comment">//.replace(&quot;\u00ff&quot;, &quot;-&quot;); // not needed</span>
                    <span class="keyword">if</span> (columnValue.maxLength &gt;= offset + done + length(word)) {
                        done += copy(word, columnValue, offset + done); <span class="comment">// TODO localized length</span>
                    } <span class="keyword">else</span> {
                        <span class="keyword">break</span>;
                    }
                }
                <span class="keyword">if</span> (done == <span class="integer">0</span> &amp;&amp; length(text) &gt; columnValue.maxLength) {
                    <span class="comment">// The value is a single word that is too big to be written to the column. Write as much as we can.</span>
                    done = copy(text, columnValue, offset);
                }
                <span class="keyword">return</span> done;
            }
            <span class="directive">private</span> <span class="directive">static</span> <span class="type">int</span> copy(Text value, Text destination, <span class="type">int</span> offset) {
                <span class="type">int</span> length = <span class="predefined-type">Math</span>.min(value.length, destination.maxLength - offset);
                value.getStyledChars(value.from, length, destination, offset);
                <span class="keyword">return</span> length;
            }

            <span class="comment">/** Copies the text representation that we built up from the options into the specified StringBuilder.
             * @param text the StringBuilder to write into
             * @return the specified StringBuilder object (to allow method chaining and a more fluid API) */</span>
            <span class="directive">public</span> <span class="predefined-type">StringBuilder</span> toString(<span class="predefined-type">StringBuilder</span> text) {
                <span class="type">int</span> columnCount = <span class="local-variable">this</span>.columns.length;
                <span class="predefined-type">StringBuilder</span> row = <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>(usageHelpWidth);
                <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">0</span>; i &lt; columnValues.size(); i++) {
                    Text column = columnValues.get(i);
                    row.append(column.toString());
                    row.append(<span class="keyword">new</span> <span class="predefined-type">String</span>(spaces(columns[i % columnCount].width - column.length)));
                    <span class="keyword">if</span> (i % columnCount == columnCount - <span class="integer">1</span>) {
                        <span class="type">int</span> lastChar = row.length() - <span class="integer">1</span>;
                        <span class="keyword">while</span> (lastChar &gt;= <span class="integer">0</span> &amp;&amp; row.charAt(lastChar) == <span class="string"><span class="delimiter">'</span><span class="content"> </span><span class="delimiter">'</span></span>) {lastChar--;} <span class="comment">// rtrim</span>
                        row.setLength(lastChar + <span class="integer">1</span>);
                        text.append(row.toString()).append(<span class="predefined-type">System</span>.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">line.separator</span><span class="delimiter">&quot;</span></span>));
                        row.setLength(<span class="integer">0</span>);
                    }
                }
                <span class="comment">//if (Ansi.enabled()) { text.append(Style.reset.off()); }</span>
                <span class="keyword">return</span> text;
            }
            <span class="directive">public</span> <span class="predefined-type">String</span> toString() { <span class="keyword">return</span> toString(<span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>()).toString(); }
        }
        <span class="comment">/** Columns define the width, indent (leading number of spaces in a column before the value) and
         * {@linkplain Overflow Overflow} policy of a column in a {@linkplain TextTable TextTable}. */</span>
        <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">Column</span> {

            <span class="comment">/** Policy for handling text that is longer than the column width:
             *  span multiple columns, wrap to the next row, or simply truncate the portion that doesn't fit. */</span>
            <span class="directive">public</span> <span class="type">enum</span> Overflow { TRUNCATE, SPAN, WRAP }

            <span class="comment">/** Column width in characters */</span>
            <span class="directive">public</span> <span class="directive">final</span> <span class="type">int</span> width;

            <span class="comment">/** Indent (number of empty spaces at the start of the column preceding the text value) */</span>
            <span class="directive">public</span> <span class="directive">final</span> <span class="type">int</span> indent;

            <span class="comment">/** Policy that determines how to handle values larger than the column width. */</span>
            <span class="directive">public</span> <span class="directive">final</span> Overflow overflow;
            <span class="directive">public</span> Column(<span class="type">int</span> width, <span class="type">int</span> indent, Overflow overflow) {
                <span class="local-variable">this</span>.width = width;
                <span class="local-variable">this</span>.indent = indent;
                <span class="local-variable">this</span>.overflow = Assert.notNull(overflow, <span class="string"><span class="delimiter">&quot;</span><span class="content">overflow</span><span class="delimiter">&quot;</span></span>);
            }
        }

        <span class="comment">/** All usage help message are generated with a color scheme that assigns certain styles and colors to common
         * parts of a usage message: the command name, options, positional parameters and option parameters.
         * Users may customize these styles by creating Help with a custom color scheme.
         * &lt;p&gt;Note that these options and styles may not be rendered if ANSI escape codes are not
         * {@linkplain Ansi#enabled() enabled}.&lt;/p&gt;
         * @see Help#defaultColorScheme(Ansi)
         */</span>
        <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">ColorScheme</span> {
            <span class="directive">public</span> <span class="directive">final</span> <span class="predefined-type">List</span>&lt;IStyle&gt; commandStyles = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;IStyle&gt;();
            <span class="directive">public</span> <span class="directive">final</span> <span class="predefined-type">List</span>&lt;IStyle&gt; optionStyles = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;IStyle&gt;();
            <span class="directive">public</span> <span class="directive">final</span> <span class="predefined-type">List</span>&lt;IStyle&gt; parameterStyles = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;IStyle&gt;();
            <span class="directive">public</span> <span class="directive">final</span> <span class="predefined-type">List</span>&lt;IStyle&gt; optionParamStyles = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;IStyle&gt;();
            <span class="directive">private</span> <span class="directive">final</span> Ansi ansi;

            <span class="comment">/** Constructs a new ColorScheme with {@link Help.Ansi#AUTO}. */</span>
            <span class="directive">public</span> ColorScheme() { <span class="local-variable">this</span>(Ansi.AUTO); }

            <span class="comment">/** Constructs a new ColorScheme with the specified Ansi enabled mode.
             * @param ansi whether to emit ANSI escape codes or not
             */</span>
            <span class="directive">public</span> ColorScheme(Ansi ansi) {<span class="local-variable">this</span>.ansi = Assert.notNull(ansi, <span class="string"><span class="delimiter">&quot;</span><span class="content">ansi</span><span class="delimiter">&quot;</span></span>); }

            <span class="comment">/** Adds the specified styles to the registered styles for commands in this color scheme and returns this color scheme.
             * @param styles the styles to add to the registered styles for commands in this color scheme
             * @return this color scheme to enable method chaining for a more fluent API */</span>
            <span class="directive">public</span> ColorScheme commands(IStyle... styles)     { <span class="keyword">return</span> addAll(commandStyles, styles); }
            <span class="comment">/** Adds the specified styles to the registered styles for options in this color scheme and returns this color scheme.
             * @param styles the styles to add to registered the styles for options in this color scheme
             * @return this color scheme to enable method chaining for a more fluent API */</span>
            <span class="directive">public</span> ColorScheme options(IStyle... styles)      { <span class="keyword">return</span> addAll(optionStyles, styles);}
            <span class="comment">/** Adds the specified styles to the registered styles for positional parameters in this color scheme and returns this color scheme.
             * @param styles the styles to add to registered the styles for parameters in this color scheme
             * @return this color scheme to enable method chaining for a more fluent API */</span>
            <span class="directive">public</span> ColorScheme parameters(IStyle... styles)   { <span class="keyword">return</span> addAll(parameterStyles, styles);}
            <span class="comment">/** Adds the specified styles to the registered styles for option parameters in this color scheme and returns this color scheme.
             * @param styles the styles to add to the registered styles for option parameters in this color scheme
             * @return this color scheme to enable method chaining for a more fluent API */</span>
            <span class="directive">public</span> ColorScheme optionParams(IStyle... styles) { <span class="keyword">return</span> addAll(optionParamStyles, styles);}
            <span class="comment">/** Returns a Text with all command styles applied to the specified command string.
             * @param command the command string to apply the registered command styles to
             * @return a Text with all command styles applied to the specified command string */</span>
            <span class="directive">public</span> Ansi.Text commandText(<span class="predefined-type">String</span> command)         { <span class="keyword">return</span> ansi().apply(command,     commandStyles); }
            <span class="comment">/** Returns a Text with all option styles applied to the specified option string.
             * @param option the option string to apply the registered option styles to
             * @return a Text with all option styles applied to the specified option string */</span>
            <span class="directive">public</span> Ansi.Text optionText(<span class="predefined-type">String</span> option)           { <span class="keyword">return</span> ansi().apply(option,      optionStyles); }
            <span class="comment">/** Returns a Text with all parameter styles applied to the specified parameter string.
             * @param parameter the parameter string to apply the registered parameter styles to
             * @return a Text with all parameter styles applied to the specified parameter string */</span>
            <span class="directive">public</span> Ansi.Text parameterText(<span class="predefined-type">String</span> parameter)     { <span class="keyword">return</span> ansi().apply(parameter,   parameterStyles); }
            <span class="comment">/** Returns a Text with all optionParam styles applied to the specified optionParam string.
             * @param optionParam the option parameter string to apply the registered option parameter styles to
             * @return a Text with all option parameter styles applied to the specified option parameter string */</span>
            <span class="directive">public</span> Ansi.Text optionParamText(<span class="predefined-type">String</span> optionParam) { <span class="keyword">return</span> ansi().apply(optionParam, optionParamStyles); }

            <span class="comment">/** Replaces colors and styles in this scheme with ones specified in system properties, and returns this scheme.
             * Supported property names:&lt;ul&gt;
             *     &lt;li&gt;{@code picocli.color.commands}&lt;/li&gt;
             *     &lt;li&gt;{@code picocli.color.options}&lt;/li&gt;
             *     &lt;li&gt;{@code picocli.color.parameters}&lt;/li&gt;
             *     &lt;li&gt;{@code picocli.color.optionParams}&lt;/li&gt;
             * &lt;/ul&gt;&lt;p&gt;Property values can be anything that {@link Help.Ansi.Style#parse(String)} can handle.&lt;/p&gt;
             * @return this ColorScheme
             */</span>
            <span class="directive">public</span> ColorScheme applySystemProperties() {
                replace(commandStyles,     <span class="predefined-type">System</span>.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">picocli.color.commands</span><span class="delimiter">&quot;</span></span>));
                replace(optionStyles,      <span class="predefined-type">System</span>.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">picocli.color.options</span><span class="delimiter">&quot;</span></span>));
                replace(parameterStyles,   <span class="predefined-type">System</span>.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">picocli.color.parameters</span><span class="delimiter">&quot;</span></span>));
                replace(optionParamStyles, <span class="predefined-type">System</span>.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">picocli.color.optionParams</span><span class="delimiter">&quot;</span></span>));
                <span class="keyword">return</span> <span class="local-variable">this</span>;
            }
            <span class="directive">private</span> <span class="type">void</span> replace(<span class="predefined-type">List</span>&lt;IStyle&gt; styles, <span class="predefined-type">String</span> property) {
                <span class="keyword">if</span> (property != <span class="predefined-constant">null</span>) {
                    styles.clear();
                    addAll(styles, <span class="predefined-type">Style</span>.parse(property));
                }
            }
            <span class="directive">private</span> ColorScheme addAll(<span class="predefined-type">List</span>&lt;IStyle&gt; styles, IStyle... add) {
                styles.addAll(<span class="predefined-type">Arrays</span>.asList(add));
                <span class="keyword">return</span> <span class="local-variable">this</span>;
            }

            <span class="directive">public</span> Ansi ansi() {
                <span class="keyword">return</span> ansi;
            }
        }

        <span class="comment">/** Creates and returns a new {@link ColorScheme} initialized with picocli default values: commands are bold,
         *  options and parameters use a yellow foreground, and option parameters use italic.
         * @param ansi whether the usage help message should contain ANSI escape codes or not
         * @return a new default color scheme
         */</span>
        <span class="directive">public</span> <span class="directive">static</span> ColorScheme defaultColorScheme(Ansi ansi) {
            <span class="keyword">return</span> <span class="keyword">new</span> ColorScheme(ansi)
                    .commands(<span class="predefined-type">Style</span>.bold)
                    .options(<span class="predefined-type">Style</span>.fg_yellow)
                    .parameters(<span class="predefined-type">Style</span>.fg_yellow)
                    .optionParams(<span class="predefined-type">Style</span>.italic);
        }

        <span class="comment">/** Provides methods and inner classes to support using ANSI escape codes in usage help messages. */</span>
        <span class="directive">public</span> <span class="type">enum</span> Ansi {
            <span class="comment">/** Only emit ANSI escape codes if the platform supports it and system property {@code &quot;picocli.ansi&quot;}
             * is not set to any value other than {@code &quot;true&quot;} (case insensitive). */</span>
            AUTO,
            <span class="comment">/** Forced ON: always emit ANSI escape code regardless of the platform. */</span>
            ON,
            <span class="comment">/** Forced OFF: never emit ANSI escape code regardless of the platform. */</span>
            OFF;
            <span class="directive">static</span> Text EMPTY_TEXT = OFF.new Text(<span class="integer">0</span>);
            <span class="directive">static</span> <span class="directive">final</span> <span class="type">boolean</span> isWindows  = <span class="predefined-type">System</span>.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">os.name</span><span class="delimiter">&quot;</span></span>).startsWith(<span class="string"><span class="delimiter">&quot;</span><span class="content">Windows</span><span class="delimiter">&quot;</span></span>);
            <span class="directive">static</span> <span class="directive">final</span> <span class="type">boolean</span> isXterm    = <span class="predefined-type">System</span>.getenv(<span class="string"><span class="delimiter">&quot;</span><span class="content">TERM</span><span class="delimiter">&quot;</span></span>) != <span class="predefined-constant">null</span> &amp;&amp; <span class="predefined-type">System</span>.getenv(<span class="string"><span class="delimiter">&quot;</span><span class="content">TERM</span><span class="delimiter">&quot;</span></span>).startsWith(<span class="string"><span class="delimiter">&quot;</span><span class="content">xterm</span><span class="delimiter">&quot;</span></span>);
            <span class="directive">static</span> <span class="directive">final</span> <span class="type">boolean</span> ISATTY = calcTTY();

            <span class="comment">// http://stackoverflow.com/questions/1403772/how-can-i-check-if-a-java-programs-input-output-streams-are-connected-to-a-term</span>
            <span class="directive">static</span> <span class="directive">final</span> <span class="type">boolean</span> calcTTY() {
                <span class="keyword">if</span> (isWindows &amp;&amp; isXterm) { <span class="keyword">return</span> <span class="predefined-constant">true</span>; } <span class="comment">// Cygwin uses pseudo-tty and console is always null...</span>
                <span class="keyword">try</span> { <span class="keyword">return</span> <span class="predefined-type">System</span>.class.getDeclaredMethod(<span class="string"><span class="delimiter">&quot;</span><span class="content">console</span><span class="delimiter">&quot;</span></span>).invoke(<span class="predefined-constant">null</span>) != <span class="predefined-constant">null</span>; }
                <span class="keyword">catch</span> (<span class="predefined-type">Throwable</span> reflectionFailed) { <span class="keyword">return</span> <span class="predefined-constant">true</span>; }
            }
            <span class="directive">private</span> <span class="directive">static</span> <span class="type">boolean</span> ansiPossible() { <span class="keyword">return</span> ISATTY &amp;&amp; (!isWindows || isXterm); }

            <span class="comment">/** Returns {@code true} if ANSI escape codes should be emitted, {@code false} otherwise.
             * @return ON: {@code true}, OFF: {@code false}, AUTO: if system property {@code &quot;picocli.ansi&quot;} is
             *      defined then return its boolean value, otherwise return whether the platform supports ANSI escape codes */</span>
            <span class="directive">public</span> <span class="type">boolean</span> enabled() {
                <span class="keyword">if</span> (<span class="local-variable">this</span> == ON)  { <span class="keyword">return</span> <span class="predefined-constant">true</span>; }
                <span class="keyword">if</span> (<span class="local-variable">this</span> == OFF) { <span class="keyword">return</span> <span class="predefined-constant">false</span>; }
                <span class="keyword">return</span> (<span class="predefined-type">System</span>.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">picocli.ansi</span><span class="delimiter">&quot;</span></span>) == <span class="predefined-constant">null</span> ? ansiPossible() : <span class="predefined-type">Boolean</span>.getBoolean(<span class="string"><span class="delimiter">&quot;</span><span class="content">picocli.ansi</span><span class="delimiter">&quot;</span></span>));
            }

            <span class="comment">/** Defines the interface for an ANSI escape sequence. */</span>
            <span class="directive">public</span> <span class="type">interface</span> <span class="class">IStyle</span> {

                <span class="comment">/** The Control Sequence Introducer (CSI) escape sequence {@value}. */</span>
                <span class="predefined-type">String</span> CSI = <span class="string"><span class="delimiter">&quot;</span><span class="char">\u001B</span><span class="content">[</span><span class="delimiter">&quot;</span></span>;

                <span class="comment">/** Returns the ANSI escape code for turning this style on.
                 * @return the ANSI escape code for turning this style on */</span>
                <span class="predefined-type">String</span> on();

                <span class="comment">/** Returns the ANSI escape code for turning this style off.
                 * @return the ANSI escape code for turning this style off */</span>
                <span class="predefined-type">String</span> off();
            }

            <span class="comment">/**
             * A set of pre-defined ANSI escape code styles and colors, and a set of convenience methods for parsing
             * text with embedded markup style names, as well as convenience methods for converting
             * styles to strings with embedded escape codes.
             */</span>
            <span class="directive">public</span> <span class="type">enum</span> <span class="predefined-type">Style</span> <span class="directive">implements</span> IStyle {
                reset(<span class="integer">0</span>, <span class="integer">0</span>), bold(<span class="integer">1</span>, <span class="integer">21</span>), faint(<span class="integer">2</span>, <span class="integer">22</span>), italic(<span class="integer">3</span>, <span class="integer">23</span>), underline(<span class="integer">4</span>, <span class="integer">24</span>), blink(<span class="integer">5</span>, <span class="integer">25</span>), reverse(<span class="integer">7</span>, <span class="integer">27</span>),
                fg_black(<span class="integer">30</span>, <span class="integer">39</span>), fg_red(<span class="integer">31</span>, <span class="integer">39</span>), fg_green(<span class="integer">32</span>, <span class="integer">39</span>), fg_yellow(<span class="integer">33</span>, <span class="integer">39</span>), fg_blue(<span class="integer">34</span>, <span class="integer">39</span>), fg_magenta(<span class="integer">35</span>, <span class="integer">39</span>), fg_cyan(<span class="integer">36</span>, <span class="integer">39</span>), fg_white(<span class="integer">37</span>, <span class="integer">39</span>),
                bg_black(<span class="integer">40</span>, <span class="integer">49</span>), bg_red(<span class="integer">41</span>, <span class="integer">49</span>), bg_green(<span class="integer">42</span>, <span class="integer">49</span>), bg_yellow(<span class="integer">43</span>, <span class="integer">49</span>), bg_blue(<span class="integer">44</span>, <span class="integer">49</span>), bg_magenta(<span class="integer">45</span>, <span class="integer">49</span>), bg_cyan(<span class="integer">46</span>, <span class="integer">49</span>), bg_white(<span class="integer">47</span>, <span class="integer">49</span>),
                ;
                <span class="directive">private</span> <span class="directive">final</span> <span class="type">int</span> startCode;
                <span class="directive">private</span> <span class="directive">final</span> <span class="type">int</span> endCode;

                <span class="predefined-type">Style</span>(<span class="type">int</span> startCode, <span class="type">int</span> endCode) {<span class="local-variable">this</span>.startCode = startCode; <span class="local-variable">this</span>.endCode = endCode; }
                <span class="directive">public</span> <span class="predefined-type">String</span> on() { <span class="keyword">return</span> CSI + startCode + <span class="string"><span class="delimiter">&quot;</span><span class="content">m</span><span class="delimiter">&quot;</span></span>; }
                <span class="directive">public</span> <span class="predefined-type">String</span> off() { <span class="keyword">return</span> CSI + endCode + <span class="string"><span class="delimiter">&quot;</span><span class="content">m</span><span class="delimiter">&quot;</span></span>; }

                                <span class="comment">/** Returns the concatenated ANSI escape codes for turning all specified styles on.
                 * @param styles the styles to generate ANSI escape codes for
                 * @return the concatenated ANSI escape codes for turning all specified styles on */</span>
                <span class="directive">public</span> <span class="directive">static</span> <span class="predefined-type">String</span> on(IStyle... styles) {
                    <span class="predefined-type">StringBuilder</span> result = <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>();
                    <span class="keyword">for</span> (IStyle style : styles) {
                        result.append(style.on());
                    }
                    <span class="keyword">return</span> result.toString();
                }
                                <span class="comment">/** Returns the concatenated ANSI escape codes for turning all specified styles off.
                 * @param styles the styles to generate ANSI escape codes for
                 * @return the concatenated ANSI escape codes for turning all specified styles off */</span>
                <span class="directive">public</span> <span class="directive">static</span> <span class="predefined-type">String</span> off(IStyle... styles) {
                    <span class="predefined-type">StringBuilder</span> result = <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>();
                    <span class="keyword">for</span> (IStyle style : styles) {
                        result.append(style.off());
                    }
                    <span class="keyword">return</span> result.toString();
                }
                                <span class="comment">/** Parses the specified style markup and returns the associated style.
                                 *  The markup may be one of the Style enum value names, or it may be one of the Style enum value
                                 *  names when {@code &quot;fg_&quot;} is prepended, or it may be one of the indexed colors in the 256 color palette.
                 * @param str the case-insensitive style markup to convert, e.g. {@code &quot;blue&quot;} or {@code &quot;fg_blue&quot;},
                 *          or {@code &quot;46&quot;} (indexed color) or {@code &quot;0;5;0&quot;} (RGB components of an indexed color)
                                 * @return the IStyle for the specified converter
                                 */</span>
                <span class="directive">public</span> <span class="directive">static</span> IStyle fg(<span class="predefined-type">String</span> str) {
                    <span class="keyword">try</span> { <span class="keyword">return</span> <span class="predefined-type">Style</span>.valueOf(str.toLowerCase(ENGLISH)); } <span class="keyword">catch</span> (<span class="exception">Exception</span> ignored) {}
                    <span class="keyword">try</span> { <span class="keyword">return</span> <span class="predefined-type">Style</span>.valueOf(<span class="string"><span class="delimiter">&quot;</span><span class="content">fg_</span><span class="delimiter">&quot;</span></span> + str.toLowerCase(ENGLISH)); } <span class="keyword">catch</span> (<span class="exception">Exception</span> ignored) {}
                    <span class="keyword">return</span> <span class="keyword">new</span> Palette256Color(<span class="predefined-constant">true</span>, str);
                }
                                <span class="comment">/** Parses the specified style markup and returns the associated style.
                                 *  The markup may be one of the Style enum value names, or it may be one of the Style enum value
                                 *  names when {@code &quot;bg_&quot;} is prepended, or it may be one of the indexed colors in the 256 color palette.
                                 * @param str the case-insensitive style markup to convert, e.g. {@code &quot;blue&quot;} or {@code &quot;bg_blue&quot;},
                 *          or {@code &quot;46&quot;} (indexed color) or {@code &quot;0;5;0&quot;} (RGB components of an indexed color)
                                 * @return the IStyle for the specified converter
                                 */</span>
                <span class="directive">public</span> <span class="directive">static</span> IStyle bg(<span class="predefined-type">String</span> str) {
                    <span class="keyword">try</span> { <span class="keyword">return</span> <span class="predefined-type">Style</span>.valueOf(str.toLowerCase(ENGLISH)); } <span class="keyword">catch</span> (<span class="exception">Exception</span> ignored) {}
                    <span class="keyword">try</span> { <span class="keyword">return</span> <span class="predefined-type">Style</span>.valueOf(<span class="string"><span class="delimiter">&quot;</span><span class="content">bg_</span><span class="delimiter">&quot;</span></span> + str.toLowerCase(ENGLISH)); } <span class="keyword">catch</span> (<span class="exception">Exception</span> ignored) {}
                    <span class="keyword">return</span> <span class="keyword">new</span> Palette256Color(<span class="predefined-constant">false</span>, str);
                }
                <span class="comment">/** Parses the specified comma-separated sequence of style descriptors and returns the associated
                 *  styles. For each markup, strings starting with {@code &quot;bg(&quot;} are delegated to
                 *  {@link #bg(String)}, others are delegated to {@link #bg(String)}.
                 * @param commaSeparatedCodes one or more descriptors, e.g. {@code &quot;bg(blue),underline,red&quot;}
                 * @return an array with all styles for the specified descriptors
                 */</span>
                <span class="directive">public</span> <span class="directive">static</span> IStyle<span class="type">[]</span> parse(<span class="predefined-type">String</span> commaSeparatedCodes) {
                    <span class="predefined-type">String</span><span class="type">[]</span> codes = commaSeparatedCodes.split(<span class="string"><span class="delimiter">&quot;</span><span class="content">,</span><span class="delimiter">&quot;</span></span>);
                    IStyle<span class="type">[]</span> styles = <span class="keyword">new</span> IStyle[codes.length];
                    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="integer">0</span>; i &lt; codes.length; ++i) {
                        <span class="keyword">if</span> (codes[i].toLowerCase(ENGLISH).startsWith(<span class="string"><span class="delimiter">&quot;</span><span class="content">fg(</span><span class="delimiter">&quot;</span></span>)) {
                            <span class="type">int</span> end = codes[i].indexOf(<span class="string"><span class="delimiter">'</span><span class="content">)</span><span class="delimiter">'</span></span>);
                            styles[i] = <span class="predefined-type">Style</span>.fg(codes[i].substring(<span class="integer">3</span>, end &lt; <span class="integer">0</span> ? codes[i].length() : end));
                        } <span class="keyword">else</span> <span class="keyword">if</span> (codes[i].toLowerCase(ENGLISH).startsWith(<span class="string"><span class="delimiter">&quot;</span><span class="content">bg(</span><span class="delimiter">&quot;</span></span>)) {
                            <span class="type">int</span> end = codes[i].indexOf(<span class="string"><span class="delimiter">'</span><span class="content">)</span><span class="delimiter">'</span></span>);
                            styles[i] = <span class="predefined-type">Style</span>.bg(codes[i].substring(<span class="integer">3</span>, end &lt; <span class="integer">0</span> ? codes[i].length() : end));
                        } <span class="keyword">else</span> {
                            styles[i] = <span class="predefined-type">Style</span>.fg(codes[i]);
                        }
                    }
                    <span class="keyword">return</span> styles;
                }
            }

            <span class="comment">/** Defines a palette map of 216 colors: 6 * 6 * 6 cube (216 colors):
             * 16 + 36 * r + 6 * g + b (0 &amp;lt;= r, g, b &amp;lt;= 5). */</span>
            <span class="directive">static</span> <span class="type">class</span> <span class="class">Palette256Color</span> <span class="directive">implements</span> IStyle {
                <span class="directive">private</span> <span class="directive">final</span> <span class="type">int</span> fgbg;
                <span class="directive">private</span> <span class="directive">final</span> <span class="type">int</span> color;

                Palette256Color(<span class="type">boolean</span> foreground, <span class="predefined-type">String</span> color) {
                    <span class="local-variable">this</span>.fgbg = foreground ? <span class="integer">38</span> : <span class="integer">48</span>;
                    <span class="predefined-type">String</span><span class="type">[]</span> rgb = color.split(<span class="string"><span class="delimiter">&quot;</span><span class="content">;</span><span class="delimiter">&quot;</span></span>);
                    <span class="keyword">if</span> (rgb.length == <span class="integer">3</span>) {
                        <span class="local-variable">this</span>.color = <span class="integer">16</span> + <span class="integer">36</span> * <span class="predefined-type">Integer</span>.decode(rgb[<span class="integer">0</span>]) + <span class="integer">6</span> * <span class="predefined-type">Integer</span>.decode(rgb[<span class="integer">1</span>]) + <span class="predefined-type">Integer</span>.decode(rgb[<span class="integer">2</span>]);
                    } <span class="keyword">else</span> {
                        <span class="local-variable">this</span>.color = <span class="predefined-type">Integer</span>.decode(color);
                    }
                }
                <span class="directive">public</span> <span class="predefined-type">String</span> on() { <span class="keyword">return</span> <span class="predefined-type">String</span>.format(CSI + <span class="string"><span class="delimiter">&quot;</span><span class="content">%d;5;%dm</span><span class="delimiter">&quot;</span></span>, fgbg, color); }
                <span class="directive">public</span> <span class="predefined-type">String</span> off() { <span class="keyword">return</span> CSI + (fgbg + <span class="integer">1</span>) + <span class="string"><span class="delimiter">&quot;</span><span class="content">m</span><span class="delimiter">&quot;</span></span>; }
            }
            <span class="directive">private</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">StyledSection</span> {
                <span class="type">int</span> startIndex, length;
                <span class="predefined-type">String</span> startStyles, endStyles;
                StyledSection(<span class="type">int</span> start, <span class="type">int</span> len, <span class="predefined-type">String</span> style1, <span class="predefined-type">String</span> style2) {
                    startIndex = start; length = len; startStyles = style1; endStyles = style2;
                }
                StyledSection withStartIndex(<span class="type">int</span> newStart) {
                    <span class="keyword">return</span> <span class="keyword">new</span> StyledSection(newStart, length, startStyles, endStyles);
                }
            }

            <span class="comment">/**
             * Returns a new Text object where all the specified styles are applied to the full length of the
             * specified plain text.
             * @param plainText the string to apply all styles to. Must not contain markup!
             * @param styles the styles to apply to the full plain text
             * @return a new Text object
             */</span>
            <span class="directive">public</span> Text apply(<span class="predefined-type">String</span> plainText, <span class="predefined-type">List</span>&lt;IStyle&gt; styles) {
                <span class="keyword">if</span> (plainText.length() == <span class="integer">0</span>) { <span class="keyword">return</span> <span class="keyword">new</span> Text(<span class="integer">0</span>); }
                Text result = <span class="keyword">new</span> Text(plainText.length());
                IStyle<span class="type">[]</span> all = styles.toArray(<span class="keyword">new</span> IStyle[styles.size()]);
                result.sections.add(<span class="keyword">new</span> StyledSection(
                        <span class="integer">0</span>, plainText.length(), <span class="predefined-type">Style</span>.on(all), <span class="predefined-type">Style</span>.off(reverse(all)) + <span class="predefined-type">Style</span>.reset.off()));
                result.plain.append(plainText);
                result.length = result.plain.length();
                <span class="keyword">return</span> result;
            }

            <span class="directive">private</span> <span class="directive">static</span> &lt;T&gt; T<span class="type">[]</span> reverse(T<span class="type">[]</span> all) {
                <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">0</span>; i &lt; all.length / <span class="integer">2</span>; i++) {
                    T temp = all[i];
                    all[i] = all[all.length - i - <span class="integer">1</span>];
                    all[all.length - i - <span class="integer">1</span>] = temp;
                }
                <span class="keyword">return</span> all;
            }
            <span class="comment">/** Encapsulates rich text with styles and colors. Text objects may be constructed with Strings containing
             * markup like {@code @|bg(red),white,underline some text|@}, and this class converts the markup to ANSI
             * escape codes.
             * &lt;p&gt;
             * Internally keeps both an enriched and a plain text representation to allow layout components to calculate
             * text width while remaining unaware of the embedded ANSI escape codes.&lt;/p&gt; */</span>
            <span class="directive">public</span> <span class="type">class</span> <span class="class">Text</span> <span class="directive">implements</span> <span class="predefined-type">Cloneable</span> {
                <span class="directive">private</span> <span class="directive">final</span> <span class="type">int</span> maxLength;
                <span class="directive">private</span> <span class="type">int</span> from;
                <span class="directive">private</span> <span class="type">int</span> length;
                <span class="directive">private</span> <span class="predefined-type">StringBuilder</span> plain = <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>();
                <span class="directive">private</span> <span class="predefined-type">List</span>&lt;StyledSection&gt; sections = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;StyledSection&gt;();

                <span class="comment">/** Constructs a Text with the specified max length (for use in a TextTable Column).
                 * @param maxLength max length of this text */</span>
                <span class="directive">public</span> Text(<span class="type">int</span> maxLength) { <span class="local-variable">this</span>.maxLength = maxLength; }

                <span class="comment">/**
                 * Constructs a Text with the specified String, which may contain markup like
                 * {@code @|bg(red),white,underline some text|@}.
                 * @param input the string with markup to parse
                 */</span>
                <span class="directive">public</span> Text(<span class="predefined-type">String</span> input) {
                    maxLength = -<span class="integer">1</span>;
                    plain.setLength(<span class="integer">0</span>);
                    <span class="type">int</span> i = <span class="integer">0</span>;

                    <span class="keyword">while</span> (<span class="predefined-constant">true</span>) {
                        <span class="type">int</span> j = input.indexOf(<span class="string"><span class="delimiter">&quot;</span><span class="content">@|</span><span class="delimiter">&quot;</span></span>, i);
                        <span class="keyword">if</span> (j == -<span class="integer">1</span>) {
                            <span class="keyword">if</span> (i == <span class="integer">0</span>) {
                                plain.append(input);
                                length = plain.length();
                                <span class="keyword">return</span>;
                            }
                            plain.append(input.substring(i, input.length()));
                            length = plain.length();
                            <span class="keyword">return</span>;
                        }
                        plain.append(input.substring(i, j));
                        <span class="type">int</span> k = input.indexOf(<span class="string"><span class="delimiter">&quot;</span><span class="content">|@</span><span class="delimiter">&quot;</span></span>, j);
                        <span class="keyword">if</span> (k == -<span class="integer">1</span>) {
                            plain.append(input);
                            length = plain.length();
                            <span class="keyword">return</span>;
                        }

                        j += <span class="integer">2</span>;
                        <span class="predefined-type">String</span> spec = input.substring(j, k);
                        <span class="predefined-type">String</span><span class="type">[]</span> items = spec.split(<span class="string"><span class="delimiter">&quot;</span><span class="content"> </span><span class="delimiter">&quot;</span></span>, <span class="integer">2</span>);
                        <span class="keyword">if</span> (items.length == <span class="integer">1</span>) {
                            plain.append(input);
                            length = plain.length();
                            <span class="keyword">return</span>;
                        }

                        IStyle<span class="type">[]</span> styles = <span class="predefined-type">Style</span>.parse(items[<span class="integer">0</span>]);
                        addStyledSection(plain.length(), items[<span class="integer">1</span>].length(),
                                <span class="predefined-type">Style</span>.on(styles), <span class="predefined-type">Style</span>.off(reverse(styles)) + <span class="predefined-type">Style</span>.reset.off());
                        plain.append(items[<span class="integer">1</span>]);
                        i = k + <span class="integer">2</span>;
                    }
                }
                <span class="directive">private</span> <span class="type">void</span> addStyledSection(<span class="type">int</span> start, <span class="type">int</span> length, <span class="predefined-type">String</span> startStyle, <span class="predefined-type">String</span> endStyle) {
                    sections.add(<span class="keyword">new</span> StyledSection(start, length, startStyle, endStyle));
                }
                <span class="directive">public</span> <span class="predefined-type">Object</span> clone() {
                    <span class="keyword">try</span> { <span class="keyword">return</span> <span class="local-variable">super</span>.clone(); } <span class="keyword">catch</span> (<span class="exception">CloneNotSupportedException</span> e) { <span class="keyword">throw</span> <span class="keyword">new</span> <span class="exception">IllegalStateException</span>(e); }
                }

                <span class="directive">public</span> Text<span class="type">[]</span> splitLines() {
                    <span class="predefined-type">List</span>&lt;Text&gt; result = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;Text&gt;();
                    <span class="type">boolean</span> trailingEmptyString = plain.length() == <span class="integer">0</span>;
                    <span class="type">int</span> start = <span class="integer">0</span>, end = <span class="integer">0</span>;
                    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">0</span>; i &lt; plain.length(); i++, end = i) {
                        <span class="type">char</span> c = plain.charAt(i);
                        <span class="type">boolean</span> eol = c == <span class="string"><span class="delimiter">'</span><span class="content">\n</span><span class="delimiter">'</span></span>;
                        eol |= (c == <span class="string"><span class="delimiter">'</span><span class="content">\r</span><span class="delimiter">'</span></span> &amp;&amp; i + <span class="integer">1</span> &lt; plain.length() &amp;&amp; plain.charAt(i + <span class="integer">1</span>) == <span class="string"><span class="delimiter">'</span><span class="content">\n</span><span class="delimiter">'</span></span> &amp;&amp; ++i &gt; <span class="integer">0</span>); <span class="comment">// \r\n</span>
                        eol |= c == <span class="string"><span class="delimiter">'</span><span class="content">\r</span><span class="delimiter">'</span></span>;
                        <span class="keyword">if</span> (eol) {
                            result.add(<span class="local-variable">this</span>.substring(start, end));
                            trailingEmptyString = i == plain.length() - <span class="integer">1</span>;
                            start = i + <span class="integer">1</span>;
                        }
                    }
                    <span class="keyword">if</span> (start &lt; plain.length() || trailingEmptyString) {
                        result.add(<span class="local-variable">this</span>.substring(start, plain.length()));
                    }
                    <span class="keyword">return</span> result.toArray(<span class="keyword">new</span> Text[result.size()]);
                }

                <span class="comment">/** Returns a new {@code Text} instance that is a substring of this Text. Does not modify this instance!
                 * @param start index in the plain text where to start the substring
                 * @return a new Text instance that is a substring of this Text */</span>
                <span class="directive">public</span> Text substring(<span class="type">int</span> start) {
                    <span class="keyword">return</span> substring(start, length);
                }

                <span class="comment">/** Returns a new {@code Text} instance that is a substring of this Text. Does not modify this instance!
                 * @param start index in the plain text where to start the substring
                 * @param end index in the plain text where to end the substring
                 * @return a new Text instance that is a substring of this Text */</span>
                <span class="directive">public</span> Text substring(<span class="type">int</span> start, <span class="type">int</span> end) {
                    Text result = (Text) clone();
                    result.from = from + start;
                    result.length = end - start;
                    <span class="keyword">return</span> result;
                }
                <span class="comment">/** Returns a new {@code Text} instance with the specified text appended. Does not modify this instance!
                 * @param string the text to append
                 * @return a new Text instance */</span>
                <span class="directive">public</span> Text append(<span class="predefined-type">String</span> string) {
                    <span class="keyword">return</span> append(<span class="keyword">new</span> Text(string));
                }

                <span class="comment">/** Returns a new {@code Text} instance with the specified text appended. Does not modify this instance!
                 * @param other the text to append
                 * @return a new Text instance */</span>
                <span class="directive">public</span> Text append(Text other) {
                    Text result = (Text) clone();
                    result.plain = <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>(plain.toString().substring(from, from + length));
                    result.from = <span class="integer">0</span>;
                    result.sections = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;StyledSection&gt;();
                    <span class="keyword">for</span> (StyledSection section : sections) {
                        result.sections.add(section.withStartIndex(section.startIndex - from));
                    }
                    result.plain.append(other.plain.toString().substring(other.from, other.from + other.length));
                    <span class="keyword">for</span> (StyledSection section : other.sections) {
                        <span class="type">int</span> index = result.length + section.startIndex - other.from;
                        result.sections.add(section.withStartIndex(index));
                    }
                    result.length = result.plain.length();
                    <span class="keyword">return</span> result;
                }

                <span class="comment">/**
                 * Copies the specified substring of this Text into the specified destination, preserving the markup.
                 * @param from start of the substring
                 * @param length length of the substring
                 * @param destination destination Text to modify
                 * @param offset indentation (padding)
                 */</span>
                <span class="directive">public</span> <span class="type">void</span> getStyledChars(<span class="type">int</span> from, <span class="type">int</span> length, Text destination, <span class="type">int</span> offset) {
                    <span class="keyword">if</span> (destination.length &lt; offset) {
                        <span class="keyword">for</span> (<span class="type">int</span> i = destination.length; i &lt; offset; i++) {
                            destination.plain.append(<span class="string"><span class="delimiter">'</span><span class="content"> </span><span class="delimiter">'</span></span>);
                        }
                        destination.length = offset;
                    }
                    <span class="keyword">for</span> (StyledSection section : sections) {
                        destination.sections.add(section.withStartIndex(section.startIndex - from + destination.length));
                    }
                    destination.plain.append(plain.toString().substring(from, from + length));
                    destination.length = destination.plain.length();
                }
                <span class="comment">/** Returns the plain text without any formatting.
                 * @return the plain text without any formatting */</span>
                <span class="directive">public</span> <span class="predefined-type">String</span> plainString() {  <span class="keyword">return</span> plain.toString().substring(from, from + length); }

                <span class="directive">public</span> <span class="type">boolean</span> equals(<span class="predefined-type">Object</span> obj) { <span class="keyword">return</span> toString().equals(<span class="predefined-type">String</span>.valueOf(obj)); }
                <span class="directive">public</span> <span class="type">int</span> hashCode() { <span class="keyword">return</span> toString().hashCode(); }

                <span class="comment">/** Returns a String representation of the text with ANSI escape codes embedded, unless ANSI is
                 * {@linkplain Ansi#enabled()} not enabled}, in which case the plain text is returned.
                 * @return a String representation of the text with ANSI escape codes embedded (if enabled) */</span>
                <span class="directive">public</span> <span class="predefined-type">String</span> toString() {
                    <span class="keyword">if</span> (!Ansi.this.enabled()) {
                        <span class="keyword">return</span> plain.toString().substring(from, from + length);
                    }
                    <span class="keyword">if</span> (length == <span class="integer">0</span>) { <span class="keyword">return</span> <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>; }
                    <span class="predefined-type">StringBuilder</span> sb = <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>(plain.length() + <span class="integer">20</span> * sections.size());
                    StyledSection current = <span class="predefined-constant">null</span>;
                    <span class="type">int</span> end = <span class="predefined-type">Math</span>.min(from + length, plain.length());
                    <span class="keyword">for</span> (<span class="type">int</span> i = from; i &lt; end; i++) {
                        StyledSection section = findSectionContaining(i);
                        <span class="keyword">if</span> (section != current) {
                            <span class="keyword">if</span> (current != <span class="predefined-constant">null</span>) { sb.append(current.endStyles); }
                            <span class="keyword">if</span> (section != <span class="predefined-constant">null</span>) { sb.append(section.startStyles); }
                            current = section;
                        }
                        sb.append(plain.charAt(i));
                    }
                    <span class="keyword">if</span> (current != <span class="predefined-constant">null</span>) { sb.append(current.endStyles); }
                    <span class="keyword">return</span> sb.toString();
                }

                <span class="directive">private</span> StyledSection findSectionContaining(<span class="type">int</span> index) {
                    <span class="keyword">for</span> (StyledSection section : sections) {
                        <span class="keyword">if</span> (index &gt;= section.startIndex &amp;&amp; index &lt; section.startIndex + section.length) {
                            <span class="keyword">return</span> section;
                        }
                    }
                    <span class="keyword">return</span> <span class="predefined-constant">null</span>;
                }
            }
        }
    }

    <span class="comment">/**
     * Utility class providing some defensive coding convenience methods.
     */</span>
    <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="type">class</span> <span class="class">Assert</span> {
        <span class="comment">/**
         * Throws a NullPointerException if the specified object is null.
         * @param object the object to verify
         * @param description error message
         * @param &lt;T&gt; type of the object to check
         * @return the verified object
         */</span>
        <span class="directive">static</span> &lt;T&gt; T notNull(T object, <span class="predefined-type">String</span> description) {
            <span class="keyword">if</span> (object == <span class="predefined-constant">null</span>) {
                <span class="keyword">throw</span> <span class="keyword">new</span> <span class="exception">NullPointerException</span>(description);
            }
            <span class="keyword">return</span> object;
        }
        <span class="directive">private</span> Assert() {} <span class="comment">// private constructor: never instantiate</span>
    }
    <span class="directive">private</span> <span class="type">enum</span> TraceLevel { OFF, WARN, INFO, DEBUG;
        <span class="directive">public</span> <span class="type">boolean</span> isEnabled(TraceLevel other) { <span class="keyword">return</span> ordinal() &gt;= other.ordinal(); }
        <span class="directive">private</span> <span class="type">void</span> print(Tracer tracer, <span class="predefined-type">String</span> msg, <span class="predefined-type">Object</span>... params) {
            <span class="keyword">if</span> (tracer.level.isEnabled(<span class="local-variable">this</span>)) { tracer.stream.printf(prefix(msg), params); }
        }
        <span class="directive">private</span> <span class="predefined-type">String</span> prefix(<span class="predefined-type">String</span> msg) { <span class="keyword">return</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">[picocli </span><span class="delimiter">&quot;</span></span> + <span class="local-variable">this</span> + <span class="string"><span class="delimiter">&quot;</span><span class="content">] </span><span class="delimiter">&quot;</span></span> + msg; }
        <span class="directive">static</span> TraceLevel lookup(<span class="predefined-type">String</span> key) { <span class="keyword">return</span> key == <span class="predefined-constant">null</span> ? WARN : empty(key) || <span class="string"><span class="delimiter">&quot;</span><span class="content">true</span><span class="delimiter">&quot;</span></span>.equalsIgnoreCase(key) ? INFO : valueOf(key); }
    }
    <span class="directive">private</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">Tracer</span> {
        TraceLevel level = TraceLevel.lookup(<span class="predefined-type">System</span>.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">picocli.trace</span><span class="delimiter">&quot;</span></span>));
        <span class="predefined-type">PrintStream</span> stream = <span class="predefined-type">System</span>.err;
        <span class="type">void</span> warn (<span class="predefined-type">String</span> msg, <span class="predefined-type">Object</span>... params) { TraceLevel.WARN.print(<span class="local-variable">this</span>, msg, params); }
        <span class="type">void</span> info (<span class="predefined-type">String</span> msg, <span class="predefined-type">Object</span>... params) { TraceLevel.INFO.print(<span class="local-variable">this</span>, msg, params); }
        <span class="type">void</span> debug(<span class="predefined-type">String</span> msg, <span class="predefined-type">Object</span>... params) { TraceLevel.DEBUG.print(<span class="local-variable">this</span>, msg, params); }
        <span class="type">boolean</span> isWarn()  { <span class="keyword">return</span> level.isEnabled(TraceLevel.WARN); }
        <span class="type">boolean</span> isInfo()  { <span class="keyword">return</span> level.isEnabled(TraceLevel.INFO); }
        <span class="type">boolean</span> isDebug() { <span class="keyword">return</span> level.isEnabled(TraceLevel.DEBUG); }
    }
    <span class="comment">/** Base class of all exceptions thrown by {@code picocli.CommandLine}.
     * @since 2.0 */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">PicocliException</span> <span class="directive">extends</span> <span class="exception">RuntimeException</span> {
        <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="type">long</span> serialVersionUID = -<span class="integer">2574128880125050818L</span>;
        <span class="directive">public</span> PicocliException(<span class="predefined-type">String</span> msg) { <span class="local-variable">super</span>(msg); }
        <span class="directive">public</span> PicocliException(<span class="predefined-type">String</span> msg, <span class="exception">Exception</span> ex) { <span class="local-variable">super</span>(msg, ex); }
    }
    <span class="comment">/** Exception indicating a problem during {@code CommandLine} initialization.
     * @since 2.0 */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">InitializationException</span> <span class="directive">extends</span> PicocliException {
        <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="type">long</span> serialVersionUID = <span class="integer">8423014001666638895L</span>;
        <span class="directive">public</span> InitializationException(<span class="predefined-type">String</span> msg) { <span class="local-variable">super</span>(msg); }
        <span class="directive">public</span> InitializationException(<span class="predefined-type">String</span> msg, <span class="exception">Exception</span> ex) { <span class="local-variable">super</span>(msg, ex); }
    }
    <span class="comment">/** Exception indicating a problem while invoking a command or subcommand.
     * @since 2.0 */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">ExecutionException</span> <span class="directive">extends</span> PicocliException {
        <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="type">long</span> serialVersionUID = <span class="integer">7764539594267007998L</span>;
        <span class="directive">private</span> <span class="directive">final</span> CommandLine commandLine;
        <span class="directive">public</span> <span class="exception">ExecutionException</span>(CommandLine commandLine, <span class="predefined-type">String</span> msg) {
            <span class="local-variable">super</span>(msg);
            <span class="local-variable">this</span>.commandLine = Assert.notNull(commandLine, <span class="string"><span class="delimiter">&quot;</span><span class="content">commandLine</span><span class="delimiter">&quot;</span></span>);
        }
        <span class="directive">public</span> <span class="exception">ExecutionException</span>(CommandLine commandLine, <span class="predefined-type">String</span> msg, <span class="exception">Exception</span> ex) {
            <span class="local-variable">super</span>(msg, ex);
            <span class="local-variable">this</span>.commandLine = Assert.notNull(commandLine, <span class="string"><span class="delimiter">&quot;</span><span class="content">commandLine</span><span class="delimiter">&quot;</span></span>);
        }
        <span class="comment">/** Returns the {@code CommandLine} object for the (sub)command that could not be invoked.
         * @return the {@code CommandLine} object for the (sub)command where invocation failed.
         */</span>
        <span class="directive">public</span> CommandLine getCommandLine() { <span class="keyword">return</span> commandLine; }
    }

    <span class="comment">/** Exception thrown by {@link ITypeConverter} implementations to indicate a String could not be converted. */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">TypeConversionException</span> <span class="directive">extends</span> PicocliException {
        <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="type">long</span> serialVersionUID = <span class="integer">4251973913816346114L</span>;
        <span class="directive">public</span> TypeConversionException(<span class="predefined-type">String</span> msg) { <span class="local-variable">super</span>(msg); }
    }
    <span class="comment">/** Exception indicating something went wrong while parsing command line options. */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">ParameterException</span> <span class="directive">extends</span> PicocliException {
        <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="type">long</span> serialVersionUID = <span class="integer">1477112829129763139L</span>;
        <span class="directive">private</span> <span class="directive">final</span> CommandLine commandLine;

        <span class="comment">/** Constructs a new ParameterException with the specified CommandLine and error message.
         * @param commandLine the command or subcommand whose input was invalid
         * @param msg describes the problem
         * @since 2.0 */</span>
        <span class="directive">public</span> ParameterException(CommandLine commandLine, <span class="predefined-type">String</span> msg) {
            <span class="local-variable">super</span>(msg);
            <span class="local-variable">this</span>.commandLine = Assert.notNull(commandLine, <span class="string"><span class="delimiter">&quot;</span><span class="content">commandLine</span><span class="delimiter">&quot;</span></span>);
        }
        <span class="comment">/** Constructs a new ParameterException with the specified CommandLine and error message.
         * @param commandLine the command or subcommand whose input was invalid
         * @param msg describes the problem
         * @param ex the exception that caused this ParameterException
         * @since 2.0 */</span>
        <span class="directive">public</span> ParameterException(CommandLine commandLine, <span class="predefined-type">String</span> msg, <span class="exception">Exception</span> ex) {
            <span class="local-variable">super</span>(msg, ex);
            <span class="local-variable">this</span>.commandLine = Assert.notNull(commandLine, <span class="string"><span class="delimiter">&quot;</span><span class="content">commandLine</span><span class="delimiter">&quot;</span></span>);
        }

        <span class="comment">/** Returns the {@code CommandLine} object for the (sub)command whose input could not be parsed.
         * @return the {@code CommandLine} object for the (sub)command where parsing failed.
         * @since 2.0
         */</span>
        <span class="directive">public</span> CommandLine getCommandLine() { <span class="keyword">return</span> commandLine; }

        <span class="directive">private</span> <span class="directive">static</span> ParameterException create(CommandLine cmd, <span class="exception">Exception</span> ex, <span class="predefined-type">String</span> arg, <span class="type">int</span> i, <span class="predefined-type">String</span><span class="type">[]</span> args) {
            <span class="predefined-type">String</span> msg = ex.getClass().getSimpleName() + <span class="string"><span class="delimiter">&quot;</span><span class="content">: </span><span class="delimiter">&quot;</span></span> + ex.getLocalizedMessage()
                    + <span class="string"><span class="delimiter">&quot;</span><span class="content"> while processing argument at or before arg[</span><span class="delimiter">&quot;</span></span> + i + <span class="string"><span class="delimiter">&quot;</span><span class="content">] '</span><span class="delimiter">&quot;</span></span> + arg + <span class="string"><span class="delimiter">&quot;</span><span class="content">' in </span><span class="delimiter">&quot;</span></span> + <span class="predefined-type">Arrays</span>.toString(args) + <span class="string"><span class="delimiter">&quot;</span><span class="content">: </span><span class="delimiter">&quot;</span></span> + ex.toString();
            <span class="keyword">return</span> <span class="keyword">new</span> ParameterException(cmd, msg, ex);
        }
    }
    <span class="comment">/**
     * Exception indicating that a required parameter was not specified.
     */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">MissingParameterException</span> <span class="directive">extends</span> ParameterException {
        <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="type">long</span> serialVersionUID = <span class="integer">5075678535706338753L</span>;
        <span class="directive">public</span> MissingParameterException(CommandLine commandLine, <span class="predefined-type">String</span> msg) {
            <span class="local-variable">super</span>(commandLine, msg);
        }

        <span class="directive">private</span> <span class="directive">static</span> MissingParameterException create(CommandLine cmd, <span class="predefined-type">Collection</span>&lt;<span class="predefined-type">Field</span>&gt; missing, <span class="predefined-type">String</span> separator) {
            <span class="keyword">if</span> (missing.size() == <span class="integer">1</span>) {
                <span class="keyword">return</span> <span class="keyword">new</span> MissingParameterException(cmd, <span class="string"><span class="delimiter">&quot;</span><span class="content">Missing required option '</span><span class="delimiter">&quot;</span></span>
                        + describe(missing.iterator().next(), separator) + <span class="string"><span class="delimiter">&quot;</span><span class="content">'</span><span class="delimiter">&quot;</span></span>);
            }
            <span class="predefined-type">List</span>&lt;<span class="predefined-type">String</span>&gt; names = <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">String</span>&gt;(missing.size());
            <span class="keyword">for</span> (<span class="predefined-type">Field</span> field : missing) {
                names.add(describe(field, separator));
            }
            <span class="keyword">return</span> <span class="keyword">new</span> MissingParameterException(cmd, <span class="string"><span class="delimiter">&quot;</span><span class="content">Missing required options </span><span class="delimiter">&quot;</span></span> + names.toString());
        }
        <span class="directive">private</span> <span class="directive">static</span> <span class="predefined-type">String</span> describe(<span class="predefined-type">Field</span> field, <span class="predefined-type">String</span> separator) {
            <span class="predefined-type">String</span> prefix = (field.isAnnotationPresent(<span class="predefined-type">Option</span>.class))
                ? field.getAnnotation(<span class="predefined-type">Option</span>.class).names()[<span class="integer">0</span>] + separator
                : <span class="string"><span class="delimiter">&quot;</span><span class="content">params[</span><span class="delimiter">&quot;</span></span> + field.getAnnotation(Parameters.class).index() + <span class="string"><span class="delimiter">&quot;</span><span class="content">]</span><span class="delimiter">&quot;</span></span> + separator;
            <span class="keyword">return</span> prefix + Help.DefaultParamLabelRenderer.renderParameterName(field);
        }
    }

    <span class="comment">/**
     * Exception indicating that multiple fields have been annotated with the same Option name.
     */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">DuplicateOptionAnnotationsException</span> <span class="directive">extends</span> InitializationException {
        <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="type">long</span> serialVersionUID = -<span class="integer">3355128012575075641L</span>;
        <span class="directive">public</span> DuplicateOptionAnnotationsException(<span class="predefined-type">String</span> msg) { <span class="local-variable">super</span>(msg); }

        <span class="directive">private</span> <span class="directive">static</span> DuplicateOptionAnnotationsException create(<span class="predefined-type">String</span> name, <span class="predefined-type">Field</span> field1, <span class="predefined-type">Field</span> field2) {
            <span class="keyword">return</span> <span class="keyword">new</span> DuplicateOptionAnnotationsException(<span class="string"><span class="delimiter">&quot;</span><span class="content">Option name '</span><span class="delimiter">&quot;</span></span> + name + <span class="string"><span class="delimiter">&quot;</span><span class="content">' is used by both </span><span class="delimiter">&quot;</span></span> +
                    field1.getDeclaringClass().getName() + <span class="string"><span class="delimiter">&quot;</span><span class="content">.</span><span class="delimiter">&quot;</span></span> + field1.getName() + <span class="string"><span class="delimiter">&quot;</span><span class="content"> and </span><span class="delimiter">&quot;</span></span> +
                    field2.getDeclaringClass().getName() + <span class="string"><span class="delimiter">&quot;</span><span class="content">.</span><span class="delimiter">&quot;</span></span> + field2.getName());
        }
    }
    <span class="comment">/** Exception indicating that there was a gap in the indices of the fields annotated with {@link Parameters}. */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">ParameterIndexGapException</span> <span class="directive">extends</span> InitializationException {
        <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="type">long</span> serialVersionUID = -<span class="integer">1520981133257618319L</span>;
        <span class="directive">public</span> ParameterIndexGapException(<span class="predefined-type">String</span> msg) { <span class="local-variable">super</span>(msg); }
    }
    <span class="comment">/** Exception indicating that a command line argument could not be mapped to any of the fields annotated with
     * {@link Option} or {@link Parameters}. */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">UnmatchedArgumentException</span> <span class="directive">extends</span> ParameterException {
        <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="type">long</span> serialVersionUID = -<span class="integer">8700426380701452440L</span>;
        <span class="directive">public</span> UnmatchedArgumentException(CommandLine commandLine, <span class="predefined-type">String</span> msg) { <span class="local-variable">super</span>(commandLine, msg); }
        <span class="directive">public</span> UnmatchedArgumentException(CommandLine commandLine, <span class="predefined-type">Stack</span>&lt;<span class="predefined-type">String</span>&gt; args) { <span class="local-variable">this</span>(commandLine, <span class="keyword">new</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">String</span>&gt;(reverse(args))); }
        <span class="directive">public</span> UnmatchedArgumentException(CommandLine commandLine, <span class="predefined-type">List</span>&lt;<span class="predefined-type">String</span>&gt; args) { <span class="local-variable">this</span>(commandLine, <span class="string"><span class="delimiter">&quot;</span><span class="content">Unmatched argument</span><span class="delimiter">&quot;</span></span> + (args.size() == <span class="integer">1</span> ? <span class="string"><span class="delimiter">&quot;</span><span class="content"> </span><span class="delimiter">&quot;</span></span> : <span class="string"><span class="delimiter">&quot;</span><span class="content">s </span><span class="delimiter">&quot;</span></span>) + args); }
    }
    <span class="comment">/** Exception indicating that more values were specified for an option or parameter than its {@link Option#arity() arity} allows. */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">MaxValuesforFieldExceededException</span> <span class="directive">extends</span> ParameterException {
        <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="type">long</span> serialVersionUID = <span class="integer">6536145439570100641L</span>;
        <span class="directive">public</span> MaxValuesforFieldExceededException(CommandLine commandLine, <span class="predefined-type">String</span> msg) { <span class="local-variable">super</span>(commandLine, msg); }
    }
    <span class="comment">/** Exception indicating that an option for a single-value option field has been specified multiple times on the command line. */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">OverwrittenOptionException</span> <span class="directive">extends</span> ParameterException {
        <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="type">long</span> serialVersionUID = <span class="integer">1338029208271055776L</span>;
        <span class="directive">public</span> OverwrittenOptionException(CommandLine commandLine, <span class="predefined-type">String</span> msg) { <span class="local-variable">super</span>(commandLine, msg); }
    }
    <span class="comment">/**
     * Exception indicating that an annotated field had a type for which no {@link ITypeConverter} was
     * {@linkplain #registerConverter(Class, ITypeConverter) registered}.
     */</span>
    <span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">MissingTypeConverterException</span> <span class="directive">extends</span> ParameterException {
        <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="type">long</span> serialVersionUID = -<span class="integer">6050931703233083760L</span>;
        <span class="directive">public</span> MissingTypeConverterException(CommandLine commandLine, <span class="predefined-type">String</span> msg) { <span class="local-variable">super</span>(commandLine, msg); }
    }
}</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Version 2.3.0<br>
Last updated 2018-02-13 20:00:09 JST
</div>
</div>
</body>
</html>