From 56e752193bfb90d11cfe73c35a24e576b9b18c87 Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Wed, 03 Jul 2013 11:03:06 +0000
Subject: [PATCH] First stab at having debuggable ACIs.

---
 opends/src/server/org/opends/server/authorization/dseecompat/IP.java                                  |   39 +
 opends/src/server/org/opends/server/authorization/dseecompat/TimeOfDay.java                           |   29 +
 opends/src/server/org/opends/server/authorization/dseecompat/AciContainer.java                        |  160 +++++---
 opends/src/server/org/opends/server/authorization/dseecompat/TargAttrFilters.java                     |   36 +-
 opends/src/server/org/opends/server/authorization/dseecompat/EnumBindRuleType.java                    |   16 
 opends/src/server/org/opends/server/authorization/dseecompat/TargAttrFilterList.java                  |   64 +-
 opends/src/server/org/opends/server/authorization/dseecompat/PermBindRulePair.java                    |   36 +
 opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciBodyTest.java |   58 +++
 opends/src/server/org/opends/server/authorization/dseecompat/AciList.java                             |   33 -
 opends/src/server/org/opends/server/authorization/dseecompat/BindRule.java                            |   84 ++--
 opends/src/server/org/opends/server/authorization/dseecompat/Permission.java                          |   57 ++
 opends/src/server/org/opends/server/authorization/dseecompat/UserDN.java                              |   50 ++
 opends/src/server/org/opends/server/authorization/dseecompat/AciBody.java                             |   86 +++-
 opends/src/server/org/opends/server/authorization/dseecompat/DNS.java                                 |   54 +-
 opends/src/server/org/opends/server/authorization/dseecompat/UserAttr.java                            |   45 +
 opends/src/server/org/opends/server/authorization/dseecompat/AuthMethod.java                          |   32 +
 opends/src/server/org/opends/server/authorization/dseecompat/SSF.java                                 |   27 +
 opends/src/server/org/opends/server/authorization/dseecompat/EnumRight.java                           |   66 +++
 opends/src/server/org/opends/server/authorization/dseecompat/KeywordBindRule.java                     |   11 
 opends/src/server/org/opends/server/authorization/dseecompat/GroupDN.java                             |   52 +-
 opends/src/server/org/opends/server/authorization/dseecompat/DayOfWeek.java                           |   43 +
 21 files changed, 742 insertions(+), 336 deletions(-)

diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/AciBody.java b/opends/src/server/org/opends/server/authorization/dseecompat/AciBody.java
index 25b6647..530b61e 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/AciBody.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/AciBody.java
@@ -23,83 +23,82 @@
  *
  *
  *      Copyright 2008-2009 Sun Microsystems, Inc.
- *      Portions copyright 2012 ForgeRock AS.
+ *      Portions copyright 2012-2013 ForgeRock AS.
  */
-
 package org.opends.server.authorization.dseecompat;
-import org.opends.messages.Message;
 
 import static org.opends.messages.AccessControlMessages.*;
 import static org.opends.server.authorization.dseecompat.Aci.*;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.opends.messages.Message;
+
 /**
  * This class represents the body of an ACI. The body of the ACI is the
  * version, name, and permission-bind rule pairs.
  */
 public class AciBody {
 
-    /*
+    /**
      * Regular expression group position for the version string.
      */
     private static final int VERSION = 1;
 
-    /*
+    /**
      * Regular expression group position for the name string.
      */
     private static final int NAME = 2;
 
-    /*
+    /**
      * Regular expression group position for the permission string.
      */
     private static final int PERM = 1;
 
-    /*
+    /**
      * Regular expression group position for the rights string.
      */
     private static final int RIGHTS = 2;
 
-    /*
+    /**
      * Regular expression group position for the bindrule string.
      */
     private static final int BINDRULE = 3;
 
-    /*
+    /**
      * Index into the ACI string where the ACI body starts.
      */
     private int startPos=0;
 
-    /*
-    * The name of the ACI, currently not used but parsed.
-    */
+    /**
+     * The name of the ACI, currently not used but parsed.
+     */
     private String name = null;
 
-    /*
-    * The version of the ACi, current not used but parsed and checked
-    * for 3.0.
-    */
+    /**
+     * The version of the ACi, current not used but parsed and checked for 3.0.
+     */
     private String version = null;
 
-    /*
-     This structure represents a permission-bind rule pairs. There can be
-     several of these.
-    */
+    /**
+     * This structure represents a permission-bind rule pairs. There can be
+     * several of these.
+     */
     private List<PermBindRulePair> permBindRulePairs;
 
-    /*
+    /**
      * Regular expression used to match the access type group (allow, deny) and
      * the rights group "(read, write, ...)". The last pattern looks for a group
      * surrounded by parenthesis. The group must contain at least one
      * non-paren character.
      */
-    private static final
-    String permissionRegex =
+    private static final String permissionRegex =
                WORD_GROUP + ZERO_OR_MORE_WHITESPACE + "\\(([^()]+)\\)";
 
-    /*
+    /**
      * Regular expression that matches a bind rule group at a coarse level. It
      * matches any character one or more times, a single quotation and
      * an optional right parenthesis.
@@ -107,7 +106,7 @@
     private static final String bindRuleRegex =
             "(.+?\"[)]*)" + ACI_STATEMENT_SEPARATOR;
 
-    /*
+    /**
      * Regular expression used to match the actions of the ACI. The actions
      * are permissions and matching bind rules.
      */
@@ -115,17 +114,17 @@
             ZERO_OR_MORE_WHITESPACE + permissionRegex +
             ZERO_OR_MORE_WHITESPACE + bindRuleRegex;
 
-    /*
+    /**
      * Regular expression used to match the version value (digit.digit).
      */
     private static final String versionRegex = "(\\d\\.\\d)";
 
-    /*
+    /**
      * Regular expression used to match the version token. Case insensitive.
      */
     private static final String versionToken = "(?i)version(?-i)";
 
-    /*
+    /**
      * Regular expression used to match the acl token. Case insensitive.
      */
     private static final String aclToken = "(?i)acl(?-i)";
@@ -141,7 +140,7 @@
         "\"([^\"]*)\"" + ACI_STATEMENT_SEPARATOR + actionRegex +
         ZERO_OR_MORE_WHITESPACE  + "\\)";
 
-    /*
+    /**
      * Regular expression used to match the header of the ACI body. The
      * header is version and acl name.
      */
@@ -260,7 +259,7 @@
      *
      * @return The permission-bind rule pairs.
      */
-    private List<PermBindRulePair> getPermBindRulePairs() {
+    List<PermBindRulePair> getPermBindRulePairs() {
         return permBindRulePairs;
     }
 
@@ -374,4 +373,31 @@
   public String getVersion () {
     return version;
   }
+
+  /** {@inheritDoc} */
+  @Override
+  public String toString()
+  {
+    final StringBuilder sb = new StringBuilder();
+    toString(sb);
+    return sb.toString();
+  }
+
+  /**
+   * Appends a string representation of this object to the provided buffer.
+   *
+   * @param buffer
+   *          The buffer into which a string representation of this object
+   *          should be appended.
+   */
+  public final void toString(StringBuilder buffer)
+  {
+    buffer.append("(version ").append(this.version);
+    buffer.append("; acl \"").append(this.name).append("\"; ");
+    for (PermBindRulePair pair : this.permBindRulePairs)
+    {
+      buffer.append(pair);
+    }
+  }
+
 }
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/AciContainer.java b/opends/src/server/org/opends/server/authorization/dseecompat/AciContainer.java
index 2bb31ce..807f7f6 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/AciContainer.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/AciContainer.java
@@ -23,28 +23,27 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
- *      Portions Copyright 2011 ForgeRock AS
+ *      Portions Copyright 2011-2013 ForgeRock AS
  */
-
 package org.opends.server.authorization.dseecompat;
 
-import org.opends.server.protocols.ldap.LDAPClientConnection;
-import org.opends.server.types.*;
-import org.opends.server.api.ClientConnection;
-import org.opends.server.api.Group;
-import org.opends.server.core.AddOperationBasis;
-import org.opends.server.core.SearchOperation;
-import org.opends.server.types.Operation;
-import java.net.InetAddress;
-import java.security.cert.Certificate;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.HashMap;
-
 import static org.opends.server.authorization.dseecompat.Aci.*;
 import static org.opends.server.authorization.dseecompat.AciHandler.*;
+import static org.opends.server.util.ServerConstants.*;
+
+import java.net.InetAddress;
+import java.security.cert.Certificate;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.opends.server.api.ClientConnection;
+import org.opends.server.api.Group;
 import org.opends.server.controls.GetEffectiveRightsRequestControl;
-import static org.opends.server.util.ServerConstants.OID_GET_EFFECTIVE_RIGHTS;
+import org.opends.server.core.AddOperation;
+import org.opends.server.core.SearchOperation;
+import org.opends.server.protocols.ldap.LDAPClientConnection;
+import org.opends.server.types.*;
 
 /**
  *  The AciContainer class contains all of the needed information to perform
@@ -55,70 +54,70 @@
 public abstract class AciContainer
 implements AciTargetMatchContext, AciEvalContext {
 
-    /*
+    /**
      * The allow and deny lists.
      */
     private LinkedList<Aci> denyList, allowList;
 
-    /*
+    /**
      * The attribute type in the resource entry currently being evaluated.
      */
     private AttributeType attributeType;
 
-    /*
+    /**
      * The attribute type value in the resource entry currently being
      * evaluated.
      */
     private AttributeValue attributeValue;
 
-    /*
+    /**
      * True if this is the first attribute type in the resource entry being
      * evaluated.
      */
     private boolean isFirst = false;
 
-    /*
+    /**
      * True if an entry test rule was seen during target matching of an ACI
      * entry. A entry test rule is an ACI with targetattrs target keyword.
      */
     private boolean isEntryTestRule = false;
 
-    /*
+    /**
      * True if the evaluation of an ACI is from the deny list.
      */
     private boolean isDenyEval;
 
-    /*
+    /**
      * True if the evaluation is a result of an LDAP add operation.
      */
     private boolean isAddOp=false;
 
-    /*
+    /**
      * The right mask to use in the evaluation of the LDAP operation.
      */
     private int rightsMask;
 
-    /*
+    /**
      * The entry being evaluated (resource entry).
      */
     private Entry resourceEntry;
 
-    /*
+    /**
      * The client connection information.
      */
     private final ClientConnection clientConnection;
 
-    /*
+    /**
      * The operation being evaluated.
      */
     private final Operation operation;
 
-    /*
+    /**
      * True if a targattrfilters match was found.
      */
     private boolean targAttrFiltersMatch=false;
 
-    /*
+    /**
      * The authorization entry currently being evaluated. If proxied
      * authorization is being used and the handler is doing a proxy access
      * check, then this entry will switched to the original authorization entry
@@ -128,24 +127,24 @@
      */
     private Entry authorizationEntry;
 
-    /*
+    /**
      * Used to save the current authorization entry when the authorization
      * entry is switched during a proxy access check.
      */
     private final Entry saveAuthorizationEntry;
 
-    /*
+    /**
      * This entry is only used if proxied authorization is being used.  It is
      * the original authorization entry before the proxied authorization change.
      */
     private Entry origAuthorizationEntry=null;
 
-    /*
+    /**
      * True if proxied authorization is being used.
      */
     private boolean proxiedAuthorization=false;
 
-    /*
+    /**
      * Used by proxied authorization processing. True if the entry has already
      * been processed by an access proxy check. Some operations might perform
      * several access checks on the same entry (modify DN), this
@@ -153,88 +152,88 @@
      */
     private boolean seenEntry=false;
 
-    /*
+    /**
      *  True if geteffectiverights evaluation is in progress.
      */
     private boolean isGetEffectiveRightsEval=false;
 
-     /*
+    /**
      *  True if the operation has a geteffectiverights control.
      */
     private boolean hasGetEffectiveRightsControl=false;
 
-    /*
+    /**
      * The geteffectiverights authzID in DN format.
      */
     private DN authzid=null;
 
-    /*
+    /**
      * True if the authZid should be used as the client DN, only used in
      * geteffectiverights evaluation.
      */
     private boolean useAuthzid=false;
 
-    /*
+    /**
      * The list of specific attributes to get rights for, in addition to
      * any attributes requested in the search.
      */
     private List<AttributeType> specificAttrs=null;
 
-    /*
+    /**
      * Table of ACIs that have targattrfilter keywords that matched. Used
      * in geteffectiverights attributeLevel write evaluation.
      */
     private final HashMap<Aci,Aci> targAttrFilterAcis=new HashMap<Aci, Aci>();
 
-    /*
+    /**
      * The name of a ACI that decided an evaluation and contained a
      * targattrfilter keyword. Used in geteffectiverights attributeLevel
      * write evaluation.
      */
     private String targAttrFiltersAciName=null;
 
-    /*
+    /**
      * Value that is used to store the allow/deny result of a deciding ACI
      * containing a targattrfilter keyword.  Used in geteffectiverights
      * attributeLevel write evaluation.
      */
     private int targAttrMatch=0;
 
-    /*
+    /**
      * The ACI that decided the last evaluation. Used in geteffectiverights
      * loginfo processing.
      */
     private Aci decidingAci=null;
 
-    /*
+    /**
      * The reason the last evaluation decision was made. Used both
      * in geteffectiverights loginfo processing and attributeLevel write
      * evaluation.
      */
     private EnumEvalReason evalReason=null;
 
-    /*
+    /**
      * A summary string holding the last evaluation information in textual
      * format. Used in geteffectiverights loginfo processing.
      */
     private String summaryString=null;
 
-   /*
+   /**
     * Flag used to determine if ACI all attributes target matched.
     */
     private int evalAllAttributes=0;
 
-   /*
+   /**
     * String used to hold a control OID string.
     */
     private String controlOID;
 
-   /*
+   /**
     * String used to hold an extended operation OID string.
     */
     private String extOpOID;
 
-    /*
+    /**
      * AuthenticationInfo class to use.
      */
     private AuthenticationInfo authInfo;
@@ -255,16 +254,14 @@
       this.resourceEntry=entry;
       this.operation=operation;
       this.clientConnection=operation.getClientConnection();
-      if(operation instanceof AddOperationBasis)
-          this.isAddOp=true;
+      this.isAddOp = operation instanceof AddOperation;
       this.authInfo = clientConnection.getAuthenticationInfo();
 
       //If the proxied authorization control was processed, then the operation
       //will contain an attachment containing the original authorization entry.
       this.origAuthorizationEntry =
                       (Entry) operation.getAttachment(ORIG_AUTH_ENTRY);
-      if(origAuthorizationEntry != null)
-         this.proxiedAuthorization=true;
+      this.proxiedAuthorization = origAuthorizationEntry != null;
       this.authorizationEntry=operation.getAuthorizationEntry();
 
       //The ACI_READ right at constructor time can only be the result of the
@@ -353,6 +350,7 @@
   /**
    * {@inheritDoc}
    */
+    @Override
     public boolean isProxiedAuthorization() {
          return this.proxiedAuthorization;
     }
@@ -360,6 +358,7 @@
   /**
    * {@inheritDoc}
    */
+    @Override
     public boolean isGetEffectiveRightsEval() {
         return this.isGetEffectiveRightsEval;
     }
@@ -407,6 +406,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public void addTargAttrFiltersMatchAci(Aci aci) {
       this.targAttrFilterAcis.put(aci, aci);
     }
@@ -414,6 +414,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public boolean hasTargAttrFiltersMatchAci(Aci aci) {
       return this.targAttrFilterAcis.containsKey(aci);
     }
@@ -421,6 +422,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public boolean isTargAttrFilterMatchAciEmpty() {
        return this.targAttrFilterAcis.isEmpty();
     }
@@ -443,6 +445,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public void setTargAttrFiltersAciName(String name) {
       this.targAttrFiltersAciName=name;
     }
@@ -450,6 +453,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public String getTargAttrFiltersAciName() {
       return this.targAttrFiltersAciName;
     }
@@ -457,6 +461,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public void setTargAttrFiltersMatchOp(int flag) {
       this.targAttrMatch |= flag;
     }
@@ -464,6 +469,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public boolean hasTargAttrFiltersMatchOp(int flag) {
        return (this.targAttrMatch & flag) != 0;
     }
@@ -471,6 +477,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public void setDecidingAci(Aci aci) {
       this.decidingAci=aci;
     }
@@ -478,6 +485,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public String getDecidingAciName() {
       if(this.decidingAci != null)
          return this.decidingAci.getName();
@@ -487,6 +495,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public void setEvalReason(EnumEvalReason reason) {
       this.evalReason=reason;
     }
@@ -494,6 +503,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public EnumEvalReason getEvalReason() {
       return this.evalReason;
     }
@@ -501,6 +511,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public void setEvalSummary(String summary) {
       this.summaryString=summary;
     }
@@ -508,7 +519,8 @@
    /**
     * {@inheritDoc}
     */
-     public String getEvalSummary() {
+     @Override
+    public String getEvalSummary() {
       return this.summaryString;
     }
 
@@ -540,6 +552,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public void setDenyList(LinkedList<Aci> denys) {
         denyList=denys;
     }
@@ -547,6 +560,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public void setAllowList(LinkedList<Aci> allows) {
         allowList=allows;
     }
@@ -554,6 +568,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public AttributeType getCurrentAttributeType() {
         return attributeType;
     }
@@ -561,6 +576,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public AttributeValue getCurrentAttributeValue() {
         return attributeValue;
     }
@@ -568,6 +584,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public void setCurrentAttributeType(AttributeType type) {
         attributeType=type;
     }
@@ -575,6 +592,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public void setCurrentAttributeValue(AttributeValue value) {
         attributeValue=value;
     }
@@ -582,6 +600,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public boolean isFirstAttribute() {
         return isFirst;
     }
@@ -589,6 +608,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public void setIsFirstAttribute(boolean val) {
         isFirst=val;
     }
@@ -596,6 +616,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public boolean hasEntryTestRule() {
         return isEntryTestRule;
     }
@@ -603,6 +624,7 @@
    /**
     * {@inheritDoc}
     */
+   @Override
    public void setEntryTestRule(boolean val) {
         isEntryTestRule=val;
     }
@@ -610,6 +632,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public Entry getResourceEntry() {
         return resourceEntry;
     }
@@ -617,6 +640,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public Entry getClientEntry() {
       return this.authorizationEntry;
     }
@@ -624,13 +648,15 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public LinkedList<Aci> getDenyList() {
         return denyList;
-     }
+    }
 
    /**
     * {@inheritDoc}
     */
+    @Override
     public LinkedList<Aci> getAllowList() {
        return allowList;
     }
@@ -638,6 +664,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public boolean isDenyEval() {
         return isDenyEval;
     }
@@ -645,6 +672,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public boolean isAnonymousUser() {
         return !authInfo.isAuthenticated();
     }
@@ -652,6 +680,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public void setDenyEval(boolean val) {
         isDenyEval = val;
     }
@@ -659,6 +688,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public DN getClientDN() {
       if(this.useAuthzid)
         return this.authzid;
@@ -672,6 +702,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public DN getResourceDN() {
         return resourceEntry.getDN();
     }
@@ -679,6 +710,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public boolean hasRights(int rights) {
        return (this.rightsMask & rights) != 0;
     }
@@ -686,6 +718,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public int getRights() {
         return this.rightsMask;
     }
@@ -693,6 +726,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public void setRights(int rights) {
          this.rightsMask=rights;
     }
@@ -700,6 +734,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public String getHostName() {
         return clientConnection.getRemoteAddress().getCanonicalHostName();
     }
@@ -707,6 +742,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public InetAddress getRemoteAddress() {
         return clientConnection.getRemoteAddress();
     }
@@ -714,6 +750,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public boolean isAddOperation() {
         return isAddOp;
     }
@@ -721,6 +758,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public void setTargAttrFiltersMatch(boolean v) {
         this.targAttrFiltersMatch=v;
     }
@@ -728,6 +766,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public boolean getTargAttrFiltersMatch() {
         return targAttrFiltersMatch;
     }
@@ -735,6 +774,7 @@
     /**
     * {@inheritDoc}
     */
+    @Override
     public String getControlOID() {
       return controlOID;
     }
@@ -742,6 +782,7 @@
    /**
     * {@inheritDoc}
     */
+    @Override
     public String getExtOpOID() {
       return extOpOID;
     }
@@ -768,6 +809,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public EnumEvalResult hasAuthenticationMethod(EnumAuthMethod authMethod,
                                                   String saslMech) {
       EnumEvalResult matched=EnumEvalResult.FALSE;
@@ -822,6 +864,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public boolean isMemberOf(Group<?> group) {
         boolean ret;
         try {
@@ -844,6 +887,7 @@
   /**
    * {@inheritDoc}
    */
+    @Override
     public String rightToString() {
       if(hasRights(ACI_SEARCH))
         return "search";
@@ -872,6 +916,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public  void setEvalUserAttributes(int v) {
     if(operation instanceof SearchOperation && (rightsMask == ACI_READ)) {
       if(v == ACI_FOUND_USER_ATTR_RULE) {
@@ -882,9 +927,10 @@
     }
   }
 
-     /**
+  /**
    * {@inheritDoc}
    */
+  @Override
   public  void setEvalOpAttributes(int v) {
     if(operation instanceof SearchOperation && (rightsMask == ACI_READ)) {
       if(v == ACI_FOUND_OP_ATTR_RULE) {
@@ -898,6 +944,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public boolean hasEvalUserAttributes() {
     return (evalAllAttributes & ACI_FOUND_USER_ATTR_RULE) ==
             ACI_FOUND_USER_ATTR_RULE;
@@ -906,6 +953,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public boolean hasEvalOpAttributes() {
     return (evalAllAttributes & ACI_FOUND_OP_ATTR_RULE) ==
             ACI_FOUND_OP_ATTR_RULE;
@@ -936,6 +984,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public void clearEvalAttributes(int v) {
     if(v == 0)
       evalAllAttributes=0;
@@ -946,6 +995,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public int getCurrentSSF() {
       return clientConnection.getSSF();
   }
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/AciList.java b/opends/src/server/org/opends/server/authorization/dseecompat/AciList.java
index 0674f03..b6f78f2 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/AciList.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/AciList.java
@@ -23,43 +23,42 @@
  *
  *
  *      Copyright 2008-2010 Sun Microsystems, Inc.
+ *      Portions Copyright 2013 ForgeRock AS
  */
-
 package org.opends.server.authorization.dseecompat;
-import org.opends.messages.Message;
 
-import org.opends.server.api.Backend;
-import static org.opends.server.authorization.dseecompat.AciHandler.*;
-import static org.opends.server.loggers.ErrorLogger.logError;
 import static org.opends.messages.AccessControlMessages.*;
-import org.opends.server.api.DITCacheMap;
-import org.opends.server.types.*;
+import static org.opends.server.authorization.dseecompat.AciHandler.*;
+import static org.opends.server.loggers.ErrorLogger.*;
 
 import java.util.*;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
+import org.opends.messages.Message;
+import org.opends.server.api.Backend;
+import org.opends.server.api.DITCacheMap;
+import org.opends.server.types.*;
+
 /**
  * The AciList class performs caching of the ACI attribute values
  * using the entry DN as the key.
  */
 public class AciList {
 
-  /*
+  /**
    * A map containing all the ACIs.
    * We use the copy-on-write technique to avoid locking when reading.
    */
   private volatile DITCacheMap<List<Aci>> aciList =
        new DITCacheMap<List<Aci>>();
 
-  /*
+  /**
    * Lock to protect internal data structures.
    */
   private final ReentrantReadWriteLock lock =
           new ReentrantReadWriteLock();
 
-  /*
-  * The configuration DN used to compare against the global ACI entry DN.
-  */
+  /** The configuration DN used to compare against the global ACI entry DN. */
   private DN configDN;
 
   /**
@@ -102,12 +101,10 @@
               AciTargets targets = aci.getTargets();
               //If there is a target, evaluate it to see if this ACI should
               //be included in the candidate set.
-              if (targets != null) {
-                boolean ret = AciTargets.isTargetApplicable(aci, targets,
-                        entryDN);
-                if (ret) {
+              if (targets != null
+                  && AciTargets.isTargetApplicable(aci, targets, entryDN))
+              {
                   candidates.add(aci);  //Add this ACI to the candidates.
-                }
               }
             }
           } else {
@@ -414,7 +411,7 @@
 
   /**
    * Rename all ACIs under the specified old DN to the new DN. A simple
-   * interation over the entire list is performed.
+   * interaction over the entire list is performed.
    * @param oldDN The DN of the original entry that was moved.
    * @param newDN The DN of the new entry.
    */
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/AuthMethod.java b/opends/src/server/org/opends/server/authorization/dseecompat/AuthMethod.java
index f4133d6..1ea4b32 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/AuthMethod.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/AuthMethod.java
@@ -23,23 +23,21 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2013 ForgeRock AS
  */
-
 package org.opends.server.authorization.dseecompat;
-import org.opends.messages.Message;
-
 import static org.opends.messages.AccessControlMessages.*;
+import static org.opends.server.loggers.ErrorLogger.*;
+
+import org.opends.messages.Message;
 import org.opends.server.core.DirectoryServer;
-import static org.opends.server.loggers.ErrorLogger.logError;
-
-
 
 /**
  * The AuthMethod class represents an authmethod bind rule keyword expression.
  */
 public class AuthMethod implements KeywordBindRule {
 
-    /*
+    /**
      * Enumeration representing the authentication method.
      */
     private EnumAuthMethod authMethod=null;
@@ -49,7 +47,7 @@
      */
     private String saslMech = null;
 
-    /*
+    /**
      * Enumeration representing the bind rule operation type.
      */
     private EnumBindRuleType type=null;
@@ -110,9 +108,27 @@
      * @param evalCtx  An evaluation context to use.
      * @return  An enumeration evaluation result.
      */
+    @Override
     public EnumEvalResult evaluate(AciEvalContext evalCtx) {
         EnumEvalResult matched =
              evalCtx.hasAuthenticationMethod(authMethod, saslMech);
         return matched.getRet(type, false);
     }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString()
+    {
+      final StringBuilder sb = new StringBuilder();
+      toString(sb);
+      return sb.toString();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final void toString(StringBuilder buffer)
+    {
+      buffer.append(super.toString());
+    }
+
 }
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/BindRule.java b/opends/src/server/org/opends/server/authorization/dseecompat/BindRule.java
index 18e3611..79cb912 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/BindRule.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/BindRule.java
@@ -23,16 +23,18 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2013 ForgeRock AS
  */
-
 package org.opends.server.authorization.dseecompat;
-import org.opends.messages.Message;
 
 import static org.opends.messages.AccessControlMessages.*;
 import static org.opends.server.authorization.dseecompat.Aci.*;
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
+
 import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.opends.messages.Message;
 
 /**
  * This class represents a single bind rule of an ACI permission-bind rule
@@ -40,78 +42,58 @@
  */
 public class BindRule {
 
-    /*
-     * This hash table holds the keyword bind rule mapping.
-     */
-    private HashMap<String, KeywordBindRule> keywordRuleMap =
+    /** This hash table holds the keyword bind rule mapping. */
+    private final HashMap<String, KeywordBindRule> keywordRuleMap =
                                     new HashMap<String, KeywordBindRule>();
 
-    /*
-     * True is a boolean "not" was seen.
-     */
+    /** True is a boolean "not" was seen. */
     private boolean negate=false;
 
-    /*
-     * Complex bind rules have left and right values.
-     */
+    /** Complex bind rules have left and right values. */
     private BindRule left = null;
     private BindRule right = null;
 
-    /*
+    /**
      * Enumeration of the boolean type of the complex bind rule ("and" or "or").
      */
     private EnumBooleanTypes booleanType = null;
 
-    /*
-     * The keyword of a simple bind rule.
-     */
+    /** The keyword of a simple bind rule. */
     private EnumBindRuleKeyword keyword = null;
 
-    /*
-     * Regular expression group position of a bind rule keyword.
-     */
+    /** Regular expression group position of a bind rule keyword. */
     private static final int keywordPos = 1;
 
-    /*
-     * Regular expression group position of a bind rule operation.
-     */
+    /** Regular expression group position of a bind rule operation. */
     private static final int opPos = 2;
 
-    /*
-     * Regular expression group position of a bind rule expression.
-     */
+    /** Regular expression group position of a bind rule expression. */
     private static final int expressionPos = 3;
 
-    /*
+    /**
      * Regular expression group position of the remainder part of an operand.
      */
     private static final int remainingOperandPos = 1;
 
-    /*
-     * Regular expression group position of the remainder of the bind rule.
-     */
+    /** Regular expression group position of the remainder of the bind rule. */
     private static final int remainingBindrulePos = 2;
 
-    /*
-     * Regular expression for valid bind rule operator group.
-     */
+    /** Regular expression for valid bind rule operator group. */
     private static final String opRegGroup = "([!=<>]+)";
 
-    /*
+    /**
      * Regular expression for the expression part of a partially parsed
      * bind rule.
      */
     private static final String expressionRegex =
                                   "\"([^\"]+)\"" + ZERO_OR_MORE_WHITESPACE;
 
-    /*
-     * Regular expression for a single bind rule.
-     */
+    /** Regular expression for a single bind rule. */
     private static final String bindruleRegex =
         WORD_GROUP_START_PATTERN + ZERO_OR_MORE_WHITESPACE +
         opRegGroup + ZERO_OR_MORE_WHITESPACE + expressionRegex;
 
-    /*
+    /**
      * Regular expression of the remainder part of a partially parsed bind rule.
      */
     private static final String remainingBindruleRegex =
@@ -588,4 +570,28 @@
             ret=evalComplex(left.evaluate(evalCtx),right.evaluate(evalCtx));
         return EnumEvalResult.negateIfNeeded(ret, negate);
     }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        toString(sb);
+        return sb.toString();
+    }
+
+    /**
+     * Appends a string representation of this object to the provided buffer.
+     *
+     * @param buffer
+     *          The buffer into which a string representation of this object
+     *          should be appended.
+     */
+    public final void toString(StringBuilder buffer) {
+        if (this.keywordRuleMap != null) {
+            for (KeywordBindRule rule : this.keywordRuleMap.values()) {
+                rule.toString(buffer);
+                buffer.append(";");
+            }
+        }
+    }
 }
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/DNS.java b/opends/src/server/org/opends/server/authorization/dseecompat/DNS.java
index 996c196..81f3d60 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/DNS.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/DNS.java
@@ -23,54 +23,46 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2013 ForgeRock AS
  */
-
 package org.opends.server.authorization.dseecompat;
 
-import org.opends.messages.Message;
-
-import static org.opends.server.loggers.ErrorLogger.*;
 import static org.opends.messages.AccessControlMessages.*;
 import static org.opends.server.authorization.dseecompat.Aci.*;
+import static org.opends.server.loggers.ErrorLogger.*;
 import static org.opends.server.loggers.debug.DebugLogger.*;
 import static org.opends.server.util.StaticUtils.*;
 
-import org.opends.server.loggers.debug.DebugTracer;
-
 import java.net.InetAddress;
 import java.util.LinkedList;
+import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+
+import org.opends.messages.Message;
+import org.opends.server.loggers.debug.DebugTracer;
 import org.opends.server.types.DebugLogLevel;
 
 /**
  * This class implements the dns bind rule keyword.
  */
 public class DNS implements KeywordBindRule {
+
   /**
    * The tracer object for the debug logger.
    */
   private static final DebugTracer TRACER = getTracer();
 
+    /** List of patterns to match against. */
+    private List<String> patterns = null;
 
-    /*
-     * List of patterns to match against.
-     */
-    LinkedList<String> patterns=null;
-
-    /*
-     * The enumeration representing the bind rule type of the DNS rule.
-     */
+    /** The enumeration representing the bind rule type of the DNS rule. */
     private EnumBindRuleType type=null;
 
-    /*
-     *  Regular expression group used to match a dns rule.
-     */
+    /** Regular expression group used to match a dns rule. */
     private static final String valueRegex = "([a-zA-Z0-9\\.\\-\\*]+)";
 
-    /*
-     * Regular expression group used to match one or more DNS values.
-     */
+    /** Regular expression group used to match one or more DNS values. */
     private static final String valuesRegExGroup =
             valueRegex + ZERO_OR_MORE_WHITESPACE +
             "(," +  ZERO_OR_MORE_WHITESPACE  +  valueRegex  +  ")*";
@@ -80,7 +72,7 @@
      * @param patterns List of dns patterns to match against.
      * @param type An enumeration representing the bind rule type.
      */
-    DNS(LinkedList<String> patterns, EnumBindRuleType type) {
+    DNS(List<String> patterns, EnumBindRuleType type) {
         this.patterns=patterns;
         this.type=type;
     }
@@ -100,7 +92,7 @@
             Message message = WARN_ACI_SYNTAX_INVALID_DNS_EXPRESSION.get(expr);
             throw new AciException(message);
         }
-        LinkedList<String>dns=new LinkedList<String>();
+        List<String> dns = new LinkedList<String>();
         int valuePos = 1;
         Pattern valuePattern = Pattern.compile(valueRegex);
         Matcher valueMatcher = valuePattern.matcher(expr);
@@ -181,6 +173,7 @@
      * @param evalCtx  An evaluation context to use in the evaluation.
      * @return An enumeration evaluation result.
      */
+    @Override
     public EnumEvalResult evaluate(AciEvalContext evalCtx) {
         EnumEvalResult matched=EnumEvalResult.FALSE;
         String[] remoteHost = evalCtx.getHostName().split("\\.", -1);
@@ -206,7 +199,7 @@
      * the bind rule expression. The first array slot may be a wild-card "*".
      * @return  True if the remote hostname matches the pattern.
      */
-      boolean evalHostName(String[] remoteHostName, String[] pat) {
+    boolean evalHostName(String[] remoteHostName, String[] pat) {
       boolean wildCard=pat[0].equals("*");
       //Check if there is a single wild-card.
       if(pat.length == 1 && wildCard)
@@ -226,4 +219,19 @@
                 return false;
       return true;
     }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        toString(sb);
+        return sb.toString();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final void toString(StringBuilder buffer) {
+        buffer.append(super.toString());
+    }
+
 }
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/DayOfWeek.java b/opends/src/server/org/opends/server/authorization/dseecompat/DayOfWeek.java
index 7c41471..f84f5d3 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/DayOfWeek.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/DayOfWeek.java
@@ -23,29 +23,28 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2013 ForgeRock AS
  */
-
 package org.opends.server.authorization.dseecompat;
-import org.opends.messages.Message;
 
 import static org.opends.messages.AccessControlMessages.*;
+
 import java.util.Calendar;
 import java.util.GregorianCalendar;
 import java.util.LinkedList;
+import java.util.List;
+
+import org.opends.messages.Message;
 
 /**
  * This class implements the dayofweek bind rule keyword.
  */
 public class DayOfWeek  implements KeywordBindRule {
 
-    /*
-     * List containing the enumeration of the day of the week.
-     */
-    LinkedList<EnumDayOfWeek> days=null;
+    /** List containing the enumeration of the day of the week. */
+    private List<EnumDayOfWeek> days = null;
 
-    /*
-     * Enumeration representing the bind rule operation type.
-     */
+    /** Enumeration representing the bind rule operation type. */
     private EnumBindRuleType type=null;
 
     /**
@@ -53,7 +52,7 @@
      * @param days  A list of day of the week enumerations.
      * @param type An enumeration representing the bind rule type.
      */
-    private DayOfWeek(LinkedList<EnumDayOfWeek> days, EnumBindRuleType type) {
+    private DayOfWeek(List<EnumDayOfWeek> days, EnumBindRuleType type) {
         this.days=days;
         this.type=type;
     }
@@ -69,11 +68,11 @@
     public static KeywordBindRule decode(String expr, EnumBindRuleType type)
     throws AciException
     {
-        LinkedList<EnumDayOfWeek>days=new LinkedList<EnumDayOfWeek>();
+        List<EnumDayOfWeek> days = new LinkedList<EnumDayOfWeek>();
         String[] dayArray=expr.split(",", -1);
-        for(int i=0, m=dayArray.length; i < m; i++)
+        for (String element : dayArray)
         {
-          EnumDayOfWeek day=EnumDayOfWeek.createDayOfWeek(dayArray[i]);
+          EnumDayOfWeek day=EnumDayOfWeek.createDayOfWeek(element);
           if (day == null)
           {
               Message message = WARN_ACI_SYNTAX_INVALID_DAYOFWEEK.get(expr);
@@ -90,6 +89,7 @@
      * @param evalCtx  An evaluation context to use in the evaluation.
      * @return An enumeration evaluation result.
      */
+    @Override
     public EnumEvalResult evaluate(AciEvalContext evalCtx) {
         EnumEvalResult matched=EnumEvalResult.FALSE;
         GregorianCalendar calendar = new GregorianCalendar();
@@ -99,4 +99,21 @@
             matched=EnumEvalResult.TRUE;
         return matched.getRet(type, false);
     }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString()
+    {
+      final StringBuilder sb = new StringBuilder();
+      toString(sb);
+      return sb.toString();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final void toString(StringBuilder buffer)
+    {
+      buffer.append(super.toString());
+    }
+
 }
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/EnumBindRuleType.java b/opends/src/server/org/opends/server/authorization/dseecompat/EnumBindRuleType.java
index 7e4274a..e7f137b 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/EnumBindRuleType.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/EnumBindRuleType.java
@@ -23,8 +23,8 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2013 ForgeRock AS
  */
-
 package org.opends.server.authorization.dseecompat;
 
 /**
@@ -63,9 +63,7 @@
      */
     GREATER_OR_EQUAL_BINDRULE_TYPE  (">=");
 
-    /*
-     * The bind rule type name.
-     */
+    /** The bind rule type name. */
     private final String type;
 
     /**
@@ -77,6 +75,16 @@
     }
 
     /**
+     * Returns the comparison operator corresponding to this EnumBindRuleType.
+     *
+     * @return the string representing the comparison operator
+     */
+    public String getType()
+    {
+      return type;
+    }
+
+    /**
      * Checks to see if the type string is equal to the enumeration type
      * name.
      * @param type  The type name to check equality for.
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/EnumRight.java b/opends/src/server/org/opends/server/authorization/dseecompat/EnumRight.java
index b7ec612..4b195a0 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/EnumRight.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/EnumRight.java
@@ -23,11 +23,15 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2013 ForgeRock AS
  */
-
 package org.opends.server.authorization.dseecompat;
+
 import static org.opends.server.authorization.dseecompat.Aci.*;
 
+import java.util.EnumSet;
+import java.util.Set;
+
 /**
  * This class provides an enumeration of the allowed rights.
  */
@@ -89,7 +93,7 @@
      */
     ADDWRITE    ("addwrite");
 
-    /*
+    /**
      * The name of the right.
      */
     private final String right;
@@ -103,6 +107,15 @@
     }
 
     /**
+     * Returns the string representation of the right.
+     *
+     * @return the string representation of the right
+     */
+    public String getRight() {
+        return right;
+    }
+
+    /**
      * Checks if the enumeration is equal to the right name.
      * @param right The name of the right to check.
      * @return  True if the right is equal to the enumeration's.
@@ -171,4 +184,53 @@
         }
         return mask;
     }
+
+    /**
+     * Return the EnumRight corresponding to the provided rightsMask.
+     *
+     * @param rightsMask
+     *          the rights mask for which to return the corresponding EnumRight
+     * @return EnumRight corresponding to the provided rightsMask.
+     */
+    public static Set<EnumRight> getEnumRight(int rightsMask) {
+        if (hasRights(rightsMask, ACI_ALL))
+            return EnumSet.of(ALL);
+
+        final EnumSet<EnumRight> results = EnumSet.noneOf(EnumRight.class);
+        if (hasRights(rightsMask, ACI_READ))
+            results.add(READ);
+        if (hasRights(rightsMask, ACI_WRITE))
+            results.add(WRITE);
+        if (hasRights(rightsMask, ACI_ADD))
+            results.add(ADD);
+        if (hasRights(rightsMask, ACI_DELETE))
+            results.add(DELETE);
+        if (hasRights(rightsMask, ACI_SEARCH))
+            results.add(SEARCH);
+        if (hasRights(rightsMask, ACI_COMPARE))
+            results.add(COMPARE);
+        if (hasRights(rightsMask, ACI_EXPORT))
+            results.add(EXPORT);
+        if (hasRights(rightsMask, ACI_IMPORT))
+            results.add(IMPORT);
+        if (hasRights(rightsMask, ACI_PROXY))
+            results.add(PROXY);
+        if (hasRights(rightsMask, ACI_SELF))
+            results.add(SELFWRITE);
+        return results;
+    }
+
+    /**
+     * Checks if the provided rights mask has the specified rights.
+     *
+     * @param rightsMask
+     *          The rights mask to look into.
+     * @param rights
+     *          The rights to check for.
+     * @return true if the rights mask has the specified rights, false
+     *           otherwise.
+     */
+    public static boolean hasRights(int rightsMask, int rights) {
+        return (rightsMask & rights) == rights;
+    }
 }
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/GroupDN.java b/opends/src/server/org/opends/server/authorization/dseecompat/GroupDN.java
index 7402d3b..3f5a0bc 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/GroupDN.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/GroupDN.java
@@ -23,37 +23,33 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2013 ForgeRock AS
  */
-
 package org.opends.server.authorization.dseecompat;
-import org.opends.messages.Message;
 
 import static org.opends.messages.AccessControlMessages.*;
 import static org.opends.server.authorization.dseecompat.Aci.*;
-import org.opends.server.types.*;
-import org.opends.server.api.Group;
-import org.opends.server.core.GroupManager;
-import org.opends.server.core.DirectoryServer;
-import java.util.Iterator;
+
 import java.util.LinkedList;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.opends.messages.Message;
+import org.opends.server.api.Group;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.core.GroupManager;
+import org.opends.server.types.*;
 
 /**
  * This class implements the groupdn bind rule keyword.
  */
 public class GroupDN implements KeywordBindRule {
 
-    /*
-     * List of group DNs.
-     */
-    LinkedList<DN> groupDNs=null;
+    /** List of group DNs. */
+    private List<DN> groupDNs = null;
 
-    /*
-     * Enumeration representing the groupdn operator type.
-     */
+    /** Enumeration representing the groupdn operator type. */
     private EnumBindRuleType type=null;
 
     /**
@@ -69,7 +65,7 @@
      * @param type An enumeration representing the bind rule type.
      * @param groupDNs A list of the dns representing groups.
      */
-    private GroupDN(EnumBindRuleType type, LinkedList<DN> groupDNs ) {
+    private GroupDN(EnumBindRuleType type, List<DN> groupDNs ) {
         this.groupDNs=groupDNs;
         this.type=type;
     }
@@ -89,7 +85,7 @@
                 WARN_ACI_SYNTAX_INVALID_GROUPDN_EXPRESSION.get(expr);
             throw new AciException(message);
         }
-        LinkedList<DN>groupDNs=new LinkedList<DN>();
+        List<DN> groupDNs = new LinkedList<DN>();
         int ldapURLPos = 1;
         Pattern ldapURLPattern = Pattern.compile(LDAP_URL);
         Matcher ldapURLMatcher = ldapURLPattern.matcher(expr);
@@ -115,14 +111,15 @@
      * @param evalCtx  An evaluation context to use  in the evaluation.
      * @return  Enumeration evaluation result.
      */
+    @Override
     public EnumEvalResult evaluate(AciEvalContext evalCtx) {
         EnumEvalResult matched = EnumEvalResult.FALSE;
-       Iterator<DN> it=groupDNs.iterator();
-        for(; it.hasNext() && matched != EnumEvalResult.TRUE;) {
-            DN  groupDN=it.next();
+        for (DN groupDN : groupDNs) {
             Group<?> group = getGroupManager().getGroupInstance(groupDN);
-            if((group != null) && (evalCtx.isMemberOf(group)))
+            if((group != null) && (evalCtx.isMemberOf(group))) {
                matched = EnumEvalResult.TRUE;
+               break;
+            }
         }
         return matched.getRet(type, false);
     }
@@ -167,4 +164,19 @@
     private static GroupManager getGroupManager() {
         return DirectoryServer.getGroupManager();
     }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        toString(sb);
+        return sb.toString();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final void toString(StringBuilder buffer) {
+        buffer.append(super.toString());
+    }
+
 }
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/IP.java b/opends/src/server/org/opends/server/authorization/dseecompat/IP.java
index 18e390f..bb88bd9 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/IP.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/IP.java
@@ -23,8 +23,8 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2013 ForgeRock AS
  */
-
 package org.opends.server.authorization.dseecompat;
 import org.opends.messages.Message;
 
@@ -41,23 +41,21 @@
  */
 public class IP implements KeywordBindRule {
 
-    /*
-      Regular expression used to do a quick check on the characters in a
-      bind rule address. These are all of the valid characters that may
-      appear in an bind rule address part.
-    */
+    /**
+     * Regular expression used to do a quick check on the characters in a
+     * bind rule address. These are all of the valid characters that may
+     * appear in an bind rule address part.
+     */
     private  static final String ipRegEx =
             "((?i)[\\.{1}[a-f]\\d:\\+{1}\\*/{1}\\t\\[{1}\\]{1}]+(?-i))";
 
-    /*
-      List of the pattern classes, one for each address decoded from the
-      bind rule.
-    */
+    /**
+     * List of the pattern classes, one for each address decoded from the bind
+     * rule.
+     */
     private List<PatternIP> patternIPList=null;
 
-    /*
-      The type of the bind rule (!= or =).
-     */
+    /** The type of the bind rule (!= or =). */
     private EnumBindRuleType type=null;
 
     /**
@@ -129,4 +127,19 @@
         }
         return matched.getRet(type, false);
     }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        toString(sb);
+        return sb.toString();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final void toString(StringBuilder buffer) {
+        buffer.append(super.toString());
+    }
+
 }
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/KeywordBindRule.java b/opends/src/server/org/opends/server/authorization/dseecompat/KeywordBindRule.java
index 8ecdf9f..6162058 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/KeywordBindRule.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/KeywordBindRule.java
@@ -23,8 +23,8 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2013 ForgeRock AS
  */
-
 package org.opends.server.authorization.dseecompat;
 
 /**
@@ -41,4 +41,13 @@
      * @return An enumeration evaluation result.
      */
     public EnumEvalResult evaluate(AciEvalContext evalCtx);
+
+    /**
+     * Appends a string representation of this object to the provided buffer.
+     *
+     * @param buffer
+     *          The buffer into which a string representation of this object
+     *          should be appended.
+     */
+    void toString(StringBuilder buffer);
 }
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/PermBindRulePair.java b/opends/src/server/org/opends/server/authorization/dseecompat/PermBindRulePair.java
index f3621ea..7519ec9 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/PermBindRulePair.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/PermBindRulePair.java
@@ -23,8 +23,8 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2013 ForgeRock AS
  */
-
 package org.opends.server.authorization.dseecompat;
 
 /**
@@ -33,14 +33,10 @@
  */
 public class PermBindRulePair {
 
-    /*
-     * The Bind Rule part.
-     */
+    /** The Bind Rule part. */
     private BindRule bindRule;
 
-    /*
-     * The permission part.
-     */
+    /** The permission part. */
     private Permission perm=null;
 
     /**
@@ -97,4 +93,30 @@
     public boolean hasRights(int right) {
         return perm.hasRights(right);
     }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        toString(sb);
+        return sb.toString();
+    }
+
+    /**
+     * Appends a string representation of this object to the provided buffer.
+     *
+     * @param buffer
+     *          The buffer into which a string representation of this object
+     *          should be appended.
+     */
+    public final void toString(StringBuilder buffer) {
+        if (this.perm != null) {
+            this.perm.toString(buffer);
+        }
+        buffer.append(" ");
+        if (this.bindRule != null) {
+            this.bindRule.toString(buffer);
+        }
+        buffer.append(")"); // not sure why, but we need this extra parenthesis
+    }
 }
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/Permission.java b/opends/src/server/org/opends/server/authorization/dseecompat/Permission.java
index 21c3fed..de1927f 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/Permission.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/Permission.java
@@ -23,38 +23,41 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2013 ForgeRock AS
  */
-
 package org.opends.server.authorization.dseecompat;
-import org.opends.messages.Message;
-
 import static org.opends.messages.AccessControlMessages.*;
 import static org.opends.server.authorization.dseecompat.Aci.*;
+
+import java.util.Iterator;
+import java.util.Set;
 import java.util.regex.Pattern;
 
+import org.opends.messages.Message;
+
 /**
  * A class representing the permissions of an bind rule. The permissions
  * of an ACI look like deny(search, write).
  */
 public class Permission {
 
-    /*
+    /**
      *  The access type (allow,deny) corresponding to the ACI permission value.
      */
     private EnumAccessType accessType = null;
 
-    /*
+    /**
      * The rights (search, add, delete, ...) corresponding to the ACI rights
      * value.
      */
     private int rights;
 
-    /*
+    /**
      * Regular expression token representing the separator.
      */
     private static final String separatorToken = ",";
 
-    /*
+    /**
      * Regular expression used to match the ACI rights string.
      */
     private static final String rightsRegex = ZERO_OR_MORE_WHITESPACE +
@@ -108,9 +111,8 @@
      * rule.
      * @throws AciException  If the accesstype or rights strings are invalid.
      */
-    public static
-    Permission decode (String accessType, String rights)
-    throws AciException {
+    public static Permission decode (String accessType, String rights)
+            throws AciException {
         return new Permission(accessType, rights);
     }
 
@@ -132,4 +134,39 @@
     public boolean hasRights(int rights) {
         return (this.rights & rights) != 0;
     }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        toString(sb);
+        return sb.toString();
+    }
+
+    /**
+     * Appends a string representation of this object to the provided buffer.
+     *
+     * @param buffer
+     *          The buffer into which a string representation of this object
+     *          should be appended.
+     */
+    public final void toString(StringBuilder buffer) {
+        if (this.accessType != null) {
+            buffer.append(accessType.toString().toLowerCase());
+            Set<EnumRight> enumRights = EnumRight.getEnumRight(rights);
+            if (enumRights != null) {
+                buffer.append("(");
+                for (Iterator<EnumRight> iter = enumRights.iterator(); iter
+                        .hasNext();) {
+                    buffer.append(iter.next().getRight());
+                    if (iter.hasNext()) {
+                        buffer.append(",");
+                    }
+                }
+                buffer.append(")");
+            } else {
+                buffer.append("(all)");
+            }
+        }
+    }
 }
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/SSF.java b/opends/src/server/org/opends/server/authorization/dseecompat/SSF.java
index c437b15..ce4f876 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/SSF.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/SSF.java
@@ -23,8 +23,8 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2013 ForgeRock AS
  */
-
 package org.opends.server.authorization.dseecompat;
 
 import org.opends.messages.Message;
@@ -33,13 +33,10 @@
 /**
  * The class represents the ssf keyword in a bind rule.SSF stands for
  * security strength factor.
- *
  */
 public class SSF implements KeywordBindRule {
 
-    /*
-     *  Enumeration representing the bind rule operation type.
-     */
+    /** Enumeration representing the bind rule operation type. */
     private EnumBindRuleType type=null;
 
     private static final int MAX_KEY_BITS=1024;
@@ -58,8 +55,7 @@
      * @return A SSF instance.
      * @throws AciException If the SSF instance cannot be created.
      */
-    static SSF
-    decode(String expr, EnumBindRuleType type) throws AciException  {
+    static SSF decode(String expr, EnumBindRuleType type) throws AciException {
         int valueAsInt = 0;
         try {
             valueAsInt = Integer.parseInt(expr);
@@ -113,4 +109,21 @@
         }
         return matched.getRet(type, false);
     }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString()
+    {
+        final StringBuilder sb = new StringBuilder();
+        toString(sb);
+        return sb.toString();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final void toString(StringBuilder buffer)
+    {
+        buffer.append(super.toString());
+    }
+
 }
\ No newline at end of file
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/TargAttrFilterList.java b/opends/src/server/org/opends/server/authorization/dseecompat/TargAttrFilterList.java
index c8723b0..4dabe06 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/TargAttrFilterList.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/TargAttrFilterList.java
@@ -23,20 +23,22 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2013 ForgeRock AS
  */
-
 package org.opends.server.authorization.dseecompat;
-import org.opends.messages.Message;
 
-import org.opends.server.types.AttributeType;
-import org.opends.server.types.SearchFilter;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.core.DirectoryServer;
 import static org.opends.messages.AccessControlMessages.*;
 import static org.opends.server.authorization.dseecompat.Aci.*;
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
+
 import java.util.LinkedHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.opends.messages.Message;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.types.AttributeType;
+import org.opends.server.types.DirectoryException;
+import org.opends.server.types.SearchFilter;
 
 /**
  * The TargAttrFilterList class represents an targattrfilters list. A
@@ -46,42 +48,42 @@
  */
 public class TargAttrFilterList {
 
-    /*
-     * The mask coresponding to the operation of this list (add or del).
-     */
+  /**
+   * The mask corresponding to the operation of this list (add or del).
+   */
     private int mask=0;
 
-    /*
-     * ListHashMap keyed by the attribute type and mapping to the corresponding
-     * search filter. LinkedHashMap is used so everything is in order.
-     */
+  /**
+   * ListHashMap keyed by the attribute type and mapping to the corresponding
+   * search filter. LinkedHashMap is used so everything is in order.
+   */
     private LinkedHashMap<AttributeType, SearchFilter> attrFilterList;
 
-    /*
-     * Regular expression group count.
-     */
+  /**
+   * Regular expression group count.
+   */
     private static int expectedGroupCount=2;
 
-    /*
-     * Regular expression attribute group position.
-     */
+  /**
+   * Regular expression attribute group position.
+   */
     private static int attributePos=1;
 
-    /*
-     * Regular expression filter group position.
-     */
+  /**
+   * Regular expression filter group position.
+   */
     private static int filterPos=2;
 
-    /*
-     * Regular expression used to match a filter list including the strange
-     * "and" token used to join the multiple attribute type filter pairs.
-     */
+  /**
+   * Regular expression used to match a filter list including the strange "and"
+   * token used to join the multiple attribute type filter pairs.
+   */
     private static final String filterListSeperator =
               ZERO_OR_MORE_WHITESPACE  + "&&" + ZERO_OR_MORE_WHITESPACE;
 
-    /*
-     * Regular expression used to match an attribute filter pair.
-     */
+  /**
+   * Regular expression used to match an attribute filter pair.
+   */
     private static final String attributeFilter=
             ATTR_NAME + ZERO_OR_MORE_WHITESPACE + ":{1}" +
             ZERO_OR_MORE_WHITESPACE + "(\\({1}.*\\){1})";
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/TargAttrFilters.java b/opends/src/server/org/opends/server/authorization/dseecompat/TargAttrFilters.java
index d614b49..1a52210 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/TargAttrFilters.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/TargAttrFilters.java
@@ -23,51 +23,51 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2013 ForgeRock AS
  */
-
 package org.opends.server.authorization.dseecompat;
-import org.opends.messages.Message;
 
 import static org.opends.messages.AccessControlMessages.*;
 import static org.opends.server.authorization.dseecompat.Aci.*;
-import org.opends.server.types.*;
 
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.opends.messages.Message;
+import org.opends.server.types.*;
 
 /**
  * The TargAttrFilters class represents a targattrfilters rule of an ACI.
  */
 public class TargAttrFilters {
 
-    /*
+    /**
      * A valid targattrfilters rule may have two TargFilterlist parts -- the
      * first one is required.
      */
-    TargAttrFilterList firstFilterList=null;
-    TargAttrFilterList secondFilterList=null;
+    private TargAttrFilterList firstFilterList = null;
+    private TargAttrFilterList secondFilterList = null;
 
-    /*
+    /**
      * Regular expression group position for the first operation value.
      */
     private static final int firstOpPos = 1;
 
-    /*
+    /**
      * Regular expression group position for the rest of an partially parsed
      * rule.
      */
     private static final int restOfExpressionPos=2;
 
-    /*
+    /**
      * Regular expression used to match the operation group (either add or del).
      */
     private static final String ADD_OR_DEL_KEYWORD_GROUP = "(add|del)";
 
-    /*
+    /**
      * Regular expression used to check for valid expression separator.
      */
-
     private static final
     String secondOpSeparator="\\)" +  ZERO_OR_MORE_WHITESPACE + ",";
 
@@ -80,31 +80,31 @@
             "[,]{1}" + ZERO_OR_MORE_WHITESPACE + "del|add" +
             ZERO_OR_MORE_WHITESPACE + EQUAL_SIGN + ZERO_OR_MORE_WHITESPACE;
 
-    /*
+    /**
      * Regular expression used to match the first targFilterList, it must exist
      * or an exception is thrown.
      */
     private static final String firstOp = "^" + ADD_OR_DEL_KEYWORD_GROUP +
             ZERO_OR_MORE_WHITESPACE + EQUAL_SIGN + ZERO_OR_MORE_WHITESPACE;
 
-    /*
+    /**
      * Regular expression used to group the remainder of a partially parsed
      * rule.  Any character one or more times.
      */
     private static String restOfExpression = "(.+)";
 
-    /*
+    /**
      * Regular expression used to match the first operation keyword and the
      * rest of the expression.
      */
     private static String keywordFullPattern = firstOp + restOfExpression;
 
-    /*
+    /**
      * The enumeration representing the operation.
      */
     EnumTargetOperator op;
 
-    /*
+    /**
      * A mask used to denote if the rule has add, del or both operations in the
      * composite TargFilterList parts.
      */
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/TimeOfDay.java b/opends/src/server/org/opends/server/authorization/dseecompat/TimeOfDay.java
index 32b67c2..75a9d3b 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/TimeOfDay.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/TimeOfDay.java
@@ -23,8 +23,8 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2013 ForgeRock AS
  */
-
 package org.opends.server.authorization.dseecompat;
 import org.opends.messages.Message;
 
@@ -37,19 +37,15 @@
  */
 public class TimeOfDay implements KeywordBindRule {
 
-    /*
+    /**
      * Regular expression matching a valid timeofday rule value (0-2359).
      */
     private static final String timeofdayRegex = "[0-2]\\d[0-5]\\d";
 
-    /*
-     *  Enumeration representing the bind rule operation type.
-     */
+    /** Enumeration representing the bind rule operation type. */
     private EnumBindRuleType type=null;
 
-    /*
-     * Holds the time value parsed from the ACI.
-     */
+    /** Holds the time value parsed from the ACI. */
     private int timeRef;
 
     /**
@@ -143,4 +139,21 @@
         }
         return matched.getRet(type, false);
     }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString()
+    {
+        final StringBuilder sb = new StringBuilder();
+        toString(sb);
+        return sb.toString();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final void toString(StringBuilder buffer)
+    {
+        buffer.append(super.toString());
+    }
+
 }
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/UserAttr.java b/opends/src/server/org/opends/server/authorization/dseecompat/UserAttr.java
index bf1173c..ac50040 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/UserAttr.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/UserAttr.java
@@ -23,20 +23,22 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
- *      Portions Copyright 2011 ForgeRock AS
+ *      Portions Copyright 2011-2013 ForgeRock AS
  */
-
 package org.opends.server.authorization.dseecompat;
-import org.opends.messages.Message;
 
 import static org.opends.messages.AccessControlMessages.*;
+
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
+
+import org.opends.messages.Message;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.protocols.internal.InternalClientConnection;
 import org.opends.server.protocols.internal.InternalSearchOperation;
 import org.opends.server.types.*;
+
 /*
  * TODO Evaluate making this class more efficient.
  *
@@ -58,36 +60,28 @@
         USERDN, GROUPDN, ROLEDN, URL, VALUE
     }
 
-    /*
-     * Filter used in  internal search.
-     */
+    /** Filter used internal search. */
     private static SearchFilter filter;
 
-    /*
+    /**
      * Used to create an attribute type that can compare the value below in
      * an entry returned from an internal search.
      */
     private  String attrStr=null;
 
-    /*
+    /**
      * Used to compare a attribute value returned from a search against this
      * value which might have been defined in the ACI userattr rule.
      */
     private  String attrVal=null;
 
-    /*
-     * Contains the type of the userattr, one of the above enumerations.
-     */
+    /** Contains the type of the userattr, one of the above enumerations. */
     private UserAttrType userAttrType=null;
 
-    /*
-     * An enumeration representing the bind rule type.
-     */
+    /** An enumeration representing the bind rule type. */
     private EnumBindRuleType type=null;
 
-    /*
-     * The class used to hold the parent inheritance information.
-     */
+    /** The class used to hold the parent inheritance information. */
     private ParentInheritance parentInheritance=null;
 
     static {
@@ -174,6 +168,7 @@
      * userattr expression.
      * @return  An enumeration containing the result of the evaluation.
      */
+    @Override
     public EnumEvalResult evaluate(AciEvalContext evalCtx) {
       EnumEvalResult matched;
       //The working resource entry might be filtered and not have an
@@ -416,4 +411,20 @@
         return result;
     }
 
+    /** {@inheritDoc} */
+    @Override
+    public String toString()
+    {
+        final StringBuilder sb = new StringBuilder();
+        toString(sb);
+        return sb.toString();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final void toString(StringBuilder buffer)
+    {
+        buffer.append(super.toString());
+    }
+
 }
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/UserDN.java b/opends/src/server/org/opends/server/authorization/dseecompat/UserDN.java
index 34748af..1bd7373 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/UserDN.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/UserDN.java
@@ -23,34 +23,37 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2013 ForgeRock AS
  */
-
 package org.opends.server.authorization.dseecompat;
-import org.opends.messages.Message;
 
 import static org.opends.messages.AccessControlMessages.*;
-import java.util.*;
-import org.opends.server.types.*;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.opends.messages.Message;
 import org.opends.server.core.DirectoryServer;
+import org.opends.server.types.*;
 
 /**
  * This class represents the userdn keyword in a bind rule.
  */
 public class UserDN implements KeywordBindRule {
-    /*
+
+    /**
      * A dummy URL for invalid URLs such as: all, parent, anyone, self.
      */
     private static String urlStr="ldap:///";
 
-    /*
+    /**
      * This list holds a list of objects representing a EnumUserDNType
      * URL mapping.
      */
     private List<UserDNTypeURL> urlList=null;
 
-    /*
-     * Enumeration of the userdn operation type.
-     */
+    /** Enumeration of the userdn operation type. */
     private EnumBindRuleType type=null;
 
     /**
@@ -78,9 +81,9 @@
 
         String[] vals=expression.split("[|][|]");
         List<UserDNTypeURL> urlList = new LinkedList<UserDNTypeURL>();
-         for(int i=0, m=vals.length; i < m; i++)
+        for (String val : vals)
         {
-            StringBuilder value = new StringBuilder(vals[i].trim());
+            StringBuilder value = new StringBuilder(val.trim());
            /*
             * TODO Evaluate using a wild-card in the dn portion of LDAP url.
             * The current implementation (DS6) does not treat a "*"
@@ -174,6 +177,7 @@
      * @return  An evaluation result enumeration containing the result
      * of the evaluation.
      */
+    @Override
     public EnumEvalResult evaluate(AciEvalContext evalCtx) {
         EnumEvalResult matched = EnumEvalResult.FALSE;
         boolean undefined=false;
@@ -372,4 +376,26 @@
         }
         return matched;
     }
-}
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        toString(sb);
+        return sb.toString();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public final void toString(StringBuilder buffer) {
+        buffer.append("userdn");
+        buffer.append(this.type.getType());
+        for (UserDNTypeURL url : this.urlList) {
+            buffer.append("\"");
+            buffer.append(urlStr);
+            buffer.append(url.getUserDNType().toString().toLowerCase());
+            buffer.append("\"");
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciBodyTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciBodyTest.java
new file mode 100644
index 0000000..f8ba1c2
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciBodyTest.java
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2013 ForgeRock AS
+ */
+package org.opends.server.authorization.dseecompat;
+
+import static org.assertj.core.api.Assertions.*;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+@SuppressWarnings("javadoc")
+public class AciBodyTest extends AciTestCase
+{
+
+  @DataProvider(name = "validAcis")
+  public Object[][] getValidAcis()
+  {
+    return new Object[][] {
+      { "(version 3.0; acl \"Anonymous extended operation access\"; deny(all) userdn=\"ldap:///anyone\";)" },
+      { "(version 3.0; acl \"Anonymous extended operation access\"; allow(read) userdn=\"ldap:///anyone\";)" },
+      { "(version 3.0; acl \"Self entry modification\"; allow(write) userdn=\"ldap:///self\";)" },
+      { "(version 3.0; acl \"Self entry read\"; allow(read,search,compare) userdn=\"ldap:///self\";)" },
+      { "(version 3.0; acl \"Anonymous read access\"; allow(read,search,compare) userdn=\"ldap:///anyone\";)" },
+      { "(version 3.0; acl \"Anonymous control access\"; allow(read) userdn=\"ldap:///anyone\";)" },
+      { "(version 3.0; acl \"Authenticated users control access\"; allow(read) userdn=\"ldap:///all\";)" }, };
+  }
+
+  @Test(dataProvider = "validAcis")
+  public void decodeValidAci(String aci) throws Exception
+  {
+    AciBody aciBody = AciBody.decode(aci);
+    assertThat(aciBody.toString()).isEqualTo(aci);
+    assertThat(aciBody.getPermBindRulePairs()).hasSize(1);
+  }
+}

--
Gitblit v1.10.0