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;
  }
 public String[] getLockTokens() {
   List<String> allTokens = new ArrayList<String>(tokens);
   for (Session session : sessions.values()) {
     String[] tokens = session.getLockTokens();
     for (String token : tokens) {
       if (!allTokens.contains(token)) {
         allTokens.add(token);
       }
     }
   }
   return allTokens.toArray(new String[allTokens.size()]);
 }
  private Privilege[] getPrivilegesLegacy(String absPath)
      throws PathNotFoundException, RepositoryException {
    List<Privilege> l = new ArrayList<Privilege>();
    for (String s : getPrivilegesNamesLegacy(absPath)) {
      Privilege privilege = registry.getPrivilege(s, null);
      if (privilege != null) {
        l.add(privilege);
      }
    }

    return l.toArray(new Privilege[l.size()]);
  }
 /**
  * Test if there is an intersection between the two arrays of privileges
  *
  * @param privileges1
  * @param privileges2
  * @return whether the two arrays contain any common element
  */
 private static boolean areIntersecting(Privilege[] privileges1, List<Privilege> privileges2) {
   for (Privilege privilege1 : privileges1) {
     if (privileges2.contains(privilege1)) {
       return true;
     }
   }
   return false;
 }
  @Override
  public Privilege[] getPrivileges(final String absPath)
      throws PathNotFoundException, RepositoryException {

    JCRNodeWrapper node =
        JCRSessionFactory.getInstance()
            .getCurrentSystemSession(workspaceName, null, null)
            .getNode(session.getRepository().getStoreProvider().getMountPoint() + absPath);
    Privilege[] privileges;
    if (supportPrivileges) {
      privileges = getPrivilegesLegacy(absPath);
    } else {
      privileges = AccessManagerUtils.getPrivileges(node, jahiaPrincipal, registry);
    }
    // filter some privileges in some specific cases, for avoid some operation from edit engines
    List<Privilege> privilegeToFilter = getPrivilegesToFilter(node.getRealNode());
    if (privilegeToFilter.size() > 0) {
      return filterPrivileges(privileges, privilegeToFilter);
    } else {
      return privileges;
    }
  }
  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()]);
  }
 public void removeLockToken(String token) {
   tokens.remove(token);
   for (Session session : sessions.values()) {
     session.removeLockToken(token);
   }
 }
 /**
  * Adds the specified lock token to the wrapped sessions. Holding a lock token makes the <code>
  * Session</code> the owner of the lock specified by that particular lock token.
  *
  * @param token a lock token (a string).
  * @deprecated As of JCR 2.0, {@link LockManager#addLockToken(String)} should be used instead.
  */
 public void addLockToken(String token) {
   tokens.add(token);
   for (Session session : sessions.values()) {
     session.addLockToken(token);
   }
 }