From 0a4fd773fbc9485ca6c9035a229f563589f9b30a Mon Sep 17 00:00:00 2001
From: Violette Roche-Montane <violette.roche-montane@forgerock.com>
Date: Mon, 13 Jan 2014 13:46:03 +0000
Subject: [PATCH] CR-2816 OPENDJ-1230 SDK Builder for syntaxes

---
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/GuideSyntaxTest.java            |    3 
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/IA5StringSyntaxTest.java        |    3 
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UTCTimeSyntaxTest.java          |    4 
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/TelexSyntaxTest.java            |    3 
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AbstractSyntaxTestCase.java     |   86 +++
 opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/Syntax.java                     |  162 +++++-
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SyntaxTestCase.java             |  746 ++++++++++++++++++++++++++++++--
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CountryStringSyntaxTest.java    |    3 
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/OtherMailboxSyntaxTest.java     |    3 
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeSyntaxTest.java    |    3 
 opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java              |  124 ++--
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeSyntaxTest.java  |    3 
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/DITContentRuleSyntaxTest.java   |    3 
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleUseSyntaxTest.java  |    3 
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UUIDSyntaxTest.java             |    3 
 opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CoreSchemaImpl.java             |  179 +++---
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/EnumSyntaxTestCase.java         |    3 
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/LDAPSyntaxTest.java             |    3 
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/BitStringSyntaxTest.java        |    3 
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SubstitutionSyntaxTestCase.java |    3 
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/RegexSyntaxTestCase.java        |    3 
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleSyntaxTest.java     |    3 
 22 files changed, 1,102 insertions(+), 247 deletions(-)

diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CoreSchemaImpl.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CoreSchemaImpl.java
index de03341..b78ac06 100644
--- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CoreSchemaImpl.java
+++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CoreSchemaImpl.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
- *      Portions copyright 2013 ForgeRock AS.
+ *      Portions copyright 2013-2014 ForgeRock AS.
  */
 package org.forgerock.opendj.ldap.schema;
 
@@ -106,8 +106,8 @@
     }
 
     private static void addRFC3112(final SchemaBuilder builder) {
-        builder.addSyntax(SYNTAX_AUTH_PASSWORD_OID, SYNTAX_AUTH_PASSWORD_DESCRIPTION,
-                RFC3112_ORIGIN, new AuthPasswordSyntaxImpl(), false);
+        builder.buildSyntax(SYNTAX_AUTH_PASSWORD_OID).description(SYNTAX_AUTH_PASSWORD_DESCRIPTION)
+                .extraProperties(RFC3112_ORIGIN).implementation(new AuthPasswordSyntaxImpl()).addToSchema();
         builder.buildMatchingRule(EMR_AUTH_PASSWORD_EXACT_OID)
                 .names(EMR_AUTH_PASSWORD_EXACT_NAME)
                 .description(EMR_AUTH_PASSWORD_EXACT_DESCRIPTION).syntaxOID(SYNTAX_AUTH_PASSWORD_OID)
@@ -551,7 +551,8 @@
     }
 
     private static void addRFC4530(final SchemaBuilder builder) {
-        builder.addSyntax(SYNTAX_UUID_OID, SYNTAX_UUID_DESCRIPTION, RFC4530_ORIGIN, new UUIDSyntaxImpl(), false);
+        builder.buildSyntax(SYNTAX_UUID_OID).description(SYNTAX_UUID_DESCRIPTION).extraProperties(RFC4530_ORIGIN)
+                .implementation(new UUIDSyntaxImpl()).addToSchema();
         builder.buildMatchingRule(EMR_UUID_OID).names(EMR_UUID_NAME).syntaxOID(SYNTAX_UUID_OID)
                 .extraProperties(RFC4530_ORIGIN).implementation(new UUIDEqualityMatchingRuleImpl())
                 .addToSchema();
@@ -572,8 +573,8 @@
     }
 
     private static void addSunProprietary(final SchemaBuilder builder) {
-        builder.addSyntax(SYNTAX_USER_PASSWORD_OID, SYNTAX_USER_PASSWORD_DESCRIPTION,
-                OPENDJ_ORIGIN, new UserPasswordSyntaxImpl(), false);
+        builder.buildSyntax(SYNTAX_USER_PASSWORD_OID).description(SYNTAX_USER_PASSWORD_DESCRIPTION)
+                .extraProperties(OPENDJ_ORIGIN).implementation(new UserPasswordSyntaxImpl()).addToSchema();
         builder.buildMatchingRule(EMR_USER_PASSWORD_EXACT_OID)
                 .names(Collections.singletonList(EMR_USER_PASSWORD_EXACT_NAME))
                 .description(EMR_USER_PASSWORD_EXACT_DESCRIPTION).syntaxOID(SYNTAX_USER_PASSWORD_OID)
@@ -845,91 +846,91 @@
 
     private static void defaultSyntaxes(final SchemaBuilder builder) {
         // All RFC 4512 / 4517
-        builder.addSyntax(SYNTAX_ATTRIBUTE_TYPE_OID, SYNTAX_ATTRIBUTE_TYPE_DESCRIPTION,
-                RFC4512_ORIGIN, new AttributeTypeSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_BINARY_OID, SYNTAX_BINARY_DESCRIPTION, RFC4512_ORIGIN,
-                new BinarySyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_BIT_STRING_OID, SYNTAX_BIT_STRING_DESCRIPTION, RFC4512_ORIGIN,
-                new BitStringSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_BOOLEAN_OID, SYNTAX_BOOLEAN_DESCRIPTION, RFC4512_ORIGIN,
-                new BooleanSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_CERTLIST_OID, SYNTAX_CERTLIST_DESCRIPTION, RFC4512_ORIGIN,
-                new CertificateListSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_CERTPAIR_OID, SYNTAX_CERTPAIR_DESCRIPTION, RFC4512_ORIGIN,
-                new CertificatePairSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_CERTIFICATE_OID, SYNTAX_CERTIFICATE_DESCRIPTION, RFC4512_ORIGIN,
-                new CertificateSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_COUNTRY_STRING_OID, SYNTAX_COUNTRY_STRING_DESCRIPTION,
-                RFC4512_ORIGIN, new CountryStringSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_DELIVERY_METHOD_OID, SYNTAX_DELIVERY_METHOD_DESCRIPTION,
-                RFC4512_ORIGIN, new DeliveryMethodSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_DIRECTORY_STRING_OID, SYNTAX_DIRECTORY_STRING_DESCRIPTION,
-                RFC4512_ORIGIN, new DirectoryStringSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_DIT_CONTENT_RULE_OID, SYNTAX_DIT_CONTENT_RULE_DESCRIPTION,
-                RFC4512_ORIGIN, new DITContentRuleSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_DIT_STRUCTURE_RULE_OID, SYNTAX_DIT_STRUCTURE_RULE_DESCRIPTION,
-                RFC4512_ORIGIN, new DITStructureRuleSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_DN_OID, SYNTAX_DN_DESCRIPTION, RFC4512_ORIGIN,
-                new DistinguishedNameSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_ENHANCED_GUIDE_OID, SYNTAX_ENHANCED_GUIDE_DESCRIPTION,
-                RFC4512_ORIGIN, new EnhancedGuideSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_FAXNUMBER_OID, SYNTAX_FAXNUMBER_DESCRIPTION, RFC4512_ORIGIN,
-                new FacsimileNumberSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_FAX_OID, SYNTAX_FAX_DESCRIPTION, RFC4512_ORIGIN,
-                new FaxSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_GENERALIZED_TIME_OID, SYNTAX_GENERALIZED_TIME_DESCRIPTION,
-                RFC4512_ORIGIN, new GeneralizedTimeSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_GUIDE_OID, SYNTAX_GUIDE_DESCRIPTION, RFC4512_ORIGIN,
-                new GuideSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_IA5_STRING_OID, SYNTAX_IA5_STRING_DESCRIPTION, RFC4512_ORIGIN,
-                new IA5StringSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_INTEGER_OID, SYNTAX_INTEGER_DESCRIPTION, RFC4512_ORIGIN,
-                new IntegerSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_JPEG_OID, SYNTAX_JPEG_DESCRIPTION, RFC4512_ORIGIN,
-                new JPEGSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_MATCHING_RULE_OID, SYNTAX_MATCHING_RULE_DESCRIPTION,
-                RFC4512_ORIGIN, new MatchingRuleSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_MATCHING_RULE_USE_OID, SYNTAX_MATCHING_RULE_USE_DESCRIPTION,
-                RFC4512_ORIGIN, new MatchingRuleUseSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_LDAP_SYNTAX_OID, SYNTAX_LDAP_SYNTAX_DESCRIPTION, RFC4512_ORIGIN,
-                new LDAPSyntaxDescriptionSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_NAME_AND_OPTIONAL_UID_OID,
-                SYNTAX_NAME_AND_OPTIONAL_UID_DESCRIPTION, RFC4517_ORIGIN,
-                new NameAndOptionalUIDSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_NAME_FORM_OID, SYNTAX_NAME_FORM_DESCRIPTION, RFC4512_ORIGIN,
-                new NameFormSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_NUMERIC_STRING_OID, SYNTAX_NUMERIC_STRING_DESCRIPTION,
-                RFC4512_ORIGIN, new NumericStringSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_OBJECTCLASS_OID, SYNTAX_OBJECTCLASS_DESCRIPTION, RFC4512_ORIGIN,
-                new ObjectClassSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_OCTET_STRING_OID, SYNTAX_OCTET_STRING_DESCRIPTION, RFC4512_ORIGIN,
-                new OctetStringSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_OID_OID, SYNTAX_OID_DESCRIPTION, RFC4512_ORIGIN,
-                new OIDSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_OTHER_MAILBOX_OID, SYNTAX_OTHER_MAILBOX_DESCRIPTION,
-                RFC4512_ORIGIN, new OtherMailboxSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_POSTAL_ADDRESS_OID, SYNTAX_POSTAL_ADDRESS_DESCRIPTION,
-                RFC4512_ORIGIN, new PostalAddressSyntaxImpl(), false);
+        builder.buildSyntax(SYNTAX_ATTRIBUTE_TYPE_OID).description(SYNTAX_ATTRIBUTE_TYPE_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new AttributeTypeSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_BINARY_OID).description(SYNTAX_BINARY_DESCRIPTION).extraProperties(RFC4512_ORIGIN)
+                .implementation(new BinarySyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_BIT_STRING_OID).description(SYNTAX_BIT_STRING_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new BitStringSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_BOOLEAN_OID).description(SYNTAX_BOOLEAN_DESCRIPTION).extraProperties(RFC4512_ORIGIN)
+                .implementation(new BooleanSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_CERTLIST_OID).description(SYNTAX_CERTLIST_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new CertificateListSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_CERTPAIR_OID).description(SYNTAX_CERTPAIR_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new CertificatePairSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_CERTIFICATE_OID).description(SYNTAX_CERTIFICATE_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new CertificateSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_COUNTRY_STRING_OID).description(SYNTAX_COUNTRY_STRING_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new CountryStringSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_DELIVERY_METHOD_OID).description(SYNTAX_DELIVERY_METHOD_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new DeliveryMethodSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_DIRECTORY_STRING_OID).description(SYNTAX_DIRECTORY_STRING_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new DirectoryStringSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_DIT_CONTENT_RULE_OID).description(SYNTAX_DIT_CONTENT_RULE_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new DITContentRuleSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_DIT_STRUCTURE_RULE_OID).description(SYNTAX_DIT_STRUCTURE_RULE_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new DITStructureRuleSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_DN_OID).description(SYNTAX_DN_DESCRIPTION).extraProperties(RFC4512_ORIGIN)
+                .implementation(new DistinguishedNameSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_ENHANCED_GUIDE_OID).description(SYNTAX_ENHANCED_GUIDE_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new EnhancedGuideSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_FAXNUMBER_OID).description(SYNTAX_FAXNUMBER_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new FacsimileNumberSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_FAX_OID).description(SYNTAX_FAX_DESCRIPTION).extraProperties(RFC4512_ORIGIN)
+                .implementation(new FaxSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_GENERALIZED_TIME_OID).description(SYNTAX_GENERALIZED_TIME_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new GeneralizedTimeSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_GUIDE_OID).description(SYNTAX_GUIDE_DESCRIPTION).extraProperties(RFC4512_ORIGIN)
+                .implementation(new GuideSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_IA5_STRING_OID).description(SYNTAX_IA5_STRING_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new IA5StringSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_INTEGER_OID).description(SYNTAX_INTEGER_DESCRIPTION).extraProperties(RFC4512_ORIGIN)
+                .implementation(new IntegerSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_JPEG_OID).description(SYNTAX_JPEG_DESCRIPTION).extraProperties(RFC4512_ORIGIN)
+                .implementation(new JPEGSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_MATCHING_RULE_OID).description(SYNTAX_MATCHING_RULE_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new MatchingRuleSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_MATCHING_RULE_USE_OID).description(SYNTAX_MATCHING_RULE_USE_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new MatchingRuleUseSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_LDAP_SYNTAX_OID).description(SYNTAX_LDAP_SYNTAX_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new LDAPSyntaxDescriptionSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_NAME_AND_OPTIONAL_UID_OID).description(SYNTAX_NAME_AND_OPTIONAL_UID_DESCRIPTION)
+                .extraProperties(RFC4517_ORIGIN).implementation(new NameAndOptionalUIDSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_NAME_FORM_OID).description(SYNTAX_NAME_FORM_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new NameFormSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_NUMERIC_STRING_OID).description(SYNTAX_NUMERIC_STRING_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new NumericStringSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_OBJECTCLASS_OID).description(SYNTAX_OBJECTCLASS_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new ObjectClassSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_OCTET_STRING_OID).description(SYNTAX_OCTET_STRING_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new OctetStringSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_OID_OID).description(SYNTAX_OID_DESCRIPTION).extraProperties(RFC4512_ORIGIN)
+                .implementation(new OIDSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_OTHER_MAILBOX_OID).description(SYNTAX_OTHER_MAILBOX_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new OtherMailboxSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_POSTAL_ADDRESS_OID).description(SYNTAX_POSTAL_ADDRESS_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new PostalAddressSyntaxImpl()).addToSchema();
         // Depreciated in RFC 4512
-        builder.addSyntax(SYNTAX_PRESENTATION_ADDRESS_OID, SYNTAX_PRESENTATION_ADDRESS_DESCRIPTION,
-                RFC2252_ORIGIN, new PresentationAddressSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_PRINTABLE_STRING_OID, SYNTAX_PRINTABLE_STRING_DESCRIPTION,
-                RFC4512_ORIGIN, new PrintableStringSyntaxImpl(), false);
+        builder.buildSyntax(SYNTAX_PRESENTATION_ADDRESS_OID).description(SYNTAX_PRESENTATION_ADDRESS_DESCRIPTION)
+                .extraProperties(RFC2252_ORIGIN).implementation(new PresentationAddressSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_PRINTABLE_STRING_OID).description(SYNTAX_PRINTABLE_STRING_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new PrintableStringSyntaxImpl()).addToSchema();
         // Depreciated in RFC 4512
-        builder.addSyntax(SYNTAX_PROTOCOL_INFORMATION_OID, SYNTAX_PROTOCOL_INFORMATION_DESCRIPTION,
-                RFC2252_ORIGIN, new ProtocolInformationSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_SUBSTRING_ASSERTION_OID, SYNTAX_SUBSTRING_ASSERTION_DESCRIPTION,
-                RFC4512_ORIGIN, new SubstringAssertionSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_SUPPORTED_ALGORITHM_OID, SYNTAX_SUPPORTED_ALGORITHM_DESCRIPTION,
-                RFC4512_ORIGIN, new SupportedAlgorithmSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_TELEPHONE_OID, SYNTAX_TELEPHONE_DESCRIPTION, RFC4512_ORIGIN,
-                new TelephoneNumberSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_TELETEX_TERM_ID_OID, SYNTAX_TELETEX_TERM_ID_DESCRIPTION,
-                RFC4512_ORIGIN, new TeletexTerminalIdentifierSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_TELEX_OID, SYNTAX_TELEX_DESCRIPTION, RFC4512_ORIGIN,
-                new TelexNumberSyntaxImpl(), false);
-        builder.addSyntax(SYNTAX_UTC_TIME_OID, SYNTAX_UTC_TIME_DESCRIPTION, RFC4512_ORIGIN,
-                new UTCTimeSyntaxImpl(), false);
+        builder.buildSyntax(SYNTAX_PROTOCOL_INFORMATION_OID).description(SYNTAX_PROTOCOL_INFORMATION_DESCRIPTION)
+                .extraProperties(RFC2252_ORIGIN).implementation(new ProtocolInformationSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_SUBSTRING_ASSERTION_OID).description(SYNTAX_SUBSTRING_ASSERTION_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new SubstringAssertionSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_SUPPORTED_ALGORITHM_OID).description(SYNTAX_SUPPORTED_ALGORITHM_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new SupportedAlgorithmSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_TELEPHONE_OID).description(SYNTAX_TELEPHONE_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new TelephoneNumberSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_TELETEX_TERM_ID_OID).description(SYNTAX_TELETEX_TERM_ID_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new TeletexTerminalIdentifierSyntaxImpl())
+                .addToSchema();
+        builder.buildSyntax(SYNTAX_TELEX_OID).description(SYNTAX_TELEX_DESCRIPTION).extraProperties(RFC4512_ORIGIN)
+                .implementation(new TelexNumberSyntaxImpl()).addToSchema();
+        builder.buildSyntax(SYNTAX_UTC_TIME_OID).description(SYNTAX_UTC_TIME_DESCRIPTION)
+                .extraProperties(RFC4512_ORIGIN).implementation(new UTCTimeSyntaxImpl()).addToSchema();
     }
 
     private CoreSchemaImpl() {
diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java
index cf28006..b65f9d0 100644
--- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java
+++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
- *      Portions copyright 2011-2013 ForgeRock AS
+ *      Portions copyright 2011-2014 ForgeRock AS
  */
 
 package org.forgerock.opendj.ldap.schema;
@@ -897,11 +897,13 @@
         lazyInitBuilder();
 
         final EnumSyntaxImpl enumImpl = new EnumSyntaxImpl(oid, Arrays.asList(enumerations));
-        final Syntax enumSyntax =
-                new Syntax(oid, description, Collections.singletonMap("X-ENUM", Arrays
-                        .asList(enumerations)), null, enumImpl);
 
-        addSyntax(enumSyntax, overwrite);
+        final Syntax.Builder syntaxBuilder = buildSyntax(oid).description(description)
+                .extraProperties(Collections.singletonMap("X-ENUM", Arrays.asList(enumerations)))
+                .implementation(enumImpl);
+
+        syntaxBuilder.addToSchema(overwrite);
+
         try {
             buildMatchingRule(enumImpl.getOrderingMatchingRule())
                     .names(OMR_GENERIC_ENUM_NAME + oid)
@@ -1379,6 +1381,24 @@
     }
 
     /**
+     * Returns a builder which can be used for incrementally constructing a new
+     * syntax before adding it to the schema. Example usage:
+     *
+     * <pre>
+     * SchemaBuilder builder = ...;
+     * builder.buildSyntax("1.2.3.4").addToSchema();
+     * </pre>
+     *
+     * @param oid
+     *            The OID of the syntax definition.
+     * @return A builder to continue building the syntax.
+     */
+    public Syntax.Builder buildSyntax(final String oid) {
+        lazyInitBuilder();
+        return new Syntax.Builder(oid, this);
+    }
+
+    /**
      * Sets the default syntax which will be used when parsing unrecognized
      * attributes.
      * <p>
@@ -1471,6 +1491,18 @@
     }
 
     /**
+     * Duplicates the syntax.
+     *
+     * @param syntax
+     *            The syntax to duplicate.
+     * @return A syntax builder.
+     */
+    public Syntax.Builder buildSyntax(final Syntax syntax) {
+        lazyInitBuilder();
+        return new Syntax.Builder(syntax, this);
+    }
+
+    /**
      * Adds the provided object class definition to this schema builder.
      *
      * @param definition
@@ -1700,8 +1732,11 @@
 
         lazyInitBuilder();
 
-        addSyntax(new Syntax(oid, description, Collections.singletonMap("X-PATTERN", Collections
-                .singletonList(pattern.toString())), null, null), overwrite);
+        final Syntax.Builder syntaxBuilder = buildSyntax(oid).description(description).extraProperties(
+                Collections.singletonMap("X-PATTERN", Collections.singletonList(pattern.toString())));
+
+        syntaxBuilder.addToSchema(overwrite);
+
         return this;
     }
 
@@ -2052,8 +2087,11 @@
 
         lazyInitBuilder();
 
-        addSyntax(new Syntax(oid, description, Collections.singletonMap("X-SUBST", Collections
-                .singletonList(substituteSyntax)), null, null), overwrite);
+        final Syntax.Builder syntaxBuilder = buildSyntax(oid).description(description).extraProperties(
+                Collections.singletonMap("X-SUBST", Collections.singletonList(substituteSyntax)));
+
+        syntaxBuilder.addToSchema(overwrite);
+
         return this;
     }
 
@@ -2110,9 +2148,7 @@
 
             // The next set of characters must be the OID.
             final String oid = SchemaUtils.readOID(reader, allowMalformedNamesAndOptions);
-
-            String description = "".intern();
-            Map<String, List<String>> extraProperties = Collections.emptyMap();
+            final Syntax.Builder syntaxBuilder = new Syntax.Builder(oid, this).definition(definition);
 
             // At this point, we should have a pretty specific syntax that
             // describes what may come next, but some of the components are
@@ -2131,17 +2167,15 @@
                 } else if (tokenName.equalsIgnoreCase("desc")) {
                     // This specifies the description for the syntax. It is an
                     // arbitrary string of characters enclosed in single quotes.
-                    description = SchemaUtils.readQuotedString(reader);
+                    syntaxBuilder.description(SchemaUtils.readQuotedString(reader));
                 } else if (tokenName.matches("^X-[A-Za-z_-]+$")) {
                     // This must be a non-standard property and it must be
                     // followed by either a single definition in single quotes
                     // or an open parenthesis followed by one or more values in
                     // single quotes separated by spaces followed by a close
                     // parenthesis.
-                    if (extraProperties.isEmpty()) {
-                        extraProperties = new HashMap<String, List<String>>();
-                    }
-                    extraProperties.put(tokenName, SchemaUtils.readExtensions(reader));
+                    final List<String> extensions = SchemaUtils.readExtensions(reader);
+                    syntaxBuilder.extraProperties(tokenName, extensions.toArray(new String[extensions.size()]));
                 } else {
                     final LocalizableMessage message =
                             ERR_ATTR_SYNTAX_ATTRSYNTAX_ILLEGAL_TOKEN1.get(definition, tokenName);
@@ -2149,17 +2183,13 @@
                 }
             }
 
-            if (!extraProperties.isEmpty()) {
-                extraProperties = Collections.unmodifiableMap(extraProperties);
-            }
-
             // See if it is a enum syntax
-            for (final Map.Entry<String, List<String>> property : extraProperties.entrySet()) {
+            for (final Map.Entry<String, List<String>> property : syntaxBuilder.getExtraProperties().entrySet()) {
                 if (property.getKey().equalsIgnoreCase("x-enum")) {
                     final EnumSyntaxImpl enumImpl = new EnumSyntaxImpl(oid, property.getValue());
-                    final Syntax enumSyntax =
-                            new Syntax(oid, description, extraProperties, definition, enumImpl);
-                    addSyntax(enumSyntax, overwrite);
+                    syntaxBuilder.implementation(enumImpl);
+
+                    syntaxBuilder.addToSchema(overwrite);
 
                     buildMatchingRule(enumImpl.getOrderingMatchingRule())
                         .names(OMR_GENERIC_ENUM_NAME + oid)
@@ -2171,7 +2201,7 @@
                 }
             }
 
-            addSyntax(new Syntax(oid, description, extraProperties, definition, null), overwrite);
+            syntaxBuilder.addToSchema(overwrite);
         } catch (final DecodeException e) {
             final LocalizableMessage msg =
                     ERR_ATTR_SYNTAX_ATTRSYNTAX_INVALID1.get(definition, e.getMessageObject());
@@ -2181,38 +2211,6 @@
     }
 
     /**
-     * Adds the provided syntax definition to this schema builder.
-     *
-     * @param oid
-     *            The OID of the syntax definition.
-     * @param description
-     *            The description of the syntax definition.
-     * @param extraProperties
-     *            A map containing additional properties associated with the
-     *            syntax definition.
-     * @param implementation
-     *            The implementation of the syntax.
-     * @param overwrite
-     *            {@code true} if any existing syntax with the same OID should
-     *            be overwritten.
-     * @return A reference to this schema builder.
-     * @throws ConflictingSchemaElementException
-     *             If {@code overwrite} was {@code false} and a conflicting
-     *             schema element was found.
-     * @throws NullPointerException
-     *             If {@code definition} was {@code null}.
-     */
-    SchemaBuilder addSyntax(final String oid, final String description,
-            final Map<String, List<String>> extraProperties, final SyntaxImpl implementation,
-            final boolean overwrite) {
-        lazyInitBuilder();
-
-        addSyntax(new Syntax(oid, description, unmodifiableCopyOfExtraProperties(extraProperties),
-                null, implementation), overwrite);
-        return this;
-    }
-
-    /**
      * Specifies whether or not the schema should allow certain illegal
      * characters in OIDs and attribute options. When this compatibility option
      * is set to {@code true} the following illegal characters will be permitted
@@ -2755,7 +2753,7 @@
         // unlikely, may be different in the new schema.
 
         for (final Syntax syntax : schema.getSyntaxes()) {
-            addSyntax(syntax.duplicate(), overwrite);
+            addSyntax(syntax, overwrite);
         }
 
         for (final MatchingRule matchingRule : schema.getMatchingRules()) {
@@ -2787,19 +2785,19 @@
         }
     }
 
-    private void addSyntax(final Syntax syntax, final boolean overwrite) {
+    SchemaBuilder addSyntax(final Syntax syntax, final boolean overwrite) {
         Syntax conflictingSyntax;
         if (numericOID2Syntaxes.containsKey(syntax.getOID())) {
             conflictingSyntax = numericOID2Syntaxes.get(syntax.getOID());
             if (!overwrite) {
-                final LocalizableMessage message =
-                        ERR_SCHEMA_CONFLICTING_SYNTAX_OID.get(syntax.toString(), syntax.getOID(),
-                                conflictingSyntax.getOID());
+                final LocalizableMessage message = ERR_SCHEMA_CONFLICTING_SYNTAX_OID.get(syntax.toString(),
+                        syntax.getOID(), conflictingSyntax.getOID());
                 throw new ConflictingSchemaElementException(message);
             }
             removeSyntax(conflictingSyntax);
         }
         numericOID2Syntaxes.put(syntax.getOID(), syntax);
+        return this;
     }
 
     private void lazyInitBuilder() {
diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/Syntax.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/Syntax.java
index ce62d06..7b8e53d 100644
--- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/Syntax.java
+++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/Syntax.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2009 Sun Microsystems, Inc.
- *      Portions copyright 2013 ForgeRock AS.
+ *      Portions copyright 2013-2014 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldap.schema;
@@ -38,7 +38,6 @@
 import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.i18n.LocalizableMessageBuilder;
 import org.forgerock.opendj.ldap.ByteSequence;
-
 import org.forgerock.util.Reject;
 
 /**
@@ -55,6 +54,117 @@
  * or via the {@link #toString()} methods.
  */
 public final class Syntax extends SchemaElement {
+
+    /**
+     * A fluent API for incrementally constructing syntaxes.
+     */
+    public final static class Builder extends SchemaElementBuilder<Builder> {
+
+        private String oid;
+        private SyntaxImpl impl;
+
+        Builder(final Syntax syntax, final SchemaBuilder builder) {
+            super(builder, syntax);
+            this.oid = syntax.oid;
+            this.impl = syntax.impl;
+        }
+
+        Builder(final String oid, final SchemaBuilder builder) {
+            super(builder);
+            this.oid(oid);
+        }
+
+        /**
+         * Adds this syntax to the schema overwriting any existing syntax with the same numeric OID.
+         *
+         * @return The parent schema builder.
+         */
+        public SchemaBuilder addToSchemaOverwrite() {
+            return this.getSchemaBuilder().addSyntax(new Syntax(this), true);
+        }
+
+        /**
+         * Adds this syntax to the schema, throwing an {@code  ConflictingSchemaElementException}
+         * if there is an existing syntax with the same numeric OID.
+         *
+         * @return The parent schema builder.
+         * @throws ConflictingSchemaElementException
+         *             If there is an existing syntax with the same numeric OID.
+         */
+        public SchemaBuilder addToSchema() {
+            return this.getSchemaBuilder().addSyntax(new Syntax(this), false);
+        }
+
+        /**
+         * Adds this syntax to the schema - overwriting any existing syntax with the same numeric OID
+         * if the overwrite parameter is set to {@code true}.
+         *
+         * @param overwrite
+         *            {@code true} if any syntax with the same OID should be overwritten.
+         * @return The parent schema builder.
+         */
+        SchemaBuilder addToSchema(final boolean overwrite) {
+            if (overwrite) {
+                return this.addToSchemaOverwrite();
+            }
+            return this.addToSchema();
+        }
+
+        @Override
+        public Builder description(final String description) {
+            return description0(description);
+        }
+
+        @Override
+        public Builder extraProperties(final Map<String, List<String>> extraProperties) {
+            return extraProperties0(extraProperties);
+        }
+
+        @Override
+        public Builder extraProperties(final String extensionName, final String... extensionValues) {
+            return extraProperties0(extensionName, extensionValues);
+        }
+
+        /**
+         * Sets the numeric OID which uniquely identifies this syntax.
+         *
+         * @param oid
+         *            The numeric OID.
+         * @return This builder.
+         */
+        public Builder oid(final String oid) {
+            this.oid = oid;
+            return this;
+        }
+
+        @Override
+        public Builder removeAllExtraProperties() {
+            return removeAllExtraProperties0();
+        }
+
+        @Override
+        public Builder removeExtraProperty(final String extensionName, final String... extensionValues) {
+            return removeExtraProperty0(extensionName, extensionValues);
+        }
+
+        /**
+         * Sets the syntax implementation.
+         *
+         * @param implementation
+         *            The syntax implementation.
+         * @return This builder.
+         */
+        public Builder implementation(final SyntaxImpl implementation) {
+            this.impl = implementation;
+            return this;
+        }
+
+        @Override
+        Builder getThis() {
+            return this;
+        }
+    }
+
     private final String oid;
     private MatchingRule equalityMatchingRule;
     private MatchingRule orderingMatchingRule;
@@ -63,6 +173,18 @@
     private Schema schema;
     private SyntaxImpl impl;
 
+    private Syntax(final Builder builder) {
+        super(builder);
+
+        // Checks for required attributes.
+        if (builder.oid == null || builder.oid.isEmpty()) {
+            throw new IllegalArgumentException("An OID must be specified.");
+        }
+
+        oid = builder.oid;
+        impl = builder.impl;
+    }
+
     /**
      * Creates a syntax representing an unrecognized syntax and whose
      * implementation is substituted by the schema's default syntax.
@@ -73,8 +195,7 @@
      *            The numeric OID of the unrecognized syntax.
      */
     Syntax(final Schema schema, final String oid) {
-        super("", Collections.singletonMap("X-SUBST",
-                Collections.singletonList(schema.getDefaultSyntax().getOID())),
+        super("", Collections.singletonMap("X-SUBST", Collections.singletonList(schema.getDefaultSyntax().getOID())),
                 null);
 
         Reject.ifNull(oid);
@@ -83,16 +204,6 @@
         this.impl = schema.getDefaultSyntax().impl;
     }
 
-    Syntax(final String oid, final String description,
-            final Map<String, List<String>> extraProperties, final String definition,
-            final SyntaxImpl implementation) {
-        super(description, extraProperties, definition);
-
-        Reject.ifNull(oid);
-        this.oid = oid;
-        this.impl = implementation;
-    }
-
     /**
      * Returns {@code true} if the provided object is an attribute syntax having
      * the same numeric OID as this attribute syntax.
@@ -225,10 +336,6 @@
         return impl.valueIsAcceptable(schema, value, invalidReason);
     }
 
-    Syntax duplicate() {
-        return new Syntax(oid, getDescription(), getExtraProperties(), toString(), impl);
-    }
-
     @Override
     void toStringContent(final StringBuilder buffer) {
         buffer.append(oid);
@@ -252,14 +359,10 @@
                     if (values.hasNext()) {
                         final String value = values.next();
                         if (value.equals(oid)) {
-                            final LocalizableMessage message =
-                                    ERR_ATTR_SYNTAX_CYCLIC_SUB_SYNTAX.get(oid);
-                            throw new SchemaException(message);
+                            throw new SchemaException(ERR_ATTR_SYNTAX_CYCLIC_SUB_SYNTAX.get(oid));
                         }
                         if (!schema.hasSyntax(value)) {
-                            final LocalizableMessage message =
-                                    ERR_ATTR_SYNTAX_UNKNOWN_SUB_SYNTAX.get(oid, value);
-                            throw new SchemaException(message);
+                            throw new SchemaException(ERR_ATTR_SYNTAX_UNKNOWN_SUB_SYNTAX.get(oid, value));
                         }
                         final Syntax subSyntax = schema.getSyntax(value);
                         if (subSyntax.impl == null) {
@@ -276,10 +379,8 @@
                             final Pattern pattern = Pattern.compile(value);
                             impl = new RegexSyntaxImpl(pattern);
                         } catch (final Exception e) {
-                            final LocalizableMessage message =
-                                    WARN_ATTR_SYNTAX_LDAPSYNTAX_REGEX_INVALID_PATTERN.get(oid,
-                                            value);
-                            throw new SchemaException(message);
+                            throw new SchemaException(
+                                    WARN_ATTR_SYNTAX_LDAPSYNTAX_REGEX_INVALID_PATTERN.get(oid, value));
                         }
                     }
                 }
@@ -300,9 +401,8 @@
                     defaultSyntax.validate(schema, warnings);
                 }
                 impl = defaultSyntax.impl;
-                final LocalizableMessage message = WARN_ATTR_SYNTAX_NOT_IMPLEMENTED1
-                        .get(getDescription(), oid, schema.getDefaultSyntax()
-                                .getOID());
+                final LocalizableMessage message = WARN_ATTR_SYNTAX_NOT_IMPLEMENTED1.get(getDescription(), oid, schema
+                        .getDefaultSyntax().getOID());
                 warnings.add(message);
             }
         }
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AbstractSyntaxTestCase.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AbstractSyntaxTestCase.java
new file mode 100644
index 0000000..fce95d5
--- /dev/null
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AbstractSyntaxTestCase.java
@@ -0,0 +1,86 @@
+/*
+ * 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 legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * 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 legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
+ */
+package org.forgerock.opendj.ldap.schema;
+
+import static org.testng.Assert.fail;
+
+import org.forgerock.i18n.LocalizableMessageBuilder;
+import org.forgerock.opendj.ldap.ByteString;
+import org.forgerock.opendj.ldap.DecodeException;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * Syntax tests.
+ */
+@SuppressWarnings("javadoc")
+public abstract class AbstractSyntaxTestCase extends SchemaTestCase {
+    /**
+     * Create data for the testAcceptableValues test. This should be a table of
+     * tables with 2 elements. The first one should be the value to test, the
+     * second the expected result of the test.
+     *
+     * @return a table containing data for the testAcceptableValues Test.
+     */
+    @DataProvider(name = "acceptableValues")
+    public abstract Object[][] createAcceptableValues();
+
+    /**
+     * Test the normalization and the approximate comparison.
+     */
+    @Test(dataProvider = "acceptableValues")
+    public void testAcceptableValues(final String value, final Boolean result) throws Exception {
+        // Make sure that the specified class can be instantiated as a task.
+        final Syntax syntax = getRule();
+
+        final LocalizableMessageBuilder reason = new LocalizableMessageBuilder();
+        // test the valueIsAcceptable method
+        final Boolean liveResult = syntax.valueIsAcceptable(ByteString.valueOf(value), reason);
+
+        if (!liveResult.equals(result)) {
+            fail(syntax + ".valueIsAcceptable gave bad result for " + value + "reason : " + reason);
+        }
+
+        // call the getters
+        syntax.getApproximateMatchingRule();
+        syntax.getDescription();
+        syntax.getEqualityMatchingRule();
+        syntax.getOID();
+        syntax.getOrderingMatchingRule();
+        syntax.getSubstringMatchingRule();
+        syntax.hashCode();
+        syntax.isHumanReadable();
+        syntax.toString();
+    }
+
+    /**
+     * Get an instance of the attribute syntax that muste be tested.
+     *
+     * @return An instance of the attribute syntax that muste be tested.
+     */
+    protected abstract Syntax getRule() throws SchemaException, DecodeException;
+}
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeSyntaxTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeSyntaxTest.java
index 7e89671..ed2367b 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeSyntaxTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeSyntaxTest.java
@@ -22,6 +22,7 @@
  *
  *
  *      Copyright 2009 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 package org.forgerock.opendj.ldap.schema;
 
@@ -32,7 +33,7 @@
 /**
  * Attribute type syntax tests.
  */
-public class AttributeTypeSyntaxTest extends SyntaxTestCase {
+public class AttributeTypeSyntaxTest extends AbstractSyntaxTestCase {
     /**
      * {@inheritDoc}
      */
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/BitStringSyntaxTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/BitStringSyntaxTest.java
index 3f20d4f..6b4f0ea 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/BitStringSyntaxTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/BitStringSyntaxTest.java
@@ -22,6 +22,7 @@
  *
  *
  *      Copyright 2009 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 package org.forgerock.opendj.ldap.schema;
 
@@ -32,7 +33,7 @@
 /**
  * Bit string syntax tests.
  */
-public class BitStringSyntaxTest extends SyntaxTestCase {
+public class BitStringSyntaxTest extends AbstractSyntaxTestCase {
     /**
      * {@inheritDoc}
      */
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CountryStringSyntaxTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CountryStringSyntaxTest.java
index 1be187c..1680147 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CountryStringSyntaxTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CountryStringSyntaxTest.java
@@ -23,6 +23,7 @@
  *
  *      Copyright 2009 Sun Microsystems, Inc.
  *      Portions Copyright 2012 Manuel Gaupp
+ *      Portions copyright 2014 ForgeRock AS.
  *
  */
 package org.forgerock.opendj.ldap.schema;
@@ -34,7 +35,7 @@
 /**
  * Country String syntax tests.
  */
-public class CountryStringSyntaxTest extends SyntaxTestCase {
+public class CountryStringSyntaxTest extends AbstractSyntaxTestCase {
     @Override
     @DataProvider(name = "acceptableValues")
     public Object[][] createAcceptableValues() {
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/DITContentRuleSyntaxTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/DITContentRuleSyntaxTest.java
index bd5b9b6..7b44e53 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/DITContentRuleSyntaxTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/DITContentRuleSyntaxTest.java
@@ -22,6 +22,7 @@
  *
  *
  *      Copyright 2009 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 package org.forgerock.opendj.ldap.schema;
 
@@ -32,7 +33,7 @@
 /**
  * DIT content rule syntax tests.
  */
-public class DITContentRuleSyntaxTest extends SyntaxTestCase {
+public class DITContentRuleSyntaxTest extends AbstractSyntaxTestCase {
     @Override
     @DataProvider(name = "acceptableValues")
     public Object[][] createAcceptableValues() {
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/EnumSyntaxTestCase.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/EnumSyntaxTestCase.java
index 652cd14..f10fbf2 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/EnumSyntaxTestCase.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/EnumSyntaxTestCase.java
@@ -22,6 +22,7 @@
  *
  *
  *      Copyright 2009 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 package org.forgerock.opendj.ldap.schema;
 
@@ -38,7 +39,7 @@
  * Enum syntax tests.
  */
 @SuppressWarnings("javadoc")
-public class EnumSyntaxTestCase extends SyntaxTestCase {
+public class EnumSyntaxTestCase extends AbstractSyntaxTestCase {
     /**
      * {@inheritDoc}
      */
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeSyntaxTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeSyntaxTest.java
index db3af17..4d04511 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeSyntaxTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/GeneralizedTimeSyntaxTest.java
@@ -22,6 +22,7 @@
  *
  *
  *      Copyright 2009 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 package org.forgerock.opendj.ldap.schema;
 
@@ -32,7 +33,7 @@
 /**
  * Generalized time syntax tests.
  */
-public class GeneralizedTimeSyntaxTest extends SyntaxTestCase {
+public class GeneralizedTimeSyntaxTest extends AbstractSyntaxTestCase {
     @Override
     @DataProvider(name = "acceptableValues")
     public Object[][] createAcceptableValues() {
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/GuideSyntaxTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/GuideSyntaxTest.java
index c651611..453b18f 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/GuideSyntaxTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/GuideSyntaxTest.java
@@ -22,6 +22,7 @@
  *
  *
  *      Copyright 2009 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 package org.forgerock.opendj.ldap.schema;
 
@@ -32,7 +33,7 @@
 /**
  * Guide syntax tests.
  */
-public class GuideSyntaxTest extends SyntaxTestCase {
+public class GuideSyntaxTest extends AbstractSyntaxTestCase {
     /**
      * {@inheritDoc}
      */
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/IA5StringSyntaxTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/IA5StringSyntaxTest.java
index 66fe5ed..485beb8 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/IA5StringSyntaxTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/IA5StringSyntaxTest.java
@@ -22,6 +22,7 @@
  *
  *
  *      Copyright 2009 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 package org.forgerock.opendj.ldap.schema;
 
@@ -32,7 +33,7 @@
 /**
  * IA5 string syntax tests.
  */
-public class IA5StringSyntaxTest extends SyntaxTestCase {
+public class IA5StringSyntaxTest extends AbstractSyntaxTestCase {
     /**
      * {@inheritDoc}
      */
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/LDAPSyntaxTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/LDAPSyntaxTest.java
index b78c37b..f285d79 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/LDAPSyntaxTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/LDAPSyntaxTest.java
@@ -22,6 +22,7 @@
  *
  *
  *      Copyright 2009 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 package org.forgerock.opendj.ldap.schema;
 
@@ -32,7 +33,7 @@
 /**
  * LDAP syntax tests.
  */
-public class LDAPSyntaxTest extends SyntaxTestCase {
+public class LDAPSyntaxTest extends AbstractSyntaxTestCase {
     /**
      * {@inheritDoc}
      */
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleSyntaxTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleSyntaxTest.java
index 872c406..47cf6fe 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleSyntaxTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleSyntaxTest.java
@@ -22,6 +22,7 @@
  *
  *
  *      Copyright 2009 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 package org.forgerock.opendj.ldap.schema;
 
@@ -32,7 +33,7 @@
 /**
  * Matching rule syntax tests.
  */
-public class MatchingRuleSyntaxTest extends SyntaxTestCase {
+public class MatchingRuleSyntaxTest extends AbstractSyntaxTestCase {
     /**
      * {@inheritDoc}
      */
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleUseSyntaxTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleUseSyntaxTest.java
index ffaa8d0..1859a7b 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleUseSyntaxTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/MatchingRuleUseSyntaxTest.java
@@ -22,6 +22,7 @@
  *
  *
  *      Copyright 2009 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 package org.forgerock.opendj.ldap.schema;
 
@@ -32,7 +33,7 @@
 /**
  * Matching rule use syntax tests.
  */
-public class MatchingRuleUseSyntaxTest extends SyntaxTestCase {
+public class MatchingRuleUseSyntaxTest extends AbstractSyntaxTestCase {
     /**
      * {@inheritDoc}
      */
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/OtherMailboxSyntaxTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/OtherMailboxSyntaxTest.java
index b02f533..c68a34b 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/OtherMailboxSyntaxTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/OtherMailboxSyntaxTest.java
@@ -22,6 +22,7 @@
  *
  *
  *      Copyright 2009 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 package org.forgerock.opendj.ldap.schema;
 
@@ -32,7 +33,7 @@
 /**
  * Other mailbox syntax tests.
  */
-public class OtherMailboxSyntaxTest extends SyntaxTestCase {
+public class OtherMailboxSyntaxTest extends AbstractSyntaxTestCase {
     /**
      * {@inheritDoc}
      */
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/RegexSyntaxTestCase.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/RegexSyntaxTestCase.java
index efb4175..fbd4f3d 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/RegexSyntaxTestCase.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/RegexSyntaxTestCase.java
@@ -22,6 +22,7 @@
  *
  *
  *      Copyright 2009 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 package org.forgerock.opendj.ldap.schema;
 
@@ -35,7 +36,7 @@
  * Regex syntax tests.
  */
 @SuppressWarnings("javadoc")
-public class RegexSyntaxTestCase extends SyntaxTestCase {
+public class RegexSyntaxTestCase extends AbstractSyntaxTestCase {
     /**
      * {@inheritDoc}
      */
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SubstitutionSyntaxTestCase.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SubstitutionSyntaxTestCase.java
index 89166aa..f5e7155 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SubstitutionSyntaxTestCase.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SubstitutionSyntaxTestCase.java
@@ -22,6 +22,7 @@
  *
  *
  *      Copyright 2009 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 package org.forgerock.opendj.ldap.schema;
 
@@ -35,7 +36,7 @@
  * Substitution syntax tests.
  */
 @SuppressWarnings("javadoc")
-public class SubstitutionSyntaxTestCase extends SyntaxTestCase {
+public class SubstitutionSyntaxTestCase extends AbstractSyntaxTestCase {
     /**
      * {@inheritDoc}
      */
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SyntaxTestCase.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SyntaxTestCase.java
index 6d66f0a..f8fcfdc 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SyntaxTestCase.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SyntaxTestCase.java
@@ -21,65 +21,719 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2009 Sun Microsystems, Inc.
+ *      Copyright 2014 ForgeRock AS.
  */
+
 package org.forgerock.opendj.ldap.schema;
 
-import static org.testng.Assert.fail;
+import static org.fest.assertions.Assertions.assertThat;
 
-import org.forgerock.i18n.LocalizableMessageBuilder;
-import org.forgerock.opendj.ldap.ByteString;
-import org.forgerock.opendj.ldap.DecodeException;
-import org.testng.annotations.DataProvider;
+import org.forgerock.opendj.ldap.schema.Syntax.Builder;
 import org.testng.annotations.Test;
 
 /**
- * Syntax tests.
+ * This class tests the Syntax class.
  */
 @SuppressWarnings("javadoc")
-public abstract class SyntaxTestCase extends SchemaTestCase {
-    /**
-     * Create data for the testAcceptableValues test. This should be a table of
-     * tables with 2 elements. The first one should be the value to test, the
-     * second the expected result of the test.
-     *
-     * @return a table containing data for the testAcceptableValues Test.
-     */
-    @DataProvider(name = "acceptableValues")
-    public abstract Object[][] createAcceptableValues();
+public class SyntaxTestCase extends SchemaTestCase {
 
-    /**
-     * Test the normalization and the approximate comparison.
-     */
-    @Test(dataProvider = "acceptableValues")
-    public void testAcceptableValues(final String value, final Boolean result) throws Exception {
-        // Make sure that the specified class can be instantiated as a task.
-        final Syntax syntax = getRule();
+    @Test()
+    public final void testCreatesANewSyntax() {
 
-        final LocalizableMessageBuilder reason = new LocalizableMessageBuilder();
-        // test the valueIsAcceptable method
-        final Boolean liveResult = syntax.valueIsAcceptable(ByteString.valueOf(value), reason);
-
-        if (!liveResult.equals(result)) {
-            fail(syntax + ".valueIsAcceptable gave bad result for " + value + "reason : " + reason);
-        }
-
-        // call the getters
-        syntax.getApproximateMatchingRule();
-        syntax.getDescription();
-        syntax.getEqualityMatchingRule();
-        syntax.getOID();
-        syntax.getOrderingMatchingRule();
-        syntax.getSubstringMatchingRule();
-        syntax.hashCode();
-        syntax.isHumanReadable();
-        syntax.toString();
+        // @formatter:off
+        final Schema schema = new SchemaBuilder(Schema.getCoreSchema())
+            .buildSyntax("1.9.1.2.3")
+            .description("Security Label")
+            .extraProperties("X-ENUM", "top-secret", "secret", "confidential")
+            .implementation(new DirectoryStringSyntaxImpl())
+            .addToSchema()
+            .toSchema();
+        // @formatter:on
+        assertThat(schema.getWarnings()).isEmpty();
+        final Syntax syntax = schema.getSyntax("1.9.1.2.3");
+        assertThat(syntax).isNotNull();
+        assertThat(syntax.getDescription()).isEqualTo("Security Label");
+        assertThat(syntax.getExtraProperties().get("X-ENUM").size()).isEqualTo(3);
+        assertThat(syntax.getApproximateMatchingRule().getNameOrOID()).isEqualTo("ds-mr-double-metaphone-approx");
+        assertThat(syntax.getEqualityMatchingRule().getNameOrOID()).isEqualTo("caseIgnoreMatch");
+        assertThat(syntax.getOrderingMatchingRule().getNameOrOID()).isEqualTo("caseIgnoreOrderingMatch");
+        assertThat(syntax.getSubstringMatchingRule().getNameOrOID()).isEqualTo("caseIgnoreSubstringsMatch");
+        assertThat(syntax.toString()).isEqualTo(
+                "( 1.9.1.2.3 DESC 'Security Label' X-ENUM ( 'top-secret' 'secret' 'confidential' ) )");
+        assertThat(syntax.isHumanReadable()).isTrue();
+        assertThat(syntax.isBEREncodingRequired()).isFalse();
     }
 
     /**
-     * Get an instance of the attribute syntax that muste be tested.
-     *
-     * @return An instance of the attribute syntax that muste be tested.
+     * Creates an empty syntax.
      */
-    protected abstract Syntax getRule() throws SchemaException, DecodeException;
+    @Test()
+    public final void testCreatesEmptySyntax() {
+        final SchemaBuilder sb = new SchemaBuilder();
+        sb.addSchema(Schema.getCoreSchema(), false);
+
+        sb.addSyntax(new Syntax(Schema.getEmptySchema(), "1.2.3.4.5"), false);
+
+        final Schema schema = sb.toSchema();
+        assertThat(schema.getWarnings()).isEmpty();
+        final Syntax syntax = schema.getSyntax("1.2.3.4.5");
+        assertThat(syntax).isNotNull();
+        assertThat(syntax.getDescription()).isEmpty();
+        assertThat(syntax.getExtraProperties().get("X-SUBST").get(0)).isEqualTo("1.3.6.1.4.1.1466.115.121.1.40");
+        assertThat(syntax.getApproximateMatchingRule()).isNull();
+        assertThat(syntax.getEqualityMatchingRule().getNameOrOID()).isEqualTo("octetStringMatch");
+        assertThat(syntax.getOrderingMatchingRule().getNameOrOID()).isEqualTo("octetStringOrderingMatch");
+        assertThat(syntax.getSubstringMatchingRule()).isNull();
+    }
+
+    /**
+     * The builder requires an OID or throw an exception.
+     */
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public final void testBuilderDoesNotAllowEmptyOid() {
+        // @formatter:off
+        new SchemaBuilder(Schema.getCoreSchema())
+            .buildSyntax("")
+            .description("Security Label")
+            .extraProperties("X-ENUM", "top-secret", "secret", "confidential")
+            .implementation(new DirectoryStringSyntaxImpl())
+            .addToSchema();
+        // @formatter:on
+    }
+
+    /**
+     * The builder requires an OID or throw an exception.
+     */
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public final void testBuilderDoesNotAllowNullOid() {
+        // @formatter:off
+        new SchemaBuilder(Schema.getCoreSchema())
+            .buildSyntax((String) null)
+            .description("Security Label")
+            .extraProperties("X-ENUM", "top-secret", "secret", "confidential")
+            .implementation(new DirectoryStringSyntaxImpl())
+            .addToSchema();
+        // @formatter:on
+    }
+
+    /**
+     * When syntax is missing, the default one is set. Actual default is OctetString.(case match)
+     */
+    @Test()
+    public final void testBuilderAllowsNullSyntax() {
+        // @formatter:off
+        final Schema schema = new SchemaBuilder(Schema.getCoreSchema())
+            .buildSyntax("1.9.1.2.3")
+                .description("Security Label")
+                .extraProperties("X-ENUM", "top-secret", "secret", "confidential")
+                .implementation(null)
+                .addToSchema()
+            .toSchema();
+        // @formatter:on
+
+        assertThat(schema.getWarnings()).isNotEmpty();
+        assertThat(schema.getWarnings().toString()).contains("It will be substituted by the default syntax");
+        final Syntax syntax = schema.getSyntax("1.9.1.2.3");
+        assertThat(syntax).isNotNull();
+        assertThat(syntax.getDescription()).isEqualTo("Security Label");
+        assertThat(syntax.getExtraProperties().get("X-ENUM").size()).isEqualTo(3);
+        assertThat(syntax.getApproximateMatchingRule()).isEqualTo(null);
+        assertThat(syntax.getEqualityMatchingRule().getNameOrOID()).isEqualTo("octetStringMatch");
+        assertThat(syntax.getOrderingMatchingRule().getNameOrOID()).isEqualTo("octetStringOrderingMatch");
+        assertThat(syntax.getSubstringMatchingRule()).isEqualTo(null);
+        assertThat(syntax.toString()).isEqualTo(
+                "( 1.9.1.2.3 DESC 'Security Label' X-ENUM ( 'top-secret' 'secret' 'confidential' ) )");
+    }
+
+    /**
+     * When syntax is missing, the default one is set. Actual default is OctetString.(case match)
+     */
+    @Test()
+    public final void testBuilderAllowsNoSyntax() {
+        // @formatter:off
+        final Schema schema = new SchemaBuilder(Schema.getCoreSchema())
+            .buildSyntax("1.9.1.2.3")
+                .description("Security Label")
+                .extraProperties("X-ENUM", "top-secret", "secret", "confidential")
+                .addToSchema()
+            .toSchema();
+        // @formatter:on
+
+        assertThat(schema.getWarnings()).isNotEmpty();
+        assertThat(schema.getWarnings().toString()).contains("It will be substituted by the default syntax");
+        final Syntax syntax = schema.getSyntax("1.9.1.2.3");
+        assertThat(syntax).isNotNull();
+        assertThat(syntax.getDescription()).isEqualTo("Security Label");
+        assertThat(syntax.getExtraProperties().get("X-ENUM").size()).isEqualTo(3);
+        assertThat(syntax.getApproximateMatchingRule()).isEqualTo(null);
+        assertThat(syntax.getEqualityMatchingRule().getNameOrOID()).isEqualTo("octetStringMatch");
+        assertThat(syntax.getOrderingMatchingRule().getNameOrOID()).isEqualTo("octetStringOrderingMatch");
+        assertThat(syntax.getSubstringMatchingRule()).isEqualTo(null);
+        assertThat(syntax.toString()).isEqualTo(
+                "( 1.9.1.2.3 DESC 'Security Label' X-ENUM ( 'top-secret' 'secret' 'confidential' ) )");
+    }
+
+    /**
+     * When syntax is missing, the default one is set. Actual default is set to directory string
+     * (1.3.6.1.4.1.1466.115.121.1.15) - matchingRules of caseIgnoreMatch and caseIgnoreSubstringsMatch.
+     */
+    @Test()
+    public final void testBuilderAllowsNoSyntaxCaseWhereDefaultSyntaxIsChanged() {
+
+        // @formatter:off
+        final Schema schema = new SchemaBuilder(Schema.getCoreSchema())
+            .defaultSyntax("1.3.6.1.4.1.1466.115.121.1.15")
+            .buildSyntax("1.9.1.2.3")
+                .description("Security Label")
+                .extraProperties("X-ENUM", "top-secret", "secret", "confidential")
+                .addToSchema()
+            .toSchema();
+        // @formatter:on
+
+        assertThat(schema.getWarnings()).isNotEmpty();
+        assertThat(schema.getWarnings().toString()).contains("It will be substituted by the default syntax");
+        final Syntax syntax = schema.getSyntax("1.9.1.2.3");
+        assertThat(syntax).isNotNull();
+        assertThat(syntax.getDescription()).isEqualTo("Security Label");
+        assertThat(syntax.getExtraProperties().get("X-ENUM").size()).isEqualTo(3);
+        assertThat(syntax.getApproximateMatchingRule().getNameOrOID()).isEqualTo("ds-mr-double-metaphone-approx");
+        assertThat(syntax.getEqualityMatchingRule().getNameOrOID()).isEqualTo("caseIgnoreMatch");
+        assertThat(syntax.getOrderingMatchingRule().getNameOrOID()).isEqualTo("caseIgnoreOrderingMatch");
+        assertThat(syntax.getSubstringMatchingRule().getNameOrOID()).isEqualTo("caseIgnoreSubstringsMatch");
+        assertThat(syntax.toString()).isEqualTo(
+                "( 1.9.1.2.3 DESC 'Security Label' X-ENUM ( 'top-secret' 'secret' 'confidential' ) )");
+    }
+
+    /**
+     * The builder allows a missing description.
+     */
+    @Test()
+    public final void testBuilderAllowsNoDescription() {
+        // @formatter:off
+        final Schema schema = new SchemaBuilder(Schema.getCoreSchema())
+            .buildSyntax("1.9.1.2.3")
+            .extraProperties("X-ENUM", "top-secret", "secret", "confidential")
+            .implementation(new OctetStringSyntaxImpl())
+            .addToSchema()
+            .toSchema();
+        // @formatter:on
+
+        assertThat(schema.getWarnings()).isEmpty();
+        final Syntax syntax = schema.getSyntax("1.9.1.2.3");
+        assertThat(syntax).isNotNull();
+        assertThat(syntax.getDescription()).isEqualTo("");
+        assertThat(syntax.getExtraProperties().get("X-ENUM").size()).isEqualTo(3);
+        assertThat(syntax.getApproximateMatchingRule()).isEqualTo(null);
+        assertThat(syntax.getEqualityMatchingRule().getNameOrOID()).isEqualTo("octetStringMatch");
+        assertThat(syntax.getOrderingMatchingRule().getNameOrOID()).isEqualTo("octetStringOrderingMatch");
+        assertThat(syntax.getSubstringMatchingRule()).isEqualTo(null);
+    }
+
+    /**
+     * The builder allows a missing description.
+     */
+    @Test()
+    public final void testBuilderAllowsNullDescription() {
+        // @formatter:off
+        final Schema schema = new SchemaBuilder(Schema.getCoreSchema())
+            .buildSyntax("1.9.1.2.3")
+            .description(null)
+            .extraProperties("X-ENUM", "top-secret", "secret", "confidential")
+            .implementation(new OctetStringSyntaxImpl())
+            .addToSchema()
+            .toSchema();
+        // @formatter:on
+
+        assertThat(schema.getWarnings()).isEmpty();
+        final Syntax syntax = schema.getSyntax("1.9.1.2.3");
+        assertThat(syntax).isNotNull();
+        assertThat(syntax.getDescription()).isEqualTo("");
+        assertThat(syntax.getExtraProperties().get("X-ENUM").size()).isEqualTo(3);
+        assertThat(syntax.getApproximateMatchingRule()).isEqualTo(null);
+        assertThat(syntax.getEqualityMatchingRule().getNameOrOID()).isEqualTo("octetStringMatch");
+        assertThat(syntax.getOrderingMatchingRule().getNameOrOID()).isEqualTo("octetStringOrderingMatch");
+        assertThat(syntax.getSubstringMatchingRule()).isEqualTo(null);
+    }
+
+    /**
+     * The builder allows a missing description.
+     */
+    @Test()
+    public final void testBuilderAllowsEmptyDescription() {
+        // @formatter:off
+        final Schema schema = new SchemaBuilder(Schema.getCoreSchema())
+            .buildSyntax("1.9.1.2.3")
+            .description("")
+            .extraProperties("X-ENUM", "top-secret", "secret", "confidential")
+            .implementation(new OctetStringSyntaxImpl())
+            .addToSchema()
+            .toSchema();
+        // @formatter:on
+
+        assertThat(schema.getWarnings()).isEmpty();
+        final Syntax syntax = schema.getSyntax("1.9.1.2.3");
+        assertThat(syntax).isNotNull();
+        assertThat(syntax.getDescription()).isEqualTo("");
+        assertThat(syntax.getExtraProperties().get("X-ENUM").size()).isEqualTo(3);
+        assertThat(syntax.getApproximateMatchingRule()).isEqualTo(null);
+        assertThat(syntax.getEqualityMatchingRule().getNameOrOID()).isEqualTo("octetStringMatch");
+        assertThat(syntax.getOrderingMatchingRule().getNameOrOID()).isEqualTo("octetStringOrderingMatch");
+        assertThat(syntax.getSubstringMatchingRule()).isEqualTo(null);
+    }
+
+    /**
+     * Extra properties is not a mandatory field.
+     */
+    @Test()
+    public final void testBuilderAllowsNoExtraProperties() {
+        // @formatter:off
+        final Schema schema = new SchemaBuilder(Schema.getCoreSchema())
+            .buildSyntax("1.9.1.2.3")
+                .description("Security Label")
+                .implementation(new OctetStringSyntaxImpl())
+                .addToSchema()
+            .toSchema();
+        // @formatter:on
+
+        assertThat(schema.getWarnings()).isEmpty();
+        final Syntax syntax = schema.getSyntax("1.9.1.2.3");
+        assertThat(syntax).isNotNull();
+        assertThat(syntax.getDescription()).isEqualTo("Security Label");
+        assertThat(syntax.getExtraProperties().isEmpty()).isTrue();
+        assertThat(syntax.getApproximateMatchingRule()).isEqualTo(null);
+        assertThat(syntax.getEqualityMatchingRule().getNameOrOID()).isEqualTo("octetStringMatch");
+        assertThat(syntax.getOrderingMatchingRule().getNameOrOID()).isEqualTo("octetStringOrderingMatch");
+        assertThat(syntax.getSubstringMatchingRule()).isEqualTo(null);
+    }
+
+    /**
+     * Extra properties set to null is not allowed.
+     */
+    @Test(expectedExceptions = NullPointerException.class)
+    public final void testBuilderDoesNotAllowNullExtraProperties() {
+        // @formatter:off
+        new SchemaBuilder(Schema.getCoreSchema())
+                .buildSyntax("1.9.1.2.3")
+                .description("Security Label")
+                .extraProperties(null)
+                .implementation(new OctetStringSyntaxImpl())
+                .addToSchema()
+            .toSchema();
+        // @formatter:on
+    }
+
+    /**
+     * Removes all the extra properties.
+     */
+    @Test()
+    public final void testBuilderRemoveExtraProperties() {
+        // @formatter:off
+        final Schema schema = new SchemaBuilder(Schema.getCoreSchema())
+            .buildSyntax("1.9.1.2.3")
+                .description("Security Label")
+                .extraProperties("X-ENUM", "top-secret", "secret", "confidential")
+                .implementation(new OctetStringSyntaxImpl())
+                .removeAllExtraProperties()
+                .addToSchema()
+            .toSchema();
+        // @formatter:on
+
+        assertThat(schema.getWarnings()).isEmpty();
+        final Syntax syntax = schema.getSyntax("1.9.1.2.3");
+        assertThat(syntax).isNotNull();
+        assertThat(syntax.getDescription()).isEqualTo("Security Label");
+        assertThat(syntax.getExtraProperties().isEmpty()).isTrue();
+        assertThat(syntax.getApproximateMatchingRule()).isEqualTo(null);
+        assertThat(syntax.getEqualityMatchingRule().getNameOrOID()).isEqualTo("octetStringMatch");
+        assertThat(syntax.getOrderingMatchingRule().getNameOrOID()).isEqualTo("octetStringOrderingMatch");
+        assertThat(syntax.getSubstringMatchingRule()).isEqualTo(null);
+    }
+
+    /**
+     * Removes specified extra properties.
+     */
+    @Test()
+    public final void testBuilderRemoveSpecifiedExtraProperties() {
+        // @formatter:off
+        final Schema schema = new SchemaBuilder(Schema.getCoreSchema())
+            .buildSyntax("1.9.1.2.3")
+                .description("Security Label")
+                .extraProperties("X-ENUM", "top-secret", "secret", "confidential")
+                .extraProperties("X-ORIGIN", "Sam Carter")
+                .implementation(new OctetStringSyntaxImpl())
+                .removeExtraProperty("X-ENUM", "top-secret")
+                .addToSchema()
+            .toSchema();
+        // @formatter:on
+
+        assertThat(schema.getWarnings()).isEmpty();
+        final Syntax syntax = schema.getSyntax("1.9.1.2.3");
+        assertThat(syntax).isNotNull();
+        assertThat(syntax.getDescription()).isEqualTo("Security Label");
+        assertThat(syntax.getExtraProperties().isEmpty()).isFalse();
+        assertThat(syntax.getExtraProperties().get("X-ENUM").size()).isEqualTo(2);
+        assertThat(syntax.getExtraProperties().get("X-ORIGIN").size()).isEqualTo(1);
+        assertThat(syntax.getApproximateMatchingRule()).isEqualTo(null);
+        assertThat(syntax.getEqualityMatchingRule().getNameOrOID()).isEqualTo("octetStringMatch");
+        assertThat(syntax.getOrderingMatchingRule().getNameOrOID()).isEqualTo("octetStringOrderingMatch");
+        assertThat(syntax.getSubstringMatchingRule()).isEqualTo(null);
+    }
+
+
+    /**
+     * Sets a syntax using a string definition.
+     */
+    @Test()
+    public final void testAddingBERSyntaxDefinition() {
+        final SchemaBuilder sb = new SchemaBuilder();
+        sb.addSchema(Schema.getCoreSchema(), false);
+
+        final String definition = "( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'X.509 Certificate' )";
+
+        sb.addSyntax(definition, true);
+
+        final Schema schema = sb.toSchema();
+        assertThat(schema.getWarnings()).isEmpty();
+        final Syntax syntax = schema.getSyntax("1.3.6.1.4.1.1466.115.121.1.8");
+        assertThat(syntax).isNotNull();
+        assertThat(syntax.getDescription()).isEqualTo("X.509 Certificate");
+        assertThat(syntax.getExtraProperties().isEmpty()).isTrue();
+        assertThat(syntax.getApproximateMatchingRule()).isNull();
+        assertThat(syntax.getEqualityMatchingRule().getNameOrOID()).isEqualTo("octetStringMatch");
+        assertThat(syntax.getOrderingMatchingRule().getNameOrOID()).isEqualTo("octetStringOrderingMatch");
+        assertThat(syntax.getSubstringMatchingRule()).isNull();
+        assertThat(syntax.isBEREncodingRequired()).isTrue();
+        assertThat(syntax.isHumanReadable()).isFalse();
+    }
+
+    /**
+     * Sets a syntax using a string definition.
+     */
+    @Test()
+    public final void testAddingASyntaxDefinitionStringOverride() {
+        final SchemaBuilder sb = new SchemaBuilder();
+        sb.addSchema(Schema.getCoreSchema(), false);
+
+        final String definition = "( 1.3.6.1.4.1.4203.1.1.2 DESC 'Authentication Password Syntaxe'"
+                + " X-ORIGIN 'RFC 4512' )";
+
+        sb.addSyntax(definition, true);
+
+        final Schema schema = sb.toSchema();
+        assertThat(schema.getWarnings()).isEmpty();
+        final Syntax syntax = schema.getSyntax("1.3.6.1.4.1.4203.1.1.2");
+        assertThat(syntax).isNotNull();
+        assertThat(syntax.getDescription()).isEqualTo("Authentication Password Syntaxe");
+        assertThat(syntax.getExtraProperties().isEmpty()).isFalse();
+        assertThat(syntax.getExtraProperties().get("X-ORIGIN").get(0)).isEqualTo("RFC 4512");
+        assertThat(syntax.getApproximateMatchingRule()).isNull();
+        assertThat(syntax.getEqualityMatchingRule().getNameOrOID()).isEqualTo("authPasswordExactMatch");
+        assertThat(syntax.getOrderingMatchingRule()).isNull();
+        assertThat(syntax.getSubstringMatchingRule()).isNull();
+    }
+
+    /**
+     * Sets a syntax using a string definition.
+     */
+    @Test()
+    public final void testAddingUnknownSyntaxDefinitionString() {
+        final SchemaBuilder sb = new SchemaBuilder();
+        sb.addSchema(Schema.getCoreSchema(), false);
+
+        final String definition = "( 1.3.6.1.4.1.4203.1.1.9999 DESC 'Custom Authentication Password'"
+                + " X-ORIGIN 'None' )";
+
+        sb.addSyntax(definition, false);
+
+        final Schema schema = sb.toSchema();
+        assertThat(schema.getWarnings()).isNotEmpty();
+        final Syntax syntax = schema.getSyntax("1.3.6.1.4.1.4203.1.1.9999");
+        assertThat(syntax).isNotNull();
+        assertThat(syntax.getDescription()).isEqualTo("Custom Authentication Password");
+        assertThat(syntax.getExtraProperties().isEmpty()).isFalse();
+        assertThat(syntax.getExtraProperties().get("X-ORIGIN").get(0)).isEqualTo("None");
+        assertThat(syntax.getApproximateMatchingRule()).isNull();
+        assertThat(syntax.getEqualityMatchingRule().getNameOrOID()).isEqualTo("octetStringMatch");
+        assertThat(syntax.getOrderingMatchingRule().getNameOrOID()).isEqualTo("octetStringOrderingMatch");
+        assertThat(syntax.getSubstringMatchingRule()).isNull();
+    }
+
+    /**
+     * Duplicates a syntax.
+     */
+    @Test()
+    public final void testBuilderDuplicatesExistingSyntax() {
+
+        final SchemaBuilder sb = new SchemaBuilder();
+        sb.addSchema(Schema.getCoreSchema(), false);
+
+        // @formatter:off
+        final Syntax.Builder syntaxBuilder = new Syntax.Builder("1.9.1.2.3", sb);
+        syntaxBuilder.description("Security Label")
+            .extraProperties("X-ENUM", "top-secret", "secret", "confidential")
+            .implementation(new DirectoryStringSyntaxImpl())
+            .addToSchema();
+        // @formatter:on
+
+        Schema schema = sb.toSchema();
+        assertThat(schema.getWarnings()).isEmpty();
+        final Syntax syntax = schema.getSyntax("1.9.1.2.3");
+        assertThat(syntax.getDescription()).isEqualTo("Security Label");
+        assertThat(syntax.getExtraProperties().get("X-ENUM").size()).isEqualTo(3);
+
+        // @formatter:off
+        sb.buildSyntax(syntax)
+            .description("Security Label II")
+            .extraProperties("X-ENUM", "private")
+            .addToSchemaOverwrite();
+        // @formatter:on
+
+        schema = sb.toSchema();
+        assertThat(schema.getWarnings()).isEmpty();
+        final Syntax dolly = schema.getSyntax("1.9.1.2.3");
+        assertThat(dolly.getDescription()).isEqualTo("Security Label II");
+        assertThat(dolly.getExtraProperties().get("X-ENUM").size()).isEqualTo(4);
+        assertThat(dolly.getApproximateMatchingRule().getNameOrOID()).isEqualTo("ds-mr-double-metaphone-approx");
+        assertThat(dolly.getEqualityMatchingRule().getNameOrOID()).isEqualTo("caseIgnoreMatch");
+        assertThat(dolly.getOrderingMatchingRule().getNameOrOID()).isEqualTo("caseIgnoreOrderingMatch");
+        assertThat(dolly.getSubstringMatchingRule().getNameOrOID()).isEqualTo("caseIgnoreSubstringsMatch");
+        assertThat(dolly.toString()).isEqualTo(
+                "( 1.9.1.2.3 DESC 'Security Label II' X-ENUM ( 'top-secret' 'secret' 'confidential' 'private' ) )");
+    }
+
+    /**
+     * Another duplicated syntax example.
+     */
+    @Test()
+    public final void testBuilderDuplicatesSyntax() {
+
+        final SchemaBuilder sb = new SchemaBuilder();
+        sb.addSchema(Schema.getCoreSchema(), false);
+        // @formatter:off
+        final Builder nfb = new Builder("1.2.3.4.5.9999", sb);
+        nfb.description("Description of the new syntax")
+            .extraProperties("X-ORIGIN", "SyntaxCheckingTestCase")
+            .addToSchema();
+
+        Schema schema = sb.toSchema();
+        assertThat(schema.getSyntaxes()).isNotEmpty();
+        final Syntax syntax = schema.getSyntax("1.2.3.4.5.9999");
+        assertThat(syntax.getDescription()).isEqualTo("Description of the new syntax");
+
+        sb.buildSyntax(syntax)
+            .oid("1.2.3.4.5.99996")
+            .extraProperties("X-ORIGIN", "Unknown")
+            .addToSchema();
+        schema = sb.toSchema();
+        assertThat(schema.getSyntaxes()).isNotEmpty();
+        // The duplicated syntax.
+        final Syntax dolly = schema.getSyntax("1.2.3.4.5.99996");
+        assertThat(dolly.getDescription()).isEqualTo("Description of the new syntax");
+        assertThat(dolly.getExtraProperties().size()).isEqualTo(1);
+        assertThat(dolly.getExtraProperties().get("X-ORIGIN").get(0)).isEqualTo("SyntaxCheckingTestCase");
+        assertThat(dolly.getExtraProperties().get("X-ORIGIN").get(1)).isEqualTo("Unknown");
+        assertThat(dolly.getExtraProperties().get("X-ORIGIN").size()).isEqualTo(2);
+
+        // The original hasn't changed.
+        final Syntax originalSyntax = schema.getSyntax("1.2.3.4.5.9999");
+        assertThat(originalSyntax.getDescription()).isEqualTo("Description of the new syntax");
+        assertThat(originalSyntax.getExtraProperties().get("X-ORIGIN").size()).isEqualTo(1);
+    }
+
+    /**
+     * Equality between syntaxes.
+     */
+    @Test()
+    public final void testBuilderSyntaxesEqualsTrue() {
+
+        // @formatter:off
+        final Schema schema = new SchemaBuilder(Schema.getCoreSchema())
+                .buildSyntax("1.9.1.2.3")
+                    .description("Security Label")
+                    .extraProperties("X-ENUM", "top-secret", "secret", "confidential")
+                    .implementation(new DirectoryStringSyntaxImpl())
+                    .addToSchema()
+                .toSchema();
+        // @formatter:on
+
+        final Syntax syntax1 = schema.getSyntax("1.9.1.2.3");
+
+        // @formatter:off
+        final Schema schema2 = new SchemaBuilder(Schema.getCoreSchema())
+                .buildSyntax("1.9.1.2.3")
+                    .description("Security Label")
+                    .extraProperties("X-ENUM", "top-secret", "secret", "confidential")
+                    .implementation(new DirectoryStringSyntaxImpl())
+                    .addToSchema()
+                .toSchema();
+        // @formatter:on
+        final Syntax syntax2 = schema2.getSyntax("1.9.1.2.3");
+
+        assertThat(syntax1).isEqualTo(syntax2);
+    }
+
+    /**
+     * Equality between syntaxes.
+     */
+    @Test()
+    public final void testBuilderSyntaxesEqualsFalse() {
+
+        // @formatter:off
+        final Schema schema = new SchemaBuilder(Schema.getCoreSchema())
+                .buildSyntax("1.9.1.2.3")
+                    .description("Security Label")
+                    .extraProperties("X-ENUM", "top-secret", "secret", "confidential")
+                    .implementation(new DirectoryStringSyntaxImpl())
+                    .addToSchema()
+                .toSchema();
+        // @formatter:on
+
+        final Syntax syntax1 = schema.getSyntax("1.9.1.2.3");
+
+        // @formatter:off
+        final Schema schema2 = new SchemaBuilder(Schema.getCoreSchema())
+                .buildSyntax("1.9.1.2.4")
+                    .description("Security Label")
+                    .extraProperties("X-ENUM", "top-secret", "secret", "confidential")
+                    .implementation(new DirectoryStringSyntaxImpl())
+                    .addToSchema()
+                .toSchema();
+        // @formatter:on
+        final Syntax syntax2 = schema2.getSyntax("1.9.1.2.4");
+
+        assertThat(syntax1).isNotEqualTo(syntax2);
+    }
+
+    /**
+     * Equality between builder and definition.
+     */
+    @Test()
+    public final void testBuilderEqualityReturnsTrueBetweenBuilderAndDefinition() {
+
+        // @formatter:off
+        final Schema schema = new SchemaBuilder(Schema.getCoreSchema())
+            .buildSyntax("1.9.1.2.3")
+            .description("Security Label")
+            .extraProperties("X-ENUM", "top-secret", "secret", "confidential")
+            .implementation(new DirectoryStringSyntaxImpl())
+            .addToSchema()
+            .toSchema();
+        // @formatter:on
+
+        assertThat(schema.getWarnings()).isEmpty();
+        final Syntax syntax1 = schema.getSyntax("1.9.1.2.3");
+
+        final SchemaBuilder sb2 = new SchemaBuilder();
+        sb2.addSchema(Schema.getCoreSchema(), false);
+
+        final String definition =
+                "( 1.9.1.2.3 DESC 'Security Label' X-ENUM ( 'top-secret' 'secret' 'confidential' ) )";
+
+        sb2.addSyntax(definition, false);
+        final Syntax syntax2 = sb2.toSchema().getSyntax("1.9.1.2.3");
+        assertThat(syntax1).isEqualTo(syntax2);
+    }
+
+    /**
+     * Equality between builder and definition fails.
+     */
+    @Test()
+    public final void testBuilderEqualityReturnsFalseBetweenBuilderAndDefinition() {
+
+        // @formatter:off
+        final Schema schema = new SchemaBuilder(Schema.getCoreSchema())
+            .buildSyntax("1.9.1.2.3")
+            .description("Security Label")
+            .extraProperties("X-ENUM", "top-secret", "secret", "confidential")
+            .implementation(new DirectoryStringSyntaxImpl())
+            .addToSchema()
+            .toSchema();
+        // @formatter:on
+
+        assertThat(schema.getWarnings()).isEmpty();
+        final Syntax syntax1 = schema.getSyntax("1.9.1.2.3");
+
+        final SchemaBuilder sb2 = new SchemaBuilder();
+        sb2.addSchema(Schema.getCoreSchema(), false);
+        final String definition =
+                "( 1.9.1.2.4 DESC 'Security Label II' X-ENUM ( 'top-secret' 'secret' 'confidential' ) )";
+
+        sb2.addSyntax(definition, false);
+
+        final Syntax syntax2 = sb2.toSchema().getSyntax("1.9.1.2.4");
+        assertThat(syntax1).isNotEqualTo(syntax2);
+    }
+
+    /**
+     * The builder allows to create chained syntaxes.
+     */
+    @Test()
+    public final void testBuilderCreatesSyntaxesUsingChainingMethods() {
+
+        // @formatter:off
+        final Schema schema = new SchemaBuilder(Schema.getCoreSchema())
+            .buildSyntax("1.9.1.2.3")
+            .description("Security Label")
+            .extraProperties("X-ENUM", "top-secret", "secret", "confidential")
+            .implementation(new DirectoryStringSyntaxImpl())
+            .addToSchema()
+            .buildSyntax("1.9.1.2.4")
+            .description("Security Label II")
+            .extraProperties("X-ENUM", "private")
+            .addToSchema()
+            .buildSyntax("non-implemented-syntax-oid")
+            .description("Not Implemented in OpenDJ")
+            .extraProperties("X-SUBST", "1.3.6.1.4.1.1466.115.121.1.15")
+            .implementation(null)
+            .addToSchema()
+            .buildSyntax("1.3.6.1.4.1.4203.1.1.2")
+            .description("Authentication Password Syntax")
+            .extraProperties("X-ORIGIN", "RFC 4512")
+            .implementation(new OctetStringSyntaxImpl())
+            .addToSchemaOverwrite()
+            .toSchema();
+        // @formatter:on
+
+
+        // Warning should be found as the syntax implementation for s2 is not specified.
+        assertThat(schema.getWarnings()).isNotEmpty();
+        assertThat(schema.getDefaultSyntax().getOID()).isEqualTo("1.3.6.1.4.1.1466.115.121.1.40"); // OctetString OID.
+
+        // First
+        final Syntax s1 = schema.getSyntax("1.9.1.2.3");
+        assertThat(s1.getDescription()).isEqualTo("Security Label");
+        assertThat(s1.getApproximateMatchingRule().getNameOrOID()).isEqualTo("ds-mr-double-metaphone-approx");
+        assertThat(s1.getEqualityMatchingRule().getNameOrOID()).isEqualTo("caseIgnoreMatch");
+        assertThat(s1.getOrderingMatchingRule().getNameOrOID()).isEqualTo("caseIgnoreOrderingMatch");
+        assertThat(s1.getSubstringMatchingRule().getNameOrOID()).isEqualTo("caseIgnoreSubstringsMatch");
+        assertThat(s1.getExtraProperties().get("X-ENUM").size()).isEqualTo(3);
+
+        // Second
+        final Syntax s2 = schema.getSyntax("1.9.1.2.4");
+        assertThat(s2.getDescription()).isEqualTo("Security Label II");
+        assertThat(s2.getExtraProperties().get("X-ENUM").size()).isEqualTo(1);
+        assertThat(s2.getApproximateMatchingRule()).isEqualTo(null);
+        assertThat(s2.getEqualityMatchingRule().getNameOrOID()).isEqualTo("octetStringMatch");
+        assertThat(s2.getOrderingMatchingRule().getNameOrOID()).isEqualTo("octetStringOrderingMatch");
+        assertThat(s2.getSubstringMatchingRule()).isEqualTo(null);
+
+        // Third
+        final Syntax s3 = schema.getSyntax("non-implemented-syntax-oid");
+        assertThat(s3.getDescription()).isEqualTo("Not Implemented in OpenDJ");
+        assertThat(s3.getExtraProperties().get("X-SUBST").size()).isEqualTo(1);
+        // The default syntax is substitute as directory string.
+        assertThat(s1.getApproximateMatchingRule().getNameOrOID()).isEqualTo("ds-mr-double-metaphone-approx");
+        assertThat(s1.getEqualityMatchingRule().getNameOrOID()).isEqualTo("caseIgnoreMatch");
+        assertThat(s1.getOrderingMatchingRule().getNameOrOID()).isEqualTo("caseIgnoreOrderingMatch");
+        assertThat(s1.getSubstringMatchingRule().getNameOrOID()).isEqualTo("caseIgnoreSubstringsMatch");
+
+        // Last
+        final Syntax s4 = schema.getSyntax("1.3.6.1.4.1.4203.1.1.2");
+        assertThat(s4.getDescription()).isEqualTo("Authentication Password Syntax");
+        assertThat(s4.getApproximateMatchingRule()).isEqualTo(null);
+        assertThat(s4.getEqualityMatchingRule().getNameOrOID()).isEqualTo("octetStringMatch");
+        assertThat(s4.getOrderingMatchingRule().getNameOrOID()).isEqualTo("octetStringOrderingMatch");
+        assertThat(s4.getSubstringMatchingRule()).isEqualTo(null);
+        assertThat(s4.getExtraProperties().get("X-ORIGIN").size()).isEqualTo(1);
+    }
 }
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/TelexSyntaxTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/TelexSyntaxTest.java
index a0269ea..0a9f1fb 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/TelexSyntaxTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/TelexSyntaxTest.java
@@ -22,6 +22,7 @@
  *
  *
  *      Copyright 2009 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 package org.forgerock.opendj.ldap.schema;
 
@@ -32,7 +33,7 @@
 /**
  * Telex syntax tests.
  */
-public class TelexSyntaxTest extends SyntaxTestCase {
+public class TelexSyntaxTest extends AbstractSyntaxTestCase {
     /**
      * {@inheritDoc}
      */
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UTCTimeSyntaxTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UTCTimeSyntaxTest.java
index e85e501..959805e 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UTCTimeSyntaxTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UTCTimeSyntaxTest.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2009 Sun Microsystems, Inc.
- *      Portions copyright 2012 ForgeRock AS
+ *      Portions copyright 2012-2014 ForgeRock AS
  *
  */
 package org.forgerock.opendj.ldap.schema;
@@ -41,7 +41,7 @@
 /**
  * UTC time syntax tests.
  */
-public class UTCTimeSyntaxTest extends SyntaxTestCase {
+public class UTCTimeSyntaxTest extends AbstractSyntaxTestCase {
     @Override
     @DataProvider(name = "acceptableValues")
     public Object[][] createAcceptableValues() {
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UUIDSyntaxTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UUIDSyntaxTest.java
index 3ec444f..2bc38cc 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UUIDSyntaxTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/UUIDSyntaxTest.java
@@ -22,6 +22,7 @@
  *
  *
  *      Copyright 2009 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 package org.forgerock.opendj.ldap.schema;
 
@@ -32,7 +33,7 @@
 /**
  * UUID syntax tests.
  */
-public class UUIDSyntaxTest extends SyntaxTestCase {
+public class UUIDSyntaxTest extends AbstractSyntaxTestCase {
     /**
      * {@inheritDoc}
      */

--
Gitblit v1.10.0