@Override
  public void deleteCategories(List<AssetCategory> categories) throws PortalException {

    List<Long> rebuildTreeGroupIds = new ArrayList<>();

    for (AssetCategory category : categories) {
      if (!rebuildTreeGroupIds.contains(category.getGroupId())
          && (getChildCategoriesCount(category.getCategoryId()) > 0)) {

        final long groupId = category.getGroupId();

        TransactionCommitCallbackUtil.registerCallback(
            new Callable<Void>() {

              @Override
              public Void call() throws Exception {
                assetCategoryLocalService.rebuildTree(groupId, true);

                return null;
              }
            });

        rebuildTreeGroupIds.add(groupId);
      }

      assetCategoryLocalService.deleteCategory(category, true);
    }
  }
  @Override
  public void addCategoryResources(AssetCategory category, ModelPermissions modelPermissions)
      throws PortalException {

    resourceLocalService.addModelResources(
        category.getCompanyId(), category.getGroupId(),
        category.getUserId(), AssetCategory.class.getName(),
        category.getCategoryId(), modelPermissions);
  }
  @Indexable(type = IndexableType.DELETE)
  @Override
  @SystemEvent(type = SystemEventConstants.TYPE_DELETE)
  public AssetCategory deleteCategory(AssetCategory category, boolean skipRebuildTree)
      throws PortalException {

    // Categories

    List<AssetCategory> categories =
        assetCategoryPersistence.findByParentCategoryId(category.getCategoryId());

    for (AssetCategory curCategory : categories) {
      assetCategoryLocalService.deleteCategory(curCategory, true);
    }

    if (!categories.isEmpty() && !skipRebuildTree) {
      final long groupId = category.getGroupId();

      TransactionCommitCallbackUtil.registerCallback(
          new Callable<Void>() {

            @Override
            public Void call() throws Exception {
              assetCategoryLocalService.rebuildTree(groupId, true);

              return null;
            }
          });
    }

    // Entries

    List<AssetEntry> entries = assetCategoryPersistence.getAssetEntries(category.getCategoryId());

    // Category

    assetCategoryPersistence.remove(category);

    // Resources

    resourceLocalService.deleteResource(
        category.getCompanyId(),
        AssetCategory.class.getName(),
        ResourceConstants.SCOPE_INDIVIDUAL,
        category.getCategoryId());

    // Properties

    assetCategoryPropertyLocalService.deleteCategoryProperties(category.getCategoryId());

    // Indexer

    assetEntryLocalService.reindex(entries);

    return category;
  }
  @Override
  public void addCategoryResources(
      AssetCategory category, boolean addGroupPermissions, boolean addGuestPermissions)
      throws PortalException {

    resourceLocalService.addResources(
        category.getCompanyId(),
        category.getGroupId(),
        category.getUserId(),
        AssetCategory.class.getName(),
        category.getCategoryId(),
        false,
        addGroupPermissions,
        addGuestPermissions);
  }
  private long[] _getLeftAndRightCategoryIds(long[] categoryIds) {
    long[] leftRightIds = new long[categoryIds.length * 3];

    for (int i = 0; i < categoryIds.length; i++) {
      long categoryId = categoryIds[i];

      try {
        AssetCategory category = AssetCategoryLocalServiceUtil.getCategory(categoryId);

        leftRightIds[3 * i] = category.getGroupId();
        leftRightIds[3 * i + 1] = category.getLeftCategoryId();
        leftRightIds[3 * i + 2] = category.getRightCategoryId();
      } catch (Exception e) {
        if (_log.isWarnEnabled()) {
          _log.warn("Error retrieving category " + categoryId);
        }
      }
    }

    return leftRightIds;
  }