protected void iteratePortlets(
      TreeNodeView parentNodeView,
      PortletCategory portletCategory,
      Set<String> portletIds,
      int parentNodeId,
      int depth) {

    List<Portlet> portlets = new ArrayList<>();

    String externalPortletCategory = null;

    for (String portletId : portletIds) {
      Portlet portlet = PortletLocalServiceUtil.getPortletById(_user.getCompanyId(), portletId);

      if (portlet != null) {
        if (portlet.isSystem()) {
        } else if (!portlet.isActive()) {
        } else if (portlet.isInstanceable() && !_includeInstanceablePortlets) {
        } else if (!portlet.isInstanceable()
            && _layoutTypePortlet.hasPortletId(portlet.getPortletId())) {

          portlets.add(portlet);
        } else if (!portlet.hasAddPortletPermission(_user.getUserId())) {
        } else {
          portlets.add(portlet);
        }

        PortletApp portletApp = portlet.getPortletApp();

        if (portletApp.isWARFile() && Validator.isNull(externalPortletCategory)) {

          PortletConfig portletConfig = PortletConfigFactoryUtil.create(portlet, _servletContext);

          ResourceBundle resourceBundle = portletConfig.getResourceBundle(getLocale());

          externalPortletCategory =
              ResourceBundleUtil.getString(resourceBundle, portletCategory.getName());
        }
      }
    }

    portlets = ListUtil.sort(portlets, new PortletTitleComparator(getLocale()));

    for (int i = 0; i < portlets.size(); i++) {
      Portlet portlet = portlets.get(i);

      TreeNodeView nodeView = new TreeNodeView(++_nodeId);

      nodeView.setDepth(depth);
      nodeView.setLeaf(true);

      if ((i + 1) == portlets.size()) {
        nodeView.setLs("1");
      } else {
        nodeView.setLs("0");
      }

      nodeView.setName(PortalUtil.getPortletTitle(portlet, _servletContext, getLocale()));
      nodeView.setObjId(portlet.getRootPortletId());
      nodeView.setParentId(parentNodeId);

      if (_hierarchicalTree) {
        parentNodeView.addChild(nodeView);
      } else {
        _list.add(nodeView);
      }
    }
  }
  protected void iteratePortletCategories(
      TreeNodeView parentNodeView,
      List<PortletCategory> portletCategories,
      long parentId,
      int depth)
      throws PortalException {

    portletCategories =
        ListUtil.sort(portletCategories, new PortletCategoryComparator(getLocale()));

    for (int i = 0; i < portletCategories.size(); i++) {
      PortletCategory portletCategory = portletCategories.get(i);

      if (portletCategory.isHidden()) {
        continue;
      }

      if (i == 0) {
        depth++;

        if (depth > _depth) {
          _depth = depth;
        }
      }

      TreeNodeView nodeView = new TreeNodeView(++_nodeId);

      nodeView.setDepth(depth);
      nodeView.setLeaf(false);

      if ((i + 1) == portletCategories.size()) {
        nodeView.setLs("1");
      } else {
        nodeView.setLs("0");
      }

      nodeView.setName(LanguageUtil.get(getLocale(), portletCategory.getName()));
      nodeView.setObjId(portletCategory.getPath());
      nodeView.setParentId(parentId);

      if (_hierarchicalTree) {
        if (parentNodeView != null) {
          parentNodeView.addChild(nodeView);
        }
      } else {
        _list.add(nodeView);
      }

      int nodeId = _nodeId;

      List<PortletCategory> subCategories =
          ListUtil.fromCollection(portletCategory.getCategories());

      iteratePortletCategories(nodeView, subCategories, nodeId, depth);

      if (_iteratePortlets) {
        iteratePortlets(
            nodeView, portletCategory, portletCategory.getPortletIds(), nodeId, depth + 1);
      }
    }
  }