@VisibleForTesting
    static List<Tuple2<ConfigGroup, String>> generateTablesForClass(
            Class<?> optionsClass, Collection<OptionWithMetaInfo> optionWithMetaInfos) {
        ConfigGroups configGroups = optionsClass.getAnnotation(ConfigGroups.class);
        List<OptionWithMetaInfo> allOptions = selectOptionsToDocument(optionWithMetaInfos);

        if (allOptions.isEmpty()) {
            return Collections.emptyList();
        }

        List<Tuple2<ConfigGroup, String>> tables;
        if (configGroups != null) {
            tables = new ArrayList<>(configGroups.groups().length + 1);
            Tree tree = new Tree(configGroups.groups(), allOptions);

            for (ConfigGroup group : configGroups.groups()) {
                List<OptionWithMetaInfo> configOptions = tree.findConfigOptions(group);
                if (!configOptions.isEmpty()) {
                    sortOptions(configOptions);
                    tables.add(Tuple2.of(group, toHtmlTable(configOptions)));
                }
            }
            List<OptionWithMetaInfo> configOptions = tree.getDefaultOptions();
            if (!configOptions.isEmpty()) {
                sortOptions(configOptions);
                tables.add(Tuple2.of(null, toHtmlTable(configOptions)));
            }
        } else {
            sortOptions(allOptions);
            tables = Collections.singletonList(Tuple2.of(null, toHtmlTable(allOptions)));
        }
        return tables;
    }
@Test
    void testCreatingTypes() {
        final String expectedTable =
                "<table class=\"configuration table table-bordered\">\n"
                        + "    <thead>\n"
                        + "        <tr>\n"
                        + "            <th class=\"text-left\" style=\"width: 20%\">Key</th>\n"
                        + "            <th class=\"text-left\" style=\"width: 15%\">Default</th>\n"
                        + "            <th class=\"text-left\" style=\"width: 10%\">Type</th>\n"
                        + "            <th class=\"text-left\" style=\"width: 55%\">Description</th>\n"
                        + "        </tr>\n"
                        + "    </thead>\n"
                        + "    <tbody>\n"
                        + "        <tr>\n"
                        + "            <td><h5>option.duration</h5></td>\n"
                        + "            <td style=\"word-wrap: break-word;\">1 min</td>\n"
                        + "            <td>Duration</td>\n"
                        + "            <td>Description</td>\n"
                        + "        </tr>\n"
                        + "        <tr>\n"
                        + "            <td><h5>option.enum</h5></td>\n"
                        + "            <td style=\"word-wrap: break-word;\">VALUE_1</td>\n"
                        + "            <td><p>Enum</p></td>\n"
                        + "            <td>Description<br /><br />Possible values:<ul><li>\"VALUE_1\"</li><li>\"VALUE_2\"</li><li>\"VALUE_3\"</li></ul></td>\n"
                        + "        </tr>\n"
                        + "        <tr>\n"
                        + "            <td><h5>option.enum.described</h5></td>\n"
                        + "            <td style=\"word-wrap: break-word;\">(none)</td>\n"
                        + "            <td><p>Enum</p></td>\n"
                        + "            <td>Description<br /><br />Possible values:<ul><li>\"A\": First letter of the alphabet</li><li>\"B\": Second letter of the alphabet</li></ul></td>\n"
                        + "        </tr>\n"
                        + "        <tr>\n"
                        + "            <td><h5>option.enum.list</h5></td>\n"
                        + "            <td style=\"word-wrap: break-word;\">VALUE_1;<wbr>VALUE_2</td>\n"
                        + "            <td><p>List&lt;Enum&gt;</p></td>\n"
                        + "            <td>Description<br /><br />Possible values:<ul><li>\"VALUE_1\"</li><li>\"VALUE_2\"</li><li>\"VALUE_3\"</li></ul></td>\n"
                        + "        </tr>\n"
                        + "        <tr>\n"
                        + "            <td><h5>option.map</h5></td>\n"
                        + "            <td style=\"word-wrap: break-word;\">key1:value1</td>\n"
                        + "            <td>Map</td>\n"
                        + "            <td>Description</td>\n"
                        + "        </tr>\n"
                        + "        <tr>\n"
                        + "            <td><h5>option.map.list</h5></td>\n"
                        + "            <td style=\"word-wrap: break-word;\">key1:value1;<wbr>key2:value2</td>\n"
                        + "            <td>List&lt;Map&gt;</td>\n"
                        + "            <td>Description</td>\n"
                        + "        </tr>\n"
                        + "        <tr>\n"
                        + "            <td><h5>option.memory</h5></td>\n"
                        + "            <td style=\"word-wrap: break-word;\">1 kb</td>\n"
                        + "            <td>MemorySize</td>\n"
                        + "            <td>Description</td>\n"
                        + "        </tr>\n"
                        + "    </tbody>\n"
                        + "</table>\n";
        final String htmlTable =
                ConfigOptionsDocGenerator.generateTablesForClass(
                                TypeTestConfigGroup.class,
                                ConfigurationOptionLocator.extractConfigOptions(
                                        TypeTestConfigGroup.class))
                        .get(0)
                        .f1;

        assertThat(htmlTable).isEqualTo(expectedTable);
    }