docs: private static Object fillBean(final OptionVisitor visitor, final Type type, final Object bean, final List<ParameterMetadata> metadatas) {
          if (!Class.class.isInstance(type)) { // can't do anything
              return null;
          }
  
          List<Object> constructorParam = bean == null ? new ArrayList<>() : null;
          try {
              final Constructor constructor = Class.class.cast(type).getConstructors()[0];
              final BeanInfo descriptor = Introspector.getBeanInfo(Class.class.cast(type));
              final Map<String, PropertyDescriptor> descriptorMap = new HashMap<>();
              for (final PropertyDescriptor d : descriptor.getPropertyDescriptors()) {
                  descriptorMap.put(d.getName(), d);
              }
              Object value = bean;
              int consIdx = -1;
              for (final ParameterMetadata metadata : metadatas) {
                  consIdx++;
                  if (metadata.getType() != ParameterMetadata.ParamType.OPTION) { // we support only 1 level for now
                      continue;
                  }
  
  
                  final String name = metadata.getName().substring(metadata.getName().lastIndexOf('.') + 1);
                  if (!descriptorMap.containsKey(name)) {
                      continue;
                  }
  
                  final PropertyDescriptor propertyDescriptor = descriptorMap.get(name);
                  if (propertyDescriptor == null) {
                      continue;
                  }
  
                  if (bean != null) { // check it is not already set
                      final Method readMethod = propertyDescriptor.getReadMethod();
                      if (readMethod == null) {
                          continue;
                      }
                      try {
                          final Object val = readMethod.invoke(bean);
                          if (val != null) {
                              continue;
                          }
                      } catch (final IllegalAccessException e) {
                          throw new IllegalStateException(e);
                      } catch (InvocationTargetException e) {
                          throw new IllegalStateException(e.getCause());
                      }
                  }
  
                  final Method write = propertyDescriptor.getWriteMethod();
                  if (write != null) {
                      final Object val = visitor.onOption(consIdx, metadata, new AnnotatedElementImpl(write.getParameterAnnotations()[0]));
                      if (val != null) {
                          try {
                              if (value == null) {
                                  constructorParam.add(val);
                              } else {
                                  write.invoke(value, val);
                              }
                          } catch (final IllegalAccessException e) {
                              throw new IllegalStateException(e);
                          } catch (final InvocationTargetException e) {
                              throw new IllegalStateException(e.getCause());
                          }
                      }
  
                  }
              }
              if (value == null) {
                  try {
                      value = constructor.newInstance(constructorParam.toArray(new Object[constructorParam.size()]));
                  } catch (final IllegalAccessException e) {
                      throw new IllegalStateException(e);
                  } catch (final InstantiationException e) {
                      throw new IllegalStateException(e);
                  } catch (final InvocationTargetException e) {
                      throw new IllegalStateException(e.getCause());
                  }
              }
              return value;
          } catch (final IntrospectionException e) {
              throw new IllegalStateException(e);
          }
      }