From 7f6277674fe97838b58a8fffb33e3351e0dc6a9f Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Thu, 27 Sep 2007 14:50:30 +0000
Subject: [PATCH] Improvements to aggregation support and foundation work for expressing arbitrary constraints within components.

---
 opendj-sdk/opends/resource/admin/metaMO.xsl                                                                                |    4 
 opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/LDAPConnectionHandlerConfiguration.xml                        |  123 ++
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.java                         |    2 
 opendj-sdk/opends/src/messages/messages/dsconfig.properties                                                                |    3 
 opendj-sdk/opends/src/server/org/opends/server/admin/condition/ContainsValueCondition.java                                 |  197 ++++
 opendj-sdk/opends/src/server/org/opends/server/admin/condition/NOTCondition.java                                           |   97 ++
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/plugin/DomainFakeCfg.java               |    6 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/server/ReplServerFakeConfiguration.java |    6 
 opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/Package.xml                                                   |   60 -
 opendj-sdk/opends/src/server/org/opends/server/admin/condition/ORCondition.java                                            |  112 ++
 opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PlainSASLMechanismHandlerConfiguration.xml                    |    8 
 opendj-sdk/opends/src/server/org/opends/server/admin/condition/Condition.java                                              |   94 ++
 opendj-sdk/opends/src/server/org/opends/server/admin/condition/IsPresentCondition.java                                     |  104 ++
 opendj-sdk/opends/src/server/org/opends/server/admin/Configuration.java                                                    |   13 
 opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PasswordPolicyConfiguration.xml                               |   20 
 opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PasswordModifyExtendedOperationHandlerConfiguration.xml       |    8 
 opendj-sdk/opends/src/server/org/opends/server/admin/condition/package-info.java                                           |   36 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.java                        |    2 
 opendj-sdk/opends/src/server/org/opends/server/admin/condition/Conditions.java                                             |  237 +++++
 opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/CreateSubCommandHandler.java                                 |  256 ++---
 opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/CramMD5SASLMechanismHandlerConfiguration.xml                  |    8 
 opendj-sdk/opends/src/messages/messages/admin.properties                                                                   |    3 
 opendj-sdk/opends/resource/admin/conditions.xsl                                                                            |   96 ++
 opendj-sdk/opends/src/server/org/opends/server/admin/AggregationPropertyDefinition.java                                    |  346 ++-----
 opendj-sdk/opends/src/server/org/opends/server/admin/condition/ANDCondition.java                                           |  112 ++
 opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/DigestMD5SASLMechanismHandlerConfiguration.xml                |    8 
 opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml                                       |    4 
 opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/ExternalSASLMechanismHandlerConfiguration.xml                 |    8 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/AggregationTest.java                   |    7 
 opendj-sdk/opends/resource/admin/admin.xsd                                                                                 |  163 +++
 opendj-sdk/opends/resource/admin/property-types/aggregation.xsl                                                            |   35 
 opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/SetPropSubCommandHandler.java                                |  256 ++---
 opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/JMXConnectionHandlerConfiguration.xml                         |   37 
 opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/GSSAPISASLMechanismHandlerConfiguration.xml                   |    8 
 opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PasswordPolicyImportPluginConfiguration.xml                   |   16 
 35 files changed, 1,823 insertions(+), 672 deletions(-)

diff --git a/opendj-sdk/opends/resource/admin/admin.xsd b/opendj-sdk/opends/resource/admin/admin.xsd
index 9fb5f95..ba3fd5c 100644
--- a/opendj-sdk/opends/resource/admin/admin.xsd
+++ b/opendj-sdk/opends/resource/admin/admin.xsd
@@ -1036,49 +1036,37 @@
         </xsd:annotation>
         <xsd:complexType>
           <xsd:sequence>
-            <xsd:element name="source-enabled-property-name"
-              minOccurs="0" maxOccurs="unbounded">
-              <xsd:annotation>
-                <xsd:documentation>
-                  The optional boolean "enabled" property in the
-                  aggregating managed object. When this property is
-                  true, the "target-enabled-property-name" in the
-                  aggregated managed objects must also be true. The
-                  "target-enabled-property-name" attribute must be
-                  specified when this attribute is defined.
-                </xsd:documentation>
-              </xsd:annotation>
-              <xsd:complexType>
-                <xsd:attribute name="name" type="tns:name-type"
-                  use="required">
-                  <xsd:annotation>
-                    <xsd:documentation>
-                      The name of the source property.
-                    </xsd:documentation>
-                  </xsd:annotation>
-                </xsd:attribute>
-              </xsd:complexType>
-            </xsd:element>
-            <xsd:element name="target-enabled-property-name"
+            <xsd:element name="target-needs-enabling-condition"
               minOccurs="0">
               <xsd:annotation>
                 <xsd:documentation>
-                  The optional boolean "enabled" property in the
-                  aggregated managed objects. This property must not be
-                  false while the aggregated managed object is
-                  referenced. This attribute must be defined when the
-                  "source-enabled-property-name" attribute is specified.
+                  A condition which indicates whether or not referenced
+                  managed objects must be enabled. The default behavior
+                  is that all referenced managed objects must be
+                  enabled.
                 </xsd:documentation>
               </xsd:annotation>
               <xsd:complexType>
-                <xsd:attribute name="name" type="tns:name-type"
-                  use="required">
-                  <xsd:annotation>
-                    <xsd:documentation>
-                      The name of the target property.
-                    </xsd:documentation>
-                  </xsd:annotation>
-                </xsd:attribute>
+                <xsd:sequence>
+                  <xsd:group ref="tns:condition-group" />
+                </xsd:sequence>
+              </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="target-is-enabled-condition"
+              minOccurs="0">
+              <xsd:annotation>
+                <xsd:documentation>
+                  A condition which indicates whether or not referenced
+                  managed objects are enabled. Managed objects are
+                  assumed to be enabled by default.
+                </xsd:documentation>
+              </xsd:annotation>
+              <xsd:complexType>
+                <xsd:sequence>
+                  <xsd:sequence>
+                    <xsd:group ref="tns:condition-group" />
+                  </xsd:sequence>
+                </xsd:sequence>
               </xsd:complexType>
             </xsd:element>
           </xsd:sequence>
@@ -1894,4 +1882,105 @@
       </xsd:attribute>
     </xsd:complexType>
   </xsd:element>
+  <xsd:group name="condition-group">
+    <xsd:choice>
+      <xsd:element name="not">
+        <xsd:annotation>
+          <xsd:documentation>
+            A condition which evaluates to true if the sub-condition is
+            false, or false if the sub-condition is true.
+          </xsd:documentation>
+        </xsd:annotation>
+        <xsd:complexType>
+          <xsd:sequence>
+            <xsd:group ref="tns:condition-group" />
+          </xsd:sequence>
+        </xsd:complexType>
+      </xsd:element>
+      <xsd:element name="and">
+        <xsd:annotation>
+          <xsd:documentation>
+            A condition which evaluates to true if and only if all of
+            its sub-conditions are true.
+          </xsd:documentation>
+        </xsd:annotation>
+        <xsd:complexType>
+          <xsd:sequence>
+            <xsd:group ref="tns:condition-group" maxOccurs="unbounded" />
+          </xsd:sequence>
+        </xsd:complexType>
+      </xsd:element>
+      <xsd:element name="or">
+        <xsd:annotation>
+          <xsd:documentation>
+            A condition which evaluates to false if and only if none of
+            its sub-conditions are true.
+          </xsd:documentation>
+        </xsd:annotation>
+        <xsd:complexType>
+          <xsd:sequence>
+            <xsd:group ref="tns:condition-group" maxOccurs="unbounded" />
+          </xsd:sequence>
+        </xsd:complexType>
+      </xsd:element>
+      <xsd:element name="implies">
+        <xsd:annotation>
+          <xsd:documentation>
+            Creates a condition which evaluates to false if and only if
+            the first sub-condition evaluates to true and the second
+            sub-condition evaluates to false. This can be used to
+            represent if-then relationships.
+          </xsd:documentation>
+        </xsd:annotation>
+        <xsd:complexType>
+          <xsd:sequence>
+            <xsd:group ref="tns:condition-group" />
+            <xsd:group ref="tns:condition-group" />
+          </xsd:sequence>
+        </xsd:complexType>
+      </xsd:element>
+      <xsd:element name="contains">
+        <xsd:annotation>
+          <xsd:documentation>
+            A condition which evaluates to true if and only if a
+            property contains a particular value.
+          </xsd:documentation>
+        </xsd:annotation>
+        <xsd:complexType>
+          <xsd:attribute name="property" type="tns:name-type"
+            use="required">
+            <xsd:annotation>
+              <xsd:documentation>
+                The name of the property to be tested.
+              </xsd:documentation>
+            </xsd:annotation>
+          </xsd:attribute>
+          <xsd:attribute name="value" type="xsd:string"
+            use="required">
+            <xsd:annotation>
+              <xsd:documentation>The property value.</xsd:documentation>
+            </xsd:annotation>
+          </xsd:attribute>
+        </xsd:complexType>
+      </xsd:element>
+      <xsd:element name="is-present">
+        <xsd:annotation>
+          <xsd:documentation>
+            Creates a condition which evaluates to true if and only if a
+            particular property has any values specified.
+          </xsd:documentation>
+        </xsd:annotation>
+        <xsd:complexType>
+          <xsd:attribute name="property" type="tns:name-type"
+            use="required">
+            <xsd:annotation>
+              <xsd:documentation>
+                The name of the property to be tested.
+              </xsd:documentation>
+            </xsd:annotation>
+          </xsd:attribute>
+        </xsd:complexType>
+      </xsd:element>
+    </xsd:choice>
+  </xsd:group>
 </xsd:schema>
diff --git a/opendj-sdk/opends/resource/admin/conditions.xsl b/opendj-sdk/opends/resource/admin/conditions.xsl
new file mode 100644
index 0000000..5931b42
--- /dev/null
+++ b/opendj-sdk/opends/resource/admin/conditions.xsl
@@ -0,0 +1,96 @@
+<!--
+  ! 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
+  !
+  !
+  !      Portions Copyright 2007 Sun Microsystems, Inc.
+  ! -->
+<xsl:stylesheet version="1.0" xmlns:adm="http://www.opends.org/admin"
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+  <!--
+    
+    
+    
+    Rules for compiling conditions from their XML definition.
+    
+    
+    
+  -->
+  <!--
+    and condition
+  -->
+  <xsl:template match="adm:and" mode="compile-condition">
+    <xsl:value-of select="'Conditions.and('" />
+    <xsl:for-each select="*">
+      <xsl:apply-templates select="." mode="compile-condition" />
+      <xsl:if test="position() != last()">
+        <xsl:value-of select="', '" />
+      </xsl:if>
+    </xsl:for-each>
+    <xsl:value-of select="')'" />
+  </xsl:template>
+  <!--
+    or condition
+  -->
+  <xsl:template match="adm:or" mode="compile-condition">
+    <xsl:value-of select="'Conditions.or('" />
+    <xsl:for-each select="*">
+      <xsl:apply-templates select="." mode="compile-condition" />
+      <xsl:if test="position() != last()">
+        <xsl:value-of select="', '" />
+      </xsl:if>
+    </xsl:for-each>
+    <xsl:value-of select="')'" />
+  </xsl:template>
+  <!--
+    not condition
+  -->
+  <xsl:template match="adm:not" mode="compile-condition">
+    <xsl:value-of select="'Conditions.not('" />
+    <xsl:apply-templates select="*[1]" mode="compile-condition" />
+    <xsl:value-of select="')'" />
+  </xsl:template>
+  <!--
+    implies condition
+  -->
+  <xsl:template match="adm:implies" mode="compile-condition">
+    <xsl:value-of select="'Conditions.implies('" />
+    <xsl:apply-templates select="*[1]" mode="compile-condition" />
+    <xsl:value-of select="', '" />
+    <xsl:apply-templates select="*[2]" mode="compile-condition" />
+    <xsl:value-of select="')'" />
+  </xsl:template>
+  <!--
+    contains condition
+  -->
+  <xsl:template match="adm:contains" mode="compile-condition">
+    <xsl:value-of
+      select="concat('Conditions.contains(&quot;', @property, '&quot;, &quot;', @value, '&quot;)')" />
+  </xsl:template>
+  <!--
+    is-present condition
+  -->
+  <xsl:template match="adm:is-present" mode="compile-condition">
+    <xsl:value-of
+      select="concat('Conditions.isPresent(&quot;', @property, '&quot;)')" />
+  </xsl:template>
+</xsl:stylesheet>
diff --git a/opendj-sdk/opends/resource/admin/metaMO.xsl b/opendj-sdk/opends/resource/admin/metaMO.xsl
index 8266696..7a0aa0d 100644
--- a/opendj-sdk/opends/resource/admin/metaMO.xsl
+++ b/opendj-sdk/opends/resource/admin/metaMO.xsl
@@ -580,7 +580,7 @@
                      '      return INSTANCE;&#xa;',
                      '    }&#xa;')" />
     <!--
-      Property provider view.
+      Server managed object getter.
     -->
     <xsl:text>&#xa;</xsl:text>
     <xsl:text>&#xa;</xsl:text>
@@ -589,7 +589,7 @@
       select="concat('    /**&#xa;',
                      '     * {@inheritDoc}&#xa;',
                      '     */&#xa;',
-                     '    public PropertyProvider properties() {&#xa;',
+                     '    public ServerManagedObject&lt;? extends ', $this-java-class,'Cfg&gt; managedObject() {&#xa;',
                      '      return impl;&#xa;',
                      '    }&#xa;')" />
     <!--
diff --git a/opendj-sdk/opends/resource/admin/property-types/aggregation.xsl b/opendj-sdk/opends/resource/admin/property-types/aggregation.xsl
index 5ff16d0..22d3a33 100644
--- a/opendj-sdk/opends/resource/admin/property-types/aggregation.xsl
+++ b/opendj-sdk/opends/resource/admin/property-types/aggregation.xsl
@@ -26,6 +26,7 @@
   ! -->
 <xsl:stylesheet version="1.0" xmlns:adm="http://www.opends.org/admin"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+  <xsl:include href="../conditions.xsl" />
   <!-- 
     Templates for processing aggregation properties.
   -->
@@ -44,6 +45,12 @@
     <xsl:if test="../../@multi-valued = 'true'">
       <import>java.util.TreeSet</import>
     </xsl:if>
+    <xsl:if test="adm:target-needs-enabling-condition">
+      <import>org.opends.server.admin.condition.Conditions</import>
+    </xsl:if>
+    <xsl:if test="adm:target-is-enabled-condition">
+      <import>org.opends.server.admin.condition.Conditions</import>
+    </xsl:if>
     <import>
       org.opends.server.admin.AggregationPropertyDefinition
     </import>
@@ -79,30 +86,26 @@
           select="concat('No relation-name defined for aggregation property ', ../../@name)" />
       </xsl:message>
     </xsl:if>
-    <xsl:if
-      test="@source-enabled-property-name and not(@target-enabled-property-name)">
-      <xsl:message terminate="yes">
-        <xsl:value-of
-          select="concat('source-enabled-property-name defined but target-enabled-property-name undefined in aggregation property ', ../../@name)" />
-      </xsl:message>
-    </xsl:if>
     <xsl:value-of
       select="concat('      builder.setParentPath(&quot;',
                      normalize-space(@parent-path), '&quot;);&#xa;')" />
     <xsl:value-of
       select="concat('      builder.setRelationDefinition(&quot;',
                      normalize-space(@relation-name), '&quot;);&#xa;')" />
-    <xsl:for-each select="adm:source-enabled-property-name">
-      <xsl:sort select="@name" />
+    <xsl:if test="adm:target-needs-enabling-condition">
       <xsl:value-of
-        select="concat('      builder.addSourceEnabledPropertyName(&quot;',
-                       normalize-space(@name), '&quot;);&#xa;')" />
-    </xsl:for-each>
-    <xsl:if test="source-enabled-property-name"></xsl:if>
-    <xsl:if test="adm:target-enabled-property-name">
+        select="'      builder.setTargetNeedsEnablingCondition('" />
+      <xsl:apply-templates
+        select="adm:target-needs-enabling-condition/*"
+        mode="compile-condition" />
+      <xsl:value-of select="');&#xa;'" />
+    </xsl:if>
+    <xsl:if test="adm:target-is-enabled-condition">
       <xsl:value-of
-        select="concat('      builder.setTargetEnabledPropertyName(&quot;',
-                       normalize-space(adm:target-enabled-property-name/@name), '&quot;);&#xa;')" />
+        select="'      builder.setTargetIsEnabledCondition('" />
+      <xsl:apply-templates select="adm:target-is-enabled-condition/*"
+        mode="compile-condition" />
+      <xsl:value-of select="');&#xa;'" />
     </xsl:if>
   </xsl:template>
   <xsl:template match="adm:aggregation"
diff --git a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/CramMD5SASLMechanismHandlerConfiguration.xml b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/CramMD5SASLMechanismHandlerConfiguration.xml
index 6fede87..b85efa0 100644
--- a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/CramMD5SASLMechanismHandlerConfiguration.xml
+++ b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/CramMD5SASLMechanismHandlerConfiguration.xml
@@ -59,8 +59,12 @@
     <adm:syntax>
       <adm:aggregation relation-name="identity-mapper"
         parent-path="/">
-        <adm:source-enabled-property-name name="enabled" />
-        <adm:target-enabled-property-name name="enabled" />
+        <adm:target-needs-enabling-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-needs-enabling-condition>
+        <adm:target-is-enabled-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-is-enabled-condition>
       </adm:aggregation>
     </adm:syntax>
     <adm:profile name="ldap">
diff --git a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/DigestMD5SASLMechanismHandlerConfiguration.xml b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/DigestMD5SASLMechanismHandlerConfiguration.xml
index 7090b82..a5a2d8f 100644
--- a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/DigestMD5SASLMechanismHandlerConfiguration.xml
+++ b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/DigestMD5SASLMechanismHandlerConfiguration.xml
@@ -87,8 +87,12 @@
     <adm:syntax>
       <adm:aggregation relation-name="identity-mapper"
         parent-path="/">
-        <adm:source-enabled-property-name name="enabled" />
-        <adm:target-enabled-property-name name="enabled" />
+        <adm:target-needs-enabling-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-needs-enabling-condition>
+        <adm:target-is-enabled-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-is-enabled-condition>
       </adm:aggregation>
     </adm:syntax>
     <adm:profile name="ldap">
diff --git a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/ExternalSASLMechanismHandlerConfiguration.xml b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/ExternalSASLMechanismHandlerConfiguration.xml
index 96c36ec..01324da 100644
--- a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/ExternalSASLMechanismHandlerConfiguration.xml
+++ b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/ExternalSASLMechanismHandlerConfiguration.xml
@@ -134,8 +134,12 @@
     <adm:syntax>
       <adm:aggregation relation-name="certificate-mapper"
         parent-path="/">
-        <adm:source-enabled-property-name name="enabled" />
-        <adm:target-enabled-property-name name="enabled" />
+        <adm:target-needs-enabling-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-needs-enabling-condition>
+        <adm:target-is-enabled-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-is-enabled-condition>
       </adm:aggregation>
     </adm:syntax>
     <adm:profile name="ldap">
diff --git a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/GSSAPISASLMechanismHandlerConfiguration.xml b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/GSSAPISASLMechanismHandlerConfiguration.xml
index c0340ef..1645579 100644
--- a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/GSSAPISASLMechanismHandlerConfiguration.xml
+++ b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/GSSAPISASLMechanismHandlerConfiguration.xml
@@ -173,8 +173,12 @@
     <adm:syntax>
       <adm:aggregation relation-name="identity-mapper"
         parent-path="/">
-        <adm:source-enabled-property-name name="enabled" />
-        <adm:target-enabled-property-name name="enabled" />
+        <adm:target-needs-enabling-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-needs-enabling-condition>
+        <adm:target-is-enabled-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-is-enabled-condition>
       </adm:aggregation>
     </adm:syntax>
     <adm:profile name="ldap">
diff --git a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml
index 7bf60ab..f149772 100644
--- a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml
+++ b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml
@@ -335,7 +335,9 @@
     <adm:syntax>
       <adm:aggregation relation-name="identity-mapper"
         parent-path="/">
-        <adm:target-enabled-property-name name="enabled" />
+        <adm:target-is-enabled-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-is-enabled-condition>
       </adm:aggregation>
     </adm:syntax>
     <adm:profile name="ldap">
diff --git a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/JMXConnectionHandlerConfiguration.xml b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/JMXConnectionHandlerConfiguration.xml
index a1af301..24a8f75 100644
--- a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/JMXConnectionHandlerConfiguration.xml
+++ b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/JMXConnectionHandlerConfiguration.xml
@@ -54,5 +54,40 @@
   <adm:property-reference name="listen-port" />
   <adm:property-reference name="use-ssl" />
   <adm:property-reference name="ssl-cert-nickname" />
-  <adm:property-reference name="key-manager-provider" />
+  <adm:property name="key-manager-provider">
+    <adm:synopsis>
+      Specifies the name of the key manager that should be used
+      with this <adm:user-friendly-name />.
+    </adm:synopsis>
+    <adm:requires-admin-action>
+      <adm:none>
+        <adm:synopsis>
+          Changes to this property will take effect immediately, but
+          only for subsequent attempts to access the key manager
+          provider for associated client connections.
+        </adm:synopsis>
+      </adm:none>
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:undefined />
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:aggregation relation-name="key-manager-provider" parent-path="/">
+        <adm:target-needs-enabling-condition>
+          <adm:and>
+            <adm:contains property="enabled" value="true" />
+            <adm:contains property="use-ssl" value="true" />
+          </adm:and>
+        </adm:target-needs-enabling-condition>
+        <adm:target-is-enabled-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-is-enabled-condition>
+      </adm:aggregation>
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:name>ds-cfg-key-manager-provider</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
 </adm:managed-object>
diff --git a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/LDAPConnectionHandlerConfiguration.xml b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/LDAPConnectionHandlerConfiguration.xml
index 97bc100..a46d69c 100644
--- a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/LDAPConnectionHandlerConfiguration.xml
+++ b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/LDAPConnectionHandlerConfiguration.xml
@@ -30,21 +30,18 @@
   package="org.opends.server.admin.std" extends="connection-handler"
   xmlns:adm="http://www.opends.org/admin"
   xmlns:ldap="http://www.opends.org/admin-ldap">
-
   <adm:synopsis>
     The
     <adm:user-friendly-name />
     is used to interact with clients using LDAP. In particular, it
     provides full support for LDAPv3 and limited support for LDAPv2.
   </adm:synopsis>
-
   <adm:profile name="ldap">
     <ldap:object-class>
       <ldap:name>ds-cfg-ldap-connection-handler</ldap:name>
       <ldap:superior>ds-cfg-connection-handler</ldap:superior>
     </ldap:object-class>
   </adm:profile>
-
   <adm:property-override name="java-class">
     <adm:default-behavior>
       <adm:defined>
@@ -54,17 +51,93 @@
       </adm:defined>
     </adm:default-behavior>
   </adm:property-override>
-
   <adm:property-reference name="listen-port" />
-
   <adm:property-reference name="use-ssl" />
-
   <adm:property-reference name="ssl-cert-nickname" />
-
-  <adm:property-reference name="key-manager-provider" />
-
-  <adm:property-reference name="trust-manager-provider" />
-
+  <adm:property name="key-manager-provider">
+    <adm:synopsis>
+      Specifies the name of the key manager that should be used with
+      this
+      <adm:user-friendly-name />
+      .
+    </adm:synopsis>
+    <adm:requires-admin-action>
+      <adm:none>
+        <adm:synopsis>
+          Changes to this property will take effect immediately, but
+          only for subsequent attempts to access the key manager
+          provider for associated client connections.
+        </adm:synopsis>
+      </adm:none>
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:undefined />
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:aggregation relation-name="key-manager-provider"
+        parent-path="/">
+        <adm:target-needs-enabling-condition>
+          <adm:and>
+            <adm:contains property="enabled" value="true" />
+            <adm:or>
+              <adm:contains property="use-ssl" value="true" />
+              <adm:contains property="allow-start-tls" value="true" />
+            </adm:or>
+          </adm:and>
+        </adm:target-needs-enabling-condition>
+        <adm:target-is-enabled-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-is-enabled-condition>
+      </adm:aggregation>
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:name>ds-cfg-key-manager-provider</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="trust-manager-provider">
+    <adm:synopsis>
+      Specifies the name of the trust manager that should be used with
+      this
+      <adm:user-friendly-name />
+      .
+    </adm:synopsis>
+    <adm:requires-admin-action>
+      <adm:none>
+        <adm:synopsis>
+          Changes to this property will take effect immediately, but
+          only for subsequent attempts to access the trust manager
+          provider for associated client connections.
+        </adm:synopsis>
+      </adm:none>
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:undefined />
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:aggregation relation-name="trust-manager-provider"
+        parent-path="/">
+        <adm:target-needs-enabling-condition>
+          <adm:and>
+            <adm:contains property="enabled" value="true" />
+            <adm:or>
+              <adm:contains property="use-ssl" value="true" />
+              <adm:contains property="allow-start-tls" value="true" />
+            </adm:or>
+          </adm:and>
+        </adm:target-needs-enabling-condition>
+        <adm:target-is-enabled-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-is-enabled-condition>
+      </adm:aggregation>
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:name>ds-cfg-trust-manager-provider</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
   <adm:property name="listen-address" multi-valued="true">
     <adm:synopsis>
       Specifies the address or set of addresses on which this
@@ -94,7 +167,6 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
-
   <adm:property name="allow-ldap-v2">
     <adm:synopsis>
       Indicates whether connections from LDAPv2 clients will be allowed.
@@ -120,7 +192,6 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
-
   <adm:property name="keep-stats">
     <adm:synopsis>
       Indicates whether the
@@ -147,7 +218,6 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
-
   <adm:property name="use-tcp-keep-alive">
     <adm:synopsis>
       Indicates whether the
@@ -178,7 +248,6 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
-
   <adm:property name="use-tcp-no-delay">
     <adm:synopsis>
       Indicates whether the
@@ -209,7 +278,6 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
-
   <adm:property name="allow-tcp-reuse-address">
     <adm:synopsis>
       Indicates whether the
@@ -241,7 +309,6 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
-
   <adm:property name="send-rejection-notice">
     <adm:synopsis>
       Indicates whether the
@@ -267,7 +334,6 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
-
   <adm:property name="max-request-size">
     <adm:synopsis>
       Specifies the size of the largest LDAP request message that will
@@ -296,7 +362,6 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
-
   <adm:property name="num-request-handlers">
     <adm:synopsis>
       Specifies the number of request handlers that will be used to read
@@ -329,7 +394,6 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
-
   <adm:property name="allow-start-tls">
     <adm:synopsis>
       Indicates whether clients will be allowed to use StartTLS.
@@ -358,7 +422,6 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
-
   <adm:property name="ssl-client-auth-policy">
     <adm:synopsis>
       Specifies the policy that the
@@ -407,7 +470,6 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
-
   <adm:property name="accept-backlog">
     <adm:synopsis>
       Specifies the maximum number of pending connection attempts that
@@ -441,7 +503,6 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
-
   <adm:property name="ssl-protocol" multi-valued="true">
     <adm:synopsis>
       Specifies the names of the SSL protocols that will be allowed for
@@ -473,7 +534,6 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
-
   <adm:property name="ssl-cipher-suite" multi-valued="true">
     <adm:synopsis>
       Specifies the names of the SSL cipher suites that will be allowed
@@ -505,19 +565,16 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
-
   <adm:property name="max-blocked-write-time-limit" mandatory="false">
     <adm:synopsis>
-      Specifies the maximum length of time that attempts to write data to LDAP
-      clients should be allowed to block.  If an attempt to write data to a
-      client takes longer than this length of time, then the client connection
-      will be terminated.
+      Specifies the maximum length of time that attempts to write data
+      to LDAP clients should be allowed to block. If an attempt to write
+      data to a client takes longer than this length of time, then the
+      client connection will be terminated.
     </adm:synopsis>
     <adm:default-behavior>
       <adm:defined>
-        <adm:value>
-          2 minutes
-        </adm:value>
+        <adm:value>2 minutes</adm:value>
       </adm:defined>
     </adm:default-behavior>
     <adm:syntax>
@@ -529,6 +586,4 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
-
 </adm:managed-object>
-
diff --git a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/Package.xml b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/Package.xml
index 88d87ba..48f4f17 100644
--- a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/Package.xml
+++ b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/Package.xml
@@ -227,36 +227,6 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
-  <adm:property name="key-manager-provider">
-    <adm:synopsis>
-      Specifies the name of the key manager that should be used
-      with this <adm:user-friendly-name />.
-    </adm:synopsis>
-    <adm:requires-admin-action>
-      <adm:none>
-        <adm:synopsis>
-          Changes to this property will take effect immediately, but
-          only for subsequent attempts to access the key manager
-          provider for associated client connections.
-        </adm:synopsis>
-      </adm:none>
-    </adm:requires-admin-action>
-    <adm:default-behavior>
-      <adm:undefined />
-    </adm:default-behavior>
-    <adm:syntax>
-      <adm:aggregation relation-name="key-manager-provider" parent-path="/">
-        <adm:source-enabled-property-name name="enabled" />
-        <adm:source-enabled-property-name name="use-ssl" />
-        <adm:target-enabled-property-name name="enabled" />
-      </adm:aggregation>
-    </adm:syntax>
-    <adm:profile name="ldap">
-      <ldap:attribute>
-        <ldap:name>ds-cfg-key-manager-provider</ldap:name>
-      </ldap:attribute>
-    </adm:profile>
-  </adm:property>
   <adm:property name="trust-store-pin">
     <adm:synopsis>
       Specifies the clear-text PIN needed to access the
@@ -374,36 +344,6 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
-  <adm:property name="trust-manager-provider">
-    <adm:synopsis>
-      Specifies the name of the trust manager that should be used with
-      this <adm:user-friendly-name />.
-    </adm:synopsis>
-    <adm:requires-admin-action>
-      <adm:none>
-        <adm:synopsis>
-          Changes to this property will take effect immediately, but
-          only for subsequent attempts to access the trust manager
-          provider for associated client connections.
-        </adm:synopsis>
-      </adm:none>
-    </adm:requires-admin-action>
-    <adm:default-behavior>
-      <adm:undefined />
-    </adm:default-behavior>
-    <adm:syntax>
-      <adm:aggregation relation-name="trust-manager-provider" parent-path="/">
-        <adm:source-enabled-property-name name="enabled" />
-        <adm:source-enabled-property-name name="use-ssl" />
-        <adm:target-enabled-property-name name="enabled" />
-      </adm:aggregation>
-    </adm:syntax>
-    <adm:profile name="ldap">
-      <ldap:attribute>
-        <ldap:name>ds-cfg-trust-manager-provider</ldap:name>
-      </ldap:attribute>
-    </adm:profile>
-  </adm:property>
   <adm:property name="include-filter" mandatory="false"
     multi-valued="true">
     <adm:synopsis>
diff --git a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PasswordModifyExtendedOperationHandlerConfiguration.xml b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PasswordModifyExtendedOperationHandlerConfiguration.xml
index 3384c17..359c1a3 100644
--- a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PasswordModifyExtendedOperationHandlerConfiguration.xml
+++ b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PasswordModifyExtendedOperationHandlerConfiguration.xml
@@ -77,8 +77,12 @@
     <adm:syntax>
       <adm:aggregation relation-name="identity-mapper"
         parent-path="/">
-        <adm:source-enabled-property-name name="enabled" />
-        <adm:target-enabled-property-name name="enabled" />
+        <adm:target-needs-enabling-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-needs-enabling-condition>
+        <adm:target-is-enabled-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-is-enabled-condition>
       </adm:aggregation>
     </adm:syntax>
     <adm:profile name="ldap">
diff --git a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PasswordPolicyConfiguration.xml b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PasswordPolicyConfiguration.xml
index adbd640..53fde07 100644
--- a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PasswordPolicyConfiguration.xml
+++ b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PasswordPolicyConfiguration.xml
@@ -72,7 +72,9 @@
     <adm:syntax>
       <adm:aggregation relation-name="password-storage-scheme"
         parent-path="/">
-        <adm:target-enabled-property-name name="enabled" />
+        <adm:target-is-enabled-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-is-enabled-condition>
       </adm:aggregation>
     </adm:syntax>
     <adm:profile name="ldap">
@@ -98,7 +100,9 @@
     <adm:syntax>
       <adm:aggregation relation-name="password-storage-scheme"
         parent-path="/">
-        <adm:target-enabled-property-name name="enabled" />
+        <adm:target-is-enabled-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-is-enabled-condition>
       </adm:aggregation>
     </adm:syntax>
     <adm:profile name="ldap">
@@ -120,7 +124,9 @@
     <adm:syntax>
       <adm:aggregation relation-name="password-validator"
         parent-path="/">
-        <adm:target-enabled-property-name name="enabled" />
+        <adm:target-is-enabled-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-is-enabled-condition>
       </adm:aggregation>
     </adm:syntax>
     <adm:profile name="ldap">
@@ -143,7 +149,9 @@
       <adm:aggregation
         relation-name="account-status-notification-handler"
         parent-path="/">
-        <adm:target-enabled-property-name name="enabled" />
+        <adm:target-is-enabled-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-is-enabled-condition>
       </adm:aggregation>
     </adm:syntax>
     <adm:profile name="ldap">
@@ -319,7 +327,9 @@
     <adm:syntax>
       <adm:aggregation relation-name="password-generator"
         parent-path="/">
-        <adm:target-enabled-property-name name="enabled" />
+        <adm:target-is-enabled-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-is-enabled-condition>
       </adm:aggregation>
     </adm:syntax>
     <adm:profile name="ldap">
diff --git a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PasswordPolicyImportPluginConfiguration.xml b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PasswordPolicyImportPluginConfiguration.xml
index ad04db7..77f57d8 100644
--- a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PasswordPolicyImportPluginConfiguration.xml
+++ b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PasswordPolicyImportPluginConfiguration.xml
@@ -86,8 +86,12 @@
     </adm:default-behavior>
     <adm:syntax>
       <adm:aggregation relation-name="password-storage-scheme" parent-path="/">
-        <adm:source-enabled-property-name name="enabled" />
-        <adm:target-enabled-property-name name="enabled" />
+        <adm:target-needs-enabling-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-needs-enabling-condition>
+        <adm:target-is-enabled-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-is-enabled-condition>
       </adm:aggregation>
     </adm:syntax>
     <adm:profile name="ldap">
@@ -118,8 +122,12 @@
     </adm:default-behavior>
     <adm:syntax>
       <adm:aggregation relation-name="password-storage-scheme" parent-path="/">
-        <adm:source-enabled-property-name name="enabled" />
-        <adm:target-enabled-property-name name="enabled" />
+        <adm:target-needs-enabling-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-needs-enabling-condition>
+        <adm:target-is-enabled-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-is-enabled-condition>
       </adm:aggregation>
     </adm:syntax>
     <adm:profile name="ldap">
diff --git a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PlainSASLMechanismHandlerConfiguration.xml b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PlainSASLMechanismHandlerConfiguration.xml
index 9389cc5..e7d26ca 100644
--- a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PlainSASLMechanismHandlerConfiguration.xml
+++ b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/PlainSASLMechanismHandlerConfiguration.xml
@@ -59,8 +59,12 @@
     <adm:syntax>
       <adm:aggregation relation-name="identity-mapper"
         parent-path="/">
-        <adm:source-enabled-property-name name="enabled" />
-        <adm:target-enabled-property-name name="enabled" />
+        <adm:target-needs-enabling-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-needs-enabling-condition>
+        <adm:target-is-enabled-condition>
+          <adm:contains property="enabled" value="true" />
+        </adm:target-is-enabled-condition>
       </adm:aggregation>
     </adm:syntax>
     <adm:profile name="ldap">
diff --git a/opendj-sdk/opends/src/messages/messages/admin.properties b/opendj-sdk/opends/src/messages/messages/admin.properties
index 427c3de..de7a129 100644
--- a/opendj-sdk/opends/src/messages/messages/admin.properties
+++ b/opendj-sdk/opends/src/messages/messages/admin.properties
@@ -308,4 +308,5 @@
  disabled because it is referenced by the "%s" property in the %s called "%s"
 SEVERE_ERR_CLIENT_REFINT_CANNOT_DISABLE_WITHOUT_NAME_133=This %s cannot be \
  disabled because it is referenced by the "%s" property in the %s
-
+SEVERE_ERR_REFINT_UNABLE_TO_EVALUATE_TARGET_CONDITION_134=An error occurred \
+ while attempting to determine if the %s in entry %s is enabled: %s
diff --git a/opendj-sdk/opends/src/messages/messages/dsconfig.properties b/opendj-sdk/opends/src/messages/messages/dsconfig.properties
index 5dce163..5dfdac8 100644
--- a/opendj-sdk/opends/src/messages/messages/dsconfig.properties
+++ b/opendj-sdk/opends/src/messages/messages/dsconfig.properties
@@ -440,3 +440,6 @@
 SEVERE_ERR_GET_HEADING_MODE_SINGLE_143=The %s could not be decoded due to the following reason:
 SEVERE_ERR_GET_HEADING_MODE_PLURAL_144=The %s could not be decoded due to the following reasons:
 INFO_EDITOR_OPTION_CREATE_A_NEW_COMPONENT_145=Create a new %s
+INFO_DSCFG_PROMPT_EDIT_TO_ENABLE_146=The referenced %s \
+ called "%s" must be enabled so that it can be used with this %s. Do \
+ you want to edit its properties in order to enable it?
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/AggregationPropertyDefinition.java b/opendj-sdk/opends/src/server/org/opends/server/admin/AggregationPropertyDefinition.java
index c1e7b96..b0a23b8 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/AggregationPropertyDefinition.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/AggregationPropertyDefinition.java
@@ -29,6 +29,7 @@
 
 
 import static org.opends.messages.AdminMessages.*;
+import static org.opends.server.loggers.debug.DebugLogger.*;
 import static org.opends.server.util.Validator.*;
 
 import java.util.Collection;
@@ -47,15 +48,21 @@
 import org.opends.server.admin.client.ManagedObject;
 import org.opends.server.admin.client.ManagedObjectDecodingException;
 import org.opends.server.admin.client.ManagementContext;
+import org.opends.server.admin.condition.Condition;
+import org.opends.server.admin.condition.Conditions;
 import org.opends.server.admin.server.ConfigurationChangeListener;
 import org.opends.server.admin.server.ConfigurationDeleteListener;
 import org.opends.server.admin.server.ServerConstraintHandler;
 import org.opends.server.admin.server.ServerManagedObject;
 import org.opends.server.admin.server.ServerManagementContext;
 import org.opends.server.config.ConfigException;
+import org.opends.server.loggers.ErrorLogger;
+import org.opends.server.loggers.debug.DebugTracer;
 import org.opends.server.types.ConfigChangeResult;
 import org.opends.server.types.DN;
+import org.opends.server.types.DebugLogLevel;
 import org.opends.server.types.ResultCode;
+import org.opends.server.util.StaticUtils;
 
 
 
@@ -126,16 +133,13 @@
     // contains the aggregated managed objects.
     private String rdName = null;
 
-    // The optional names of boolean "enabled" properties in this
-    // managed object. When all of the properties are true, the
-    // enabled property in the aggregated managed object must also be
-    // true.
-    private List<String> sourceEnabledPropertyNames = new LinkedList<String>();
+    // The condition which is used to determine if a referenced
+    // managed object is enabled.
+    private Condition targetIsEnabledCondition = Conditions.TRUE;
 
-    // The optional name of a boolean "enabled" property in the
-    // aggregated managed object. This property must not be false
-    // while the aggregated managed object is referenced.
-    private String targetEnabledPropertyName = null;
+    // The condition which is used to determine whether or not
+    // referenced managed objects need to be enabled.
+    private Condition targetNeedsEnablingCondition = Conditions.TRUE;
 
 
 
@@ -148,27 +152,6 @@
 
 
     /**
-     * Registers a boolean "enabled" property in this managed object.
-     * When all the registered properties are true, the enabled
-     * property in the aggregated managed object must also be true.
-     * <p>
-     * By default no source properties are defined which indicates
-     * that the target property must always be true. When there is one
-     * or more source properties defined, a target property must also
-     * be defined.
-     *
-     * @param sourceEnabledPropertyName
-     *          The optional boolean "enabled" property in this
-     *          managed object.
-     */
-    public final void addSourceEnabledPropertyName(
-        String sourceEnabledPropertyName) {
-      this.sourceEnabledPropertyNames.add(sourceEnabledPropertyName);
-    }
-
-
-
-    /**
      * Sets the name of the managed object which is the parent of the
      * aggregated managed objects.
      * <p>
@@ -204,20 +187,31 @@
 
 
     /**
-     * Sets the optional boolean "enabled" property in the aggregated
-     * managed object. This property must not be false while the
-     * aggregated managed object is referenced.
-     * <p>
-     * By default no target property is defined. It must be defined,
-     * if the source property is defined.
+     * Sets the condition which is used to determine if a referenced
+     * managed object is enabled. By default referenced managed
+     * objects are assumed to always be enabled.
      *
-     * @param targetEnabledPropertyName
-     *          The optional boolean "enabled" property in the
-     *          aggregated managed object.
+     * @param condition
+     *          The condition which is used to determine if a
+     *          referenced managed object is enabled.
      */
-    public final void setTargetEnabledPropertyName(
-        String targetEnabledPropertyName) {
-      this.targetEnabledPropertyName = targetEnabledPropertyName;
+    public final void setTargetIsEnabledCondition(Condition condition) {
+      this.targetIsEnabledCondition = condition;
+    }
+
+
+
+    /**
+     * Sets the condition which is used to determine whether or not
+     * referenced managed objects need to be enabled. By default
+     * referenced managed objects must always be enabled.
+     *
+     * @param condition
+     *          The condition which is used to determine whether or
+     *          not referenced managed objects need to be enabled.
+     */
+    public final void setTargetNeedsEnablingCondition(Condition condition) {
+      this.targetNeedsEnablingCondition = condition;
     }
 
 
@@ -240,18 +234,9 @@
         throw new IllegalStateException("Relation definition undefined");
       }
 
-      // Make sure that if a source property is specified then a
-      // target property is also specified.
-      if (!sourceEnabledPropertyNames.isEmpty()
-          && targetEnabledPropertyName == null) {
-        throw new IllegalStateException(
-            "One or more source properties defined but "
-                + "target property is undefined");
-      }
-
       return new AggregationPropertyDefinition<C, S>(d, propertyName, options,
           adminAction, defaultBehavior, parentPathString, rdName,
-          sourceEnabledPropertyNames, targetEnabledPropertyName);
+          targetNeedsEnablingCondition, targetIsEnabledCondition);
     }
 
   }
@@ -287,18 +272,20 @@
      * {@inheritDoc}
      */
     public ConfigChangeResult applyConfigurationChange(S configuration) {
-      PropertyProvider provider = configuration.properties();
-      Collection<Boolean> values = provider
-          .getPropertyValues(getTargetEnabledPropertyDefinition());
-      if (values.iterator().next() == false) {
-        // This should not happen - the
-        // isConfigurationChangeAcceptable() call-back should have
-        // trapped this.
-        throw new IllegalStateException("Attempting to disable a referenced "
-            + configuration.definition().getUserFriendlyName());
-      } else {
-        return new ConfigChangeResult(ResultCode.SUCCESS, false);
+      ServerManagedObject<?> mo = configuration.managedObject();
+      try {
+        if (targetIsEnabledCondition.evaluate(mo)) {
+          return new ConfigChangeResult(ResultCode.SUCCESS, false);
+        }
+      } catch (ConfigException e) {
+        // This should not happen - ignore it and throw an exception
+        // anyway below.
       }
+
+      // This should not happen - the previous call-back should have
+      // trapped this.
+      throw new IllegalStateException("Attempting to disable a referenced "
+          + configuration.definition().getUserFriendlyName());
     }
 
 
@@ -310,14 +297,27 @@
         List<Message> unacceptableReasons) {
       // Always prevent the referenced component from being
       // disabled.
-      PropertyProvider provider = configuration.properties();
-      Collection<Boolean> values = provider
-          .getPropertyValues(getTargetEnabledPropertyDefinition());
-      if (values.iterator().next() == false) {
+      ServerManagedObject<?> mo = configuration.managedObject();
+      try {
+        if (!targetIsEnabledCondition.evaluate(mo)) {
+          unacceptableReasons.add(message);
+          return false;
+        } else {
+          return true;
+        }
+      } catch (ConfigException e) {
+        // The condition could not be evaluated.
+        if (debugEnabled()) {
+          TRACER.debugCaught(DebugLogLevel.ERROR, e);
+        }
+
+        Message message = ERR_REFINT_UNABLE_TO_EVALUATE_TARGET_CONDITION.get(mo
+            .getManagedObjectDefinition().getUserFriendlyName(), String
+            .valueOf(configuration.dn()), StaticUtils.getExceptionMessage(e));
+        ErrorLogger.logError(message);
         unacceptableReasons.add(message);
         return false;
       }
-      return true;
     }
 
 
@@ -407,15 +407,14 @@
       SortedSet<String> names = managedObject
           .getPropertyValues(AggregationPropertyDefinition.this);
       ServerManagementContext context = ServerManagementContext.getInstance();
-      BooleanPropertyDefinition tpd = getTargetEnabledPropertyDefinition();
-      List<BooleanPropertyDefinition> spdlist =
-        getSourceEnabledPropertyDefinitions();
       Message thisUFN = managedObject.getManagedObjectDefinition()
           .getUserFriendlyName();
       String thisDN = managedObject.getDN().toString();
       Message thatUFN = getRelationDefinition().getUserFriendlyName();
 
       boolean isUsable = true;
+      boolean needsEnabling = targetNeedsEnablingCondition
+          .evaluate(managedObject);
       for (String name : names) {
         ManagedObjectPath<C, S> path = getChildPath(name);
         String thatDN = path.toDN().toString();
@@ -425,35 +424,15 @@
               getName(), thisUFN, thisDN, thatUFN, thatDN);
           unacceptableReasons.add(msg);
           isUsable = false;
-        } else if (tpd != null) {
-          // Check that the referenced component is enabled.
+        } else if (needsEnabling) {
+          // Check that the referenced component is enabled if
+          // required.
           ServerManagedObject<? extends S> ref = context.getManagedObject(path);
-
-          if (!spdlist.isEmpty()) {
-            // Target must be enabled but only if the source
-            // properties are enabled.
-            boolean isRequired = true;
-            for (BooleanPropertyDefinition spd : spdlist) {
-              if (!managedObject.getPropertyValue(spd)) {
-                isRequired = false;
-                break;
-              }
-            }
-
-            if (isRequired && !ref.getPropertyValue(tpd)) {
-              Message msg = ERR_SERVER_REFINT_SOURCE_ENABLED_TARGET_DISABLED
-                  .get(name, getName(), thisUFN, thisDN, thatUFN, thatDN);
-              unacceptableReasons.add(msg);
-              isUsable = false;
-            }
-          } else {
-            // Target must always be enabled.
-            if (!ref.getPropertyValue(tpd)) {
-              Message msg = ERR_SERVER_REFINT_TARGET_DISABLED.get(name,
-                  getName(), thisUFN, thisDN, thatUFN, thatDN);
-              unacceptableReasons.add(msg);
-              isUsable = false;
-            }
+          if (!targetIsEnabledCondition.evaluate(ref)) {
+            Message msg = ERR_SERVER_REFINT_TARGET_DISABLED.get(name,
+                getName(), thisUFN, thisDN, thatUFN, thatDN);
+            unacceptableReasons.add(msg);
+            isUsable = false;
           }
         }
       }
@@ -478,9 +457,6 @@
 
       // Add change and delete listeners against all referenced
       // components.
-      BooleanPropertyDefinition tpd = getTargetEnabledPropertyDefinition();
-      List<BooleanPropertyDefinition> spdlist =
-        getSourceEnabledPropertyDefinitions();
       Message thisUFN = managedObject.getManagedObjectDefinition()
           .getUserFriendlyName();
       String thisDN = managedObject.getDN().toString();
@@ -488,18 +464,8 @@
 
       // Referenced managed objects will only need a change listener
       // if they have can be disabled.
-      boolean needsChangeListeners;
-      if (tpd != null) {
-        needsChangeListeners = true;
-        for (BooleanPropertyDefinition spd : spdlist) {
-          if (!managedObject.getPropertyValue(spd)) {
-            needsChangeListeners = false;
-            break;
-          }
-        }
-      } else {
-        needsChangeListeners = false;
-      }
+      boolean needsChangeListeners = targetNeedsEnablingCondition
+          .evaluate(managedObject);
 
       // Delete listeners need to be registered against the parent
       // entry of the referenced components.
@@ -611,18 +577,12 @@
         throws AuthorizationException, CommunicationException {
       // If all of this managed object's "enabled" properties are true
       // then any referenced managed objects must also be enabled.
-      boolean needsEnabling = true;
-      for (BooleanPropertyDefinition spd :
-        getSourceEnabledPropertyDefinitions()) {
-        if (!managedObject.getPropertyValue(spd)) {
-          needsEnabling = false;
-        }
-      }
+      boolean needsEnabling = targetNeedsEnablingCondition.evaluate(context,
+          managedObject);
 
       // Check the referenced managed objects exist and, if required,
       // are enabled.
       boolean isAcceptable = true;
-      BooleanPropertyDefinition tpd = getTargetEnabledPropertyDefinition();
       Message ufn = getRelationDefinition().getUserFriendlyName();
       for (String name : managedObject
           .getPropertyValues(AggregationPropertyDefinition.this)) {
@@ -653,8 +613,8 @@
         }
 
         // Make sure the reference managed object is enabled.
-        if (tpd != null && needsEnabling) {
-          if (!ref.getPropertyValue(tpd)) {
+        if (needsEnabling) {
+          if (!targetIsEnabledCondition.evaluate(context, ref)) {
             Message msg = ERR_CLIENT_REFINT_TARGET_DISABLED.get(ufn, name,
                 getName());
             unacceptableReasons.add(msg);
@@ -849,15 +809,7 @@
         throws AuthorizationException, CommunicationException {
       // If the modified managed object is disabled and there are some
       // active references then refuse the change.
-      BooleanPropertyDefinition tpd = getTargetEnabledPropertyDefinition();
-
-      // The referenced managed object cannot be disabled: always ok.
-      if (tpd == null) {
-        return true;
-      }
-
-      // The referenced managed object is enabled: always ok.
-      if (managedObject.getPropertyValue(tpd)) {
+      if (targetIsEnabledCondition.evaluate(context, managedObject)) {
         return true;
       }
 
@@ -866,16 +818,7 @@
       boolean isAcceptable = true;
       for (ManagedObject<?> mo : findReferences(context, managedObject
           .getManagedObjectPath().getName())) {
-        boolean needsEnabling = true;
-        for (BooleanPropertyDefinition spd :
-          getSourceEnabledPropertyDefinitions()) {
-          if (!mo.getPropertyValue(spd)) {
-            needsEnabling = false;
-            break;
-          }
-        }
-
-        if (needsEnabling) {
+        if (targetNeedsEnablingCondition.evaluate(context, mo)) {
           String name = mo.getManagedObjectPath().getName();
           if (name == null) {
             Message msg = ERR_CLIENT_REFINT_CANNOT_DISABLE_WITHOUT_NAME.get(
@@ -910,6 +853,11 @@
     }
   }
 
+  /**
+   * The tracer object for the debug logger.
+   */
+  private static final DebugTracer TRACER = getTracer();
+
 
 
   /**
@@ -937,14 +885,14 @@
   // The active server-side referential integrity change listeners
   // associated with this property.
   private final Map<DN, List<ReferentialIntegrityChangeListener>>
-    changeListeners =
-      new HashMap<DN, List<ReferentialIntegrityChangeListener>>();
+    changeListeners = new HashMap<DN,
+      List<ReferentialIntegrityChangeListener>>();
 
   // The active server-side referential integrity delete listeners
   // associated with this property.
   private final Map<DN, List<ReferentialIntegrityDeleteListener>>
-    deleteListeners =
-      new HashMap<DN, List<ReferentialIntegrityDeleteListener>>();
+    deleteListeners = new HashMap<DN,
+      List<ReferentialIntegrityDeleteListener>>();
 
   // The name of the managed object which is the parent of the
   // aggregated managed objects.
@@ -962,22 +910,13 @@
   // aggregated managed objects.
   private InstantiableRelationDefinition<C, S> relationDefinition;
 
-  // The decoded source property definitions.
-  private List<BooleanPropertyDefinition> sourceEnabledProperties;
+  // The condition which is used to determine if a referenced managed
+  // object is enabled.
+  private final Condition targetIsEnabledCondition;
 
-  // The optional names of boolean "enabled" properties in this
-  // managed object. When all of the properties are true or if there
-  // are none defined, the enabled property in the aggregated managed
-  // object must also be true.
-  private final List<String> sourceEnabledPropertyNames;
-
-  // The decoded target property definition.
-  private BooleanPropertyDefinition targetEnabledProperty;
-
-  // The optional name of a boolean "enabled" property in the
-  // aggregated managed object. This property must not be false
-  // while the aggregated managed object is referenced.
-  private final String targetEnabledPropertyName;
+  // The condition which is used to determine whether or not
+  // referenced managed objects need to be enabled.
+  private final Condition targetNeedsEnablingCondition;
 
 
 
@@ -986,14 +925,14 @@
       AbstractManagedObjectDefinition<?, ?> d, String propertyName,
       EnumSet<PropertyOption> options, AdministratorAction adminAction,
       DefaultBehaviorProvider<String> defaultBehavior, String parentPathString,
-      String rdName, List<String> sourceEnabledPropertyNames,
-      String targetEnabledPropertyName) {
+      String rdName, Condition targetNeedsEnablingCondition,
+      Condition targetIsEnabledCondition) {
     super(d, String.class, propertyName, options, adminAction, defaultBehavior);
 
     this.parentPathString = parentPathString;
     this.rdName = rdName;
-    this.sourceEnabledPropertyNames = sourceEnabledPropertyNames;
-    this.targetEnabledPropertyName = targetEnabledPropertyName;
+    this.targetNeedsEnablingCondition = targetNeedsEnablingCondition;
+    this.targetIsEnabledCondition = targetIsEnabledCondition;
   }
 
 
@@ -1115,32 +1054,27 @@
 
 
   /**
-   * Gets the optional boolean "enabled" properties in this managed
-   * object. When these properties are all true or if there are no
-   * properties, the enabled property in the aggregated managed object
-   * must also be true.
+   * Gets the condition which is used to determine if a referenced
+   * managed object is enabled.
    *
-   * @return Returns the optional boolean "enabled" properties in this
-   *         managed object, which may be empty.
+   * @return Returns the condition which is used to determine if a
+   *         referenced managed object is enabled.
    */
-  public final List<BooleanPropertyDefinition>
-      getSourceEnabledPropertyDefinitions() {
-    return sourceEnabledProperties;
+  public final Condition getTargetIsEnabledCondition() {
+    return targetIsEnabledCondition;
   }
 
 
 
   /**
-   * Gets the optional boolean "enabled" property in the aggregated
-   * managed object. This property must not be false while the
-   * aggregated managed object is referenced.
+   * Gets the condition which is used to determine whether or not
+   * referenced managed objects need to be enabled.
    *
-   * @return Returns the optional boolean "enabled" property in the
-   *         aggregated managed object, or <code>null</code> if none
-   *         is defined.
+   * @return Returns the condition which is used to determine whether
+   *         or not referenced managed objects need to be enabled.
    */
-  public final BooleanPropertyDefinition getTargetEnabledPropertyDefinition() {
-    return targetEnabledProperty;
+  public final Condition getTargetNeedsEnablingCondition() {
+    return targetNeedsEnablingCondition;
   }
 
 
@@ -1175,22 +1109,11 @@
     builder.append(" relationDefinition=");
     builder.append(relationDefinition.getName());
 
-    builder.append(" sourceEnabledPropertyName=[");
-    boolean isFirst = true;
-    for (String name : sourceEnabledPropertyNames) {
-      if (!isFirst) {
-        builder.append(", ");
-      } else {
-        isFirst = false;
-      }
-      builder.append(name);
-    }
-    builder.append(']');
+    builder.append(" targetNeedsEnablingCondition=");
+    builder.append(String.valueOf(targetNeedsEnablingCondition));
 
-    if (targetEnabledPropertyName != null) {
-      builder.append(" targetEnabledPropertyName=");
-      builder.append(targetEnabledPropertyName);
-    }
+    builder.append(" targetIsEnabledCondition=");
+    builder.append(String.valueOf(targetIsEnabledCondition));
   }
 
 
@@ -1224,28 +1147,9 @@
     RelationDefinition<?, ?> rd = parent.getRelationDefinition(rdName);
     relationDefinition = (InstantiableRelationDefinition<C, S>) rd;
 
-    // Now decode the property definitions.
-    AbstractManagedObjectDefinition<?, ?> d = getManagedObjectDefinition();
-    sourceEnabledProperties = new LinkedList<BooleanPropertyDefinition>();
-    for (String name : sourceEnabledPropertyNames) {
-      PropertyDefinition<?> pd = d.getPropertyDefinition(name);
-
-      // Runtime cast is required to workaround a
-      // bug in JDK versions prior to 1.5.0_08.
-      sourceEnabledProperties.add(BooleanPropertyDefinition.class.cast(pd));
-    }
-
-    d = relationDefinition.getChildDefinition();
-    if (targetEnabledPropertyName == null) {
-      targetEnabledProperty = null;
-    } else {
-      PropertyDefinition<?> pd = d
-          .getPropertyDefinition(targetEnabledPropertyName);
-
-      // Runtime cast is required to workaround a
-      // bug in JDK versions prior to 1.5.0_08.
-      targetEnabledProperty = BooleanPropertyDefinition.class.cast(pd);
-    }
+    // Now decode the conditions.
+    targetNeedsEnablingCondition.initialize(getManagedObjectDefinition());
+    targetIsEnabledCondition.initialize(rd.getChildDefinition());
 
     // Register a client-side constraint with the referenced
     // definition. This will be used to enforce referential integrity
@@ -1271,7 +1175,7 @@
 
     };
 
-    d.registerConstraint(constraint);
+    rd.getChildDefinition().registerConstraint(constraint);
   }
 
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/Configuration.java b/opendj-sdk/opends/src/server/org/opends/server/admin/Configuration.java
index 564618d..6046c5d 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/Configuration.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/Configuration.java
@@ -29,6 +29,7 @@
 
 
 
+import org.opends.server.admin.server.ServerManagedObject;
 import org.opends.server.types.DN;
 
 
@@ -40,7 +41,7 @@
 public interface Configuration {
 
   /**
-   * Get the DN of the LDAP entry associated with this configuration.
+   * Gets the DN of the LDAP entry associated with this configuration.
    *
    * @return Returns the DN of the LDAP entry associated with this
    *         configuration.
@@ -50,7 +51,7 @@
 
 
   /**
-   * Get the configuration definition associated with this
+   * Gets the configuration definition associated with this
    * configuration.
    *
    * @return Returns the configuration definition associated with this
@@ -62,9 +63,11 @@
 
 
   /**
-   * Get a property provider view of this configuration.
+   * Gets the underlying server-side managed object associated with
+   * this configuration.
    *
-   * @return Returns a property provider view of this configuration.
+   * @return Returns the underlying server-side managed object
+   *         associated with this configuration.
    */
-  PropertyProvider properties();
+  ServerManagedObject<? extends Configuration> managedObject();
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/condition/ANDCondition.java b/opendj-sdk/opends/src/server/org/opends/server/admin/condition/ANDCondition.java
new file mode 100644
index 0000000..55e1778
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/condition/ANDCondition.java
@@ -0,0 +1,112 @@
+/*
+ * 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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.condition;
+
+
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.opends.server.admin.AbstractManagedObjectDefinition;
+import org.opends.server.admin.client.AuthorizationException;
+import org.opends.server.admin.client.CommunicationException;
+import org.opends.server.admin.client.ManagedObject;
+import org.opends.server.admin.client.ManagementContext;
+import org.opends.server.admin.server.ServerManagedObject;
+import org.opends.server.config.ConfigException;
+import org.opends.server.util.Validator;
+
+
+
+/**
+ * A condition which evaluates to <code>true</code> if and only if
+ * all of its sub-conditions are <code>true</code>.
+ */
+public final class ANDCondition implements Condition {
+
+  // The list of sub-conditions.
+  private final List<Condition> conditions;
+
+
+
+  /**
+   * Creates a new logical AND condition with the provided
+   * sub-conditions.
+   *
+   * @param conditions
+   *          The sub-conditions which will be combined using a
+   *          logical AND.
+   */
+  public ANDCondition(Condition... conditions) {
+    Validator.ensureNotNull(conditions);
+    this.conditions = Arrays.asList(conditions);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean evaluate(ManagementContext context,
+      ManagedObject<?> managedObject) throws AuthorizationException,
+      CommunicationException {
+    for (Condition condition : conditions) {
+      if (!condition.evaluate(context, managedObject)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean evaluate(ServerManagedObject<?> managedObject)
+      throws ConfigException {
+    for (Condition condition : conditions) {
+      if (!condition.evaluate(managedObject)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public void initialize(AbstractManagedObjectDefinition<?, ?> d)
+      throws Exception {
+    for (Condition condition : conditions) {
+      condition.initialize(d);
+    }
+  }
+
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/condition/Condition.java b/opendj-sdk/opends/src/server/org/opends/server/admin/condition/Condition.java
new file mode 100644
index 0000000..b4df06d
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/condition/Condition.java
@@ -0,0 +1,94 @@
+/*
+ * 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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.condition;
+
+
+
+import org.opends.server.admin.AbstractManagedObjectDefinition;
+import org.opends.server.admin.client.AuthorizationException;
+import org.opends.server.admin.client.CommunicationException;
+import org.opends.server.admin.client.ManagedObject;
+import org.opends.server.admin.client.ManagementContext;
+import org.opends.server.admin.server.ServerManagedObject;
+import org.opends.server.config.ConfigException;
+
+
+
+/**
+ * An interface for evaluating conditions.
+ */
+public interface Condition {
+
+  /**
+   * Initializes this condition.
+   *
+   * @param d
+   *          The abstract managed object definition associated with
+   *          this condition.
+   * @throws Exception
+   *           If this condition could not be initialized.
+   */
+  void initialize(AbstractManagedObjectDefinition<?, ?> d) throws Exception;
+
+
+
+  /**
+   * Evaluates this condition against the provided client managed
+   * object.
+   *
+   * @param context
+   *          The client management context.
+   * @param managedObject
+   *          The client managed object.
+   * @return Returns <code>true</code> if this condition is
+   *         satisfied.
+   * @throws AuthorizationException
+   *           If the condition could not be evaluated due to an
+   *           authorization problem.
+   * @throws CommunicationException
+   *           If the condition could not be evaluated due to an
+   *           communication problem.
+   */
+  boolean evaluate(ManagementContext context, ManagedObject<?> managedObject)
+      throws AuthorizationException, CommunicationException;
+
+
+
+  /**
+   * Evaluates this condition against the provided server managed
+   * object.
+   *
+   * @param managedObject
+   *          The server managed object.
+   * @return Returns <code>true</code> if this condition is
+   *         satisfied.
+   * @throws ConfigException
+   *           If the condition could not be evaluated due to an
+   *           unexpected configuration exception.
+   */
+  boolean evaluate(ServerManagedObject<?> managedObject) throws ConfigException;
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/condition/Conditions.java b/opendj-sdk/opends/src/server/org/opends/server/admin/condition/Conditions.java
new file mode 100644
index 0000000..c62df51
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/condition/Conditions.java
@@ -0,0 +1,237 @@
+/*
+ * 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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.condition;
+
+
+
+import org.opends.server.admin.AbstractManagedObjectDefinition;
+import org.opends.server.admin.client.AuthorizationException;
+import org.opends.server.admin.client.CommunicationException;
+import org.opends.server.admin.client.ManagedObject;
+import org.opends.server.admin.client.ManagementContext;
+import org.opends.server.admin.server.ServerManagedObject;
+import org.opends.server.config.ConfigException;
+
+
+
+/**
+ * This class consists exclusively of static methods that operate on
+ * or return conditions.
+ */
+public final class Conditions {
+
+  /**
+   * A condition which always evaluates to <code>false</code>.
+   */
+  public static final Condition FALSE = new Condition() {
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean evaluate(ManagementContext context,
+        ManagedObject<?> managedObject) throws AuthorizationException,
+        CommunicationException {
+      return false;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean evaluate(ServerManagedObject<?> managedObject)
+        throws ConfigException {
+      return false;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void initialize(AbstractManagedObjectDefinition<?, ?> d)
+        throws Exception {
+      // No implementation required.
+    }
+
+  };
+
+  /**
+   * A condition which always evaluates to <code>true</code>.
+   */
+  public static final Condition TRUE = new Condition() {
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean evaluate(ManagementContext context,
+        ManagedObject<?> managedObject) throws AuthorizationException,
+        CommunicationException {
+      return true;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean evaluate(ServerManagedObject<?> managedObject)
+        throws ConfigException {
+      return true;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void initialize(AbstractManagedObjectDefinition<?, ?> d)
+        throws Exception {
+      // No implementation required.
+    }
+
+  };
+
+
+
+  /**
+   * Creates a condition which evaluates to <code>true</code> if and
+   * only if all of its sub-conditions are <code>true</code>.
+   *
+   * @param conditions
+   *          The sub-conditions which be combined using a logical
+   *          AND.
+   * @return Returns a condition which evaluates to <code>true</code>
+   *         if and only if all of its sub-conditions are
+   *         <code>true</code>.
+   */
+  public static Condition and(Condition... conditions) {
+    return new ANDCondition(conditions);
+  }
+
+
+
+  /**
+   * Creates a condition which evaluates to <code>true</code> if and
+   * only if a property contains a particular value.
+   *
+   * @param propertyName
+   *          The property name.
+   * @param propertyStringValue
+   *          The string representation of the required property
+   *          value.
+   * @return Returns a condition which evaluates to <code>true</code>
+   *         if and only if a property contains a particular value.
+   */
+  public static Condition contains(String propertyName,
+      String propertyStringValue) {
+    return new ContainsValueCondition(propertyName, propertyStringValue);
+  }
+
+
+
+  /**
+   * Creates a condition which evaluates to <code>false</code> if
+   * and only if the first sub-condition evaluates to
+   * <code>true</code> and the second sub-condition evaluates to
+   * <code>false</code>. This can be used to represent if-then
+   * relationships.
+   *
+   * @param premise
+   *          The sub-condition which, when <code>true</code>
+   *          implies that the implication sub-condition must also be
+   *          <code>true</code>.
+   * @param implication
+   *          The sub-condition which, must be <code>true</code>
+   *          when the premise is <code>true</code>.
+   * @return Returns a condition which evaluates to <code>false</code>
+   *         if and only if the first sub-condition evaluates to
+   *         <code>true</code> and the second sub-condition
+   *         evaluates to <code>false</code>.
+   */
+  public static Condition implies(Condition premise, Condition implication) {
+    return or(not(premise), implication);
+  }
+
+
+
+  /**
+   * Creates a condition which evaluates to <code>true</code> if and
+   * only if a particular property has any values specified.
+   *
+   * @param propertyName
+   *          The property name.
+   * @return Returns a condition which evaluates to <code>true</code>
+   *         if and only if a particular property has any values
+   *         specified.
+   */
+  public static Condition isPresent(String propertyName) {
+    return new IsPresentCondition(propertyName);
+  }
+
+
+
+  /**
+   * Creates a condition which evaluates to <code>true</code> if the
+   * sub-condition is <code>false</code>, or <code>false</code>
+   * if the sub-condition is <code>true</code>.
+   *
+   * @param condition
+   *          The sub-condition which will be inverted.
+   * @return Returns a condition which evaluates to <code>true</code>
+   *         if the sub-condition is <code>false</code>, or
+   *         <code>false</code> if the sub-condition is
+   *         <code>true</code>.
+   */
+  public static Condition not(Condition condition) {
+    return new NOTCondition(condition);
+  }
+
+
+
+  /**
+   * Creates a condition which evaluates to <code>false</code> if
+   * and only if all of its sub-conditions are <code>false</code>.
+   *
+   * @param conditions
+   *          The sub-conditions which be combined using a logical OR.
+   * @return Returns a condition which evaluates to <code>false</code>
+   *         if and only if all of its sub-conditions are
+   *         <code>false</code>.
+   */
+  public static Condition or(Condition... conditions) {
+    return new ORCondition(conditions);
+  }
+
+
+
+  // Prevent instantiation.
+  private Conditions() {
+    // No implementation required.
+  }
+
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/condition/ContainsValueCondition.java b/opendj-sdk/opends/src/server/org/opends/server/admin/condition/ContainsValueCondition.java
new file mode 100644
index 0000000..1103c77
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/condition/ContainsValueCondition.java
@@ -0,0 +1,197 @@
+/*
+ * 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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.condition;
+
+
+
+import java.util.SortedSet;
+
+import org.opends.server.admin.AbstractManagedObjectDefinition;
+import org.opends.server.admin.IllegalPropertyValueStringException;
+import org.opends.server.admin.PropertyDefinition;
+import org.opends.server.admin.client.AuthorizationException;
+import org.opends.server.admin.client.CommunicationException;
+import org.opends.server.admin.client.ManagedObject;
+import org.opends.server.admin.client.ManagementContext;
+import org.opends.server.admin.server.ServerManagedObject;
+import org.opends.server.config.ConfigException;
+import org.opends.server.util.Validator;
+
+
+
+/**
+ * A condition which evaluates to <code>true</code> if and only if a
+ * property contains a particular value.
+ */
+public final class ContainsValueCondition implements Condition {
+
+  /**
+   * The strongly typed underlying implementation.
+   *
+   * @param <T>
+   *          The type of the property value being tested.
+   */
+  private static final class Impl<T> implements Condition {
+
+    // The property.
+    private final PropertyDefinition<T> pd;
+
+    // The required property value.
+    private final T value;
+
+
+
+    // Private constructor.
+    private Impl(PropertyDefinition<T> pd, T value)
+        throws IllegalPropertyValueStringException {
+      this.pd = pd;
+      this.value = value;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean evaluate(ManagementContext context,
+        ManagedObject<?> managedObject) throws AuthorizationException,
+        CommunicationException {
+      SortedSet<T> values = managedObject.getPropertyValues(pd);
+      return values.contains(value);
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean evaluate(ServerManagedObject<?> managedObject)
+        throws ConfigException {
+      SortedSet<T> values = managedObject.getPropertyValues(pd);
+      return values.contains(value);
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void initialize(AbstractManagedObjectDefinition<?, ?> d)
+        throws Exception {
+      // Not used.
+    }
+
+
+
+    // Private implementation of fix() method.
+    private void setPropertyValue(ManagedObject<?> managedObject) {
+      managedObject.setPropertyValue(pd, value);
+    }
+
+  }
+
+  // The strongly typed private implementation.
+  private Impl<?> impl = null;
+
+  // The property name.
+  private final String propertyName;
+
+  // The string representation of the required property value.
+  private final String propertyStringValue;
+
+
+
+  /**
+   * Creates a new contains value condition.
+   *
+   * @param propertyName
+   *          The property name.
+   * @param stringValue
+   *          The string representation of the required property
+   *          value.
+   */
+  public ContainsValueCondition(String propertyName, String stringValue) {
+    Validator.ensureNotNull(propertyName, stringValue);
+    this.propertyName = propertyName;
+    this.propertyStringValue = stringValue;
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean evaluate(ManagementContext context,
+      ManagedObject<?> managedObject) throws AuthorizationException,
+      CommunicationException {
+    return impl.evaluate(context, managedObject);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean evaluate(ServerManagedObject<?> managedObject)
+      throws ConfigException {
+    return impl.evaluate(managedObject);
+  }
+
+
+
+  /**
+   * Modifies the provided managed object so that it has the property
+   * value associated with this condition.
+   *
+   * @param managedObject
+   *          The managed object.
+   */
+  public void setPropertyValue(ManagedObject<?> managedObject) {
+    impl.setPropertyValue(managedObject);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public void initialize(AbstractManagedObjectDefinition<?, ?> d)
+      throws Exception {
+    // Decode the property.
+    buildImpl(d.getPropertyDefinition(propertyName));
+  }
+
+
+
+  // Creates the new private implementation.
+  private <T> void buildImpl(PropertyDefinition<T> pd)
+      throws IllegalPropertyValueStringException {
+    T value = pd.decodeValue(propertyStringValue);
+    this.impl = new Impl<T>(pd, value);
+  }
+
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/condition/IsPresentCondition.java b/opendj-sdk/opends/src/server/org/opends/server/admin/condition/IsPresentCondition.java
new file mode 100644
index 0000000..90036f8
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/condition/IsPresentCondition.java
@@ -0,0 +1,104 @@
+/*
+ * 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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.condition;
+
+
+
+import java.util.SortedSet;
+
+import org.opends.server.admin.AbstractManagedObjectDefinition;
+import org.opends.server.admin.PropertyDefinition;
+import org.opends.server.admin.client.AuthorizationException;
+import org.opends.server.admin.client.CommunicationException;
+import org.opends.server.admin.client.ManagedObject;
+import org.opends.server.admin.client.ManagementContext;
+import org.opends.server.admin.server.ServerManagedObject;
+import org.opends.server.config.ConfigException;
+import org.opends.server.util.Validator;
+
+
+
+/**
+ * A condition which evaluates to <code>true</code> if and only if a
+ * particular property has any values specified.
+ */
+public final class IsPresentCondition implements Condition {
+
+  // The property name.
+  private final String propertyName;
+
+  // The property definition.
+  private PropertyDefinition<?> pd;
+
+
+
+  /**
+   * Creates a new is present condition.
+   *
+   * @param propertyName
+   *          The property name.
+   */
+  public IsPresentCondition(String propertyName) {
+    Validator.ensureNotNull(propertyName);
+    this.propertyName = propertyName;
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean evaluate(ManagementContext context,
+      ManagedObject<?> managedObject) throws AuthorizationException,
+      CommunicationException {
+    SortedSet<?> values = managedObject.getPropertyValues(pd);
+    return !values.isEmpty();
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean evaluate(ServerManagedObject<?> managedObject)
+      throws ConfigException {
+    SortedSet<?> values = managedObject.getPropertyValues(pd);
+    return !values.isEmpty();
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public void initialize(AbstractManagedObjectDefinition<?, ?> d)
+      throws Exception {
+    // Decode the property.
+    this.pd = d.getPropertyDefinition(propertyName);
+  }
+
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/condition/NOTCondition.java b/opendj-sdk/opends/src/server/org/opends/server/admin/condition/NOTCondition.java
new file mode 100644
index 0000000..883c560
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/condition/NOTCondition.java
@@ -0,0 +1,97 @@
+/*
+ * 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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.condition;
+
+
+
+import org.opends.server.admin.AbstractManagedObjectDefinition;
+import org.opends.server.admin.client.AuthorizationException;
+import org.opends.server.admin.client.CommunicationException;
+import org.opends.server.admin.client.ManagedObject;
+import org.opends.server.admin.client.ManagementContext;
+import org.opends.server.admin.server.ServerManagedObject;
+import org.opends.server.config.ConfigException;
+import org.opends.server.util.Validator;
+
+
+
+/**
+ * A condition which evaluates to <code>true</code> if the
+ * sub-condition is <code>false</code>, or <code>false</code> if
+ * the sub-condition is <code>true</code>.
+ */
+public final class NOTCondition implements Condition {
+
+  // The single sub-condition.
+  private final Condition condition;
+
+
+
+  /**
+   * Creates a new logical NOT condition with the provided
+   * sub-condition.
+   *
+   * @param condition
+   *          The sub-condition which will be inverted.
+   */
+  public NOTCondition(Condition condition) {
+    Validator.ensureNotNull(condition);
+    this.condition = condition;
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean evaluate(ManagementContext context,
+      ManagedObject<?> managedObject) throws AuthorizationException,
+      CommunicationException {
+    return !condition.evaluate(context, managedObject);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean evaluate(ServerManagedObject<?> managedObject)
+      throws ConfigException {
+    return !condition.evaluate(managedObject);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public void initialize(AbstractManagedObjectDefinition<?, ?> d)
+      throws Exception {
+    condition.initialize(d);
+  }
+
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/condition/ORCondition.java b/opendj-sdk/opends/src/server/org/opends/server/admin/condition/ORCondition.java
new file mode 100644
index 0000000..06f7383
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/condition/ORCondition.java
@@ -0,0 +1,112 @@
+/*
+ * 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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.condition;
+
+
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.opends.server.admin.AbstractManagedObjectDefinition;
+import org.opends.server.admin.client.AuthorizationException;
+import org.opends.server.admin.client.CommunicationException;
+import org.opends.server.admin.client.ManagedObject;
+import org.opends.server.admin.client.ManagementContext;
+import org.opends.server.admin.server.ServerManagedObject;
+import org.opends.server.config.ConfigException;
+import org.opends.server.util.Validator;
+
+
+
+/**
+ * A condition which evaluates to <code>false</code> if and only if
+ * all of its sub-conditions are <code>false</code>.
+ */
+public final class ORCondition implements Condition {
+
+  // The list of sub-conditions.
+  private final List<Condition> conditions;
+
+
+
+  /**
+   * Creates a new logical OR condition with the provided
+   * sub-conditions.
+   *
+   * @param conditions
+   *          The sub-conditions which will be combined using a
+   *          logical OR.
+   */
+  public ORCondition(Condition... conditions) {
+    Validator.ensureNotNull(conditions);
+    this.conditions = Arrays.asList(conditions);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean evaluate(ManagementContext context,
+      ManagedObject<?> managedObject) throws AuthorizationException,
+      CommunicationException {
+    for (Condition condition : conditions) {
+      if (condition.evaluate(context, managedObject)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean evaluate(ServerManagedObject<?> managedObject)
+      throws ConfigException {
+    for (Condition condition : conditions) {
+      if (condition.evaluate(managedObject)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public void initialize(AbstractManagedObjectDefinition<?, ?> d)
+      throws Exception {
+    for (Condition condition : conditions) {
+      condition.initialize(d);
+    }
+  }
+
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/condition/package-info.java b/opendj-sdk/opends/src/server/org/opends/server/admin/condition/package-info.java
new file mode 100644
index 0000000..7ae73eb
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/condition/package-info.java
@@ -0,0 +1,36 @@
+/*
+ * 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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+/**
+ * Logical conditions for defining constraints.
+ * <p>
+ * This package contains interfaces for building and evaluating
+ * arbitrary logical conditions which can be used with constraints.
+ */
+@org.opends.server.types.PublicAPI(
+    stability = org.opends.server.types.StabilityLevel.PRIVATE)
+package org.opends.server.admin.condition;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/CreateSubCommandHandler.java b/opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/CreateSubCommandHandler.java
index b303f19..9708b8b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/CreateSubCommandHandler.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/CreateSubCommandHandler.java
@@ -46,7 +46,6 @@
 import org.opends.messages.Message;
 import org.opends.server.admin.AbstractManagedObjectDefinition;
 import org.opends.server.admin.AggregationPropertyDefinition;
-import org.opends.server.admin.BooleanPropertyDefinition;
 import org.opends.server.admin.Configuration;
 import org.opends.server.admin.ConfigurationClient;
 import org.opends.server.admin.DefaultBehaviorException;
@@ -74,6 +73,8 @@
 import org.opends.server.admin.client.ManagementContext;
 import org.opends.server.admin.client.MissingMandatoryPropertiesException;
 import org.opends.server.admin.client.OperationRejectedException;
+import org.opends.server.admin.condition.Condition;
+import org.opends.server.admin.condition.ContainsValueCondition;
 import org.opends.server.protocols.ldap.LDAPResultCode;
 import org.opends.server.tools.ClientException;
 import org.opends.server.util.args.ArgumentException;
@@ -454,148 +455,141 @@
     ManagedObjectDefinition<?, ?> d = mo.getManagedObjectDefinition();
     Message ufn = d.getUserFriendlyName();
 
-    for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
-      if (pd instanceof AggregationPropertyDefinition) {
-        // Runtime cast is required to workaround a
-        // bug in JDK versions prior to 1.5.0_08.
-        AggregationPropertyDefinition<?, ?> apd =
-          AggregationPropertyDefinition.class.cast(pd);
+    try {
+      for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
+        if (pd instanceof AggregationPropertyDefinition) {
+          // Runtime cast is required to workaround a
+          // bug in JDK versions prior to 1.5.0_08.
+          AggregationPropertyDefinition<?, ?> apd =
+            AggregationPropertyDefinition.class.cast(pd);
 
-        // Skip this aggregation if it doesn't have an enable
-        // property.
-        BooleanPropertyDefinition tpd = apd
-            .getTargetEnabledPropertyDefinition();
-        if (tpd == null) {
-          continue;
-        }
-
-        // Skip this aggregation if this managed object's enable
-        // properties are not all true.
-        boolean needsEnabling = true;
-        for (BooleanPropertyDefinition bpd : apd
-            .getSourceEnabledPropertyDefinitions()) {
-          if (!mo.getPropertyValue(bpd)) {
-            needsEnabling = false;
-            break;
-          }
-        }
-        if (!needsEnabling) {
-          continue;
-        }
-
-        // The referenced component(s) must be enabled.
-        for (String name : mo.getPropertyValues(apd)) {
-          ManagedObjectPath<?, ?> path = apd.getChildPath(name);
-          Message rufn = path.getManagedObjectDefinition()
-              .getUserFriendlyName();
-          ManagedObject<?> ref;
-          try {
-            ref = context.getManagedObject(path);
-          } catch (AuthorizationException e) {
-            Message msg = ERR_DSCFG_ERROR_CREATE_AUTHZ.get(ufn);
-            throw new ClientException(
-                LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS, msg);
-          } catch (DefinitionDecodingException e) {
-            Message msg = ERR_DSCFG_ERROR_GET_CHILD_DDE.get(rufn, rufn, rufn);
-            throw new ClientException(LDAPResultCode.OTHER, msg);
-          } catch (ManagedObjectDecodingException e) {
-            // FIXME: should not abort here. Instead, display the
-            // errors (if verbose) and apply the changes to the
-            // partial managed object.
-            Message msg = ERR_DSCFG_ERROR_GET_CHILD_MODE.get(rufn);
-            throw new ClientException(LDAPResultCode.OTHER, msg, e);
-          } catch (CommunicationException e) {
-            Message msg = ERR_DSCFG_ERROR_CREATE_CE.get(ufn, e.getMessage());
-            throw new ClientException(LDAPResultCode.OTHER, msg);
-          } catch (ManagedObjectNotFoundException e) {
-            Message msg = ERR_DSCFG_ERROR_GET_CHILD_MONFE.get(rufn);
-            throw new ClientException(LDAPResultCode.NO_SUCH_OBJECT, msg);
+          // Skip this aggregation if the referenced managed objects
+          // do not need to be enabled.
+          if (!apd.getTargetNeedsEnablingCondition().evaluate(context, mo)) {
+            continue;
           }
 
-          while (!ref.getPropertyValue(tpd)) {
-            boolean isBadReference = true;
-            app.println();
-            if (app.confirmAction(
-                INFO_EDITOR_PROMPT_ENABLED_REFERENCED_COMPONENT.get(rufn, name,
-                    ufn), true)) {
-              ref.setPropertyValue(tpd, true);
-              try {
-                ref.commit();
-                isBadReference = false;
-              } catch (MissingMandatoryPropertiesException e) {
-                // Give the user the chance to fix the problems.
-                app.println();
-                displayMissingMandatoryPropertyException(app, e);
-                app.println();
-                if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT.get(rufn), true)) {
-                  // FIXME: edit the properties of the referenced
-                  // object.
-                  MenuResult<Void> result = SetPropSubCommandHandler
-                      .modifyManagedObject(app, context, ref);
-                  if (result.isQuit()) {
-                    return result;
-                  } else if (result.isSuccess()) {
-                    // The referenced component was modified
-                    // successfully, but may still be disabled.
-                    isBadReference = false;
-                  }
-                }
-              } catch (AuthorizationException e) {
-                Message msg = ERR_DSCFG_ERROR_CREATE_AUTHZ.get(ufn);
-                throw new ClientException(
-                    LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS, msg);
-              } catch (ConcurrentModificationException e) {
-                Message msg = ERR_DSCFG_ERROR_CREATE_CME.get(ufn);
-                throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION,
-                    msg);
-              } catch (OperationRejectedException e) {
-                // Give the user the chance to fix the problems.
-                app.println();
-                displayOperationRejectedException(app, e);
-                app.println();
-                if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT.get(rufn), true)) {
-                  MenuResult<Void> result = SetPropSubCommandHandler
-                      .modifyManagedObject(app, context, ref);
-                  if (result.isQuit()) {
-                    return result;
-                  } else if (result.isSuccess()) {
-                    // The referenced component was modified
-                    // successfully, but may still be disabled.
-                    isBadReference = false;
-                  }
-                }
-              } catch (CommunicationException e) {
-                Message msg = ERR_DSCFG_ERROR_CREATE_CE
-                    .get(ufn, e.getMessage());
-                throw new ClientException(LDAPResultCode.OTHER, msg);
-              } catch (ManagedObjectAlreadyExistsException e) {
-                // Should never happen.
-                throw new IllegalStateException(e);
-              }
+          // The referenced component(s) must be enabled.
+          for (String name : mo.getPropertyValues(apd)) {
+            ManagedObjectPath<?, ?> path = apd.getChildPath(name);
+            Message rufn = path.getManagedObjectDefinition()
+                .getUserFriendlyName();
+            ManagedObject<?> ref;
+            try {
+              ref = context.getManagedObject(path);
+            } catch (DefinitionDecodingException e) {
+              Message msg = ERR_DSCFG_ERROR_GET_CHILD_DDE.get(rufn, rufn, rufn);
+              throw new ClientException(LDAPResultCode.OTHER, msg);
+            } catch (ManagedObjectDecodingException e) {
+              // FIXME: should not abort here. Instead, display the
+              // errors (if verbose) and apply the changes to the
+              // partial managed object.
+              Message msg = ERR_DSCFG_ERROR_GET_CHILD_MODE.get(rufn);
+              throw new ClientException(LDAPResultCode.OTHER, msg, e);
+            } catch (ManagedObjectNotFoundException e) {
+              Message msg = ERR_DSCFG_ERROR_GET_CHILD_MONFE.get(rufn);
+              throw new ClientException(LDAPResultCode.NO_SUCH_OBJECT, msg);
             }
 
-            // If the referenced component is still disabled because
-            // the user refused to modify it, then give the used the
-            // option of editing the referencing component.
-            if (isBadReference) {
-              app.println();
-              app.println(ERR_SET_REFERENCED_COMPONENT_DISABLED.get(ufn, rufn));
-              app.println();
-              if (app
-                  .confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn), true)) {
-                return MenuResult.again();
+            Condition condition = apd.getTargetIsEnabledCondition();
+            while (!condition.evaluate(context, ref)) {
+              boolean isBadReference = true;
+
+              if (condition instanceof ContainsValueCondition) {
+                // Attempt to automatically enable the managed object.
+                ContainsValueCondition cvc = (ContainsValueCondition) condition;
+                app.println();
+                if (app.confirmAction(
+                    INFO_EDITOR_PROMPT_ENABLED_REFERENCED_COMPONENT.get(rufn,
+                        name, ufn), true)) {
+                  cvc.setPropertyValue(ref);
+                  try {
+                    ref.commit();
+                    isBadReference = false;
+                  } catch (MissingMandatoryPropertiesException e) {
+                    // Give the user the chance to fix the problems.
+                    app.println();
+                    displayMissingMandatoryPropertyException(app, e);
+                    app.println();
+                    if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT.get(rufn),
+                        true)) {
+                      MenuResult<Void> result = SetPropSubCommandHandler
+                          .modifyManagedObject(app, context, ref);
+                      if (result.isQuit()) {
+                        return result;
+                      } else if (result.isSuccess()) {
+                        // The referenced component was modified
+                        // successfully, but may still be disabled.
+                        isBadReference = false;
+                      }
+                    }
+                  } catch (ConcurrentModificationException e) {
+                    Message msg = ERR_DSCFG_ERROR_CREATE_CME.get(ufn);
+                    throw new ClientException(
+                        LDAPResultCode.CONSTRAINT_VIOLATION, msg);
+                  } catch (OperationRejectedException e) {
+                    // Give the user the chance to fix the problems.
+                    app.println();
+                    displayOperationRejectedException(app, e);
+                    app.println();
+                    if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT.get(rufn),
+                        true)) {
+                      MenuResult<Void> result = SetPropSubCommandHandler
+                          .modifyManagedObject(app, context, ref);
+                      if (result.isQuit()) {
+                        return result;
+                      } else if (result.isSuccess()) {
+                        // The referenced component was modified
+                        // successfully, but may still be disabled.
+                        isBadReference = false;
+                      }
+                    }
+                  } catch (ManagedObjectAlreadyExistsException e) {
+                    // Should never happen.
+                    throw new IllegalStateException(e);
+                  }
+                }
               } else {
-                return MenuResult.cancel();
+                app.println();
+                if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT_TO_ENABLE.get(
+                    rufn, name, ufn), true)) {
+                  MenuResult<Void> result = SetPropSubCommandHandler
+                      .modifyManagedObject(app, context, ref);
+                  if (result.isQuit()) {
+                    return result;
+                  } else if (result.isSuccess()) {
+                    // The referenced component was modified
+                    // successfully, but may still be disabled.
+                    isBadReference = false;
+                  }
+                }
               }
-            }
 
-            // If the referenced component is now enabled, then drop out.
-            if (ref.getPropertyValue(tpd)) {
-              break;
+              // If the referenced component is still disabled because
+              // the user refused to modify it, then give the used the
+              // option of editing the referencing component.
+              if (isBadReference) {
+                app.println();
+                app.println(ERR_SET_REFERENCED_COMPONENT_DISABLED
+                    .get(ufn, rufn));
+                app.println();
+                if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn),
+                    true)) {
+                  return MenuResult.again();
+                } else {
+                  return MenuResult.cancel();
+                }
+              }
             }
           }
         }
       }
+    } catch (AuthorizationException e) {
+      Message msg = ERR_DSCFG_ERROR_CREATE_AUTHZ.get(ufn);
+      throw new ClientException(LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS, msg);
+    } catch (CommunicationException e) {
+      Message msg = ERR_DSCFG_ERROR_CREATE_CE.get(ufn, e.getMessage());
+      throw new ClientException(LDAPResultCode.OTHER, msg);
     }
 
     return MenuResult.success();
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/SetPropSubCommandHandler.java b/opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/SetPropSubCommandHandler.java
index ea75a75..216a4fb 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/SetPropSubCommandHandler.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/SetPropSubCommandHandler.java
@@ -40,7 +40,6 @@
 
 import org.opends.messages.Message;
 import org.opends.server.admin.AggregationPropertyDefinition;
-import org.opends.server.admin.BooleanPropertyDefinition;
 import org.opends.server.admin.DefinitionDecodingException;
 import org.opends.server.admin.IllegalPropertyValueStringException;
 import org.opends.server.admin.InstantiableRelationDefinition;
@@ -63,6 +62,8 @@
 import org.opends.server.admin.client.ManagementContext;
 import org.opends.server.admin.client.MissingMandatoryPropertiesException;
 import org.opends.server.admin.client.OperationRejectedException;
+import org.opends.server.admin.condition.Condition;
+import org.opends.server.admin.condition.ContainsValueCondition;
 import org.opends.server.protocols.ldap.LDAPResultCode;
 import org.opends.server.tools.ClientException;
 import org.opends.server.util.args.ArgumentException;
@@ -340,148 +341,141 @@
     ManagedObjectDefinition<?, ?> d = mo.getManagedObjectDefinition();
     Message ufn = d.getUserFriendlyName();
 
-    for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
-      if (pd instanceof AggregationPropertyDefinition) {
-        // Runtime cast is required to workaround a
-        // bug in JDK versions prior to 1.5.0_08.
-        AggregationPropertyDefinition<?, ?> apd =
-          AggregationPropertyDefinition.class.cast(pd);
+    try {
+      for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
+        if (pd instanceof AggregationPropertyDefinition) {
+          // Runtime cast is required to workaround a
+          // bug in JDK versions prior to 1.5.0_08.
+          AggregationPropertyDefinition<?, ?> apd =
+            AggregationPropertyDefinition.class.cast(pd);
 
-        // Skip this aggregation if it doesn't have an enable
-        // property.
-        BooleanPropertyDefinition tpd = apd
-            .getTargetEnabledPropertyDefinition();
-        if (tpd == null) {
-          continue;
-        }
-
-        // Skip this aggregation if this managed object's enable
-        // properties are not all true.
-        boolean needsEnabling = true;
-        for (BooleanPropertyDefinition bpd : apd
-            .getSourceEnabledPropertyDefinitions()) {
-          if (!mo.getPropertyValue(bpd)) {
-            needsEnabling = false;
-            break;
-          }
-        }
-        if (!needsEnabling) {
-          continue;
-        }
-
-        // The referenced component(s) must be enabled.
-        for (String name : mo.getPropertyValues(apd)) {
-          ManagedObjectPath<?, ?> path = apd.getChildPath(name);
-          Message rufn = path.getManagedObjectDefinition()
-              .getUserFriendlyName();
-          ManagedObject<?> ref;
-          try {
-            ref = context.getManagedObject(path);
-          } catch (AuthorizationException e) {
-            Message msg = ERR_DSCFG_ERROR_MODIFY_AUTHZ.get(ufn);
-            throw new ClientException(
-                LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS, msg);
-          } catch (DefinitionDecodingException e) {
-            Message msg = ERR_DSCFG_ERROR_GET_CHILD_DDE.get(rufn, rufn, rufn);
-            throw new ClientException(LDAPResultCode.OTHER, msg);
-          } catch (ManagedObjectDecodingException e) {
-            // FIXME: should not abort here. Instead, display the
-            // errors (if verbose) and apply the changes to the
-            // partial managed object.
-            Message msg = ERR_DSCFG_ERROR_GET_CHILD_MODE.get(rufn);
-            throw new ClientException(LDAPResultCode.OTHER, msg, e);
-          } catch (CommunicationException e) {
-            Message msg = ERR_DSCFG_ERROR_MODIFY_CE.get(ufn, e.getMessage());
-            throw new ClientException(LDAPResultCode.OTHER, msg);
-          } catch (ManagedObjectNotFoundException e) {
-            Message msg = ERR_DSCFG_ERROR_GET_CHILD_MONFE.get(rufn);
-            throw new ClientException(LDAPResultCode.NO_SUCH_OBJECT, msg);
+          // Skip this aggregation if the referenced managed objects
+          // do not need to be enabled.
+          if (!apd.getTargetNeedsEnablingCondition().evaluate(context, mo)) {
+            continue;
           }
 
-          while (!ref.getPropertyValue(tpd)) {
-            boolean isBadReference = true;
-            app.println();
-            if (app.confirmAction(
-                INFO_EDITOR_PROMPT_ENABLED_REFERENCED_COMPONENT.get(rufn, name,
-                    ufn), true)) {
-              ref.setPropertyValue(tpd, true);
-              try {
-                ref.commit();
-                isBadReference = false;
-              } catch (MissingMandatoryPropertiesException e) {
-                // Give the user the chance to fix the problems.
-                app.println();
-                displayMissingMandatoryPropertyException(app, e);
-                app.println();
-                if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT.get(rufn), true)) {
-                  // FIXME: edit the properties of the referenced
-                  // object.
-                  MenuResult<Void> result =
-                    modifyManagedObject(app, context, ref);
-                  if (result.isQuit()) {
-                    return result;
-                  } else if (result.isSuccess()) {
-                    // The referenced component was modified
-                    // successfully, but may still be disabled.
-                    isBadReference = false;
-                  }
-                }
-              } catch (AuthorizationException e) {
-                Message msg = ERR_DSCFG_ERROR_MODIFY_AUTHZ.get(ufn);
-                throw new ClientException(
-                    LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS, msg);
-              } catch (ConcurrentModificationException e) {
-                Message msg = ERR_DSCFG_ERROR_MODIFY_CME.get(ufn);
-                throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION,
-                    msg);
-              } catch (OperationRejectedException e) {
-                // Give the user the chance to fix the problems.
-                app.println();
-                displayOperationRejectedException(app, e);
-                app.println();
-                if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT.get(rufn), true)) {
-                  MenuResult<Void> result =
-                    modifyManagedObject(app, context, ref);
-                  if (result.isQuit()) {
-                    return result;
-                  } else if (result.isSuccess()) {
-                    // The referenced component was modified
-                    // successfully, but may still be disabled.
-                    isBadReference = false;
-                  }
-                }
-              } catch (CommunicationException e) {
-                Message msg = ERR_DSCFG_ERROR_MODIFY_CE
-                    .get(ufn, e.getMessage());
-                throw new ClientException(LDAPResultCode.OTHER, msg);
-              } catch (ManagedObjectAlreadyExistsException e) {
-                // Should never happen.
-                throw new IllegalStateException(e);
-              }
+          // The referenced component(s) must be enabled.
+          for (String name : mo.getPropertyValues(apd)) {
+            ManagedObjectPath<?, ?> path = apd.getChildPath(name);
+            Message rufn = path.getManagedObjectDefinition()
+                .getUserFriendlyName();
+            ManagedObject<?> ref;
+            try {
+              ref = context.getManagedObject(path);
+            } catch (DefinitionDecodingException e) {
+              Message msg = ERR_DSCFG_ERROR_GET_CHILD_DDE.get(rufn, rufn, rufn);
+              throw new ClientException(LDAPResultCode.OTHER, msg);
+            } catch (ManagedObjectDecodingException e) {
+              // FIXME: should not abort here. Instead, display the
+              // errors (if verbose) and apply the changes to the
+              // partial managed object.
+              Message msg = ERR_DSCFG_ERROR_GET_CHILD_MODE.get(rufn);
+              throw new ClientException(LDAPResultCode.OTHER, msg, e);
+            } catch (ManagedObjectNotFoundException e) {
+              Message msg = ERR_DSCFG_ERROR_GET_CHILD_MONFE.get(rufn);
+              throw new ClientException(LDAPResultCode.NO_SUCH_OBJECT, msg);
             }
 
-            // If the referenced component is still disabled because
-            // the user refused to modify it, then give the used the
-            // option of editing the referencing component.
-            if (isBadReference) {
-              app.println();
-              app.println(ERR_SET_REFERENCED_COMPONENT_DISABLED.get(ufn, rufn));
-              app.println();
-              if (app
-                  .confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn), true)) {
-                return MenuResult.again();
+            Condition condition = apd.getTargetIsEnabledCondition();
+            while (!condition.evaluate(context, ref)) {
+              boolean isBadReference = true;
+
+              if (condition instanceof ContainsValueCondition) {
+                // Attempt to automatically enable the managed object.
+                ContainsValueCondition cvc = (ContainsValueCondition) condition;
+                app.println();
+                if (app.confirmAction(
+                    INFO_EDITOR_PROMPT_ENABLED_REFERENCED_COMPONENT.get(rufn,
+                        name, ufn), true)) {
+                  cvc.setPropertyValue(ref);
+                  try {
+                    ref.commit();
+                    isBadReference = false;
+                  } catch (MissingMandatoryPropertiesException e) {
+                    // Give the user the chance to fix the problems.
+                    app.println();
+                    displayMissingMandatoryPropertyException(app, e);
+                    app.println();
+                    if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT.get(rufn),
+                        true)) {
+                      MenuResult<Void> result = modifyManagedObject(app,
+                          context, ref);
+                      if (result.isQuit()) {
+                        return result;
+                      } else if (result.isSuccess()) {
+                        // The referenced component was modified
+                        // successfully, but may still be disabled.
+                        isBadReference = false;
+                      }
+                    }
+                  } catch (ConcurrentModificationException e) {
+                    Message msg = ERR_DSCFG_ERROR_MODIFY_CME.get(ufn);
+                    throw new ClientException(
+                        LDAPResultCode.CONSTRAINT_VIOLATION, msg);
+                  } catch (OperationRejectedException e) {
+                    // Give the user the chance to fix the problems.
+                    app.println();
+                    displayOperationRejectedException(app, e);
+                    app.println();
+                    if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT.get(rufn),
+                        true)) {
+                      MenuResult<Void> result = modifyManagedObject(app,
+                          context, ref);
+                      if (result.isQuit()) {
+                        return result;
+                      } else if (result.isSuccess()) {
+                        // The referenced component was modified
+                        // successfully, but may still be disabled.
+                        isBadReference = false;
+                      }
+                    }
+                  } catch (ManagedObjectAlreadyExistsException e) {
+                    // Should never happen.
+                    throw new IllegalStateException(e);
+                  }
+                }
               } else {
-                return MenuResult.cancel();
+                app.println();
+                if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT_TO_ENABLE.get(
+                    rufn, name, ufn), true)) {
+                  MenuResult<Void> result = SetPropSubCommandHandler
+                      .modifyManagedObject(app, context, ref);
+                  if (result.isQuit()) {
+                    return result;
+                  } else if (result.isSuccess()) {
+                    // The referenced component was modified
+                    // successfully, but may still be disabled.
+                    isBadReference = false;
+                  }
+                }
               }
-            }
 
-            // If the referenced component is now enabled, then drop out.
-            if (ref.getPropertyValue(tpd)) {
-              break;
+              // If the referenced component is still disabled because
+              // the user refused to modify it, then give the used the
+              // option of editing the referencing component.
+              if (isBadReference) {
+                app.println();
+                app.println(ERR_SET_REFERENCED_COMPONENT_DISABLED
+                    .get(ufn, rufn));
+                app.println();
+                if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn),
+                    true)) {
+                  return MenuResult.again();
+                } else {
+                  return MenuResult.cancel();
+                }
+              }
             }
           }
         }
       }
+    } catch (AuthorizationException e) {
+      Message msg = ERR_DSCFG_ERROR_MODIFY_AUTHZ.get(ufn);
+      throw new ClientException(LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS, msg);
+    } catch (CommunicationException e) {
+      Message msg = ERR_DSCFG_ERROR_MODIFY_CE.get(ufn, e.getMessage());
+      throw new ClientException(LDAPResultCode.OTHER, msg);
     }
 
     return MenuResult.success();
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.java
index 3e1f1ea..24c8f74 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.java
@@ -579,7 +579,7 @@
     /**
      * {@inheritDoc}
      */
-    public PropertyProvider properties() {
+    public ServerManagedObject<? extends TestChildCfg> managedObject() {
       return impl;
     }
 
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.java
index 8c58e60..2b1596e 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.java
@@ -721,7 +721,7 @@
     /**
      * {@inheritDoc}
      */
-    public PropertyProvider properties() {
+    public ServerManagedObject<? extends TestParentCfg> managedObject() {
       return impl;
     }
 
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/AggregationTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/AggregationTest.java
index fdbc7d2..f156ea0 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/AggregationTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/AggregationTest.java
@@ -52,6 +52,7 @@
 import org.opends.server.admin.UndefinedDefaultBehaviorProvider;
 import org.opends.server.admin.client.OperationRejectedException;
 import org.opends.server.admin.client.ldap.JNDIDirContextAdaptor;
+import org.opends.server.admin.condition.Conditions;
 import org.opends.server.admin.std.client.ConnectionHandlerCfgClient;
 import org.opends.server.admin.std.client.LDAPConnectionHandlerCfgClient;
 import org.opends.server.admin.std.client.RootCfgClient;
@@ -306,7 +307,7 @@
         .setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<String>());
     builder.setParentPath("/");
     builder.setRelationDefinition("connection-handler");
-    builder.setTargetEnabledPropertyName("enabled");
+    builder.setTargetIsEnabledCondition(Conditions.contains("enabled", "true"));
     aggregationPropertyDefinitionTargetMustBeEnabled = builder.getInstance();
     TestCfg.initializePropertyDefinition(aggregationPropertyDefinitionTargetMustBeEnabled);
 
@@ -319,8 +320,8 @@
         .setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<String>());
     builder.setParentPath("/");
     builder.setRelationDefinition("connection-handler");
-    builder.setTargetEnabledPropertyName("enabled");
-    builder.addSourceEnabledPropertyName("mandatory-boolean-property");
+    builder.setTargetIsEnabledCondition(Conditions.contains("enabled", "true"));
+    builder.setTargetNeedsEnablingCondition(Conditions.contains("mandatory-boolean-property", "true"));
     aggregationPropertyDefinitionTargetAndSourceMustBeEnabled = builder
         .getInstance();
     TestCfg.initializePropertyDefinition(aggregationPropertyDefinitionTargetAndSourceMustBeEnabled);
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/plugin/DomainFakeCfg.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/plugin/DomainFakeCfg.java
index 0cfa1e1..9dabda9 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/plugin/DomainFakeCfg.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/plugin/DomainFakeCfg.java
@@ -28,9 +28,10 @@
 
 import java.util.SortedSet;
 
+import org.opends.server.admin.Configuration;
 import org.opends.server.admin.ManagedObjectDefinition;
-import org.opends.server.admin.PropertyProvider;
 import org.opends.server.admin.server.ConfigurationChangeListener;
+import org.opends.server.admin.server.ServerManagedObject;
 import org.opends.server.admin.std.client.ReplicationDomainCfgClient;
 import org.opends.server.admin.std.meta.ReplicationDomainCfgDefn.IsolationPolicy;
 import org.opends.server.admin.std.server.ReplicationDomainCfg;
@@ -174,8 +175,7 @@
   /**
    * {@inheritDoc}
    */
-  public PropertyProvider properties()
-  {
+  public ServerManagedObject<? extends Configuration> managedObject() {
     return null;
   }
 
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/server/ReplServerFakeConfiguration.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/server/ReplServerFakeConfiguration.java
index 0e3926f..5135c2f 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/server/ReplServerFakeConfiguration.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/server/ReplServerFakeConfiguration.java
@@ -28,9 +28,10 @@
 
 import java.util.SortedSet;
 
+import org.opends.server.admin.Configuration;
 import org.opends.server.admin.ManagedObjectDefinition;
-import org.opends.server.admin.PropertyProvider;
 import org.opends.server.admin.server.ConfigurationChangeListener;
+import org.opends.server.admin.server.ServerManagedObject;
 import org.opends.server.admin.std.client.ReplicationServerCfgClient;
 import org.opends.server.admin.std.server.ReplicationServerCfg;
 import org.opends.server.types.DN;
@@ -182,8 +183,7 @@
   /**
    * {@inheritDoc}
    */
-  public PropertyProvider properties()
-  {
+  public ServerManagedObject<? extends Configuration> managedObject() {
     return null;
   }
 

--
Gitblit v1.10.0