From 4b31a35ca148d08a0c89ebbcbb51edeb3ba411b9 Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Thu, 25 Jan 2007 01:59:52 +0000
Subject: [PATCH] Make a number of updates to schema processing, all of which fall under the umbrella of issue #1163.  The individual issues addressed include:

---
 opendj-sdk/opends/src/server/org/opends/server/core/SchemaConfigManager.java                                  |   11 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/EntrySchemaCheckingTestCase.java | 1433 ++++++++++++
 opendj-sdk/opends/resource/schema/00-core.ldif                                                                |  192 
 opendj-sdk/opends/src/server/org/opends/server/util/LDIFReader.java                                           |    2 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/AttributeTypeSyntaxTest.java    |   43 
 opendj-sdk/opends/src/server/org/opends/server/schema/AttributeTypeSyntax.java                                |  228 +
 opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperation.java                                      |   23 
 opendj-sdk/opends/src/server/org/opends/server/schema/NameFormSyntax.java                                     |  226 -
 opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java                                    |  224 +
 opendj-sdk/opends/src/server/org/opends/server/types/MatchingRuleUse.java                                     |    3 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java    | 1529 +++++++++++++
 opendj-sdk/opends/src/server/org/opends/server/types/DITContentRule.java                                      |    3 
 opendj-sdk/opends/src/server/org/opends/server/core/ModifyDNOperation.java                                    |   19 
 opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java                                     |  137 +
 opendj-sdk/opends/src/server/org/opends/server/schema/MatchingRuleUseSyntax.java                              |  148 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java      |  118 +
 opendj-sdk/opends/src/server/org/opends/server/types/Entry.java                                               |  839 ++++---
 opendj-sdk/opends/src/server/org/opends/server/schema/DITContentRuleSyntax.java                               |  358 +-
 opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java                                      |   36 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestEntry.java                   |    2 
 opendj-sdk/opends/src/server/org/opends/server/types/NameForm.java                                            |    2 
 opendj-sdk/opends/src/server/org/opends/server/types/ObjectClass.java                                         |    2 
 opendj-sdk/opends/src/server/org/opends/server/schema/DITStructureRuleSyntax.java                             |   87 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/DITContentRuleSyntaxTest.java   |    8 
 opendj-sdk/opends/src/server/org/opends/server/core/AddOperation.java                                         |   45 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaTestMatchingRule.java   |   39 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestModifyDNOperation.java        |   66 
 opendj-sdk/opends/src/server/org/opends/server/types/AttributeType.java                                       |    3 
 opendj-sdk/opends/src/server/org/opends/server/messages/SchemaMessages.java                                   |  199 +
 opendj-sdk/opends/src/server/org/opends/server/schema/ObjectClassSyntax.java                                  |  326 +-
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java         |  176 +
 opendj-sdk/opends/resource/schema/02-config.ldif                                                              |    3 
 opendj-sdk/opends/src/server/org/opends/server/messages/BackendMessages.java                                  |  279 ++
 33 files changed, 5,599 insertions(+), 1,210 deletions(-)

diff --git a/opendj-sdk/opends/resource/schema/00-core.ldif b/opendj-sdk/opends/resource/schema/00-core.ldif
index 06db180..599c89f 100644
--- a/opendj-sdk/opends/resource/schema/00-core.ldif
+++ b/opendj-sdk/opends/resource/schema/00-core.ldif
@@ -34,72 +34,72 @@
 objectClass: subschema
 attributeTypes: ( 2.5.4.41 NAME 'name' EQUALITY caseIgnoreMatch
   SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768}
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.49 NAME 'distinguishedName'
   EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.0 NAME 'objectClass' EQUALITY objectIdentifierMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 2.5.4.1 NAME 'aliasedObjectName'
   EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
-  SINGLE-VALUE X-ORIGIN 'RFC 2256' )
+  SINGLE-VALUE X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 2.5.4.2 NAME 'knowledgeInformation' EQUALITY caseIgnoreMatch
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} X-ORIGIN 'RFC 2256' )
-attributeTypes: ( 2.5.4.3 NAME 'cn' SUP name X-ORIGIN 'RFC 2256' )
-attributeTypes: ( 2.5.4.4 NAME 'sn' SUP name X-ORIGIN 'RFC 2256' )
+attributeTypes: ( 2.5.4.3 NAME 'cn' SUP name X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.4 NAME 'sn' SUP name X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.5 NAME 'serialNumber' EQUALITY caseIgnoreMatch
   SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{64}
-  X-ORIGIN 'RFC 2256' )
-attributeTypes: ( 2.5.4.6 NAME 'c' SUP name SINGLE-VALUE X-ORIGIN 'RFC 2256' )
-attributeTypes: ( 2.5.4.7 NAME 'l' SUP name X-ORIGIN 'RFC 2256' )
-attributeTypes: ( 2.5.4.8 NAME 'st' SUP name X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.6 NAME 'c' SUP name SINGLE-VALUE X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.7 NAME 'l' SUP name X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.8 NAME 'st' SUP name X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.9 NAME 'street' EQUALITY caseIgnoreMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-ORIGIN 'RFC 2256' )
-attributeTypes: ( 2.5.4.10 NAME 'o' SUP name X-ORIGIN 'RFC 2256' )
-attributeTypes: ( 2.5.4.11 NAME 'ou' SUP name X-ORIGIN 'RFC 2256' )
-attributeTypes: ( 2.5.4.12 NAME 'title' SUP name X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.10 NAME 'o' SUP name X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.11 NAME 'ou' SUP name X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.12 NAME 'title' SUP name X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.13 NAME 'description' EQUALITY caseIgnoreMatch
   SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024}
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.14 NAME 'searchGuide'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.25 X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.25 X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.15 NAME 'businessCategory' EQUALITY caseIgnoreMatch
   SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128}
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.16 NAME 'postalAddress' EQUALITY caseIgnoreListMatch
   SUBSTR caseIgnoreListSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.41
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.17 NAME 'postalCode' EQUALITY caseIgnoreMatch
   SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40}
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.18 NAME 'postOfficeBox' EQUALITY caseIgnoreMatch
   SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40}
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.19 NAME 'physicalDeliveryOfficeName'
   EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.20 NAME 'telephoneNumber' EQUALITY telephoneNumberMatch
   SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{32}
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.21 NAME 'telexNumber'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.52 X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.52 X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.22 NAME 'teletexTerminalIdentifier'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.51 X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.51 X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.23 NAME 'facsimileTelephoneNumber'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.22 X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.22 X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.24 NAME 'x121Address' EQUALITY numericStringMatch
   SUBSTR numericStringSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{15}
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.25 NAME 'internationaliSDNNumber'
   EQUALITY numericStringMatch SUBSTR numericStringSubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{16} X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{16} X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.26 NAME 'registeredAddress' SUP postalAddress
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.27 NAME 'destinationIndicator' EQUALITY caseIgnoreMatch
   SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{128}
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.28 NAME 'preferredDeliveryMethod'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.14 SINGLE-VALUE X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.14 SINGLE-VALUE X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.29 NAME 'presentationAddress'
   EQUALITY presentationAddressMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.43
   SINGLE-VALUE X-ORIGIN 'RFC 2256' )
@@ -107,36 +107,36 @@
   EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38
   X-ORIGIN 'RFC 2256' )
 attributeTypes: ( 2.5.4.31 NAME 'member' SUP distinguishedName
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.32 NAME 'owner' SUP distinguishedName
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.33 NAME 'roleOccupant' SUP distinguishedName
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.34 NAME 'seeAlso' SUP distinguishedName
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.35 NAME 'userPassword'
-  SYNTAX 1.3.6.1.4.1.26027.1.3.1 X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.26027.1.3.1 X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.36 NAME 'userCertificate'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 X-ORIGIN 'RFC 4523' )
 attributeTypes: ( 2.5.4.37 NAME 'cACertificate'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 X-ORIGIN 'RFC 4523' )
 attributeTypes: ( 2.5.4.38 NAME 'authorityRevocationList'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 X-ORIGIN 'RFC 4523' )
 attributeTypes: ( 2.5.4.39 NAME 'certificateRevocationList'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 X-ORIGIN 'RFC 4523' )
 attributeTypes: ( 2.5.4.40 NAME 'crossCertificatePair'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.10 X-ORIGIN 'RFC 2256' )
-attributeTypes: ( 2.5.4.42 NAME 'givenName' SUP name X-ORIGIN 'RFC 2256' )
-attributeTypes: ( 2.5.4.43 NAME 'initials' SUP name X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.10 X-ORIGIN 'RFC 4523' )
+attributeTypes: ( 2.5.4.42 NAME 'givenName' SUP name X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.43 NAME 'initials' SUP name X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.44 NAME 'generationQualifier' SUP name
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.45 NAME 'x500UniqueIdentifier' EQUALITY bitStringMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.46 NAME 'dnQualifier' EQUALITY caseIgnoreMatch
   ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.47 NAME 'enhancedSearchGuide'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.21 X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.21 X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 1.3.6.1.1.16.4 NAME 'entryUUID'
   DESC 'UUID of the entry' EQUALITY uuidMatch ORDERING uuidOrderingMatch
   SYNTAX 1.3.6.1.1.16.1 SINGLE-VALUE NO-USER-MODIFICATION
@@ -145,75 +145,75 @@
   EQUALITY protocolInformationMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.42
   X-ORIGIN 'RFC 2256' )
 attributeTypes: ( 2.5.4.50 NAME 'uniqueMember' EQUALITY uniqueMemberMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.51 NAME 'houseIdentifier' EQUALITY caseIgnoreMatch
   SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768}
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.5.4.52 NAME 'supportedAlgorithms'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.49 X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.49 X-ORIGIN 'RFC 4523' )
 attributeTypes: ( 2.5.4.53 NAME 'deltaRevocationList'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 X-ORIGIN 'RFC 2256' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 X-ORIGIN 'RFC 4523' )
 attributeTypes: ( 2.5.4.54 NAME 'dmdName' SUP name X-ORIGIN 'RFC 2256' )
 attributeTypes: ( 2.5.18.1 NAME 'createTimestamp' EQUALITY generalizedTimeMatch
   ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
   SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation
-  X-ORIGIN 'RFC 2252' )
+  X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 2.5.18.2 NAME 'modifyTimestamp' EQUALITY generalizedTimeMatch
   ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
   SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation
-  X-ORIGIN 'RFC 2252' )
+  X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 2.5.18.3 NAME 'creatorsName' EQUALITY distinguishedNameMatch
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION
-  USAGE directoryOperation X-ORIGIN 'RFC 2252' )
+  USAGE directoryOperation X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 2.5.18.4 NAME 'modifiersName' EQUALITY distinguishedNameMatch
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION
-  USAGE directoryOperation X-ORIGIN 'RFC 2252' )
+  USAGE directoryOperation X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 2.5.18.10 NAME 'subschemaSubentry'
   EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
   SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation
-  X-ORIGIN 'RFC 2252' )
+  X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 2.5.21.5 NAME 'attributeTypes' EQUALITY caseIgnoreMatch
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.3 USAGE directoryOperation
-  X-ORIGIN 'RFC 2252' )
+  X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 2.5.21.6 NAME 'objectClasses' EQUALITY caseIgnoreMatch
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.37 USAGE directoryOperation
-  X-ORIGIN 'RFC 2252' )
+  X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 2.5.21.4 NAME 'matchingRules' EQUALITY caseIgnoreMatch
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.30 USAGE directoryOperation
-  X-ORIGIN 'RFC 2252' )
+  X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 2.5.21.8 NAME 'matchingRuleUse' EQUALITY caseIgnoreMatch
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.31 USAGE directoryOperation
-  X-ORIGIN 'RFC 2252' )
+  X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 1.3.6.1.4.1.1466.101.120.5 NAME 'namingContexts'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE dSAOperation X-ORIGIN 'RFC 2252' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE dSAOperation X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 1.3.6.1.4.1.1466.101.120.6 NAME 'altServer'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 USAGE dSAOperation X-ORIGIN 'RFC 2252' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 USAGE dSAOperation X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 1.3.6.1.4.1.1466.101.120.7 NAME 'supportedExtension'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation X-ORIGIN 'RFC 2252' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 1.3.6.1.4.1.1466.101.120.13 NAME 'supportedControl'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation X-ORIGIN 'RFC 2252' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 1.3.6.1.4.1.1466.101.120.14 NAME 'supportedSASLMechanisms'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dSAOperation X-ORIGIN 'RFC 2252' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dSAOperation X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 1.3.6.1.4.1.1466.101.120.15 NAME 'supportedLDAPVersion'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 USAGE dSAOperation X-ORIGIN 'RFC 2252' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 USAGE dSAOperation X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 1.3.6.1.4.1.4203.1.3.5 NAME 'supportedFeatures'
   EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38
   USAGE dSAOperation X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 1.3.6.1.4.1.1466.101.120.16 NAME 'ldapSyntaxes'
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.54 USAGE directoryOperation
-  X-ORIGIN 'RFC 2252' )
+  X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 2.5.21.1 NAME 'dITStructureRules' EQUALITY caseIgnoreMatch
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.17 USAGE directoryOperation
-  X-ORIGIN 'RFC 2252' )
+  X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 2.5.21.7 NAME 'nameForms' EQUALITY caseIgnoreMatch
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.35 USAGE directoryOperation
-  X-ORIGIN 'RFC 2252' )
+  X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 2.5.21.2 NAME 'dITContentRules' EQUALITY caseIgnoreMatch
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.16 USAGE directoryOperation
-  X-ORIGIN 'RFC 2252' )
+  X-ORIGIN 'RFC 4512' )
 attributeTypes: ( 0.9.2342.19200300.100.1.25 NAME 'dc'
   EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'RFC 2247' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 2.16.840.1.113730.3.1.1 NAME 'carLicense'
   DESC 'vehicle license or registration plate' EQUALITY caseIgnoreMatch
   SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
@@ -332,13 +332,13 @@
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 2079' )
 attributeTypes: ( 0.9.2342.19200300.100.1.55 NAME 'audio'
   EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{250000}
-  X-ORIGIN 'RFC 1274' )
+  X-ORIGIN 'RFC 2798' )
 attributeTypes: ( 0.9.2342.19200300.100.1.7 NAME 'photo'
   EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
-  X-ORIGIN 'RFC 1274' )
+  X-ORIGIN 'RFC 2798' )
 attributeTypes: ( 0.9.2342.19200300.100.1.1 NAME 'uid'
   EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} X-ORIGIN 'RFC 1274' )
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} X-ORIGIN 'RFC 4519' )
 attributeTypes: ( 1.3.6.1.1.4 NAME 'vendorName'
   EQUALITY 1.3.6.1.4.1.1466.109.114.1 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
   SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation X-ORIGIN 'RFC 3045' )
@@ -374,55 +374,55 @@
   NO-USER-MODIFICATION USAGE directoryOperation
   X-ORIGIN 'Sun Java System Directory Server' )
 objectClasses: ( 2.5.6.0 NAME 'top' ABSTRACT MUST objectClass
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4512' )
 objectClasses: ( 2.5.6.1 NAME 'alias' SUP top STRUCTURAL MUST aliasedObjectName
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4512' )
 objectClasses: ( 2.5.6.2 NAME 'country' SUP top STRUCTURAL MUST c
-  MAY ( searchGuide $ description ) X-ORIGIN 'RFC 2256' )
+  MAY ( searchGuide $ description ) X-ORIGIN 'RFC 4519' )
 objectClasses: ( 2.5.6.3 NAME 'locality' SUP top STRUCTURAL
   MAY ( street $ seeAlso $ searchGuide $ st $ l $ description )
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
 objectClasses: ( 2.5.6.4 NAME 'organization' SUP top STRUCTURAL MUST o
   MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $ x121Address $
   registeredAddress $ destinationIndicator $ preferredDeliveryMethod $
   telexNumber $ teletexTerminalIdentifier $ telephoneNumber $
   internationaliSDNNumber $ facsimileTelephoneNumber $ street $ postOfficeBox $
   postalCode $ postalAddress $ physicalDeliveryOfficeName $ st $ l $
-  description ) X-ORIGIN 'RFC 2256' )
+  description ) X-ORIGIN 'RFC 4519' )
 objectClasses: ( 2.5.6.5 NAME 'organizationalUnit' SUP top STRUCTURAL MUST ou
   MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $ x121Address $
   registeredAddress $ destinationIndicator $ preferredDeliveryMethod $
   telexNumber $ teletexTerminalIdentifier $ telephoneNumber $
   internationaliSDNNumber $ facsimileTelephoneNumber $ street $ postOfficeBox $
   postalCode $ postalAddress $ physicalDeliveryOfficeName $ st $ l $
-  description ) X-ORIGIN 'RFC 2256' )
+  description ) X-ORIGIN 'RFC 4519' )
 objectClasses: ( 2.5.6.6 NAME 'person' SUP top STRUCTURAL MUST ( sn $ cn )
   MAY ( userPassword $ telephoneNumber $ seeAlso $ description )
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
 objectClasses: ( 2.5.6.7 NAME 'organizationalPerson' SUP person STRUCTURAL
   MAY ( title $ x121Address $ registeredAddress $ destinationIndicator $
   preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
   telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $
   street $ postOfficeBox $ postalCode $ postalAddress $
-  physicalDeliveryOfficeName $ ou $ st $ l ) X-ORIGIN 'RFC 2256' )
+  physicalDeliveryOfficeName $ ou $ st $ l ) X-ORIGIN 'RFC 4519' )
 objectClasses: ( 2.5.6.8 NAME 'organizationalRole' SUP top STRUCTURAL MUST cn
   MAY ( x121Address $ registeredAddress $ destinationIndicator $
   preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
   telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $
   seeAlso $ roleOccupant $ preferredDeliveryMethod $ street $ postOfficeBox $
   postalCode $ postalAddress $ physicalDeliveryOfficeName $ ou $ st $ l $
-  description ) X-ORIGIN 'RFC 2256' )
+  description ) X-ORIGIN 'RFC 4519' )
 objectClasses: ( 2.5.6.9 NAME 'groupOfNames' SUP top STRUCTURAL
   MUST cn MAY ( member $ businessCategory $ seeAlso $ owner $ ou $ o $
-  description ) X-ORIGIN 'RFC 2256' )
+  description ) X-ORIGIN 'RFC 4519' )
 objectClasses: ( 2.5.6.10 NAME 'residentialPerson' SUP person STRUCTURAL MUST l
   MAY ( businessCategory $ x121Address $ registeredAddress $
   destinationIndicator $ preferredDeliveryMethod $ telexNumber $
   teletexTerminalIdentifier $ telephoneNumber $ internationaliSDNNumber $
   facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $
-  postalAddress $ physicalDeliveryOfficeName $ st $ l ) X-ORIGIN 'RFC 2256' )
+  postalAddress $ physicalDeliveryOfficeName $ st $ l ) X-ORIGIN 'RFC 4519' )
 objectClasses: ( 2.5.6.11 NAME 'applicationProcess' SUP top STRUCTURAL MUST cn
-  MAY ( seeAlso $ ou $ l $ description ) X-ORIGIN 'RFC 2256' )
+  MAY ( seeAlso $ ou $ l $ description ) X-ORIGIN 'RFC 4519' )
 objectClasses: ( 2.5.6.12 NAME 'applicationEntity' SUP top STRUCTURAL
   MUST ( presentationAddress $ cn ) MAY ( supportedApplicationContext $
   seeAlso $ ou $ o $ l $ description ) X-ORIGIN 'RFC 2256' )
@@ -430,23 +430,23 @@
   MAY knowledgeInformation X-ORIGIN 'RFC 2256' )
 objectClasses: ( 2.5.6.14 NAME 'device' SUP top STRUCTURAL MUST cn
   MAY ( serialNumber $ seeAlso $ owner $ ou $ o $ l $ description )
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4519' )
 objectClasses: ( 2.5.6.15 NAME 'strongAuthenticationUser' SUP top AUXILIARY
-  MUST userCertificate X-ORIGIN 'RFC 2256' )
+  MUST userCertificate X-ORIGIN 'RFC 4523' )
 objectClasses: ( 2.5.6.16 NAME 'certificationAuthority' SUP top AUXILIARY
   MUST ( authorityRevocationList $ certificateRevocationList $ caCertificate )
-  MAY crossCertificatePair X-ORIGIN 'RFC 2256' )
+  MAY crossCertificatePair X-ORIGIN 'RFC 4523' )
 objectClasses: ( 2.5.6.16.2 NAME 'certificationAuthority-V2'
   SUP certificationAuthority AUXILIARY MAY deltaRevocationList
-  X-ORIGIN 'RFC 2256' )
+  X-ORIGIN 'RFC 4523' )
 objectClasses: ( 2.5.6.17 NAME 'groupOfUniqueNames' SUP top STRUCTURAL
   MUST cn MAY ( uniqueMember $ businessCategory $ seeAlso $ owner $ ou $ o $
-  description ) X-ORIGIN 'RFC 2256' )
+  description ) X-ORIGIN 'RFC 4519' )
 objectClasses: ( 2.5.6.18 NAME 'userSecurityInformation' SUP top AUXILIARY
-  MAY ( supportedAlgorithms ) X-ORIGIN 'RFC 2256' )
+  MAY ( supportedAlgorithms ) X-ORIGIN 'RFC 4523' )
 objectClasses: ( 2.5.6.19 NAME 'cRLDistributionPoint' SUP top STRUCTURAL
   MUST cn MAY ( certificateRevocationList $ authorityRevocationList $
-  deltaRevocationList ) X-ORIGIN 'RFC 2256' )
+  deltaRevocationList ) X-ORIGIN 'RFC 4523' )
 objectClasses: ( 2.5.6.20 NAME 'dmd' SUP top STRUCTURAL MUST dmdName
   MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $ x121Address $
   registeredAddress $ destinationIndicator $ preferredDeliveryMethod $
@@ -455,10 +455,10 @@
   postalCode $ postalAddress $ physicalDeliveryOfficeName $ st $ l $
   description ) X-ORIGIN 'RFC 2256' )
 objectClasses: ( 1.3.6.1.4.1.1466.101.120.111 NAME 'extensibleObject' SUP top
-  AUXILIARY X-ORIGIN 'RFC 2252' )
+  AUXILIARY X-ORIGIN 'RFC 4512' )
 objectClasses: ( 2.5.20.1 NAME 'subschema' AUXILIARY MAY ( dITStructureRules $
   nameForms $ ditContentRules $ objectClasses $ attributeTypes $ matchingRules $
-  matchingRuleUse ) X-ORIGIN 'RFC 2252' )
+  matchingRuleUse ) X-ORIGIN 'RFC 4512' )
 objectClasses: ( 0.9.2342.19200300.100.4.5 NAME 'account' SUP top STRUCTURAL
   MUST uid MAY ( description $ seeAlso $ l $ o $ ou $ host )
   X-ORIGIN 'RFC 4524' )
@@ -494,7 +494,7 @@
 objectClasses: ( 0.9.2342.19200300.100.4.19 NAME 'simpleSecurityObject' SUP top
   AUXILIARY MUST userPassword X-ORIGIN 'RFC 4524' )
 objectClasses: ( 1.3.6.1.4.1.1466.344 NAME 'dcObject' SUP top AUXILIARY MUST dc
-  X-ORIGIN 'RFC 2247' )
+  X-ORIGIN 'RFC 4519' )
 objectClasses: ( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson'
   SUP organizationalPerson STRUCTURAL MAY ( audio $ businessCategory $
   carLicense $ departmentNumber $ displayName $ employeeNumber $ employeeType $
@@ -512,7 +512,7 @@
   o $ ou $ st $ street $ uid $ description $ owner $ seeAlso )
   X-ORIGIN 'draft-furuseth-ldap-untypedobject' )
 objectClasses: ( 1.3.6.1.1.3.1 NAME 'uidObject' SUP top AUXILIARY MUST uid
-  X-ORIGIN 'RFC 2377' )
+  X-ORIGIN 'RFC 4519' )
 objectClasses: ( 2.16.840.1.113730.3.2.6 NAME 'referral'
   DESC 'named subordinate reference object' STRUCTURAL MUST ref
   X-ORIGIN 'RFC 3296' )
diff --git a/opendj-sdk/opends/resource/schema/02-config.ldif b/opendj-sdk/opends/resource/schema/02-config.ldif
index 765ae13..dfcbc48 100644
--- a/opendj-sdk/opends/resource/schema/02-config.ldif
+++ b/opendj-sdk/opends/resource/schema/02-config.ldif
@@ -292,7 +292,8 @@
   SINGLE-VALUE X-ORIGIN 'OpenDS Directory Server' )
 attributeTypes: ( 1.3.6.1.4.1.26027.1.1.84
   NAME 'ds-cfg-profiler-state' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
-  SINGLE-VALUE NO-USER-MODIFICATION X-ORIGIN 'OpenDS Directory Server' )
+  SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation
+  X-ORIGIN 'OpenDS Directory Server' )
 attributeTypes: ( 1.3.6.1.4.1.26027.1.1.85
   NAME 'ds-cfg-profile-sample-interval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
   SINGLE-VALUE X-ORIGIN 'OpenDS Directory Server' )
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java b/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java
index 57392a6..d9d94f7 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java
@@ -992,7 +992,7 @@
               try
               {
                 type = AttributeTypeSyntax.decodeAttributeType(v.getValue(),
-                                                               newSchema);
+                                                newSchema, false);
               }
               catch (DirectoryException de)
               {
@@ -1017,7 +1017,7 @@
               try
               {
                 oc = ObjectClassSyntax.decodeObjectClass(v.getValue(),
-                                                         newSchema);
+                                                         newSchema, false);
               }
               catch (DirectoryException de)
               {
@@ -1041,7 +1041,8 @@
               NameForm nf;
               try
               {
-                nf = NameFormSyntax.decodeNameForm(v.getValue(), newSchema);
+                nf = NameFormSyntax.decodeNameForm(v.getValue(), newSchema,
+                                                   false);
               }
               catch (DirectoryException de)
               {
@@ -1066,7 +1067,7 @@
               try
               {
                 dcr = DITContentRuleSyntax.decodeDITContentRule(v.getValue(),
-                                                                newSchema);
+                                                newSchema, false);
               }
               catch (DirectoryException de)
               {
@@ -1116,7 +1117,7 @@
               try
               {
                 mru = MatchingRuleUseSyntax.decodeMatchingRuleUse(v.getValue(),
-                                                                  newSchema);
+                                                 newSchema, false);
               }
               catch (DirectoryException de)
               {
@@ -1162,7 +1163,7 @@
               try
               {
                 type = AttributeTypeSyntax.decodeAttributeType(v.getValue(),
-                                                               newSchema);
+                                                newSchema, false);
               }
               catch (DirectoryException de)
               {
@@ -1188,7 +1189,7 @@
               try
               {
                 oc = ObjectClassSyntax.decodeObjectClass(v.getValue(),
-                                                         newSchema);
+                                                         newSchema, false);
               }
               catch (DirectoryException de)
               {
@@ -1212,7 +1213,8 @@
               NameForm nf;
               try
               {
-                nf = NameFormSyntax.decodeNameForm(v.getValue(), newSchema);
+                nf = NameFormSyntax.decodeNameForm(v.getValue(), newSchema,
+                                                   false);
               }
               catch (DirectoryException de)
               {
@@ -1237,7 +1239,7 @@
               try
               {
                 dcr = DITContentRuleSyntax.decodeDITContentRule(v.getValue(),
-                                                                newSchema);
+                                                newSchema, false);
               }
               catch (DirectoryException de)
               {
@@ -1289,7 +1291,7 @@
               try
               {
                 mru = MatchingRuleUseSyntax.decodeMatchingRuleUse(v.getValue(),
-                                                                  newSchema);
+                                                 newSchema, false);
               }
               catch (DirectoryException de)
               {
@@ -1435,7 +1437,7 @@
 
 
     // Make sure that the new attribute type doesn't reference an undefined
-    // superior attribute type.
+    // or OBSOLETE superior attribute type.
     AttributeType superiorType = attributeType.getSuperiorType();
     if (superiorType != null)
     {
@@ -1447,6 +1449,56 @@
         throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                      msgID);
       }
+      else if (superiorType.isObsolete())
+      {
+        int    msgID   = MSGID_SCHEMA_MODIFY_OBSOLETE_SUPERIOR_ATTRIBUTE_TYPE;
+        String message = getMessage(msgID, attributeType.getNameOrOID(),
+                                    superiorType.getNameOrOID());
+        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                     msgID);
+      }
+    }
+
+
+    // Make sure that none of the associated matching rules are marked OBSOLETE.
+    MatchingRule mr = attributeType.getEqualityMatchingRule();
+    if ((mr != null) && mr.isObsolete())
+    {
+      int    msgID   = MSGID_SCHEMA_MODIFY_ATTRTYPE_OBSOLETE_MR;
+      String message = getMessage(msgID, attributeType.getNameOrOID(),
+                                  mr.getNameOrOID());
+      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                   msgID);
+    }
+
+    mr = attributeType.getOrderingMatchingRule();
+    if ((mr != null) && mr.isObsolete())
+    {
+      int    msgID   = MSGID_SCHEMA_MODIFY_ATTRTYPE_OBSOLETE_MR;
+      String message = getMessage(msgID, attributeType.getNameOrOID(),
+                                  mr.getNameOrOID());
+      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                   msgID);
+    }
+
+    mr = attributeType.getSubstringMatchingRule();
+    if ((mr != null) && mr.isObsolete())
+    {
+      int    msgID   = MSGID_SCHEMA_MODIFY_ATTRTYPE_OBSOLETE_MR;
+      String message = getMessage(msgID, attributeType.getNameOrOID(),
+                                  mr.getNameOrOID());
+      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                   msgID);
+    }
+
+    mr = attributeType.getApproximateMatchingRule();
+    if ((mr != null) && mr.isObsolete())
+    {
+      int    msgID   = MSGID_SCHEMA_MODIFY_ATTRTYPE_OBSOLETE_MR;
+      String message = getMessage(msgID, attributeType.getNameOrOID(),
+                                  mr.getNameOrOID());
+      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                   msgID);
     }
 
 
@@ -1572,7 +1624,8 @@
         AttributeType at;
         try
         {
-          at = AttributeTypeSyntax.decodeAttributeType(v.getValue(), schema);
+          at = AttributeTypeSyntax.decodeAttributeType(v.getValue(), schema,
+                                                       false);
         }
         catch (DirectoryException de)
         {
@@ -1746,7 +1799,8 @@
 
 
     // Make sure that the new objectclass doesn't reference an undefined
-    // superior class, or an undefined required or optional attribute type.
+    // superior class, or an undefined required or optional attribute type,
+    // and that none of them are OBSOLETE.
     ObjectClass superiorClass = objectClass.getSuperiorClass();
     if (superiorClass != null)
     {
@@ -1758,6 +1812,14 @@
         throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                      msgID);
       }
+      else if (superiorClass.isObsolete())
+      {
+        int    msgID   = MSGID_SCHEMA_MODIFY_OBSOLETE_SUPERIOR_OBJECTCLASS;
+        String message = getMessage(msgID, objectClass.getNameOrOID(),
+                                    superiorClass.getNameOrOID());
+        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                     msgID);
+      }
     }
 
     for (AttributeType at : objectClass.getRequiredAttributes())
@@ -1770,6 +1832,14 @@
         throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                      msgID);
       }
+      else if (at.isObsolete())
+      {
+        int    msgID   = MSGID_SCHEMA_MODIFY_OC_OBSOLETE_REQUIRED_ATTR;
+        String message = getMessage(msgID, objectClass.getNameOrOID(),
+                                    at.getNameOrOID());
+        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                     msgID);
+      }
     }
 
     for (AttributeType at : objectClass.getOptionalAttributes())
@@ -1782,6 +1852,14 @@
         throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                      msgID);
       }
+      else if (at.isObsolete())
+      {
+        int    msgID   = MSGID_SCHEMA_MODIFY_OC_OBSOLETE_OPTIONAL_ATTR;
+        String message = getMessage(msgID, objectClass.getNameOrOID(),
+                                    at.getNameOrOID());
+        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                     msgID);
+      }
     }
 
 
@@ -1906,7 +1984,7 @@
         ObjectClass oc;
         try
         {
-          oc = ObjectClassSyntax.decodeObjectClass(v.getValue(), schema);
+          oc = ObjectClassSyntax.decodeObjectClass(v.getValue(), schema, false);
         }
         catch (DirectoryException de)
         {
@@ -2045,7 +2123,8 @@
 
 
     // Make sure that the new name form doesn't reference an undefined
-    // structural class, or an undefined required or optional attribute type.
+    // structural class, or an undefined required or optional attribute type, or
+    // that any of them are marked OBSOLETE.
     ObjectClass structuralClass = nameForm.getStructuralClass();
     if (! schema.hasObjectClass(structuralClass.getOID()))
     {
@@ -2063,6 +2142,14 @@
       throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                    msgID);
     }
+    if (structuralClass.isObsolete())
+    {
+      int    msgID   = MSGID_SCHEMA_MODIFY_NF_OC_OBSOLETE;
+      String message = getMessage(msgID, nameForm.getNameOrOID(),
+                                  structuralClass.getNameOrOID());
+      throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
+                                   msgID);
+    }
 
     NameForm existingNFForClass = schema.getNameForm(structuralClass);
     if ((existingNFForClass != null) && (existingNFForClass != existingNF))
@@ -2085,6 +2172,14 @@
         throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                      msgID);
       }
+      else if (at.isObsolete())
+      {
+        int    msgID   = MSGID_SCHEMA_MODIFY_NF_OBSOLETE_REQUIRED_ATTR;
+        String message = getMessage(msgID, nameForm.getNameOrOID(),
+                                    at.getNameOrOID());
+        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                     msgID);
+      }
     }
 
     for (AttributeType at : nameForm.getOptionalAttributes())
@@ -2097,6 +2192,14 @@
         throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                      msgID);
       }
+      else if (at.isObsolete())
+      {
+        int    msgID   = MSGID_SCHEMA_MODIFY_NF_OBSOLETE_OPTIONAL_ATTR;
+        String message = getMessage(msgID, nameForm.getNameOrOID(),
+                                    at.getNameOrOID());
+        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                     msgID);
+      }
     }
 
 
@@ -2220,7 +2323,7 @@
         NameForm nf;
         try
         {
-          nf = NameFormSyntax.decodeNameForm(v.getValue(), schema);
+          nf = NameFormSyntax.decodeNameForm(v.getValue(), schema, false);
         }
         catch (DirectoryException de)
         {
@@ -2363,6 +2466,15 @@
                                    msgID);
     }
 
+    if (structuralClass.isObsolete())
+    {
+      int    msgID   = MSGID_SCHEMA_MODIFY_DCR_STRUCTURAL_OC_OBSOLETE;
+      String message = getMessage(msgID, ditContentRule.getName(),
+                                  structuralClass.getNameOrOID());
+      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                   msgID);
+    }
+
     for (ObjectClass oc : ditContentRule.getAuxiliaryClasses())
     {
       if (! schema.hasObjectClass(oc.getOID()))
@@ -2373,6 +2485,22 @@
         throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                      msgID);
       }
+      if (oc.getObjectClassType() != ObjectClassType.AUXILIARY)
+      {
+        int    msgID   = MSGID_SCHEMA_MODIFY_DCR_OC_NOT_AUXILIARY;
+        String message = getMessage(msgID, ditContentRule.getName(),
+                                    oc.getNameOrOID());
+        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
+                                     msgID);
+      }
+      if (oc.isObsolete())
+      {
+        int    msgID   = MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_AUXILIARY_OC;
+        String message = getMessage(msgID, ditContentRule.getName(),
+                                    oc.getNameOrOID());
+        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
+                                     msgID);
+      }
     }
 
     for (AttributeType at : ditContentRule.getRequiredAttributes())
@@ -2385,6 +2513,14 @@
         throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                      msgID);
       }
+      else if (at.isObsolete())
+      {
+        int    msgID   = MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_REQUIRED_ATTR;
+        String message = getMessage(msgID, ditContentRule.getName(),
+                                    at.getNameOrOID());
+        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                     msgID);
+      }
     }
 
     for (AttributeType at : ditContentRule.getOptionalAttributes())
@@ -2397,6 +2533,14 @@
         throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                      msgID);
       }
+      else if (at.isObsolete())
+      {
+        int    msgID   = MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_OPTIONAL_ATTR;
+        String message = getMessage(msgID, ditContentRule.getName(),
+                                    at.getNameOrOID());
+        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                     msgID);
+      }
     }
 
     for (AttributeType at : ditContentRule.getProhibitedAttributes())
@@ -2409,6 +2553,14 @@
         throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                      msgID);
       }
+      else if (at.isObsolete())
+      {
+        int    msgID   = MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_PROHIBITED_ATTR;
+        String message = getMessage(msgID, ditContentRule.getName(),
+                                    at.getNameOrOID());
+        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                     msgID);
+      }
     }
 
 
@@ -2616,6 +2768,29 @@
       throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                    msgID);
     }
+    if (nameForm.isObsolete())
+    {
+      int    msgID   = MSGID_SCHEMA_MODIFY_DSR_OBSOLETE_NAME_FORM;
+      String message = getMessage(msgID, ditStructureRule.getNameOrRuleID(),
+                                  nameForm.getNameOrOID());
+      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                   msgID);
+    }
+
+
+    // If there are any superior rules, then make sure none of them are marked
+    // OBSOLETE.
+    for (DITStructureRule dsr : ditStructureRule.getSuperiorRules())
+    {
+      if (dsr.isObsolete())
+      {
+        int    msgID   = MSGID_SCHEMA_MODIFY_DSR_OBSOLETE_SUPERIOR_RULE;
+        String message = getMessage(msgID, ditStructureRule.getNameOrRuleID(),
+                                    dsr.getNameOrRuleID());
+        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                     msgID);
+      }
+    }
 
 
     // If there is no existing rule, then we're adding a new DIT structure rule.
@@ -2867,6 +3042,15 @@
                                    msgID);
     }
 
+    if (matchingRule.isObsolete())
+    {
+      int    msgID   = MSGID_SCHEMA_MODIFY_MRU_OBSOLETE_MR;
+      String message = getMessage(msgID, matchingRuleUse.getName(),
+                                  matchingRule.getNameOrOID());
+      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                   msgID);
+    }
+
 
     // Make sure that the new matching rule use doesn't reference an undefined
     // attribute type.
@@ -2880,6 +3064,14 @@
         throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                      msgID);
       }
+      else if (at.isObsolete())
+      {
+        int    msgID   = MSGID_SCHEMA_MODIFY_MRU_OBSOLETE_ATTR;
+        String message = getMessage(msgID, matchingRuleUse.getName(),
+                                    matchingRule.getNameOrOID());
+        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                     msgID);
+      }
     }
 
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/AddOperation.java b/opendj-sdk/opends/src/server/org/opends/server/core/AddOperation.java
index d1958f3..2adae2b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/AddOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/AddOperation.java
@@ -1470,7 +1470,8 @@
         if (DirectoryServer.checkSchema())
         {
           StringBuilder invalidReason = new StringBuilder();
-          if (! entry.conformsToSchema(parentEntry, true, invalidReason))
+          if (! entry.conformsToSchema(parentEntry, true, true, true,
+                                       invalidReason))
           {
             setResultCode(ResultCode.OBJECTCLASS_VIOLATION);
             setErrorMessage(invalidReason);
@@ -1599,6 +1600,48 @@
                 break;
             }
           }
+
+
+          // See if the entry contains any attributes or object classes marked
+          // OBSOLETE.  If so, then reject the entry.
+          for (AttributeType at : userAttributes.keySet())
+          {
+            if (at.isObsolete())
+            {
+              int    msgID   = MSGID_ADD_ATTR_IS_OBSOLETE;
+              String message = getMessage(msgID, String.valueOf(entryDN),
+                                          at.getNameOrOID());
+              appendErrorMessage(message);
+              setResultCode(ResultCode.CONSTRAINT_VIOLATION);
+              break addProcessing;
+            }
+          }
+
+          for (AttributeType at : operationalAttributes.keySet())
+          {
+            if (at.isObsolete())
+            {
+              int    msgID   = MSGID_ADD_ATTR_IS_OBSOLETE;
+              String message = getMessage(msgID, String.valueOf(entryDN),
+                                          at.getNameOrOID());
+              appendErrorMessage(message);
+              setResultCode(ResultCode.CONSTRAINT_VIOLATION);
+              break addProcessing;
+            }
+          }
+
+          for (ObjectClass oc : objectClasses.keySet())
+          {
+            if (oc.isObsolete())
+            {
+              int    msgID   = MSGID_ADD_OC_IS_OBSOLETE;
+              String message = getMessage(msgID, String.valueOf(entryDN),
+                                          oc.getNameOrOID());
+              appendErrorMessage(message);
+              setResultCode(ResultCode.CONSTRAINT_VIOLATION);
+              break addProcessing;
+            }
+          }
         }
 
         // Check to see if the client has permission to perform the add.
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java b/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
index 280134a..d4654fd 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -2952,7 +2952,41 @@
       objectClass = new ObjectClass(definition, name,
                                     Collections.singleton(name), oid, null,
                                     getTopObjectClass(), null, null,
-                                    ObjectClassType.ABSTRACT, false, null);
+                                    ObjectClassType.STRUCTURAL, false, null);
+    }
+
+    return objectClass;
+  }
+
+
+
+  /**
+   * Causes the Directory Server to construct a new auxiliary objectclass
+   * definition with the provided name and with no required or allowed
+   * attributes. This should only be used if there is no objectclass for the
+   * specified name. It will not register the created objectclass with the
+   * Directory Server.
+   *
+   * @param  name  The name to use for the objectclass, as provided by the user.
+   *
+   * @return  The constructed objectclass definition.
+   */
+  public static ObjectClass getDefaultAuxiliaryObjectClass(String name)
+  {
+    assert debugEnter(CLASS_NAME, "getDefaultObjectClass",
+                      String.valueOf(name));
+
+    String lowerName = toLowerCase(name);
+    ObjectClass objectClass = directoryServer.schema.getObjectClass(lowerName);
+    if (objectClass == null)
+    {
+      String oid        = lowerName + "-oid";
+      String definition = "( " + oid + " NAME '" + name + "' ABSTRACT )";
+
+      objectClass = new ObjectClass(definition, name,
+                                    Collections.singleton(name), oid, null,
+                                    getTopObjectClass(), null, null,
+                                    ObjectClassType.AUXILIARY, false, null);
     }
 
     return objectClass;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/ModifyDNOperation.java b/opendj-sdk/opends/src/server/org/opends/server/core/ModifyDNOperation.java
index 2f44f55..70da684 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/ModifyDNOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/ModifyDNOperation.java
@@ -1486,7 +1486,8 @@
         if (DirectoryServer.checkSchema())
         {
           StringBuilder invalidReason = new StringBuilder();
-          if (! newEntry.conformsToSchema(null, false, invalidReason))
+          if (! newEntry.conformsToSchema(null, false, true, true,
+                                          invalidReason))
           {
             setResultCode(ResultCode.OBJECTCLASS_VIOLATION);
             appendErrorMessage(getMessage(MSGID_MODDN_VIOLATES_SCHEMA,
@@ -1494,6 +1495,19 @@
                                           String.valueOf(invalidReason)));
             break modifyDNProcessing;
           }
+
+          for (int i=0; i < newRDNValues; i++)
+          {
+            AttributeType at = newRDN.getAttributeType(i);
+            if (at.isObsolete())
+            {
+              setResultCode(ResultCode.CONSTRAINT_VIOLATION);
+              appendErrorMessage(getMessage(MSGID_MODDN_NEWRDN_ATTR_IS_OBSOLETE,
+                                            String.valueOf(entryDN),
+                                            at.getNameOrOID()));
+              break modifyDNProcessing;
+            }
+          }
         }
 
 
@@ -1697,7 +1711,8 @@
           if (DirectoryServer.checkSchema())
           {
             StringBuilder invalidReason = new StringBuilder();
-            if (! newEntry.conformsToSchema(null, false, invalidReason))
+            if (! newEntry.conformsToSchema(null, false, true, true,
+                                            invalidReason))
             {
               setResultCode(ResultCode.OBJECTCLASS_VIOLATION);
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperation.java b/opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperation.java
index 1983be7..854de22 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperation.java
@@ -1350,6 +1350,26 @@
             }
           }
 
+          // If the attribute type is marked "OBSOLETE" and the modification
+          // is setting new values, then fail unless this is an internal
+          // operation or is related to synchronization in some way.
+          if (t.isObsolete())
+          {
+            if (a.hasValue() &&
+                (m.getModificationType() != ModificationType.DELETE))
+            {
+              if (! (isInternalOperation() || isSynchronizationOperation() ||
+                     m.isInternal()))
+              {
+                setResultCode(ResultCode.CONSTRAINT_VIOLATION);
+                appendErrorMessage(getMessage(MSGID_MODIFY_ATTR_IS_OBSOLETE,
+                                              String.valueOf(entryDN),
+                                              a.getName()));
+                break modifyProcessing;
+              }
+            }
+          }
+
 
           // If the modification is updating the password attribute, then
           // perform any necessary password policy processing.  This processing
@@ -2312,7 +2332,8 @@
         if (DirectoryServer.checkSchema())
         {
           StringBuilder invalidReason = new StringBuilder();
-          if (! modifiedEntry.conformsToSchema(null, false, invalidReason))
+          if (! modifiedEntry.conformsToSchema(null, false, false, false,
+                                               invalidReason))
           {
             setResultCode(ResultCode.OBJECTCLASS_VIOLATION);
             appendErrorMessage(getMessage(MSGID_MODIFY_VIOLATES_SCHEMA,
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/SchemaConfigManager.java b/opendj-sdk/opends/src/server/org/opends/server/core/SchemaConfigManager.java
index fbaf2be..d20ce16 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/SchemaConfigManager.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/SchemaConfigManager.java
@@ -986,7 +986,7 @@
             try
             {
               attrType = attrTypeSyntax.decodeAttributeType(v.getValue(),
-                                                            schema);
+                                                            schema, false);
             }
             catch (DirectoryException de)
             {
@@ -1058,7 +1058,7 @@
             ObjectClass oc;
             try
             {
-              oc = ocSyntax.decodeObjectClass(v.getValue(), schema);
+              oc = ocSyntax.decodeObjectClass(v.getValue(), schema, false);
             }
             catch (DirectoryException de)
             {
@@ -1130,7 +1130,7 @@
             NameForm nf;
             try
             {
-              nf = nfSyntax.decodeNameForm(v.getValue(), schema);
+              nf = nfSyntax.decodeNameForm(v.getValue(), schema, false);
               nf.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME);
               nf.setSchemaFile(schemaFile);
             }
@@ -1204,7 +1204,7 @@
             DITContentRule dcr;
             try
             {
-              dcr = dcrSyntax.decodeDITContentRule(v.getValue(), schema);
+              dcr = dcrSyntax.decodeDITContentRule(v.getValue(), schema, false);
               dcr.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME);
               dcr.setSchemaFile(schemaFile);
             }
@@ -1353,7 +1353,8 @@
             MatchingRuleUse mru;
             try
             {
-              mru = mruSyntax.decodeMatchingRuleUse(v.getValue(), schema);
+              mru = mruSyntax.decodeMatchingRuleUse(v.getValue(), schema,
+                                                    false);
               mru.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME);
               mru.setSchemaFile(schemaFile);
             }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/BackendMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/BackendMessages.java
index eec2341..0f5e9c9 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/BackendMessages.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/BackendMessages.java
@@ -2962,6 +2962,215 @@
 
 
   /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add an attribute type whose superior type is OBSOLETE.  This takes two
+   * arguments, which are the name or OID of the attribute type and the name or
+   * OID of the superior type.
+   */
+  public static final int MSGID_SCHEMA_MODIFY_OBSOLETE_SUPERIOR_ATTRIBUTE_TYPE =
+       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 274;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add an attribute type with a matching rule that is OBSOLETE.  This takes
+   * two arguments, which are the name or OID of the attribute type and the name
+   * or OID of the matching rule.
+   */
+  public static final int MSGID_SCHEMA_MODIFY_ATTRTYPE_OBSOLETE_MR =
+       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 275;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add an object class whose superior class is OBSOLETE.  This takes two
+   * arguments, which are the name or OID of the object class and the name or
+   * OID of the superior class.
+   */
+  public static final int MSGID_SCHEMA_MODIFY_OBSOLETE_SUPERIOR_OBJECTCLASS =
+       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 276;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add an object class that requires an OBSOLETE attribute type.  This takes
+   * two arguments, which are the name or OID of the object class and the name
+   * or OID of the required attribute type.
+   */
+  public static final int MSGID_SCHEMA_MODIFY_OC_OBSOLETE_REQUIRED_ATTR =
+       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 277;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add an object class that allows an OBSOLETE attribute type.  This takes
+   * two arguments, which are the name or OID of the object class and the name
+   * or OID of the optional attribute type.
+   */
+  public static final int MSGID_SCHEMA_MODIFY_OC_OBSOLETE_OPTIONAL_ATTR =
+       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 278;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add a name form whose structural object class is marked OBSOLETE.  This
+   * takes two arguments, which are the name or OID of the name form and the
+   * name or OID of the structural object class.
+   */
+  public static final int MSGID_SCHEMA_MODIFY_NF_OC_OBSOLETE =
+       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 279;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add a name form that requires an attribute type which is marked OBSOLETE.
+   * This takes two arguments, which are the name or OID of the name form and
+   * the name or OID of the required attribute type.
+   */
+  public static final int MSGID_SCHEMA_MODIFY_NF_OBSOLETE_REQUIRED_ATTR =
+       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 280;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add a name form that allows an attribute type which is marked OBSOLETE.
+   * This takes two arguments, which are the name or OID of the name form and
+   * the  name or OID of the optional attribute type.
+   */
+  public static final int MSGID_SCHEMA_MODIFY_NF_OBSOLETE_OPTIONAL_ATTR =
+       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 281;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add a DIT content rule whose structural object class is marked OBSOLETE.
+   * This takes two arguments, which are the name of the DIT content rule and
+   * the name or OID of the structural object class.
+   */
+  public static final int MSGID_SCHEMA_MODIFY_DCR_STRUCTURAL_OC_OBSOLETE =
+       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 282;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add a DIT content rule with an auxiliary object class that is not declared
+   * auxiliary.  This takes two arguments, which are the name of the DIT content
+   * rule and the name or OID of the object class.
+   */
+  public static final int MSGID_SCHEMA_MODIFY_DCR_OC_NOT_AUXILIARY =
+       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 283;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add a DIT content rule with an AUXILIARY object class that is marked
+   * OBSOLETE.  This takes two arguments, which are the name of the DIT content
+   * rule and the name or OID of the auxiliary object class.
+   */
+  public static final int MSGID_SCHEMA_MODIFY_DCR_AUXILIARY_OC_OBSOLETE =
+       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 284;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add a DIT content rule that requires an attribute type that is marked
+   * OBSOLETE.  This takes two arguments, which are the name of the DIT content
+   * rule and the name or OID of the attribute type.
+   */
+  public static final int MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_REQUIRED_ATTR =
+       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 285;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add a DIT content rule that allows an attribute type that is marked
+   * OBSOLETE.  This takes two arguments, which are the name of the DIT content
+   * rule and the name or OID of the attribute type.
+   */
+  public static final int MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_OPTIONAL_ATTR =
+       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 286;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add a DIT content rule that prohibits an attribute type that is marked
+   * OBSOLETE.  This takes two arguments, which are the name of the DIT content
+   * rule and the name or OID of the attribute type.
+   */
+  public static final int MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_PROHIBITED_ATTR =
+       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 287;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add a DIT structure rule whose associated name form is marked OBSOLETE.
+   * This takes two arguments, which are the name or rule ID of the DIT
+   * structure rule and the name or OID of the name form.
+   */
+  public static final int MSGID_SCHEMA_MODIFY_DSR_OBSOLETE_NAME_FORM =
+       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 288;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add a DIT structure rule with a superior rule that is marked OBSOLETE.
+   * This takes two arguments, which are the name or rule ID of the DIT
+   * structure rule and the name or rule ID of the superior rule.
+   */
+  public static final int MSGID_SCHEMA_MODIFY_DSR_OBSOLETE_SUPERIOR_RULE =
+       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 289;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add a matching rule use with a matching rule that is marked OBSOLETE.  This
+   * takes two arguments, which are the name of the matching rule use and the
+   * name or OID of the matching rule.
+   */
+  public static final int MSGID_SCHEMA_MODIFY_MRU_OBSOLETE_MR =
+       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 290;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add a matching rule use with an attribute type that is marked OBSOLETE.
+   * This takes two arguments, which are the name of the matching rule use and
+   * the name or OID of the attribute type.
+   */
+  public static final int MSGID_SCHEMA_MODIFY_MRU_OBSOLETE_ATTR =
+       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 291;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add a DIT content rule with an auxiliary object class that is declared
+   * OBSOLETE.  This takes two arguments, which are the name of the DIT content
+   * rule and the name or OID of the object class.
+   */
+  public static final int MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_AUXILIARY_OC =
+       CATEGORY_MASK_BACKEND | SEVERITY_MASK_MILD_ERROR | 292;
+
+
+
+  /**
    * Associates a set of generic messages with the message IDs defined in this
    * class.
    */
@@ -3492,6 +3701,76 @@
     registerMessage(MSGID_SCHEMA_MODIFY_REMOVE_NO_SUCH_MR_USE,
                     "Unable to remove matching rule use %s from the server " +
                     "schema because no such matching rule use is defined.");
+    registerMessage(MSGID_SCHEMA_MODIFY_OBSOLETE_SUPERIOR_ATTRIBUTE_TYPE,
+                    "Unable to add attribute type %s because the superior " +
+                    "type %s is marked as OBSOLETE in the server schema.");
+    registerMessage(MSGID_SCHEMA_MODIFY_ATTRTYPE_OBSOLETE_MR,
+                    "Unable to add attribute type %s because the associated " +
+                    "matching rule %s is marked as OBSOLETE in the server " +
+                    "schema.");
+    registerMessage(MSGID_SCHEMA_MODIFY_OBSOLETE_SUPERIOR_OBJECTCLASS,
+                    "Unable to add object class %s because the superior " +
+                    "class %s is marked as OBSOLETE in the server schema.");
+    registerMessage(MSGID_SCHEMA_MODIFY_OC_OBSOLETE_REQUIRED_ATTR,
+                    "Unable to add object class %s because required " +
+                    "attribute %s is marked as OBSOLETE in the server schema.");
+    registerMessage(MSGID_SCHEMA_MODIFY_OC_OBSOLETE_OPTIONAL_ATTR,
+                    "Unable to add object class %s because optional " +
+                    "attribute %s is marked as OBSOLETE in the server schema.");
+    registerMessage(MSGID_SCHEMA_MODIFY_NF_OC_OBSOLETE,
+                    "Unable to add name form %s because its structural " +
+                    "object class %s is marked as OBSOLETE in the server " +
+                    "schema.");
+    registerMessage(MSGID_SCHEMA_MODIFY_NF_OBSOLETE_REQUIRED_ATTR,
+                    "Unable to add name form %s because it requires " +
+                    "attribute type %s which is marked as OBSOLETE in the " +
+                    "server schema.");
+    registerMessage(MSGID_SCHEMA_MODIFY_NF_OBSOLETE_OPTIONAL_ATTR,
+                    "Unable to add name form %s because it allows " +
+                    "attribute type %s which is marked as OBSOLETE in the " +
+                    "server schema.");
+    registerMessage(MSGID_SCHEMA_MODIFY_DCR_STRUCTURAL_OC_OBSOLETE,
+                    "Unable to add DIT content rule %s because its " +
+                    "structural object class %s is marked as OBSOLETE in " +
+                    "the server schema.");
+    registerMessage(MSGID_SCHEMA_MODIFY_DCR_OC_NOT_AUXILIARY,
+                    "Unable to add DIT content rule %s because it references " +
+                    "auxiliary object class %s which is defined in the " +
+                    "server schema but is not an auxiliary class.");
+    registerMessage(MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_AUXILIARY_OC,
+                    "Unable to add DIT content rule %s because it references " +
+                    "auxiliary object class %s which is marked as OBSOLETE " +
+                    "in the server schema.");
+    registerMessage(MSGID_SCHEMA_MODIFY_DCR_AUXILIARY_OC_OBSOLETE,
+                    "Unable to add DIT content rule %s because it allows " +
+                    "auxiliary object class %s which is marked as OBSOLETE " +
+                    "in the server schema.");
+    registerMessage(MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_REQUIRED_ATTR,
+                    "Unable to add DIT content rule %s because it requires " +
+                    "attribute type %s which is marked as OBSOLETE in the " +
+                    "server schema.");
+    registerMessage(MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_OPTIONAL_ATTR,
+                    "Unable to add DIT content rule %s because it allows " +
+                    "attribute type %s which is marked as OBSOLETE in the " +
+                    "server schema.");
+    registerMessage(MSGID_SCHEMA_MODIFY_DCR_OBSOLETE_PROHIBITED_ATTR,
+                    "Unable to add DIT content rule %s because it prohibits " +
+                    "attribute type %s which is marked as OBSOLETE in the " +
+                    "server schema.");
+    registerMessage(MSGID_SCHEMA_MODIFY_DSR_OBSOLETE_NAME_FORM,
+                    "Unable to add DIT structure rule %s because its name " +
+                    "form %s is marked OBSOLETE in the server schema.");
+    registerMessage(MSGID_SCHEMA_MODIFY_DSR_OBSOLETE_SUPERIOR_RULE,
+                    "Unable to add DIT structure rule %s because it " +
+                    "references superior rule %s whihc is marked as OBSOLETE " +
+                    "in the server schema.");
+    registerMessage(MSGID_SCHEMA_MODIFY_MRU_OBSOLETE_MR,
+                    "Unable to add matching rule use %s because its matching " +
+                    "rule %s is marked OBSOLETE in the server schema.");
+    registerMessage(MSGID_SCHEMA_MODIFY_MRU_OBSOLETE_ATTR,
+                    "Unable to add matching rule use %s because it " +
+                    "references attribute type %s which is marked as " +
+                    "OBSOLETE in the server schema.");
 
 
     registerMessage(MSGID_SCHEMA_RESTORE_NO_SUCH_BACKUP,
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java
index b1f6b31..67f2b53 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java
@@ -2193,9 +2193,8 @@
   /**
    * The message ID for the message that will be used if an entry could not be
    * checked against a DIT structure rule because the server was unable to
-   * obtain a read lock on the parent entry.  This takes three arguments, which
-   * are the DN of the entry, the name of the DIT structure rule, and the DN of
-   * the parent entry.
+   * obtain a read lock on the parent entry.  This takes two arguments, which
+   * are the DN of the entry and the DN of the parent entry.
    */
   public static final int MSGID_ENTRY_SCHEMA_DSR_COULD_NOT_LOCK_PARENT =
        CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 212;
@@ -2205,9 +2204,8 @@
   /**
    * The message ID for the message that will be used if an entry could not be
    * checked against a DIT structure rule because the server was unable to
-   * retrieve its parent entry.  This takes three arguments, which are the DN of
-   * the entry, the name of the DIT structure rule, and the DN of the parent
-   * entry.
+   * retrieve its parent entry.  This takes two arguments, which are the DN of
+   * the entry and the DN of the parent entry.
    */
   public static final int MSGID_ENTRY_SCHEMA_DSR_NO_PARENT_ENTRY =
        CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 213;
@@ -2217,9 +2215,8 @@
   /**
    * The message ID for the message that will be used if an entry could not be
    * checked against a DIT structure rule because its parent entry did not
-   * contain a single structural objectclass.  This takes three arguments, which
-   * are the DN of the entry, the name of the DIT structure rule, and the DN of
-   * the parent entry.
+   * contain a single structural objectclass.  This takes two arguments, which
+   * are the DN of the entry and the DN of the parent entry.
    */
   public static final int MSGID_ENTRY_SCHEMA_DSR_NO_PARENT_OC =
        CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 214;
@@ -6077,6 +6074,82 @@
 
 
   /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add an entry with an attribute type that is marked OBSOLETE.  This takes
+   * two arguments, which are the DN of the entry and the name of the attribute
+   * type.
+   */
+  public static final int MSGID_ADD_ATTR_IS_OBSOLETE =
+       CATEGORY_MASK_CORE | SEVERITY_MASK_SEVERE_WARNING | 581;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add an entry with an objectclass that is marked OBSOLETE.  This takes two
+   * arguments, which are the DN of the entry and the name of the objectclass.
+   */
+  public static final int MSGID_ADD_OC_IS_OBSOLETE =
+       CATEGORY_MASK_CORE | SEVERITY_MASK_SEVERE_WARNING | 582;
+
+
+
+  /**
+   * The message ID for the message that will be used if an entry cannot be
+   * modified because one of the targeted attributes was marked OBSOLETE.  This
+   * takes two arguments, which are the DN of the target entry and the name of
+   * the attribute.
+   */
+  public static final int MSGID_MODIFY_ATTR_IS_OBSOLETE =
+       CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 583;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attempt is made to
+   * add an OBSOLETE objectclass to an entry.  This takes two arguments, which
+   * are the name of the objectclass and the DN of the entry.
+   */
+  public static final int MSGID_ENTRY_ADD_OBSOLETE_OC =
+       CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 584;
+
+
+
+  /**
+   * The message ID for the response message that will be used if a modify DN
+   * operation fails because the new RDN contains an attribute type which is
+   * marked OBSOLETE in the server schema.  This takes two arguments, which are
+   * the DN of the current entry and the name or OID of the obsolete attribute
+   * type.
+   */
+  public static final int MSGID_MODDN_NEWRDN_ATTR_IS_OBSOLETE =
+       CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 585;
+
+
+
+  /**
+   * The message ID for the message that will be used if there was no DIT
+   * structure rule associated with an entry, but there was a DIT structure rule
+   * for its parent.  This takes two arguments, which are the DN of the entry
+   * and the DN of the parent entry.
+   */
+  public static final int MSGID_ENTRY_SCHEMA_VIOLATES_PARENT_DSR =
+       CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 586;
+
+
+
+  /**
+   * The message ID for the message that will be used if an unexpected error
+   * occurs while attempting to evaluate a DIT structure rule for an entry's
+   * parent.  This takes two arguments, which are the DN of the entry and a
+   * string representation of the exception that was caught.
+   */
+  public static final int MSGID_ENTRY_SCHEMA_COULD_NOT_CHECK_PARENT_DSR =
+       CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 587;
+
+
+
+  /**
    * Associates a set of generic messages with the message IDs defined
    * in this class.
    */
@@ -6509,19 +6582,24 @@
                     "%s that is not allowed by DIT content rule %s.");
     registerMessage(MSGID_ENTRY_SCHEMA_DSR_COULD_NOT_LOCK_PARENT,
                     "The Directory Server was unable to evaluate entry %s to " +
-                    "determine whether it was compliant with DIT structure " +
-                    "rule %s because it was unable to obtain a read lock " +
-                    "on parent entry %s.");
+                    "determine whether it was compliant with the DIT " +
+                    "structure rule configuration because it was unable to " +
+                    "obtain a read lock on parent entry %s.");
     registerMessage(MSGID_ENTRY_SCHEMA_DSR_NO_PARENT_ENTRY,
                     "The Directory Server was unable to evaluate entry %s to " +
-                    "determine whether it was compliant with DIT structure " +
-                    "rule %s because parent entry %s either does not exist " +
-                    "or could not be retrieved.");
+                    "determine whether it was compliant with the DIT " +
+                    "structure rule configuration because parent entry %s " +
+                    "either does not exist or could not be retrieved.");
     registerMessage(MSGID_ENTRY_SCHEMA_DSR_NO_PARENT_OC,
                     "The Directory Server was unable to evaluate entry %s to " +
-                    "determine whether it was compliant with DIT structure " +
-                    "rule %s because the parent entry %s does not appear to " +
-                    "contain a valid structural objectclass.");
+                    "determine whether it was compliant with the DIT " +
+                    "rule configuration because the parent entry %s does not " +
+                    "appear to contain a valid structural objectclass.");
+    registerMessage(MSGID_ENTRY_SCHEMA_VIOLATES_PARENT_DSR,
+                    "Entry %s is invalid according to the server schema " +
+                    "because there is no DIT structure rule that applies " +
+                    "to that entry, but there is a DIT structure rule for " +
+                    "the parent entry %s.");
     registerMessage(MSGID_ENTRY_SCHEMA_DSR_DISALLOWED_SUPERIOR_OC,
                     "Entry %s violates the Directory Server schema " +
                     "configuration because DIT structure rule %s does not " +
@@ -6530,6 +6608,10 @@
     registerMessage(MSGID_ENTRY_SCHEMA_COULD_NOT_CHECK_DSR,
                     "An unexpected error occurred while attempting to check " +
                     "entry %s against DIT structure rule %s:  %s.");
+    registerMessage(MSGID_ENTRY_SCHEMA_COULD_NOT_CHECK_PARENT_DSR,
+                    "An unexpected error occurred while attempting to " +
+                    "perform DIT structure rule processing for the parent of " +
+                    "entry %s:  %s.");
     registerMessage(MSGID_ENTRY_SET_UNKNOWN_OC,
                     "Objectclass %s cannot be used in entry %s because that " +
                     "class is not defined in the Directory Server schema.");
@@ -6539,6 +6621,9 @@
     registerMessage(MSGID_ENTRY_ADD_DUPLICATE_OC,
                     "Objectclass %s is already present in entry %s and " +
                     "cannot be added a second time.");
+    registerMessage(MSGID_ENTRY_ADD_OBSOLETE_OC,
+                    "Objectclass %s added to entry %s is marked OBSOLETE in " +
+                    "the server schema.");
     registerMessage(MSGID_ENTRY_DUPLICATE_VALUES,
                     "Unable to add one or more values to attribute %s " +
                     "because at least one of the values already exists.");
@@ -6780,6 +6865,14 @@
                     "Entry \"%s\" contains an value \"%s\" for attribute %s " +
                     "that is invalid according to the syntax for that " +
                     "attribute:  %s.");
+    registerMessage(MSGID_ADD_ATTR_IS_OBSOLETE,
+                    "Entry \"%s\" cannot be added because it contains " +
+                    "attribute type %s which is declared OBSOLETE in the " +
+                    "server schema.");
+    registerMessage(MSGID_ADD_OC_IS_OBSOLETE,
+                    "Entry \"%s\" cannot be added because it contains " +
+                    "objectclass %s which is declared OBSOLETE in the server " +
+                    "schema.");
     registerMessage(MSGID_ADD_INVALID_PWPOLICY_DN_SYNTAX,
                     "Entry \"%s\" cannot be added because it contains an " +
                     "invalid password policy subentry DN:  %s.");
@@ -7115,6 +7208,10 @@
                     "The modify DN operation for entry %s cannot be " +
                     "performed because the change would have violated the " +
                     "server schema:  %s.");
+    registerMessage(MSGID_MODDN_NEWRDN_ATTR_IS_OBSOLETE,
+                    "The modify DN operation for entry %s cannot be " +
+                    "performed because the new RDN includes attribute type " +
+                    "%s which is declared OBSOLETE in the server schema.");
     registerMessage(MSGID_MODDN_PREOP_INCREMENT_NO_ATTR,
                     "The modify DN operation for entry %s cannot be " +
                     "performed because a pre-operation plugin attempted to " +
@@ -7194,6 +7291,10 @@
                     "Entry %s cannot be modified because the modification " +
                     "attempted to update attribute %s which is defined as " +
                     "NO-USER-MODIFICATION in the server schema.");
+    registerMessage(MSGID_MODIFY_ATTR_IS_OBSOLETE,
+                    "Entry %s cannot be modified because the modification " +
+                    "attempted to set one or more new values for attribute " +
+                    "%s which is marked OBSOLETE in the server schema.");
     registerMessage(MSGID_MODIFY_PASSWORDS_CANNOT_HAVE_OPTIONS,
                     "Attributes used to hold user passwords are not allowed " +
                     "to have any attribute options.");
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/SchemaMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/SchemaMessages.java
index 683722e..ff00b56 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/SchemaMessages.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/SchemaMessages.java
@@ -2964,6 +2964,115 @@
        MSGID_ATTR_SYNTAX_ATTRSYNTAX_INVALID_EXTENSION =
             CATEGORY_MASK_SCHEMA | SEVERITY_MASK_MILD_ERROR | 265;
 
+
+
+  /**
+   * The message ID for the message that will be used if an objectclass has
+   * an invalid superior type.  This takes four arguments, which are the OID of
+   * the objectclass, the objectclass type for that class, the objectclass type
+   * type of the superior class, and the name or OID of the superior class.
+   */
+  public static final int MSGID_ATTR_SYNTAX_OBJECTCLASS_INVALID_SUPERIOR_TYPE =
+       CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_WARNING | 266;
+
+
+
+  /**
+   * The message ID for the message that will be used if a structural
+   * objectclass does not have a superior chain that includes the "top"
+   * objectclass.  This takes a single argument, which is the OID for that
+   * objectclass.
+   */
+  public static final int
+       MSGID_ATTR_SYNTAX_OBJECTCLASS_STRUCTURAL_SUPERIOR_NOT_TOP =
+            CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_WARNING | 267;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attribute type
+   * has a usage that is not the same as the usage of its superior type.  This
+   * takes three arguments, which is the OID of the attribute type, its
+   * attribute usage, and the name or OID of the superior type.
+   */
+  public static final int MSGID_ATTR_SYNTAX_ATTRTYPE_INVALID_SUPERIOR_USAGE =
+       CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_WARNING | 268;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attribute type
+   * is defined as collective but the superior type is not collective.  This
+   * takes two arguments, which are the OID of the attribute type and the name
+   * or OID of the superior type.
+   */
+  public static final int
+       MSGID_ATTR_SYNTAX_ATTRTYPE_COLLECTIVE_FROM_NONCOLLECTIVE =
+            CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_WARNING | 269;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attribute type
+   * is not defined as collective but the superior type is collective.  This
+   * takes two arguments, which are the OID of the attribute type and the name
+   * or OID of the superior type.
+   */
+  public static final int
+       MSGID_ATTR_SYNTAX_ATTRTYPE_NONCOLLECTIVE_FROM_COLLECTIVE =
+            CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_WARNING | 270;
+
+
+
+  /**
+   * The message ID for the message that will be used if a DIT content rule
+   * description value is invalid because it prohibits an attribute type that is
+   * required by the rule's structural object class.  This takes three
+   * arguments, which are the definition of the DIT content rule, the name or
+   * OID of the prohibited attribute type, and the name or OID of the structural
+   * object class that requires it.
+   */
+  public static final int
+       MSGID_ATTR_SYNTAX_DCR_PROHIBITED_REQUIRED_BY_STRUCTURAL =
+            CATEGORY_MASK_SCHEMA | SEVERITY_MASK_MILD_ERROR | 271;
+
+
+
+  /**
+   * The message ID for the message that will be used if a DIT content rule
+   * description value is invalid because it prohibits an attribute type that is
+   * required by one the rule's allowed auxiliary object classes.  This takes
+   * three arguments, which are the definition of the DIT content rule, the name
+   * or OID of the prohibited attribute type, and the name or OID of the
+   * auxiliary object class that requires it.
+   */
+  public static final int
+       MSGID_ATTR_SYNTAX_DCR_PROHIBITED_REQUIRED_BY_AUXILIARY =
+            CATEGORY_MASK_SCHEMA | SEVERITY_MASK_MILD_ERROR | 272;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attribute type
+   * is defined as collective but has a usage other than userApplications.  This
+   * takes a single argument, which is the OID of the attribute type.
+   */
+  public static final int MSGID_ATTR_SYNTAX_ATTRTYPE_COLLECTIVE_IS_OPERATIONAL =
+       CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_WARNING | 273;
+
+
+
+  /**
+   * The message ID for the message that will be used if an attribute type
+   * is defined as NO-USER-MODIFICATION but does not have an operational usage.
+   * This takes a single argument, which is the OID of the attribute type.
+   */
+  public static final int
+       MSGID_ATTR_SYNTAX_ATTRTYPE_NO_USER_MOD_NOT_OPERATIONAL =
+            CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_WARNING | 274;
+
+
+
   /**
    * Associates a set of generic messages with the message IDs defined in this
    * class.
@@ -3244,46 +3353,60 @@
                     "The definition for the attribute type with OID %s " +
                     "declared a superior type with an OID of %s.  No " +
                     "attribute type with this OID exists in the server " +
-                    "schema, so the Directory Server will use a generic " +
-                    "attribute type as the superior type for this definition.");
+                    "schema.");
     registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_APPROXIMATE_MR,
                     "The definition for the attribute type with OID %s " +
                     "declared that approximate matching should be performed " +
                     "using the matching rule \"%s\".  No such approximate " +
                     "matching rule is configured for use in the Directory " +
-                    "Server, so the default approximate matching rule for " +
-                    "the attribute's syntax will be used.");
+                    "Server.");
     registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_EQUALITY_MR,
                     "The definition for the attribute type with OID %s " +
                     "declared that equality matching should be performed " +
                     "using the matching rule \"%s\".  No such equality " +
                     "matching rule is configured for use in the Directory " +
-                    "Server, so the default equality matching rule for the " +
-                    "attribute's syntax will be used.");
+                    "Server.");
     registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_ORDERING_MR,
                     "The definition for the attribute type with OID %s " +
                     "declared that ordering matching should be performed " +
                     "using the matching rule \"%s\".  No such ordering " +
                     "matching rule is configured for use in the Directory " +
-                    "Server, so the default ordering matching rule for the " +
-                    "attribute's syntax will be used.");
+                    "Server.");
     registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_SUBSTRING_MR,
                     "The definition for the attribute type with OID %s " +
                     "declared that substring matching should be performed " +
                     "using the matching rule \"%s\".  No such substring " +
                     "matching rule is configured for use in the Directory " +
-                    "Server, so the default substring matching rule for the " +
-                    "attribute's syntax will be used.");
+                    "Server.");
     registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_SYNTAX,
                     "The definition for the attribute type with OID %s " +
                     "declared that it should have a syntax with OID %s.  No " +
                     "such syntax is configured for use in the Directory " +
-                    "Server, so the default attribute syntax will be used.");
+                    "Server.");
     registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_INVALID_ATTRIBUTE_USAGE,
                     "The definition for the attribute type with OID %s " +
                     "declared that it should have an attribute usage of " +
-                    "%s.  This is an invalid usage, so the default usage of " +
-                    "%s will be used.");
+                    "%s.  This is an invalid usage.");
+    registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_INVALID_SUPERIOR_USAGE,
+                    "The definition for attribute type %s is invalid because " +
+                    "its attribute usage %s is not the same as the usage for " +
+                    "its superior type %s.");
+    registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_COLLECTIVE_FROM_NONCOLLECTIVE,
+                    "The definition for attribute type %s is invalid because " +
+                    "it is defined as a collective type but the superior " +
+                    "type %s is not collective.");
+    registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_NONCOLLECTIVE_FROM_COLLECTIVE,
+                    "The definition for attribute type %s is invalid because " +
+                    "it is not defined as a collective type but the superior " +
+                    "type %s is collective.");
+    registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_COLLECTIVE_IS_OPERATIONAL,
+                    "The definition for attribute type %s is invalid because " +
+                    "it is declared COLLECTIVE but does not have a usage " +
+                    "of userApplications.");
+    registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_NO_USER_MOD_NOT_OPERATIONAL,
+                    "The definition for attribute type %s is invalid because " +
+                    "it is declared NO-USER-MODIFICATION but does not have " +
+                    "an operational usage.");
     registerMessage(MSGID_ATTR_SYNTAX_ATTRTYPE_EXPECTED_QUOTE_AT_POS,
                     "The provided value \"%s\" could not be parsed as an " +
                     "attribute type description because a single quote was " +
@@ -3333,9 +3456,7 @@
     registerMessage(MSGID_ATTR_SYNTAX_OBJECTCLASS_UNKNOWN_SUPERIOR_CLASS,
                     "The definition for the objectclass with OID %s declared " +
                     "a superior objectclass with an OID of %s.  No " +
-                    "objectclass with this OID exists in the server schema, " +
-                    "so the Directory Server will assume it to be an empty " +
-                    "objectclass with no required or optional attributes.");
+                    "objectclass with this OID exists in the server schema.");
     registerMessage(MSGID_ATTR_SYNTAX_OBJECTCLASS_EXPECTED_QUOTE_AT_POS,
                     "The provided value \"%s\" could not be parsed as an " +
                     "objectclass description because a single quote was " +
@@ -3345,14 +3466,20 @@
                     "The definition for the objectclass with OID %s declared " +
                     "that it should include required attribute \"%s\".  No " +
                     "attribute type matching this name or OID exists in the " +
-                    "server schema, so a default attribute type with the " +
-                    "directory string syntax will be used.");
+                    "server schema.");
     registerMessage(MSGID_ATTR_SYNTAX_OBJECTCLASS_UNKNOWN_OPTIONAL_ATTR,
                     "The definition for the objectclass with OID %s declared " +
                     "that it should include optional attribute \"%s\".  No " +
                     "attribute type matching this name or OID exists in the " +
-                    "server schema, so a default attribute type with the " +
-                    "directory string syntax will be used.");
+                    "server schema.");
+    registerMessage(MSGID_ATTR_SYNTAX_OBJECTCLASS_INVALID_SUPERIOR_TYPE,
+                    "The definition for objectclass %s is invalid because it " +
+                    "has an objectclass type of %s but this is incompatible " +
+                    "with the objectclass type %s for the superior class %s.");
+    registerMessage(MSGID_ATTR_SYNTAX_OBJECTCLASS_STRUCTURAL_SUPERIOR_NOT_TOP,
+                    "The definition for objectclass %s is invalid because " +
+                    "it is defined as a structural class but its superior " +
+                    "chain does not include the \"top\" objectclass.");
 
 
     registerMessage(MSGID_ATTR_SYNTAX_IA5_ILLEGAL_CHARACTER,
@@ -3557,8 +3684,7 @@
     registerMessage(MSGID_ATTR_SYNTAX_DCR_UNKNOWN_STRUCTURAL_CLASS,
                     "The DIT content rule \"%s\" is associated with a " +
                     "structural objectclass %s that is not defined in the " +
-                    "server schema.  A default objectclass will be created " +
-                    "with this OID.");
+                    "server schema.");
     registerMessage(MSGID_ATTR_SYNTAX_DCR_STRUCTURAL_CLASS_NOT_STRUCTURAL,
                     "The DIT content rule \"%s\" is associated with the " +
                     "objectclass with OID %s (%s).  This objectclass exists " +
@@ -3575,8 +3701,7 @@
     registerMessage(MSGID_ATTR_SYNTAX_DCR_UNKNOWN_AUXILIARY_CLASS,
                     "The DIT content rule \"%s\" is associated with an " +
                     "auxiliary objectclass %s that is not defined in the " +
-                    "server schema.  A default objectclass will be created " +
-                    "with this OID.");
+                    "server schema.");
     registerMessage(MSGID_ATTR_SYNTAX_DCR_AUXILIARY_CLASS_NOT_AUXILIARY,
                     "The DIT content rule \"%s\" is associated with an " +
                     "auxiliary objectclass %s.  This objectclass exists " +
@@ -3585,18 +3710,23 @@
     registerMessage(MSGID_ATTR_SYNTAX_DCR_UNKNOWN_REQUIRED_ATTR,
                     "The DIT content rule \"%s\" is associated with a " +
                     "required attribute type %s that is not defined in the " +
-                    "server schema.  A default attribute type will be " +
-                    "created with this name.");
+                    "server schema.");
     registerMessage(MSGID_ATTR_SYNTAX_DCR_UNKNOWN_OPTIONAL_ATTR,
                     "The DIT content rule \"%s\" is associated with an " +
                     "optional attribute type %s that is not defined in the " +
-                    "server schema.  A default attribute type will be " +
-                    "created with this name.");
+                    "server schema.");
     registerMessage(MSGID_ATTR_SYNTAX_DCR_UNKNOWN_PROHIBITED_ATTR,
                     "The DIT content rule \"%s\" is associated with a " +
                     "prohibited attribute type %s that is not defined in the " +
-                    "server schema.  A default attribute type will be " +
-                    "created with this name.");
+                    "server schema.");
+    registerMessage(MSGID_ATTR_SYNTAX_DCR_PROHIBITED_REQUIRED_BY_STRUCTURAL,
+                    "The DIT content rule \"%s\" is not valid because it " +
+                    "prohibits the use of attribute type %s which is " +
+                    "required by the associated structural object class %s.");
+    registerMessage(MSGID_ATTR_SYNTAX_DCR_PROHIBITED_REQUIRED_BY_AUXILIARY,
+                    "The DIT content rule \"%s\" is not valid because it " +
+                    "prohibits the use of attribute type %s which is " +
+                    "required by the associated auxiliary object class %s.");
     registerMessage(MSGID_ATTR_SYNTAX_DCR_EXPECTED_QUOTE_AT_POS,
                     "The provided value \"%s\" could not be parsed as a DIT " +
                     "content rule description because a single quote was " +
@@ -3641,8 +3771,7 @@
     registerMessage(MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_STRUCTURAL_CLASS,
                     "The name form description \"%s\" is associated with a " +
                     "structural objectclass %s that is not defined in the " +
-                    "server schema.  A default objectclass will be created " +
-                    "with this OID.");
+                    "server schema.");
     registerMessage(MSGID_ATTR_SYNTAX_NAME_FORM_STRUCTURAL_CLASS_NOT_STRUCTURAL,
                     "The name form description \"%s\" is associated with the " +
                     "objectclass with OID %s (%s).  This objectclass exists " +
@@ -3652,14 +3781,12 @@
                     "The definition for the name form with OID %s declared " +
                     "that it should include required attribute \"%s\".  No " +
                     "attribute type matching this name or OID exists in the " +
-                    "server schema, so a default attribute type with the " +
-                    "directory string syntax will be used.");
+                    "server schema.");
     registerMessage(MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_OPTIONAL_ATTR,
                     "The definition for the name form with OID %s declared " +
                     "that it should include optional attribute \"%s\".  No " +
                     "attribute type matching this name or OID exists in the " +
-                    "server schema, so a default attribute type with the " +
-                    "directory string syntax will be used.");
+                    "server schema.");
     registerMessage(MSGID_ATTR_SYNTAX_NAME_FORM_NO_STRUCTURAL_CLASS,
                     "The provided value \"%s\" could not be parsed as a name " +
                     "form description because it does not specify the " +
diff --git a/opendj-sdk/opends/src/server/org/opends/server/schema/AttributeTypeSyntax.java b/opendj-sdk/opends/src/server/org/opends/server/schema/AttributeTypeSyntax.java
index 6ed5126..387baf6 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/schema/AttributeTypeSyntax.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/schema/AttributeTypeSyntax.java
@@ -45,13 +45,11 @@
 import org.opends.server.types.AttributeUsage;
 import org.opends.server.types.ByteString;
 import org.opends.server.types.DirectoryException;
-import org.opends.server.types.ErrorLogCategory;
-import org.opends.server.types.ErrorLogSeverity;
+import org.opends.server.types.InitializationException;
 import org.opends.server.types.ResultCode;
 import org.opends.server.types.Schema;
 
 import static org.opends.server.loggers.Debug.*;
-import static org.opends.server.loggers.Error.*;
 import static org.opends.server.messages.MessageHandler.*;
 import static org.opends.server.messages.SchemaMessages.*;
 import static org.opends.server.schema.SchemaConstants.*;
@@ -103,17 +101,10 @@
 
 
   /**
-   * Initializes this attribute syntax based on the information in the provided
-   * configuration entry.
-   *
-   * @param  configEntry  The configuration entry that contains the information
-   *                      to use to initialize this attribute syntax.
-   *
-   * @throws  ConfigException  If an unrecoverable problem arises in the
-   *                           process of performing the initialization.
+   * {@inheritDoc}
    */
   public void initializeSyntax(ConfigEntry configEntry)
-         throws ConfigException
+         throws ConfigException, InitializationException
   {
     assert debugEnter(CLASS_NAME, "initializeSyntax",
                       String.valueOf(configEntry));
@@ -122,36 +113,37 @@
          DirectoryServer.getEqualityMatchingRule(EMR_CASE_IGNORE_OID);
     if (defaultEqualityMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE,
-               EMR_CASE_IGNORE_OID, SYNTAX_ATTRIBUTE_TYPE_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE;
+      String message = getMessage(msgID, EMR_CASE_IGNORE_OID,
+                                  SYNTAX_ATTRIBUTE_TYPE_NAME);
+      throw new InitializationException(msgID, message);
     }
 
     defaultOrderingMatchingRule =
          DirectoryServer.getOrderingMatchingRule(OMR_CASE_IGNORE_OID);
     if (defaultOrderingMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE,
-               OMR_CASE_IGNORE_OID, SYNTAX_ATTRIBUTE_TYPE_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE;
+      String message = getMessage(msgID, OMR_CASE_IGNORE_OID,
+                                  SYNTAX_ATTRIBUTE_TYPE_NAME);
+      throw new InitializationException(msgID, message);
     }
 
     defaultSubstringMatchingRule =
          DirectoryServer.getSubstringMatchingRule(SMR_CASE_IGNORE_OID);
     if (defaultSubstringMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE,
-               SMR_CASE_IGNORE_OID, SYNTAX_ATTRIBUTE_TYPE_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE;
+      String message = getMessage(msgID, SMR_CASE_IGNORE_OID,
+                                  SYNTAX_ATTRIBUTE_TYPE_NAME);
+      throw new InitializationException(msgID, message);
     }
   }
 
 
 
   /**
-   * Retrieves the common name for this attribute syntax.
-   *
-   * @return  The common name for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getSyntaxName()
   {
@@ -163,9 +155,7 @@
 
 
   /**
-   * Retrieves the OID for this attribute syntax.
-   *
-   * @return  The OID for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getOID()
   {
@@ -177,9 +167,7 @@
 
 
   /**
-   * Retrieves a description for this attribute syntax.
-   *
-   * @return  A description for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getDescription()
   {
@@ -191,12 +179,7 @@
 
 
   /**
-   * Retrieves the default equality matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default equality matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if equality
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public EqualityMatchingRule getEqualityMatchingRule()
   {
@@ -208,12 +191,7 @@
 
 
   /**
-   * Retrieves the default ordering matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default ordering matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if ordering
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public OrderingMatchingRule getOrderingMatchingRule()
   {
@@ -225,12 +203,7 @@
 
 
   /**
-   * Retrieves the default substring matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default substring matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if substring
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public SubstringMatchingRule getSubstringMatchingRule()
   {
@@ -242,12 +215,7 @@
 
 
   /**
-   * Retrieves the default approximate matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default approximate matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if approximate
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public ApproximateMatchingRule getApproximateMatchingRule()
   {
@@ -260,16 +228,7 @@
 
 
   /**
-   * Indicates whether the provided value is acceptable for use in an attribute
-   * with this syntax.  If it is not, then the reason may be appended to the
-   * provided buffer.
-   *
-   * @param  value          The value for which to make the determination.
-   * @param  invalidReason  The buffer to which the invalid reason should be
-   *                        appended.
-   *
-   * @return  <CODE>true</CODE> if the provided value is acceptable for use with
-   *          this syntax, or <CODE>false</CODE> if not.
+   * {@inheritDoc}
    */
   public boolean valueIsAcceptable(ByteString value,
                                    StringBuilder invalidReason)
@@ -282,7 +241,7 @@
     // acceptable.
     try
     {
-      decodeAttributeType(value, DirectoryServer.getSchema());
+      decodeAttributeType(value, DirectoryServer.getSchema(), true);
       return true;
     }
     catch (DirectoryException de)
@@ -303,10 +262,16 @@
    * should not be in order to allow the desired capitalization to be
    * preserved).
    *
-   * @param  value   The ASN.1 octet string containing the value to decode (it
-   *                 does not need to be normalized).
-   * @param  schema  The schema to use to resolve references to other schema
-   *                 elements.
+   * @param  value                 The ASN.1 octet string containing the value
+   *                               to decode (it does not need to be
+   *                               normalized).
+   * @param  schema                The schema to use to resolve references to
+   *                               other schema elements.
+   * @param  allowUnknownElements  Indicates whether to allow values that
+   *                               reference a superior attribute type which are
+   *                               not defined in the server schema. This should
+   *                               only be true when called by
+   *                               {@code valueIsAcceptable}.
    *
    * @return  The decoded attribute type definition.
    *
@@ -314,7 +279,8 @@
    *                              attribute type definition.
    */
   public static AttributeType decodeAttributeType(ByteString value,
-                                                  Schema schema)
+                                                  Schema schema,
+                                                  boolean allowUnknownElements)
          throws DirectoryException
   {
     assert debugEnter(CLASS_NAME, "decodeAttributeType", String.valueOf(value));
@@ -596,17 +562,21 @@
         superiorType = schema.getAttributeType(woidBuffer.toString());
         if (superiorType == null)
         {
-          // This is bad because we don't know what the superior attribute type
-          // is so we can't base this attribute type on it.  Log a message and
-          // just go with the default type.
-          int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_SUPERIOR_TYPE;
-          String message = getMessage(msgID, String.valueOf(oid),
-                                      String.valueOf(woidBuffer));
-          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                   message, msgID);
-
-          superiorType =
-               DirectoryServer.getDefaultAttributeType(woidBuffer.toString());
+          if (allowUnknownElements)
+          {
+            superiorType = DirectoryServer.getDefaultAttributeType(
+                                                woidBuffer.toString());
+          }
+          else
+          {
+            // This is bad because we don't know what the superior attribute
+            // type is so we can't base this attribute type on it.
+            int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_SUPERIOR_TYPE;
+            String message = getMessage(msgID, String.valueOf(oid),
+                                        String.valueOf(woidBuffer));
+            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                         message, msgID);
+          }
         }
 
 
@@ -640,13 +610,12 @@
         if (emr == null)
         {
           // This is bad because we have no idea what the equality matching
-          // rule should be.  Log a message and go with the default matching
-          // rule for the associated syntax.
+          // rule should be.
           int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_EQUALITY_MR;
           String message = getMessage(msgID, String.valueOf(oid),
                                       String.valueOf(woidBuffer));
-          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                   message, msgID);
+          throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                       message, msgID);
         }
         else
         {
@@ -664,13 +633,12 @@
         if (omr == null)
         {
           // This is bad because we have no idea what the ordering matching
-          // rule should be.  Log a message and go with the default matching
-          // rule for the associated syntax.
+          // rule should be.
           int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_ORDERING_MR;
           String message = getMessage(msgID, String.valueOf(oid),
                                       String.valueOf(woidBuffer));
-          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                   message, msgID);
+          throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                       message, msgID);
         }
         else
         {
@@ -688,13 +656,12 @@
         if (smr == null)
         {
           // This is bad because we have no idea what the substring matching
-          // rule should be.  Log a message and go with the default matching
-          // rule for the associated syntax.
+          // rule should be.
           int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_SUBSTRING_MR;
           String message = getMessage(msgID, String.valueOf(oid),
                                       String.valueOf(woidBuffer));
-          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                   message, msgID);
+          throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                       message, msgID);
         }
         else
         {
@@ -794,10 +761,8 @@
           int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_SYNTAX;
           String message = getMessage(msgID, String.valueOf(oid),
                                       String.valueOf(oidBuffer));
-          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                   message, msgID);
-
-          syntax = DirectoryServer.getDefaultAttributeSyntax();
+          throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                       message, msgID);
         }
 
         if (approximateMatchingRule == null)
@@ -878,15 +843,15 @@
         }
         else
         {
-          // This must be an illegal usage.  Log a message and use the default.
+          // This must be an illegal usage.
           attributeUsage = AttributeUsage.USER_APPLICATIONS;
 
           int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_INVALID_ATTRIBUTE_USAGE;
           String message = getMessage(msgID, String.valueOf(oid),
                                       String.valueOf(usageBuffer),
                                       String.valueOf(attributeUsage));
-          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                   message, msgID);
+          throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
+                                       message, msgID);
         }
       }
       else
@@ -911,13 +876,12 @@
       if (amr == null)
       {
         // This is bad because we have no idea what the approximate matching
-        // rule should be.  Log a message and go with the default matching
-        // rule for the associated syntax.
+        // rule should be.
         int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_APPROXIMATE_MR;
         String message = getMessage(msgID, String.valueOf(oid),
                                     String.valueOf(ruleName));
-        logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                 message, msgID);
+        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                     msgID);
       }
       else
       {
@@ -926,6 +890,62 @@
     }
 
 
+    // If there is a superior type, then it must have the same usage as the
+    // subordinate type.  Also, if the superior type is collective, then so must
+    // the subordinate type be collective.
+    if (superiorType != null)
+    {
+      if (superiorType.getUsage() != attributeUsage)
+      {
+        int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_INVALID_SUPERIOR_USAGE;
+        String message = getMessage(msgID, oid, String.valueOf(attributeUsage),
+                                    superiorType.getNameOrOID());
+        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                     msgID);
+      }
+
+      if (superiorType.isCollective() != isCollective)
+      {
+        int msgID;
+        if (isCollective)
+        {
+          msgID = MSGID_ATTR_SYNTAX_ATTRTYPE_COLLECTIVE_FROM_NONCOLLECTIVE;
+        }
+        else
+        {
+          msgID = MSGID_ATTR_SYNTAX_ATTRTYPE_NONCOLLECTIVE_FROM_COLLECTIVE;
+        }
+
+        String message = getMessage(msgID, oid, superiorType.getNameOrOID());
+        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                     msgID);
+      }
+    }
+
+
+    // If the attribute type is COLLECTIVE, then it must have a usage of
+    // userApplications.
+    if (isCollective && (attributeUsage != AttributeUsage.USER_APPLICATIONS))
+    {
+      int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_COLLECTIVE_IS_OPERATIONAL;
+      String message = getMessage(msgID, oid);
+      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                   msgID);
+    }
+
+
+    // If the attribute type is NO-USER-MODIFICATION, then it must not have a
+    // usage of userApplications.
+    if (isNoUserModification &&
+        (attributeUsage == AttributeUsage.USER_APPLICATIONS))
+    {
+      int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_NO_USER_MOD_NOT_OPERATIONAL;
+      String message = getMessage(msgID, oid);
+      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                   msgID);
+    }
+
+
     return new AttributeType(value.stringValue(), primaryName, typeNames, oid,
                              description, superiorType, syntax,
                              approximateMatchingRule, equalityMatchingRule,
diff --git a/opendj-sdk/opends/src/server/org/opends/server/schema/DITContentRuleSyntax.java b/opendj-sdk/opends/src/server/org/opends/server/schema/DITContentRuleSyntax.java
index a8dc05e..d9f00ed 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/schema/DITContentRuleSyntax.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/schema/DITContentRuleSyntax.java
@@ -45,15 +45,13 @@
 import org.opends.server.types.ByteString;
 import org.opends.server.types.DirectoryException;
 import org.opends.server.types.DITContentRule;
-import org.opends.server.types.ErrorLogCategory;
-import org.opends.server.types.ErrorLogSeverity;
+import org.opends.server.types.InitializationException;
 import org.opends.server.types.ObjectClass;
 import org.opends.server.types.ObjectClassType;
 import org.opends.server.types.ResultCode;
 import org.opends.server.types.Schema;
 
 import static org.opends.server.loggers.Debug.*;
-import static org.opends.server.loggers.Error.*;
 import static org.opends.server.messages.MessageHandler.*;
 import static org.opends.server.messages.SchemaMessages.*;
 import static org.opends.server.schema.SchemaConstants.*;
@@ -104,17 +102,10 @@
 
 
   /**
-   * Initializes this attribute syntax based on the information in the provided
-   * configuration entry.
-   *
-   * @param  configEntry  The configuration entry that contains the information
-   *                      to use to initialize this attribute syntax.
-   *
-   * @throws  ConfigException  If an unrecoverable problem arises in the
-   *                           process of performing the initialization.
+   * {@inheritDoc}
    */
   public void initializeSyntax(ConfigEntry configEntry)
-         throws ConfigException
+         throws ConfigException, InitializationException
   {
     assert debugEnter(CLASS_NAME, "initializeSyntax",
                       String.valueOf(configEntry));
@@ -123,36 +114,37 @@
          DirectoryServer.getEqualityMatchingRule(EMR_CASE_IGNORE_OID);
     if (defaultEqualityMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE,
-               EMR_CASE_IGNORE_OID, SYNTAX_DIT_CONTENT_RULE_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE;
+      String message = getMessage(msgID, EMR_CASE_IGNORE_OID,
+                                  SYNTAX_DIT_CONTENT_RULE_NAME);
+      throw new InitializationException(msgID, message);
     }
 
     defaultOrderingMatchingRule =
          DirectoryServer.getOrderingMatchingRule(OMR_CASE_IGNORE_OID);
     if (defaultOrderingMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE,
-               OMR_CASE_IGNORE_OID, SYNTAX_DIT_CONTENT_RULE_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE;
+      String message = getMessage(msgID, OMR_CASE_IGNORE_OID,
+                                  SYNTAX_DIT_CONTENT_RULE_NAME);
+      throw new InitializationException(msgID, message);
     }
 
     defaultSubstringMatchingRule =
          DirectoryServer.getSubstringMatchingRule(SMR_CASE_IGNORE_OID);
     if (defaultSubstringMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE,
-               SMR_CASE_IGNORE_OID, SYNTAX_DIT_CONTENT_RULE_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE;
+      String message = getMessage(msgID, SMR_CASE_IGNORE_OID,
+                                  SYNTAX_DIT_CONTENT_RULE_NAME);
+      throw new InitializationException(msgID, message);
     }
   }
 
 
 
   /**
-   * Retrieves the common name for this attribute syntax.
-   *
-   * @return  The common name for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getSyntaxName()
   {
@@ -164,9 +156,7 @@
 
 
   /**
-   * Retrieves the OID for this attribute syntax.
-   *
-   * @return  The OID for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getOID()
   {
@@ -178,9 +168,7 @@
 
 
   /**
-   * Retrieves a description for this attribute syntax.
-   *
-   * @return  A description for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getDescription()
   {
@@ -192,12 +180,7 @@
 
 
   /**
-   * Retrieves the default equality matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default equality matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if equality
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public EqualityMatchingRule getEqualityMatchingRule()
   {
@@ -209,12 +192,7 @@
 
 
   /**
-   * Retrieves the default ordering matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default ordering matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if ordering
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public OrderingMatchingRule getOrderingMatchingRule()
   {
@@ -226,12 +204,7 @@
 
 
   /**
-   * Retrieves the default substring matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default substring matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if substring
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public SubstringMatchingRule getSubstringMatchingRule()
   {
@@ -243,12 +216,7 @@
 
 
   /**
-   * Retrieves the default approximate matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default approximate matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if approximate
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public ApproximateMatchingRule getApproximateMatchingRule()
   {
@@ -261,16 +229,7 @@
 
 
   /**
-   * Indicates whether the provided value is acceptable for use in an attribute
-   * with this syntax.  If it is not, then the reason may be appended to the
-   * provided buffer.
-   *
-   * @param  value          The value for which to make the determination.
-   * @param  invalidReason  The buffer to which the invalid reason should be
-   *                        appended.
-   *
-   * @return  <CODE>true</CODE> if the provided value is acceptable for use with
-   *          this syntax, or <CODE>false</CODE> if not.
+   * {@inheritDoc}
    */
   public boolean valueIsAcceptable(ByteString value,
                                    StringBuilder invalidReason)
@@ -283,7 +242,7 @@
     // acceptable.
     try
     {
-      decodeDITContentRule(value, DirectoryServer.getSchema());
+      decodeDITContentRule(value, DirectoryServer.getSchema(), true);
       return true;
     }
     catch (DirectoryException de)
@@ -304,10 +263,16 @@
    * should not be in order to allow the desired capitalization to be
    * preserved).
    *
-   * @param  value   The ASN.1 octet string containing the value to decode (it
-   *                 does not need to be normalized).
-   * @param  schema  The schema to use to resolve references to other schema
-   *                 elements.
+   * @param  value                 The ASN.1 octet string containing the value
+   *                               to decode (it does not need to be
+   *                               normalized).
+   * @param  schema                The schema to use to resolve references to
+   *                               other schema elements.
+   * @param  allowUnknownElements  Indicates whether to allow values that
+   *                               reference a name form and/or superior rules
+   *                               which are not defined in the server schema.
+   *                               This should only be true when called by
+   *                               {@code valueIsAcceptable}.
    *
    * @return  The decoded DIT content rule definition.
    *
@@ -315,7 +280,7 @@
    *                              DIT content rule definition.
    */
   public static DITContentRule decodeDITContentRule(ByteString value,
-                                                    Schema schema)
+                                    Schema schema, boolean allowUnknownElements)
          throws DirectoryException
   {
     assert debugEnter(CLASS_NAME, "decodeDITContentRule",
@@ -457,16 +422,21 @@
 
 
     // Get the objectclass with the specified OID.  If it does not exist or is
-    // not structural, then log a warning but continue on.
+    // not structural, then fail.
     ObjectClass structuralClass = schema.getObjectClass(oid);
     if (structuralClass == null)
     {
-      int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_STRUCTURAL_CLASS;
-      String message = getMessage(msgID, valueStr, oid);
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-               message, msgID);
-
-      structuralClass = DirectoryServer.getDefaultObjectClass(oid);
+      if (allowUnknownElements)
+      {
+        structuralClass = DirectoryServer.getDefaultObjectClass(oid);
+      }
+      else
+      {
+        int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_STRUCTURAL_CLASS;
+        String message = getMessage(msgID, valueStr, oid);
+        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                     msgID);
+      }
     }
     else if (structuralClass.getObjectClassType() != ObjectClassType.STRUCTURAL)
     {
@@ -474,8 +444,8 @@
       String message =
            getMessage(msgID, valueStr, oid, structuralClass.getNameOrOID(),
                       String.valueOf(structuralClass.getObjectClassType()));
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-               message, msgID);
+      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                   msgID);
     }
 
 
@@ -627,25 +597,30 @@
             ObjectClass oc = schema.getObjectClass(woidBuffer.toString());
             if (oc == null)
             {
-              // This isn't good because it is an unknown auxiliary class.  Log
-              // a message and construct a default.
-              int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_AUXILIARY_CLASS;
-              String message = getMessage(msgID, valueStr,
+              // This isn't good because it is an unknown auxiliary class.
+              if (allowUnknownElements)
+              {
+                oc = DirectoryServer.getDefaultAuxiliaryObjectClass(
                                           woidBuffer.toString());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-
-              oc = DirectoryServer.getDefaultObjectClass(woidBuffer.toString());
+              }
+              else
+              {
+                int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_AUXILIARY_CLASS;
+                String message = getMessage(msgID, valueStr,
+                                            woidBuffer.toString());
+                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                             message, msgID);
+              }
             }
             else if (oc.getObjectClassType() != ObjectClassType.AUXILIARY)
             {
-              // This isn't good because it isn't an auxiliary class.  Log a
-              // message but continue on.
+              // This isn't good because it isn't an auxiliary class.
               int msgID = MSGID_ATTR_SYNTAX_DCR_AUXILIARY_CLASS_NOT_AUXILIARY;
               String message = getMessage(msgID, valueStr,
-                                          woidBuffer.toString());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
+                                          woidBuffer.toString(),
+                                          oc.getObjectClassType().toString());
+              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                           message, msgID);
             }
 
             ocs.add(oc);
@@ -676,23 +651,29 @@
           ObjectClass oc = schema.getObjectClass(woidBuffer.toString());
           if (oc == null)
           {
-            // This isn't good because it is an unknown auxiliary class.  Log
-            // a message and construct a default.
-            int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_AUXILIARY_CLASS;
-            String message = getMessage(msgID, valueStr, woidBuffer.toString());
-            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                     message, msgID);
-
-            oc = DirectoryServer.getDefaultObjectClass(woidBuffer.toString());
+            // This isn't good because it is an unknown auxiliary class.
+            if (allowUnknownElements)
+            {
+              oc = DirectoryServer.getDefaultAuxiliaryObjectClass(
+                                        woidBuffer.toString());
+            }
+            else
+            {
+              int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_AUXILIARY_CLASS;
+              String message = getMessage(msgID, valueStr,
+                                          woidBuffer.toString());
+              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                           message, msgID);
+            }
           }
           else if (oc.getObjectClassType() != ObjectClassType.AUXILIARY)
           {
-            // This isn't good because it isn't an auxiliary class.  Log a
-            // message but continue on.
+            // This isn't good because it isn't an auxiliary class.
             int msgID = MSGID_ATTR_SYNTAX_DCR_AUXILIARY_CLASS_NOT_AUXILIARY;
-            String message = getMessage(msgID, valueStr, woidBuffer.toString());
-            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                     message, msgID);
+            String message = getMessage(msgID, valueStr, woidBuffer.toString(),
+                                        oc.getObjectClassType().toString());
+            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                         message, msgID);
           }
 
           ocs.add(oc);
@@ -721,16 +702,19 @@
             {
               // This isn't good because it means that the DIT content rule
               // requires an attribute type that we don't know anything about.
-              // in this case all we can do is log a message and construct a
-              // default type.
-              int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_REQUIRED_ATTR;
-              String message = getMessage(msgID, valueStr,
-                                          woidBuffer.toString());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-
-              attr = DirectoryServer.getDefaultAttributeType(
-                                          woidBuffer.toString());
+              if (allowUnknownElements)
+              {
+                attr = DirectoryServer.getDefaultAttributeType(
+                                            woidBuffer.toString());
+              }
+              else
+              {
+                int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_REQUIRED_ATTR;
+                String message = getMessage(msgID, valueStr,
+                                            woidBuffer.toString());
+                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                             message, msgID);
+              }
             }
 
             attrs.add(attr);
@@ -762,16 +746,20 @@
           if (attr == null)
           {
             // This isn't good because it means that the DIT content rule
-            // requires an attribute type that we don't know anything about.  In
-            // this case all we can do is log a message and construct a default
-            // type.
-            int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_REQUIRED_ATTR;
-            String message = getMessage(msgID, valueStr, woidBuffer.toString());
-            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                     message, msgID);
-
-            attr = DirectoryServer.getDefaultAttributeType(
-                                        woidBuffer.toString());
+            // requires an attribute type that we don't know anything about.
+            if (allowUnknownElements)
+            {
+              attr = DirectoryServer.getDefaultAttributeType(
+                                          woidBuffer.toString());
+            }
+            else
+            {
+              int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_REQUIRED_ATTR;
+              String message = getMessage(msgID, valueStr,
+                                          woidBuffer.toString());
+              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                           message, msgID);
+            }
           }
 
           attrs.add(attr);
@@ -799,17 +787,20 @@
             if (attr == null)
             {
               // This isn't good because it means that the DIT content rule
-              // allows an attribute type that we don't know anything about.  In
-              // this case all we can do is log a message and construct a
-              // default type.
-              int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_OPTIONAL_ATTR;
-              String message = getMessage(msgID, valueStr,
-                                          woidBuffer.toString());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-
-              attr = DirectoryServer.getDefaultAttributeType(
-                                          woidBuffer.toString());
+              // allows an attribute type that we don't know anything about.
+              if (allowUnknownElements)
+              {
+                attr = DirectoryServer.getDefaultAttributeType(
+                                            woidBuffer.toString());
+              }
+              else
+              {
+                int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_OPTIONAL_ATTR;
+                String message = getMessage(msgID, valueStr,
+                                            woidBuffer.toString());
+                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                             message, msgID);
+              }
             }
 
             attrs.add(attr);
@@ -841,15 +832,20 @@
           if (attr == null)
           {
             // This isn't good because it means that the DIT content rule allows
-            // an attribute type that we don't know anything about.  In this
-            // case all we can do is log a message and construct a default type.
-            int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_OPTIONAL_ATTR;
-            String message = getMessage(msgID, valueStr, woidBuffer.toString());
-            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                     message, msgID);
-
-            attr = DirectoryServer.getDefaultAttributeType(
-                                        woidBuffer.toString());
+            // an attribute type that we don't know anything about.
+            if (allowUnknownElements)
+            {
+              attr = DirectoryServer.getDefaultAttributeType(
+                                          woidBuffer.toString());
+            }
+            else
+            {
+              int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_OPTIONAL_ATTR;
+              String message = getMessage(msgID, valueStr,
+                                          woidBuffer.toString());
+              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                           message, msgID);
+            }
           }
 
           attrs.add(attr);
@@ -878,16 +874,19 @@
             {
               // This isn't good because it means that the DIT content rule
               // prohibits an attribute type that we don't know anything about.
-              // In this case all we can do is log a message and construct a
-              // default type.
-              int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_PROHIBITED_ATTR;
-              String message = getMessage(msgID, valueStr,
-                                          woidBuffer.toString());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-
-              attr = DirectoryServer.getDefaultAttributeType(
-                                          woidBuffer.toString());
+              if (allowUnknownElements)
+              {
+                attr = DirectoryServer.getDefaultAttributeType(
+                                            woidBuffer.toString());
+              }
+              else
+              {
+                int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_PROHIBITED_ATTR;
+                String message = getMessage(msgID, valueStr,
+                                            woidBuffer.toString());
+                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                             message, msgID);
+              }
             }
 
             attrs.add(attr);
@@ -920,15 +919,19 @@
           {
             // This isn't good because it means that the DIT content rule
             // prohibits an attribute type that we don't know anything about.
-            // In this case all we can do is log a message and construct a
-            // default type.
-            int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_PROHIBITED_ATTR;
-            String message = getMessage(msgID, valueStr, woidBuffer.toString());
-            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                     message, msgID);
-
-            attr = DirectoryServer.getDefaultAttributeType(
-                                        woidBuffer.toString());
+            if (allowUnknownElements)
+            {
+              attr = DirectoryServer.getDefaultAttributeType(
+                                          woidBuffer.toString());
+            }
+            else
+            {
+              int    msgID   = MSGID_ATTR_SYNTAX_DCR_UNKNOWN_PROHIBITED_ATTR;
+              String message = getMessage(msgID, valueStr,
+                                          woidBuffer.toString());
+              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                           message, msgID);
+            }
           }
 
           attrs.add(attr);
@@ -949,6 +952,33 @@
     }
 
 
+    // Make sure that none of the prohibited attributes is required by the
+    // structural or any of the auxiliary classes.
+    for (AttributeType t : prohibitedAttributes)
+    {
+      if (structuralClass.isRequired(t))
+      {
+        int msgID = MSGID_ATTR_SYNTAX_DCR_PROHIBITED_REQUIRED_BY_STRUCTURAL;
+        String message = getMessage(msgID, valueStr, t.getNameOrOID(),
+                                    structuralClass.getNameOrOID());
+        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                     msgID);
+      }
+
+      for (ObjectClass oc : auxiliaryClasses)
+      {
+        if (oc.isRequired(t))
+        {
+          int msgID = MSGID_ATTR_SYNTAX_DCR_PROHIBITED_REQUIRED_BY_AUXILIARY;
+          String message = getMessage(msgID, valueStr, t.getNameOrOID(),
+                                      oc.getNameOrOID());
+          throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                       msgID);
+        }
+      }
+    }
+
+
     return new DITContentRule(value.stringValue(), structuralClass, names,
                               description, auxiliaryClasses, requiredAttributes,
                               optionalAttributes, prohibitedAttributes,
diff --git a/opendj-sdk/opends/src/server/org/opends/server/schema/DITStructureRuleSyntax.java b/opendj-sdk/opends/src/server/org/opends/server/schema/DITStructureRuleSyntax.java
index 9ebbfd6..24674f7 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/schema/DITStructureRuleSyntax.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/schema/DITStructureRuleSyntax.java
@@ -44,14 +44,12 @@
 import org.opends.server.types.ByteString;
 import org.opends.server.types.DirectoryException;
 import org.opends.server.types.DITStructureRule;
-import org.opends.server.types.ErrorLogCategory;
-import org.opends.server.types.ErrorLogSeverity;
+import org.opends.server.types.InitializationException;
 import org.opends.server.types.NameForm;
 import org.opends.server.types.ResultCode;
 import org.opends.server.types.Schema;
 
 import static org.opends.server.loggers.Debug.*;
-import static org.opends.server.loggers.Error.*;
 import static org.opends.server.messages.MessageHandler.*;
 import static org.opends.server.messages.SchemaMessages.*;
 import static org.opends.server.schema.SchemaConstants.*;
@@ -102,17 +100,10 @@
 
 
   /**
-   * Initializes this attribute syntax based on the information in the provided
-   * configuration entry.
-   *
-   * @param  configEntry  The configuration entry that contains the information
-   *                      to use to initialize this attribute syntax.
-   *
-   * @throws  ConfigException  If an unrecoverable problem arises in the
-   *                           process of performing the initialization.
+   * {@inheritDoc}
    */
   public void initializeSyntax(ConfigEntry configEntry)
-         throws ConfigException
+         throws ConfigException, InitializationException
   {
     assert debugEnter(CLASS_NAME, "initializeSyntax",
                       String.valueOf(configEntry));
@@ -121,36 +112,37 @@
          DirectoryServer.getEqualityMatchingRule(EMR_CASE_IGNORE_OID);
     if (defaultEqualityMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE,
-               EMR_CASE_IGNORE_OID, SYNTAX_DIT_STRUCTURE_RULE_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE;
+      String message = getMessage(msgID, EMR_CASE_IGNORE_OID,
+                                  SYNTAX_DIT_STRUCTURE_RULE_NAME);
+      throw new InitializationException(msgID, message);
     }
 
     defaultOrderingMatchingRule =
          DirectoryServer.getOrderingMatchingRule(OMR_CASE_IGNORE_OID);
     if (defaultOrderingMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE,
-               OMR_CASE_IGNORE_OID, SYNTAX_DIT_STRUCTURE_RULE_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE;
+      String message = getMessage(msgID, OMR_CASE_IGNORE_OID,
+                                  SYNTAX_DIT_STRUCTURE_RULE_NAME);
+      throw new InitializationException(msgID, message);
     }
 
     defaultSubstringMatchingRule =
          DirectoryServer.getSubstringMatchingRule(SMR_CASE_IGNORE_OID);
     if (defaultSubstringMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE,
-               SMR_CASE_IGNORE_OID, SYNTAX_DIT_STRUCTURE_RULE_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE;
+      String message = getMessage(msgID, SMR_CASE_IGNORE_OID,
+                                  SYNTAX_DIT_STRUCTURE_RULE_NAME);
+      throw new InitializationException(msgID, message);
     }
   }
 
 
 
   /**
-   * Retrieves the common name for this attribute syntax.
-   *
-   * @return  The common name for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getSyntaxName()
   {
@@ -162,9 +154,7 @@
 
 
   /**
-   * Retrieves the OID for this attribute syntax.
-   *
-   * @return  The OID for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getOID()
   {
@@ -176,9 +166,7 @@
 
 
   /**
-   * Retrieves a description for this attribute syntax.
-   *
-   * @return  A description for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getDescription()
   {
@@ -190,12 +178,7 @@
 
 
   /**
-   * Retrieves the default equality matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default equality matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if equality
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public EqualityMatchingRule getEqualityMatchingRule()
   {
@@ -207,12 +190,7 @@
 
 
   /**
-   * Retrieves the default ordering matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default ordering matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if ordering
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public OrderingMatchingRule getOrderingMatchingRule()
   {
@@ -224,12 +202,7 @@
 
 
   /**
-   * Retrieves the default substring matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default substring matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if substring
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public SubstringMatchingRule getSubstringMatchingRule()
   {
@@ -241,12 +214,7 @@
 
 
   /**
-   * Retrieves the default approximate matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default approximate matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if approximate
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public ApproximateMatchingRule getApproximateMatchingRule()
   {
@@ -259,16 +227,7 @@
 
 
   /**
-   * Indicates whether the provided value is acceptable for use in an attribute
-   * with this syntax.  If it is not, then the reason may be appended to the
-   * provided buffer.
-   *
-   * @param  value          The value for which to make the determination.
-   * @param  invalidReason  The buffer to which the invalid reason should be
-   *                        appended.
-   *
-   * @return  <CODE>true</CODE> if the provided value is acceptable for use with
-   *          this syntax, or <CODE>false</CODE> if not.
+   * {@inheritDoc}
    */
   public boolean valueIsAcceptable(ByteString value,
                                    StringBuilder invalidReason)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/schema/MatchingRuleUseSyntax.java b/opendj-sdk/opends/src/server/org/opends/server/schema/MatchingRuleUseSyntax.java
index e238546..c28dd53 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/schema/MatchingRuleUseSyntax.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/schema/MatchingRuleUseSyntax.java
@@ -45,14 +45,12 @@
 import org.opends.server.types.AttributeType;
 import org.opends.server.types.ByteString;
 import org.opends.server.types.DirectoryException;
-import org.opends.server.types.ErrorLogCategory;
-import org.opends.server.types.ErrorLogSeverity;
+import org.opends.server.types.InitializationException;
 import org.opends.server.types.MatchingRuleUse;
 import org.opends.server.types.ResultCode;
 import org.opends.server.types.Schema;
 
 import static org.opends.server.loggers.Debug.*;
-import static org.opends.server.loggers.Error.*;
 import static org.opends.server.messages.MessageHandler.*;
 import static org.opends.server.messages.SchemaMessages.*;
 import static org.opends.server.schema.SchemaConstants.*;
@@ -103,17 +101,10 @@
 
 
   /**
-   * Initializes this attribute syntax based on the information in the provided
-   * configuration entry.
-   *
-   * @param  configEntry  The configuration entry that contains the information
-   *                      to use to initialize this attribute syntax.
-   *
-   * @throws  ConfigException  If an unrecoverable problem arises in the
-   *                           process of performing the initialization.
+   * {@inheritDoc}
    */
   public void initializeSyntax(ConfigEntry configEntry)
-         throws ConfigException
+         throws ConfigException, InitializationException
   {
     assert debugEnter(CLASS_NAME, "initializeSyntax",
                       String.valueOf(configEntry));
@@ -122,36 +113,37 @@
          DirectoryServer.getEqualityMatchingRule(EMR_CASE_IGNORE_OID);
     if (defaultEqualityMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE,
-               EMR_CASE_IGNORE_OID, SYNTAX_MATCHING_RULE_USE_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE;
+      String message = getMessage(msgID, EMR_CASE_IGNORE_OID,
+                                  SYNTAX_MATCHING_RULE_USE_NAME);
+      throw new InitializationException(msgID, message);
     }
 
     defaultOrderingMatchingRule =
          DirectoryServer.getOrderingMatchingRule(OMR_CASE_IGNORE_OID);
     if (defaultOrderingMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE,
-               OMR_CASE_IGNORE_OID, SYNTAX_MATCHING_RULE_USE_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE;
+      String message = getMessage(msgID, OMR_CASE_IGNORE_OID,
+                                  SYNTAX_MATCHING_RULE_USE_NAME);
+      throw new InitializationException(msgID, message);
     }
 
     defaultSubstringMatchingRule =
          DirectoryServer.getSubstringMatchingRule(SMR_CASE_IGNORE_OID);
     if (defaultSubstringMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE,
-               SMR_CASE_IGNORE_OID, SYNTAX_MATCHING_RULE_USE_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE;
+      String message = getMessage(msgID, SMR_CASE_IGNORE_OID,
+                                  SYNTAX_MATCHING_RULE_USE_NAME);
+      throw new InitializationException(msgID, message);
     }
   }
 
 
 
   /**
-   * Retrieves the common name for this attribute syntax.
-   *
-   * @return  The common name for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getSyntaxName()
   {
@@ -163,9 +155,7 @@
 
 
   /**
-   * Retrieves the OID for this attribute syntax.
-   *
-   * @return  The OID for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getOID()
   {
@@ -177,9 +167,7 @@
 
 
   /**
-   * Retrieves a description for this attribute syntax.
-   *
-   * @return  A description for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getDescription()
   {
@@ -191,12 +179,7 @@
 
 
   /**
-   * Retrieves the default equality matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default equality matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if equality
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public EqualityMatchingRule getEqualityMatchingRule()
   {
@@ -208,12 +191,7 @@
 
 
   /**
-   * Retrieves the default ordering matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default ordering matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if ordering
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public OrderingMatchingRule getOrderingMatchingRule()
   {
@@ -225,12 +203,7 @@
 
 
   /**
-   * Retrieves the default substring matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default substring matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if substring
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public SubstringMatchingRule getSubstringMatchingRule()
   {
@@ -242,12 +215,7 @@
 
 
   /**
-   * Retrieves the default approximate matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default approximate matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if approximate
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public ApproximateMatchingRule getApproximateMatchingRule()
   {
@@ -260,16 +228,7 @@
 
 
   /**
-   * Indicates whether the provided value is acceptable for use in an attribute
-   * with this syntax.  If it is not, then the reason may be appended to the
-   * provided buffer.
-   *
-   * @param  value          The value for which to make the determination.
-   * @param  invalidReason  The buffer to which the invalid reason should be
-   *                        appended.
-   *
-   * @return  <CODE>true</CODE> if the provided value is acceptable for use with
-   *          this syntax, or <CODE>false</CODE> if not.
+   * {@inheritDoc}
    */
   public boolean valueIsAcceptable(ByteString value,
                                    StringBuilder invalidReason)
@@ -282,7 +241,7 @@
     // acceptable.
     try
     {
-      decodeMatchingRuleUse(value, DirectoryServer.getSchema());
+      decodeMatchingRuleUse(value, DirectoryServer.getSchema(), true);
       return true;
     }
     catch (DirectoryException de)
@@ -303,10 +262,16 @@
    * should not be in order to allow the desired capitalization to be
    * preserved).
    *
-   * @param  value   The ASN.1 octet string containing the value to decode (it
-   *                 does not need to be normalized).
-   * @param  schema  The schema to use to resolve references to other schema
-   *                 elements.
+   * @param  value                 The ASN.1 octet string containing the value
+   *                               to decode (it does not need to be
+   *                               normalized).
+   * @param  schema                The schema to use to resolve references to
+   *                               other schema elements.
+   * @param  allowUnknownElements  Indicates whether to allow values that
+   *                               reference a name form and/or superior rules
+   *                               which are not defined in the server schema.
+   *                               This should only be true when called by
+   *                               {@code valueIsAcceptable}.
    *
    * @return  The decoded matching rule use definition.
    *
@@ -314,7 +279,8 @@
    *                              matching rule use definition.
    */
   public static MatchingRuleUse decodeMatchingRuleUse(ByteString value,
-                                                      Schema schema)
+                                     Schema schema,
+                                     boolean allowUnknownElements)
          throws DirectoryException
   {
     assert debugEnter(CLASS_NAME, "decodeMatchingRuleUse",
@@ -610,15 +576,18 @@
             {
               // This isn't good because it means that the matching rule use
               // specifies an attribute type that we don't know anything about.
-              // In this case all we can do is log a message and construct a
-              // default type.
-              int msgID = MSGID_ATTR_SYNTAX_MRUSE_UNKNOWN_ATTR;
-              String message = getMessage(msgID, oid, woidBuffer.toString());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-
-              attr = DirectoryServer.getDefaultAttributeType(
-                                          woidBuffer.toString());
+              if (allowUnknownElements)
+              {
+                attr = DirectoryServer.getDefaultAttributeType(
+                                            woidBuffer.toString());
+              }
+              else
+              {
+                int msgID = MSGID_ATTR_SYNTAX_MRUSE_UNKNOWN_ATTR;
+                String message = getMessage(msgID, oid, woidBuffer.toString());
+                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                             message, msgID);
+              }
             }
 
             attrs.add(attr);
@@ -651,15 +620,18 @@
           {
             // This isn't good because it means that the matching rule use
             // specifies an attribute type that we don't know anything about.
-            // In this case all we can do is log a message and construct a
-            // default type.
-            int msgID = MSGID_ATTR_SYNTAX_MRUSE_UNKNOWN_ATTR;
-            String message = getMessage(msgID, oid, woidBuffer.toString());
-            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                     message, msgID);
-
-            attr = DirectoryServer.getDefaultAttributeType(
-                                        woidBuffer.toString());
+            if (allowUnknownElements)
+            {
+              attr = DirectoryServer.getDefaultAttributeType(
+                                          woidBuffer.toString());
+            }
+            else
+            {
+              int msgID = MSGID_ATTR_SYNTAX_MRUSE_UNKNOWN_ATTR;
+              String message = getMessage(msgID, oid, woidBuffer.toString());
+              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                           message, msgID);
+            }
           }
 
           attrs.add(attr);
diff --git a/opendj-sdk/opends/src/server/org/opends/server/schema/NameFormSyntax.java b/opendj-sdk/opends/src/server/org/opends/server/schema/NameFormSyntax.java
index c349dc6..0a664c4 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/schema/NameFormSyntax.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/schema/NameFormSyntax.java
@@ -44,8 +44,7 @@
 import org.opends.server.types.AttributeType;
 import org.opends.server.types.ByteString;
 import org.opends.server.types.DirectoryException;
-import org.opends.server.types.ErrorLogCategory;
-import org.opends.server.types.ErrorLogSeverity;
+import org.opends.server.types.InitializationException;
 import org.opends.server.types.NameForm;
 import org.opends.server.types.ObjectClass;
 import org.opends.server.types.ObjectClassType;
@@ -53,7 +52,6 @@
 import org.opends.server.types.Schema;
 
 import static org.opends.server.loggers.Debug.*;
-import static org.opends.server.loggers.Error.*;
 import static org.opends.server.messages.MessageHandler.*;
 import static org.opends.server.messages.SchemaMessages.*;
 import static org.opends.server.schema.SchemaConstants.*;
@@ -104,17 +102,10 @@
 
 
   /**
-   * Initializes this attribute syntax based on the information in the provided
-   * configuration entry.
-   *
-   * @param  configEntry  The configuration entry that contains the information
-   *                      to use to initialize this attribute syntax.
-   *
-   * @throws  ConfigException  If an unrecoverable problem arises in the
-   *                           process of performing the initialization.
+   * {@inheritDoc}
    */
   public void initializeSyntax(ConfigEntry configEntry)
-         throws ConfigException
+         throws ConfigException, InitializationException
   {
     assert debugEnter(CLASS_NAME, "initializeSyntax",
                       String.valueOf(configEntry));
@@ -123,36 +114,37 @@
          DirectoryServer.getEqualityMatchingRule(EMR_CASE_IGNORE_OID);
     if (defaultEqualityMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE,
-               EMR_CASE_IGNORE_OID, SYNTAX_NAME_FORM_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE;
+      String message = getMessage(msgID, EMR_CASE_IGNORE_OID,
+                                  SYNTAX_NAME_FORM_NAME);
+      throw new InitializationException(msgID, message);
     }
 
     defaultOrderingMatchingRule =
          DirectoryServer.getOrderingMatchingRule(OMR_CASE_IGNORE_OID);
     if (defaultOrderingMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE,
-               OMR_CASE_IGNORE_OID, SYNTAX_NAME_FORM_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE;
+      String message = getMessage(msgID, OMR_CASE_IGNORE_OID,
+                                  SYNTAX_NAME_FORM_NAME);
+      throw new InitializationException(msgID, message);
     }
 
     defaultSubstringMatchingRule =
          DirectoryServer.getSubstringMatchingRule(SMR_CASE_IGNORE_OID);
     if (defaultSubstringMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE,
-               SMR_CASE_IGNORE_OID, SYNTAX_NAME_FORM_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE;
+      String message = getMessage(msgID, SMR_CASE_IGNORE_OID,
+                                  SYNTAX_NAME_FORM_NAME);
+      throw new InitializationException(msgID, message);
     }
   }
 
 
 
   /**
-   * Retrieves the common name for this attribute syntax.
-   *
-   * @return  The common name for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getSyntaxName()
   {
@@ -164,9 +156,7 @@
 
 
   /**
-   * Retrieves the OID for this attribute syntax.
-   *
-   * @return  The OID for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getOID()
   {
@@ -178,9 +168,7 @@
 
 
   /**
-   * Retrieves a description for this attribute syntax.
-   *
-   * @return  A description for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getDescription()
   {
@@ -192,12 +180,7 @@
 
 
   /**
-   * Retrieves the default equality matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default equality matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if equality
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public EqualityMatchingRule getEqualityMatchingRule()
   {
@@ -209,12 +192,7 @@
 
 
   /**
-   * Retrieves the default ordering matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default ordering matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if ordering
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public OrderingMatchingRule getOrderingMatchingRule()
   {
@@ -226,12 +204,7 @@
 
 
   /**
-   * Retrieves the default substring matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default substring matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if substring
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public SubstringMatchingRule getSubstringMatchingRule()
   {
@@ -243,12 +216,7 @@
 
 
   /**
-   * Retrieves the default approximate matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default approximate matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if approximate
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public ApproximateMatchingRule getApproximateMatchingRule()
   {
@@ -261,16 +229,7 @@
 
 
   /**
-   * Indicates whether the provided value is acceptable for use in an attribute
-   * with this syntax.  If it is not, then the reason may be appended to the
-   * provided buffer.
-   *
-   * @param  value          The value for which to make the determination.
-   * @param  invalidReason  The buffer to which the invalid reason should be
-   *                        appended.
-   *
-   * @return  <CODE>true</CODE> if the provided value is acceptable for use with
-   *          this syntax, or <CODE>false</CODE> if not.
+   * {@inheritDoc}
    */
   public boolean valueIsAcceptable(ByteString value,
                                    StringBuilder invalidReason)
@@ -283,7 +242,7 @@
     // acceptable.
     try
     {
-      decodeNameForm(value, DirectoryServer.getSchema());
+      decodeNameForm(value, DirectoryServer.getSchema(), true);
       return true;
     }
     catch (DirectoryException de)
@@ -303,17 +262,25 @@
    * octet string value does not need to be normalized (and in fact, it should
    * not be in order to allow the desired capitalization to be preserved).
    *
-   * @param  value   The ASN.1 octet string containing the value to decode (it
-   *                 does not need to be normalized).
-   * @param  schema  The reference to the Directory Server schema to use to
-   *                 decode the name form information.
+   * @param  value                 The ASN.1 octet string containing the value
+   *                               to decode (it does not need to be
+   *                               normalized).
+   * @param  schema                The schema to use to resolve references to
+   *                               other schema elements.
+   * @param  allowUnknownElements  Indicates whether to allow values that
+   *                               reference a structural objectclass and/or
+   *                               required or optional attribute types which
+   *                               are not defined in the server schema.  This
+   *                               should only be true when called by
+   *                               {@code valueIsAcceptable}.
    *
    * @return  The decoded name form definition.
    *
    * @throws  DirectoryException  If the provided value cannot be decoded as an
    *                              name form definition.
    */
-  public static NameForm decodeNameForm(ByteString value, Schema schema)
+  public static NameForm decodeNameForm(ByteString value, Schema schema,
+                                        boolean allowUnknownElements)
          throws DirectoryException
   {
     assert debugEnter(CLASS_NAME, "decodeNameForm", String.valueOf(value));
@@ -589,29 +556,34 @@
         if (structuralClass == null)
         {
           // This is bad because we don't know what the structural objectclass
-          // is.  Log a message and create a default objectclass with the
-          // specified name.
-          int    msgID   = MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_STRUCTURAL_CLASS;
-          String message = getMessage(msgID, String.valueOf(oid),
-                                      String.valueOf(woidBuffer));
-          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-                   message, msgID);
-          structuralClass =
-               DirectoryServer.getDefaultObjectClass(woidBuffer.toString());
+          // is.
+          if (allowUnknownElements)
+          {
+            structuralClass = DirectoryServer.getDefaultObjectClass(
+                                                   woidBuffer.toString());
+          }
+          else
+          {
+            int msgID = MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_STRUCTURAL_CLASS;
+            String message = getMessage(msgID, String.valueOf(oid),
+                                        String.valueOf(woidBuffer));
+            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                         message, msgID);
+          }
         }
         else if (structuralClass.getObjectClassType() !=
                  ObjectClassType.STRUCTURAL)
         {
           // This is bad because the associated structural class type is not
-          // structural.  Log a message and continue.
+          // structural.
           int msgID =
                MSGID_ATTR_SYNTAX_NAME_FORM_STRUCTURAL_CLASS_NOT_STRUCTURAL;
           String message =
                getMessage(msgID, String.valueOf(oid),
                           String.valueOf(woidBuffer),
                           String.valueOf(structuralClass.getObjectClassType()));
-          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-                   message, msgID);
+          throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                       msgID);
         }
       }
       else if (lowerTokenName.equals("must"))
@@ -634,16 +606,19 @@
             if (attr == null)
             {
               // This isn't good because it means that the name form requires
-              // an attribute type that we don't know anything about.  In this
-              // case all we can do is log a message and construct a default
-              // type.
-              int msgID = MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_REQUIRED_ATTR;
-              String message = getMessage(msgID, oid, woidBuffer.toString());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-
-              attr = DirectoryServer.getDefaultAttributeType(
-                                          woidBuffer.toString());
+              // an attribute type that we don't know anything about.
+              if (allowUnknownElements)
+              {
+                attr = DirectoryServer.getDefaultAttributeType(
+                                            woidBuffer.toString());
+              }
+              else
+              {
+                int msgID = MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_REQUIRED_ATTR;
+                String message = getMessage(msgID, oid, woidBuffer.toString());
+                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                             message, msgID);
+              }
             }
 
             attrs.add(attr);
@@ -675,15 +650,19 @@
           if (attr == null)
           {
             // This isn't good because it means that the name form requires an
-            // attribute type that we don't know anything about.  In this case
-            // all we can do is log a message and construct a default type.
-            int msgID = MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_REQUIRED_ATTR;
-            String message = getMessage(msgID, oid, woidBuffer.toString());
-            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                     message, msgID);
-
-            attr = DirectoryServer.getDefaultAttributeType(
-                                        woidBuffer.toString());
+            // attribute type that we don't know anything about.
+            if (allowUnknownElements)
+            {
+              attr = DirectoryServer.getDefaultAttributeType(
+                                          woidBuffer.toString());
+            }
+            else
+            {
+              int msgID = MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_REQUIRED_ATTR;
+              String message = getMessage(msgID, oid, woidBuffer.toString());
+              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                           message, msgID);
+            }
           }
 
           attrs.add(attr);
@@ -711,16 +690,19 @@
             if (attr == null)
             {
               // This isn't good because it means that the name form allows an
-              // attribute type that we don't know anything about.  In this
-              // case all we can do is log a message and construct a default
-              // type.
-              int msgID = MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_OPTIONAL_ATTR;
-              String message = getMessage(msgID, oid, woidBuffer.toString());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-
-              attr = DirectoryServer.getDefaultAttributeType(
-                                          woidBuffer.toString());
+              // attribute type that we don't know anything about.
+              if (allowUnknownElements)
+              {
+                attr = DirectoryServer.getDefaultAttributeType(
+                                            woidBuffer.toString());
+              }
+              else
+              {
+                int msgID = MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_OPTIONAL_ATTR;
+                String message = getMessage(msgID, oid, woidBuffer.toString());
+                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                             message, msgID);
+              }
             }
 
             attrs.add(attr);
@@ -752,15 +734,19 @@
           if (attr == null)
           {
             // This isn't good because it means that the name form allows an
-            // attribute type that we don't know anything about.  In this case
-            // all we can do is log a message and construct a default type.
-            int msgID = MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_OPTIONAL_ATTR;
-            String message = getMessage(msgID, oid, woidBuffer.toString());
-            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                     message, msgID);
-
-            attr = DirectoryServer.getDefaultAttributeType(
-                                        woidBuffer.toString());
+            // attribute type that we don't know anything about.
+            if (allowUnknownElements)
+            {
+              attr = DirectoryServer.getDefaultAttributeType(
+                                          woidBuffer.toString());
+            }
+            else
+            {
+              int msgID = MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_OPTIONAL_ATTR;
+              String message = getMessage(msgID, oid, woidBuffer.toString());
+              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                           message, msgID);
+            }
           }
 
           attrs.add(attr);
diff --git a/opendj-sdk/opends/src/server/org/opends/server/schema/ObjectClassSyntax.java b/opendj-sdk/opends/src/server/org/opends/server/schema/ObjectClassSyntax.java
index 627ccfb..557b4bb 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/schema/ObjectClassSyntax.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/schema/ObjectClassSyntax.java
@@ -46,18 +46,17 @@
 import org.opends.server.types.AttributeType;
 import org.opends.server.types.ByteString;
 import org.opends.server.types.DirectoryException;
-import org.opends.server.types.ErrorLogCategory;
-import org.opends.server.types.ErrorLogSeverity;
+import org.opends.server.types.InitializationException;
 import org.opends.server.types.ObjectClass;
 import org.opends.server.types.ObjectClassType;
 import org.opends.server.types.ResultCode;
 import org.opends.server.types.Schema;
 
 import static org.opends.server.loggers.Debug.*;
-import static org.opends.server.loggers.Error.*;
 import static org.opends.server.messages.MessageHandler.*;
 import static org.opends.server.messages.SchemaMessages.*;
 import static org.opends.server.schema.SchemaConstants.*;
+import static org.opends.server.util.ServerConstants.*;
 import static org.opends.server.util.StaticUtils.*;
 
 
@@ -105,17 +104,10 @@
 
 
   /**
-   * Initializes this attribute syntax based on the information in the provided
-   * configuration entry.
-   *
-   * @param  configEntry  The configuration entry that contains the information
-   *                      to use to initialize this attribute syntax.
-   *
-   * @throws  ConfigException  If an unrecoverable problem arises in the
-   *                           process of performing the initialization.
+   * {@inheritDoc}
    */
   public void initializeSyntax(ConfigEntry configEntry)
-         throws ConfigException
+         throws ConfigException, InitializationException
   {
     assert debugEnter(CLASS_NAME, "initializeSyntax",
                       String.valueOf(configEntry));
@@ -124,36 +116,37 @@
          DirectoryServer.getEqualityMatchingRule(EMR_CASE_IGNORE_OID);
     if (defaultEqualityMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE,
-               EMR_CASE_IGNORE_OID, SYNTAX_OBJECTCLASS_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE;
+      String message = getMessage(msgID, EMR_CASE_IGNORE_OID,
+                                  SYNTAX_OBJECTCLASS_NAME);
+      throw new InitializationException(msgID, message);
     }
 
     defaultOrderingMatchingRule =
          DirectoryServer.getOrderingMatchingRule(OMR_CASE_IGNORE_OID);
     if (defaultOrderingMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE,
-               OMR_CASE_IGNORE_OID, SYNTAX_OBJECTCLASS_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE;
+      String message = getMessage(msgID, OMR_CASE_IGNORE_OID,
+                                  SYNTAX_OBJECTCLASS_NAME);
+      throw new InitializationException(msgID, message);
     }
 
     defaultSubstringMatchingRule =
          DirectoryServer.getSubstringMatchingRule(SMR_CASE_IGNORE_OID);
     if (defaultSubstringMatchingRule == null)
     {
-      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
-               MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE,
-               SMR_CASE_IGNORE_OID, SYNTAX_OBJECTCLASS_NAME);
+      int    msgID   = MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE;
+      String message = getMessage(msgID, SMR_CASE_IGNORE_OID,
+                                  SYNTAX_OBJECTCLASS_NAME);
+      throw new InitializationException(msgID, message);
     }
   }
 
 
 
   /**
-   * Retrieves the common name for this attribute syntax.
-   *
-   * @return  The common name for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getSyntaxName()
   {
@@ -165,9 +158,7 @@
 
 
   /**
-   * Retrieves the OID for this attribute syntax.
-   *
-   * @return  The OID for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getOID()
   {
@@ -179,9 +170,7 @@
 
 
   /**
-   * Retrieves a description for this attribute syntax.
-   *
-   * @return  A description for this attribute syntax.
+   * {@inheritDoc}
    */
   public String getDescription()
   {
@@ -193,12 +182,7 @@
 
 
   /**
-   * Retrieves the default equality matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default equality matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if equality
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public EqualityMatchingRule getEqualityMatchingRule()
   {
@@ -210,12 +194,7 @@
 
 
   /**
-   * Retrieves the default ordering matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default ordering matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if ordering
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public OrderingMatchingRule getOrderingMatchingRule()
   {
@@ -227,12 +206,7 @@
 
 
   /**
-   * Retrieves the default substring matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default substring matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if substring
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public SubstringMatchingRule getSubstringMatchingRule()
   {
@@ -244,12 +218,7 @@
 
 
   /**
-   * Retrieves the default approximate matching rule that will be used for
-   * attributes with this syntax.
-   *
-   * @return  The default approximate matching rule that will be used for
-   *          attributes with this syntax, or <CODE>null</CODE> if approximate
-   *          matches will not be allowed for this type by default.
+   * {@inheritDoc}
    */
   public ApproximateMatchingRule getApproximateMatchingRule()
   {
@@ -262,16 +231,7 @@
 
 
   /**
-   * Indicates whether the provided value is acceptable for use in an attribute
-   * with this syntax.  If it is not, then the reason may be appended to the
-   * provided buffer.
-   *
-   * @param  value          The value for which to make the determination.
-   * @param  invalidReason  The buffer to which the invalid reason should be
-   *                        appended.
-   *
-   * @return  <CODE>true</CODE> if the provided value is acceptable for use with
-   *          this syntax, or <CODE>false</CODE> if not.
+   * {@inheritDoc}
    */
   public boolean valueIsAcceptable(ByteString value,
                                    StringBuilder invalidReason)
@@ -284,7 +244,7 @@
     // acceptable.
     try
     {
-      decodeObjectClass(value, DirectoryServer.getSchema());
+      decodeObjectClass(value, DirectoryServer.getSchema(), true);
       return true;
     }
     catch (DirectoryException de)
@@ -304,17 +264,25 @@
    * octet string value does not need to be normalized (and in fact, it should
    * not be in order to allow the desired capitalization to be preserved).
    *
-   * @param  value   The ASN.1 octet string containing the value to decode (it
-   *                 does not need to be normalized).
-   * @param  schema  The schema to use to resolve references to other schema
-   *                 elements.
+   * @param  value                 The ASN.1 octet string containing the value
+   *                               to decode (it does not need to be
+   *                               normalized).
+   * @param  schema                The schema to use to resolve references to
+   *                               other schema elements.
+   * @param  allowUnknownElements  Indicates whether to allow values that
+   *                               reference a superior class or required or
+   *                               optional attribute types which are not
+   *                               defined in the server schema.  This should
+   *                               only be true when called by
+   *                               {@code valueIsAcceptable}.
    *
    * @return  The decoded objectclass definition.
    *
    * @throws  DirectoryException  If the provided value cannot be decoded as an
    *                              objectclass definition.
    */
-  public static ObjectClass decodeObjectClass(ByteString value, Schema schema)
+  public static ObjectClass decodeObjectClass(ByteString value, Schema schema,
+                                              boolean allowUnknownElements)
          throws DirectoryException
   {
     assert debugEnter(CLASS_NAME, "decodeObjectClass", String.valueOf(value));
@@ -593,17 +561,21 @@
         superiorClass = schema.getObjectClass(woidBuffer.toString());
         if (superiorClass == null)
         {
-          // This is bad because we don't know what the superior objectclass
-          // is so we can't base this objectclass on it.  Log a message and
-          // just create a default empty superior class.
-          int    msgID   = MSGID_ATTR_SYNTAX_OBJECTCLASS_UNKNOWN_SUPERIOR_CLASS;
-          String message = getMessage(msgID, String.valueOf(oid),
-                                      String.valueOf(woidBuffer));
-          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                   message, msgID);
-
-          superiorClass =
-               DirectoryServer.getDefaultObjectClass(woidBuffer.toString());
+          if (allowUnknownElements)
+          {
+            superiorClass =
+                 DirectoryServer.getDefaultObjectClass(woidBuffer.toString());
+          }
+          else
+          {
+            // This is bad because we don't know what the superior objectclass
+            // is so we can't base this objectclass on it.
+            int msgID = MSGID_ATTR_SYNTAX_OBJECTCLASS_UNKNOWN_SUPERIOR_CLASS;
+            String message = getMessage(msgID, String.valueOf(oid),
+                                        String.valueOf(woidBuffer));
+            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                         message, msgID);
+          }
         }
 
 
@@ -652,17 +624,20 @@
             AttributeType attr = schema.getAttributeType(woidBuffer.toString());
             if (attr == null)
             {
-              // This isn't good because it means that the objectclass requires
-              // an attribute type that we don't know anything about.  In this
-              // case all we can do is log a message and construct a default
-              // type.
-              int msgID = MSGID_ATTR_SYNTAX_OBJECTCLASS_UNKNOWN_REQUIRED_ATTR;
-              String message = getMessage(msgID, oid, woidBuffer.toString());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-
-              attr = DirectoryServer.getDefaultAttributeType(
-                                          woidBuffer.toString());
+              if (allowUnknownElements)
+              {
+                attr = DirectoryServer.getDefaultAttributeType(
+                                            woidBuffer.toString());
+              }
+              else
+              {
+                // This isn't good because it means that the objectclass
+                // requires an attribute type that we don't know anything about.
+                int msgID = MSGID_ATTR_SYNTAX_OBJECTCLASS_UNKNOWN_REQUIRED_ATTR;
+                String message = getMessage(msgID, oid, woidBuffer.toString());
+                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                             message, msgID);
+              }
             }
 
             attrs.add(attr);
@@ -693,16 +668,20 @@
           AttributeType attr = schema.getAttributeType(woidBuffer.toString());
           if (attr == null)
           {
-            // This isn't good because it means that the objectclass requires an
-            // attribute type that we don't know anything about.  In this case
-            // all we can do is log a message and construct a default type.
-            int msgID = MSGID_ATTR_SYNTAX_OBJECTCLASS_UNKNOWN_REQUIRED_ATTR;
-            String message = getMessage(msgID, oid, woidBuffer.toString());
-            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                     message, msgID);
-
-            attr = DirectoryServer.getDefaultAttributeType(
-                                        woidBuffer.toString());
+            if (allowUnknownElements)
+            {
+              attr = DirectoryServer.getDefaultAttributeType(
+                                          woidBuffer.toString());
+            }
+            else
+            {
+              // This isn't good because it means that the objectclass requires
+              // an attribute type that we don't know anything about.
+              int msgID = MSGID_ATTR_SYNTAX_OBJECTCLASS_UNKNOWN_REQUIRED_ATTR;
+              String message = getMessage(msgID, oid, woidBuffer.toString());
+              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                           message, msgID);
+            }
           }
 
           attrs.add(attr);
@@ -729,17 +708,20 @@
             AttributeType attr = schema.getAttributeType(woidBuffer.toString());
             if (attr == null)
             {
-              // This isn't good because it means that the objectclass allows
-              // an attribute type that we don't know anything about.  In this
-              // case all we can do is log a message and construct a default
-              // type.
-              int msgID = MSGID_ATTR_SYNTAX_OBJECTCLASS_UNKNOWN_OPTIONAL_ATTR;
-              String message = getMessage(msgID, oid, woidBuffer.toString());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-
-              attr = DirectoryServer.getDefaultAttributeType(
-                                          woidBuffer.toString());
+              if (allowUnknownElements)
+              {
+                attr = DirectoryServer.getDefaultAttributeType(
+                                            woidBuffer.toString());
+              }
+              else
+              {
+                // This isn't good because it means that the objectclass allows
+                // an attribute type that we don't know anything about.
+                int msgID = MSGID_ATTR_SYNTAX_OBJECTCLASS_UNKNOWN_OPTIONAL_ATTR;
+                String message = getMessage(msgID, oid, woidBuffer.toString());
+                throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                             message, msgID);
+              }
             }
 
             attrs.add(attr);
@@ -770,16 +752,20 @@
           AttributeType attr = schema.getAttributeType(woidBuffer.toString());
           if (attr == null)
           {
-            // This isn't good because it means that the objectclass allows an
-            // attribute type that we don't know anything about.  In this case
-            // all we can do is log a message and construct a default type.
-            int msgID = MSGID_ATTR_SYNTAX_OBJECTCLASS_UNKNOWN_OPTIONAL_ATTR;
-            String message = getMessage(msgID, oid, woidBuffer.toString());
-            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                     message, msgID);
-
-            attr = DirectoryServer.getDefaultAttributeType(
-                                        woidBuffer.toString());
+            if (allowUnknownElements)
+            {
+              attr = DirectoryServer.getDefaultAttributeType(
+                                          woidBuffer.toString());
+            }
+            else
+            {
+              // This isn't good because it means that the objectclass allows an
+              // attribute type that we don't know anything about.
+              int msgID = MSGID_ATTR_SYNTAX_OBJECTCLASS_UNKNOWN_OPTIONAL_ATTR;
+              String message = getMessage(msgID, oid, woidBuffer.toString());
+              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                           message, msgID);
+            }
           }
 
           attrs.add(attr);
@@ -800,11 +786,73 @@
     }
 
 
-    // This should only happen for the "top" objectclass.
     if (superiorClass.getOID().equals(oid))
     {
+      // This should only happen for the "top" objectclass.
       superiorClass = null;
     }
+    else
+    {
+      // Make sure that the inheritance configuration is acceptable.
+      ObjectClassType superiorType = superiorClass.getObjectClassType();
+      switch (objectClassType)
+      {
+        case ABSTRACT:
+          // Abstract classes may only inherit from other abstract classes.
+          if (superiorType != ObjectClassType.ABSTRACT)
+          {
+            int msgID = MSGID_ATTR_SYNTAX_OBJECTCLASS_INVALID_SUPERIOR_TYPE;
+            String message = getMessage(msgID, oid, objectClassType.toString(),
+                                        superiorType.toString(),
+                                        superiorClass.getNameOrOID());
+            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                         message, msgID);
+          }
+          break;
+
+        case AUXILIARY:
+          // Auxiliary classes may only inherit from abstract classes or other
+          // auxiliary classes.
+          if ((superiorType != ObjectClassType.ABSTRACT) &&
+              (superiorType != ObjectClassType.AUXILIARY))
+          {
+            int msgID = MSGID_ATTR_SYNTAX_OBJECTCLASS_INVALID_SUPERIOR_TYPE;
+            String message = getMessage(msgID, oid, objectClassType.toString(),
+                                        superiorType.toString(),
+                                        superiorClass.getNameOrOID());
+            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                         message, msgID);
+          }
+          break;
+
+        case STRUCTURAL:
+          // Structural classes may only inherit from abstract classes or other
+          // structural classes.
+          if ((superiorType != ObjectClassType.ABSTRACT) &&
+              (superiorType != ObjectClassType.STRUCTURAL))
+          {
+            int msgID = MSGID_ATTR_SYNTAX_OBJECTCLASS_INVALID_SUPERIOR_TYPE;
+            String message = getMessage(msgID, oid, objectClassType.toString(),
+                                        superiorType.toString(),
+                                        superiorClass.getNameOrOID());
+            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                         message, msgID);
+          }
+
+          // Structural classes must have the "top" objectclass somewhere in the
+          // superior chain.
+          if (! superiorChainIncludesTop(superiorClass))
+          {
+            int msgID =
+                 MSGID_ATTR_SYNTAX_OBJECTCLASS_STRUCTURAL_SUPERIOR_NOT_TOP;
+            String message = getMessage(msgID, oid);
+            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                         message, msgID);
+          }
+          break;
+      }
+    }
+
 
 
     return new ObjectClass(value.stringValue(), primaryName, names, oid,
@@ -1341,5 +1389,35 @@
 
     return startPos;
   }
+
+
+
+  /**
+   * Indicates whether the provided objectclass or any of its superiors is equal
+   * to the "top" objectclass.
+   *
+   * @param  superiorClass  The objectclass for which to make the determination.
+   *
+   * @return  {@code true} if the provided class or any of its superiors is
+   *          equal to the "top" objectclass, or {@code false} if not.
+   */
+  private static boolean superiorChainIncludesTop(ObjectClass superiorClass)
+  {
+    assert debugEnter(CLASS_NAME, "superiorChainIncludesTop",
+                      String.valueOf(superiorClass));
+
+    if (superiorClass == null)
+    {
+      return false;
+    }
+    else if (superiorClass.hasName(OC_TOP))
+    {
+      return true;
+    }
+    else
+    {
+      return superiorChainIncludesTop(superiorClass.getSuperiorClass());
+    }
+  }
 }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/AttributeType.java b/opendj-sdk/opends/src/server/org/opends/server/types/AttributeType.java
index d87e727..c2e193a 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/AttributeType.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/AttributeType.java
@@ -404,7 +404,8 @@
     Schema     schema = DirectoryServer.getSchema();
 
     AttributeType at =
-         AttributeTypeSyntax.decodeAttributeType(value, schema);
+         AttributeTypeSyntax.decodeAttributeType(value, schema,
+                                              false);
     at.setSchemaFile(getSchemaFile());
 
     return at;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/DITContentRule.java b/opendj-sdk/opends/src/server/org/opends/server/types/DITContentRule.java
index 088a9b4..3bd23d4 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/DITContentRule.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/DITContentRule.java
@@ -257,7 +257,8 @@
     Schema     schema = DirectoryConfig.getSchema();
 
     DITContentRule dcr =
-         DITContentRuleSyntax.decodeDITContentRule(value, schema);
+         DITContentRuleSyntax.decodeDITContentRule(value, schema,
+                                                   false);
     dcr.setSchemaFile(getSchemaFile());
 
     return dcr;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/Entry.java b/opendj-sdk/opends/src/server/org/opends/server/types/Entry.java
index b0218da..8a16ba2 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/Entry.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/Entry.java
@@ -487,6 +487,14 @@
                                      message, msgID);
       }
 
+      if (oc.isObsolete())
+      {
+        int    msgID   = MSGID_ENTRY_ADD_OBSOLETE_OC;
+        String message = getMessage(msgID, name, String.valueOf(dn));
+        throw new DirectoryException(ResultCode.OBJECTCLASS_VIOLATION,
+                                     message, msgID);
+      }
+
       tmpOCMap.put(oc, name);
     }
 
@@ -2144,34 +2152,142 @@
    *       forms, DIT content rules, and DIT structure rules.</LI>
    * </UL>
    *
-   * @param  parentEntry     The entry that is the immediate parent of
-   *                         this entry, which may be checked for DIT
-   *                         structure rule conformance.  This may be
-   *                         <CODE>null</CODE> if there is no parent
-   *                         or if it is unavailable to the caller.
-   * @param  parentProvided  Indicates whether the caller attempted to
-   *                         provide the parent  If not, then the
-   *                         parent entry will be loaded on demand if
-   *                         it is required.
-   * @param  invalidReason   The buffer to which an explanation will
-   *                         be appended if this entry does not
-   *                         conform to the server's schema
-   *                         configuration.
+   * @param  parentEntry             The entry that is the immediate
+   *                                 parent of this entry, which may
+   *                                 be checked for DIT structure rule
+   *                                 conformance.  This may be
+   *                                 {@code null} if there is no
+   *                                 parent or if it is unavailable
+   *                                to the caller.
+   * @param  parentProvided          Indicates whether the caller
+   *                                 attempted to provide the parent.
+   *                                 If not, then the parent entry
+   *                                 will be loaded on demand if it is
+   *                                 required.
+   * @param  validateNameForms       Indicates whether to validate the
+   *                                 entry against name form
+   *                                 definitions.  This should only be
+   *                                 {@code true} for add and modify
+   *                                 DN operations, as well as for
+   *                                 for imports.
+   * @param  validateStructureRules  Indicates whether to validate the
+   *                                 entry against DIT structure rule
+   *                                 definitions.  This should only
+   *                                 be {@code true} for add and
+   *                                 modify DN operations.
+   * @param  invalidReason           The buffer to which an
+   *                                 explanation will be appended if
+   *                                 this entry does not conform to
+   *                                 the server's schema
+   *                                 configuration.
    *
-   * @return  <CODE>true</CODE> if this entry conforms to the server's
-   *          schema requirements, or <CODE>false</CODE> if it does
-   *          not.
+   * @return  {@code true} if this entry conforms to the server's
+   *          schema requirements, or {@code false} if it does not.
    */
   public boolean conformsToSchema(Entry parentEntry,
                                   boolean parentProvided,
+                                  boolean validateNameForms,
+                                  boolean validateStructureRules,
                                   StringBuilder invalidReason)
   {
     assert debugEnter(CLASS_NAME, "conformsToSchema",
                       "java.lang.StringBuilder");
 
 
-    // First, make sure that we recognize all of the objectclasses and
-    // that all of the required attributes are present.
+    // Get the structural objectclass for the entry.  If there isn't
+    // one, or if there's more than one, then see if that's OK.
+    AcceptRejectWarn structuralPolicy =
+         DirectoryServer.getSingleStructuralObjectClassPolicy();
+    ObjectClass structuralClass = null;
+    boolean multipleOCErrorLogged = false;
+    for (ObjectClass oc : objectClasses.keySet())
+    {
+      if (oc.getObjectClassType() == ObjectClassType.STRUCTURAL)
+      {
+        if ((structuralClass == null) ||
+            oc.isDescendantOf(structuralClass))
+        {
+          structuralClass = oc;
+        }
+        else if (! structuralClass.isDescendantOf(oc))
+        {
+          int msgID = MSGID_ENTRY_SCHEMA_MULTIPLE_STRUCTURAL_CLASSES;
+          String message = getMessage(msgID, String.valueOf(dn),
+                                structuralClass.getNameOrOID(),
+                                oc.getNameOrOID());
+
+          if (structuralPolicy == AcceptRejectWarn.REJECT)
+          {
+            invalidReason.append(message);
+            return false;
+          }
+          else if (structuralPolicy == AcceptRejectWarn.WARN)
+          {
+            if (! multipleOCErrorLogged)
+            {
+              logError(ErrorLogCategory.SCHEMA,
+                       ErrorLogSeverity.SEVERE_WARNING, message,
+                       msgID);
+              multipleOCErrorLogged = true;
+            }
+          }
+        }
+      }
+    }
+
+    NameForm         nameForm         = null;
+    DITContentRule   ditContentRule   = null;
+    DITStructureRule ditStructureRule = null;
+    if (structuralClass == null)
+    {
+      int msgID = MSGID_ENTRY_SCHEMA_NO_STRUCTURAL_CLASS;
+      String message = getMessage(msgID, String.valueOf(dn));
+
+      if (structuralPolicy == AcceptRejectWarn.REJECT)
+      {
+        invalidReason.append(message);
+        return false;
+      }
+      else if (structuralPolicy == AcceptRejectWarn.WARN)
+      {
+        logError(ErrorLogCategory.SCHEMA,
+                 ErrorLogSeverity.SEVERE_WARNING, message, msgID);
+      }
+    }
+    else
+    {
+      ditContentRule =
+           DirectoryServer.getDITContentRule(structuralClass);
+      if ((ditContentRule != null) && ditContentRule.isObsolete())
+      {
+        ditContentRule = null;
+      }
+
+      if (validateNameForms)
+      {
+        nameForm = DirectoryServer.getNameForm(structuralClass);
+        if ((nameForm != null) && nameForm.isObsolete())
+        {
+          nameForm = null;
+        }
+
+        if (validateStructureRules && (nameForm != null))
+        {
+          ditStructureRule =
+               DirectoryServer.getDITStructureRule(nameForm);
+          if ((ditStructureRule != null) &&
+              ditStructureRule.isObsolete())
+          {
+            ditStructureRule = null;
+          }
+        }
+      }
+    }
+
+
+    // Make sure that we recognize all of the objectclasses, that all
+    // auxiliary classes are allowed by the DIT content rule, and that
+    // all attributes required by the object classes are present.
     for (ObjectClass o : objectClasses.keySet())
     {
       if (DirectoryServer.getObjectClass(o.getOID()) == null)
@@ -2183,6 +2299,26 @@
         return false;
       }
 
+      if ((o.getObjectClassType() == ObjectClassType.AUXILIARY) &&
+          (ditContentRule != null) &&
+          (! ditContentRule.getAuxiliaryClasses().contains(o)))
+      {
+        int msgID = MSGID_ENTRY_SCHEMA_DISALLOWED_AUXILIARY_CLASS;
+        String message = getMessage(msgID, String.valueOf(dn),
+                                    o.getNameOrOID(),
+                                    ditContentRule.getName());
+        if (structuralPolicy == AcceptRejectWarn.REJECT)
+        {
+          invalidReason.append(message);
+          return false;
+        }
+        else if (structuralPolicy == AcceptRejectWarn.WARN)
+        {
+          logError(ErrorLogCategory.SCHEMA,
+                   ErrorLogSeverity.SEVERE_WARNING, message, msgID);
+        }
+      }
+
       for (AttributeType t : o.getRequiredAttributes())
       {
         if (! (userAttributes.containsKey(t) ||
@@ -2200,9 +2336,9 @@
     }
 
 
-    // Next, make sure all the user attributes are allowed, and make
-    // sure that if they are single-valued that they properly conform
-    // to that.
+    // Make sure all the user attributes are allowed, and make sure
+    // that if they are single-valued that they properly conform to
+    // that.
     for (AttributeType t : userAttributes.keySet())
     {
       boolean found = false;
@@ -2215,6 +2351,14 @@
         }
       }
 
+      if ((! found) && (ditContentRule != null))
+      {
+        if (ditContentRule.isRequiredOrOptional(t))
+        {
+          found = true;
+        }
+      }
+
       if (! found)
       {
         int msgID = MSGID_ENTRY_SCHEMA_DISALLOWED_USER_ATTR_FOR_OC;
@@ -2272,158 +2416,206 @@
     }
 
 
-    // Optionally, make sure that the entry contains exactly one
-    // structural objectclass.
-    AcceptRejectWarn structuralPolicy =
-         DirectoryServer.getSingleStructuralObjectClassPolicy();
-    if ((structuralPolicy == AcceptRejectWarn.REJECT) ||
-        (structuralPolicy == AcceptRejectWarn.WARN))
+    // If there is a name form for this entry, then make sure that the
+    // RDN for the entry is in compliance with it.
+    if (nameForm != null)
     {
-      ObjectClass structuralClass = null;
-      for (ObjectClass oc : objectClasses.keySet())
+      RDN rdn = dn.getRDN();
+      if (rdn != null)
       {
-        if (oc.getObjectClassType() == ObjectClassType.STRUCTURAL)
+        // Make sure that all the required attributes are present.
+        for (AttributeType t : nameForm.getRequiredAttributes())
         {
-          if (structuralClass == null)
+          if (! rdn.hasAttributeType(t))
           {
-            structuralClass = oc;
-          }
-          else
-          {
-            if (oc.isDescendantOf(structuralClass))
-            {
-              // This is acceptable, but we want to make the class the
-              // new structural class.
-              structuralClass = oc;
-            }
-            else if (! structuralClass.isDescendantOf(oc))
-            {
-              // This is not acceptable because there are multiple
-              // conflicting structural classes.
-              int msgID =
-                   MSGID_ENTRY_SCHEMA_MULTIPLE_STRUCTURAL_CLASSES;
-              String message = getMessage(msgID, String.valueOf(dn),
-                                    structuralClass.getNameOrOID(),
-                                    oc.getNameOrOID());
+            int msgID = MSGID_ENTRY_SCHEMA_RDN_MISSING_REQUIRED_ATTR;
+            String message = getMessage(msgID, String.valueOf(dn),
+                                        t.getNameOrOID(),
+                                        nameForm.getNameOrOID());
 
-              if (structuralPolicy == AcceptRejectWarn.REJECT)
-              {
-                invalidReason.append(message);
-                return false;
-              }
-              else
-              {
-                logError(ErrorLogCategory.SCHEMA,
-                         ErrorLogSeverity.SEVERE_WARNING, message,
-                         msgID);
-                break;
-              }
+            if (structuralPolicy == AcceptRejectWarn.REJECT)
+            {
+              invalidReason.append(message);
+              return false;
+            }
+            else if (structuralPolicy == AcceptRejectWarn.WARN)
+            {
+              logError(ErrorLogCategory.SCHEMA,
+                       ErrorLogSeverity.SEVERE_WARNING, message,
+                       msgID);
+            }
+          }
+        }
+
+        // Make sure that all attributes in the RDN are allowed.
+        int numAVAs = rdn.getNumValues();
+        for (int i = 0; i < numAVAs; i++)
+        {
+          AttributeType t = rdn.getAttributeType(i);
+          if (! nameForm.isRequiredOrOptional(t))
+          {
+            int    msgID   = MSGID_ENTRY_SCHEMA_RDN_DISALLOWED_ATTR;
+            String message = getMessage(msgID, String.valueOf(dn),
+                                        t.getNameOrOID(),
+                                        nameForm.getNameOrOID());
+
+            if (structuralPolicy == AcceptRejectWarn.REJECT)
+            {
+              invalidReason.append(message);
+              return false;
+            }
+            else if (structuralPolicy == AcceptRejectWarn.WARN)
+            {
+              logError(ErrorLogCategory.SCHEMA,
+                       ErrorLogSeverity.SEVERE_WARNING, message,
+                       msgID);
             }
           }
         }
       }
+    }
 
-      if (structuralClass == null)
+
+    // If there is a DIT content rule for this entry, then make sure
+    // that the entry is in compliance with it.
+    if (ditContentRule != null)
+    {
+      // Make sure that all of the required attributes are present.
+      for (AttributeType t : ditContentRule.getRequiredAttributes())
       {
-        // This is not acceptable because the entry does not contain a
-        // structural objectclass.
-        int msgID = MSGID_ENTRY_SCHEMA_NO_STRUCTURAL_CLASS;
-        String message = getMessage(msgID, String.valueOf(dn));
+        if (! (userAttributes.containsKey(t) ||
+               operationalAttributes.containsKey(t) ||
+               t.isObjectClassType()))
+        {
+          int msgID =
+               MSGID_ENTRY_SCHEMA_MISSING_REQUIRED_ATTR_FOR_DCR;
+          String message = getMessage(msgID, String.valueOf(dn),
+                                      t.getNameOrOID(),
+                                      ditContentRule.getName());
 
-        if (structuralPolicy == AcceptRejectWarn.REJECT)
-        {
-          invalidReason.append(message);
-          return false;
+          if (structuralPolicy == AcceptRejectWarn.REJECT)
+          {
+            invalidReason.append(message);
+            return false;
+          }
+          else if (structuralPolicy == AcceptRejectWarn.WARN)
+          {
+            logError(ErrorLogCategory.SCHEMA,
+                     ErrorLogSeverity.SEVERE_WARNING, message, msgID);
+          }
         }
-        else
+      }
+
+      // Make sure that none of the prohibited attributes are present.
+      for (AttributeType t : ditContentRule.getProhibitedAttributes())
+      {
+        if (userAttributes.containsKey(t) ||
+            operationalAttributes.containsKey(t))
         {
-          logError(ErrorLogCategory.SCHEMA,
-                   ErrorLogSeverity.SEVERE_WARNING, message, msgID);
+          int    msgID   = MSGID_ENTRY_SCHEMA_PROHIBITED_ATTR_FOR_DCR;
+          String message = getMessage(msgID, String.valueOf(dn),
+                                      t.getNameOrOID(),
+                                      ditContentRule.getName());
+
+          if (structuralPolicy == AcceptRejectWarn.REJECT)
+          {
+            invalidReason.append(message);
+            return false;
+          }
+          else if (structuralPolicy == AcceptRejectWarn.WARN)
+          {
+            logError(ErrorLogCategory.SCHEMA,
+                     ErrorLogSeverity.SEVERE_WARNING, message, msgID);
+          }
+        }
+      }
+    }
+
+
+    // If there is a DIT structure rule for this entry, then make sure
+    // that the entry is in compliance with it.
+    if ((ditStructureRule != null) &&
+        ditStructureRule.hasSuperiorRules())
+    {
+      if (parentProvided)
+      {
+        if (parentEntry != null)
+        {
+          boolean dsrValid =
+               validateDITStructureRule(ditStructureRule,
+                                        structuralClass, parentEntry,
+                                        structuralPolicy,
+                                        invalidReason);
+          if (! dsrValid)
+          {
+            return false;
+          }
         }
       }
       else
       {
-        // See if there is an applicable name form definition.  If so,
-        // then make sure that the entry is compliant.
-        NameForm nameForm =
-             DirectoryServer.getNameForm(structuralClass);
-        if ((nameForm != null) && (! nameForm.isObsolete()))
+        // Get the DN of the parent entry if possible.
+        DN parentDN = dn.getParentDNInSuffix();
+        if (parentDN != null)
         {
-          RDN rdn = dn.getRDN();
-          if (rdn != null)
+          // Get the parent entry and check its structural class.
+          Lock lock = null;
+          for (int i=0; i < 3; i++)
           {
-            // Make sure that all the required attributes are present.
-            for (AttributeType t : nameForm.getRequiredAttributes())
+            lock = LockManager.lockRead(parentDN);
+            if (lock != null)
             {
-              if (! rdn.hasAttributeType(t))
-              {
-                int    msgID   =
-                     MSGID_ENTRY_SCHEMA_RDN_MISSING_REQUIRED_ATTR;
-                String message = getMessage(msgID, String.valueOf(dn),
-                                            t.getNameOrOID(),
-                                            nameForm.getNameOrOID());
-
-                if (structuralPolicy == AcceptRejectWarn.REJECT)
-                {
-                  invalidReason.append(message);
-                  return false;
-                }
-                else
-                {
-                  logError(ErrorLogCategory.SCHEMA,
-                           ErrorLogSeverity.SEVERE_WARNING, message,
-                           msgID);
-                }
-              }
-            }
-
-            // Make sure that all attributes in the RDN are allowed.
-            int numAVAs = rdn.getNumValues();
-            for (int i = 0; i < numAVAs; i++)
-            {
-              AttributeType t = rdn.getAttributeType(i);
-              if (! nameForm.isRequiredOrOptional(t))
-              {
-                int msgID = MSGID_ENTRY_SCHEMA_RDN_DISALLOWED_ATTR;
-                String message = getMessage(msgID, String.valueOf(dn),
-                                            t.getNameOrOID(),
-                                            nameForm.getNameOrOID());
-
-                if (structuralPolicy == AcceptRejectWarn.REJECT)
-                {
-                  invalidReason.append(message);
-                  return false;
-                }
-                else
-                {
-                  logError(ErrorLogCategory.SCHEMA,
-                           ErrorLogSeverity.SEVERE_WARNING, message,
-                           msgID);
-                }
-              }
+              break;
             }
           }
 
-
-          // See if there is a DIT structure rule that corresponds to
-          // this name form.  If so, then make sure that the entry is
-          // acceptable according to that structure rule.  Note that
-          // we will perform this check for entries that have a
-          // parent, meaning that structure rules will not be
-          // evaluated for suffix entries.  We will also only perform
-          // validation for structure rules that have superior rules,
-          // so make sure that is the case as well.
-          DITStructureRule dsr =
-               DirectoryServer.getDITStructureRule(nameForm);
-          if ((dsr != null) && (! dsr.isObsolete()) &&
-              dsr.hasSuperiorRules())
+          if (lock == null)
           {
-            if (parentProvided)
+            int msgID = MSGID_ENTRY_SCHEMA_DSR_COULD_NOT_LOCK_PARENT;
+            String message = getMessage(msgID, String.valueOf(dn),
+                                  String.valueOf(parentDN));
+
+            if (structuralPolicy == AcceptRejectWarn.REJECT)
             {
-              if (parentEntry != null)
+              invalidReason.append(message);
+              return false;
+            }
+            else if (structuralPolicy == AcceptRejectWarn.WARN)
+            {
+              logError(ErrorLogCategory.SCHEMA,
+                       ErrorLogSeverity.SEVERE_WARNING, message,
+                       msgID);
+            }
+          }
+          else
+          {
+            try
+            {
+              parentEntry = DirectoryServer.getEntry(parentDN);
+              if (parentEntry == null)
+              {
+                int msgID = MSGID_ENTRY_SCHEMA_DSR_NO_PARENT_ENTRY;
+                String message =
+                     getMessage(msgID, String.valueOf(dn),
+                                String.valueOf(parentDN));
+
+                if (structuralPolicy == AcceptRejectWarn.REJECT)
+                {
+                  invalidReason.append(message);
+                  return false;
+                }
+                else if (structuralPolicy == AcceptRejectWarn.WARN)
+                {
+                  logError(ErrorLogCategory.SCHEMA,
+                           ErrorLogSeverity.SEVERE_WARNING, message,
+                           msgID);
+                }
+              }
+              else
               {
                 boolean dsrValid =
-                     validateDITStructureRule(dsr, structuralClass,
+                     validateDITStructureRule(ditStructureRule,
+                                              structuralClass,
                                               parentEntry,
                                               structuralPolicy,
                                               invalidReason);
@@ -2433,241 +2625,199 @@
                 }
               }
             }
-            else
+            catch (Exception e)
             {
-              // Get the DN of the parent entry if possible.
-              DN parentDN = dn.getParentDNInSuffix();
-              if (parentDN != null)
+              assert debugException(CLASS_NAME, "conformsToSchema",
+                                    e);
+
+              int    msgID   = MSGID_ENTRY_SCHEMA_COULD_NOT_CHECK_DSR;
+              String message =
+                   getMessage(msgID, String.valueOf(dn),
+                              ditStructureRule.getNameOrRuleID(),
+                              stackTraceToSingleLineString(e));
+
+              if (structuralPolicy == AcceptRejectWarn.REJECT)
               {
-                // Get the parent entry and check its structural
-                // class.
-                Lock lock = null;
-                for (int i=0; i < 3; i++)
-                {
-                  lock = LockManager.lockRead(parentDN);
-                  if (lock != null)
-                  {
-                    break;
-                  }
-                }
-
-                if (lock == null)
-                {
-                  int    msgID   =
-                       MSGID_ENTRY_SCHEMA_DSR_COULD_NOT_LOCK_PARENT;
-                  String message = getMessage(msgID,
-                                        String.valueOf(dn),
-                                        dsr.getNameOrRuleID(),
-                                        String.valueOf(parentDN));
-
-                  if (structuralPolicy == AcceptRejectWarn.REJECT)
-                  {
-                    invalidReason.append(message);
-                    return false;
-                  }
-                  else
-                  {
-                    logError(ErrorLogCategory.SCHEMA,
-                             ErrorLogSeverity.SEVERE_WARNING, message,
-                             msgID);
-                  }
-                }
-                else
-                {
-                  try
-                  {
-                    parentEntry = DirectoryServer.getEntry(parentDN);
-                    if (parentEntry == null)
-                    {
-                      int    msgID   =
-                           MSGID_ENTRY_SCHEMA_DSR_NO_PARENT_ENTRY;
-                      String message = getMessage(msgID,
-                                            String.valueOf(dn),
-                                            dsr.getNameOrRuleID(),
-                                            String.valueOf(parentDN));
-
-                      if (structuralPolicy == AcceptRejectWarn.REJECT)
-                      {
-                        invalidReason.append(message);
-                        return false;
-                      }
-                      else
-                      {
-                        logError(ErrorLogCategory.SCHEMA,
-                                 ErrorLogSeverity.SEVERE_WARNING,
-                                 message, msgID);
-                      }
-                    }
-                    else
-                    {
-                      boolean dsrValid =
-                           validateDITStructureRule(dsr,
-                                                    structuralClass,
-                                                    parentEntry,
-                                                    structuralPolicy,
-                                                    invalidReason);
-                      if (! dsrValid)
-                      {
-                        return false;
-                      }
-                    }
-                  }
-                  catch (Exception e)
-                  {
-                    assert debugException(CLASS_NAME,
-                                          "conformsToSchema", e);
-
-                    int    msgID   =
-                         MSGID_ENTRY_SCHEMA_COULD_NOT_CHECK_DSR;
-                    String message =
-                         getMessage(msgID, String.valueOf(dn),
-                                    dsr.getNameOrRuleID(),
-                                    stackTraceToSingleLineString(e));
-
-                    if (structuralPolicy == AcceptRejectWarn.REJECT)
-                    {
-                      invalidReason.append(message);
-                      return false;
-                    }
-                    else
-                    {
-                      logError(ErrorLogCategory.SCHEMA,
-                               ErrorLogSeverity.SEVERE_WARNING,
-                               message, msgID);
-                    }
-                  }
-                  finally
-                  {
-                    LockManager.unlock(parentDN, lock);
-                  }
-                }
+                invalidReason.append(message);
+                return false;
               }
+              else if (structuralPolicy == AcceptRejectWarn.WARN)
+              {
+                logError(ErrorLogCategory.SCHEMA,
+                         ErrorLogSeverity.SEVERE_WARNING, message,
+                         msgID);
+              }
+            }
+            finally
+            {
+              LockManager.unlock(parentDN, lock);
             }
           }
         }
-
-
-        // See if there is an applicable DIT content rule.  If so,
-        // then make sure that the entry is compliant.
-        DITContentRule dcr =
-             DirectoryServer.getDITContentRule(structuralClass);
-        if ((dcr != null) && (! dcr.isObsolete()))
+      }
+    }
+    else if (validateStructureRules)
+    {
+      // There is no DIT structure rule for this entry, but there may
+      // be one for the parent entry.  If there is such a rule for the
+      // parent entry, then this entry will not be valid.
+      boolean parentExists = false;
+      ObjectClass parentStructuralClass = null;
+      if (parentEntry != null)
+      {
+        parentExists = true;
+        parentStructuralClass =
+             parentEntry.getStructuralObjectClass();
+      }
+      else if (! parentProvided)
+      {
+        DN parentDN = getDN().getParentDNInSuffix();
+        if (parentDN != null)
         {
-          // Make sure that the entry contains all required
-          // attributes.
-          for (AttributeType t : dcr.getRequiredAttributes())
+          // Get the parent entry and check its structural class.
+          Lock lock = null;
+          for (int i=0; i < 3; i++)
           {
-            if (userAttributes.containsKey(t) ||
-                operationalAttributes.containsKey(t) ||
-                t.isObjectClassType())
+            lock = LockManager.lockRead(parentDN);
+            if (lock != null)
             {
               break;
             }
-            else
-            {
-              int    msgID   =
-                   MSGID_ENTRY_SCHEMA_MISSING_REQUIRED_ATTR_FOR_DCR;
-              String message = getMessage(msgID, String.valueOf(dn),
-                                          t.getNameOrOID(),
-                                          dcr.getName());
-
-              if (structuralPolicy == AcceptRejectWarn.REJECT)
-              {
-                invalidReason.append(message);
-                return false;
-              }
-              else
-              {
-                logError(ErrorLogCategory.SCHEMA,
-                         ErrorLogSeverity.SEVERE_WARNING, message,
-                         msgID);
-              }
-            }
           }
 
-          // Make sure that the entry does not contain any prohibited
-          // attributes.
-          for (AttributeType t : dcr.getProhibitedAttributes())
+          if (lock == null)
           {
-            if (userAttributes.containsKey(t) ||
-                operationalAttributes.containsKey(t))
-            {
-              int    msgID   =
-                   MSGID_ENTRY_SCHEMA_PROHIBITED_ATTR_FOR_DCR;
-              String message = getMessage(msgID, String.valueOf(dn),
-                                          t.getNameOrOID(),
-                                          dcr.getName());
+            int msgID = MSGID_ENTRY_SCHEMA_DSR_COULD_NOT_LOCK_PARENT;
+            String message = getMessage(msgID, String.valueOf(dn),
+                                  String.valueOf(parentDN));
 
-              if (structuralPolicy == AcceptRejectWarn.REJECT)
-              {
-                invalidReason.append(message);
-                return false;
-              }
-              else
-              {
-                logError(ErrorLogCategory.SCHEMA,
-                         ErrorLogSeverity.SEVERE_WARNING, message,
-                         msgID);
-              }
+            if (structuralPolicy == AcceptRejectWarn.REJECT)
+            {
+              invalidReason.append(message);
+              return false;
+            }
+            else if (structuralPolicy == AcceptRejectWarn.WARN)
+            {
+              logError(ErrorLogCategory.SCHEMA,
+                       ErrorLogSeverity.SEVERE_WARNING, message,
+                       msgID);
             }
           }
-
-          // Make sure that all user attributes are allowed.
-          for (AttributeType t : userAttributes.keySet())
+          else
           {
-            if (! dcr.isRequiredOrOptional(t, true))
+            try
             {
-              int    msgID   =
-                   MSGID_ENTRY_SCHEMA_DISALLOWED_USER_ATTR_FOR_DCR;
-              String message = getMessage(msgID, String.valueOf(dn),
-                                          t.getNameOrOID(),
-                                          dcr.getName());
-
-              if (structuralPolicy == AcceptRejectWarn.REJECT)
+              parentEntry = DirectoryServer.getEntry(parentDN);
+              if (parentEntry == null)
               {
-                invalidReason.append(message);
-                return false;
-              }
-              else
-              {
-                logError(ErrorLogCategory.SCHEMA,
-                         ErrorLogSeverity.SEVERE_WARNING, message,
-                         msgID);
-              }
-            }
-          }
-
-          // Make sure that all auxiliary objectclasses are allowed.
-          for (ObjectClass oc : objectClasses.keySet())
-          {
-            if (oc.getObjectClassType() == ObjectClassType.AUXILIARY)
-            {
-              if (! dcr.isAllowedAuxiliaryClass(oc))
-              {
-                int    msgID   =
-                     MSGID_ENTRY_SCHEMA_DISALLOWED_AUXILIARY_CLASS;
-                String message = getMessage(msgID, String.valueOf(dn),
-                                            oc.getNameOrOID(),
-                                            dcr.getName());
+                int msgID = MSGID_ENTRY_SCHEMA_DSR_NO_PARENT_ENTRY;
+                String message =
+                     getMessage(msgID, String.valueOf(dn),
+                                String.valueOf(parentDN));
 
                 if (structuralPolicy == AcceptRejectWarn.REJECT)
                 {
                   invalidReason.append(message);
                   return false;
                 }
-                else
+                else if (structuralPolicy == AcceptRejectWarn.WARN)
                 {
                   logError(ErrorLogCategory.SCHEMA,
                            ErrorLogSeverity.SEVERE_WARNING, message,
                            msgID);
                 }
               }
+              else
+              {
+                parentExists = true;
+                parentStructuralClass =
+                     parentEntry.getStructuralObjectClass();
+              }
+            }
+            catch (Exception e)
+            {
+              assert debugException(CLASS_NAME, "conformsToSchema",
+                                    e);
+
+              int msgID =
+                   MSGID_ENTRY_SCHEMA_COULD_NOT_CHECK_PARENT_DSR;
+              String message =
+                   getMessage(msgID, String.valueOf(dn),
+                              stackTraceToSingleLineString(e));
+
+              if (structuralPolicy == AcceptRejectWarn.REJECT)
+              {
+                invalidReason.append(message);
+                return false;
+              }
+              else if (structuralPolicy == AcceptRejectWarn.WARN)
+              {
+                logError(ErrorLogCategory.SCHEMA,
+                         ErrorLogSeverity.SEVERE_WARNING, message,
+                         msgID);
+              }
+            }
+            finally
+            {
+              LockManager.unlock(parentDN, lock);
+            }
+          }
+        }
+      }
+
+      if (parentExists)
+      {
+        if (parentStructuralClass == null)
+        {
+          int    msgID   = MSGID_ENTRY_SCHEMA_DSR_NO_PARENT_OC;
+          String message = getMessage(msgID, String.valueOf(dn),
+                                String.valueOf(parentEntry.getDN()));
+
+          if (structuralPolicy == AcceptRejectWarn.REJECT)
+          {
+            invalidReason.append(message);
+            return false;
+          }
+          else if (structuralPolicy == AcceptRejectWarn.WARN)
+          {
+            logError(ErrorLogCategory.SCHEMA,
+                     ErrorLogSeverity.SEVERE_WARNING, message, msgID);
+          }
+        }
+        else
+        {
+          NameForm parentNF =
+               DirectoryServer.getNameForm(parentStructuralClass);
+          if ((parentNF != null) && (! parentNF.isObsolete()))
+          {
+            DITStructureRule parentDSR =
+                 DirectoryServer.getDITStructureRule(parentNF);
+            if ((parentDSR != null) && (! parentDSR.isObsolete()))
+            {
+              int    msgID   = MSGID_ENTRY_SCHEMA_VIOLATES_PARENT_DSR;
+              String message =
+                   getMessage(msgID, String.valueOf(dn),
+                              String.valueOf(parentEntry.getDN()));
+
+              if (structuralPolicy == AcceptRejectWarn.REJECT)
+              {
+                invalidReason.append(message);
+                return false;
+              }
+              else if (structuralPolicy == AcceptRejectWarn.WARN)
+              {
+                logError(ErrorLogCategory.SCHEMA,
+                         ErrorLogSeverity.SEVERE_WARNING, message,
+                         msgID);
+              }
             }
           }
         }
       }
     }
 
+
+    // If we've gotten here, then the entry is acceptable.
     return true;
   }
 
@@ -2702,7 +2852,6 @@
     {
       int    msgID   = MSGID_ENTRY_SCHEMA_DSR_NO_PARENT_OC;
       String message = getMessage(msgID, String.valueOf(dn),
-                            dsr.getNameOrRuleID(),
                             String.valueOf(parentEntry.getDN()));
 
       if (structuralPolicy == AcceptRejectWarn.REJECT)
@@ -2710,7 +2859,7 @@
         invalidReason.append(message);
         return false;
       }
-      else
+      else if (structuralPolicy == AcceptRejectWarn.WARN)
       {
         logError(ErrorLogCategory.SCHEMA,
                  ErrorLogSeverity.SEVERE_WARNING, message,
@@ -2740,7 +2889,7 @@
         invalidReason.append(message);
         return false;
       }
-      else
+      else if (structuralPolicy == AcceptRejectWarn.WARN)
       {
         logError(ErrorLogCategory.SCHEMA,
                  ErrorLogSeverity.SEVERE_WARNING, message, msgID);
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/MatchingRuleUse.java b/opendj-sdk/opends/src/server/org/opends/server/types/MatchingRuleUse.java
index 7190358..cfad455 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/MatchingRuleUse.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/MatchingRuleUse.java
@@ -201,7 +201,8 @@
     Schema     schema = DirectoryConfig.getSchema();
 
     MatchingRuleUse mru =
-         MatchingRuleUseSyntax.decodeMatchingRuleUse(value, schema);
+         MatchingRuleUseSyntax.decodeMatchingRuleUse(value, schema,
+                                                     false);
     mru.setSchemaFile(getSchemaFile());
 
     return mru;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/NameForm.java b/opendj-sdk/opends/src/server/org/opends/server/types/NameForm.java
index eb5e8b0..bc3390b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/NameForm.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/NameForm.java
@@ -217,7 +217,7 @@
     ByteString value  = ByteStringFactory.create(definition);
     Schema     schema = DirectoryConfig.getSchema();
 
-    NameForm nf = NameFormSyntax.decodeNameForm(value, schema);
+    NameForm nf = NameFormSyntax.decodeNameForm(value, schema, false);
     nf.setSchemaFile(getSchemaFile());
 
     return nf;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/ObjectClass.java b/opendj-sdk/opends/src/server/org/opends/server/types/ObjectClass.java
index ea7c0c2..5852210 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/ObjectClass.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/ObjectClass.java
@@ -260,7 +260,7 @@
     Schema     schema = DirectoryConfig.getSchema();
 
     ObjectClass oc = ObjectClassSyntax.decodeObjectClass(value,
-                                                         schema);
+                                            schema, false);
     oc.setSchemaFile(getSchemaFile());
 
     return oc;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/util/LDIFReader.java b/opendj-sdk/opends/src/server/org/opends/server/util/LDIFReader.java
index 8b6c10b..082139d 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/util/LDIFReader.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/util/LDIFReader.java
@@ -310,7 +310,7 @@
       if (checkSchema)
       {
         StringBuilder invalidReason = new StringBuilder();
-        if (! entry.conformsToSchema(null, false, invalidReason))
+        if (! entry.conformsToSchema(null, false, true, false, invalidReason))
         {
           int    msgID   = MSGID_LDIF_SCHEMA_VIOLATION;
           String message = getMessage(msgID, String.valueOf(entryDN),
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java
index ae85150..cdf2f90 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java
@@ -835,6 +835,283 @@
 
   /**
    * Tests the behavior of the schema backend when attempting to add a new
+   * attribute type with an undefined syntax.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddAttributeTypeUndefinedSyntax()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testaddatundefinedsyntax-oid " +
+              "NAME 'testAddATUndefinedSyntax' " +
+              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.99999 SINGLE-VALUE " +
+              "X-ORGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, System.err) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new
+   * attribute type with an undefined equality matching rule.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddAttributeTypeUndefinedEMR()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testaddatundefinedemr-oid " +
+              "NAME 'testAddATUndefinedEMR' EQUALITY xxxundefinedxxx " +
+              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
+              "X-ORGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, System.err) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new
+   * attribute type with an undefined ordering matching rule.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddAttributeTypeUndefinedOMR()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testaddatundefinedomr-oid " +
+              "NAME 'testAddATUndefinedOMR' ORDERING xxxundefinedxxx " +
+              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
+              "X-ORGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, System.err) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new
+   * attribute type with an undefined substring matching rule.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddAttributeTypeUndefinedSMR()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testaddatundefinedsmr-oid " +
+              "NAME 'testAddATUndefinedSMR' SUBSTR xxxundefinedxxx " +
+              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
+              "X-ORGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, System.err) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new
+   * attribute type with an undefined approximate matching rule.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddAttributeTypeUndefinedAMR()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testaddatundefinedamr-oid " +
+              "NAME 'testAddATUndefinedAMR' " +
+              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
+              "X-APPROX 'xxxundefinedxxx' X-ORGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, System.err) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new
+   * attribute type with an invalid usage.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddAttributeTypeInvalidUsage()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testaddatundefinedsyntax-oid " +
+              "NAME 'testAddATUndefinedSyntax' " +
+              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
+              "USAGE xxxinvalidxxx X-ORGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, System.err) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new
+   * attribute type whose superior type is marked OBSOLETE in the server schema.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddAttributeTypeObsoleteSuperior()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testaddatobsoletesuperiorsup-oid " +
+              "NAME 'testAddATObsoleteSuperiorSup' OBSOLETE " +
+              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
+              "X-ORGIN 'SchemaBackendTestCase' )",
+         "attributeTypes: ( testaddatobsoletesuperior-oid " +
+              "NAME 'testAddATObsoleteSuperior' " +
+              "SUP testAddATObsoleteSuperiorSup " +
+              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
+              "X-ORGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, System.err) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new
+   * attribute type whose equality matching rule is marked OBSOLETE in the
+   * server schema.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddAttributeTypeObsoleteEMR()
+         throws Exception
+  {
+    SchemaTestMatchingRule matchingRule =
+         new SchemaTestMatchingRule("testAddATObsoleteEMRMatch",
+                                    "1.3.6.1.4.1.26027.1.999.20", true);
+    DirectoryServer.registerMatchingRule(matchingRule, false);
+
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testaddatobsoleteemr-oid " +
+              "NAME 'testAddATObsoleteEMR' " +
+              "EQUALITY testAddATObsoleteEMRMatch " +
+              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
+              "X-ORGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, System.err) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new
    * attribute type that conflicts with multiple existing types.
    *
    * @throws  Exception  If an unexpected problem occurs.
@@ -1594,6 +1871,120 @@
 
   /**
    * Tests the behavior of the schema backend when attempting to add a new
+   * objectclass that references an obsolete superior class.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddObjectClassObsoleteSuperiorClass()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses: ( testaddocobsoletesuperiorsup-oid " +
+              "NAME 'testAddOCObsoleteSuperiorSup' OBSOLETE STRUCTURAL " +
+              "MUST cn X-ORIGIN 'SchemaBackendTestCase' )",
+         "objectClasses: ( testaddocobsoletesuperior-oid " +
+              "NAME 'testAddOCObsoleteSuperior' OBSOLETE " +
+              "SUP testAddOCObsoleteSuperiorSup STRUCTURAL MUST cn " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new
+   * objectclass that references an obsolete required attribute type.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddObjectClassObsoleteRequiredAttribute()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testaddocobsoleterequiredattrat-oid " +
+              "NAME 'testAddOCObsoleteRequiredAttrAT' OBSOLETE " +
+              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
+              "X-ORIGIN 'SchemaBackendTestCase' )",
+         "-",
+         "add: objectClasses",
+         "objectClasses: ( testaddocobsoleterequiredattroc-oid " +
+              "NAME 'testAddOCObsoleteRequiredAttrOC' " +
+              "STRUCTURAL MUST testAddOCObsoleteRequiredAttrAT " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new
+   * objectclass that references an obsolete optional attribute type.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddObjectClassObsoleteOptionalAttribute()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testaddocobsoleteoptionalattrat-oid " +
+              "NAME 'testAddOCObsoleteOptionalAttrAT' OBSOLETE " +
+              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
+              "X-ORIGIN 'SchemaBackendTestCase' )",
+         "-",
+         "add: objectClasses",
+         "objectClasses: ( testaddocobsoleteoptionalattroc-oid " +
+              "NAME 'testAddOCObsoleteOptionalAttrOC' " +
+              "STRUCTURAL MAY testAddOCObsoleteOptionalAttrAT " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new
    * objectclass that references an undefined required attribute.
    *
    * @throws  Exception  If an unexpected problem occurs.
@@ -1626,6 +2017,40 @@
 
   /**
    * Tests the behavior of the schema backend when attempting to add a new
+   * objectclass that references an undefined required attribute when multiple
+   * required attributes were provided.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddObjectClassMultipleUndefinedRequiredAttribute()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses: ( testaddocmultipleundefinedrequired-oid NAME " +
+              "'testAddOCMultipleUndefinedRequired' SUP top STRUCTURAL " +
+              "MUST ( cn $ xxxundefinedxxx ) " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new
    * objectclass that references an undefined optional attribute.
    *
    * @throws  Exception  If an unexpected problem occurs.
@@ -1657,6 +2082,136 @@
 
 
   /**
+   * Tests the behavior of the schema backend when attempting to add a new
+   * objectclass that references an undefined optional attribute when multiple
+   * optional attributes were provided.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddObjectClassMultipleUndefinedOptionalAttribute()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses: ( testaddocmultipleundefinedoptional-oid NAME " +
+              "'testAddOCMultipleUndefinedOptional' SUP top STRUCTURAL " +
+              "MAY ( cn $ xxxundefinedxxx ) " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new
+   * abstract objectclass whose superior class is not abstract.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddAbstractObjectClassWithNonAbstractSuperior()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses: ( testaddabstractocwithnonabstractsuperior-oid NAME " +
+              "'testAddAbstractOCWithNonAbstractSuperior' SUP person " +
+              "ABSTRACT MAY description X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new
+   * auxiliary objectclass whose superior class is structural.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddAuxiliaryObjectClassWithStructuralSuperior()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses: ( testaddauxiliaryocwithstructuralsuperior-oid NAME " +
+              "'testAddAuxiliaryOCWithStructuralSuperior' SUP person " +
+              "AUXILIARY MAY description X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new
+   * structural objectclass whose superior class is auxiliary.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddStructuralObjectClassWithAuxiliarySuperior()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses: ( testaddstructuralocwithauxiliarysuperior-oid NAME " +
+              "'testAddStructuralOCWithAuxiliarySuperior' SUP posixAccount " +
+              "STRUCTURAL MAY description X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
    * Tests the behavior of the schema backend when attempting to remove an
    * objectclass that exists and for which there are no dependencies.
    *
@@ -1942,7 +2497,7 @@
               "MUST cn X-ORIGIN 'SchemaBackendTestCase')",
          "-",
          "add: nameForms",
-         "nameForms: ( testaddnameformwithundefinereqdat-oid " +
+         "nameForms: ( testaddnameformwithundefinedreqat-oid " +
               "NAME 'testAddNameFormWithUndefinedReqAT' " +
               "OC testAddNameFormWithUndefinedReqATOC MUST xxxundefinedxxx " +
               "X-ORIGIN 'SchemaBackendTestCase' )");
@@ -1967,6 +2522,50 @@
 
   /**
    * Tests the behavior of the schema backend when attempting to add a new name
+   * form that references a required attribute type not defined in the server
+   * schema when multiple required attributes were given.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddNameFormWithMultipleUndefinedReqAT()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testaddnameformwithmultipleundefinedreqatoc-oid " +
+              "NAME 'testAddNameFormWithMultipleUndefinedReqATOC' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+         "-",
+         "add: nameForms",
+         "nameForms: ( testaddnameformwithmultipleundefinedreqat-oid " +
+              "NAME 'testAddNameFormWithMultipleUndefinedReqAT' " +
+              "OC testAddNameFormWithMultipleUndefinedReqATOC " +
+              "MUST ( cn $ xxxundefinedxxx ) " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String nameFormName = "testaddnameformwithmultipleundefinedreqat";
+    assertFalse(DirectoryServer.getSchema().hasNameForm(nameFormName));
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+    assertFalse(DirectoryServer.getSchema().hasNameForm(nameFormName));
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new name
    * form that references an optional attribute type not defined in the server
    * schema.
    *
@@ -1985,7 +2584,7 @@
               "MUST cn X-ORIGIN 'SchemaBackendTestCase')",
          "-",
          "add: nameForms",
-         "nameForms: ( testaddnameformwithundefineoptdat-oid " +
+         "nameForms: ( testaddnameformwithundefinedoptat-oid " +
               "NAME 'testAddNameFormWithUndefinedOptAT' " +
               "OC testAddNameFormWithUndefinedOptATOC MUST cn " +
               "MAY xxxundefinedxxx X-ORIGIN 'SchemaBackendTestCase' )");
@@ -2010,6 +2609,50 @@
 
   /**
    * Tests the behavior of the schema backend when attempting to add a new name
+   * form that references an optional attribute type not defined in the server
+   * schema when multiple optional attribute types were provided.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddNameFormWithMultipleUndefinedOptAT()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testaddnameformwithmultipleundefinedoptatoc-oid " +
+              "NAME 'testAddNameFormWithMultipleUndefinedOptATOC' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+         "-",
+         "add: nameForms",
+         "nameForms: ( testaddnameformwithmultipleundefinedoptat-oid " +
+              "NAME 'testAddNameFormWithMultipleUndefinedOptAT' " +
+              "OC testAddNameFormWithMultipleUndefinedOptATOC MUST cn " +
+              "MAY ( description $ xxxundefinedxxx ) " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String nameFormName = "testaddnameformwithmultipleundefinedoptat";
+    assertFalse(DirectoryServer.getSchema().hasNameForm(nameFormName));
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+    assertFalse(DirectoryServer.getSchema().hasNameForm(nameFormName));
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new name
    * form whose structural objectclass is not defined in the server schema.
    *
    * @throws  Exception  If an unexpected problem occurs.
@@ -2088,6 +2731,136 @@
 
   /**
    * Tests the behavior of the schema backend when attempting to add a new name
+   * form whose structural objectclass is OBSOLETE rather than structural.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddNameFormWithObsoleteOC()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testaddnameformwithobsoleteococ-oid " +
+              "NAME 'testAddNameFormWithObsoleteOCOC' OBSOLETE SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+         "-",
+         "add: nameForms",
+         "nameForms: ( testaddnameformwithobsoleteoc-oid " +
+              "NAME 'testAddNameFormWithObsoleteOC' " +
+              "OC testAddNameFormWithObsoleteOCOC MUST cn " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String nameFormName = "testaddnameformwithobsoleteoc";
+    assertFalse(DirectoryServer.getSchema().hasNameForm(nameFormName));
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+    assertFalse(DirectoryServer.getSchema().hasNameForm(nameFormName));
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new name
+   * form with a required attribute type that is declared OBSOLETE.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddNameFormWithObsoleteReqAT()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testaddnfwithobsoletereqatat-oid " +
+              "NAME 'testAddNFWithObsoleteReqATAT' OBSOLETE " +
+              "X-ORIGIN 'SchemaBackendTestCase' )",
+         "-",
+         "add: objectClasses",
+         "objectClasses:  ( testaddnfwithobsoletereqatoc-oid " +
+              "NAME 'testAddNFWithObsoleteReqATOC' SUP top STRUCTURAL " +
+              "MUST cn X-ORIGIN 'SchemaBackendTestCase' )",
+         "-",
+         "add: nameForms",
+         "nameForms: ( testaddnfwithobsoletereqatnf-oid " +
+              "NAME 'testAddNFWithObsoleteReqATNF' " +
+              "OC testAddNFWithObsoleteReqATOC " +
+              "MUST testAddNFWithObsoleteReqATAT " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new name
+   * form with an optional attribute type that is declared OBSOLETE.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddNameFormWithObsoleteOptAT()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testaddnfwithobsoleteoptatat-oid " +
+              "NAME 'testAddNFWithObsoleteOptATAT' OBSOLETE " +
+              "X-ORIGIN 'SchemaBackendTestCase' )",
+         "-",
+         "add: objectClasses",
+         "objectClasses:  ( testaddnfwithobsoleteoptatoc-oid " +
+              "NAME 'testAddNFWithObsoleteOptATOC' SUP top STRUCTURAL " +
+              "MUST cn X-ORIGIN 'SchemaBackendTestCase' )",
+         "-",
+         "add: nameForms",
+         "nameForms: ( testaddnfwithobsoleteoptatnf-oid " +
+              "NAME 'testAddNFWithObsoleteOptATNF' " +
+              "OC testAddNFWithObsoleteOptATOC " +
+              "MUST cn MAY testAddNFWithObsoleteOptATAT " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new name
    * form that references a structural objectclass already referenced by another
    * name form.
    *
@@ -2585,6 +3358,43 @@
 
   /**
    * Tests the behavior of the schema backend when attempting to add a new DIT
+   * content rule whose structural objectclass is OBSOLETE.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddDITContentRuleObsoleteOC()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testaddditcontentruleobsoleteococ-oid " +
+              "NAME 'testAddDITContentRuleObsoleteOCOC' OBSOLETE SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testaddditcontentruleobsoleteococ-oid " +
+              "NAME 'testAddDITContentRuleObsoleteOC' NOT description " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new DIT
    * content rule whose structural objectclass is already referenced by an
    * existing DIT content rule.
    *
@@ -2667,6 +3477,162 @@
 
   /**
    * Tests the behavior of the schema backend when attempting to add a new DIT
+   * content rule with an undefined auxiliary objectclass when multiple
+   * auxiliary classes were provided.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddDITContentRuleMultipleUndefinedAuxOC()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testaddditcontentrulemultundefinedauxococ-oid " +
+              "NAME 'testAddDITContentRuleMultUndefinedAuxOCOC' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testaddditcontentrulemultundefinedauxococ-oid " +
+              "NAME 'testAddDITContentRuleMultUndefinedAuxOC' " +
+              "AUX ( posixAccount $ xxxundefinedxxx ) " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new DIT
+   * content rule with an auxiliary objectclass that is not auxiliary.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddDITContentRuleAuxOCNotAux()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testaddditcontentruleauxocnotauxoc-oid " +
+              "NAME 'testAddDITContentRuleAuxOCNotAuxOC' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testaddditcontentruleauxocnotaux-oid " +
+              "NAME 'testAddDITContentRuleAuxOCNotAuxOC' " +
+              "AUX person X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new DIT
+   * content rule with an auxiliary objectclass that is not auxiliary when
+   * multiple auxiliary classes were provided.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddDITContentRuleMultipleAuxOCNotAux()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testaddditcontentrulemultipleauxocnotauxoc-oid " +
+              "NAME 'testAddDITContentRuleMultipleAuxOCNotAuxOC' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testaddditcontentrulemultipleauxocnotaux-oid " +
+              "NAME 'testAddDITContentRuleMultipleAuxOCNotAuxOC' " +
+              "AUX ( posixAccount $ person ) " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new DIT
+   * content rule with an auxiliary objectclass that is OBSOLETE.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddDITContentRuleObsoleteAuxOC()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testaddditcontentruleobsoleteauxstructural-oid " +
+              "NAME 'testAddDITContentRuleObsoleteAuxOCStructural' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase' )",
+         "objectClasses:  ( testaddditcontentruleobsoleteauxauxiliary-oid " +
+              "NAME 'testAddDITContentRuleObsoleteAuxOCAuxiliary' OBSOLETE " +
+              "SUP top AUXILIARY MUST cn X-ORIGIN 'SchemaBackendTestCase' )",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testaddditcontentruleobsoleteauxstructural-oid " +
+              "NAME 'testAddDITContentRuleObsoleteAuxOC' " +
+              "AUX testAddDITContentRuleObsoleteAuxOCAuxiliary " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new DIT
    * content rule that references an undefined required attribute type.
    *
    * @throws  Exception  If an unexpected problem occurs.
@@ -2680,8 +3646,8 @@
          "changetype: modify",
          "add: objectClasses",
          "objectClasses:  ( testaddditcontentruleundefinedreqatoc-oid " +
-              "NAME 'testAddDITContentRuleAuxiliaryOCOC' SUP top STRUCTURAL " +
-              "MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+              "NAME 'testAddDITContentRuleUndefinedReqATOC' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
          "-",
          "add: ditContentRules",
          "ditContentRules: ( testaddditcontentruleundefinedreqatoc-oid " +
@@ -2704,6 +3670,45 @@
 
   /**
    * Tests the behavior of the schema backend when attempting to add a new DIT
+   * content rule that references an undefined required attribute type when
+   * multiple required attributes were provided.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddDITContentRuleMultipleUndefinedReqAT()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testaddditcontentrulemultundefinedreqatoc-oid " +
+              "NAME 'testAddDITContentRuleMultUndefinedReqATOC' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testaddditcontentrulemultundefinedreqatoc-oid " +
+              "NAME 'testAddDITContentMultRuleUndefinedReqAT' " +
+              "MUST ( cn $ xxxundefinedxxx ) " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new DIT
    * content rule that references an undefined optional attribute type.
    *
    * @throws  Exception  If an unexpected problem occurs.
@@ -2717,8 +3722,8 @@
          "changetype: modify",
          "add: objectClasses",
          "objectClasses:  ( testaddditcontentruleundefinedoptatoc-oid " +
-              "NAME 'testAddDITContentRuleAuxiliaryOCOC' SUP top STRUCTURAL " +
-              "MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+              "NAME 'testAddDITContentRuleUndefinedOptATOC' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
          "-",
          "add: ditContentRules",
          "ditContentRules: ( testaddditcontentruleundefinedoptatoc-oid " +
@@ -2741,6 +3746,45 @@
 
   /**
    * Tests the behavior of the schema backend when attempting to add a new DIT
+   * content rule that references an undefined optional attribute type when
+   * multiple optional attributes were provided.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddDITContentRuleMultipleUndefinedOptAT()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testaddditcontentrulemultundefinedoptatoc-oid " +
+              "NAME 'testAddDITContentRuleMultUndefinedOptATOC' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testaddditcontentrulemultundefinedoptatoc-oid " +
+              "NAME 'testAddDITContentRuleMultUndefinedOptAT' " +
+              "MAY ( cn $ xxxundefinedxxx ) " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new DIT
    * content rule that references an undefined prohibited attribute type.
    *
    * @throws  Exception  If an unexpected problem occurs.
@@ -2754,8 +3798,8 @@
          "changetype: modify",
          "add: objectClasses",
          "objectClasses:  ( testaddditcontentruleundefinednotatoc-oid " +
-              "NAME 'testAddDITContentRuleAuxiliaryOCOC' SUP top STRUCTURAL " +
-              "MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+              "NAME 'testAddDITContentRuleUndefinedNotATOC' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
          "-",
          "add: ditContentRules",
          "ditContentRules: ( testaddditcontentruleundefinednotatoc-oid " +
@@ -2777,6 +3821,250 @@
 
 
   /**
+   * Tests the behavior of the schema backend when attempting to add a new DIT
+   * content rule that references an undefined prohibited attribute type when
+   * multiple prohibited attributes were provided.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddDITContentRuleMultipleUndefinedNotAT()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testaddditcontentrulemultundefinednotatoc-oid " +
+              "NAME 'testAddDITContentRuleMultUndefinedNotATOC' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testaddditcontentrulemultundefinednotatoc-oid " +
+              "NAME 'testAddDITContentRuleMultUndefinedNotAT' " +
+              "NOT ( description $ xxxundefinedxxx ) " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new DIT
+   * content rule that prohibits an attribute type that is required by the
+   * structural object class.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddDITContentRuleProhibitRequiredStructuralAttribute()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testadddcrprohibitreqstructuralatoc-oid " +
+              "NAME 'testAddDCRProhibitReqStructuralATOC' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testadddcrprohibitreqstructuralatoc-oid " +
+              "NAME 'testAddDCRProhibitReqStructuralAT' " +
+              "NOT cn X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new DIT
+   * content rule that prohibits an attribute type that is required by an
+   * associated auxiliary object class.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddDITContentRuleProhibitRequiredAuxiliaryAttribute()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testadddcrprohibitreqauxiliaryatoc-oid " +
+              "NAME 'testAddDCRProhibitReqAuxiliaryATOC' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testadddcrprohibitreqauxiliaryatoc-oid " +
+              "NAME 'testAddDCRProhibitReqAuxiliaryAT' AUX posixAccount " +
+              "NOT uid X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new DIT
+   * content rule with an OBSOLETE required attribute type.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddDITContentRuleObsoleteRequiredAttributeType()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testadddcrobsoletereqatat-oid " +
+              "NAME 'testAddDCRObsoleteReqATAT' OBSOLETE " +
+              "X-ORIGIN 'SchemaBackendTestCase' )",
+         "-",
+         "add: objectClasses",
+         "objectClasses:  ( testadddcrobsoletereqatoc-oid " +
+              "NAME 'testAddDCRObsoleteReqATOC' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testadddcrobsoletereqatoc-oid " +
+              "NAME 'testAddDCRObsoleteReqATDCR' " +
+              "MUST testAddDCRObsoleteReqATAT " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new DIT
+   * content rule with an OBSOLETE optional attribute type.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddDITContentRuleObsoleteOptionalAttributeType()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testadddcrobsoleteoptatat-oid " +
+              "NAME 'testAddDCRObsoleteOptATAT' OBSOLETE " +
+              "X-ORIGIN 'SchemaBackendTestCase' )",
+         "-",
+         "add: objectClasses",
+         "objectClasses:  ( testadddcrobsoleteoptatoc-oid " +
+              "NAME 'testAddDCRObsoleteOptATOC' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testadddcrobsoleteoptatoc-oid " +
+              "NAME 'testAddDCRObsoleteOptATDCR' " +
+              "MAY testAddDCRObsoleteOptATAT " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new DIT
+   * content rule with an OBSOLETE prohibited attribute type.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddDITContentRuleObsoleteProhibitedAttributeType()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testadddcrobsoletenotatat-oid " +
+              "NAME 'testAddDCRObsoleteNotATAT' OBSOLETE " +
+              "X-ORIGIN 'SchemaBackendTestCase' )",
+         "-",
+         "add: objectClasses",
+         "objectClasses:  ( testadddcrobsoletenotatoc-oid " +
+              "NAME 'testAddDCRObsoleteNotATOC' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testadddcrobsoletenotatoc-oid " +
+              "NAME 'testAddDCRObsoleteNotATDCR' " +
+              "NOT testAddDCRObsoleteNotATAT " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
    * Tests the behavior of the schema backend when attempting to remove an
    * existing DIT content rule.
    *
@@ -3141,6 +4429,105 @@
 
 
   /**
+   * Tests the behavior of the schema backend when attempting to add a new
+   * DIT structure rule that references a name form which is OBSOLETE.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddDITStructureRuleObsoleteNameForm()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testaddditstructureruleobsoletenameformoc-oid " +
+              "NAME 'testAddDITStructureRuleObsoleteNameFormOC' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+         "-",
+         "add: nameForms",
+         "nameForms: ( testaddditstructureruleobsoletenameformnf-oid " +
+              "NAME 'testAddDITStructureRuleObsoleteNameFormNF' OBSOLETE " +
+              "OC testAddDITStructureRuleObsoleteNameFormOC MUST cn " +
+              "X-ORIGIN 'SchemaBackendTestCase' )",
+         "-",
+         "add: ditStructureRules",
+         "ditStructureRules: ( 999011 " +
+              "NAME 'testAddDITStructureRuleObsoleteNameForm' " +
+              "FORM testAddDITStructureRuleObsoleteNameFormNF " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new
+   * DIT structure rule that references a superior rule which is OBSOLETE.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddDITStructureRuleObsoleteSuperiorRule()
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testaddditstructureruleobsoletesuperioroc1-oid " +
+              "NAME 'testAddDITStructureRuleObsoleteSuperiorOC1' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+         "objectClasses:  ( testaddditstructureruleobsoletesuperioroc2-oid " +
+              "NAME 'testAddDITStructureRuleObsoleteSuperiorOC2' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+         "-",
+         "add: nameForms",
+         "nameForms: ( testaddditstructureruleobsoletesuperiornf1-oid " +
+              "NAME 'testAddDITStructureRuleObsoleteSuperiorNF1' " +
+              "OC testAddDITStructureRuleObsoleteSuperiorOC1 MUST cn " +
+              "X-ORIGIN 'SchemaBackendTestCase' )",
+         "nameForms: ( testaddditstructureruleobsoletesuperiornf2-oid " +
+              "NAME 'testAddDITStructureRuleObsoleteSuperiorNF2' " +
+              "OC testAddDITStructureRuleObsoleteSuperiorOC2 MUST cn " +
+              "X-ORIGIN 'SchemaBackendTestCase' )",
+         "-",
+         "add: ditStructureRules",
+         "ditStructureRules: ( 999012 " +
+              "NAME 'testAddDITStructureRuleObsoleteSuperiorSup' OBSOLETE " +
+              "FORM testAddDITStructureRuleObsoleteSuperiorNF1 " +
+              "X-ORIGIN 'SchemaBackendTestCase' )",
+         "ditStructureRules: ( 999013 " +
+              "NAME 'testAddDITStructureRuleObsoleteSuperiorSub' " +
+              "FORM testAddDITStructureRuleObsoleteSuperiorNF2 SUP 999012 " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
    * Tests the behavior of the schema backend when attempting to remove an
    * existing DIT structure rule definition.
    *
@@ -3623,6 +5010,132 @@
 
 
   /**
+   * Tests the behavior of the schema backend when attempting to add a new
+   * matching rule use that references an undefined attribute type.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddMatchingRuleUseAttributeTypeMultipleUndefined()
+         throws Exception
+  {
+    SchemaTestMatchingRule matchingRule =
+         new SchemaTestMatchingRule("testAddMRUATMultipleUndefinedMatch",
+                                    "1.3.6.1.4.1.26027.1.999.19");
+    DirectoryServer.registerMatchingRule(matchingRule, false);
+
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: matchingRuleUse",
+         "matchingRuleUse: ( 1.3.6.1.4.1.26027.1.999.19 " +
+              "NAME 'testAddMatchingRuleUseATMultipleUndefined' " +
+              "APPLIES ( cn $ xxxundefinedxxx ) " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    assertFalse(DirectoryServer.getSchema().hasMatchingRuleUse(matchingRule));
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new
+   * matching rule whose matching rule is OBSOLETE.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddMatchingRuleUseObsoleteMatchingRule()
+         throws Exception
+  {
+    SchemaTestMatchingRule matchingRule =
+         new SchemaTestMatchingRule("testAddMRUObsoleteMRMatch",
+                                    "1.3.6.1.4.1.26027.1.999.21", true);
+    DirectoryServer.registerMatchingRule(matchingRule, false);
+
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: matchingRuleUse",
+         "matchingRuleUse: ( 1.3.6.1.4.1.26027.1.999.21 " +
+              "NAME 'testAddMatchingRuleUseObsoleteMatchingRule' " +
+              "APPLIES cn X-ORIGIN 'SchemaBackendTestCase' )");
+
+    assertFalse(DirectoryServer.getSchema().hasMatchingRuleUse(matchingRule));
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests the behavior of the schema backend when attempting to add a new
+   * matching rule with an associated attribute type that is marked OBSOLETE.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddMatchingRuleUseObsoleteAttributeType()
+         throws Exception
+  {
+    SchemaTestMatchingRule matchingRule =
+         new SchemaTestMatchingRule("testAddMRUObsoleteATMatch",
+                                    "1.3.6.1.4.1.26027.1.999.22");
+    DirectoryServer.registerMatchingRule(matchingRule, false);
+
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testaddmruobsoleteat-oid " +
+              "NAME 'testAddMRUObsoleteAT' OBSOLETE )",
+         "-",
+         "add: matchingRuleUse",
+         "matchingRuleUse: ( 1.3.6.1.4.1.26027.1.999.22 " +
+              "NAME 'testAddMatchingRuleUseObsoleteAttributeType' " +
+              "APPLIES testAddMRUObsoleteAT " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    assertFalse(DirectoryServer.getSchema().hasMatchingRuleUse(matchingRule));
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
    * Tests the behavior of the schema backend when attempting to remove an
    * existing matching rule use.
    *
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaTestMatchingRule.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaTestMatchingRule.java
index 14f5b57..16a3da6 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaTestMatchingRule.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaTestMatchingRule.java
@@ -47,6 +47,9 @@
 public class SchemaTestMatchingRule
        extends EqualityMatchingRule
 {
+  // Indicates whether this matching rule should be considered OBSOLETE.
+  private boolean isObsolete;
+
   // The matching rule that will do all the real work behind the scenes.
   private CaseIgnoreEqualityMatchingRule caseIgnoreMatchingRule;
 
@@ -76,6 +79,32 @@
 
     caseIgnoreMatchingRule = new CaseIgnoreEqualityMatchingRule();
     caseIgnoreMatchingRule.initializeMatchingRule(null);
+    isObsolete = false;
+  }
+
+
+
+  /**
+   * Creates a new instance of this matching rule with the provided information.
+   *
+   * @param  name        The name to use for this matching rule.
+   * @param  oid         The OID to use for this matching rule.
+   * @param  isObsolete  Indicates whether this matching rule should be marked
+   *                     OBSOLETE.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  public SchemaTestMatchingRule(String name, String oid, boolean isObsolete)
+         throws Exception
+  {
+    super();
+
+    this.name       = name;
+    this.oid        = oid;
+    this.isObsolete = isObsolete;
+
+    caseIgnoreMatchingRule = new CaseIgnoreEqualityMatchingRule();
+    caseIgnoreMatchingRule.initializeMatchingRule(null);
   }
 
 
@@ -154,6 +183,16 @@
 
 
   /**
+   * {@inheritDoc}
+   */
+  public boolean isObsolete()
+  {
+    return isObsolete;
+  }
+
+
+
+  /**
    * Retrieves the normalized form of the provided value, which is best suited
    * for efficiently performing matching operations on that value.
    *
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java
index cd66f54..8c2db5e 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java
@@ -53,6 +53,7 @@
 import org.opends.server.protocols.ldap.BindResponseProtocolOp;
 import org.opends.server.protocols.ldap.LDAPAttribute;
 import org.opends.server.protocols.ldap.LDAPMessage;
+import org.opends.server.tools.LDAPModify;
 import org.opends.server.types.Attribute;
 import org.opends.server.types.AttributeType;
 import org.opends.server.types.AttributeValue;
@@ -2271,5 +2272,180 @@
       s.close();
     } catch (Exception e) {}
   }
+
+
+
+  /**
+   * Tests an add operation that attempts to add an entry with a user attribute
+   * marked OBSOLETE in the server schema.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddObsoleteUserAttribute()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(false);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testaddobsoleteuserattribute-oid " +
+              "NAME 'testAddObsoleteUserAttribute' OBSOLETE " +
+              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
+              "X-ORGIN 'SchemaBackendTestCase' )");
+
+    String attrName = "testaddobsoleteuserattribute";
+    assertFalse(DirectoryServer.getSchema().hasAttributeType(attrName));
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+    assertTrue(DirectoryServer.getSchema().hasAttributeType(attrName));
+
+    path = TestCaseUtils.createTempFile(
+         "dn: o=test",
+         "changetype: add",
+         "objectClass: top",
+         "objectClass: organization",
+         "objectClass: extensibleObject",
+         "o: test",
+         "testAddObsoleteUserAttribute: foo");
+
+    args = new String[]
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests an add operation that attempts to add an entry with an operational
+   * attribute marked OBSOLETE in the server schema.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddObsoleteOperationalAttribute()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(false);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testaddobsoleteoperationalattribute-oid " +
+              "NAME 'testAddObsoleteOperationalAttribute' OBSOLETE " +
+              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
+              "USAGE directoryOperation X-ORGIN 'SchemaBackendTestCase' )");
+
+    String attrName = "testaddobsoleteoperationalattribute";
+    assertFalse(DirectoryServer.getSchema().hasAttributeType(attrName));
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+    assertTrue(DirectoryServer.getSchema().hasAttributeType(attrName));
+
+    path = TestCaseUtils.createTempFile(
+         "dn: o=test",
+         "changetype: add",
+         "objectClass: top",
+         "objectClass: organization",
+         "objectClass: extensibleObject",
+         "o: test",
+         "testAddObsoleteOperationalAttribute: foo");
+
+    args = new String[]
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests an add operation that attempts to add an entry with an auxiliary
+   * objectclass marked OBSOLETE in the server schema.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddObsoleteObjectClass()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(false);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses: ( testaddobsoleteobjectclass-oid " +
+              "NAME 'testAddObsoleteObjectClass' OBSOLETE AUXILIARY " +
+              "MAY description X-ORGIN 'SchemaBackendTestCase' )");
+
+    String ocName = "testaddobsoleteobjectclass";
+    assertFalse(DirectoryServer.getSchema().hasObjectClass(ocName));
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+    assertTrue(DirectoryServer.getSchema().hasObjectClass(ocName));
+
+    path = TestCaseUtils.createTempFile(
+         "dn: o=test",
+         "changetype: add",
+         "objectClass: top",
+         "objectClass: organization",
+         "objectClass: testAddObsoleteObjectClass",
+         "o: test");
+
+    args = new String[]
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
 }
 
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java
index 73b08df..28c818d 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java
@@ -55,6 +55,7 @@
 import org.opends.server.protocols.ldap.LDAPMessage;
 import org.opends.server.protocols.ldap.LDAPModification;
 import org.opends.server.protocols.ldap.LDAPFilter;
+import org.opends.server.tools.LDAPModify;
 import org.opends.server.types.*;
 
 import static org.testng.Assert.*;
@@ -4384,5 +4385,122 @@
     } catch (Exception e) {}
   }
 
+
+
+  /**
+   * Tests a modify operation that attemtps to set a value for an attribute type
+   * that is marked OBSOLETE in the server schema.
+   *
+   * @param  baseDN  The base DN for the test backend.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test(dataProvider = "baseDNs")
+  public void testModifyObsoleteAttribute(String baseDN)
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testmodifyobsoleteattribute-oid " +
+              "NAME 'testModifyObsoleteAttribute' OBSOLETE " +
+              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
+              "X-ORGIN 'SchemaBackendTestCase' )");
+
+    String attrName = "testmodifyobsoleteattribute";
+    assertFalse(DirectoryServer.getSchema().hasAttributeType(attrName));
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+    assertTrue(DirectoryServer.getSchema().hasAttributeType(attrName));
+
+    TestCaseUtils.clearJEBackend(true,"userRoot",baseDN);
+
+    path = TestCaseUtils.createTempFile(
+         "dn: " + baseDN,
+         "changetype: modify",
+         "add: objectClass",
+         "objectClass: extensibleObject",
+         "-",
+         "replace: testModifyObsoleteAttribute",
+         "testModifyObsoleteAttribute: foo");
+
+    args = new String[]
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Tests a modify operation that attemtps to add an OBSOLETE object class to
+   * an entry.
+   *
+   * @param  baseDN  The base DN for the test backend.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test(dataProvider = "baseDNs")
+  public void testModifyAddObsoleteObjectClass(String baseDN)
+         throws Exception
+  {
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses: ( testmodifyaddobsoleteobjectclass-oid " +
+              "NAME 'testModifyAddObsoleteObjectClass' OBSOLETE " +
+              "AUXILIARY MAY description X-ORGIN 'SchemaBackendTestCase' )");
+
+    String ocName = "testmodifyaddobsoleteobjectclass";
+    assertFalse(DirectoryServer.getSchema().hasObjectClass(ocName));
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+    assertTrue(DirectoryServer.getSchema().hasObjectClass(ocName));
+
+    TestCaseUtils.clearJEBackend(true,"userRoot",baseDN);
+
+    path = TestCaseUtils.createTempFile(
+         "dn: " + baseDN,
+         "changetype: modify",
+         "add: objectClass",
+         "objectClass: testModifyAddObsoleteObjectClass");
+
+    args = new String[]
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
 }
 
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestModifyDNOperation.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestModifyDNOperation.java
index 5b731e9..1925f82 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestModifyDNOperation.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestModifyDNOperation.java
@@ -45,6 +45,7 @@
 import org.opends.server.controls.LDAPAssertionRequestControl;
 import org.opends.server.plugins.InvocationCounterPlugin;
 import org.opends.server.plugins.ShortCircuitPlugin;
+import org.opends.server.tools.LDAPModify;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -1208,4 +1209,69 @@
     }
 
   }
+
+
+
+  /**
+   * Tests performing a modify DN operation in which the new RDN contains an
+   * attribute type marked OBSOLETE in the server schema.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testModifyDNWithObsoleteAttribute()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: attributeTypes",
+         "attributeTypes: ( testmodifydnwithobsoleteattribute-oid " +
+              "NAME 'testModifyDNWithObsoleteAttribute' OBSOLETE " +
+              "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
+              "X-ORGIN 'SchemaBackendTestCase' )");
+
+    String attrName = "testmodifydnwithobsoleteattribute";
+    assertFalse(DirectoryServer.getSchema().hasAttributeType(attrName));
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+    assertTrue(DirectoryServer.getSchema().hasAttributeType(attrName));
+
+    path = TestCaseUtils.createTempFile(
+         "dn: cn=oldrdn,o=test",
+         "changetype: add",
+         "objectClass: top",
+         "objectClass: device",
+         "objectClass: extensibleObject",
+         "cn: oldrdn",
+         "",
+         "dn: cn=oldrdn,o=test",
+         "changetype: moddn",
+         "newRDN: testModifyDNWithObsoleteAttribute=foo",
+         "deleteOldRDN: 0"
+    );
+
+    args = new String[]
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
 }
+
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/AttributeTypeSyntaxTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/AttributeTypeSyntaxTest.java
index 4c69a52..d9bb87b 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/AttributeTypeSyntaxTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/AttributeTypeSyntaxTest.java
@@ -61,14 +61,46 @@
   public Object[][] createAcceptableValues()
   {
     return new Object [][] {
-        {"(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE SUP 1.2" +
-          " EQUALITY 2.3 ORDERING 5.6 SUBSTR 7.8 SYNTAX 9.1 SINGLE-VALUE" +
-          " COLLECTIVE NO-USER-MODIFICATION USAGE directoryOperations )",
+        {"(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE SUP cn " +
+          " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch" +
+          " SUBSTR caseIgnoreSubstringsMatch" +
+          " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE" +
+          " USAGE userApplications )",
+          true},
+        {"(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE " +
+          " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch" +
+          " SUBSTR caseIgnoreSubstringsMatch" +
+          " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE" +
+          " COLLECTIVE USAGE userApplications )",
           true},
         {"(1.2.8.5 NAME 'testtype' DESC 'full type')",
               true},
-        {"(1.2.8.5 USAGE directoryOperations )",
+        {"(1.2.8.5 USAGE directoryOperation )",
               true},
+        {"(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE SUP cn " +
+          " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch" +
+          " SUBSTR caseIgnoreSubstringsMatch" +
+          " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE" +
+          " COLLECTIVE USAGE userApplications )",
+          false}, // Collective can't inherit from non-collective
+        {"(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE " +
+          " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch" +
+          " SUBSTR caseIgnoreSubstringsMatch" +
+          " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE" +
+          " COLLECTIVE USAGE directoryOperation )",
+          false}, // Collective can't be operational
+        {"(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE SUP cn " +
+          " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch" +
+          " SUBSTR caseIgnoreSubstringsMatch" +
+          " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE" +
+          " NO-USER-MODIFICATION USAGE directoryOperation )",
+          false}, // directoryOperation can't inherit from userApplications
+        {"(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE " +
+          " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch" +
+          " SUBSTR caseIgnoreSubstringsMatch" +
+          " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE" +
+          " NO-USER-MODIFICATION USAGE userApplications )",
+          false}, // NO-USER-MODIFICATION can't have non-operational usage
     };
   }
 
@@ -113,7 +145,8 @@
     // correct approximate matching rule.
     AttributeType attrType =
          AttributeTypeSyntax.decodeAttributeType(definition,
-                                                 DirectoryServer.getSchema());
+                                                 DirectoryServer.getSchema(),
+                                                 false);
     assertNotNull(attrType);
     assertNotNull(attrType.getApproximateMatchingRule());
     assertEquals(attrType.getApproximateMatchingRule(), testApproxRule);
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/DITContentRuleSyntaxTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/DITContentRuleSyntaxTest.java
index 434ce34..7953916 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/DITContentRuleSyntaxTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/DITContentRuleSyntaxTest.java
@@ -53,21 +53,21 @@
              + "( x121Address $ telexNumber ) )", true},
         {"( 2.5.6.4 NAME 'full rule' DESC 'rule with all possible fields' "
               + " OBSOLETE"
-              + " AUX ( person )"
+              + " AUX ( posixAccount )"
               + " MUST ( cn $ sn )"
               + " MAY ( dc )"
               + " NOT ( x121Address $ telexNumber ) )"
                 , true},
         {"( 2.5.6.4 NAME 'full rule' DESC 'ommit parenthesis' "
                   + " OBSOLETE"
-                  + " AUX person "
+                  + " AUX posixAccount "
                   + " MUST cn "
                   + " MAY dc "
                   + " NOT x121Address )"
               , true},
          {"( 2.5.6.4 NAME 'full rule' DESC 'use numeric OIDs' "
                 + " OBSOLETE"
-                + " AUX 2.5.6.6"
+                + " AUX 1.3.6.1.1.1.2.0"
                 + " MUST cn "
                 + " MAY dc "
                 + " NOT x121Address )"
@@ -88,7 +88,7 @@
                  , false},
          {"( 2.5.6.4 NAME 'full rule' DESC 'missing closing parenthesis' "
                  + " OBSOLETE"
-                 + " AUX person "
+                 + " AUX posixAccount"
                  + " MUST cn "
                  + " MAY dc "
                  + " NOT x121Address"
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/EntrySchemaCheckingTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/EntrySchemaCheckingTestCase.java
new file mode 100644
index 0000000..388f68b
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/EntrySchemaCheckingTestCase.java
@@ -0,0 +1,1433 @@
+/*
+ * 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 2006 Sun Microsystems, Inc.
+ */
+package org.opends.server.types;
+
+
+
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+
+import org.testng.annotations.Test;
+
+import org.opends.server.TestCaseUtils;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.tools.LDAPModify;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.AttributeType;
+import org.opends.server.types.AttributeValue;
+
+import static org.testng.Assert.*;
+
+import static org.opends.server.types.AcceptRejectWarn.*;
+
+
+
+/**
+ * This class provides a set of test cases that cover the schema validation
+ * processing that should be performed on entries during add, modify, and
+ * modify DN operations.
+ */
+public class EntrySchemaCheckingTestCase
+       extends TypesTestCase
+{
+  /**
+   * Ensures that the provided entry fails schema checking validation with
+   * strict compliance enabled, but will pass in a more relaxed configuration.
+   *
+   * @param  e  The entry to be tested.
+   */
+  private void failOnlyForStrictEvaluation(Entry e)
+  {
+    try
+    {
+      StringBuilder invalidReason = new StringBuilder();
+      DirectoryServer.setSingleStructuralObjectClassPolicy(REJECT);
+      assertFalse(e.conformsToSchema(null, false, true, true, invalidReason),
+                  "Entry validation succeeded with REJECT policy");
+
+      DirectoryServer.setSingleStructuralObjectClassPolicy(WARN);
+      assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
+                 "Entry validation failed with WARN policy:  " +
+                 invalidReason.toString());
+
+      DirectoryServer.setSingleStructuralObjectClassPolicy(ACCEPT);
+      assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
+                 "Entry validation failed with ACCEPT policy:  " +
+                 invalidReason.toString());
+    }
+    finally
+    {
+      DirectoryServer.setSingleStructuralObjectClassPolicy(REJECT);
+    }
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry with a valid single structural
+   * objectclass.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testValidSingleStructuralClass()
+         throws Exception
+  {
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: dc=example,dc=com",
+         "objectClass: top",
+         "objectClass: domain",
+         "dc: example");
+
+    StringBuilder invalidReason = new StringBuilder();
+    assertTrue(e.conformsToSchema(null, true, true, true, invalidReason),
+               invalidReason.toString());
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry (not covered by a DIT content rule)
+   * with a valid single structural objectclass as well as an auxiliary
+   * objectclass.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testValidSingleStructuralClassAndAuxiliaryClass()
+         throws Exception
+  {
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: dc=example,dc=com",
+         "objectClass: top",
+         "objectClass: organization",
+         "objectClass: dcObject",
+         "dc: example",
+         "o: Example Org");
+
+    StringBuilder invalidReason = new StringBuilder();
+    assertTrue(e.conformsToSchema(null, true, true, true, invalidReason),
+               invalidReason.toString());
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry that does not contain a structural
+   * objectclass.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testNoStructuralClass()
+         throws Exception
+  {
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: dc=example,dc=com",
+         "objectClass: top",
+         "objectClass: dcObject",
+         "dc: example");
+
+    failOnlyForStrictEvaluation(e);
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry that contains multiple structural
+   * objectclasses.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testMultipleStructuralClasses()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: uid=test.user,o=test",
+         "objectClass: top",
+         "objectClass: person",
+         "objectClass: organizationalPerson",
+         "objectClass: inetOrgPerson",
+         "objectClass: account",
+         "uid: test.user",
+         "givenName: Test",
+         "sn: User",
+         "cn: Test User");
+
+    failOnlyForStrictEvaluation(e);
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry that contains an undefined objectclass
+   * with no other structural class.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testUndefinedStructuralObjectClass()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test,o=test",
+         "objectClass: top",
+         "objectClass: xxxundefinedstructuralxxx",
+         "cn: test");
+
+    assertFalse(e.conformsToSchema(null, false, true, true,
+                                   new StringBuilder()));
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry that contains an undefined objectclass
+   * as well as a valid structural class.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testUndefinedAuxiliaryObjectClass()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test,o=test",
+         "objectClass: top",
+         "objectClass: device",
+         "objectClass: xxxundefinedauxiliaryxxx",
+         "cn: test");
+
+    assertFalse(e.conformsToSchema(null, false, true, true,
+                                   new StringBuilder()));
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry that is missing an attribute required
+   * by its structural object class.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testMissingAttributeRequiredByStructuralClass()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testmissingatrequiredbystructuraloc-oid " +
+              "NAME 'testMissingATRequiredByStructuralOC' SUP top STRUCTURAL " +
+              "MUST ( cn $ description ) " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase')");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test,o=test",
+         "objectClass: top",
+         "objectClass: testMissingATRequiredByStructuralOC",
+         "cn: test");
+
+    assertFalse(e.conformsToSchema(null, false, true, true,
+                                   new StringBuilder()));
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry that is missing an attribute required
+   * by an auxiliary object class.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testMissingAttributeRequiredByAuxiliaryClass()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testmissingatrequiredbyauxiliaryoc-oid " +
+              "NAME 'testMissingATRequiredByAuxiliaryOC' SUP top AUXILIARY " +
+              "MUST ( cn $ description ) " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase')");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test,o=test",
+         "objectClass: top",
+         "objectClass: device",
+         "objectClass: testMissingATRequiredByAuxiliaryOC",
+         "cn: test");
+
+    assertFalse(e.conformsToSchema(null, false, true, true,
+                                   new StringBuilder()));
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry that includes an attribute type that
+   * is not allowed by any of its object classes.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testDisallowedAttributeType()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testdisallowedattributetypeoc-oid " +
+              "NAME 'testDisallowedAttributeTypeOC' SUP top STRUCTURAL " +
+              "MUST cn X-ORIGIN 'EntrySchemaCheckingTestCase')");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test,o=test",
+         "objectClass: top",
+         "objectClass: testDisallowedAttributeTypeOC",
+         "cn: test",
+         "description: foo");
+
+    assertFalse(e.conformsToSchema(null, false, true, true,
+                                   new StringBuilder()));
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry that includes multiple values for a
+   * multivalued attribute.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testMultipleValuesForMultiValuedAttribute()
+         throws Exception
+  {
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: o=test",
+         "objectClass: top",
+         "objectClass: organization",
+         "o: test",
+         "o: foo");
+
+    StringBuilder invalidReason = new StringBuilder();
+    assertTrue(e.conformsToSchema(null, true, true, true, invalidReason),
+               invalidReason.toString());
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry that includes multiple values for a
+   * single-valued attribute.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testMultipleValuesForSingleValuedAttribute()
+         throws Exception
+  {
+    // The LDIF reader won't let us do this directly, so we have to hack around
+    // it.
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: dc=example,dc=com",
+         "objectClass: top",
+         "objectClass: domain",
+         "dc: example");
+
+    e.addAttribute(new Attribute("dc", "foo"),
+                   new LinkedList<AttributeValue>());
+
+    assertFalse(e.conformsToSchema(null, false, true, true, new StringBuilder()));
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry that includes multiple values for a
+   * single-valued operational attribute.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testMultipleValuesForSingleValuedOperationalAttribute()
+         throws Exception
+  {
+    // The LDIF reader won't let us do this directly, so we have to hack around
+    // it.
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: dc=example,dc=com",
+         "objectClass: top",
+         "objectClass: domain",
+         "dc: example");
+
+    AttributeType creatorsNameType =
+         DirectoryServer.getAttributeType("creatorsname");
+    assertTrue(creatorsNameType.isOperational());
+
+    LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(2);
+    values.add(new AttributeValue(creatorsNameType, "cn=Directory Manager"));
+    values.add(new AttributeValue(creatorsNameType, "cn=Another User"));
+
+    e.addAttribute(new Attribute(creatorsNameType, "creatorsName", values),
+                   new LinkedList<AttributeValue>());
+
+    assertFalse(e.conformsToSchema(null, false, true, true, new StringBuilder()));
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry that contains structural and auxiliary
+   * objectclasses where the auxiliary class is allowed by a DIT content rule.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAuxiliaryClassAllowedByDCR()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testauxiliaryclassallowedbydcroc-oid " +
+              "NAME 'testAuxiliaryClassAllowedByDCROC' SUP top STRUCTURAL " +
+              "MUST cn X-ORIGIN 'EntrySchemaCheckingTestCase')",
+         "objectClasses:  ( testauxiliaryclassallowedbydcrocaux-oid " +
+              "NAME 'testAuxiliaryClassAllowedByDCROCAux' SUP top AUXILIARY " +
+              "MAY description X-ORIGIN 'EntrySchemaCheckingTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testauxiliaryclassallowedbydcroc-oid " +
+              "NAME 'testAuxiliaryClassAllowedByDCR' " +
+              "AUX testAuxiliaryClassAllowedByDCROCAux " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test,o=test",
+         "objectClass: top",
+         "objectClass: testAuxiliaryClassAllowedByDCROC",
+         "objectClass: testAuxiliaryClassAllowedByDCROCAux",
+         "cn: test");
+
+    StringBuilder invalidReason = new StringBuilder();
+    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
+               invalidReason.toString());
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry that contains structural and auxiliary
+   * objectclasses where the auxiliary class is not allowed by the associated
+   * DIT content rule.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAuxiliaryClassNotAllowedByDCR()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testauxiliaryclassnotallowedbydcroc-oid " +
+              "NAME 'testAuxiliaryClassNotAllowedByDCROC' SUP top STRUCTURAL " +
+              "MUST cn X-ORIGIN 'EntrySchemaCheckingTestCase')",
+         "objectClasses:  ( testauxiliaryclassnotallowedbydcrocaux-oid " +
+              "NAME 'testAuxiliaryClassNotAllowedByDCROCAux' SUP top " +
+              "AUXILIARY MAY description " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testauxiliaryclassnotallowedbydcroc-oid " +
+              "NAME 'testAuxiliaryClassNotAllowedByDCR' " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test,o=test",
+         "objectClass: top",
+         "objectClass: testAuxiliaryClassNotAllowedByDCROC",
+         "objectClass: testAuxiliaryClassNotAllowedByDCROCAux",
+         "cn: test");
+
+    failOnlyForStrictEvaluation(e);
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry covered by a DIT content rule to
+   * ensure that attributes required by the DIT content rule are allowed even
+   * if not directly allowed by any of the entry's objectclasses.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAllowAttributeRequiredByDCR()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testallowatrequiredbydcroc-oid " +
+              "NAME 'testAllowATRequiredByDCROC' SUP top STRUCTURAL " +
+              "MUST cn X-ORIGIN 'EntrySchemaCheckingTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testallowatrequiredbydcroc-oid " +
+              "NAME 'testAllowATRequiredByDCR' MUST description " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test,o=test",
+         "objectClass: top",
+         "objectClass: testAllowATRequiredByDCROC",
+         "cn: test",
+         "description: foo");
+
+    StringBuilder invalidReason = new StringBuilder();
+    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
+               invalidReason.toString());
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry covered by a DIT content rule to
+   * ensure that attributes required by the DIT content rule are required even
+   * if not directly allowed by any of the entry's objectclasses.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testRequireAttributeRequiredByDCR()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testrequireatrequiredbydcroc-oid " +
+              "NAME 'testRequireATRequiredByDCROC' SUP top STRUCTURAL " +
+              "MUST cn X-ORIGIN 'EntrySchemaCheckingTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testrequireatrequiredbydcroc-oid " +
+              "NAME 'testRequireATRequiredByDCR' MUST description " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test,o=test",
+         "objectClass: top",
+         "objectClass: testRequireATRequiredByDCROC",
+         "cn: test");
+
+    failOnlyForStrictEvaluation(e);
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry for which there is a DIT content rule
+   * covering the structural objectclass but that DIT content rule is marked
+   * OBSOLETE.  In this case, any attribute types required by the DIT content
+   * rule should not be required for the entry.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testDontRequireAttributeRequiredByObsoleteDCR()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testdontrequireatrequiredbyobsoletedcroc-oid " +
+              "NAME 'testDontRequireATRequiredByObsoleteDCROC' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'EntrySchemaCheckingTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testdontrequireatrequiredbyobsoletedcroc-oid " +
+              "NAME 'testDontRequireATRequiredByObsoleteDCR' OBSOLETE " +
+              "MUST description X-ORIGIN 'EntrySchemaCheckingTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test,o=test",
+         "objectClass: top",
+         "objectClass: testDontRequireATRequiredByObsoleteDCROC",
+         "cn: test");
+
+    StringBuilder invalidReason = new StringBuilder();
+    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
+               invalidReason.toString());
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry covered by a DIT content rule to
+   * ensure that attributes allowed by the DIT content rule are allowed even
+   * if not directly allowed by any of the entry's objectclasses.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAllowAttributeAllowedByDCR()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testallowatallowedbydcroc-oid " +
+              "NAME 'testAllowATAllowedByDCROC' SUP top STRUCTURAL " +
+              "MUST cn X-ORIGIN 'EntrySchemaCheckingTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testallowatallowedbydcroc-oid " +
+              "NAME 'testAllowATAllowedByDCR' MAY description " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test,o=test",
+         "objectClass: top",
+         "objectClass: testAllowATAllowedByDCROC",
+         "cn: test",
+         "description: foo");
+
+    StringBuilder invalidReason = new StringBuilder();
+    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
+               invalidReason.toString());
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry covered by a DIT content rule to
+   * ensure that attributes allowed by the DIT content rule are allowed but
+   * not required if they are not required by any of the associated object
+   * classes.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testDontRequireAttributeAllowedByDCR()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testdontrequireatallowedbydcroc-oid " +
+              "NAME 'testDontRequireATAllowedByDCROC' SUP top STRUCTURAL " +
+              "MUST cn X-ORIGIN 'EntrySchemaCheckingTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testdontrequireatallowedbydcroc-oid " +
+              "NAME 'testDontRequireATAllowedByDCR' MAY description " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test,o=test",
+         "objectClass: top",
+         "objectClass: testDontRequireATAllowedByDCROC",
+         "cn: test");
+
+    StringBuilder invalidReason = new StringBuilder();
+    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
+               invalidReason.toString());
+  }
+
+
+
+  /**
+   * Tests schema checking for an entry covered by a DIT content rule to
+   * ensure that attributes prohibited by the DIT content rule are not allowed
+   * even if they are allowed by the associated object classes.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testDontAllowAttributeProhibitedByDCR()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testdontallowattributeprohibitedbydcroc-oid " +
+              "NAME 'testDontAllowAttributeProhibitedByDCROC' SUP top " +
+              "STRUCTURAL MUST cn MAY description " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase')",
+         "-",
+         "add: ditContentRules",
+         "ditContentRules: ( testdontallowattributeprohibitedbydcroc-oid " +
+              "NAME 'testDontAllowAttributeProhibitedByDCR' NOT description " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test,o=test",
+         "objectClass: top",
+         "objectClass: testDontAllowAttributeProhibitedByDCROC",
+         "cn: test",
+         "description: foo");
+
+    failOnlyForStrictEvaluation(e);
+  }
+
+
+
+  /**
+   * Tests that an entry covered by a name form will be accepted if its
+   * single-valued RDN component is compliant with that name form.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testSatisfiesSingleValuedNameForm()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testsatisfiessinglevaluednameformoc-oid " +
+              "NAME 'testSatisfiesSingleValuedNameFormOC' SUP top STRUCTURAL " +
+              "MUST cn X-ORIGIN 'EntrySchemaCheckingTestCase')",
+         "-",
+         "add: nameForms",
+         "nameForms: ( testsatisfiessinglevaluednameform-oid " +
+              "NAME 'testSatisfiesSingleValuedNameForm' " +
+              "OC testSatisfiesSingleValuedNameFormOC MUST cn " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test,o=test",
+         "objectClass: top",
+         "objectClass: testSatisfiesSingleValuedNameFormOC",
+         "cn: test");
+
+    StringBuilder invalidReason = new StringBuilder();
+    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
+               invalidReason.toString());
+  }
+
+
+
+  /**
+   * Tests that an entry covered by a name form will be rejected if its
+   * single-valued RDN component violates that name form.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testViolatesSingleValuedNameForm()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testviolatessinglevaluednameformoc-oid " +
+              "NAME 'testViolatesSingleValuedNameFormOC' SUP top STRUCTURAL " +
+              "MUST cn MAY description X-ORIGIN 'EntrySchemaCheckingTestCase')",
+         "-",
+         "add: nameForms",
+         "nameForms: ( testviolatessinglevaluednameform-oid " +
+              "NAME 'testViolatesSingleValuedNameForm' " +
+              "OC testViolatesSingleValuedNameFormOC MUST cn " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: description=foo,o=test",
+         "objectClass: top",
+         "objectClass: testViolatesSingleValuedNameFormOC",
+         "cn: test",
+         "description: foo");
+
+    failOnlyForStrictEvaluation(e);
+  }
+
+
+
+  /**
+   * Tests that an entry covered by a name form will be rejected if its
+   * multivalued RDN component violates that name form which only allows a
+   * single value.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testMVViolatesSingleValuedNameForm()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testmvviolatessinglevaluednameformoc-oid " +
+              "NAME 'testMVViolatesSingleValuedNameFormOC' SUP top STRUCTURAL " +
+              "MUST cn MAY description X-ORIGIN 'EntrySchemaCheckingTestCase')",
+         "-",
+         "add: nameForms",
+         "nameForms: ( testmvviolatessinglevaluednameform-oid " +
+              "NAME 'testMVViolatesSingleValuedNameForm' " +
+              "OC testMVViolatesSingleValuedNameFormOC MUST cn " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test+description=foo,o=test",
+         "objectClass: top",
+         "objectClass: testMVViolatesSingleValuedNameFormOC",
+         "cn: test",
+         "description: foo");
+
+    failOnlyForStrictEvaluation(e);
+  }
+
+
+
+  /**
+   * Tests that an entry covered by a name form will not be rejected if its
+   * single-valued RDN component violates that name form but the name form is
+   * declared OBSOLETE.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testViolatesSingleValuedObsoleteNameForm()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testviolatessinglevaluedobsoletenameformoc-oid " +
+              "NAME 'testViolatesSingleValuedObsoleteNameFormOC' SUP top " +
+              "STRUCTURAL MUST cn MAY description " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase')",
+         "-",
+         "add: nameForms",
+         "nameForms: ( testviolatessinglevaluedobsoletenameform-oid " +
+              "NAME 'testViolatesSingleValuedObsoleteNameForm' OBSOLETE " +
+              "OC testViolatesSingleValuedObsoleteNameFormOC MUST cn " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: description=foo,o=test",
+         "objectClass: top",
+         "objectClass: testViolatesSingleValuedObsoleteNameFormOC",
+         "cn: test",
+         "description: foo");
+
+    StringBuilder invalidReason = new StringBuilder();
+    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
+               invalidReason.toString());
+  }
+
+
+
+  /**
+   * Tests that an entry covered by a name form will be accepted if its
+   * multivalued RDN component is compliant with that name form which requires
+   * multiple values.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testSatisfiesRequiredMultiValuedNameForm()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testsatisfiesrequiredmultivaluednameformoc-oid " +
+              "NAME 'testSatisfiesRequiredMultiValuedNameFormOC' SUP top " +
+              "STRUCTURAL MUST cn MAY description " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase')",
+         "-",
+         "add: nameForms",
+         "nameForms: ( testsatisfiesrequiredmultivaluednameform-oid " +
+              "NAME 'testSatisfiesRequiredMultiValuedNameForm' " +
+              "OC testSatisfiesRequiredMultiValuedNameFormOC " +
+              "MUST ( cn $ description ) " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test+description=foo,o=test",
+         "objectClass: top",
+         "objectClass: testSatisfiesRequiredMultiValuedNameFormOC",
+         "cn: test",
+         "description: foo");
+
+    StringBuilder invalidReason = new StringBuilder();
+    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
+               invalidReason.toString());
+  }
+
+
+
+  /**
+   * Tests that an entry covered by a name form will be accepted if its
+   * single-valued RDN component only contains one of the multiple required
+   * attribute types.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testViolatesRequiredMultiValuedNameForm()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testviolatesrequiredmultivaluednameformoc-oid " +
+              "NAME 'testViolatesRequiredMultiValuedNameFormOC' SUP top " +
+              "STRUCTURAL MUST cn MAY description " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase')",
+         "-",
+         "add: nameForms",
+         "nameForms: ( testviolatesrequiredmultivaluednameform-oid " +
+              "NAME 'testViolatesRequiredMultiValuedNameForm' " +
+              "OC testViolatesRequiredMultiValuedNameFormOC " +
+              "MUST ( cn $ description ) " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test,o=test",
+         "objectClass: top",
+         "objectClass: testViolatesRequiredMultiValuedNameFormOC",
+         "cn: test",
+         "description: foo");
+
+    failOnlyForStrictEvaluation(e);
+  }
+
+
+
+  /**
+   * Tests that an entry covered by a name form will be accepted if its
+   * single-valued RDN component is compliant with that name form which requires
+   * one value but allows other values.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testSVSatisfiesOptionalMultiValuedNameForm()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testsvsatisfiesoptionalmultivaluednameformoc-oid " +
+              "NAME 'testSVSatisfiesOptionalMultiValuedNameFormOC' SUP top " +
+              "STRUCTURAL MUST cn MAY description " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase')",
+         "-",
+         "add: nameForms",
+         "nameForms: ( testsvsatisfiesoptionalmultivaluednameform-oid " +
+              "NAME 'testSVSatisfiesOptionalMultiValuedNameForm' " +
+              "OC testSVSatisfiesOptionalMultiValuedNameFormOC MUST cn " +
+              "MAY description X-ORIGIN 'EntrySchemaCheckingTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test,o=test",
+         "objectClass: top",
+         "objectClass: testSVSatisfiesOptionalMultiValuedNameFormOC",
+         "cn: test",
+         "description: foo");
+
+    StringBuilder invalidReason = new StringBuilder();
+    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
+               invalidReason.toString());
+  }
+
+
+
+  /**
+   * Tests that an entry covered by a name form will be accepted if its
+   * multivalued RDN component is compliant with that name form which requires
+   * one value but allows other values.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testMVSatisfiesOptionalMultiValuedNameForm()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testmvsatisfiesoptionalmultivaluednameformoc-oid " +
+              "NAME 'testMVSatisfiesOptionalMultiValuedNameFormOC' SUP top " +
+              "STRUCTURAL MUST cn MAY description " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase')",
+         "-",
+         "add: nameForms",
+         "nameForms: ( testmvsatisfiesoptionalmultivaluednameform-oid " +
+              "NAME 'testMVSatisfiesOptionalMultiValuedNameForm' " +
+              "OC testMVSatisfiesOptionalMultiValuedNameFormOC MUST cn " +
+              "MAY description X-ORIGIN 'EntrySchemaCheckingTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=test+description=foo,o=test",
+         "objectClass: top",
+         "objectClass: testMVSatisfiesOptionalMultiValuedNameFormOC",
+         "cn: test",
+         "description: foo");
+
+    StringBuilder invalidReason = new StringBuilder();
+    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
+               invalidReason.toString());
+  }
+
+
+
+  /**
+   * Tests that an entry covered by a name form will be accepted if its
+   * single-valued RDN component violates that name form which requires
+   * one value but allows other values.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testSVViolatesOptionalMultiValuedNameForm()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testsvviolatesoptionalmultivaluednameformoc-oid " +
+              "NAME 'testSVViolatesOptionalMultiValuedNameFormOC' SUP top " +
+              "STRUCTURAL MUST cn MAY description " +
+              "X-ORIGIN 'EntrySchemaCheckingTestCase')",
+         "-",
+         "add: nameForms",
+         "nameForms: ( testsvviolatesoptionalmultivaluednameform-oid " +
+              "NAME 'testSVViolatesOptionalMultiValuedNameForm' " +
+              "OC testSVViolatesOptionalMultiValuedNameFormOC MUST cn " +
+              "MAY description X-ORIGIN 'EntrySchemaCheckingTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: description=foo,o=test",
+         "objectClass: top",
+         "objectClass: testSVViolatesOptionalMultiValuedNameFormOC",
+         "cn: test",
+         "description: foo");
+
+    failOnlyForStrictEvaluation(e);
+  }
+
+
+
+  /**
+   * Performs various tests to ensure that the server appropriately enforces DIT
+   * structure rule constraints.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testDITStructureRuleConstraints()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    String path = TestCaseUtils.createTempFile(
+         "dn: cn=schema",
+         "changetype: modify",
+         "add: objectClasses",
+         "objectClasses:  ( testditstructureruleconstraintssupoc-oid " +
+              "NAME 'testDITStructureRuleConstraintsSupOC' SUP top " +
+              "STRUCTURAL MUST ou X-ORIGIN 'SchemaBackendTestCase')",
+         "objectClasses:  ( testditstructureruleconstraintssuboc-oid " +
+              "NAME 'testDITStructureRuleConstraintsSubOC' SUP top " +
+              "STRUCTURAL MUST cn X-ORIGIN 'SchemaBackendTestCase')",
+         "-",
+         "add: nameForms",
+         "nameForms: ( testditstructureruleconstraintsupsnf-oid " +
+              "NAME 'testDITStructureRuleConstraintsSupNF' " +
+              "OC testDITStructureRuleConstraintsSupOC MUST ou " +
+              "X-ORIGIN 'SchemaBackendTestCase' )",
+         "nameForms: ( testditstructureruleconstraintsubsnf-oid " +
+              "NAME 'testDITStructureRuleConstraintsSubNF' " +
+              "OC testDITStructureRuleConstraintsSubOC MUST cn " +
+              "X-ORIGIN 'SchemaBackendTestCase' )",
+         "-",
+         "add: ditStructureRules",
+         "ditStructureRules: ( 999014 " +
+              "NAME 'testDITStructureRuleConstraintsSup' " +
+              "FORM testDITStructureRuleConstraintsSupNF " +
+              "X-ORIGIN 'SchemaBackendTestCase' )",
+         "ditStructureRules: ( 999015 " +
+              "NAME 'testDITStructureRuleConstraintsSub' " +
+              "FORM testDITStructureRuleConstraintsSubNF SUP 999014 " +
+              "X-ORIGIN 'SchemaBackendTestCase' )");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+
+    Entry e = TestCaseUtils.makeEntry(
+         "dn: cn=child,ou=parent,o=test",
+         "objectClass: top",
+         "objectClass: testDITStructureRuleConstraintsSubOC",
+         "cn: child");
+
+    failOnlyForStrictEvaluation(e);
+
+
+    path = TestCaseUtils.createTempFile(
+         "dn: ou=parent,o=test",
+         "changetype: add",
+         "objectClass: top",
+         "objectClass: testDITStructureRuleConstraintsSupOC",
+         "ou: parent");
+
+    args = new String[]
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    StringBuilder invalidReason = new StringBuilder();
+    assertTrue(e.conformsToSchema(null, false, true, true, invalidReason),
+               invalidReason.toString());
+
+
+    e = TestCaseUtils.makeEntry(
+         "dn: cn=not below valid parent,o=test",
+         "objectClass: top",
+         "objectClass: testDITStructureRuleConstraintsSubOC",
+         "cn: not below valid parent");
+    failOnlyForStrictEvaluation(e);
+
+
+    e = TestCaseUtils.makeEntry(
+         "dn: cn=invalid entry below parent covered by DSR,ou=parent,o=test",
+         "objectClass: top",
+         "objectClass: device",
+         "cn: invalid entry below parent covered by DSR");
+    invalidReason = new StringBuilder();
+    failOnlyForStrictEvaluation(e);
+  }
+}
+
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestEntry.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestEntry.java
index e030d25..eb27124 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestEntry.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestEntry.java
@@ -275,7 +275,7 @@
         + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.45 )";
 
     AttributeType type = AttributeTypeSyntax.decodeAttributeType(
-        new ASN1OctetString(string), DirectoryServer.getSchema());
+        new ASN1OctetString(string), DirectoryServer.getSchema(), false);
 
     // Test values.
     String[] values = new String[] { "{ }",

--
Gitblit v1.10.0