You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by en...@apache.org on 2021/05/28 17:31:17 UTC

[sling-org-apache-sling-jcr-jackrabbit-accessmanager] branch master updated: cleanup - change tabs to spaces

This is an automated email from the ASF dual-hosted git repository.

enorman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-jackrabbit-accessmanager.git


The following commit(s) were added to refs/heads/master by this push:
     new 0825da1  cleanup - change tabs to spaces
0825da1 is described below

commit 0825da1234ebd3be107acd9dc1ed04ae692ec8ab
Author: Eric Norman <en...@apache.org>
AuthorDate: Fri May 28 10:31:08 2021 -0700

    cleanup - change tabs to spaces
---
 .../jcr/jackrabbit/accessmanager/DeleteAces.java   |   26 +-
 .../sling/jcr/jackrabbit/accessmanager/GetAcl.java |   22 +-
 .../jackrabbit/accessmanager/GetEffectiveAcl.java  |   22 +-
 .../jcr/jackrabbit/accessmanager/ModifyAce.java    |  238 ++---
 .../jackrabbit/accessmanager/PrivilegesInfo.java   | 1081 ++++++++++----------
 .../accessmanager/impl/PrivilegesHelper.java       |    2 +-
 .../accessmanager/post/AbstractGetAclServlet.java  |  164 +--
 .../accessmanager/post/DeleteAcesServlet.java      |  277 +++--
 .../accessmanager/post/GetAclServlet.java          |   50 +-
 .../accessmanager/post/GetEffectiveAclServlet.java |   26 +-
 .../accessmanager/post/ModifyAceServlet.java       |  429 ++++----
 11 files changed, 1165 insertions(+), 1172 deletions(-)

diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/DeleteAces.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/DeleteAces.java
index 2c6102c..6833952 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/DeleteAces.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/DeleteAces.java
@@ -30,17 +30,17 @@ import javax.jcr.Session;
  */
 public interface DeleteAces {
 
-	/**
-	 * Deletes one or more ACEs from the access control list of a resource.
-	 * 
-	 * @param jcrSession the JCR session of the user updating the user
-	 * @param resourcePath The path of the resource to update the ACL for (required)
-	 * @param principalNamesToDelete An array of ace principal names to delete.. (required)
-	 * @throws RepositoryException if any errors applying the changes 
-	 */
-	void deleteAces(Session jcrSession,
-							String resourcePath,
-							String [] principalNamesToDelete
-				) throws RepositoryException;
-	
+    /**
+     * Deletes one or more ACEs from the access control list of a resource.
+     * 
+     * @param jcrSession the JCR session of the user updating the user
+     * @param resourcePath The path of the resource to update the ACL for (required)
+     * @param principalNamesToDelete An array of ace principal names to delete.. (required)
+     * @throws RepositoryException if any errors applying the changes 
+     */
+    void deleteAces(Session jcrSession,
+                            String resourcePath,
+                            String [] principalNamesToDelete
+                ) throws RepositoryException;
+
 }
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/GetAcl.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/GetAcl.java
index 14b00f3..145b238 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/GetAcl.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/GetAcl.java
@@ -31,16 +31,16 @@ import javax.json.JsonObject;
  */
 public interface GetAcl {
 
-	/**
-	 * Gets the access control list for a resource.
-	 * 
-	 * @param jcrSession the JCR session of the user updating the user
-	 * @param resourcePath The path of the resource to get the ACL for (required)
+    /**
+     * Gets the access control list for a resource.
+     * 
+     * @param jcrSession the JCR session of the user updating the user
+     * @param resourcePath The path of the resource to get the ACL for (required)
      * @return the ACL as a JSON object 
-	 * @throws RepositoryException if any errors reading the information
-	 */
-	JsonObject getAcl(Session jcrSession,
-							String resourcePath
-				) throws RepositoryException;
-	
+     * @throws RepositoryException if any errors reading the information
+     */
+    JsonObject getAcl(Session jcrSession,
+                            String resourcePath
+                ) throws RepositoryException;
+
 }
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/GetEffectiveAcl.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/GetEffectiveAcl.java
index 767ef46..e118c8a 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/GetEffectiveAcl.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/GetEffectiveAcl.java
@@ -31,16 +31,16 @@ import javax.json.JsonObject;
  */
 public interface GetEffectiveAcl {
 
-	/**
-	 * Gets the effective access control list for a resource.
-	 * 
-	 * @param jcrSession the JCR session of the user updating the user
-	 * @param resourcePath The path of the resource to get the ACL for (required)
+    /**
+     * Gets the effective access control list for a resource.
+     * 
+     * @param jcrSession the JCR session of the user updating the user
+     * @param resourcePath The path of the resource to get the ACL for (required)
      * @return the ACL as a JSON object 
-	 * @throws RepositoryException if any errors reading the information
-	 */
-	JsonObject getEffectiveAcl(Session jcrSession,
-							String resourcePath
-				) throws RepositoryException;
-	
+     * @throws RepositoryException if any errors reading the information
+     */
+    JsonObject getEffectiveAcl(Session jcrSession,
+                            String resourcePath
+                ) throws RepositoryException;
+
 }
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/ModifyAce.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/ModifyAce.java
index ffcfdd1..39d4947 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/ModifyAce.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/ModifyAce.java
@@ -35,149 +35,149 @@ import javax.jcr.Value;
  */
 public interface ModifyAce {
 
-	/**
-	 * Add or modify the access control entry for the specified user 
-	 * or group.
-	 * 
-	 * This is equivalent to {@link #modifyAce(Session, String, String, Map, String, boolean)} with
-	 * the autoSave parameter value equal to true.
-	 * 
-	 * @param jcrSession the JCR session of the user updating the user
-	 * @param resourcePath The absolute path of the resource to apply the ACE to (required)
-	 * @param principalId The name of the user/group to provision (required)
-	 * @param privileges Map of privileges to apply. (optional)
+    /**
+     * Add or modify the access control entry for the specified user 
+     * or group.
+     * 
+     * This is equivalent to {@link #modifyAce(Session, String, String, Map, String, boolean)} with
+     * the autoSave parameter value equal to true.
+     * 
+     * @param jcrSession the JCR session of the user updating the user
+     * @param resourcePath The absolute path of the resource to apply the ACE to (required)
+     * @param principalId The name of the user/group to provision (required)
+     * @param privileges Map of privileges to apply. (optional)
      * @param order where the access control entry should go in the list.
      *         <table style='margin-left: 30px;' border="1">
      *          <caption>The value should be one of these:</caption>
      *          <tbody>
      *            <tr><td>null</td><td>If the ACE for the principal doesn't exist add at the end, otherwise leave the ACE at it's current position.</td></tr>
-     * 			  <tr><td>first</td><td>Place the target ACE as the first amongst its siblings</td></tr>
-	 *			  <tr><td>last</td><td>Place the target ACE as the last amongst its siblings</td></tr>
-	 * 			  <tr><td>before xyz</td><td>Place the target ACE immediately before the sibling whose name is xyz</td></tr>
-	 * 			  <tr><td>after xyz</td><td>Place the target ACE immediately after the sibling whose name is xyz</td></tr>
-	 * 			  <tr><td>numeric</td><td>Place the target ACE at the specified numeric index</td></tr>
+     *               <tr><td>first</td><td>Place the target ACE as the first amongst its siblings</td></tr>
+     *              <tr><td>last</td><td>Place the target ACE as the last amongst its siblings</td></tr>
+     *               <tr><td>before xyz</td><td>Place the target ACE immediately before the sibling whose name is xyz</td></tr>
+     *               <tr><td>after xyz</td><td>Place the target ACE immediately after the sibling whose name is xyz</td></tr>
+     *               <tr><td>numeric</td><td>Place the target ACE at the specified numeric index</td></tr>
      *          </tbody>
-	 *         </table>
-	 * @throws RepositoryException if any errors applying the changes 
-	 */
-	void modifyAce(Session jcrSession,
-							String resourcePath,
-							String principalId,
-							Map<String, String> privileges,
-							String order
-				) throws RepositoryException;
+     *         </table>
+     * @throws RepositoryException if any errors applying the changes 
+     */
+    void modifyAce(Session jcrSession,
+                            String resourcePath,
+                            String principalId,
+                            Map<String, String> privileges,
+                            String order
+                ) throws RepositoryException;
 
-	/**
-	 * Add or modify the access control entry for the specified user 
-	 * or group.
-	 * 
-	 * @param jcrSession the JCR session of the user updating the user
-	 * @param resourcePath The absolute path of the resource to apply the ACE to (required)
-	 * @param principalId The name of the user/group to provision (required)
-	 * @param privileges Map of privileges to apply. (optional)
+    /**
+     * Add or modify the access control entry for the specified user 
+     * or group.
+     * 
+     * @param jcrSession the JCR session of the user updating the user
+     * @param resourcePath The absolute path of the resource to apply the ACE to (required)
+     * @param principalId The name of the user/group to provision (required)
+     * @param privileges Map of privileges to apply. (optional)
      * @param order where the access control entry should go in the list.
      *         <table style='margin-left: 30px;' border="1">
      *          <caption>The value should be one of these:</caption>
      *          <tbody>
      *            <tr><td>null</td><td>If the ACE for the principal doesn't exist add at the end, otherwise leave the ACE at it's current position.</td></tr>
-     * 			  <tr><td>first</td><td>Place the target ACE as the first amongst its siblings</td></tr>
-	 *			  <tr><td>last</td><td>Place the target ACE as the last amongst its siblings</td></tr>
-	 * 			  <tr><td>before xyz</td><td>Place the target ACE immediately before the sibling whose name is xyz</td></tr>
-	 * 			  <tr><td>after xyz</td><td>Place the target ACE immediately after the sibling whose name is xyz</td></tr>
-	 * 			  <tr><td>numeric</td><td>Place the target ACE at the specified numeric index</td></tr>
+     *               <tr><td>first</td><td>Place the target ACE as the first amongst its siblings</td></tr>
+     *              <tr><td>last</td><td>Place the target ACE as the last amongst its siblings</td></tr>
+     *               <tr><td>before xyz</td><td>Place the target ACE immediately before the sibling whose name is xyz</td></tr>
+     *               <tr><td>after xyz</td><td>Place the target ACE immediately after the sibling whose name is xyz</td></tr>
+     *               <tr><td>numeric</td><td>Place the target ACE at the specified numeric index</td></tr>
      *          </tbody>
-	 *         </table>
-	 * @param autoSave true to automatically save changes to the JCR session, false otherwise
-	 * @throws RepositoryException if any errors applying the changes 
-	 */
-	default void modifyAce(Session jcrSession,
-							String resourcePath,
-							String principalId,
-							Map<String, String> privileges,
-							String order,
-							boolean autoSave
-				) throws RepositoryException {
-		throw new UnsupportedRepositoryOperationException();
-	}
-	
-	/**
-	 * Add or modify the access control entry for the specified user 
-	 * or group.
-	 * 
-	 * This is equivalent to {@link #modifyAce(Session, String, String, Map, String, Map, Map, Set, boolean)} with
-	 * the autoSave parameter value equal to true.
-	 * 
-	 * @param jcrSession the JCR session of the user updating the user
-	 * @param resourcePath The absolute path of the resource to apply the ACE to (required)
-	 * @param principalId The name of the user/group to provision (required)
-	 * @param privileges Map of privileges to apply. (optional)
+     *         </table>
+     * @param autoSave true to automatically save changes to the JCR session, false otherwise
+     * @throws RepositoryException if any errors applying the changes 
+     */
+    default void modifyAce(Session jcrSession,
+                            String resourcePath,
+                            String principalId,
+                            Map<String, String> privileges,
+                            String order,
+                            boolean autoSave
+                ) throws RepositoryException {
+        throw new UnsupportedRepositoryOperationException();
+    }
+
+    /**
+     * Add or modify the access control entry for the specified user 
+     * or group.
+     * 
+     * This is equivalent to {@link #modifyAce(Session, String, String, Map, String, Map, Map, Set, boolean)} with
+     * the autoSave parameter value equal to true.
+     * 
+     * @param jcrSession the JCR session of the user updating the user
+     * @param resourcePath The absolute path of the resource to apply the ACE to (required)
+     * @param principalId The name of the user/group to provision (required)
+     * @param privileges Map of privileges to apply. (optional)
      * @param order where the access control entry should go in the list.
      *         <table style='margin-left: 30px;' border="1">
      *          <caption>The value should be one of these:</caption>
      *          <tbody>
      *            <tr><td>null</td><td>If the ACE for the principal doesn't exist add at the end, otherwise leave the ACE at it's current position.</td></tr>
-     * 			  <tr><td>first</td><td>Place the target ACE as the first amongst its siblings</td></tr>
-	 *			  <tr><td>last</td><td>Place the target ACE as the last amongst its siblings</td></tr>
-	 * 			  <tr><td>before xyz</td><td>Place the target ACE immediately before the sibling whose name is xyz</td></tr>
-	 * 			  <tr><td>after xyz</td><td>Place the target ACE immediately after the sibling whose name is xyz</td></tr>
-	 * 			  <tr><td>numeric</td><td>Place the target ACE at the specified numeric index</td></tr>
+     *               <tr><td>first</td><td>Place the target ACE as the first amongst its siblings</td></tr>
+     *              <tr><td>last</td><td>Place the target ACE as the last amongst its siblings</td></tr>
+     *               <tr><td>before xyz</td><td>Place the target ACE immediately before the sibling whose name is xyz</td></tr>
+     *               <tr><td>after xyz</td><td>Place the target ACE immediately after the sibling whose name is xyz</td></tr>
+     *               <tr><td>numeric</td><td>Place the target ACE at the specified numeric index</td></tr>
      *          </tbody>
-	 *         </table>
-	 * @param restrictions Map of single-value restrictions to apply. (optional)
-	 * @param mvRestrictions Map of multi-value restrictions to apply. (optional)
-	 * @param removeRestrictionNames Set of existing restriction names to remove (optional)
-	 * @throws RepositoryException if any errors applying the changes 
-	 */
-	default void modifyAce(Session jcrSession,
-							String resourcePath,
-							String principalId,
-							Map<String, String> privileges,
-							String order,
-							Map<String, Value> restrictions,
-							Map<String, Value[]> mvRestrictions,
-							Set<String> removeRestrictionNames
-				) throws RepositoryException {
-		modifyAce(jcrSession, resourcePath, principalId, 
-				privileges, order, restrictions, mvRestrictions, 
-				removeRestrictionNames, true);
-	}
+     *         </table>
+     * @param restrictions Map of single-value restrictions to apply. (optional)
+     * @param mvRestrictions Map of multi-value restrictions to apply. (optional)
+     * @param removeRestrictionNames Set of existing restriction names to remove (optional)
+     * @throws RepositoryException if any errors applying the changes 
+     */
+    default void modifyAce(Session jcrSession,
+                            String resourcePath,
+                            String principalId,
+                            Map<String, String> privileges,
+                            String order,
+                            Map<String, Value> restrictions,
+                            Map<String, Value[]> mvRestrictions,
+                            Set<String> removeRestrictionNames
+                ) throws RepositoryException {
+        modifyAce(jcrSession, resourcePath, principalId, 
+                privileges, order, restrictions, mvRestrictions, 
+                removeRestrictionNames, true);
+    }
 
-	/**
-	 * Add or modify the access control entry for the specified user 
-	 * or group.
-	 * 
-	 * @param jcrSession the JCR session of the user updating the user
-	 * @param resourcePath The absolute path of the resource to apply the ACE to (required)
-	 * @param principalId The name of the user/group to provision (required)
-	 * @param privileges Map of privileges to apply. (optional)
+    /**
+     * Add or modify the access control entry for the specified user 
+     * or group.
+     * 
+     * @param jcrSession the JCR session of the user updating the user
+     * @param resourcePath The absolute path of the resource to apply the ACE to (required)
+     * @param principalId The name of the user/group to provision (required)
+     * @param privileges Map of privileges to apply. (optional)
      * @param order where the access control entry should go in the list.
      *         <table style='margin-left: 30px;' border="1">
      *          <caption>The value should be one of these:</caption>
      *          <tbody>
      *            <tr><td>null</td><td>If the ACE for the principal doesn't exist add at the end, otherwise leave the ACE at it's current position.</td></tr>
-     * 			  <tr><td>first</td><td>Place the target ACE as the first amongst its siblings</td></tr>
-	 *			  <tr><td>last</td><td>Place the target ACE as the last amongst its siblings</td></tr>
-	 * 			  <tr><td>before xyz</td><td>Place the target ACE immediately before the sibling whose name is xyz</td></tr>
-	 * 			  <tr><td>after xyz</td><td>Place the target ACE immediately after the sibling whose name is xyz</td></tr>
-	 * 			  <tr><td>numeric</td><td>Place the target ACE at the specified numeric index</td></tr>
+     *               <tr><td>first</td><td>Place the target ACE as the first amongst its siblings</td></tr>
+     *              <tr><td>last</td><td>Place the target ACE as the last amongst its siblings</td></tr>
+     *               <tr><td>before xyz</td><td>Place the target ACE immediately before the sibling whose name is xyz</td></tr>
+     *               <tr><td>after xyz</td><td>Place the target ACE immediately after the sibling whose name is xyz</td></tr>
+     *               <tr><td>numeric</td><td>Place the target ACE at the specified numeric index</td></tr>
      *          </tbody>
-	 *         </table>
-	 * @param restrictions Map of single-value restrictions to apply. (optional)
-	 * @param mvRestrictions Map of multi-value restrictions to apply. (optional)
-	 * @param removeRestrictionNames Set of existing restriction names to remove (optional)
-	 * @param autoSave true to automatically save changes to the JCR session, false otherwise
-	 * @throws RepositoryException if any errors applying the changes 
-	 */
-	default void modifyAce(Session jcrSession,
-							String resourcePath,
-							String principalId,
-							Map<String, String> privileges,
-							String order,
-							Map<String, Value> restrictions,
-							Map<String, Value[]> mvRestrictions,
-							Set<String> removeRestrictionNames,
-							boolean autoSave
-				) throws RepositoryException {
-		throw new UnsupportedRepositoryOperationException();
-	}
+     *         </table>
+     * @param restrictions Map of single-value restrictions to apply. (optional)
+     * @param mvRestrictions Map of multi-value restrictions to apply. (optional)
+     * @param removeRestrictionNames Set of existing restriction names to remove (optional)
+     * @param autoSave true to automatically save changes to the JCR session, false otherwise
+     * @throws RepositoryException if any errors applying the changes 
+     */
+    default void modifyAce(Session jcrSession,
+                            String resourcePath,
+                            String principalId,
+                            Map<String, String> privileges,
+                            String order,
+                            Map<String, Value> restrictions,
+                            Map<String, Value[]> mvRestrictions,
+                            Set<String> removeRestrictionNames,
+                            boolean autoSave
+                ) throws RepositoryException {
+        throw new UnsupportedRepositoryOperationException();
+    }
 }
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/PrivilegesInfo.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/PrivilegesInfo.java
index 4e679f8..6ebddc2 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/PrivilegesInfo.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/PrivilegesInfo.java
@@ -47,124 +47,123 @@ import org.apache.sling.jcr.base.util.AccessControlUtil;
  * Helper class to assist in the usage of access control from scripts.
  */
 public class PrivilegesInfo {
-	
-	/**
-	 * Return the supported Privileges for the specified node.
-	 * 
-	 * @param node the node to check
-	 * @return array of Privileges
-	 * @throws RepositoryException if any errors reading the information
-	 */
-	public Privilege [] getSupportedPrivileges(Node node) throws RepositoryException {
-		return getSupportedPrivileges(node.getSession(), node.getPath());
-	}
-	
-	/**
-	 * Returns the supported privileges for the specified path.
-	 * 
-	 * @param session the session for the current user
-	 * @param absPath the path to get the privileges for
-	 * @return array of Privileges
-	 * @throws RepositoryException if any errors reading the information
-	 */
-	public Privilege [] getSupportedPrivileges(Session session, String absPath) throws RepositoryException {
-		AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
-		return accessControlManager.getSupportedPrivileges(absPath);
-	}
-	
-	/**
-	 * Wrapper class that holds the set of Privileges that are granted 
-	 * and/or denied for a specific principal.
-	 */
-	public static class AccessRights {
-		private Set<Privilege> granted = new HashSet<>();
-		private Set<Privilege> denied = new HashSet<>();
-
-		private ResourceBundle resBundle = null;
-		private ResourceBundle getResourceBundle(Locale locale) {
-			if (resBundle == null || !resBundle.getLocale().equals(locale)) {
-				resBundle = ResourceBundle.getBundle(getClass().getPackage().getName() + ".PrivilegesResources", locale);
-			}
-			return resBundle;
-		}
-		
-
-		public Set<Privilege> getGranted() {
-			return granted;
-		}
-		public Set<Privilege> getDenied() {
-			return denied;
-		}
-		
-		public String getPrivilegeSetDisplayName(Locale locale) {
-			if (denied != null && !denied.isEmpty()) {
-				//if there are any denied privileges, then this is a custom privilege set
-				return getResourceBundle(locale).getString("privilegeset.custom");
-			} else {
-				if (granted.isEmpty()) {
-					//appears to have an empty privilege set
-					return getResourceBundle(locale).getString("privilegeset.none");
-				}
-					
-				if (granted.size() == 1) {
-					//check if the single privilege is jcr:all or jcr:read
-					Iterator<Privilege> iterator = granted.iterator();
-					Privilege next = iterator.next();
-					if (PrivilegeConstants.JCR_ALL.equals(next.getName())) {
-						//full control privilege set
-						return getResourceBundle(locale).getString("privilegeset.all");
-					} else if (PrivilegeConstants.JCR_READ.equals(next.getName())) {
-						//readonly privilege set
-						return getResourceBundle(locale).getString("privilegeset.readonly");
-					} 
-				} else if (granted.size() == 2) {
-					//check if the two privileges are jcr:read and jcr:write
-					Iterator<Privilege> iterator = granted.iterator();
-					Privilege next = iterator.next();
-					Privilege next2 = iterator.next();
-					if ( (PrivilegeConstants.JCR_READ.equals(next.getName()) && PrivilegeConstants.JCR_WRITE.equals(next2.getName())) ||
-							(PrivilegeConstants.JCR_READ.equals(next2.getName()) && PrivilegeConstants.JCR_WRITE.equals(next.getName())) ) {
-						//read/write privileges
-						return getResourceBundle(locale).getString("privilegeset.readwrite");
-					}
-				}
-
-				//some other set of privileges
-				return getResourceBundle(locale).getString("privilegeset.custom");
-			}
-		}
-	}
-
-	/**
-	 * Returns the mapping of declared access rights that have been set for the resource at
-	 * the given path. 
-	 * 
-	 * @param node the node to get the access rights for
-	 * @return map of access rights.  Key is the user/group principal, value contains the granted/denied privileges
-	 * @throws RepositoryException if any errors reading the information
-	 */
-	public Map<Principal, AccessRights> getDeclaredAccessRights(Node node) throws RepositoryException {
-		return getDeclaredAccessRights(node.getSession(), node.getPath());
-	}
-	
-	/**
-	 * Returns the mapping of declared access rights that have been set for the resource at
-	 * the given path. 
-	 * 
-	 * @param session the current user session.
-	 * @param absPath the path of the resource to get the access rights for
-	 * @return map of access rights.  Key is the user/group principal, value contains the granted/denied privileges
-	 * @throws RepositoryException if any errors reading the information
-	 */
-	public Map<Principal, AccessRights> getDeclaredAccessRights(Session session, String absPath) throws RepositoryException {
-		AccessControlEntry[] entries = getDeclaredAccessControlEntries(session, absPath);
-		return mergePrivilegesFromEntries(entries);
-	}
-
-	private AccessControlEntry[] getDeclaredAccessControlEntries(Session session, String absPath) throws RepositoryException {
-		AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
-		AccessControlPolicy[] policies = accessControlManager.getPolicies(absPath);
-		
+
+    /**
+     * Return the supported Privileges for the specified node.
+     * 
+     * @param node the node to check
+     * @return array of Privileges
+     * @throws RepositoryException if any errors reading the information
+     */
+    public Privilege [] getSupportedPrivileges(Node node) throws RepositoryException {
+        return getSupportedPrivileges(node.getSession(), node.getPath());
+    }
+
+    /**
+     * Returns the supported privileges for the specified path.
+     * 
+     * @param session the session for the current user
+     * @param absPath the path to get the privileges for
+     * @return array of Privileges
+     * @throws RepositoryException if any errors reading the information
+     */
+    public Privilege [] getSupportedPrivileges(Session session, String absPath) throws RepositoryException {
+        AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
+        return accessControlManager.getSupportedPrivileges(absPath);
+    }
+
+    /**
+     * Wrapper class that holds the set of Privileges that are granted 
+     * and/or denied for a specific principal.
+     */
+    public static class AccessRights {
+        private Set<Privilege> granted = new HashSet<>();
+        private Set<Privilege> denied = new HashSet<>();
+
+        private ResourceBundle resBundle = null;
+        private ResourceBundle getResourceBundle(Locale locale) {
+            if (resBundle == null || !resBundle.getLocale().equals(locale)) {
+                resBundle = ResourceBundle.getBundle(getClass().getPackage().getName() + ".PrivilegesResources", locale);
+            }
+            return resBundle;
+        }
+
+        public Set<Privilege> getGranted() {
+            return granted;
+        }
+        public Set<Privilege> getDenied() {
+            return denied;
+        }
+
+        public String getPrivilegeSetDisplayName(Locale locale) {
+            if (denied != null && !denied.isEmpty()) {
+                //if there are any denied privileges, then this is a custom privilege set
+                return getResourceBundle(locale).getString("privilegeset.custom");
+            } else {
+                if (granted.isEmpty()) {
+                    //appears to have an empty privilege set
+                    return getResourceBundle(locale).getString("privilegeset.none");
+                }
+
+                if (granted.size() == 1) {
+                    //check if the single privilege is jcr:all or jcr:read
+                    Iterator<Privilege> iterator = granted.iterator();
+                    Privilege next = iterator.next();
+                    if (PrivilegeConstants.JCR_ALL.equals(next.getName())) {
+                        //full control privilege set
+                        return getResourceBundle(locale).getString("privilegeset.all");
+                    } else if (PrivilegeConstants.JCR_READ.equals(next.getName())) {
+                        //readonly privilege set
+                        return getResourceBundle(locale).getString("privilegeset.readonly");
+                    }
+                } else if (granted.size() == 2) {
+                    //check if the two privileges are jcr:read and jcr:write
+                    Iterator<Privilege> iterator = granted.iterator();
+                    Privilege next = iterator.next();
+                    Privilege next2 = iterator.next();
+                    if ( (PrivilegeConstants.JCR_READ.equals(next.getName()) && PrivilegeConstants.JCR_WRITE.equals(next2.getName())) ||
+                            (PrivilegeConstants.JCR_READ.equals(next2.getName()) && PrivilegeConstants.JCR_WRITE.equals(next.getName())) ) {
+                        //read/write privileges
+                        return getResourceBundle(locale).getString("privilegeset.readwrite");
+                    }
+                }
+
+                //some other set of privileges
+                return getResourceBundle(locale).getString("privilegeset.custom");
+            }
+        }
+    }
+
+    /**
+     * Returns the mapping of declared access rights that have been set for the resource at
+     * the given path. 
+     * 
+     * @param node the node to get the access rights for
+     * @return map of access rights.  Key is the user/group principal, value contains the granted/denied privileges
+     * @throws RepositoryException if any errors reading the information
+     */
+    public Map<Principal, AccessRights> getDeclaredAccessRights(Node node) throws RepositoryException {
+        return getDeclaredAccessRights(node.getSession(), node.getPath());
+    }
+
+    /**
+     * Returns the mapping of declared access rights that have been set for the resource at
+     * the given path.
+     *
+     * @param session the current user session.
+     * @param absPath the path of the resource to get the access rights for
+     * @return map of access rights.  Key is the user/group principal, value contains the granted/denied privileges
+     * @throws RepositoryException if any errors reading the information
+     */
+    public Map<Principal, AccessRights> getDeclaredAccessRights(Session session, String absPath) throws RepositoryException {
+        AccessControlEntry[] entries = getDeclaredAccessControlEntries(session, absPath);
+        return mergePrivilegesFromEntries(entries);
+    }
+
+    private AccessControlEntry[] getDeclaredAccessControlEntries(Session session, String absPath) throws RepositoryException {
+        AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
+        AccessControlPolicy[] policies = accessControlManager.getPolicies(absPath);
+
         List<AccessControlEntry> allEntries = new ArrayList<>();
         for (AccessControlPolicy accessControlPolicy : policies) {
             if (accessControlPolicy instanceof AccessControlList) {
@@ -173,165 +172,163 @@ public class PrivilegesInfo {
             }
         }
         return allEntries.toArray(new AccessControlEntry[allEntries.size()]);
-	}
-
-	/**
-	 * Returns the declared access rights for the specified Node for the given
-	 * principalId.
-	 * 
-	 * @param node the JCR node to retrieve the access rights for
-	 * @param principalId the principalId to get the access rights for
-	 * @return access rights for the specified principal
-	 * @throws RepositoryException if any errors reading the information
-	 */
-	public AccessRights getDeclaredAccessRightsForPrincipal(Node node, String principalId) throws RepositoryException {
-		return getDeclaredAccessRightsForPrincipal(node.getSession(), node.getPath(), principalId);
-	}
-
-	/**
-	 * Returns the declared access rights for the resource at the specified path for the given
-	 * principalId.
-	 * 
-	 * @param session the current JCR session
-	 * @param absPath the path of the resource to retrieve the rights for
-	 * @param principalId the principalId to get the access rights for
-	 * @return access rights for the specified principal
-	 * @throws RepositoryException if any errors reading the information
-	 */
-	public AccessRights getDeclaredAccessRightsForPrincipal(Session session, String absPath, String principalId) throws RepositoryException {
-		AccessRights rights = new AccessRights();
-		if (principalId != null && principalId.length() > 0) {
-			AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
-			AccessControlPolicy[] policies = accessControlManager.getPolicies(absPath);
-			for (AccessControlPolicy accessControlPolicy : policies) {
-				if (accessControlPolicy instanceof AccessControlList) {
-					AccessControlEntry[] accessControlEntries = ((AccessControlList)accessControlPolicy).getAccessControlEntries();
-					for (AccessControlEntry ace : accessControlEntries) {
-						if (principalId.equals(ace.getPrincipal().getName())) {
-							boolean isAllow = AccessControlUtil.isAllow(ace);
-							if (isAllow) {
-								rights.getGranted().addAll(Arrays.asList(ace.getPrivileges()));
-							} else {
-								rights.getDenied().addAll(Arrays.asList(ace.getPrivileges()));
-							}
-						}
-					}
-				}
-			}
-		}
-		
-		return rights;
-	}
-	
-	/**
-	 * Returns the restrictions for the specified path.
-	 * 
-	 * @param node the node to inspect
-	 * @param principalId the principalId to get the access rights for
-	 * @return map of restrictions (key is restriction name, value is Value or Value[])
-	 * @throws RepositoryException if any errors reading the information
-	 */
-	public Map<String, Object> getDeclaredRestrictionsForPrincipal(Node node, String principalId) throws RepositoryException {
-		return getDeclaredRestrictionsForPrincipal(node.getSession(), node.getPath(), principalId);
-	}
-	
-	/**
-	 * Returns the restrictions for the specified path.
-	 * 
-	 * @param session the session for the current user
-	 * @param absPath the path to get the privileges for
-	 * @param principalId the principalId to get the access rights for
-	 * @return map of restrictions (key is restriction name, value is Value or Value[])
-	 * @throws RepositoryException if any errors reading the information
-	 */
-	public Map<String, Object> getDeclaredRestrictionsForPrincipal(Session session, String absPath, String principalId) throws RepositoryException {
-		Map<String, Object> restrictions = new LinkedHashMap<>();
-		AccessControlEntry[] entries = getDeclaredAccessControlEntries(session, absPath);
-		if (entries != null) {
-			for (AccessControlEntry ace : entries) {
-				if (principalId.equals(ace.getPrincipal().getName()) &&
-						ace instanceof JackrabbitAccessControlEntry) {
-					JackrabbitAccessControlEntry jace = (JackrabbitAccessControlEntry)ace;
-					String[] restrictionNames = jace.getRestrictionNames();
-					if (restrictionNames != null) {
-						for (String name : restrictionNames) {
-							try {
-								Value value = jace.getRestriction(name);
-								if (value != null) {
-									restrictions.put(name, value);
-								}
-							} catch (ValueFormatException vfe) {
-								//try multi-value restriction
-								Value[] values = jace.getRestrictions(name);
-								if (values != null && values.length > 0) {
-									restrictions.put(name,  values);
-								}
-							}
-						}
-					}
-				}
-			}
-		}
-		return restrictions;
-	}
-
-	
-	
-	/**
-	 * Returns the mapping of effective access rights that have been set for the resource at
-	 * the given path. 
-	 * 
-	 * @param node the node to get the access rights for
-	 * @return map of access rights.  Key is the user/group principal, value contains the granted/denied privileges
-	 * @throws RepositoryException if any errors reading the information
-	 */
-	public Map<Principal, AccessRights> getEffectiveAccessRights(Node node) throws RepositoryException {
-		return getEffectiveAccessRights(node.getSession(), node.getPath());
-	}
-	
-	/**
-	 * Returns the mapping of effective access rights that have been set for the resource at
-	 * the given path. 
-	 * 
-	 * @param session the current user session.
-	 * @param absPath the path of the resource to get the access rights for
-	 * @return map of access rights.  Key is the user/group principal, value contains the granted/denied privileges
-	 * @throws RepositoryException if any errors reading the information
-	 */
-	public Map<Principal, AccessRights> getEffectiveAccessRights(Session session, String absPath) throws RepositoryException {
-		AccessControlEntry[] entries = getEffectiveAccessControlEntries(session, absPath);
-		return mergePrivilegesFromEntries(entries);
-	}
-
-	/**
-	 * Loop through each of the entries to merge the granted and denied privileges into
-	 * the map
-	 * 
-	 * @param entries the entries to process
-	 * @throws RepositoryException if any errors reading the information
-	 */
-	private Map<Principal, AccessRights> mergePrivilegesFromEntries(AccessControlEntry[] entries)
-			throws RepositoryException {
-		Map<Principal, AccessRights> accessMap = new LinkedHashMap<>();
-		if (entries != null) {
-			for (AccessControlEntry ace : entries) {
-				Principal principal = ace.getPrincipal();
-				AccessRights accessPrivileges = accessMap.computeIfAbsent(principal, k -> new AccessRights());
-				boolean allow = AccessControlUtil.isAllow(ace);
-				if (allow) {
-					accessPrivileges.getGranted().addAll(Arrays.asList(ace.getPrivileges()));
-				} else {
-					accessPrivileges.getDenied().addAll(Arrays.asList(ace.getPrivileges()));
-				}
-			}
-		}
-		return accessMap;
-	}
-	
-	private AccessControlEntry[] getEffectiveAccessControlEntries(Session session, String absPath) throws RepositoryException {
-		AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
-		AccessControlPolicy[] policies = accessControlManager.getEffectivePolicies(absPath);
-		
+    }
+
+    /**
+     * Returns the declared access rights for the specified Node for the given
+     * principalId.
+     *
+     * @param node the JCR node to retrieve the access rights for
+     * @param principalId the principalId to get the access rights for
+     * @return access rights for the specified principal
+     * @throws RepositoryException if any errors reading the information
+     */
+    public AccessRights getDeclaredAccessRightsForPrincipal(Node node, String principalId) throws RepositoryException {
+        return getDeclaredAccessRightsForPrincipal(node.getSession(), node.getPath(), principalId);
+    }
+
+    /**
+     * Returns the declared access rights for the resource at the specified path for the given
+     * principalId.
+     *
+     * @param session the current JCR session
+     * @param absPath the path of the resource to retrieve the rights for
+     * @param principalId the principalId to get the access rights for
+     * @return access rights for the specified principal
+     * @throws RepositoryException if any errors reading the information
+     */
+    public AccessRights getDeclaredAccessRightsForPrincipal(Session session, String absPath, String principalId) throws RepositoryException {
+        AccessRights rights = new AccessRights();
+        if (principalId != null && principalId.length() > 0) {
+            AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
+            AccessControlPolicy[] policies = accessControlManager.getPolicies(absPath);
+            for (AccessControlPolicy accessControlPolicy : policies) {
+                if (accessControlPolicy instanceof AccessControlList) {
+                    AccessControlEntry[] accessControlEntries = ((AccessControlList)accessControlPolicy).getAccessControlEntries();
+                    for (AccessControlEntry ace : accessControlEntries) {
+                        if (principalId.equals(ace.getPrincipal().getName())) {
+                            boolean isAllow = AccessControlUtil.isAllow(ace);
+                            if (isAllow) {
+                                rights.getGranted().addAll(Arrays.asList(ace.getPrivileges()));
+                            } else {
+                                rights.getDenied().addAll(Arrays.asList(ace.getPrivileges()));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return rights;
+    }
+
+    /**
+     * Returns the restrictions for the specified path.
+     *
+     * @param node the node to inspect
+     * @param principalId the principalId to get the access rights for
+     * @return map of restrictions (key is restriction name, value is Value or Value[])
+     * @throws RepositoryException if any errors reading the information
+     */
+    public Map<String, Object> getDeclaredRestrictionsForPrincipal(Node node, String principalId) throws RepositoryException {
+        return getDeclaredRestrictionsForPrincipal(node.getSession(), node.getPath(), principalId);
+    }
+
+    /**
+     * Returns the restrictions for the specified path.
+     *
+     * @param session the session for the current user
+     * @param absPath the path to get the privileges for
+     * @param principalId the principalId to get the access rights for
+     * @return map of restrictions (key is restriction name, value is Value or Value[])
+     * @throws RepositoryException if any errors reading the information
+     */
+    public Map<String, Object> getDeclaredRestrictionsForPrincipal(Session session, String absPath, String principalId) throws RepositoryException {
+        Map<String, Object> restrictions = new LinkedHashMap<>();
+        AccessControlEntry[] entries = getDeclaredAccessControlEntries(session, absPath);
+        if (entries != null) {
+            for (AccessControlEntry ace : entries) {
+                if (principalId.equals(ace.getPrincipal().getName()) &&
+                        ace instanceof JackrabbitAccessControlEntry) {
+                    JackrabbitAccessControlEntry jace = (JackrabbitAccessControlEntry)ace;
+                    String[] restrictionNames = jace.getRestrictionNames();
+                    if (restrictionNames != null) {
+                        for (String name : restrictionNames) {
+                            try {
+                                Value value = jace.getRestriction(name);
+                                if (value != null) {
+                                    restrictions.put(name, value);
+                                }
+                            } catch (ValueFormatException vfe) {
+                                //try multi-value restriction
+                                Value[] values = jace.getRestrictions(name);
+                                if (values != null && values.length > 0) {
+                                    restrictions.put(name,  values);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return restrictions;
+    }
+
+    /**
+     * Returns the mapping of effective access rights that have been set for the resource at
+     * the given path.
+     *
+     * @param node the node to get the access rights for
+     * @return map of access rights.  Key is the user/group principal, value contains the granted/denied privileges
+     * @throws RepositoryException if any errors reading the information
+     */
+    public Map<Principal, AccessRights> getEffectiveAccessRights(Node node) throws RepositoryException {
+        return getEffectiveAccessRights(node.getSession(), node.getPath());
+    }
+
+    /**
+     * Returns the mapping of effective access rights that have been set for the resource at
+     * the given path.
+     *
+     * @param session the current user session.
+     * @param absPath the path of the resource to get the access rights for
+     * @return map of access rights.  Key is the user/group principal, value contains the granted/denied privileges
+     * @throws RepositoryException if any errors reading the information
+     */
+    public Map<Principal, AccessRights> getEffectiveAccessRights(Session session, String absPath) throws RepositoryException {
+        AccessControlEntry[] entries = getEffectiveAccessControlEntries(session, absPath);
+        return mergePrivilegesFromEntries(entries);
+    }
+
+    /**
+     * Loop through each of the entries to merge the granted and denied privileges into
+     * the map
+     *
+     * @param entries the entries to process
+     * @throws RepositoryException if any errors reading the information
+     */
+    private Map<Principal, AccessRights> mergePrivilegesFromEntries(AccessControlEntry[] entries)
+            throws RepositoryException {
+        Map<Principal, AccessRights> accessMap = new LinkedHashMap<>();
+        if (entries != null) {
+            for (AccessControlEntry ace : entries) {
+                Principal principal = ace.getPrincipal();
+                AccessRights accessPrivileges = accessMap.computeIfAbsent(principal, k -> new AccessRights());
+                boolean allow = AccessControlUtil.isAllow(ace);
+                if (allow) {
+                    accessPrivileges.getGranted().addAll(Arrays.asList(ace.getPrivileges()));
+                } else {
+                    accessPrivileges.getDenied().addAll(Arrays.asList(ace.getPrivileges()));
+                }
+            }
+        }
+        return accessMap;
+    }
+
+    private AccessControlEntry[] getEffectiveAccessControlEntries(Session session, String absPath) throws RepositoryException {
+        AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
+        AccessControlPolicy[] policies = accessControlManager.getEffectivePolicies(absPath);
+
         List<AccessControlEntry> allEntries = new ArrayList<>();
         for (AccessControlPolicy accessControlPolicy : policies) {
             if (accessControlPolicy instanceof AccessControlList) {
@@ -340,271 +337,269 @@ public class PrivilegesInfo {
             }
         }
         return allEntries.toArray(new AccessControlEntry[allEntries.size()]);
-	}
-
-	/**
-	 * Returns the effective access rights for the specified Node for the given
-	 * principalId.
-	 * 
-	 * @param node the JCR node to retrieve the access rights for
-	 * @param principalId the principalId to get the access rights for
-	 * @return access rights for the specified principal
-	 * @throws RepositoryException if any errors reading the information
-	 */
-	public AccessRights getEffectiveAccessRightsForPrincipal(Node node, String principalId) throws RepositoryException {
-		return getEffectiveAccessRightsForPrincipal(node.getSession(), node.getPath(), principalId);
-	}
-
-	/**
-	 * Returns the effective access rights for the resource at the specified path for the given
-	 * principalId.
-	 * 
-	 * @param session the current JCR session
-	 * @param absPath the path of the resource to retrieve the rights for
-	 * @param principalId the principalId to get the access rights for
-	 * @return access rights for the specified principal
-	 * @throws RepositoryException if any errors reading the information
-	 */
-	public AccessRights getEffectiveAccessRightsForPrincipal(Session session, String absPath, String principalId) throws RepositoryException {
-		AccessRights rights = new AccessRights();
-		if (principalId != null && principalId.length() > 0) {
-			AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
-			AccessControlPolicy[] policies = accessControlManager.getEffectivePolicies(absPath);
-			for (AccessControlPolicy accessControlPolicy : policies) {
-				if (accessControlPolicy instanceof AccessControlList) {
-					AccessControlEntry[] accessControlEntries = ((AccessControlList)accessControlPolicy).getAccessControlEntries();
-					for (AccessControlEntry ace : accessControlEntries) {
-						if (principalId.equals(ace.getPrincipal().getName())) {
-							boolean isAllow = AccessControlUtil.isAllow(ace);
-							if (isAllow) {
-								rights.getGranted().addAll(Arrays.asList(ace.getPrivileges()));
-							} else {
-								rights.getDenied().addAll(Arrays.asList(ace.getPrivileges()));
-							}
-						}
-					}
-				}
-			}
-		}
-		
-		return rights;
-	}
-	
-	
-	
-	/**
-	 * Checks whether the current user has been granted privileges
-	 * to add children to the specified node.
-	 *  
-	 * @param node the node to check
-	 * @return true if the current user has the privileges, false otherwise
-	 */
-	public boolean canAddChildren(Node node) {
-		try {
-			return canAddChildren(node.getSession(), node.getPath());
-		} catch (RepositoryException e) {
-			return false;
-		}
-	}
-	
-	/**
-	 * Checks whether the current user has been granted privileges
-	 * to add children to the specified path.
-	 *  
-	 * @param session the JCR session of the current user
-	 * @param absPath the path of the resource to check
-	 * @return true if the current user has the privileges, false otherwise
-	 */
-	public boolean canAddChildren(Session session, String absPath) {
-		try {
-			AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
-			return accessControlManager.hasPrivileges(absPath, new Privilege[] {
-							accessControlManager.privilegeFromName(Privilege.JCR_ADD_CHILD_NODES)
-						});
-		} catch (RepositoryException e) {
-			return false;
-		}
-	}
-	
-	/**
-	 * Checks whether the current user has been granted privileges
-	 * to delete children to the specified node.
-	 *  
-	 * @param node the node to check
-	 * @return true if the current user has the privileges, false otherwise
-	 */
-	public boolean canDeleteChildren(Node node) {
-		try {
-			return canDeleteChildren(node.getSession(), node.getPath());
-		} catch (RepositoryException e) {
-			return false;
-		}
-	}
-
-	/**
-	 * Checks whether the current user has been granted privileges
-	 * to delete children of the specified path.
-	 *  
-	 * @param session the JCR session of the current user
-	 * @param absPath the path of the resource to check
-	 * @return true if the current user has the privileges, false otherwise
-	 */
-	public boolean canDeleteChildren(Session session, String absPath) {
-		try {
-			AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
-			
-			return accessControlManager.hasPrivileges(absPath, new Privilege[] {
-							accessControlManager.privilegeFromName(Privilege.JCR_REMOVE_CHILD_NODES)
-						});
-		} catch (RepositoryException e) {
-			return false;
-		}
-	}
-	
-	/**
-	 * Checks whether the current user has been granted privileges
-	 * to delete the specified node.
-	 *  
-	 * @param node the node to check
-	 * @return true if the current user has the privileges, false otherwise
-	 */
-	public boolean canDelete(Node node) {
-		try {
-			return canDelete(node.getSession(), node.getPath());
-		} catch (RepositoryException e) {
-			return false;
-		}
-	}
-	
-	/**
-	 * Checks whether the current user has been granted privileges
-	 * to delete the specified path.
-	 *  
-	 * @param session the JCR session of the current user
-	 * @param absPath the path of the resource to check
-	 * @return true if the current user has the privileges, false otherwise
-	 */
-	public boolean canDelete(Session session, String absPath) {
-		try {
-			AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
-			
-			String parentPath;
-			int lastSlash = absPath.lastIndexOf('/');
-			if (lastSlash == 0) {
-				//the parent is the root folder.
-				parentPath = "/";
-			} else {
-				//strip the last segment
-				parentPath = absPath.substring(0, lastSlash);
-			}
-			return accessControlManager.hasPrivileges(absPath, new Privilege[] {
-							accessControlManager.privilegeFromName(Privilege.JCR_REMOVE_NODE)
-						}) && canDeleteChildren(session, parentPath);
-		} catch (RepositoryException e) {
-			return false;
-		}
-	}
-
-	/**
-	 * Checks whether the current user has been granted privileges
-	 * to modify properties of the specified node.
-	 *  
-	 * @param node the node to check
-	 * @return true if the current user has the privileges, false otherwise
-	 */
-	public boolean canModifyProperties(Node node) {
-		try {
-			return canModifyProperties(node.getSession(), node.getPath());
-		} catch (RepositoryException e) {
-			return false;
-		}
-	}
-	
-	/**
-	 * Checks whether the current user has been granted privileges
-	 * to modify properties of the specified path.
-	 *  
-	 * @param session the JCR session of the current user
-	 * @param absPath the path of the resource to check
-	 * @return true if the current user has the privileges, false otherwise
-	 */
-	public boolean canModifyProperties(Session session, String absPath) {
-		try {
-			AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
-			return accessControlManager.hasPrivileges(absPath, new Privilege[] {
-							accessControlManager.privilegeFromName(Privilege.JCR_MODIFY_PROPERTIES)
-						});
-		} catch (RepositoryException e) {
-			return false;
-		}
-	}
-	
-	/**
-	 * Checks whether the current user has been granted privileges
-	 * to read the access control of the specified node.
-	 *  
-	 * @param node the node to check
-	 * @return true if the current user has the privileges, false otherwise
-	 */
-	public boolean canReadAccessControl(Node node) {
-		try {
-			return canReadAccessControl(node.getSession(), node.getPath());
-		} catch (RepositoryException e) {
-			return false;
-		}
-	}
-	
-	/**
-	 * Checks whether the current user has been granted privileges
-	 * to read the access control of the specified path.
-	 *  
-	 * @param session the JCR session of the current user
-	 * @param absPath the path of the resource to check
-	 * @return true if the current user has the privileges, false otherwise
-	 */
-	public boolean canReadAccessControl(Session session, String absPath) {
-		try {
-			AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
-			return accessControlManager.hasPrivileges(absPath, new Privilege[] {
-							accessControlManager.privilegeFromName(Privilege.JCR_READ_ACCESS_CONTROL)
-						});
-		} catch (RepositoryException e) {
-			return false;
-		}
-	}
-	
-	/**
-	 * Checks whether the current user has been granted privileges
-	 * to modify the access control of the specified node.
-	 *  
-	 * @param node the node to check
-	 * @return true if the current user has the privileges, false otherwise
-	 */
-	public boolean canModifyAccessControl(Node node) {
-		try {
-			return canModifyAccessControl(node.getSession(), node.getPath());
-		} catch (RepositoryException e) {
-			return false;
-		}
-	}
-	
-	/**
-	 * Checks whether the current user has been granted privileges
-	 * to modify the access control of the specified path.
-	 *  
-	 * @param session the JCR session of the current user
-	 * @param absPath the path of the resource to check
-	 * @return true if the current user has the privileges, false otherwise
-	 */
-	public boolean canModifyAccessControl(Session session, String absPath) {
-		try {
-			AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
-			return accessControlManager.hasPrivileges(absPath, new Privilege[] {
-							accessControlManager.privilegeFromName(Privilege.JCR_MODIFY_ACCESS_CONTROL)
-						});
-		} catch (RepositoryException e) {
-			return false;
-		}
-	}
+    }
+
+    /**
+     * Returns the effective access rights for the specified Node for the given
+     * principalId.
+     * 
+     * @param node the JCR node to retrieve the access rights for
+     * @param principalId the principalId to get the access rights for
+     * @return access rights for the specified principal
+     * @throws RepositoryException if any errors reading the information
+     */
+    public AccessRights getEffectiveAccessRightsForPrincipal(Node node, String principalId) throws RepositoryException {
+        return getEffectiveAccessRightsForPrincipal(node.getSession(), node.getPath(), principalId);
+    }
+
+    /**
+     * Returns the effective access rights for the resource at the specified path for the given
+     * principalId.
+     *
+     * @param session the current JCR session
+     * @param absPath the path of the resource to retrieve the rights for
+     * @param principalId the principalId to get the access rights for
+     * @return access rights for the specified principal
+     * @throws RepositoryException if any errors reading the information
+     */
+    public AccessRights getEffectiveAccessRightsForPrincipal(Session session, String absPath, String principalId) throws RepositoryException {
+        AccessRights rights = new AccessRights();
+        if (principalId != null && principalId.length() > 0) {
+            AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
+            AccessControlPolicy[] policies = accessControlManager.getEffectivePolicies(absPath);
+            for (AccessControlPolicy accessControlPolicy : policies) {
+                if (accessControlPolicy instanceof AccessControlList) {
+                    AccessControlEntry[] accessControlEntries = ((AccessControlList)accessControlPolicy).getAccessControlEntries();
+                    for (AccessControlEntry ace : accessControlEntries) {
+                        if (principalId.equals(ace.getPrincipal().getName())) {
+                            boolean isAllow = AccessControlUtil.isAllow(ace);
+                            if (isAllow) {
+                                rights.getGranted().addAll(Arrays.asList(ace.getPrivileges()));
+                            } else {
+                                rights.getDenied().addAll(Arrays.asList(ace.getPrivileges()));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return rights;
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to add children to the specified node.
+     *
+     * @param node the node to check
+     * @return true if the current user has the privileges, false otherwise
+     */
+    public boolean canAddChildren(Node node) {
+        try {
+            return canAddChildren(node.getSession(), node.getPath());
+        } catch (RepositoryException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to add children to the specified path.
+     *
+     * @param session the JCR session of the current user
+     * @param absPath the path of the resource to check
+     * @return true if the current user has the privileges, false otherwise
+     */
+    public boolean canAddChildren(Session session, String absPath) {
+        try {
+            AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
+            return accessControlManager.hasPrivileges(absPath, new Privilege[] {
+                            accessControlManager.privilegeFromName(Privilege.JCR_ADD_CHILD_NODES)
+                        });
+        } catch (RepositoryException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to delete children to the specified node.
+     *
+     * @param node the node to check
+     * @return true if the current user has the privileges, false otherwise
+     */
+    public boolean canDeleteChildren(Node node) {
+        try {
+            return canDeleteChildren(node.getSession(), node.getPath());
+        } catch (RepositoryException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to delete children of the specified path.
+     *
+     * @param session the JCR session of the current user
+     * @param absPath the path of the resource to check
+     * @return true if the current user has the privileges, false otherwise
+     */
+    public boolean canDeleteChildren(Session session, String absPath) {
+        try {
+            AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
+            
+            return accessControlManager.hasPrivileges(absPath, new Privilege[] {
+                            accessControlManager.privilegeFromName(Privilege.JCR_REMOVE_CHILD_NODES)
+                        });
+        } catch (RepositoryException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to delete the specified node.
+     *
+     * @param node the node to check
+     * @return true if the current user has the privileges, false otherwise
+     */
+    public boolean canDelete(Node node) {
+        try {
+            return canDelete(node.getSession(), node.getPath());
+        } catch (RepositoryException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to delete the specified path.
+     *
+     * @param session the JCR session of the current user
+     * @param absPath the path of the resource to check
+     * @return true if the current user has the privileges, false otherwise
+     */
+    public boolean canDelete(Session session, String absPath) {
+        try {
+            AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
+
+            String parentPath;
+            int lastSlash = absPath.lastIndexOf('/');
+            if (lastSlash == 0) {
+                //the parent is the root folder.
+                parentPath = "/";
+            } else {
+                //strip the last segment
+                parentPath = absPath.substring(0, lastSlash);
+            }
+            return accessControlManager.hasPrivileges(absPath, new Privilege[] {
+                            accessControlManager.privilegeFromName(Privilege.JCR_REMOVE_NODE)
+                        }) && canDeleteChildren(session, parentPath);
+        } catch (RepositoryException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to modify properties of the specified node.
+     *
+     * @param node the node to check
+     * @return true if the current user has the privileges, false otherwise
+     */
+    public boolean canModifyProperties(Node node) {
+        try {
+            return canModifyProperties(node.getSession(), node.getPath());
+        } catch (RepositoryException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to modify properties of the specified path.
+     *
+     * @param session the JCR session of the current user
+     * @param absPath the path of the resource to check
+     * @return true if the current user has the privileges, false otherwise
+     */
+    public boolean canModifyProperties(Session session, String absPath) {
+        try {
+            AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
+            return accessControlManager.hasPrivileges(absPath, new Privilege[] {
+                            accessControlManager.privilegeFromName(Privilege.JCR_MODIFY_PROPERTIES)
+                        });
+        } catch (RepositoryException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to read the access control of the specified node.
+     *
+     * @param node the node to check
+     * @return true if the current user has the privileges, false otherwise
+     */
+    public boolean canReadAccessControl(Node node) {
+        try {
+            return canReadAccessControl(node.getSession(), node.getPath());
+        } catch (RepositoryException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to read the access control of the specified path.
+     *
+     * @param session the JCR session of the current user
+     * @param absPath the path of the resource to check
+     * @return true if the current user has the privileges, false otherwise
+     */
+    public boolean canReadAccessControl(Session session, String absPath) {
+        try {
+            AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
+            return accessControlManager.hasPrivileges(absPath, new Privilege[] {
+                            accessControlManager.privilegeFromName(Privilege.JCR_READ_ACCESS_CONTROL)
+                        });
+        } catch (RepositoryException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to modify the access control of the specified node.
+     *
+     * @param node the node to check
+     * @return true if the current user has the privileges, false otherwise
+     */
+    public boolean canModifyAccessControl(Node node) {
+        try {
+            return canModifyAccessControl(node.getSession(), node.getPath());
+        } catch (RepositoryException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to modify the access control of the specified path.
+     *
+     * @param session the JCR session of the current user
+     * @param absPath the path of the resource to check
+     * @return true if the current user has the privileges, false otherwise
+     */
+    public boolean canModifyAccessControl(Session session, String absPath) {
+        try {
+            AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
+            return accessControlManager.hasPrivileges(absPath, new Privilege[] {
+                            accessControlManager.privilegeFromName(Privilege.JCR_MODIFY_ACCESS_CONTROL)
+                        });
+        } catch (RepositoryException e) {
+            return false;
+        }
+    }
 
 }
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/impl/PrivilegesHelper.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/impl/PrivilegesHelper.java
index 4c5d716..0f182ef 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/impl/PrivilegesHelper.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/impl/PrivilegesHelper.java
@@ -56,7 +56,7 @@ public abstract class PrivilegesHelper {
             if (privilege.isAggregate()) {
                 Privilege[] ap = privilege.getAggregatePrivileges();
                 for (Privilege privilege2 : ap) {
-                	Set<Privilege> set = privilegeToAncestorMap.computeIfAbsent(privilege2, k -> new HashSet<>());
+                    Set<Privilege> set = privilegeToAncestorMap.computeIfAbsent(privilege2, k -> new HashSet<>());
                     set.add(privilege);
                 }
             }
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractGetAclServlet.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractGetAclServlet.java
index 70aa524..6151e0d 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractGetAclServlet.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractGetAclServlet.java
@@ -56,8 +56,8 @@ import org.apache.sling.jcr.jackrabbit.accessmanager.impl.PrivilegesHelper;
 public abstract class AbstractGetAclServlet extends SlingAllMethodsServlet {
 
     protected static final String KEY_ORDER = "order";
-	protected static final String KEY_DENIED = "denied";
-	protected static final String KEY_GRANTED = "granted";
+    protected static final String KEY_DENIED = "denied";
+    protected static final String KEY_GRANTED = "granted";
 
     /* (non-Javadoc)
      * @see org.apache.sling.api.servlets.SlingSafeMethodsServlet#doGet(org.apache.sling.api.SlingHttpServletRequest, org.apache.sling.api.SlingHttpServletResponse)
@@ -67,57 +67,57 @@ public abstract class AbstractGetAclServlet extends SlingAllMethodsServlet {
             SlingHttpServletResponse response) throws ServletException,
             IOException {
 
-		try {
-			Session session = request.getResourceResolver().adaptTo(Session.class);
-	    	String resourcePath = request.getResource().getPath();
+        try {
+            Session session = request.getResourceResolver().adaptTo(Session.class);
+            String resourcePath = request.getResource().getPath();
 
-	    	JsonObject acl = internalGetAcl(session, resourcePath);
-	        response.setContentType("application/json");
-	        response.setCharacterEncoding("UTF-8");
+            JsonObject acl = internalGetAcl(session, resourcePath);
+            response.setContentType("application/json");
+            response.setCharacterEncoding("UTF-8");
 
-	        boolean isTidy = false;
-	        final String[] selectors = request.getRequestPathInfo().getSelectors();
-	        if (selectors.length > 0) {
-	        	for (final String level : selectors) {
-		            if("tidy".equals(level)) {
-		            	isTidy = true;
-		            	break;
-		            }
-				}
-	        }
+            boolean isTidy = false;
+            final String[] selectors = request.getRequestPathInfo().getSelectors();
+            if (selectors.length > 0) {
+                for (final String level : selectors) {
+                    if("tidy".equals(level)) {
+                        isTidy = true;
+                        break;
+                    }
+                }
+            }
 
-	        Map<String, Object> options = new HashMap<>();
+            Map<String, Object> options = new HashMap<>();
             options.put(JsonGenerator.PRETTY_PRINTING, isTidy);
-	        try (JsonGenerator generator = Json.createGeneratorFactory(options).createGenerator(response.getWriter())) {
-				generator.write(acl).flush();
-	        }
+            try (JsonGenerator generator = Json.createGeneratorFactory(options).createGenerator(response.getWriter())) {
+                generator.write(acl).flush();
+            }
         } catch (AccessDeniedException ade) {
             response.sendError(HttpServletResponse.SC_NOT_FOUND);
         } catch (ResourceNotFoundException rnfe) {
             response.sendError(HttpServletResponse.SC_NOT_FOUND, rnfe.getMessage());
         } catch (Exception throwable) {
             throw new ServletException(String.format("Exception while handling GET %s with %s",
-                    						request.getResource().getPath(), getClass().getName()),
-            							throwable);
+                                            request.getResource().getPath(), getClass().getName()),
+                                        throwable);
         }
     }
 
     @SuppressWarnings("unchecked")
-	protected JsonObject internalGetAcl(Session jcrSession, String resourcePath) throws RepositoryException {
+    protected JsonObject internalGetAcl(Session jcrSession, String resourcePath) throws RepositoryException {
 
         if (jcrSession == null) {
             throw new RepositoryException("JCR Session not found");
         }
 
-		Item item = jcrSession.getItem(resourcePath);
-		if (item != null) {
-			resourcePath = item.getPath();
-		} else {
-			throw new ResourceNotFoundException("Resource is not a JCR Node");
-		}
+        Item item = jcrSession.getItem(resourcePath);
+        if (item != null) {
+            resourcePath = item.getPath();
+        } else {
+            throw new ResourceNotFoundException("Resource is not a JCR Node");
+        }
 
-		// Calculate a map of privileges to all the aggregate privileges it is contained in.
-		// Use for fast lookup during the mergePrivilegeSets calls below.
+        // Calculate a map of privileges to all the aggregate privileges it is contained in.
+        // Use for fast lookup during the mergePrivilegeSets calls below.
         Map<Privilege, Set<Privilege>> privilegeToAncestorMap = PrivilegesHelper.buildPrivilegeToAncestorMap(jcrSession, resourcePath);
 
         AccessControlEntry[] declaredAccessControlEntries = getAccessControlEntries(jcrSession, resourcePath);
@@ -136,32 +136,32 @@ public abstract class AbstractGetAclServlet extends SlingAllMethodsServlet {
         }
         //evaluate these in reverse order so the most entries with highest specificity are last
         for (int i = declaredAccessControlEntries.length - 1; i >= 0; i--) {
-			AccessControlEntry ace = declaredAccessControlEntries[i];
-			Principal principal = ace.getPrincipal();
+            AccessControlEntry ace = declaredAccessControlEntries[i];
+            Principal principal = ace.getPrincipal();
+
+            if (ace instanceof JackrabbitAccessControlEntry) {
+                JackrabbitAccessControlEntry jace = (JackrabbitAccessControlEntry)ace;
+                String[] restrictionNames = jace.getRestrictionNames();
+                if (restrictionNames != null) {
+                    Map<String, Object> restrictions = restrictionMap.get(principal.getName());
+                    if (restrictions == null) {
+                        restrictions = new HashMap<>();
+                        restrictionMap.put(principal.getName(), restrictions);
+                    }
+                    for (String rname : restrictionNames) {
+                        try {
+                            //try as a single-value restriction
+                            Value value = jace.getRestriction(rname);
+                            restrictions.put(rname, value);
+                        } catch (ValueFormatException vfe) {
+                            //try as a multi-value restriction
+                            Value[] values = jace.getRestrictions(rname);
+                            restrictions.put(rname, values);
+                        }
+                    }
+                }
+            }
 
-			if (ace instanceof JackrabbitAccessControlEntry) {
-				JackrabbitAccessControlEntry jace = (JackrabbitAccessControlEntry)ace;
-				String[] restrictionNames = jace.getRestrictionNames();
-				if (restrictionNames != null) {
-					Map<String, Object> restrictions = restrictionMap.get(principal.getName());
-					if (restrictions == null) {
-						restrictions = new HashMap<>();
-						restrictionMap.put(principal.getName(), restrictions);
-					}
-					for (String rname : restrictionNames) {
-						try {
-							//try as a single-value restriction
-							Value value = jace.getRestriction(rname);
-							restrictions.put(rname, value);
-						} catch (ValueFormatException vfe) {
-							//try as a multi-value restriction
-							Value[] values = jace.getRestrictions(rname);
-							restrictions.put(rname, values);
-						}
-					}
-				}
-			}
-			
             Map<String, Object> map = aclMap.get(principal.getName());
 
             Set<Privilege> grantedSet = (Set<Privilege>) map.get(KEY_GRANTED);
@@ -179,16 +179,16 @@ public abstract class AbstractGetAclServlet extends SlingAllMethodsServlet {
             if (allow) {
                 Privilege[] privileges = ace.getPrivileges();
                 for (Privilege privilege : privileges) {
-                	PrivilegesHelper.mergePrivilegeSets(privilege,
-                			privilegeToAncestorMap,
-							grantedSet, deniedSet);
+                    PrivilegesHelper.mergePrivilegeSets(privilege,
+                            privilegeToAncestorMap,
+                            grantedSet, deniedSet);
                 }
             } else {
                 Privilege[] privileges = ace.getPrivileges();
                 for (Privilege privilege : privileges) {
                     PrivilegesHelper.mergePrivilegeSets(privilege,
-                			privilegeToAncestorMap,
-							deniedSet, grantedSet);
+                            privilegeToAncestorMap,
+                            deniedSet, grantedSet);
                 }
             }
         }
@@ -225,25 +225,25 @@ public abstract class AbstractGetAclServlet extends SlingAllMethodsServlet {
 
             Map<String, Object> restrictions = restrictionMap.get(principalName);
             if (restrictions != null && !restrictions.isEmpty()) {
-            	Set<Entry<String, Object>> entrySet2 = restrictions.entrySet();
-            	JsonObjectBuilder jsonRestrictions = Json.createObjectBuilder();
-            	for (Entry<String, Object> entry2 : entrySet2) {
-    				Object rvalue = entry2.getValue();
-    				if (rvalue != null) {
-    					if (rvalue.getClass().isArray()) {
-    		                JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
-    		                int length = Array.getLength(rvalue);
-    		                for (int i= 0; i  < length; i++) {
-    		                	Object object = Array.get(rvalue, i);
-    		                	addTo(arrayBuilder, object);
-    		                }
-    		                jsonRestrictions.add(entry2.getKey(), arrayBuilder);
-    					} else {
-    						addTo(jsonRestrictions, entry2.getKey(), rvalue);
-    					}
-    				}
-    			}
-            	aceObject.add("restrictions", jsonRestrictions);
+                Set<Entry<String, Object>> entrySet2 = restrictions.entrySet();
+                JsonObjectBuilder jsonRestrictions = Json.createObjectBuilder();
+                for (Entry<String, Object> entry2 : entrySet2) {
+                    Object rvalue = entry2.getValue();
+                    if (rvalue != null) {
+                        if (rvalue.getClass().isArray()) {
+                            JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
+                            int length = Array.getLength(rvalue);
+                            for (int i= 0; i  < length; i++) {
+                                Object object = Array.get(rvalue, i);
+                                addTo(arrayBuilder, object);
+                            }
+                            jsonRestrictions.add(entry2.getKey(), arrayBuilder);
+                        } else {
+                            addTo(jsonRestrictions, entry2.getKey(), rvalue);
+                        }
+                    }
+                }
+                aceObject.add("restrictions", jsonRestrictions);
             }
             
             aclList.add(aceObject.build());
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/DeleteAcesServlet.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/DeleteAcesServlet.java
index 7087de4..c9a70d3 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/DeleteAcesServlet.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/DeleteAcesServlet.java
@@ -83,158 +83,157 @@ import org.slf4j.LoggerFactory;
 
 @Component(service = {Servlet.class, DeleteAces.class},
     property= {
-    		"sling.servlet.resourceTypes=sling/servlet/default",
-    		"sling.servlet.methods=POST",
-    		"sling.servlet.selectors=deleteAce",
-    		"sling.servlet.prefix:Integer=-1"
+            "sling.servlet.resourceTypes=sling/servlet/default",
+            "sling.servlet.methods=POST",
+            "sling.servlet.selectors=deleteAce",
+            "sling.servlet.prefix:Integer=-1"
     })
 public class DeleteAcesServlet extends AbstractAccessPostServlet implements DeleteAces {
-	private static final long serialVersionUID = 3784866802938282971L;
+    private static final long serialVersionUID = 3784866802938282971L;
 
-	/**
+    /**
      * default log
      */
     private final transient Logger log = LoggerFactory.getLogger(getClass());
 
     /**
      * Overridden since the @Reference annotation is not inherited from the super method
-	 */
-	@Override
+     */
+    @Override
     @Reference(service = PostResponseCreator.class,
-	    cardinality = ReferenceCardinality.MULTIPLE,
-	    policy = ReferencePolicy.DYNAMIC)
-	protected void bindPostResponseCreator(PostResponseCreator creator, Map<String, Object> properties) {
-		super.bindPostResponseCreator(creator, properties);
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.apache.sling.jackrabbit.usermanager.impl.post.AbstractPostServlet#unbindPostResponseCreator(org.apache.sling.servlets.post.PostResponseCreator, java.util.Map)
-	 */
-	@Override
-	protected void unbindPostResponseCreator(PostResponseCreator creator, Map<String, Object> properties) { //NOSONAR
-		super.unbindPostResponseCreator(creator, properties);
-	}
-    
-	
-	/* (non-Javadoc)
-	 * @see org.apache.sling.jackrabbit.accessmanager.post.AbstractAccessPostServlet#handleOperation(org.apache.sling.api.SlingHttpServletRequest, org.apache.sling.servlets.post.PostResponse, java.util.List)
-	 */
-	@Override
-	protected void handleOperation(SlingHttpServletRequest request,
-			PostResponse htmlResponse, List<Modification> changes)
-			throws RepositoryException {
-
-		Session session = request.getResourceResolver().adaptTo(Session.class);
-    	String resourcePath = request.getResource().getPath();
+        cardinality = ReferenceCardinality.MULTIPLE,
+        policy = ReferencePolicy.DYNAMIC)
+    protected void bindPostResponseCreator(PostResponseCreator creator, Map<String, Object> properties) {
+        super.bindPostResponseCreator(creator, properties);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.sling.jackrabbit.usermanager.impl.post.AbstractPostServlet#unbindPostResponseCreator(org.apache.sling.servlets.post.PostResponseCreator, java.util.Map)
+     */
+    @Override
+    protected void unbindPostResponseCreator(PostResponseCreator creator, Map<String, Object> properties) { //NOSONAR
+        super.unbindPostResponseCreator(creator, properties);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.sling.jackrabbit.accessmanager.post.AbstractAccessPostServlet#handleOperation(org.apache.sling.api.SlingHttpServletRequest, org.apache.sling.servlets.post.PostResponse, java.util.List)
+     */
+    @Override
+    protected void handleOperation(SlingHttpServletRequest request,
+            PostResponse htmlResponse, List<Modification> changes)
+            throws RepositoryException {
+
+        Session session = request.getResourceResolver().adaptTo(Session.class);
+        String resourcePath = request.getResource().getPath();
         String[] applyTo = request.getParameterValues(SlingPostConstants.RP_APPLY_TO);
         deleteAces(session, resourcePath, applyTo, changes);
-	}
-
-	/* (non-Javadoc)
-	 * @see org.apache.sling.jcr.jackrabbit.accessmanager.DeleteAces#deleteAces(javax.jcr.Session, java.lang.String, java.lang.String[])
-	 */
-	public void deleteAces(Session jcrSession, String resourcePath,
-			String[] principalNamesToDelete) throws RepositoryException {
-		deleteAces(jcrSession, resourcePath, principalNamesToDelete, null);
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.apache.sling.jcr.jackrabbit.accessmanager.DeleteAces#deleteAces(javax.jcr.Session, java.lang.String, java.lang.String[])
-	 */
-	protected void deleteAces(Session jcrSession, String resourcePath,
-			String[] principalNamesToDelete, List<Modification> changes) throws RepositoryException {
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.sling.jcr.jackrabbit.accessmanager.DeleteAces#deleteAces(javax.jcr.Session, java.lang.String, java.lang.String[])
+     */
+    public void deleteAces(Session jcrSession, String resourcePath,
+            String[] principalNamesToDelete) throws RepositoryException {
+        deleteAces(jcrSession, resourcePath, principalNamesToDelete, null);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.sling.jcr.jackrabbit.accessmanager.DeleteAces#deleteAces(javax.jcr.Session, java.lang.String, java.lang.String[])
+     */
+    protected void deleteAces(Session jcrSession, String resourcePath,
+            String[] principalNamesToDelete, List<Modification> changes) throws RepositoryException {
         if (principalNamesToDelete == null) {
-			throw new RepositoryException("principalIds were not sumitted.");
+            throw new RepositoryException("principalIds were not sumitted.");
         } else {
-    		if (jcrSession == null) {
-    			throw new RepositoryException("JCR Session not found");
-    		}
-
-        	if (resourcePath == null) {
-    			throw new ResourceNotFoundException("Resource path was not supplied.");
-        	}
-
-    		Item item = jcrSession.getItem(resourcePath);
-    		if (item != null) {
-    			resourcePath = item.getPath();
-    		} else {
-    			throw new ResourceNotFoundException("Resource is not a JCR Node");
-    		}
-
-    		//load the principalIds array into a set for quick lookup below
-			Set<String> pidSet = new HashSet<>();
-			pidSet.addAll(Arrays.asList(principalNamesToDelete));
-
-			// validate that the submitted names are valid
-			Set<String> notFound = null;
-			Set<Principal> found = new HashSet<>();
-			PrincipalManager principalManager = AccessControlUtil.getPrincipalManager(jcrSession);
-			for (String pid : pidSet) {
-				Principal principal = principalManager.getPrincipal(pid);
-				if (principal == null) {
-					if (notFound == null) {
-						notFound = new HashSet<>();
-					}
-					notFound.add(pid);
-				} else {
-					found.add(principal);
-				}
-			}
-			if (notFound != null && !notFound.isEmpty()) {
-				throw new RepositoryException("Invalid principalId was submitted.");
-			}
-			
-			try {
-				AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(jcrSession);
-				AccessControlList updatedAcl = getAccessControlListOrNull(accessControlManager, resourcePath, false);
-
-				// if there is no AccessControlList, then there is nothing to be deleted
-				if (updatedAcl == null) {
-					// log the warning about principals where no ACE was found
-					for (Principal principal : found) {
-						log.warn("No AccessControlEntry was found to be deleted for principal: {}", principal.getName());
-					}
-				} else {
-					//keep track of the existing Aces for the target principal
-					AccessControlEntry[] accessControlEntries = updatedAcl.getAccessControlEntries();
-					List<AccessControlEntry> oldAces = new ArrayList<>();
-					for (AccessControlEntry ace : accessControlEntries) {
-						if (pidSet.contains(ace.getPrincipal().getName())) {
-							oldAces.add(ace);
-						}
-					}
-
-					// track which of the submitted principals had an ACE removed
-					Set<Principal> removedPrincipalSet = new HashSet<>();
-					
-					//remove the old aces
-					if (!oldAces.isEmpty()) {
-						for (AccessControlEntry ace : oldAces) {
-							updatedAcl.removeAccessControlEntry(ace);
-					
-							// remove from the candidate set
-							removedPrincipalSet.add(ace.getPrincipal());
-						}
-					}
-
-					// log the warning about principals where no ACE was found
-					for (Principal principal : found) {
-						if (removedPrincipalSet.contains(principal)) {
-							if (changes != null) {
-								changes.add(Modification.onDeleted(principal.getName()));
-							}
-						} else {
-							log.warn("No AccessControlEntry was found to be deleted for principal: {}", principal.getName());
-						}
-					}
-
-					//apply the changed policy
-					accessControlManager.setPolicy(resourcePath, updatedAcl);
-				}
-			} catch (RepositoryException re) {
-				throw new RepositoryException("Failed to delete access control.", re);
-			}
+            if (jcrSession == null) {
+                throw new RepositoryException("JCR Session not found");
+            }
+
+            if (resourcePath == null) {
+                throw new ResourceNotFoundException("Resource path was not supplied.");
+            }
+
+            Item item = jcrSession.getItem(resourcePath);
+            if (item != null) {
+                resourcePath = item.getPath();
+            } else {
+                throw new ResourceNotFoundException("Resource is not a JCR Node");
+            }
+
+            //load the principalIds array into a set for quick lookup below
+            Set<String> pidSet = new HashSet<>();
+            pidSet.addAll(Arrays.asList(principalNamesToDelete));
+
+            // validate that the submitted names are valid
+            Set<String> notFound = null;
+            Set<Principal> found = new HashSet<>();
+            PrincipalManager principalManager = AccessControlUtil.getPrincipalManager(jcrSession);
+            for (String pid : pidSet) {
+                Principal principal = principalManager.getPrincipal(pid);
+                if (principal == null) {
+                    if (notFound == null) {
+                        notFound = new HashSet<>();
+                    }
+                    notFound.add(pid);
+                } else {
+                    found.add(principal);
+                }
+            }
+            if (notFound != null && !notFound.isEmpty()) {
+                throw new RepositoryException("Invalid principalId was submitted.");
+            }
+            
+            try {
+                AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(jcrSession);
+                AccessControlList updatedAcl = getAccessControlListOrNull(accessControlManager, resourcePath, false);
+
+                // if there is no AccessControlList, then there is nothing to be deleted
+                if (updatedAcl == null) {
+                    // log the warning about principals where no ACE was found
+                    for (Principal principal : found) {
+                        log.warn("No AccessControlEntry was found to be deleted for principal: {}", principal.getName());
+                    }
+                } else {
+                    //keep track of the existing Aces for the target principal
+                    AccessControlEntry[] accessControlEntries = updatedAcl.getAccessControlEntries();
+                    List<AccessControlEntry> oldAces = new ArrayList<>();
+                    for (AccessControlEntry ace : accessControlEntries) {
+                        if (pidSet.contains(ace.getPrincipal().getName())) {
+                            oldAces.add(ace);
+                        }
+                    }
+
+                    // track which of the submitted principals had an ACE removed
+                    Set<Principal> removedPrincipalSet = new HashSet<>();
+
+                    //remove the old aces
+                    if (!oldAces.isEmpty()) {
+                        for (AccessControlEntry ace : oldAces) {
+                            updatedAcl.removeAccessControlEntry(ace);
+
+                            // remove from the candidate set
+                            removedPrincipalSet.add(ace.getPrincipal());
+                        }
+                    }
+
+                    // log the warning about principals where no ACE was found
+                    for (Principal principal : found) {
+                        if (removedPrincipalSet.contains(principal)) {
+                            if (changes != null) {
+                                changes.add(Modification.onDeleted(principal.getName()));
+                            }
+                        } else {
+                            log.warn("No AccessControlEntry was found to be deleted for principal: {}", principal.getName());
+                        }
+                    }
+
+                    //apply the changed policy
+                    accessControlManager.setPolicy(resourcePath, updatedAcl);
+                }
+            } catch (RepositoryException re) {
+                throw new RepositoryException("Failed to delete access control.", re);
+            }
         }
-	}
-	
+    }
+
 }
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetAclServlet.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetAclServlet.java
index 66c6c94..31e165f 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetAclServlet.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetAclServlet.java
@@ -100,36 +100,36 @@ import org.osgi.service.component.annotations.Component;
 
 @Component(service = {Servlet.class, GetAcl.class},
 property= {
-		"sling.servlet.resourceTypes=sling/servlet/default",
-		"sling.servlet.methods=GET",
-		"sling.servlet.selectors=acl",
-		"sling.servlet.selectors=tidy.acl",
-		"sling.servlet.extensions=json",
-		"sling.servlet.prefix:Integer=-1"
+        "sling.servlet.resourceTypes=sling/servlet/default",
+        "sling.servlet.methods=GET",
+        "sling.servlet.selectors=acl",
+        "sling.servlet.selectors=tidy.acl",
+        "sling.servlet.extensions=json",
+        "sling.servlet.prefix:Integer=-1"
 })
 public class GetAclServlet extends AbstractGetAclServlet implements GetAcl {
-	private static final long serialVersionUID = 3391376559396223185L;
+    private static final long serialVersionUID = 3391376559396223185L;
 
-	/* (non-Javadoc)
-	 * @see org.apache.sling.jcr.jackrabbit.accessmanager.GetAcl#getAcl(javax.jcr.Session, java.lang.String)
-	 */
-	public JsonObject getAcl(Session jcrSession, String resourcePath)
-			throws RepositoryException {
-		return internalGetAcl(jcrSession, resourcePath);
-	}
+    /* (non-Javadoc)
+     * @see org.apache.sling.jcr.jackrabbit.accessmanager.GetAcl#getAcl(javax.jcr.Session, java.lang.String)
+     */
+    public JsonObject getAcl(Session jcrSession, String resourcePath)
+            throws RepositoryException {
+        return internalGetAcl(jcrSession, resourcePath);
+    }
 
-	@Override
-	protected AccessControlEntry[] getAccessControlEntries(Session session, String absPath) throws RepositoryException {
-		AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
-		AccessControlPolicy[] policies = accessControlManager.getPolicies(absPath);
+    @Override
+    protected AccessControlEntry[] getAccessControlEntries(Session session, String absPath) throws RepositoryException {
+        AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
+        AccessControlPolicy[] policies = accessControlManager.getPolicies(absPath);
         List<AccessControlEntry> allEntries = new ArrayList<>(); 
-		for (AccessControlPolicy accessControlPolicy : policies) {
-			if (accessControlPolicy instanceof AccessControlList) {
-				AccessControlEntry[] accessControlEntries = ((AccessControlList)accessControlPolicy).getAccessControlEntries();
-				allEntries.addAll(Arrays.asList(accessControlEntries));
-			}
-		}
+        for (AccessControlPolicy accessControlPolicy : policies) {
+            if (accessControlPolicy instanceof AccessControlList) {
+                AccessControlEntry[] accessControlEntries = ((AccessControlList)accessControlPolicy).getAccessControlEntries();
+                allEntries.addAll(Arrays.asList(accessControlEntries));
+            }
+        }
         return allEntries.toArray(new AccessControlEntry[allEntries.size()]);
-	}
+    }
 
 }
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetEffectiveAclServlet.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetEffectiveAclServlet.java
index 432a08e..dfc04dd 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetEffectiveAclServlet.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetEffectiveAclServlet.java
@@ -100,25 +100,25 @@ import org.osgi.service.component.annotations.Component;
 
 @Component(service = {Servlet.class, GetEffectiveAcl.class},
 property= {
-		"sling.servlet.resourceTypes=sling/servlet/default",
-		"sling.servlet.methods=GET",
-		"sling.servlet.selectors=eacl",
-		"sling.servlet.selectors=tidy.eacl",
-		"sling.servlet.extensions=json",
-		"sling.servlet.prefix:Integer=-1"
+        "sling.servlet.resourceTypes=sling/servlet/default",
+        "sling.servlet.methods=GET",
+        "sling.servlet.selectors=eacl",
+        "sling.servlet.selectors=tidy.eacl",
+        "sling.servlet.extensions=json",
+        "sling.servlet.prefix:Integer=-1"
 })
 @SuppressWarnings("serial")
 public class GetEffectiveAclServlet extends AbstractGetAclServlet implements GetEffectiveAcl {
 
     /* (non-Javadoc)
-	 * @see org.apache.sling.jcr.jackrabbit.accessmanager.GetEffectiveAcl#getEffectiveAcl(javax.jcr.Session, java.lang.String)
-	 */
-	public JsonObject getEffectiveAcl(Session jcrSession, String resourcePath)
-			throws RepositoryException {
-		return internalGetAcl(jcrSession, resourcePath);
-	}
+     * @see org.apache.sling.jcr.jackrabbit.accessmanager.GetEffectiveAcl#getEffectiveAcl(javax.jcr.Session, java.lang.String)
+     */
+    public JsonObject getEffectiveAcl(Session jcrSession, String resourcePath)
+            throws RepositoryException {
+        return internalGetAcl(jcrSession, resourcePath);
+    }
 
-	@Override
+    @Override
     protected AccessControlEntry[] getAccessControlEntries(Session session, String absPath) throws RepositoryException {
         AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
         AccessControlPolicy[] policies = accessControlManager.getEffectivePolicies(absPath);
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/ModifyAceServlet.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/ModifyAceServlet.java
index 56d32c9..f4541ac 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/ModifyAceServlet.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/ModifyAceServlet.java
@@ -97,242 +97,241 @@ import org.osgi.service.component.annotations.ReferencePolicyOption;
 
 @Component(service = {Servlet.class, ModifyAce.class},
 property= {
-		"sling.servlet.resourceTypes=sling/servlet/default",
-		"sling.servlet.methods=POST",
-		"sling.servlet.selectors=modifyAce",
-		"sling.servlet.prefix:Integer=-1"
+        "sling.servlet.resourceTypes=sling/servlet/default",
+        "sling.servlet.methods=POST",
+        "sling.servlet.selectors=modifyAce",
+        "sling.servlet.prefix:Integer=-1"
 })
 public class ModifyAceServlet extends AbstractAccessPostServlet implements ModifyAce {
-	private static final long serialVersionUID = -9182485466670280437L;
+    private static final long serialVersionUID = -9182485466670280437L;
 
-	private transient RestrictionProvider restrictionProvider = null;
+    private transient RestrictionProvider restrictionProvider = null;
 
-	// NOTE: the @Reference annotation is not inherited, so subclasses will need to override the #bindRestrictionProvider 
-	// and #unbindRestrictionProvider methods to provide the @Reference annotation.     
-	//
+    // NOTE: the @Reference annotation is not inherited, so subclasses will need to override the #bindRestrictionProvider 
+    // and #unbindRestrictionProvider methods to provide the @Reference annotation.     
+    //
     @Reference(cardinality=ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC, policyOption=ReferencePolicyOption.GREEDY)
     protected void bindRestrictionProvider(RestrictionProvider rp) {
-    	this.restrictionProvider = rp;
+        this.restrictionProvider = rp;
     }
     protected void unbindRestrictionProvider(RestrictionProvider rp) { //NOSONAR
-    	this.restrictionProvider = null;
+        this.restrictionProvider = null;
     }
-    
+
     /**
      * Overridden since the @Reference annotation is not inherited from the super method
-	 */
-	@Override
+     */
+    @Override
     @Reference(service = PostResponseCreator.class,
-	    cardinality = ReferenceCardinality.MULTIPLE,
-	    policy = ReferencePolicy.DYNAMIC)
-	protected void bindPostResponseCreator(PostResponseCreator creator, Map<String, Object> properties) {
-		super.bindPostResponseCreator(creator, properties);
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.apache.sling.jackrabbit.usermanager.impl.post.AbstractPostServlet#unbindPostResponseCreator(org.apache.sling.servlets.post.PostResponseCreator, java.util.Map)
-	 */
-	@Override
-	protected void unbindPostResponseCreator(PostResponseCreator creator, Map<String, Object> properties) { //NOSONAR
-		super.unbindPostResponseCreator(creator, properties);
-	}
+        cardinality = ReferenceCardinality.MULTIPLE,
+        policy = ReferencePolicy.DYNAMIC)
+    protected void bindPostResponseCreator(PostResponseCreator creator, Map<String, Object> properties) {
+        super.bindPostResponseCreator(creator, properties);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.sling.jackrabbit.usermanager.impl.post.AbstractPostServlet#unbindPostResponseCreator(org.apache.sling.servlets.post.PostResponseCreator, java.util.Map)
+     */
+    @Override
+    protected void unbindPostResponseCreator(PostResponseCreator creator, Map<String, Object> properties) { //NOSONAR
+        super.unbindPostResponseCreator(creator, properties);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.sling.jackrabbit.accessmanager.post.AbstractAccessPostServlet#handleOperation(org.apache.sling.api.SlingHttpServletRequest, org.apache.sling.servlets.post.PostResponse, java.util.List)
+     */
+    @Override
+    protected void handleOperation(SlingHttpServletRequest request,
+            PostResponse response, List<Modification> changes)
+            throws RepositoryException {
+        Session session = request.getResourceResolver().adaptTo(Session.class);
+        String resourcePath = request.getResource().getPath();
+        String principalId = request.getParameter("principalId");
+        Map<String, String> privileges = new HashMap<>();
+        Map<String, Value> restrictions = new HashMap<>();
+        Map<String, Value[]> mvRestrictions = new HashMap<>();
+        Set<String> removeRestrictionNames = new HashSet<>();
+
+        //lazy initialized map for quick lookup when processing POSTed restrictions
+        Map<String, RestrictionDefinition> supportedRestrictionsMap = null;
+        ValueFactory factory = session.getValueFactory();
+
+        Enumeration<?> parameterNames = request.getParameterNames();
+        while (parameterNames.hasMoreElements()) {
+            Object nextElement = parameterNames.nextElement();
+            if (nextElement instanceof String) {
+                String paramName = (String)nextElement;
+                if (paramName.startsWith("privilege@")) {
+                    String privilegeName = paramName.substring(10);
+                    String parameterValue = request.getParameter(paramName);
+                    privileges.put(privilegeName, parameterValue);
+                } else if (paramName.startsWith("restriction@")) {
+                    if (restrictionProvider == null) {
+                        throw new IllegalArgumentException("No restriction provider is available so unable to process POSTed restriction values");
+                    }
+                    if (supportedRestrictionsMap == null) {
+                        supportedRestrictionsMap = new HashMap<>();
+
+                        //populate the map for quick lookup below
+                        Set<RestrictionDefinition> supportedRestrictions = restrictionProvider.getSupportedRestrictions(resourcePath);
+                        for (RestrictionDefinition restrictionDefinition : supportedRestrictions) {
+                            supportedRestrictionsMap.put(restrictionDefinition.getName(), restrictionDefinition);
+                        }
+                    }
+
+                    if (paramName.endsWith("@Delete")) {
+                        String restrictionName = paramName.substring(12, paramName.length() - 7);
+                        removeRestrictionNames.add(restrictionName);
+                    } else {
+                        String restrictionName = paramName.substring(12);
+                        String[] parameterValues = request.getParameterValues(paramName);
+                        if (parameterValues != null) {
+                            RestrictionDefinition rd = supportedRestrictionsMap.get(restrictionName);
+                            if (rd == null) {
+                                //illegal restriction name?
+                                throw new IllegalArgumentException("Invalid or not supported restriction name was supplied");
+                            }
+
+                            boolean multival = rd.getRequiredType().isArray();
+                            int restrictionType = rd.getRequiredType().tag();
+
+                            if (multival) {
+                                Value [] v = new Value[parameterValues.length];
+                                for (int j = 0; j < parameterValues.length; j++) {
+                                    String string = parameterValues[j];
+                                    v[j] = factory.createValue(string, restrictionType);
+                                }
+
+                                mvRestrictions.put(restrictionName, v);
+                            } else if (parameterValues.length > 0) {
+                                Value v = factory.createValue(parameterValues[0], restrictionType);
+                                restrictions.put(restrictionName, v);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        String order = request.getParameter("order");
+        modifyAce(session, resourcePath, principalId, privileges, order, restrictions, mvRestrictions, 
+                removeRestrictionNames, false, changes);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.sling.jcr.jackrabbit.accessmanager.ModifyAce#modifyAce(javax.jcr.Session, java.lang.String, java.lang.String, java.util.Map, java.lang.String, boolean)
+     */
+    @Override
+    public void modifyAce(Session jcrSession, String resourcePath, String principalId, Map<String, String> privileges,
+            String order, boolean autoSave) throws RepositoryException {
+        modifyAce(jcrSession, resourcePath, principalId, privileges, order, 
+                null, null, null, autoSave);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.sling.jcr.jackrabbit.accessmanager.ModifyAce#modifyAce(javax.jcr.Session, java.lang.String, java.lang.String, java.util.Map, java.lang.String)
+     */
+    public void modifyAce(Session jcrSession, String resourcePath,
+            String principalId, Map<String, String> privileges, String order)
+            throws RepositoryException {
+        modifyAce(jcrSession, resourcePath, principalId, privileges, order, true);
+    }
     
-	
-	/* (non-Javadoc)
-	 * @see org.apache.sling.jackrabbit.accessmanager.post.AbstractAccessPostServlet#handleOperation(org.apache.sling.api.SlingHttpServletRequest, org.apache.sling.servlets.post.PostResponse, java.util.List)
-	 */
-	@Override
-	protected void handleOperation(SlingHttpServletRequest request,
-			PostResponse response, List<Modification> changes)
-			throws RepositoryException {
-		Session session = request.getResourceResolver().adaptTo(Session.class);
-    	String resourcePath = request.getResource().getPath();
-		String principalId = request.getParameter("principalId");
-		Map<String, String> privileges = new HashMap<>();
-		Map<String, Value> restrictions = new HashMap<>();
-		Map<String, Value[]> mvRestrictions = new HashMap<>();
-		Set<String> removeRestrictionNames = new HashSet<>();
+    /* (non-Javadoc)
+     * @see org.apache.sling.jcr.jackrabbit.accessmanager.ModifyAce#modifyAce(javax.jcr.Session, java.lang.String, java.lang.String, java.util.Map, java.lang.String, java.util.Map, java.util.Map, java.util.Set)
+     */
+    @Override
+    public void modifyAce(Session jcrSession, String resourcePath, String principalId, Map<String, String> privileges,
+            String order, Map<String, Value> restrictions, Map<String, Value[]> mvRestrictions,
+            Set<String> removeRestrictionNames) throws RepositoryException {
+        modifyAce(jcrSession, resourcePath, principalId, privileges, order, 
+                restrictions, mvRestrictions, removeRestrictionNames, true);
+    }
 
-		//lazy initialized map for quick lookup when processing POSTed restrictions
-		Map<String, RestrictionDefinition> supportedRestrictionsMap = null;
-		ValueFactory factory = session.getValueFactory();
+    /* (non-Javadoc)
+     * @see org.apache.sling.jcr.jackrabbit.accessmanager.ModifyAce#modifyAce(javax.jcr.Session, java.lang.String, java.lang.String, java.util.Map, java.lang.String, java.util.Map, java.util.Map, java.util.Set, boolean)
+     */
+    @Override
+    public void modifyAce(Session jcrSession, String resourcePath, String principalId, Map<String, String> privileges,
+            String order, Map<String, Value> restrictions, Map<String, Value[]> mvRestrictions,
+            Set<String> removeRestrictionNames, boolean autoSave) throws RepositoryException {
+        modifyAce(jcrSession, resourcePath, principalId, privileges, order, 
+                restrictions, mvRestrictions, removeRestrictionNames, autoSave, null);
+    }
 
-		Enumeration<?> parameterNames = request.getParameterNames();
-		while (parameterNames.hasMoreElements()) {
-			Object nextElement = parameterNames.nextElement();
-			if (nextElement instanceof String) {
-				String paramName = (String)nextElement;
-				if (paramName.startsWith("privilege@")) {
-					String privilegeName = paramName.substring(10);
-					String parameterValue = request.getParameter(paramName);
-					privileges.put(privilegeName, parameterValue);
-				} else if (paramName.startsWith("restriction@")) {
-					if (restrictionProvider == null) {
-						throw new IllegalArgumentException("No restriction provider is available so unable to process POSTed restriction values");
-					}
-					if (supportedRestrictionsMap == null) {
-						supportedRestrictionsMap = new HashMap<>();
+    protected void modifyAce(Session jcrSession, String resourcePath, String principalId, Map<String, String> privileges,
+            String order, Map<String, Value> restrictions, Map<String, Value[]> mvRestrictions,
+            Set<String> removeRestrictionNames, boolean autoSave, List<Modification> changes) throws RepositoryException {
+        if (jcrSession == null) {
+            throw new RepositoryException("JCR Session not found");
+        }
 
-						//populate the map for quick lookup below
-						Set<RestrictionDefinition> supportedRestrictions = restrictionProvider.getSupportedRestrictions(resourcePath);
-						for (RestrictionDefinition restrictionDefinition : supportedRestrictions) {
-							supportedRestrictionsMap.put(restrictionDefinition.getName(), restrictionDefinition);
-						}
-					}
-					
-					if (paramName.endsWith("@Delete")) {
-						String restrictionName = paramName.substring(12, paramName.length() - 7);
-						removeRestrictionNames.add(restrictionName);
-					} else {
-						String restrictionName = paramName.substring(12);
-						String[] parameterValues = request.getParameterValues(paramName);
-						if (parameterValues != null) {
-							RestrictionDefinition rd = supportedRestrictionsMap.get(restrictionName);
-							if (rd == null) {
-								//illegal restriction name?
-								throw new IllegalArgumentException("Invalid or not supported restriction name was supplied");
-							}
-							
-							boolean multival = rd.getRequiredType().isArray();
-							int restrictionType = rd.getRequiredType().tag();
-							
-							if (multival) {
-								Value [] v = new Value[parameterValues.length];
-								for (int j = 0; j < parameterValues.length; j++) {
-									String string = parameterValues[j];
-									v[j] = factory.createValue(string, restrictionType);
-								}
+        if (principalId == null) {
+            throw new RepositoryException("principalId was not submitted.");
+        }
 
-								mvRestrictions.put(restrictionName, v);
-							} else if (parameterValues.length > 0) {
-								Value v = factory.createValue(parameterValues[0], restrictionType);
-								restrictions.put(restrictionName, v);
-							}
-						}
-					}
-				}
-			}
-		}
-		String order = request.getParameter("order");
-    	modifyAce(session, resourcePath, principalId, privileges, order, restrictions, mvRestrictions, 
-    			removeRestrictionNames, false, changes);
-	}
-	
+        // validate that the submitted name is valid
+        PrincipalManager principalManager = AccessControlUtil.getPrincipalManager(jcrSession);
+        Principal principal = principalManager.getPrincipal(principalId);
+        if (principal == null) {
+            throw new RepositoryException("Invalid principalId was submitted.");
+        }
 
-	/* (non-Javadoc)
-	 * @see org.apache.sling.jcr.jackrabbit.accessmanager.ModifyAce#modifyAce(javax.jcr.Session, java.lang.String, java.lang.String, java.util.Map, java.lang.String, boolean)
-	 */
-	@Override
-	public void modifyAce(Session jcrSession, String resourcePath, String principalId, Map<String, String> privileges,
-			String order, boolean autoSave) throws RepositoryException {
-		modifyAce(jcrSession, resourcePath, principalId, privileges, order, 
-				null, null, null, autoSave);
-	}
+        if (resourcePath == null) {
+            throw new ResourceNotFoundException("Resource path was not supplied.");
+        }
 
-	/* (non-Javadoc)
-	 * @see org.apache.sling.jcr.jackrabbit.accessmanager.ModifyAce#modifyAce(javax.jcr.Session, java.lang.String, java.lang.String, java.util.Map, java.lang.String)
-	 */
-	public void modifyAce(Session jcrSession, String resourcePath,
-			String principalId, Map<String, String> privileges, String order)
-			throws RepositoryException {
-		modifyAce(jcrSession, resourcePath, principalId, privileges, order, true);
-	}
-	/* (non-Javadoc)
-	 * @see org.apache.sling.jcr.jackrabbit.accessmanager.ModifyAce#modifyAce(javax.jcr.Session, java.lang.String, java.lang.String, java.util.Map, java.lang.String, java.util.Map, java.util.Map, java.util.Set)
-	 */
-	@Override
-	public void modifyAce(Session jcrSession, String resourcePath, String principalId, Map<String, String> privileges,
-			String order, Map<String, Value> restrictions, Map<String, Value[]> mvRestrictions,
-			Set<String> removeRestrictionNames) throws RepositoryException {
-		modifyAce(jcrSession, resourcePath, principalId, privileges, order, 
-				restrictions, mvRestrictions, removeRestrictionNames, true);
-	}	
+        Item item = jcrSession.getItem(resourcePath);
+        if (item != null) {
+            resourcePath = item.getPath();
+        } else {
+            throw new ResourceNotFoundException("Resource is not a JCR Node");
+        }
 
-	/* (non-Javadoc)
-	 * @see org.apache.sling.jcr.jackrabbit.accessmanager.ModifyAce#modifyAce(javax.jcr.Session, java.lang.String, java.lang.String, java.util.Map, java.lang.String, java.util.Map, java.util.Map, java.util.Set, boolean)
-	 */
-	@Override
-	public void modifyAce(Session jcrSession, String resourcePath, String principalId, Map<String, String> privileges,
-			String order, Map<String, Value> restrictions, Map<String, Value[]> mvRestrictions,
-			Set<String> removeRestrictionNames, boolean autoSave) throws RepositoryException {
-		modifyAce(jcrSession, resourcePath, principalId, privileges, order, 
-				restrictions, mvRestrictions, removeRestrictionNames, autoSave, null);
-	}
-	
-	protected void modifyAce(Session jcrSession, String resourcePath, String principalId, Map<String, String> privileges,
-			String order, Map<String, Value> restrictions, Map<String, Value[]> mvRestrictions,
-			Set<String> removeRestrictionNames, boolean autoSave, List<Modification> changes) throws RepositoryException {
-		if (jcrSession == null) {
-			throw new RepositoryException("JCR Session not found");
-		}
+        // Collect the modified privileges from the request.
+        Set<String> grantedPrivilegeNames = new HashSet<>();
+        Set<String> deniedPrivilegeNames = new HashSet<>();
+        Set<String> removedPrivilegeNames = new HashSet<>();
+        if (privileges != null) {
+            Set<Entry<String, String>> entrySet = privileges.entrySet();
+            for (Entry<String, String> entry : entrySet) {
+                String privilegeName = entry.getKey();
+                if (privilegeName.startsWith("privilege@")) {
+                    privilegeName = privilegeName.substring(10);
+                }
+                String parameterValue = entry.getValue();
+                if (parameterValue != null && parameterValue.length() > 0) {
+                    if ("granted".equals(parameterValue)) {
+                        grantedPrivilegeNames.add(privilegeName);
+                    } else if ("denied".equals(parameterValue)) {
+                        deniedPrivilegeNames.add(privilegeName);
+                    } else if ("none".equals(parameterValue)){
+                        removedPrivilegeNames.add(privilegeName);
+                    }
+                }
+            }
+        }
 
-		if (principalId == null) {
-			throw new RepositoryException("principalId was not submitted.");
-		}
-		
-		// validate that the submitted name is valid
-		PrincipalManager principalManager = AccessControlUtil.getPrincipalManager(jcrSession);
-		Principal principal = principalManager.getPrincipal(principalId);
-		if (principal == null) {
-			throw new RepositoryException("Invalid principalId was submitted.");
-		}
-		
-    	if (resourcePath == null) {
-			throw new ResourceNotFoundException("Resource path was not supplied.");
-    	}
+        // Make the actual changes.
+        try {
+            AccessControlUtil.replaceAccessControlEntry(jcrSession, resourcePath, principal,
+                    grantedPrivilegeNames.toArray(new String[grantedPrivilegeNames.size()]),
+                    deniedPrivilegeNames.toArray(new String[deniedPrivilegeNames.size()]),
+                    removedPrivilegeNames.toArray(new String[removedPrivilegeNames.size()]),
+                    order,
+                    restrictions,
+                    mvRestrictions,
+                    removeRestrictionNames);
 
-		Item item = jcrSession.getItem(resourcePath);
-		if (item != null) {
-			resourcePath = item.getPath();
-		} else {
-			throw new ResourceNotFoundException("Resource is not a JCR Node");
-		}
-		
-		// Collect the modified privileges from the request.
-		Set<String> grantedPrivilegeNames = new HashSet<>();
-		Set<String> deniedPrivilegeNames = new HashSet<>();
-		Set<String> removedPrivilegeNames = new HashSet<>();
-		if (privileges != null) {
-			Set<Entry<String, String>> entrySet = privileges.entrySet();
-			for (Entry<String, String> entry : entrySet) {
-				String privilegeName = entry.getKey();
-				if (privilegeName.startsWith("privilege@")) {
-					privilegeName = privilegeName.substring(10);
-				}
-				String parameterValue = entry.getValue();
-				if (parameterValue != null && parameterValue.length() > 0) {
-					if ("granted".equals(parameterValue)) {
-						grantedPrivilegeNames.add(privilegeName);
-					} else if ("denied".equals(parameterValue)) {
-						deniedPrivilegeNames.add(privilegeName);
-					} else if ("none".equals(parameterValue)){
-						removedPrivilegeNames.add(privilegeName);
-					}
-				}
-			}
-		}
+            if (changes != null) {
+                changes.add(Modification.onModified(principal.getName()));
+            }
+
+            if (autoSave && jcrSession.hasPendingChanges()) {
+                jcrSession.save();
+            }
+        } catch (RepositoryException re) {
+            throw new RepositoryException("Failed to create ace.", re);
+        }
+    }
 
-		// Make the actual changes.
-		try {
-			AccessControlUtil.replaceAccessControlEntry(jcrSession, resourcePath, principal,
-					grantedPrivilegeNames.toArray(new String[grantedPrivilegeNames.size()]),
-					deniedPrivilegeNames.toArray(new String[deniedPrivilegeNames.size()]),
-					removedPrivilegeNames.toArray(new String[removedPrivilegeNames.size()]),
-					order,
-					restrictions,
-					mvRestrictions,
-					removeRestrictionNames);
-			
-			if (changes != null) {
-				changes.add(Modification.onModified(principal.getName()));
-			}
-			
-			if (autoSave && jcrSession.hasPendingChanges()) {
-				jcrSession.save();
-			}
-		} catch (RepositoryException re) {
-			throw new RepositoryException("Failed to create ace.", re);
-		}
-	}
-	
 }