private List<Privilege> getPrivilegesToFilter(Node node) {

    if (node instanceof JCRNodeWrapper) {
      node = ((JCRNodeWrapper) node).getRealNode();
    }

    List<Privilege> privilegeToFilterOut = new ArrayList<>();

    // jcr:modifyAccessControl permission when data source is AccessControllable, only on
    // ExternalNodeImpl
    // ExtensionNodeImpl acls can be modify
    if (aclReadOnly && node instanceof ExternalNodeImpl) {
      privilegeToFilterOut.add(modifyAccessControlPrivilege);
    }

    // all write permissions in case of the data source not writable and not extendable
    if (!writable
        && node instanceof ExternalNodeImpl
        && (session.getOverridableProperties() == null
            || session.getOverridableProperties().size() == 0)) {
      privilegeToFilterOut.add(writePrivilege);
      privilegeToFilterOut.addAll(Lists.newArrayList(writePrivilege.getAggregatePrivileges()));
    }

    return privilegeToFilterOut;
  }
  @Override
  public boolean hasPrivileges(final String absPath, final Privilege[] privileges)
      throws PathNotFoundException, RepositoryException {

    if (supportPrivileges) {
      // if the node is created in the same session, return true
      for (Item item : session.getNewItems()) {
        if (item.getPath().equals(absPath)) {
          return true;
        }
      }

      // check privilege names
      return hasPrivilegesLegacy(absPath, privileges);
    } else {
      // check ACLs
      Set<String> privs = new HashSet<>();
      for (Privilege privilege : privileges) {
        privs.add(privilege.getName());
      }
      String mountPoint = session.getRepository().getStoreProvider().getMountPoint();
      Session securitySession =
          JCRSessionFactory.getInstance()
              .getCurrentSystemSession(session.getWorkspace().getName(), null, null);
      PathWrapper pathWrapper =
          new ExternalPathWrapperImpl(
              StringUtils.equals(absPath, "/") ? mountPoint : mountPoint + absPath,
              securitySession);
      return AccessManagerUtils.isGranted(
          pathWrapper,
          privs,
          securitySession,
          jahiaPrincipal,
          workspaceName,
          false,
          pathPermissionCache,
          compiledAcls,
          registry);
    }
  }
  private static Privilege[] filterPrivileges(
      Privilege[] privileges, List<Privilege> privilegesToFilterOut) {

    Set<Privilege> filteredResult = new HashSet<Privilege>();
    for (Privilege privilege : privileges) {
      if (!privilegesToFilterOut.contains(privilege)) {
        if (privilege.isAggregate()
            && areIntersecting(privilege.getDeclaredAggregatePrivileges(), privilegesToFilterOut)) {
          // We de-aggregate a privilege in case any of its children are to be filtered out, since a
          // privilege is valid only if all its children are valid.
          filteredResult.addAll(
              Arrays.asList(
                  filterPrivileges(
                      privilege.getDeclaredAggregatePrivileges(), privilegesToFilterOut)));
        } else {
          filteredResult.add(privilege);
        }
      }
    }

    return filteredResult.toArray(new Privilege[filteredResult.size()]);
  }