/** Find all children for all known menu components. Populates {@link #uriToMenuElement}. */
 protected void findChildren() {
   for (MenuComponent menuElement : menuComponents) {
     uriToMenuElement.put(menuElement.getId(), menuElement);
     logger.debug("Found menu element " + menuElement.getId() + " " + menuElement);
     if (menuElement.getParentId() == null) continue;
     List<MenuComponent> siblings = menuElementTree.get(menuElement.getParentId());
     if (siblings == null) {
       siblings = new ArrayList<>();
       synchronized (menuElementTree) {
         menuElementTree.put(menuElement.getParentId(), siblings);
       }
     }
     siblings.add(menuElement);
   }
   //		if (uriToMenuElement.isEmpty()) {
   //			logger.error("No menu elements found, check classpath/Raven/SPI");
   //		}
 }
  /**
   * Add a {@link JMenu} to the list of components as described by the menu component. If there are
   * no children, the menu is not added.
   *
   * @param components List of components where to add the created {@link JMenu}
   * @param menuComponent The {@link MenuComponent} definition for this menu
   * @param isToolbar True if the list of components is to be added to a toolbar
   */
  private void addMenu(
      List<Component> components, MenuComponent menuComponent, MenuOptions menuOptions) {
    URI menuId = menuComponent.getId();
    if (menuOptions.isToolbar()) {
      logger.warn("Can't have menu " + menuComponent + " within toolBar element");
      return;
    }
    MenuOptions childOptions = new MenuOptions(menuOptions);
    List<Component> subComponents = makeComponents(menuId, childOptions);
    if (subComponents.isEmpty()) {
      logger.warn("No sub components found for menu " + menuId);
      return;
    }

    JMenu menu = new JMenu(menuComponent.getAction());
    for (Component menuItem : subComponents)
      if (menuItem == null) menu.addSeparator();
      else menu.add(menuItem);
    registerComponent(menuId, menu);
    components.add(menu);
  }
  /**
   * Make the list of Swing {@link Component}s that are the children of the given {@link URI}.
   *
   * @param id The {@link URI} of the parent which children are to be made
   * @param menuOptions Options of the created menu, for instance {@link MenuOptions#isToolbar()}.
   * @return A {@link List} of {@link Component}s that can be added to a {@link JMenuBar}, {@link
   *     JMenu} or {@link JToolBar}.
   */
  protected List<Component> makeComponents(URI id, MenuOptions menuOptions) {
    List<Component> components = new ArrayList<>();
    for (MenuComponent childElement : getChildren(id)) {
      if (childElement instanceof ContextualMenuComponent)
        ((ContextualMenuComponent) childElement)
            .setContextualSelection(menuOptions.getContextualSelection());
      /*
       * Important - check this AFTER setContextualSelection so the item
       * can change it's enabled-state if needed.
       */
      if (!childElement.isEnabled()) continue;
      MenuType type = childElement.getType();
      Action action = childElement.getAction();
      URI childId = childElement.getId();
      if (type.equals(MenuType.action)) {
        if (action == null) {
          logger.warn("Skipping invalid action " + childId + " for " + id);
          continue;
        }

        Component actionComponent;
        if (menuOptions.isOptionGroup()) {
          if (menuOptions.isToolbar()) {
            actionComponent = new JToggleButton(action);
            toolbarizeButton((AbstractButton) actionComponent);
          } else actionComponent = new JRadioButtonMenuItem(action);
        } else {
          if (menuOptions.isToolbar()) {
            actionComponent = new JButton(action);
            toolbarizeButton((AbstractButton) actionComponent);
          } else actionComponent = new JMenuItem(action);
        }
        registerComponent(childId, actionComponent);
        components.add(actionComponent);
      } else if (type.equals(MenuType.toggle)) {
        if (action == null) {
          logger.warn("Skipping invalid toggle " + childId + " for " + id);
          continue;
        }
        Component toggleComponent;
        if (menuOptions.isToolbar()) toggleComponent = new JToggleButton(action);
        else toggleComponent = new JCheckBoxMenuItem(action);
        registerComponent(childId, toggleComponent);
        components.add(toggleComponent);
      } else if (type.equals(MenuType.custom)) {
        Component customComponent = childElement.getCustomComponent();
        if (customComponent == null) {
          logger.warn("Skipping null custom component " + childId + " for " + id);
          continue;
        }
        registerComponent(childId, customComponent);
        components.add(customComponent);
      } else if (type.equals(MenuType.optionGroup))
        addOptionGroup(components, childId, menuOptions);
      else if (type.equals(MenuType.section)) addSection(components, childId, menuOptions);
      else if (type.equals(MenuType.menu)) addMenu(components, childElement, menuOptions);
      else {
        logger.warn("Skipping invalid/unknown type " + type + " for " + id);
        continue;
      }
    }
    stripTrailingNullSeparator(components);
    return components;
  }