/**
  * Removes all top-level sub-menus and reassigns their children to the parent menu.
  *
  * @param menu The parent menu containing the sub-menus to collapse.
  */
 private static void collapseSubMenus(RadialMenu menu) {
   final List<RadialMenuItem> menuItems = menu.getItems(false /* includeCorners */);
   for (RadialMenuItem item : menuItems) {
     if (item.hasSubMenu()) {
       final RadialSubMenu subMenu = item.getSubMenu();
       final List<RadialMenuItem> subItems = subMenu.getItems(true /* includeCorners */);
       menu.removeItem(item.getItemId());
       menu.addAll(subItems);
     }
   }
 }
  /**
   * Populates a {@link RadialMenu} with items specific to the provided node based on {@link
   * NodeMenuRule}s.
   *
   * @param menu The menu to populate.
   * @param node The node with which to populate the menu.
   * @return {@code true} if successful, {@code false} otherwise.
   */
  public boolean prepareMenuForNode(RadialMenu menu, AccessibilityNodeInfoCompat node) {
    if (node == null) {
      return false;
    }

    // Always reset the menu since it is based on the current cursor.
    menu.clear();

    // Track which rules accept the node.
    final LinkedList<NodeMenuRule> matchingRules = new LinkedList<NodeMenuRule>();
    for (NodeMenuRule rule : mRules) {
      if (rule.accept(mService, node)) {
        matchingRules.add(rule);
      }
    }

    boolean canCollapseMenu = false;

    for (NodeMenuRule rule : matchingRules) {
      final List<RadialMenuItem> ruleResults = rule.getMenuItemsForNode(mService, node);
      if (ruleResults.isEmpty()) {
        continue;
      }

      final CharSequence subMenuName = rule.getUserFriendlyMenuName(mService);
      final RadialSubMenu ruleSubMenu =
          menu.addSubMenu(RadialMenu.NONE, 0, RadialMenu.NONE, subMenuName);
      ruleSubMenu.addAll(ruleResults);

      canCollapseMenu |= rule.canCollapseMenu();
    }

    // Collapse if the menu contains only a single collapsible sub-menu.
    if ((menu.size() == 1) && canCollapseMenu) {
      collapseSubMenus(menu);
    }

    if (menu.size() == 0) {
      mSpeechController.speak(
          mService.getString(R.string.title_local_breakout_no_items),
          SpeechController.QUEUE_MODE_FLUSH_ALL,
          FeedbackItem.FLAG_NO_HISTORY,
          null);
      return false;
    }

    return true;
  }