docs: public final void setArgs(String... args) throws CmdArgsException
      {
          try
          {
              options = new HashMap<>();
              Option opt = null;
              int index = 0;
              for (String arg : args)
              {
                  if (opt != null)
                  {
                      options.put(opt.name, ConvertUtility.convert(opt.cls, arg));
                      opt = null;
                  }
                  else
                  {
                      if (map.containsKey(arg))
                      {
                          opt = map.get(arg);
                          if (opt.exclusiveGroup != null)
                          {
                              if (effectiveGroup != null && !effectiveGroup.equals(opt.exclusiveGroup))
                              {
                                  throw new CmdArgsException(opt.exclusiveGroup+" mix with "+effectiveGroup, this);
                              }
                              effectiveGroup = opt.exclusiveGroup;
                          }
                      }
                      else
                      {
                          break;
                      }
                  }
                  index++;
              }
              // defaults
              for (Option o : map.values())
              {
                  if (!o.mandatory && !options.containsKey(o.name))
                  {
                      options.put(o.name, o.defValue);
                  }
              }
              int len = args.length-index;
              if (hasArrayArgument)
              {
                  if (len < types.size())
                  {
                      throw new CmdArgsException("too few arguments", this);
                  }
              }
              else
              {
                  if (len != types.size())
                  {
                      throw new CmdArgsException("wrong number of arguments", this);
                  }
              }
              arguments = new HashMap<>();
              int arraySize = len - types.size() + 1;
              int arrayIndex = Integer.MAX_VALUE;
              Object array = null;
              Class<?> componenType = null;
              if (hasArrayArgument)
              {
                  arrayIndex = types.size()-1;
                  Class<?> arrayType = types.get(arrayIndex);
                  componenType = arrayType.getComponentType();
                  array = Array.newInstance(componenType, arraySize);
                  arguments.put(names.get(arrayIndex), array);
              }
              for (int ii=0;ii<len;ii++)
              {
                  if (ii < arrayIndex)
                  {
                      Object value = ConvertUtility.convert(types.get(ii), args[ii+index]);
                      arguments.put(names.get(ii), value);
                  }
                  else
                  {
                      Object value = ConvertUtility.convert(componenType, args[ii+index]);
                      Array.set(array, ii - arrayIndex, value);
                  }
              }
              for (Option o : map.values())
              {
                  if (o.mandatory && !options.containsKey(o.name))
                  {
                      throw new CmdArgsException("mandatory option "+o.name+": "+o.description+" missing", this);
                  }
              }
              if (effectiveGroup != null)
              {
                  for (Option o : groups.get(effectiveGroup))
                  {
                      if (o.mandatory && !options.containsKey(o.name))
                      {
                          throw new CmdArgsException(effectiveGroup+" option "+o.name+": "+o.description+" missing", this);
                      }
                  }
              }
          }
          catch (Exception ex)
          {
              throw new CmdArgsException(ex, this);
          }
      }