You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2018/05/15 22:31:07 UTC

[directory-ldap-api] 05/06: The Fast OpenLdapSchemaParser and all the associate changes.

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

elecharny pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/directory-ldap-api.git

commit 3bdb996da6cbfb8d02ce2f743ba98c6e454f6a9b
Author: Emmanuel Lécharny <el...@symas.com>
AuthorDate: Wed May 16 00:27:24 2018 +0200

    The Fast OpenLdapSchemaParser and all the associate changes.
---
 .../java/org/apache/directory/api/i18n/I18n.java   |   28 +-
 .../apache/directory/api/i18n/errors.properties    |   28 +-
 .../ldap/client/api/DefaultSchemaLoader.java       |   22 +-
 .../ldap/client/api/LdapNetworkConnection.java     |    2 +-
 ldap/codec/core/res.txt                            |  530 ++
 ldap/model/src/checkstyle/suppressions.xml         |    2 +-
 ldap/model/src/main/antlr/distinguishedName.g      |   12 -
 ldap/model/src/main/antlr/schema-extension.g       |  119 -
 ldap/model/src/main/antlr/schema-qdstring.g        |  162 -
 ldap/model/src/main/antlr/schema-value.g           |  442 --
 ldap/model/src/main/antlr/schema.g                 | 1085 ----
 .../model/schema/parsers/AbstractSchemaParser.java |  153 +-
 .../AttributeTypeDescriptionSchemaParser.java      |   21 +-
 .../model/schema/parsers/ConsoleParserMonitor.java |   72 -
 .../DitContentRuleDescriptionSchemaParser.java     |   21 +-
 .../DitStructureRuleDescriptionSchemaParser.java   |   21 +-
 .../schema/parsers/FastOpenLdapSchemaParser.java   | 2266 --------
 .../LdapComparatorDescriptionSchemaParser.java     |   21 +-
 .../parsers/LdapSyntaxDescriptionSchemaParser.java |   19 +-
 .../MatchingRuleDescriptionSchemaParser.java       |   20 +-
 .../MatchingRuleUseDescriptionSchemaParser.java    |   20 +-
 .../parsers/NameFormDescriptionSchemaParser.java   |   20 +-
 .../parsers/NormalizerDescriptionSchemaParser.java |   20 +-
 .../ObjectClassDescriptionSchemaParser.java        |   20 +-
 .../model/schema/parsers/OpenLdapSchemaParser.java | 6117 +++++++++++++++++++-
 .../ldap/model/schema/parsers/ParserMonitor.java   |   53 -
 .../model/schema/parsers/ParserMonitorAdapter.java |   55 -
 .../schema/parsers/ReusableAntlrSchemaLexer.java   |   79 -
 .../schema/parsers/ReusableAntlrSchemaParser.java  |   62 -
 .../SyntaxCheckerDescriptionSchemaParser.java      |   21 +-
 .../AttributeTypeDescriptionSyntaxChecker.java     |    2 +-
 .../DitContentRuleDescriptionSyntaxChecker.java    |    2 +-
 .../DitStructureRuleDescriptionSyntaxChecker.java  |    2 +-
 .../LdapSyntaxDescriptionSyntaxChecker.java        |    2 +-
 .../MatchingRuleDescriptionSyntaxChecker.java      |    2 +-
 .../MatchingRuleUseDescriptionSyntaxChecker.java   |    2 +-
 .../NameFormDescriptionSyntaxChecker.java          |    2 +-
 .../ObjectClassDescriptionSyntaxChecker.java       |    2 +-
 .../model/schema/SchemaObjectRendererTest.java     |    8 +-
 .../parsers/FastOpenLdapSchemaParserTest.java      |   22 +-
 .../schema/parsers/OpenLdapSchemaParserTest.java   |   18 +-
 .../AttributeTypeDescriptionSyntaxCheckerTest.java |    2 +-
 ...DitContentRuleDescriptionSyntaxCheckerTest.java |    2 +-
 ...tStructureRuleDescriptionSyntaxCheckerTest.java |    2 +-
 .../ObjectClassDescriptionSyntaxCheckerTest.java   |    2 +-
 ...uteTypeDescriptionSchemaParserRelaxedTest.java} |  466 +-
 ...buteTypeDescriptionSchemaParserStrictTest.java} |  636 +-
 .../ComparatorDescriptionSchemaParserTest.java     |   21 +-
 ...entRuleDescriptionSchemaParserRelaxedTest.java} |  156 +-
 .../DitContentRuleDescriptionSchemaParserTest.java |  228 +-
 ...ureRuleDescriptionSchemaParserRelaxedTest.java} |   97 +-
 ...tureRuleDescriptionSchemaParserStrictTest.java} |  139 +-
 .../LdapSyntaxDescriptionSchemaParserTest.java     |   19 +-
 .../MatchingRuleDescriptionSchemaParserTest.java   |  146 +-
 ...MatchingRuleUseDescriptionSchemaParserTest.java |  126 +-
 .../NameFormDescriptionSchemaParserTest.java       |  141 +-
 .../NormalizerDescriptionSchemaParserTest.java     |    4 +-
 ...ctClassDescriptionSchemaParserRelaxedTest.java} |  189 +-
 ...ectClassDescriptionSchemaParserStrictTest.java} |  295 +-
 .../syntaxes/parser/SchemaParserTestUtils.java     |  510 +-
 .../SyntaxCheckerDescriptionSchemaParserTest.java  |   14 +-
 61 files changed, 8577 insertions(+), 6195 deletions(-)

diff --git a/i18n/src/main/java/org/apache/directory/api/i18n/I18n.java b/i18n/src/main/java/org/apache/directory/api/i18n/I18n.java
index 4c541f3..bffc107 100644
--- a/i18n/src/main/java/org/apache/directory/api/i18n/I18n.java
+++ b/i18n/src/main/java/org/apache/directory/api/i18n/I18n.java
@@ -806,9 +806,8 @@ public enum I18n
     ERR_13777_COLLECTIVE_NOT_MULTI_VALUED( "ERR_13777_COLLECTIVE_NOT_MULTI_VALUED" ),
     ERR_13778_COLLECTIVE_NOT_ALLOWED_IN_MUST( "ERR_13778_COLLECTIVE_NOT_ALLOWED_IN_MUST" ),
     ERR_13779_COLLECTIVE_NOT_ALLOWED_IN_MAY( "ERR_13779_COLLECTIVE_NOT_ALLOWED_IN_MAY" ),
-
-    ERR_13780_AT_DESCRIPTION_HAS_ELEMENT_TWICE( "ERR_13780_AT_DESCRIPTION_HAS_ELEMENT_TWICE" ),
-    ERR_13781_OC_DESCRIPTION_HAS_ELEMENT_TWICE( "ERR_13781_OC_DESCRIPTION_HAS_ELEMENT_TWICE" ),
+    ERR_13780_SCHEMA_OBJECT_DESCRIPTION_HAS_ELEMENT_TWICE( "ERR_13780_SCHEMA_OBJECT_DESCRIPTION_HAS_ELEMENT_TWICE" ),
+    ERR_13781_MR_DESCRIPTION_INVALID( "ERR_13781_MR_DESCRIPTION_INVALID" ),
     ERR_13782_END_OF_FILE( "ERR_13782_END_OF_FILE" ),
     ERR_13783_SPACE_EXPECTED( "ERR_13783_SPACE_EXPECTED" ),
     ERR_13784_BAD_OID_TWO_ZEROES( "ERR_13785_BAD_OID_CONSECUTIVE_DOTS" ),
@@ -834,6 +833,29 @@ public enum I18n
     ERR_13804_OBJECT_IDENTIFIER_HAS_NO_OID( "ERR_13804_OBJECT_IDENTIFIER_HAS_NO_OID" ),
     ERR_13805_OBJECT_IDENTIFIER_INVALID_OID( "ERR_13805_OBJECT_IDENTIFIER_INVALID_OID" ),
     ERR_13806_UNEXPECTED_ELEMENT_READ( "ERR_13806_UNEXPECTED_ELEMENT_READ" ),
+    ERR_13807_SYN_DESCRIPTION_INVALID( "ERR_13807_SYN_DESCRIPTION_INVALID" ),
+    ERR_13808_SYNTAX_REQUIRED( "ERR_13808_SYNTAX_REQUIRED" ),
+    ERR_13809_DCR_DESCRIPTION_INVALID( "ERR_13809_DCR_DESCRIPTION_INVALID" ),
+    ERR_13810_DSR_DESCRIPTION_INVALID( "ERR_13810_DSR_DESCRIPTION_INVALID" ),
+    ERR_13811_INVALID_RULE_ID( "ERR_13811_INVALID_RULE_ID" ),
+    ERR_13812_FORM_REQUIRED( "ERR_13812_FORM_REQUIRED" ),
+    ERR_13813_MORE_RULE_IDS_EXPECTED( "ERR_13813_MORE_RULE_IDS_EXPECTED" ),
+    ERR_13814_APPLIES_REQUIRED( "ERR_13814_APPLIES_REQUIRED" ),
+    ERR_13815_MRU_DESCRIPTION_INVALID( "ERR_13815_MRU_DESCRIPTION_INVALID" ),
+    ERR_13816_NF_DESCRIPTION_INVALID( "ERR_13816_NF_DESCRIPTION_INVALID" ),
+    ERR_13817_STRUCTURAL_OBJECT_CLASS_REQUIRED( "ERR_13817_STRUCTURAL_OBJECT_CLASS_REQUIRED" ),
+    ERR_13818_MUST_REQUIRED( "ERR_13818_MUST_REQUIRED" ),
+    ERR_13819_FQCN_REQUIRED( "ERR_13819_FQCN_REQUIRED" ),
+    ERR_13820_BYTE_CODE_REQUIRED( "ERR_13820_BYTE_CODE_REQUIRED" ),
+    ERR_13821_NORM_DESCRIPTION_INVALID( "ERR_13821_NORM_DESCRIPTION_INVALID" ),
+    ERR_13822_INVALID_FQCN_BAD_IDENTIFIER_START( "ERR_13822_INVALID_FQCN_BAD_IDENTIFIER_START" ),
+    ERR_13823_INVALID_FQCN_DOUBLE_DOT( "ERR_13823_INVALID_FQCN_DOUBLE_DOT" ),
+    ERR_13824_INVALID_FQCN_BAD_IDENTIFIER( "ERR_13824_INVALID_FQCN_BAD_IDENTIFIER" ),
+    ERR_13825_COMP_DESCRIPTION_INVALID( "ERR_13825_COMP_DESCRIPTION_INVALID" ),
+    ERR_13826_SC_DESCRIPTION_INVALID( "ERR_13826_SC_DESCRIPTION_INVALID" ),
+    ERR_13827_EMPTY_SYNTAX_LEN( "ERR_13827_EMPTY_SYNTAX_LEN" ),
+    ERR_13828_MISSING_SYNTAX_OID( "ERR_13828_MISSING_SYNTAX_OID" ),
+    ERR_13829_NO_OPENING_PAREN( "ERR_13829_NO_OPENING_PAREN" ),
 
     
     // api-ldap-net-mina 14000 - 14999
diff --git a/i18n/src/main/resources/org/apache/directory/api/i18n/errors.properties b/i18n/src/main/resources/org/apache/directory/api/i18n/errors.properties
index 333f43f..f9b9001 100644
--- a/i18n/src/main/resources/org/apache/directory/api/i18n/errors.properties
+++ b/i18n/src/main/resources/org/apache/directory/api/i18n/errors.properties
@@ -769,9 +769,8 @@ ERR_13776_CANNOT_SUBTYPE_COLLECTIVE=The Collective Attribute ({0}) cannot be sub
 ERR_13777_COLLECTIVE_NOT_MULTI_VALUED=The Collective Attribute ({0}) cannot be single valued
 ERR_13778_COLLECTIVE_NOT_ALLOWED_IN_MUST=The Collective Attribute ({0}) cannot be added in the MUST list of the {1} ObjectClass
 ERR_13779_COLLECTIVE_NOT_ALLOWED_IN_MAY=The Collective Attribute ({0}) cannot be added in the MAY list of the {1} ObjectClass
-
-ERR_13780_AT_DESCRIPTION_HAS_ELEMENT_TWICE=Can''t have a {0} twice in an AttributeTypeDescription (line {1}, col {2})
-ERR_13781_OC_DESCRIPTION_HAS_ELEMENT_TWICE=Can''t have a {0} twice in an ObjectClassDescription (line {1}, col {2})
+ERR_13780_SCHEMA_OBJECT_DESCRIPTION_HAS_ELEMENT_TWICE=Can''t have a {0} twice in an Schema Object Description (line {1}, col {2})
+ERR_13781_MR_DESCRIPTION_INVALID=Error, MatchingRule definition invalid (line {0}, col {1})
 ERR_13782_END_OF_FILE=End of file met (line {0}, col {1})
 ERR_13783_SPACE_EXPECTED=Space expected (line {0}, col {1})
 ERR_13784_BAD_OID_TWO_ZEROES=Bad OID, we have a number that starts with ''0'' (line {0}, col {1})
@@ -797,6 +796,29 @@ ERR_13803_OC_DESCRIPTION_INVALID=Error, ObjectClass definition invalid (line {0}
 ERR_13804_OBJECT_IDENTIFIER_HAS_NO_OID=The ObjectIdentifier does not have any OID (line {0}, col {1})
 ERR_13805_OBJECT_IDENTIFIER_INVALID_OID=The ObjectIdentifier has an invalid OID (line {0}, col {1})
 ERR_13806_UNEXPECTED_ELEMENT_READ=Unexpected element read: {0} (line {1}, col {2})
+ERR_13807_SYN_DESCRIPTION_INVALID=Error, LdapSyntax definition invalid (line {0}, col {1})
+ERR_13808_SYNTAX_REQUIRED=SYNTAX is required (line {0}, col {1})
+ERR_13809_DCR_DESCRIPTION_INVALID=Error, DitContentRule definition invalid (line {0}, col {1})
+ERR_13810_DSR_DESCRIPTION_INVALID=Error, DitStructureRule definition invalid (line {0}, col {1})
+ERR_13811_INVALID_RULE_ID=Invalid or missing ruleid (line {0}, col {1})
+ERR_13812_FORM_REQUIRED=FORM required (line {0}, col {1})
+ERR_13813_MORE_RULE_IDS_EXPECTED=more RULEID expected (line {0}, col {1})
+ERR_13814_APPLIES_REQUIRED=APPLIES required (line {0}, col {1})
+ERR_13815_MRU_DESCRIPTION_INVALID=Error, MatchingRuleUse definition invalid (line {0}, col {1})
+ERR_13816_NF_DESCRIPTION_INVALID=Error, NameForm definition invalid (line {0}, col {1})
+ERR_13817_STRUCTURAL_OBJECT_CLASS_REQUIRED=OC required (line {0}, col {1})
+ERR_13818_MUST_REQUIRED=MUST required (line {0}, col {1})
+ERR_13819_FQCN_REQUIRED=FQCN required (line {0}, col {1})
+ERR_13820_BYTE_CODE_REQUIRED=BYTECODE required (line {0}, col {1})
+ERR_13821_NORM_DESCRIPTION_INVALID=Error, Normalizer definition invalid (line {0}, col {1})
+ERR_13822_INVALID_FQCN_BAD_IDENTIFIER_START=The FQCN is invalid, an identifier starts with an invalid java letter (line {0}, col {1})
+ERR_13823_INVALID_FQCN_DOUBLE_DOT=The FQCN is invalid, there are two consecutive dots (line {0}, col {1})
+ERR_13824_INVALID_FQCN_BAD_IDENTIFIER=The FQCN is invalid, an identifier has a wrong java letter (line {0}, col {1})
+ERR_13825_COMP_DESCRIPTION_INVALID=Error, LdapComparator definition invalid (line {0}, col {1})
+ERR_13826_SC_DESCRIPTION_INVALID=Error, SyntaxChecker definition invalid (line {0}, col {1})
+ERR_13827_EMPTY_SYNTAX_LEN=The SYNTAX length is empty (line {0}, col {1})
+ERR_13828_MISSING_SYNTAX_OID=The SYNTAX has no OID (line {0}, col {1})
+ERR_13829_NO_OPENING_PAREN=There is a missing opening ''('' (line {0}, col {1})
 
 # api-ldap-net-mina 14000-14999
 
diff --git a/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/DefaultSchemaLoader.java b/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/DefaultSchemaLoader.java
index 97c6a11..07b1030 100644
--- a/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/DefaultSchemaLoader.java
+++ b/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/DefaultSchemaLoader.java
@@ -343,7 +343,7 @@ public class DefaultSchemaLoader extends AbstractSchemaLoader
 
             try
             {
-                AttributeType attributeType = AT_DESCR_SCHEMA_PARSER.parseAttributeTypeDescription( desc );
+                AttributeType attributeType = AT_DESCR_SCHEMA_PARSER.parse( desc );
 
                 updateSchemas( attributeType );
             }
@@ -368,7 +368,7 @@ public class DefaultSchemaLoader extends AbstractSchemaLoader
 
             try
             {
-                LdapComparatorDescription comparator = C_DESCR_SCHEMA_PARSER.parseComparatorDescription( desc );
+                LdapComparatorDescription comparator = C_DESCR_SCHEMA_PARSER.parse( desc );
 
                 updateSchemas( comparator );
             }
@@ -393,7 +393,7 @@ public class DefaultSchemaLoader extends AbstractSchemaLoader
 
             try
             {
-                DitContentRule ditContentRule = DCR_DESCR_SCHEMA_PARSER.parseDITContentRuleDescription( desc );
+                DitContentRule ditContentRule = DCR_DESCR_SCHEMA_PARSER.parse( desc );
 
                 updateSchemas( ditContentRule );
             }
@@ -418,7 +418,7 @@ public class DefaultSchemaLoader extends AbstractSchemaLoader
 
             try
             {
-                DitStructureRule ditStructureRule = DSR_DESCR_SCHEMA_PARSER.parseDITStructureRuleDescription( desc );
+                DitStructureRule ditStructureRule = DSR_DESCR_SCHEMA_PARSER.parse( desc );
 
                 updateSchemas( ditStructureRule );
             }
@@ -443,7 +443,7 @@ public class DefaultSchemaLoader extends AbstractSchemaLoader
 
             try
             {
-                LdapSyntax ldapSyntax = LS_DESCR_SCHEMA_PARSER.parseLdapSyntaxDescription( desc );
+                LdapSyntax ldapSyntax = LS_DESCR_SCHEMA_PARSER.parse( desc );
 
                 updateSchemas( ldapSyntax );
             }
@@ -468,7 +468,7 @@ public class DefaultSchemaLoader extends AbstractSchemaLoader
 
             try
             {
-                MatchingRule matchingRule = MR_DESCR_SCHEMA_PARSER.parseMatchingRuleDescription( desc );
+                MatchingRule matchingRule = MR_DESCR_SCHEMA_PARSER.parse( desc );
 
                 updateSchemas( matchingRule );
             }
@@ -493,7 +493,7 @@ public class DefaultSchemaLoader extends AbstractSchemaLoader
 
             try
             {
-                MatchingRuleUse matchingRuleUse = MRU_DESCR_SCHEMA_PARSER.parseMatchingRuleUseDescription( desc );
+                MatchingRuleUse matchingRuleUse = MRU_DESCR_SCHEMA_PARSER.parse( desc );
 
                 updateSchemas( matchingRuleUse );
             }
@@ -518,7 +518,7 @@ public class DefaultSchemaLoader extends AbstractSchemaLoader
 
             try
             {
-                NameForm nameForm = NF_DESCR_SCHEMA_PARSER.parseNameFormDescription( desc );
+                NameForm nameForm = NF_DESCR_SCHEMA_PARSER.parse( desc );
 
                 updateSchemas( nameForm );
             }
@@ -543,7 +543,7 @@ public class DefaultSchemaLoader extends AbstractSchemaLoader
 
             try
             {
-                NormalizerDescription normalizer = N_DESCR_SCHEMA_PARSER.parseNormalizerDescription( desc );
+                NormalizerDescription normalizer = N_DESCR_SCHEMA_PARSER.parse( desc );
 
                 updateSchemas( normalizer );
             }
@@ -568,7 +568,7 @@ public class DefaultSchemaLoader extends AbstractSchemaLoader
 
             try
             {
-                ObjectClass objectClass = OC_DESCR_SCHEMA_PARSER.parseObjectClassDescription( desc );
+                ObjectClass objectClass = OC_DESCR_SCHEMA_PARSER.parse( desc );
 
                 updateSchemas( objectClass );
             }
@@ -593,7 +593,7 @@ public class DefaultSchemaLoader extends AbstractSchemaLoader
 
             try
             {
-                SyntaxCheckerDescription syntaxChecker = SC_DESCR_SCHEMA_PARSER.parseSyntaxCheckerDescription( desc );
+                SyntaxCheckerDescription syntaxChecker = SC_DESCR_SCHEMA_PARSER.parse( desc );
 
                 updateSchemas( syntaxChecker );
             }
diff --git a/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdapNetworkConnection.java b/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdapNetworkConnection.java
index f9c155f..b6ca7e0 100644
--- a/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdapNetworkConnection.java
+++ b/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdapNetworkConnection.java
@@ -4313,7 +4313,7 @@ public class LdapNetworkConnection extends AbstractLdapConnection implements Lda
                 registries.getAttributeTypeRegistry().register( atType );
             }
 
-            for ( ObjectClass oc : olsp.getObjectClassTypes() )
+            for ( ObjectClass oc : olsp.getObjectClasses() )
             {
                 registries.buildReference( errors, oc );
                 registries.getObjectClassRegistry().register( oc );
diff --git a/ldap/codec/core/res.txt b/ldap/codec/core/res.txt
new file mode 100644
index 0000000..cb7bec5
--- /dev/null
+++ b/ldap/codec/core/res.txt
@@ -0,0 +1,530 @@
+Strings : 
+
+---------------------------------------------------
+
+src/main/java/org/apache/directory/api/ldap/codec/actions/controls/InitControls.java:                LOG.debug( "A new list of controls has been initialized" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/controls/InitControls.java:                LOG.debug( "An empty list of controls has been initialized" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapMessage/StoreMessageId.java:                LOG.debug( "Ldap Message Id has been decoded : " + messageId );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/AddReferral.java:                    LOG.warn( "The Referral error message is not allowed when havind an error code no equals to REFERRAL" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/AddReferral.java:                LOG.debug( "The referral error message is set to " + sb.toString() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/InitReferrals.java:            LOG.debug( "Initialising a referrals list" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/StoreErrorMessage.java:            LOG.debug( "The error message is : " + errorMessage );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/StoreMatchedDN.java:                        LOG.warn( "The matched Dn should not be set when the result code is not one of NoSuchObject,"
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/StoreMatchedDN.java:                            + " AliasProblem, InvalidDNSyntax or AliasDreferencingProblem" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/StoreMatchedDN.java:            LOG.debug( "The matchedDn is " + matchedDn );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/StoreResultCode.java:            LOG.debug( "The result code is set to " + resultCode );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/abandon/InitAbandonRequest.java:                LOG.debug( "AbandonMessage Id has been decoded : {}", Integer.valueOf( abandonnedMessageId ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/AddAddRequestAttributeType.java:            LOG.debug( "Adding type {}", type );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/AddAttributeValue.java:                        LOG.debug( "Adding value {}", Strings.dumpBytes( ( byte[] ) value ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/AddAttributeValue.java:                        LOG.debug( "Adding value {}" + value );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/StoreAddRequestEntryName.java:                String msg = "Invalid Dn given : " + dnStr + " (" + Strings.dumpBytes( dnBytes )
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/StoreAddRequestEntryName.java:                LOG.error( "{} : {}", msg, ine.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/StoreAddRequestEntryName.java:            LOG.debug( "Adding an entry with Dn : {}", addRequest.getEntry() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/InitSaslBind.java:            LOG.debug( "The SaslCredential has been created" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/StoreName.java:            LOG.debug( " The Bind name is {}", bindRequestMessage.getName() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/StoreSaslCredentials.java:            LOG.debug( "The credentials are : {}", Strings.dumpBytes( bindRequestMessage
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/StoreSaslMechanism.java:            LOG.debug( "The mechanism is : {}", bindRequestMessage.getSaslMechanism() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/StoreSimpleAuth.java:            LOG.debug( "The simple authentication is : {}", Strings.dumpBytes( bindRequestMessage
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/StoreVersion.java:                LOG.debug( "Ldap version ", Integer.valueOf( version ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/compare/InitCompareRequest.java:            LOG.debug( "Compare Request" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/compare/StoreCompareRequestAssertionValue.java:                    LOG.debug( "Comparing attribute value {}", Strings.dumpBytes( compareRequest
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/compare/StoreCompareRequestAssertionValue.java:                    LOG.debug( "Comparing attribute value {}", compareRequest.getAssertionValue() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/compare/StoreCompareRequestAttributeDesc.java:            LOG.debug( "Comparing attribute description {}", compareRequest.getAttributeId() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/compare/StoreCompareRequestEntryName.java:                String msg = "Invalid Dn given : " + dnStr + " (" + Strings.dumpBytes( dnBytes )
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/compare/StoreCompareRequestEntryName.java:                LOG.error( "{} : {}", msg, ine.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/compare/StoreCompareRequestEntryName.java:            LOG.debug( "Comparing Dn {}", entry );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/del/InitDelRequest.java:            LOG.debug( "Deleting Dn {}", entry );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/extended/InitExtendedRequest.java:            LOG.debug( "Extended request being processed ..." );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/extended/StoreExtendedRequestName.java:                    String msg = "The Request name is not a valid OID : "
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/extended/StoreExtendedRequestName.java:                        + Strings.utf8ToString( requestNameBytes ) + " ("
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/extended/StoreExtendedRequestName.java:                        + Strings.dumpBytes( requestNameBytes ) + ") is invalid";
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/extended/StoreExtendedRequestName.java:                String msg = "The Request name is not a valid OID : "
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/extended/StoreExtendedRequestName.java:                    + Strings.utf8ToString( requestNameBytes ) + " ("
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/extended/StoreExtendedRequestName.java:                    + Strings.dumpBytes( requestNameBytes ) + ") is invalid";
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/extended/StoreExtendedRequestName.java:                LOG.error( "{} : {}", msg, de.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/extended/StoreExtendedRequestName.java:            LOG.debug( "OID read : {}", req.getRequestName() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/extended/StoreExtendedRequestValue.java:            LOG.debug( "Extended value : {}", extendedRequest.getRequestValue() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/AddModifyRequestAttribute.java:            LOG.debug( "Modifying type : {}", type );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/InitAttributeVals.java:            LOG.debug( "No vals for this attribute" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/InitAttributeVals.java:            LOG.debug( "Some vals are to be decoded" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/StoreModifyRequestAttributeValue.java:            LOG.debug( "Value modified : {}", value );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/StoreModifyRequestObjectName.java:                String msg = "Invalid Dn given : " + dnStr + " (" + Strings.dumpBytes( dnBytes )
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/StoreModifyRequestObjectName.java:                    + ") is invalid";
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/StoreModifyRequestObjectName.java:                LOG.error( "{} : {}", msg, ine.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/StoreModifyRequestObjectName.java:            LOG.debug( "Modification of Dn {}", modifyRequest.getName() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/StoreOperationType.java:                    LOG.debug( "Modification operation : ADD" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/StoreOperationType.java:                    LOG.debug( "Modification operation : DELETE" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/StoreOperationType.java:                    LOG.debug( "Modification operation : REPLACE" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/StoreOperationType.java:                    LOG.debug( "Modification operation : UNKNOWN" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/InitModifyDnRequest.java:            LOG.debug( "ModifyDn request" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestDeleteOldRdn.java:                LOG.debug( " Old Rdn attributes will be deleted" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestDeleteOldRdn.java:                LOG.debug( " Old Rdn attributes will be retained" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestEntryName.java:                String msg = "Invalid Dn given : " + dnStr + " (" + Strings.dumpBytes( dnBytes )
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestEntryName.java:                    + ") is invalid";
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestEntryName.java:                LOG.error( "{} : {}", msg, ine.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestEntryName.java:            LOG.debug( "Modifying Dn {}", entry );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewRdn.java:                String msg = "Invalid new Rdn given : " + dnStr + " (" + Strings.dumpBytes( dnBytes )
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewRdn.java:                    + ") is invalid";
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewRdn.java:                LOG.error( "{} : {}", msg, ine.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewRdn.java:            LOG.debug( "Modifying with new Rdn {}", newRdn );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewSuperior.java:                    LOG.warn( "The new superior is null, so we will change the entry" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewSuperior.java:                String msg = "Invalid new superior Dn given : " + dnStr + " ("
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewSuperior.java:                    + Strings.dumpBytes( dnBytes ) + ") is invalid";
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewSuperior.java:                LOG.error( "{} : {}", msg, ine.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewSuperior.java:            LOG.debug( "New superior Dn {}", newSuperior );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitAndFilter.java:            LOG.debug( "Initialize AND filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitApproxMatchFilter.java:            LOG.debug( "Initialize Approx Match filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitAssertionValueFilter.java:            LOG.debug( "Initialize Assertion Value filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitAttributeDescFilter.java:            LOG.debug( "Initialize AttributeDesc filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitEqualityMatchFilter.java:            LOG.debug( "Initialize Equality Match filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitExtensibleMatchFilter.java:            LOG.debug( "Initialize Extensible Match filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitGreaterOrEqualFilter.java:            LOG.debug( "Initialize Greater Or Equal filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitLessOrEqualFilter.java:            LOG.debug( "Initialize Less Or Equal filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitNotFilter.java:            LOG.debug( "Initialize NOT filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitOrFilter.java:            LOG.debug( "Initialize OR filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitPresentFilter.java:            presentFilter.setAttributeDescription( "" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitPresentFilter.java:            LOG.debug( "Initialize Present filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitSubstringsFilter.java:            LOG.debug( "Initialize Substrings filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreAny.java:            LOG.debug( "Stored a any substring : {}", any );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreFinal.java:            LOG.debug( "Stored a any substring : {}", finalValue );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreMatchingRuleDnAttributes.java:            LOG.debug( "Dn Attributes : {}", Boolean.valueOf( extensibleMatchFilter.isDnAttributes() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreMatchValue.java:            LOG.debug( "Stored a match value : {}", value );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/InitSearchRequest.java:            LOG.debug( "Search Request" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/InitSearchRequestAttributeDescList.java:            LOG.debug( "Initialize AttributeDesc list" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestAttributeDesc.java:            LOG.debug( "Decoded Attribute Description : {}", attributeDescription );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestBaseObject.java:                String msg = "Invalid root Dn given : " + dnStr + " (" + Strings.dumpBytes( dnBytes )
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestBaseObject.java:                    + ") is invalid";
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestBaseObject.java:                LOG.error( "{} : {}", msg, ine.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestBaseObject.java:            LOG.debug( "Searching with root Dn : {}", baseObject );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestDerefAlias.java:                    LOG.debug( "Handling object strategy : NEVER_DEREF_ALIASES" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestDerefAlias.java:                    LOG.debug( "Handling object strategy : DEREF_IN_SEARCHING" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestDerefAlias.java:                    LOG.debug( "Handling object strategy : DEREF_FINDING_BASE_OBJ" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestDerefAlias.java:                    LOG.debug( "Handling object strategy : DEREF_ALWAYS" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestDerefAlias.java:                    LOG.debug( "Handling object strategy : UNKNOWN" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestScope.java:                    LOG.debug( "Searching within BASE_OBJECT scope " );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestScope.java:                    LOG.debug( "Searching within SINGLE_LEVEL scope " );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestScope.java:                    LOG.debug( "Searching within WHOLE_SUBTREE scope " );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestScope.java:                    LOG.debug( "Searching within UNKNOWN scope " );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestSizeLimit.java:            LOG.debug( "The sizeLimit value is set to {} objects", Long.valueOf( sizeLimit ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestTimeLimit.java:            LOG.debug( "The timeLimit value is set to {} seconds", Integer.valueOf( timeLimit ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestTypesOnly.java:            LOG.debug( "The search will return {}", searchRequest.getTypesOnly() ? "only attributs type"
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestTypesOnly.java:                : "attributes types and values" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreTypeMatchingRule.java:                LOG.debug( "Stored a type matching rule : {}", type );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/add/InitAddResponse.java:            LOG.debug( "Add Response" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/bind/StoreServerSASLCreds.java:            LOG.debug( "The SASL credentials value is : {}", Strings.dumpBytes( serverSaslCreds ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/compare/InitCompareResponse.java:            LOG.debug( "Compare response " );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/del/InitDelResponse.java:            LOG.debug( "Del response " );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/extended/InitExtendedResponse.java:            LOG.debug( "Extended Response" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/extended/StoreExtendedResponseName.java:            LOG.debug( "OID read : {}", extendedResponse.getResponseName() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/extended/StoreExtendedResponseValue.java:            LOG.debug( "Extended value : {}", extendedResponse.getResponseValue() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/intermediate/InitIntermediateResponse.java:            LOG.debug( "Intermediate Response" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/intermediate/StoreIntermediateResponseName.java:                String msg = "The Intermediate Response name is not a valid OID : "
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/intermediate/StoreIntermediateResponseName.java:                    + Strings.utf8ToString( responseNameBytes ) + " ("
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/intermediate/StoreIntermediateResponseName.java:                    + Strings.dumpBytes( responseNameBytes ) + ") is invalid";
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/intermediate/StoreIntermediateResponseName.java:                LOG.error( "{} : {}", msg, oidStr );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/intermediate/StoreIntermediateResponseName.java:            LOG.debug( "OID read : {}", intermediateResponse.getResponseName() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/intermediate/StoreIntermediateResponseValue.java:            LOG.debug( "Value read : {}", Strings.dumpBytes( intermediateResponse.getResponseValue() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/modify/InitModifyResponse.java:            LOG.debug( "Modify response" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/modifydn/InitModifyDnResponse.java:            LOG.debug( "Modify Dn response " );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/done/InitSearchResultDone.java:            LOG.debug( "Search Result Done found" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/AddAttributeType.java:                String msg = "The Attribute type " + type + "is invalid : " + ine.getMessage();
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/AddAttributeType.java:                LOG.error( "{} : {}", msg, ine.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/AddAttributeType.java:            LOG.debug( "Attribute type : {}", type );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/StoreSearchResultAttributeValue.java:                searchResultEntry.addAttributeValue( "" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/StoreSearchResultAttributeValue.java:                    LOG.debug( "The attribute value is null" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/StoreSearchResultAttributeValue.java:                        LOG.debug( "Attribute value {}", Strings.dumpBytes( ( byte[] ) value ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/StoreSearchResultAttributeValue.java:                        LOG.debug( "Attribute value {}", value );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/StoreSearchResultEntryObjectName.java:                String msg = "The Dn " + Strings.dumpBytes( dnBytes ) + "is invalid : "
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/StoreSearchResultEntryObjectName.java:                LOG.error( "{} : {}", msg, ine.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/StoreSearchResultEntryObjectName.java:            LOG.debug( "Search Result Entry Dn found : {}", searchResultEntry.getObjectName() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/reference/InitSearchResultReference.java:            LOG.debug( "SearchResultReference response " );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/reference/StoreReference.java:            LOG.debug( "Search reference URL found : {}", url );
+src/main/java/org/apache/directory/api/ldap/codec/api/LdapApiServiceFactory.java:            String msg = "Not initialized yet!";
+src/main/java/org/apache/directory/api/ldap/codec/api/LdapApiServiceFactory.java:            StringBuilder sb = new StringBuilder( "The LdapCodecService is already set to an instance of " );
+src/main/java/org/apache/directory/api/ldap/codec/api/LdapDecoder.java:                LOG.debug( "Decoded LdapMessage : " + container );
+src/main/java/org/apache/directory/api/ldap/codec/api/LdapEncoder.java:            throw new NullPointerException( "codec argument cannot be null" );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                                        LOG.debug( "changeType = " + changeType );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                                LOG.debug( "previousDN = " + previousDn );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                        LOG.debug( "changeNumber = " + changeNumber );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/pagedSearch/PagedResultsGrammar.java:                                LOG.debug( "size = " + size );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/persistentSearch/PersistentSearchGrammar.java:                                LOG.debug( "changeTypes = " + changeTypes );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/persistentSearch/PersistentSearchGrammar.java:                                LOG.debug( "changesOnly = " + changesOnly );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/persistentSearch/PersistentSearchGrammar.java:                                LOG.debug( "returnECs = " + returnECs );
+src/main/java/org/apache/directory/api/ldap/codec/controls/sort/SortRequestGrammar.java:                    LOG.debug( "AttributeTypeDesc = " + atDesc );
+src/main/java/org/apache/directory/api/ldap/codec/controls/sort/SortRequestGrammar.java:                        LOG.debug( "ReverseOrder = " + reverseOrder );
+src/main/java/org/apache/directory/api/ldap/codec/controls/sort/SortRequestGrammar.java:                            LOG.debug( "MatchingRuleOid = " + matchingRuleOid );
+src/main/java/org/apache/directory/api/ldap/codec/controls/sort/SortResponseGrammar.java:                            LOG.debug( "AttributeType = " + atType );
+src/main/java/org/apache/directory/api/ldap/codec/decorators/AddRequestDecorator.java:            throw new EncoderException( "The PDU buffer size is too small !", boe );
+src/main/java/org/apache/directory/api/ldap/codec/decorators/SearchRequestDecorator.java:                            throw new IllegalArgumentException( "Unexpected filter type: " + filterType );
+src/main/java/org/apache/directory/api/ldap/codec/osgi/DefaultLdapCodecService.java:            throw new NullPointerException( "Control argument was null." );
+src/main/java/org/apache/directory/api/ldap/codec/osgi/DefaultLdapCodecService.java:        throw new NotImplementedException( "Figure out how to transform" );
+src/main/java/org/apache/directory/api/ldap/codec/osgi/DefaultLdapCodecService.java:        throw new NotImplementedException( "Figure out how to transform" );
+src/main/java/org/apache/directory/api/ldap/codec/osgi/DefaultLdapCodecService.java:                    NamingException ne = new NamingException( "Unable to decode encoded response value: "
+src/main/java/org/apache/directory/api/ldap/codec/search/AttributeValueAssertionFilter.java:                    throw new IllegalArgumentException( "Unexpected filter type: " + filterType );
+LOGS : 
+
+---------------------------------------------------
+
+src/main/java/org/apache/directory/api/ldap/codec/actions/CheckLengthNotNull.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/controls/AddControl.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/controls/AddControl.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/controls/AddControl.java:            LOG.debug( I18n.msg( I18n.MSG_08201_CONTROL_OID, oidValue ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/controls/InitControls.java:                LOG.debug( "A new list of controls has been initialized" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/controls/InitControls.java:                LOG.debug( "An empty list of controls has been initialized" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/controls/StoreControlCriticality.java:            LOG.error( I18n
+src/main/java/org/apache/directory/api/ldap/codec/actions/controls/StoreControlCriticality.java:            LOG.debug( I18n.msg( I18n.MSG_08202_CONTROL_CRITICALITY, control.isCritical() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/controls/StoreControlValue.java:            LOG.debug( I18n.msg( I18n.MSG_08203_CONTROL_VALUE, Strings.dumpBytes( control.getValue() ) ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapMessage/InitLdapMessage.java:            LOG.error( I18n.err( I18n.ERR_04066 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapMessage/StoreMessageId.java:            LOG.error( I18n.err( I18n.ERR_04068 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapMessage/StoreMessageId.java:                LOG.debug( "Ldap Message Id has been decoded : " + messageId );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapMessage/StoreMessageId.java:            LOG.error( I18n.err( I18n.ERR_04070, Strings.dumpBytes( value.getData() ), ide
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/AddReferral.java:                    LOG.error( I18n.err( I18n.ERR_04015, badUrl, luee.getMessage() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/AddReferral.java:                    LOG.warn( "The Referral error message is not allowed when havind an error code no equals to REFERRAL" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/AddReferral.java:                LOG.debug( "The referral error message is set to " + sb.toString() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/InitReferrals.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/InitReferrals.java:            LOG.debug( "Initialising a referrals list" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/StoreErrorMessage.java:            LOG.debug( "The error message is : " + errorMessage );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/StoreMatchedDN.java:                        LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/StoreMatchedDN.java:                    if ( LOG.isWarnEnabled() )
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/StoreMatchedDN.java:                        LOG.warn( "The matched Dn should not be set when the result code is not one of NoSuchObject,"
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/StoreMatchedDN.java:            LOG.debug( "The matchedDn is " + matchedDn );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/StoreResultCode.java:            LOG.error( I18n.err( I18n.ERR_04018, Strings.dumpBytes( value.getData() ), ide.getMessage() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/StoreResultCode.java:            LOG.debug( "The result code is set to " + resultCode );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/abandon/InitAbandonRequest.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/abandon/InitAbandonRequest.java:                LOG.debug( "AbandonMessage Id has been decoded : {}", Integer.valueOf( abandonnedMessageId ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/abandon/InitAbandonRequest.java:            LOG.error( I18n
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/AddAddRequestAttributeType.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/AddAddRequestAttributeType.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/AddAddRequestAttributeType.java:            LOG.debug( "Adding type {}", type );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/AddAttributeValue.java:                        LOG.debug( "Adding value {}", Strings.dumpBytes( ( byte[] ) value ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/AddAttributeValue.java:                        LOG.debug( "Adding value {}" + value );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/InitAddRequest.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/StoreAddRequestEntryName.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/StoreAddRequestEntryName.java:                LOG.error( "{} : {}", msg, ine.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/StoreAddRequestEntryName.java:            LOG.debug( "Adding an entry with Dn : {}", addRequest.getEntry() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/InitBindRequest.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/InitSaslBind.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/InitSaslBind.java:            LOG.debug( "The SaslCredential has been created" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/StoreName.java:            LOG.debug( " The Bind name is {}", bindRequestMessage.getName() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/StoreSaslCredentials.java:            LOG.debug( "The credentials are : {}", Strings.dumpBytes( bindRequestMessage
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/StoreSaslMechanism.java:            LOG.debug( "The mechanism is : {}", bindRequestMessage.getSaslMechanism() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/StoreSimpleAuth.java:            LOG.debug( "The simple authentication is : {}", Strings.dumpBytes( bindRequestMessage
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/StoreVersion.java:                LOG.debug( "Ldap version ", Integer.valueOf( version ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/StoreVersion.java:            LOG.error( I18n
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/compare/InitCompareRequest.java:            LOG.debug( "Compare Request" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/compare/StoreCompareRequestAssertionValue.java:                    LOG.debug( "Comparing attribute value {}", Strings.dumpBytes( compareRequest
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/compare/StoreCompareRequestAssertionValue.java:                    LOG.debug( "Comparing attribute value {}", compareRequest.getAssertionValue() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/compare/StoreCompareRequestAttributeDesc.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/compare/StoreCompareRequestAttributeDesc.java:            LOG.debug( "Comparing attribute description {}", compareRequest.getAttributeId() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/compare/StoreCompareRequestEntryName.java:                LOG.error( "{} : {}", msg, ine.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/compare/StoreCompareRequestEntryName.java:            LOG.debug( "Comparing Dn {}", entry );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/del/InitDelRequest.java:                LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/del/InitDelRequest.java:            LOG.debug( "Deleting Dn {}", entry );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/extended/InitExtendedRequest.java:            LOG.debug( "Extended request being processed ..." );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/extended/StoreExtendedRequestName.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/extended/StoreExtendedRequestName.java:                    LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/extended/StoreExtendedRequestName.java:                LOG.error( "{} : {}", msg, de.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/extended/StoreExtendedRequestName.java:            LOG.debug( "OID read : {}", req.getRequestName() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/extended/StoreExtendedRequestValue.java:            LOG.debug( "Extended value : {}", extendedRequest.getRequestValue() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/AddModifyRequestAttribute.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/AddModifyRequestAttribute.java:            LOG.debug( "Modifying type : {}", type );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/InitAttributeVals.java:            LOG.debug( "No vals for this attribute" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/InitAttributeVals.java:            LOG.debug( "Some vals are to be decoded" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/StoreModifyRequestAttributeValue.java:            LOG.debug( "Value modified : {}", value );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/StoreModifyRequestObjectName.java:                LOG.error( "{} : {}", msg, ine.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/StoreModifyRequestObjectName.java:            LOG.debug( "Modification of Dn {}", modifyRequest.getName() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/StoreOperationType.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/StoreOperationType.java:                    LOG.debug( "Modification operation : ADD" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/StoreOperationType.java:                    LOG.debug( "Modification operation : DELETE" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/StoreOperationType.java:                    LOG.debug( "Modification operation : REPLACE" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/StoreOperationType.java:                    LOG.debug( "Modification operation : UNKNOWN" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/InitModifyDnRequest.java:            LOG.debug( "ModifyDn request" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestDeleteOldRdn.java:            LOG.error( I18n
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestDeleteOldRdn.java:                LOG.debug( " Old Rdn attributes will be deleted" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestDeleteOldRdn.java:                LOG.debug( " Old Rdn attributes will be retained" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestEntryName.java:                LOG.error( "{} : {}", msg, ine.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestEntryName.java:            LOG.debug( "Modifying Dn {}", entry );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewRdn.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewRdn.java:                LOG.error( "{} : {}", msg, ine.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewRdn.java:            LOG.debug( "Modifying with new Rdn {}", newRdn );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewSuperior.java:                if ( LOG.isWarnEnabled() )
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewSuperior.java:                    LOG.warn( "The new superior is null, so we will change the entry" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewSuperior.java:                LOG.error( "{} : {}", msg, ine.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewSuperior.java:            LOG.debug( "New superior Dn {}", newSuperior );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitAndFilter.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitAndFilter.java:            LOG.debug( "Initialize AND filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitApproxMatchFilter.java:            LOG.debug( "Initialize Approx Match filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitAssertionValueFilter.java:            LOG.debug( "Initialize Assertion Value filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitAttributeDescFilter.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitAttributeDescFilter.java:            LOG.debug( "Initialize AttributeDesc filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitEqualityMatchFilter.java:            LOG.debug( "Initialize Equality Match filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitExtensibleMatchFilter.java:            LOG.debug( "Initialize Extensible Match filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitGreaterOrEqualFilter.java:            LOG.debug( "Initialize Greater Or Equal filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitLessOrEqualFilter.java:            LOG.debug( "Initialize Less Or Equal filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitNotFilter.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitNotFilter.java:            LOG.debug( "Initialize NOT filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitOrFilter.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitOrFilter.java:            LOG.debug( "Initialize OR filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitPresentFilter.java:            LOG.debug( "Initialize Present filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitSubstringsFilter.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitSubstringsFilter.java:            LOG.debug( "Initialize Substrings filter" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreAny.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreAny.java:            LOG.debug( "Stored a any substring : {}", any );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreFinal.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreFinal.java:            LOG.debug( "Stored a any substring : {}", finalValue );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreInitial.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreMatchingRuleDnAttributes.java:            LOG.error( I18n
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreMatchingRuleDnAttributes.java:            LOG.debug( "Dn Attributes : {}", Boolean.valueOf( extensibleMatchFilter.isDnAttributes() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreMatchValue.java:            LOG.debug( "Stored a match value : {}", value );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreSubstringFilterType.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/InitSearchRequest.java:            LOG.debug( "Search Request" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/InitSearchRequestAttributeDescList.java:            LOG.debug( "Initialize AttributeDesc list" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestAttributeDesc.java:            LOG.debug( "Decoded Attribute Description : {}", attributeDescription );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestBaseObject.java:                LOG.error( "{} : {}", msg, ine.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestBaseObject.java:            LOG.debug( "Searching with root Dn : {}", baseObject );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestDerefAlias.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestDerefAlias.java:                    LOG.debug( "Handling object strategy : NEVER_DEREF_ALIASES" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestDerefAlias.java:                    LOG.debug( "Handling object strategy : DEREF_IN_SEARCHING" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestDerefAlias.java:                    LOG.debug( "Handling object strategy : DEREF_FINDING_BASE_OBJ" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestDerefAlias.java:                    LOG.debug( "Handling object strategy : DEREF_ALWAYS" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestDerefAlias.java:                    LOG.debug( "Handling object strategy : UNKNOWN" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestScope.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestScope.java:                    LOG.debug( "Searching within BASE_OBJECT scope " );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestScope.java:                    LOG.debug( "Searching within SINGLE_LEVEL scope " );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestScope.java:                    LOG.debug( "Searching within WHOLE_SUBTREE scope " );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestScope.java:                    LOG.debug( "Searching within UNKNOWN scope " );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestSizeLimit.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestSizeLimit.java:            LOG.debug( "The sizeLimit value is set to {} objects", Long.valueOf( sizeLimit ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestTimeLimit.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestTimeLimit.java:            LOG.debug( "The timeLimit value is set to {} seconds", Integer.valueOf( timeLimit ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestTypesOnly.java:            LOG.error( I18n
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestTypesOnly.java:            LOG.debug( "The search will return {}", searchRequest.getTypesOnly() ? "only attributs type"
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreTypeMatchingRule.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreTypeMatchingRule.java:                LOG.debug( "Stored a type matching rule : {}", type );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/unbind/InitUnbindRequest.java:            LOG.error( I18n.err( I18n.ERR_04071, Integer.valueOf( expectedLength ) ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/add/InitAddResponse.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/add/InitAddResponse.java:            LOG.debug( "Add Response" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/bind/StoreServerSASLCreds.java:            LOG.debug( "The SASL credentials value is : {}", Strings.dumpBytes( serverSaslCreds ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/compare/InitCompareResponse.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/compare/InitCompareResponse.java:            LOG.debug( "Compare response " );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/del/InitDelResponse.java:            LOG.debug( "Del response " );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/extended/InitExtendedResponse.java:            LOG.debug( "Extended Response" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/extended/StoreExtendedResponseName.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/extended/StoreExtendedResponseName.java:            LOG.debug( "OID read : {}", extendedResponse.getResponseName() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/extended/StoreExtendedResponseValue.java:            LOG.debug( "Extended value : {}", extendedResponse.getResponseValue() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/intermediate/InitIntermediateResponse.java:            LOG.debug( "Intermediate Response" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/intermediate/StoreIntermediateResponseName.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/intermediate/StoreIntermediateResponseName.java:                LOG.error( "{} : {}", msg, oidStr );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/intermediate/StoreIntermediateResponseName.java:            LOG.debug( "OID read : {}", intermediateResponse.getResponseName() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/intermediate/StoreIntermediateResponseValue.java:            LOG.debug( "Value read : {}", Strings.dumpBytes( intermediateResponse.getResponseValue() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/modify/InitModifyResponse.java:            LOG.debug( "Modify response" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/modifydn/InitModifyDnResponse.java:            LOG.debug( "Modify Dn response " );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/done/InitSearchResultDone.java:            LOG.debug( "Search Result Done found" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/AddAttributeType.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/AddAttributeType.java:                LOG.error( "{} : {}", msg, ine.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/AddAttributeType.java:            LOG.debug( "Attribute type : {}", type );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/StoreSearchResultAttributeValue.java:                    LOG.debug( "The attribute value is null" );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/StoreSearchResultAttributeValue.java:                        LOG.debug( "Attribute value {}", Strings.dumpBytes( ( byte[] ) value ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/StoreSearchResultAttributeValue.java:                        LOG.debug( "Attribute value {}", value );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/StoreSearchResultEntryObjectName.java:                LOG.error( "{} : {}", msg, ine.getMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/StoreSearchResultEntryObjectName.java:            LOG.debug( "Search Result Entry Dn found : {}", searchResultEntry.getObjectName() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/reference/InitSearchResultReference.java:            LOG.debug( "SearchResultReference response " );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/reference/StoreReference.java:                LOG.error( I18n.err( I18n.ERR_04021, urlStr, luee.getMessage() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/reference/StoreReference.java:            LOG.debug( "Search reference URL found : {}", url );
+src/main/java/org/apache/directory/api/ldap/codec/api/LdapApiServiceFactory.java:            LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/api/LdapApiServiceFactory.java:            LOG.error( sb.toString() );
+src/main/java/org/apache/directory/api/ldap/codec/api/LdapApiServiceFactory.java:                LOG.error( "Failed to instantiate a viable instance, instantiating new instance of ", e );
+src/main/java/org/apache/directory/api/ldap/codec/api/LdapDecoder.java:            LOG.error( message );
+src/main/java/org/apache/directory/api/ldap/codec/api/LdapDecoder.java:                LOG.debug( "Decoded LdapMessage : " + container );
+src/main/java/org/apache/directory/api/ldap/codec/api/LdapDecoder.java:            LOG.error( I18n.err( I18n.ERR_04062 ) );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                                        LOG.debug( "changeType = " + changeType );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                                    LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                            LOG.error( msg, ide );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                            LOG.error( I18n.err( I18n.ERR_04045 ) );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                                LOG.error( I18n.err( I18n.ERR_04047, Strings.dumpBytes( value.getData() ) ) );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                                LOG.debug( "previousDN = " + previousDn );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                        LOG.debug( "changeNumber = " + changeNumber );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                    LOG.error( msg, lde );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/pagedSearch/PagedResultsGrammar.java:                                LOG.debug( "size = " + size );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/pagedSearch/PagedResultsGrammar.java:                            LOG.error( msg, ide );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/persistentSearch/PersistentSearchGrammar.java:                                LOG.debug( "changeTypes = " + changeTypes );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/persistentSearch/PersistentSearchGrammar.java:                            LOG.error( msg, ide );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/persistentSearch/PersistentSearchGrammar.java:                                LOG.debug( "changesOnly = " + changesOnly );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/persistentSearch/PersistentSearchGrammar.java:                            LOG.error( msg, bde );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/persistentSearch/PersistentSearchGrammar.java:                                LOG.debug( "returnECs = " + returnECs );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/persistentSearch/PersistentSearchGrammar.java:                            LOG.error( msg, bde );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/subentries/SubentriesGrammar.java:                            LOG.error( I18n.err( I18n.ERR_04054, Strings.dumpBytes( value.getData() ), bde.getMessage() ) );
+src/main/java/org/apache/directory/api/ldap/codec/controls/sort/SortRequestGrammar.java:                    LOG.debug( "AttributeTypeDesc = " + atDesc );
+src/main/java/org/apache/directory/api/ldap/codec/controls/sort/SortRequestGrammar.java:                        LOG.debug( "ReverseOrder = " + reverseOrder );
+src/main/java/org/apache/directory/api/ldap/codec/controls/sort/SortRequestGrammar.java:                    //LOG.error( msg, e );
+src/main/java/org/apache/directory/api/ldap/codec/controls/sort/SortRequestGrammar.java:                            LOG.debug( "MatchingRuleOid = " + matchingRuleOid );
+src/main/java/org/apache/directory/api/ldap/codec/controls/sort/SortResponseGrammar.java:                            LOG.debug( "AttributeType = " + atType );
+src/main/java/org/apache/directory/api/ldap/codec/LdapMessageGrammar.java:                        LOG.error( msg );
+src/main/java/org/apache/directory/api/ldap/codec/osgi/DefaultLdapCodecService.java:            LOG.info( I18n.msg( I18n.MSG_06000_REGISTERED_CONTROL_FACTORY, cascadeFactory.getOid() ) );
+src/main/java/org/apache/directory/api/ldap/codec/osgi/DefaultLdapCodecService.java:            LOG.info( I18n.msg( I18n.MSG_06000_REGISTERED_CONTROL_FACTORY, entryChangeFactory.getOid() ) );
+src/main/java/org/apache/directory/api/ldap/codec/osgi/DefaultLdapCodecService.java:            LOG.info( I18n.msg( I18n.MSG_06000_REGISTERED_CONTROL_FACTORY, manageDsaItFactory.getOid() ) );
+src/main/java/org/apache/directory/api/ldap/codec/osgi/DefaultLdapCodecService.java:            LOG.info( I18n.msg( I18n.MSG_06000_REGISTERED_CONTROL_FACTORY, proxiedAuthzFactory.getOid() ) );
+src/main/java/org/apache/directory/api/ldap/codec/osgi/DefaultLdapCodecService.java:            LOG.info( I18n.msg( I18n.MSG_06000_REGISTERED_CONTROL_FACTORY, pageResultsFactory.getOid() ) );
+src/main/java/org/apache/directory/api/ldap/codec/osgi/DefaultLdapCodecService.java:            LOG.info( I18n.msg( I18n.MSG_06000_REGISTERED_CONTROL_FACTORY, persistentSearchFactory.getOid() ) );
+src/main/java/org/apache/directory/api/ldap/codec/osgi/DefaultLdapCodecService.java:            LOG.info( I18n.msg( I18n.MSG_06000_REGISTERED_CONTROL_FACTORY, subentriesFactory.getOid() ) );
+src/main/java/org/apache/directory/api/ldap/codec/osgi/DefaultLdapCodecService.java:            LOG.info( I18n.msg( I18n.MSG_06000_REGISTERED_CONTROL_FACTORY, sortRequestFactory.getOid() ) );
+src/main/java/org/apache/directory/api/ldap/codec/osgi/DefaultLdapCodecService.java:            LOG.info( I18n.msg( I18n.MSG_06000_REGISTERED_CONTROL_FACTORY, sortResponseFactory.getOid() ) );
+I18n.err : 
+
+---------------------------------------------------
+
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapMessage/InitLdapMessage.java:            LOG.error( I18n.err( I18n.ERR_04066 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapMessage/InitLdapMessage.java:            throw new DecoderException( I18n.err( I18n.ERR_04067 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapMessage/StoreMessageId.java:            LOG.error( I18n.err( I18n.ERR_04068 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapMessage/StoreMessageId.java:            throw new DecoderException( I18n.err( I18n.ERR_04069 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapMessage/StoreMessageId.java:            LOG.error( I18n.err( I18n.ERR_04070, Strings.dumpBytes( value.getData() ), ide
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/AddReferral.java:                    LOG.error( I18n.err( I18n.ERR_04015, badUrl, luee.getMessage() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/AddReferral.java:                    throw new DecoderException( I18n.err( I18n.ERR_04016, luee.getMessage() ), luee );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/InitReferrals.java:            String msg = I18n.err( I18n.ERR_04011 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/StoreMatchedDN.java:                        String msg = I18n.err( I18n.ERR_04013, dnStr, Strings.dumpBytes( dnBytes ), ine
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/StoreMatchedDN.java:                        throw new DecoderException( I18n.err( I18n.ERR_04014, ine.getLocalizedMessage() ), ine );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/StoreResultCode.java:            LOG.error( I18n.err( I18n.ERR_04018, Strings.dumpBytes( value.getData() ), ide.getMessage() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/abandon/InitAbandonRequest.java:            String msg = I18n.err( I18n.ERR_04075 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/AddAddRequestAttributeType.java:            String msg = I18n.err( I18n.ERR_04086 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/AddAddRequestAttributeType.java:            String msg = I18n.err( I18n.ERR_04087 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/InitAddRequest.java:            String msg = I18n.err( I18n.ERR_04084 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/StoreAddRequestEntryName.java:            String msg = I18n.err( I18n.ERR_04085 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/InitBindRequest.java:            String msg = I18n.err( I18n.ERR_04077 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/InitSaslBind.java:            String msg = I18n.err( I18n.ERR_04079 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/compare/StoreCompareRequestAttributeDesc.java:            String msg = I18n.err( I18n.ERR_04093 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/compare/StoreCompareRequestEntryName.java:            throw new DecoderException( I18n.err( I18n.ERR_04089 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/del/InitDelRequest.java:            throw new DecoderException( I18n.err( I18n.ERR_04073 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/del/InitDelRequest.java:                String msg = I18n.err( I18n.ERR_04074, dnStr, Strings.dumpBytes( dnBytes ), ine
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/extended/StoreExtendedRequestName.java:            String msg = I18n.err( I18n.ERR_04095 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/AddModifyRequestAttribute.java:            String msg = I18n.err( I18n.ERR_04083 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/StoreOperationType.java:            String msg = I18n.err( I18n.ERR_04082, Strings.dumpBytes( tlv.getValue().getData() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestEntryName.java:            throw new DecoderException( I18n.err( I18n.ERR_04089 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewRdn.java:            String msg = I18n.err( I18n.ERR_04090 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewSuperior.java:                throw new DecoderException( I18n.err( I18n.ERR_04092 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitAndFilter.java:            String msg = I18n.err( I18n.ERR_04006 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitAttributeDescFilter.java:            String msg = I18n.err( I18n.ERR_04007 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitNotFilter.java:            String msg = I18n.err( I18n.ERR_04009 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitOrFilter.java:            String msg = I18n.err( I18n.ERR_04010 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitSubstringsFilter.java:            String msg = I18n.err( I18n.ERR_04012 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreAny.java:            String msg = I18n.err( I18n.ERR_04019 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreFinal.java:            String msg = I18n.err( I18n.ERR_04020 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreInitial.java:            String msg = I18n.err( I18n.ERR_04108 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreSubstringFilterType.java:            String msg = I18n.err( I18n.ERR_04106 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestDerefAlias.java:            String msg = I18n.err( I18n.ERR_04102, value.toString() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestScope.java:            String msg = I18n.err( I18n.ERR_04101, value.toString() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestSizeLimit.java:            String msg = I18n.err( I18n.ERR_04103, value.toString() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestTimeLimit.java:            String msg = I18n.err( I18n.ERR_04104, value.toString() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreTypeMatchingRule.java:            String msg = I18n.err( I18n.ERR_04022 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/unbind/InitUnbindRequest.java:            LOG.error( I18n.err( I18n.ERR_04071, Integer.valueOf( expectedLength ) ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/unbind/InitUnbindRequest.java:            throw new DecoderException( I18n.err( I18n.ERR_04072 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/add/InitAddResponse.java:            String msg = I18n.err( I18n.ERR_04088 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/compare/InitCompareResponse.java:            String msg = I18n.err( I18n.ERR_04094 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/extended/StoreExtendedResponseName.java:            String msg = I18n.err( I18n.ERR_04017 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/intermediate/StoreIntermediateResponseName.java:            String msg = I18n.err( I18n.ERR_04095 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/AddAttributeType.java:            String msg = I18n.err( I18n.ERR_04081 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/reference/StoreReference.java:                LOG.error( I18n.err( I18n.ERR_04021, urlStr, luee.getMessage() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/reference/StoreReference.java:                throw new DecoderException( I18n.err( I18n.ERR_04016, luee.getMessage() ), luee );
+src/main/java/org/apache/directory/api/ldap/codec/api/LdapDecoder.java:            String message = I18n.err( I18n.ERR_04060, e.getLocalizedMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/api/LdapDecoder.java:            LOG.error( I18n.err( I18n.ERR_04062 ) );
+src/main/java/org/apache/directory/api/ldap/codec/api/LdapDecoder.java:            throw new DecoderException( I18n.err( I18n.ERR_04063 ) );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                                    String msg = I18n.err( I18n.ERR_04044 );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                            String msg = I18n.err( I18n.ERR_04044 );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                            LOG.error( I18n.err( I18n.ERR_04045 ) );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                            throw new DecoderException( I18n.err( I18n.ERR_04046 ) );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                                LOG.error( I18n.err( I18n.ERR_04047, Strings.dumpBytes( value.getData() ) ) );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                                throw new DecoderException( I18n.err( I18n.ERR_04048 ), ine );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                    String msg = I18n.err( I18n.ERR_04049 );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/pagedSearch/PagedResultsGrammar.java:                            String msg = I18n.err( I18n.ERR_04050 );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/persistentSearch/PersistentSearchGrammar.java:                            String msg = I18n.err( I18n.ERR_04051 );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/persistentSearch/PersistentSearchGrammar.java:                            String msg = I18n.err( I18n.ERR_04052 );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/persistentSearch/PersistentSearchGrammar.java:                            String msg = I18n.err( I18n.ERR_04053 );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/subentries/SubentriesGrammar.java:                            LOG.error( I18n.err( I18n.ERR_04054, Strings.dumpBytes( value.getData() ), bde.getMessage() ) );
+src/main/java/org/apache/directory/api/ldap/codec/controls/sort/SortRequestGrammar.java:                    //String msg = I18n.err( I18n.ERR_04050 );
+src/main/java/org/apache/directory/api/ldap/codec/decorators/AddRequestDecorator.java:            throw new IllegalArgumentException( I18n.err( I18n.ERR_04481_ENTRY_NULL_VALUE ) );
+src/main/java/org/apache/directory/api/ldap/codec/decorators/ExtendedRequestDecorator.java:                throw new EncoderException( I18n.err( I18n.ERR_04043 ) );
+src/main/java/org/apache/directory/api/ldap/codec/LdapMessageGrammar.java:                        String msg = I18n.err( I18n.ERR_04109 );
+src/main/java/org/apache/directory/api/ldap/codec/LdapMessageGrammar.java:                        throw new DecoderException( I18n.err( I18n.ERR_04109 ) );
+src/main/java/org/apache/directory/api/ldap/codec/search/ExtensibleMatchFilter.java:                throw new EncoderException( I18n.err( I18n.ERR_04056 ) );
+src/main/java/org/apache/directory/api/ldap/codec/search/NotFilter.java:            throw new DecoderException( I18n.err( I18n.ERR_04057 ) );
+src/main/java/org/apache/directory/api/ldap/codec/search/NotFilter.java:            throw new DecoderException( I18n.err( I18n.ERR_04057 ) );
+src/main/java/org/apache/directory/api/ldap/codec/search/SubstringFilter.java:                throw new EncoderException( I18n.err( I18n.ERR_04058 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapMessage/InitLdapMessage.java:            LOG.error( I18n.err( I18n.ERR_04066 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapMessage/InitLdapMessage.java:            throw new DecoderException( I18n.err( I18n.ERR_04067 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapMessage/StoreMessageId.java:            LOG.error( I18n.err( I18n.ERR_04068 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapMessage/StoreMessageId.java:            throw new DecoderException( I18n.err( I18n.ERR_04069 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapMessage/StoreMessageId.java:            LOG.error( I18n.err( I18n.ERR_04070, Strings.dumpBytes( value.getData() ), ide
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/AddReferral.java:                    LOG.error( I18n.err( I18n.ERR_04015, badUrl, luee.getMessage() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/AddReferral.java:                    throw new DecoderException( I18n.err( I18n.ERR_04016, luee.getMessage() ), luee );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/InitReferrals.java:            String msg = I18n.err( I18n.ERR_04011 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/StoreMatchedDN.java:                        String msg = I18n.err( I18n.ERR_04013, dnStr, Strings.dumpBytes( dnBytes ), ine
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/StoreMatchedDN.java:                        throw new DecoderException( I18n.err( I18n.ERR_04014, ine.getLocalizedMessage() ), ine );
+src/main/java/org/apache/directory/api/ldap/codec/actions/ldapResult/StoreResultCode.java:            LOG.error( I18n.err( I18n.ERR_04018, Strings.dumpBytes( value.getData() ), ide.getMessage() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/abandon/InitAbandonRequest.java:            String msg = I18n.err( I18n.ERR_04075 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/abandon/InitAbandonRequest.java:                .err( I18n.ERR_04076, Strings.dumpBytes( value.getData() ), ide.getMessage() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/AddAddRequestAttributeType.java:            String msg = I18n.err( I18n.ERR_04086 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/AddAddRequestAttributeType.java:            String msg = I18n.err( I18n.ERR_04087 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/InitAddRequest.java:            String msg = I18n.err( I18n.ERR_04084 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/add/StoreAddRequestEntryName.java:            String msg = I18n.err( I18n.ERR_04085 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/InitBindRequest.java:            String msg = I18n.err( I18n.ERR_04077 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/InitSaslBind.java:            String msg = I18n.err( I18n.ERR_04079 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/bind/StoreVersion.java:                .err( I18n.ERR_04078, Strings.dumpBytes( value.getData() ), ide.getMessage() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/compare/StoreCompareRequestAttributeDesc.java:            String msg = I18n.err( I18n.ERR_04093 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/compare/StoreCompareRequestEntryName.java:            throw new DecoderException( I18n.err( I18n.ERR_04089 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/del/InitDelRequest.java:            throw new DecoderException( I18n.err( I18n.ERR_04073 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/del/InitDelRequest.java:                String msg = I18n.err( I18n.ERR_04074, dnStr, Strings.dumpBytes( dnBytes ), ine
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/extended/StoreExtendedRequestName.java:            String msg = I18n.err( I18n.ERR_04095 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/AddModifyRequestAttribute.java:            String msg = I18n.err( I18n.ERR_04083 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modify/StoreOperationType.java:            String msg = I18n.err( I18n.ERR_04082, Strings.dumpBytes( tlv.getValue().getData() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestDeleteOldRdn.java:                .err( I18n.ERR_04091, Strings.dumpBytes( value.getData() ), bde.getMessage() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestEntryName.java:            throw new DecoderException( I18n.err( I18n.ERR_04089 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewRdn.java:            String msg = I18n.err( I18n.ERR_04090 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/modifydn/StoreModifyDnRequestNewSuperior.java:                throw new DecoderException( I18n.err( I18n.ERR_04092 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitAndFilter.java:            String msg = I18n.err( I18n.ERR_04006 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitAttributeDescFilter.java:            String msg = I18n.err( I18n.ERR_04007 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitNotFilter.java:            String msg = I18n.err( I18n.ERR_04009 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitOrFilter.java:            String msg = I18n.err( I18n.ERR_04010 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/InitSubstringsFilter.java:            String msg = I18n.err( I18n.ERR_04012 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreAny.java:            String msg = I18n.err( I18n.ERR_04019 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreFinal.java:            String msg = I18n.err( I18n.ERR_04020 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreInitial.java:            String msg = I18n.err( I18n.ERR_04108 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreMatchingRuleDnAttributes.java:                .err( I18n.ERR_13014_DN_ATTR_FLAG_INVALID, Strings.dumpBytes( value.getData() ), bde.getMessage() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/filter/StoreSubstringFilterType.java:            String msg = I18n.err( I18n.ERR_04106 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestDerefAlias.java:            String msg = I18n.err( I18n.ERR_04102, value.toString() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestScope.java:            String msg = I18n.err( I18n.ERR_04101, value.toString() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestSizeLimit.java:            String msg = I18n.err( I18n.ERR_04103, value.toString() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestTimeLimit.java:            String msg = I18n.err( I18n.ERR_04104, value.toString() );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreSearchRequestTypesOnly.java:                .err( I18n.ERR_04105, Strings.dumpBytes( value.getData() ), bde.getMessage() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/search/StoreTypeMatchingRule.java:            String msg = I18n.err( I18n.ERR_04022 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/unbind/InitUnbindRequest.java:            LOG.error( I18n.err( I18n.ERR_04071, Integer.valueOf( expectedLength ) ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/request/unbind/InitUnbindRequest.java:            throw new DecoderException( I18n.err( I18n.ERR_04072 ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/add/InitAddResponse.java:            String msg = I18n.err( I18n.ERR_04088 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/compare/InitCompareResponse.java:            String msg = I18n.err( I18n.ERR_04094 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/extended/StoreExtendedResponseName.java:            String msg = I18n.err( I18n.ERR_04017 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/intermediate/StoreIntermediateResponseName.java:            String msg = I18n.err( I18n.ERR_04095 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/entry/AddAttributeType.java:            String msg = I18n.err( I18n.ERR_04081 );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/reference/StoreReference.java:                LOG.error( I18n.err( I18n.ERR_04021, urlStr, luee.getMessage() ) );
+src/main/java/org/apache/directory/api/ldap/codec/actions/response/search/reference/StoreReference.java:                throw new DecoderException( I18n.err( I18n.ERR_04016, luee.getMessage() ), luee );
+src/main/java/org/apache/directory/api/ldap/codec/api/LdapDecoder.java:            String message = I18n.err( I18n.ERR_04060, e.getLocalizedMessage() );
+src/main/java/org/apache/directory/api/ldap/codec/api/LdapDecoder.java:            LOG.error( I18n.err( I18n.ERR_04062 ) );
+src/main/java/org/apache/directory/api/ldap/codec/api/LdapDecoder.java:            throw new DecoderException( I18n.err( I18n.ERR_04063 ) );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                                    String msg = I18n.err( I18n.ERR_04044 );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                            String msg = I18n.err( I18n.ERR_04044 );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                            LOG.error( I18n.err( I18n.ERR_04045 ) );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                            throw new DecoderException( I18n.err( I18n.ERR_04046 ) );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                                LOG.error( I18n.err( I18n.ERR_04047, Strings.dumpBytes( value.getData() ) ) );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                                throw new DecoderException( I18n.err( I18n.ERR_04048 ), ine );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/entryChange/EntryChangeGrammar.java:                    String msg = I18n.err( I18n.ERR_04049 );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/pagedSearch/PagedResultsGrammar.java:                            String msg = I18n.err( I18n.ERR_04050 );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/persistentSearch/PersistentSearchGrammar.java:                            String msg = I18n.err( I18n.ERR_04051 );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/persistentSearch/PersistentSearchGrammar.java:                            String msg = I18n.err( I18n.ERR_04052 );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/persistentSearch/PersistentSearchGrammar.java:                            String msg = I18n.err( I18n.ERR_04053 );
+src/main/java/org/apache/directory/api/ldap/codec/controls/search/subentries/SubentriesGrammar.java:                            LOG.error( I18n.err( I18n.ERR_04054, Strings.dumpBytes( value.getData() ), bde.getMessage() ) );
+src/main/java/org/apache/directory/api/ldap/codec/controls/sort/SortRequestGrammar.java:                    //String msg = I18n.err( I18n.ERR_04050 );
+src/main/java/org/apache/directory/api/ldap/codec/decorators/AddRequestDecorator.java:            throw new IllegalArgumentException( I18n.err( I18n.ERR_04481_ENTRY_NULL_VALUE ) );
+src/main/java/org/apache/directory/api/ldap/codec/decorators/ExtendedRequestDecorator.java:                throw new EncoderException( I18n.err( I18n.ERR_04043 ) );
+src/main/java/org/apache/directory/api/ldap/codec/LdapMessageGrammar.java:                        String msg = I18n.err( I18n.ERR_04109 );
+src/main/java/org/apache/directory/api/ldap/codec/LdapMessageGrammar.java:                        throw new DecoderException( I18n.err( I18n.ERR_04109 ) );
+src/main/java/org/apache/directory/api/ldap/codec/search/ExtensibleMatchFilter.java:                throw new EncoderException( I18n.err( I18n.ERR_04056 ) );
+src/main/java/org/apache/directory/api/ldap/codec/search/NotFilter.java:            throw new DecoderException( I18n.err( I18n.ERR_04057 ) );
+src/main/java/org/apache/directory/api/ldap/codec/search/NotFilter.java:            throw new DecoderException( I18n.err( I18n.ERR_04057 ) );
+src/main/java/org/apache/directory/api/ldap/codec/search/SubstringFilter.java:                throw new EncoderException( I18n.err( I18n.ERR_04058 ) );
diff --git a/ldap/model/src/checkstyle/suppressions.xml b/ldap/model/src/checkstyle/suppressions.xml
index a638848..75dd160 100644
--- a/ldap/model/src/checkstyle/suppressions.xml
+++ b/ldap/model/src/checkstyle/suppressions.xml
@@ -55,7 +55,7 @@
     <suppress files="org.apache.directory.api.ldap.model.entry.DefaultAttribute" checks="FileLength" />
     <suppress files="org.apache.directory.api.ldap.model.entry.DefaultEntry" checks="FileLength" />
     <suppress files="org.apache.directory.api.ldap.model.ldif.LdifReader" checks="FileLength" />
-    <suppress files="org.apache.directory.api.ldap.model.schema.parsers.FastOpenLdapSchemaParser" checks="FileLength" />
+    <suppress files="org.apache.directory.api.ldap.model.schema.parsers.OpenLdapSchemaParser" checks="FileLength" />
 
     <!-- Setter return super type, which is not recognized by Checkstyle -->
     <suppress files="org.apache.directory.api.ldap.model.message" checks="HiddenField" />
diff --git a/ldap/model/src/main/antlr/distinguishedName.g b/ldap/model/src/main/antlr/distinguishedName.g
index 9d1d432..2d243e1 100644
--- a/ldap/model/src/main/antlr/distinguishedName.g
+++ b/ldap/model/src/main/antlr/distinguishedName.g
@@ -29,7 +29,6 @@ import java.util.Map;
 import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
 import javax.naming.NameParser;
 import org.apache.directory.api.ldap.model.entry.Value;
-import org.apache.directory.api.ldap.model.schema.parsers.ParserMonitor;
 import org.apache.directory.api.ldap.model.schema.SchemaManager;
 import org.apache.directory.api.ldap.model.schema.AttributeType;
 import org.apache.directory.api.util.ExpansibleByteBuffer;
@@ -137,19 +136,8 @@ options    {
 }
 
 {
-    private ParserMonitor monitor = null;
-    
-    public void setParserMonitor( ParserMonitor monitor )
-    {
-        this.monitor = monitor;
-    }
-    
     private void matchedProduction( String msg )
     {
-        if ( null != monitor )
-        {
-            monitor.matchedProduction( msg );
-        }
     }
 
     /**
diff --git a/ldap/model/src/main/antlr/schema-extension.g b/ldap/model/src/main/antlr/schema-extension.g
deleted file mode 100644
index b6eb96b..0000000
--- a/ldap/model/src/main/antlr/schema-extension.g
+++ /dev/null
@@ -1,119 +0,0 @@
-header {
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.api.ldap.model.schema.syntaxes;
-
-import java.io.StringReader;
-import java.util.List;
-
-}
-
-
-   
-/**
- * An antlr generated schema lexer. This is a sub-lexer.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-class AntlrSchemaExtensionLexer extends Lexer;
-
-options    {
-    k = 2 ;
-    exportVocab=AntlrSchemaExtension ;
-    charVocabulary = '\u0000'..'\uFFFE'; 
-    caseSensitive = false ;
-    defaultErrorHandler = false ;
-}
-
-protected WHSP
-    :
-    ( options {greedy=true;} :
-    ' '
-    |
-    '\t'
-    |
-    '\r' (options {greedy=true;} : '\n')? { newline(); } 
-    |
-    '\n' { newline(); }
-    )+
-    { $setType(Token.SKIP); } //ignore this token
-    ;
-
-protected QUOTE : '\'' ;
-//protected ESC : '\\' ;
-
-XKEY : xstring:XSTRING { setText(xstring.getText().trim()); }; 
-XVALUES : values:VALUES { setText(values.getText().trim()); };
-
-protected XSTRING : ( "x-" ( 'a'..'z' | '-' | '_' )+ (WHSP)? ) ; 
-protected VALUES : ( VALUE | '('  VALUE ( ('$')? VALUE )* ')' ) ;
-protected VALUE : (WHSP)? ( QUOTED_STRING ) (options {greedy=true;}: WHSP)? ;
-protected QUOTED_STRING : ( QUOTE (~'\'')* QUOTE ) ;
-
-
-
-
-
-
-/**
- * An antlr generated schema parser. This is a sub-parser used to parse
- * extensions according to RFC4512.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-class AntlrSchemaExtensionParser extends Parser;
-options    {
-    k = 3 ;
-    defaultErrorHandler = false ;
-    //buildAST=true ;
-}
-
-
-    /**
-     * extensions = *( SP xstring SP qdstrings )
-     * xstring = "X" HYPHEN 1*( ALPHA / HYPHEN / USCORE )
-     */
-extension returns [AntlrSchemaParser.Extension extension = new AntlrSchemaParser.Extension()]
-    :
-    ( xkey:XKEY { extension.key = xkey.getText(); } )
-    ( xvalues:XVALUES { extension.values = qdstrings(xvalues.getText()); } )
-    ;
-    
-    
-qdstrings [String s] returns [List<String> qdstrings]
-    {
-        try 
-        {
-            AntlrSchemaQdstringLexer lexer = new AntlrSchemaQdstringLexer(new StringReader(s));
-            AntlrSchemaQdstringParser parser = new AntlrSchemaQdstringParser(lexer);
-            qdstrings = parser.qdstrings();
-        }
-        catch (RecognitionException re) {
-            re.printStackTrace();
-            throw re;
-        }
-        catch (TokenStreamException tse) {
-            tse.printStackTrace();
-            throw tse;
-        }
-    }
-    :
-    ;
-
diff --git a/ldap/model/src/main/antlr/schema-qdstring.g b/ldap/model/src/main/antlr/schema-qdstring.g
deleted file mode 100644
index 03d8f83..0000000
--- a/ldap/model/src/main/antlr/schema-qdstring.g
+++ /dev/null
@@ -1,162 +0,0 @@
-header {
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.api.ldap.model.schema.syntaxes;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.directory.api.ldap.model.schema.parsers.ParserMonitor;
-
-}
-
-   
-/**
- * An antlr generated schema lexer. This is a sub-lexer.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-class AntlrSchemaQdstringLexer extends Lexer;
-
-options    {
-    k = 2 ;
-    exportVocab=AntlrSchemaQdstring ;
-    charVocabulary = '\u0000'..'\uFFFE'; 
-    caseSensitive = false ;
-    defaultErrorHandler = false ;
-}
-
-WHSP
-    :
-    ( options {greedy=true;} :
-    ' '
-    |
-    '\t'
-    |
-    '\r' (options {greedy=true;} : '\n')? { newline(); } 
-    |
-    '\n' { newline(); }
-    )+
-    { $setType(Token.SKIP); } //ignore this token
-    ;
-
-LPAR : '(' ;
-RPAR : ')' ;
-QUOTE : '\'' ;
-QDSTRING : ( QUOTE (~'\'')* QUOTE ) ;
-
-
-/**
- * An antlr generated schema parser. This is a sub-parser used to parse
- * qdstring and qdstrings according to RFC4512.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-class AntlrSchemaQdstringParser extends Parser;
-options    {
-    k = 3 ;
-    defaultErrorHandler = false ;
-    //buildAST=true ;
-}
-
-{
-    private ParserMonitor monitor = null;
-    public void setParserMonitor( ParserMonitor monitor )
-    {
-        this.monitor = monitor;
-    }
-    private void matchedProduction( String msg )
-    {
-        if ( null != monitor )
-        {
-            monitor.matchedProduction( msg );
-        }
-    }
-}
-
-    /**
-     * qdstrings = qdstring / ( LPAREN WSP qdstringlist WSP RPAREN )
-     * qdstringlist = [ qdstring *( SP qdstring ) ]
-     */
-qdstrings returns [List<String> qdstrings]
-    {
-        matchedProduction( "AntlrSchemaQdstringParser.qdstrings()" );
-        qdstrings = new ArrayList<String>();
-        String qdstring = null;
-    }
-    :
-    (
-        ( 
-            q:QDSTRING 
-            { 
-                qdstring = q.getText(); 
-                if(qdstring.startsWith("'")) {
-                    qdstring = qdstring.substring(1, qdstring.length());
-                }
-                if(qdstring.endsWith("'")) {
-                    qdstring = qdstring.substring(0, qdstring.length()-1);
-                }
-                qdstring = qdstring.replaceAll("\\\\5C", "\\\\");
-                qdstring = qdstring.replaceAll("\\\\5c", "\\\\");
-                qdstring = qdstring.replaceAll("\\\\27", "'");
-                qdstrings.add(qdstring);
-            } 
-        )
-    |
-        ( LPAR qdstring=qdstring { qdstrings.add(qdstring); } ( qdstring=qdstring { qdstrings.add(qdstring); } )* RPAR )
-    )
-    ;
-
-    /**
-     * qdstring = SQUOTE dstring SQUOTE
-     * dstring = 1*( QS / QQ / QUTF8 )   ; escaped UTF-8 string
-     *
-     * QQ =  ESC %x32 %x37 ; "\27"
-     * QS =  ESC %x35 ( %x43 / %x63 ) ; "\5C" / "\5c"
-     *
-     * ; Any UTF-8 encoded Unicode character
-     * ; except %x27 ("\'") and %x5C ("\")
-     * QUTF8    = QUTF1 / UTFMB
-     *
-     * ; Any ASCII character except %x27 ("\'") and %x5C ("\")
-     * QUTF1    = %x00-26 / %x28-5B / %x5D-7F
-     */    
-qdstring returns [String qdstring=null]
-    {
-        matchedProduction( "AntlrSchemaQdstringParser.qdstring()" );
-    }
-    : 
-    ( 
-        q:QDSTRING 
-        { 
-            qdstring = q.getText(); 
-            if(qdstring.startsWith("'")) {
-                qdstring = qdstring.substring(1, qdstring.length());
-            }
-            if(qdstring.endsWith("'")) {
-                qdstring = qdstring.substring(0, qdstring.length()-1);
-            }
-            qdstring = qdstring.replaceAll("\\\\5C", "\\\\");
-            qdstring = qdstring.replaceAll("\\\\5c", "\\\\");
-            qdstring = qdstring.replaceAll("\\\\27", "'");
-        } 
-    )
-    ; 
-
diff --git a/ldap/model/src/main/antlr/schema-value.g b/ldap/model/src/main/antlr/schema-value.g
deleted file mode 100644
index 02992b6..0000000
--- a/ldap/model/src/main/antlr/schema-value.g
+++ /dev/null
@@ -1,442 +0,0 @@
-header {
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.api.ldap.model.schema.syntaxes;
-
-import java.util.List;
-import java.util.ArrayList;
-
-import org.apache.directory.api.ldap.model.schema.parsers.ParserMonitor;
-
-}
-
-
-/**
- * An antlr generated schema lexer. This is a sub-lexer.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-class AntlrSchemaValueLexer extends Lexer;
-
-options    {
-    k = 3 ;
-    exportVocab=AntlrSchemaValue ;
-    charVocabulary = '\3'..'\377' ;
-    caseSensitive = false ;
-    defaultErrorHandler = false ;
-}
-
-WHSP
-    :
-    ( options {greedy=true;} :
-    ' '
-    |
-    '\t'
-    |
-    '\r' (options {greedy=true;} : '\n')? { newline(); } 
-    |
-    '\n' { newline(); }
-    |
-    '#' (~'\n')* '\n' { newline(); }
-    )+
-    { setText(" "); }
-    //{$setType(Token.SKIP);} //ignore this token
-    ;
-
-LPAR : '(' ;
-RPAR : ')' ;
-protected CHAR : 'a'..'z' ;
-protected LDIGIT : '1'..'9' ;
-protected DIGIT : '0'..'9' ; 
-protected NUMBER : DIGIT | ( LDIGIT (DIGIT)+ ) ;
-protected NUMBER2 : (DIGIT)+ ;
-protected NUMERICOID : NUMBER2 ( '.' NUMBER2 )+ ;
-protected HYPEN : '-';
-protected OTHER : '_' | ';' | '.' | ':' | '#' ;
-protected DESCR: CHAR ( CHAR | DIGIT | HYPEN )* ;
-protected QUIRKS_DESCR: ( CHAR | DIGIT | HYPEN | OTHER )+ ;
-
-QUOTE : '\'' ;
-DOLLAR : '$' ;
-LCURLY : '{' ;
-RCURLY : '}' ;
-LEN : LCURLY n:NUMBER2 RCURLY { setText(n.getText()); } ;
-
-
-DESCR_OR_QUIRKS_DESCR :
-    ( NUMERICOID QUIRKS_DESCR ) => QUIRKS_DESCR { $setType( QUIRKS_DESCR ); }
-    |
-    ( NUMBER QUIRKS_DESCR ) => QUIRKS_DESCR { $setType( QUIRKS_DESCR ); }
-    |
-    ( HYPEN QUIRKS_DESCR ) => QUIRKS_DESCR { $setType( QUIRKS_DESCR ); }
-    |
-    ( OTHER QUIRKS_DESCR ) => QUIRKS_DESCR { $setType( QUIRKS_DESCR ); }
-    |
-    ( DESCR QUIRKS_DESCR ) => QUIRKS_DESCR { $setType( QUIRKS_DESCR ); }
-    |
-    ( DESCR ) { $setType( DESCR ); }
-    |
-    ( NUMBER '.' ) => NUMERICOID { $setType( NUMERICOID ); }
-    |
-    ( NUMBER ) { $setType( NUMBER ); }
-    ;
-
-
-/**
- * An antlr generated schema parser. This is a sub-parser used to parse
- * numericoid, oid, oids, qdescr, qdescrs according to RFC4512.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-class AntlrSchemaValueParser extends Parser;
-options    {
-    k = 3 ;
-    defaultErrorHandler = false ;
-    //buildAST=true ;
-}
-
-{
-    private ParserMonitor monitor = null;
-    public void setParserMonitor( ParserMonitor monitor )
-    {
-        this.monitor = monitor;
-    }
-    private void matchedProduction( String msg )
-    {
-        if ( null != monitor )
-        {
-            monitor.matchedProduction( msg );
-        }
-    }
-}
-
-    /**
-     * noidlen = numericoid [ LCURLY len RCURLY ]
-     * len = number
-     */
-noidlen returns [AntlrSchemaParser.NoidLen noidlen = new AntlrSchemaParser.NoidLen()]
-    {
-        matchedProduction( "AntlrSchemaValueParser.noidlen()" );
-    }
-    :
-    ( 
-        (LPAR)?
-        (WHSP)?
-        (QUOTE)?
-        (
-            ( d4:DESCR { noidlen.noid = d4.getText(); } )
-            |
-            ( n2:NUMERICOID { noidlen.noid = n2.getText(); } )
-        )
-        (QUOTE)?
-        (WHSP)?
-        (RPAR)?
-        (
-            l:LEN { noidlen.len = Long.parseLong(l.getText()); }
-            (QUOTE)?
-            (WHSP)?
-            (RPAR)?
-        )?
-    )
-    ;
-
-
-    /**
-     * noidlen = numericoid [ LCURLY len RCURLY ]
-     * len = number
-     */
-quirksNoidlen returns [AntlrSchemaParser.NoidLen noidlen = new AntlrSchemaParser.NoidLen()]
-    {
-        matchedProduction( "AntlrSchemaValueParser.quirksNoidlen()" );
-    }
-    :
-    (
-        (LPAR)?
-        (WHSP)?
-        (QUOTE)?
-        (
-            ( q2:QUIRKS_DESCR { noidlen.noid = q2.getText(); } )
-            |
-            ( d4:DESCR { noidlen.noid = d4.getText(); } )
-            |
-            ( n2:NUMERICOID { noidlen.noid = n2.getText(); } )
-        )
-        (QUOTE)?
-        (WHSP)?
-        (RPAR)?
-        (
-            l:LEN { noidlen.len = Long.parseLong(l.getText()); }
-            (QUOTE)?
-            (WHSP)?
-            (RPAR)?
-        )?    
-    )
-    ;
-
-
-    /**
-     * numericoid = number 1*( DOT number )
-     */
-numericoid returns [String numericoid=null]
-    {
-        matchedProduction( "AntlrSchemaValueParser.numericoid()" );
-    }
-    : 
-    (
-        (WHSP)?
-        (LPAR (WHSP)? )?
-        (
-            ( QUOTE n1:NUMERICOID { numericoid = n1.getText(); } QUOTE )
-            |
-            ( n2:NUMERICOID { numericoid = n2.getText(); } )
-        )
-        (
-        (WHSP)?
-        (RPAR)?
-        )
-    )
-    ;
-
-
-    /**
-     * oid = descr / numericoid
-     * numericoid = number 1*( DOT number )
-     * descr = keystring
-     * keystring = leadkeychar *keychar
-     * leadkeychar = ALPHA
-     * keychar = ALPHA / DIGIT / HYPHEN
-     * number  = DIGIT / ( LDIGIT 1*DIGIT )
-     *
-     */
-oid returns [String oid=null]
-    {
-        matchedProduction( "AntlrSchemaValueParser.oid()" );
-    }
-    : 
-    (
-        (WHSP)?
-        (
-            ( QUOTE n1:NUMERICOID { oid = n1.getText(); } QUOTE  )
-            |
-            ( n2:NUMERICOID { oid = n2.getText(); } )
-            |
-            ( QUOTE d1:DESCR { oid = d1.getText(); } QUOTE )
-            |
-            ( d2:DESCR { oid = d2.getText(); } )
-        )
-        (options {greedy=true;} : WHSP)?
-    )
-    ;
-
-
-    /**
-     * oids = oid / ( LPAREN WSP oidlist WSP RPAREN )
-     * oidlist = oid *( WSP DOLLAR WSP oid )
-     */
-oids returns [List<String> oids]
-    {
-        matchedProduction( "AntlrSchemaValueParser.oids()" );
-        oids = new ArrayList<String>();
-        String oid = null;
-    }
-    :
-    (
-        ( 
-            oid=oid { oids.add(oid); } 
-        )
-    |
-        (
-            LPAR
-            oid=oid { oids.add(oid); } 
-            ( 
-                (DOLLAR)? 
-                oid=oid { oids.add(oid); } 
-            )* 
-            RPAR
-        )
-    )
-    ;
-
-
-    /**
-     * qdescr = SQUOTE descr SQUOTE
-     */
-qdescr returns [String qdescr=null]
-    {
-        matchedProduction( "AntlrSchemaValueParser.qdescr()" );
-    }
-    : 
-    ( 
-        (WHSP)?
-        (
-            ( QUOTE d1:DESCR { qdescr = d1.getText(); } QUOTE )
-            |
-            ( d2:DESCR { qdescr = d2.getText(); } )
-        )
-    )
-    ; 
-
-
-    /**
-     * qdescrs = qdescr / ( LPAREN WSP qdescrlist WSP RPAREN )
-     * qdescrlist = [ qdescr *( SP qdescr ) ]
-     */
-qdescrs returns [List<String> qdescrs]
-    {
-        matchedProduction( "AntlrSchemaValueParser.qdescrs()" );
-        qdescrs = new ArrayList<String>();
-        String qdescr = null;
-    }
-    :
-    (
-        ( 
-            qdescr=qdescr { qdescrs.add(qdescr); } 
-        )
-    |
-        (             
-        
-            LPAR 
-            qdescr=qdescr { qdescrs.add(qdescr); } 
-            (options {greedy=true;} : WHSP)?
-            (DOLLAR)?
-            (options {greedy=true;} : WHSP)?
-            (
-                qdescr=qdescr { qdescrs.add(qdescr); } 
-                (options {greedy=true;} : WHSP)?
-                (DOLLAR)?
-                (options {greedy=true;} : WHSP)?
-            )*
-            RPAR 
-        )
-    )
-    ;
-    
-    
-    
-    /**
-     * qdescr = SQUOTE descr SQUOTE
-     */
-quirksQdescr returns [String qdescr=null]
-    {
-        matchedProduction( "AntlrSchemaValueParser.qdescr()" );
-    }
-    : 
-    ( 
-        (WHSP)?
-        (
-            ( QUOTE d1:QUIRKS_DESCR { qdescr = d1.getText(); } QUOTE )
-            |
-            ( d2:QUIRKS_DESCR { qdescr = d2.getText(); } )
-            |
-            ( QUOTE d3:DESCR { qdescr = d3.getText(); } QUOTE )
-            |
-            ( d4:DESCR { qdescr = d4.getText(); } )
-            |
-            ( QUOTE n1:NUMERICOID { qdescr = n1.getText(); } QUOTE  )
-            |
-            ( n2:NUMERICOID { qdescr = n2.getText(); } )
-        )
-        (options {greedy=true;} : WHSP)?
-    )
-    ; 
-
-
-    /**
-     * qdescrs = qdescr / ( LPAREN WSP qdescrlist WSP RPAREN )
-     * qdescrlist = [ qdescr *( SP qdescr ) ]
-     */
-quirksQdescrs returns [List<String> qdescrs]
-    {
-        matchedProduction( "AntlrSchemaValueParser.qdescrs()" );
-        qdescrs = new ArrayList<String>();
-        String qdescr = null;
-    }
-    :
-    (
-        ( 
-            qdescr=quirksQdescr { qdescrs.add(qdescr); } 
-        )
-    |
-        ( 
-            LPAR 
-            qdescr=quirksQdescr { qdescrs.add(qdescr); } 
-            (options {greedy=true;} : WHSP)?
-            (DOLLAR)?
-            (options {greedy=true;} : WHSP)?
-            (
-                qdescr=quirksQdescr { qdescrs.add(qdescr); } 
-                (options {greedy=true;} : WHSP)?
-                (DOLLAR)?
-                (options {greedy=true;} : WHSP)?
-            )*
-            RPAR 
-        )
-    )
-    ;
-    
-    
-    
-    
-    /**
-     * ruleid = number
-     * number  = DIGIT / ( LDIGIT 1*DIGIT )
-     *
-     */
-ruleid returns [Integer ruleid=null]
-    {
-        matchedProduction( "AntlrSchemaValueParser.ruleid()" );
-    }
-    : 
-    (
-        (WHSP)? 
-        n:NUMBER { ruleid = Integer.parseInt(n.getText()); }
-    )
-    ;
-
-
-    /**
-     * ruleids = ruleid / ( LPAREN WSP ruleidlist WSP RPAREN )
-     * ruleidlist = ruleid *( SP ruleid )
-     */
-ruleids returns [List<Integer> ruleids]
-    {
-        matchedProduction( "AntlrSchemaValueParser.ruleids()" );
-        ruleids = new ArrayList<Integer>();
-        Integer ruleid = null;
-    }
-    :
-    (
-        ( 
-            ruleid=ruleid { ruleids.add(ruleid); } 
-        )
-    |
-        ( 
-            LPAR 
-            ruleid=ruleid { ruleids.add(ruleid); } 
-            ( 
-                WHSP
-                ruleid=ruleid { ruleids.add(ruleid); } 
-            )* 
-            (WHSP)?
-            RPAR 
-        )
-    )
-    ;
-    
\ No newline at end of file
diff --git a/ldap/model/src/main/antlr/schema.g b/ldap/model/src/main/antlr/schema.g
deleted file mode 100644
index 9aa790b..0000000
--- a/ldap/model/src/main/antlr/schema.g
+++ /dev/null
@@ -1,1085 +0,0 @@
-header {
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.api.ldap.model.schema.syntaxes;
-
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.directory.api.ldap.model.schema.parsers.LdapComparatorDescription;
-import org.apache.directory.api.ldap.model.schema.DitContentRule;
-import org.apache.directory.api.ldap.model.schema.DitStructureRule;
-import org.apache.directory.api.ldap.model.schema.LdapSyntax;
-import org.apache.directory.api.ldap.model.schema.MatchingRule;
-import org.apache.directory.api.ldap.model.schema.MutableMatchingRule;
-import org.apache.directory.api.ldap.model.schema.MatchingRuleUse;
-import org.apache.directory.api.ldap.model.schema.NameForm;
-import org.apache.directory.api.ldap.model.schema.parsers.NormalizerDescription;
-import org.apache.directory.api.ldap.model.schema.parsers.ParserMonitor;
-import org.apache.directory.api.ldap.model.schema.AttributeType;
-import org.apache.directory.api.ldap.model.schema.MutableAttributeType;
-import org.apache.directory.api.ldap.model.schema.ObjectClass;
-import org.apache.directory.api.ldap.model.schema.MutableObjectClass;
-import org.apache.directory.api.ldap.model.schema.parsers.SyntaxCheckerDescription;
-import org.apache.directory.api.ldap.model.schema.syntaxCheckers.OpenLdapObjectIdentifierMacro;
-import org.apache.directory.api.ldap.model.schema.ObjectClassTypeEnum;
-import org.apache.directory.api.ldap.model.schema.UsageEnum;
-
-}
-
-/**
- * An antlr generated schema main lexer.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-class AntlrSchemaLexer extends Lexer;
-
-options    {
-    k = 8 ;
-    exportVocab=AntlrSchema ;
-    charVocabulary = '\u0000'..'\uFFFE';
-    caseSensitive = false ;
-    defaultErrorHandler = false ;
-}
-
-WHSP
-    :
-    ( options {greedy=true;} :
-    ' '
-    |
-    '\t'
-    |
-    '\r' (options {greedy=true;} : '\n')? { newline(); } 
-    |
-    '\n' { newline(); }
-    |
-    '#' (~'\n')* '\n' { newline(); }
-    )+
-    {$setType(Token.SKIP);} //ignore this token
-    ;
-
-LPAR : '(' ;
-RPAR : ')' ;
-QUOTE : '\'' ;
-DOLLAR : '$' ;
-LBRACKET : '{' ;
-RBRACKET : '}' ;
-
-LEN : LBRACKET ('0'..'9')+ RBRACKET ;
-
-SINGLE_VALUE : ( "single-value" (WHSP)? ) ;
-COLLECTIVE : ( "collective" (WHSP)? ) ;
-NO_USER_MODIFICATION : ( "no-user-modification" (WHSP)? ) ;
-
-OBSOLETE : ( "obsolete" (WHSP)? ) ;
-ABSTRACT : ( "abstract" (WHSP)? ) ;
-STRUCTURAL : ( "structural" (WHSP)? ) ;
-protected AUXILIARY : ( "auxiliary" (WHSP)? ) ;
-
-OBJECTIDENTIFIER : 
-    ( "objectidentifier" 
-      WHSP
-      ( oiName:UNQUOTED_STRING ) 
-      WHSP
-      ( oiValue:UNQUOTED_STRING ) 
-    ) 
-    { setText( oiName.getText() + " " + oiValue.getText() ); }
-    ;
-
-OBJECTCLASS : ( "objectclass" (WHSP)? ) ;
-ATTRIBUTETYPE : ( "attributetype" (WHSP)? ) ;
-
-STARTNUMERICOID : ( LPAR (options {greedy=true;} : WHSP)? ( numericoid:VALUES ) ) { setText(numericoid.getText()); } ;
-NAME : ( "name" (options {greedy=true;} : WHSP)? qdstrings:VALUES ) { setText(qdstrings.getText().trim()); } ;
-DESC : ( "desc" (options {greedy=true;} : WHSP)? qdstring:VALUES ) { setText(qdstring.getText().trim()); } ;
-SUP : ( "sup" (options {greedy=true;} : WHSP)? sup:VALUES ) { setText(sup.getText().trim()); } ;
-MUST : ( "must" (options {greedy=true;} : WHSP)? must:VALUES ) { setText(must.getText().trim()); } ;
-MAY : ( "may" (options {greedy=true;} : WHSP)? may:VALUES ) { setText(may.getText()); } ;
-protected AUX : ( "aux" (options {greedy=true;} : WHSP)? aux:VALUES ) { setText(aux.getText()); } ;
-NOT : ( "not" (options {greedy=true;} : WHSP)? not:VALUES ) { setText(not.getText()); } ;
-FORM : ( "form" (options {greedy=true;} : WHSP)? form:VALUES ) { setText(form.getText()); } ;
-OC : ( "oc" (options {greedy=true;} : WHSP)? oc:VALUES ) { setText(oc.getText()); } ;
-EQUALITY : ( "equality" (options {greedy=true;} : WHSP)? equality:VALUES ) { setText(equality.getText().trim()); } ;
-ORDERING : ( "ordering" (options {greedy=true;} : WHSP)? ordering:VALUES ) { setText(ordering.getText().trim()); } ;
-SUBSTR : ( "substr" (options {greedy=true;} : WHSP)? substring:VALUES ) { setText(substring.getText().trim()); } ;
-SYNTAX : ( "syntax" (options {greedy=true;} : WHSP)? syntax:VALUES (len:LEN)? ) { setText(syntax.getText().trim() + (len!=null?len.getText().trim():"")); } ;
-APPLIES : ( "applies" (options {greedy=true;} : WHSP)? applies:VALUES ) { setText(applies.getText().trim()); } ;
-EXTENSION : x:( "x-" ( options {greedy=true;} : 'a'..'z' | '-' | '_' )+ (options {greedy=true;} : WHSP)? VALUES ) ; 
-FQCN : ( "fqcn" (options {greedy=true;} : WHSP)? fqcn:FQCN_VALUE ) { setText(fqcn.getText().trim()); } ;
-BYTECODE : ( "bytecode" (options {greedy=true;} : WHSP)? bytecode:BYTECODE_VALUE ) { setText(bytecode.getText().trim()); } ;
-
-AUX_OR_AUXILIARY :
-    ( AUXILIARY ) => AUXILIARY { $setType( AUXILIARY ); }
-    |
-    ( AUX ) { $setType( AUX ); }
-    ;
-
-protected VALUES : ( VALUE | LPAR  VALUE ( (DOLLAR)? VALUE )* RPAR ) ;
-protected VALUE : (WHSP)? ( QUOTED_STRING | UNQUOTED_STRING ) (options {greedy=true;}: WHSP)? ;
-protected UNQUOTED_STRING : (options{greedy=true;}: 'a'..'z' | '0'..'9' | '-' | '_' | ';' | '.' | ':' )+ ;
-protected QUOTED_STRING : ( QUOTE (~'\'')* QUOTE ) ;
-protected FQCN_VALUE : ( FQCN_IDENTIFIER ( '.' FQCN_IDENTIFIER )* ) ;
-protected FQCN_IDENTIFIER : ( FQCN_LETTER ( FQCN_LETTERORDIGIT )* ) ;
-protected FQCN_LETTER : 
-       '\u0024' |
-       '\u005f' |
-       '\u0061'..'\u007a' |
-       '\u00c0'..'\u00d6' |
-       '\u00d8'..'\u00f6' |
-       '\u00f8'..'\u00ff' |
-       '\u0100'..'\u1fff' |
-       '\u3040'..'\u318f' |
-       '\u3300'..'\u337f' |
-       '\u3400'..'\u3d2d' |
-       '\u4e00'..'\u9fff' |
-       '\uf900'..'\ufaff' ;
-protected FQCN_LETTERORDIGIT : 
-       '\u0024' |
-       '\u005f' |
-       '\u0061'..'\u007a' |
-       '\u00c0'..'\u00d6' |
-       '\u00d8'..'\u00f6' |
-       '\u00f8'..'\u00ff' |
-       '\u0100'..'\u1fff' |
-       '\u3040'..'\u318f' |
-       '\u3300'..'\u337f' |
-       '\u3400'..'\u3d2d' |
-       '\u4e00'..'\u9fff' |
-       '\uf900'..'\ufaff' |
-       '\u0030'..'\u0039' ;
-protected BYTECODE_VALUE : ( 'a'..'z' | '0'..'9' | '+' | '/' | '=' )+ ;
-
-
-USAGE : ( "usage" (WHSP)? ) ;
-USER_APPLICATIONS : ( "userapplications" (WHSP)? ) ;
-DIRECTORY_OPERATION : ( "directoryoperation" (WHSP)? ) ;
-DISTRIBUTED_OPERATION : ( "distributedoperation" (WHSP)? ) ;
-DSA_OPERATION : ( "dsaoperation" (WHSP)? ) ;
-
-/**
- * An antlr generated schema main parser.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-class AntlrSchemaParser extends Parser;
-options    {
-    k = 3 ;
-    defaultErrorHandler = false ;
-    //buildAST=true ;
-}
-
-{
-    private ParserMonitor monitor = null;
-    private boolean isQuirksModeEnabled = false;
-    public void setParserMonitor( ParserMonitor monitor )
-    {
-        this.monitor = monitor;
-    }
-    private void matchedProduction( String msg )
-    {
-        if ( null != monitor )
-        {
-            monitor.matchedProduction( msg );
-        }
-    }
-    public void setQuirksMode( boolean enabled )
-    {
-        this.isQuirksModeEnabled = enabled;
-    }
-    public boolean isQuirksMode()
-    {
-        return this.isQuirksModeEnabled;
-    }
-    static class Extension
-    {
-        String key = "";
-        List<String> values = new ArrayList<String>();
-        
-        public void addValue( String value )
-        {
-            this.values.add( value );
-        }
-    }
-    static class NoidLen
-    {
-        String noid = "";
-        long len = 0L;
-    }
-    static class ElementTracker
-    {
-        Map<String, Integer> elementMap = new HashMap<String, Integer>();
-        void track(String element, Token token) throws SemanticException 
-        {
-            if(elementMap.containsKey(element))
-            {
-                throw new SemanticException( element + " appears twice.", token.getFilename(), token.getLine() , token.getColumn() );
-            }
-            elementMap.put(element, Integer.valueOf(1));
-        }
-        boolean contains(String element) 
-        {
-            return elementMap.containsKey(element);
-        }
-    }
-
-}
-
-openLdapSchema returns [List<Object> list = new ArrayList<Object>()]
-    {
-        AttributeType attributeType = null;
-        ObjectClass objectClass = null;
-        OpenLdapObjectIdentifierMacro oloid = null;
-    }
-    :
-    (
-        oloid = openLdapObjectIdentifier { list.add( oloid ); }
-        |
-        attributeType = openLdapAttributeType { list.add( attributeType ); }
-        |
-        objectClass = openLdapObjectClass { list.add( objectClass ); }
-    )*
-    ;
-
-openLdapObjectIdentifier returns [OpenLdapObjectIdentifierMacro oloid]
-    {
-        matchedProduction( "openLdapObjectIdentifier()" );
-    }
-    :
-    (
-        oi:OBJECTIDENTIFIER 
-        {
-            String[] nameAndValue = oi.getText().split( " " );
-            oloid = new OpenLdapObjectIdentifierMacro();
-            oloid.setName( nameAndValue[0] );
-            oloid.setRawOidOrNameSuffix( nameAndValue[1] );
-        }
-    )
-    ;
-    
-
-openLdapObjectClass returns [ObjectClass objectClass]
-    {
-        matchedProduction( "openLdapObjectClass()" );
-    }
-    :
-    (
-        OBJECTCLASS
-        ( objectClass=objectClassDescription )
-    )
-    ;
-    
-    
-openLdapAttributeType returns [AttributeType attributeType]
-    {
-        matchedProduction( "openLdapAttributeType()" );
-    }
-    :
-    (
-        ATTRIBUTETYPE
-        ( attributeType=attributeTypeDescription )
-    )
-    ;
-
-
-    /**
-     * Production for matching object class descriptions. It is fault-tolerant
-     * against element ordering.
-     *
-     * <pre>
-     * ObjectClassDescription = LPAREN WSP
-     *     numericoid                 ; object identifier
-     *     [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
-     *     [ SP "DESC" SP qdstring ]  ; description
-     *     [ SP "OBSOLETE" ]          ; not active
-     *     [ SP "SUP" SP oids ]       ; superior object classes
-     *     [ SP kind ]                ; kind of class
-     *     [ SP "MUST" SP oids ]      ; attribute types
-     *     [ SP "MAY" SP oids ]       ; attribute types
-     *     extensions WSP RPAREN
-     *
-     * kind = "ABSTRACT" / "STRUCTURAL" / "AUXILIARY"
-     * 
-     * extensions = *( SP xstring SP qdstrings )
-     * xstring = "X" HYPHEN 1*( ALPHA / HYPHEN / USCORE ) 
-     * </pre>
-    */
-objectClassDescription returns [MutableObjectClass objectClass]
-    {
-        matchedProduction( "objectClassDescription()" );
-        ElementTracker et = new ElementTracker();
-    }
-    :
-    ( oid:STARTNUMERICOID { objectClass = new MutableObjectClass(numericoid(oid.getText())); } )
-    (
-        ( name:NAME { et.track("NAME", name); objectClass.setNames(qdescrs(name.getText())); } )
-        |
-        ( desc:DESC { et.track("DESC", desc); objectClass.setDescription(qdstring(desc.getText())); } )
-        |
-        ( obsolete:OBSOLETE { et.track("OBSOLETE", obsolete); objectClass.setObsolete( true ); } )
-        |
-        ( sup:SUP { et.track("SUP", sup); objectClass.setSuperiorOids(oids(sup.getText())); } )
-        |
-        ( kind1:ABSTRACT { et.track("KIND", kind1); objectClass.setType( ObjectClassTypeEnum.ABSTRACT ); }
-          |
-          kind2:STRUCTURAL { et.track("KIND", kind2); objectClass.setType( ObjectClassTypeEnum.STRUCTURAL ); }
-          |
-          kind3:AUXILIARY { et.track("KIND", kind3); objectClass.setType( ObjectClassTypeEnum.AUXILIARY ); } 
-        )
-        |
-        ( must:MUST { et.track("MUST", must); objectClass.setMustAttributeTypeOids(oids(must.getText())); } )
-        |
-        ( may:MAY { et.track("MAY", may); objectClass.setMayAttributeTypeOids(oids(may.getText())); } )
-        |
-        ( extension:EXTENSION { 
-            Extension ex = extension(extension.getText());
-            et.track(ex.key, extension); 
-            objectClass.addExtension(ex.key, ex.values); 
-         } )
-    )*    
-    RPAR
-    ;
-
-
-    /**
-     * Production for matching attribute type descriptions. It is fault-tolerant
-     * against element ordering.
-     *
-     * <pre>
-     * AttributeTypeDescription = LPAREN WSP
-     *     numericoid                    ; object identifier
-     *     [ SP "NAME" SP qdescrs ]      ; short names (descriptors)
-     *     [ SP "DESC" SP qdstring ]     ; description
-     *     [ SP "OBSOLETE" ]             ; not active
-     *     [ SP "SUP" SP oid ]           ; supertype
-     *     [ SP "EQUALITY" SP oid ]      ; equality matching rule
-     *     [ SP "ORDERING" SP oid ]      ; ordering matching rule
-     *     [ SP "SUBSTR" SP oid ]        ; substrings matching rule
-     *     [ SP "SYNTAX" SP noidlen ]    ; value syntax
-     *     [ SP "SINGLE-VALUE" ]         ; single-value
-     *     [ SP "COLLECTIVE" ]           ; collective
-     *     [ SP "NO-USER-MODIFICATION" ] ; not user modifiable
-     *     [ SP "USAGE" SP usage ]       ; usage
-     *     extensions WSP RPAREN         ; extensions
-     * 
-     * usage = "userApplications"     /  ; user
-     *         "directoryOperation"   /  ; directory operational
-     *         "distributedOperation" /  ; DSA-shared operational
-     *         "dSAOperation"            ; DSA-specific operational     
-     * 
-     * extensions = *( SP xstring SP qdstrings )
-     * xstring = "X" HYPHEN 1*( ALPHA / HYPHEN / USCORE ) 
-     * </pre>
-    */
-attributeTypeDescription returns [MutableAttributeType attributeType]
-    {
-        matchedProduction( "attributeTypeDescription()" );
-        ElementTracker et = new ElementTracker();
-    }
-    :
-    ( oid:STARTNUMERICOID { attributeType = new MutableAttributeType(numericoid(oid.getText())); } )
-    (
-        ( name:NAME { et.track("NAME", name); attributeType.setNames(qdescrs(name.getText())); } )
-        |
-        ( desc:DESC { et.track("DESC", desc); attributeType.setDescription(qdstring(desc.getText())); } )
-        |
-        ( obsolete:OBSOLETE { et.track("OBSOLETE", obsolete); attributeType.setObsolete( true ); } )
-        |
-        ( superior:SUP { et.track("SUP", superior); attributeType.setSuperiorOid(oid(superior.getText())); } )
-        |
-        ( equality:EQUALITY { et.track("EQUALITY", equality); attributeType.setEqualityOid(oid(equality.getText())); } )
-        |
-        ( ordering:ORDERING { et.track("ORDERING", ordering); attributeType.setOrderingOid(oid(ordering.getText())); } )
-        |
-        ( substring:SUBSTR { et.track("SUBSTR", substring); attributeType.setSubstringOid(oid(substring.getText())); } )
-        |
-        ( syntax:SYNTAX { 
-           et.track("SYNTAX", syntax); 
-            NoidLen noidlen = noidlen(syntax.getText());
-            attributeType.setSyntaxOid(noidlen.noid); 
-            attributeType.setSyntaxLength(noidlen.len);
-          } )
-        |
-        ( singleValued:SINGLE_VALUE { et.track("SINGLE_VALUE", singleValued); attributeType.setSingleValued( true ); } )
-        |
-        ( collective:COLLECTIVE { et.track("COLLECTIVE", collective); attributeType.setCollective( true ); } )
-        |
-        ( noUserModification:NO_USER_MODIFICATION { et.track("NO_USER_MODIFICATION", noUserModification); attributeType.setUserModifiable( false ); } )
-        |
-        ( usage1:USAGE (WHSP)* USER_APPLICATIONS { et.track("USAGE", usage1); attributeType.setUsage( UsageEnum.USER_APPLICATIONS ); }
-          |
-          usage2:USAGE DIRECTORY_OPERATION { et.track("USAGE", usage2); attributeType.setUsage( UsageEnum.DIRECTORY_OPERATION ); }
-          |
-          usage3:USAGE DISTRIBUTED_OPERATION { et.track("USAGE", usage3); attributeType.setUsage( UsageEnum.DISTRIBUTED_OPERATION ); } 
-          |
-          usage4:USAGE DSA_OPERATION { et.track("USAGE", usage4); attributeType.setUsage( UsageEnum.DSA_OPERATION ); } 
-        )
-        |
-        ( extension:EXTENSION { 
-            Extension ex = extension(extension.getText());
-            et.track(ex.key, extension); 
-            attributeType.addExtension(ex.key, ex.values); 
-         } )
-    )*    
-    RPAR
-    {
-        if( !isQuirksModeEnabled )
-        {
-            // semantic check: required elements
-            if( !et.contains("SYNTAX") && !et.contains("SUP") ) 
-            {
-                throw new SemanticException( "One of SYNTAX or SUP is required", null, 0, 0 );
-            }
-        
-            // COLLECTIVE requires USAGE userApplications
-            if ( attributeType.isCollective() && ( attributeType.getUsage() != UsageEnum.USER_APPLICATIONS ) )
-            {
-                throw new SemanticException( "COLLECTIVE requires USAGE userApplications", null, 0, 0 );
-            }
-        
-            // NO-USER-MODIFICATION requires an operational USAGE.
-            if ( !attributeType.isUserModifiable() && ( attributeType.getUsage() == UsageEnum.USER_APPLICATIONS ) )
-            {
-                throw new SemanticException( "NO-USER-MODIFICATION requires an operational USAGE", null, 0, 0 );
-            }
-        }
-    }
-    ;
-
-
-    /**
-     * Production for matching ldap syntax descriptions. It is fault-tolerant
-     * against element ordering.
-     *
-     * <pre>
-     * SyntaxDescription = LPAREN WSP
-     *    numericoid                 ; object identifier
-     *    [ SP "DESC" SP qdstring ]  ; description
-     *    extensions WSP RPAREN      ; extensions
-     * </pre>
-    */
-ldapSyntaxDescription returns [LdapSyntax ldapSyntax]
-    {
-        matchedProduction( "ldapSyntaxDescription()" );
-        ElementTracker et = new ElementTracker();
-    }
-    :
-    ( oid:STARTNUMERICOID { ldapSyntax = new LdapSyntax(numericoid(oid.getText())); } )
-    (
-        ( name:NAME { et.track("NAME", name); ldapSyntax.setNames(qdescrs(name.getText())); } )
-        |
-        ( desc:DESC { et.track("DESC", desc); ldapSyntax.setDescription(qdstring(desc.getText())); } )
-        |
-        ( extension:EXTENSION { 
-            Extension ex = extension(extension.getText());
-            et.track(ex.key, extension); 
-            ldapSyntax.addExtension(ex.key, ex.values); 
-         } )
-    )*
-    RPAR
-    ;
-
-
-
-    /**
-     * Production for matching rule descriptions. It is fault-tolerant
-     * against element ordering.
-     *
-     * <pre>
-     * MatchingRuleDescription = LPAREN WSP
-     *    numericoid                 ; object identifier
-     *    [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
-     *    [ SP "DESC" SP qdstring ]  ; description
-     *    [ SP "OBSOLETE" ]          ; not active
-     *    SP "SYNTAX" SP numericoid  ; assertion syntax
-     *    extensions WSP RPAREN      ; extensions
-     * </pre>
-    */
-matchingRuleDescription returns [MutableMatchingRule matchingRule]
-    {
-        matchedProduction( "matchingRuleDescription()" );
-        ElementTracker et = new ElementTracker();
-    }
-    :
-    ( oid:STARTNUMERICOID { matchingRule = new MutableMatchingRule(numericoid(oid.getText())); } )
-    (
-        ( name:NAME { et.track("NAME", name); matchingRule.setNames(qdescrs(name.getText())); } )
-        |
-        ( desc:DESC { et.track("DESC", desc); matchingRule.setDescription(qdstring(desc.getText())); } )
-        |
-        ( obsolete:OBSOLETE { et.track("OBSOLETE", obsolete); matchingRule.setObsolete( true ); } )
-        |
-        ( syntax:SYNTAX { et.track("SYNTAX", syntax); matchingRule.setSyntaxOid(numericoid(syntax.getText())); } )
-        |
-        ( extension:EXTENSION { 
-            Extension ex = extension(extension.getText());
-            et.track(ex.key, extension); 
-            matchingRule.addExtension(ex.key, ex.values); 
-         } )
-    )*
-    RPAR
-    {
-        if( !isQuirksModeEnabled )
-        {    
-            // semantic check: required elements
-            if( !et.contains("SYNTAX") ) {
-                throw new SemanticException( "SYNTAX is required", null, 0, 0 );
-            }
-        }
-    }
-    ;
-
-
-    /**
-     * Production for matching rule use descriptions. It is fault-tolerant
-     * against element ordering.
-     *
-     * <pre>
-     * MatchingRuleUseDescription = LPAREN WSP
-     *    numericoid                 ; object identifier
-     *    [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
-     *    [ SP "DESC" SP qdstring ]  ; description
-     *    [ SP "OBSOLETE" ]          ; not active
-     *    SP "APPLIES" SP oids       ; attribute types
-     *    extensions WSP RPAREN      ; extensions
-     * </pre>
-    */
-matchingRuleUseDescription returns [MatchingRuleUse matchingRuleUse]
-    {
-        matchedProduction( "matchingRuleUseDescription()" );
-        ElementTracker et = new ElementTracker();
-    }
-    :
-    ( oid:STARTNUMERICOID { matchingRuleUse = new MatchingRuleUse(numericoid(oid.getText())); } )
-    (
-        ( name:NAME { et.track("NAME", name); matchingRuleUse.setNames(qdescrs(name.getText())); } )
-        |
-        ( desc:DESC { et.track("DESC", desc); matchingRuleUse.setDescription(qdstring(desc.getText())); } )
-        |
-        ( obsolete:OBSOLETE { et.track("OBSOLETE", obsolete); matchingRuleUse.setObsolete( true ); } )
-        |
-        ( applies:APPLIES { et.track("APPLIES", applies); matchingRuleUse.setApplicableAttributeOids(oids(applies.getText())); } )
-        |
-        ( extension:EXTENSION { 
-            Extension ex = extension(extension.getText());
-            et.track(ex.key, extension); 
-            matchingRuleUse.addExtension(ex.key, ex.values); 
-         } )
-    )*
-    RPAR
-    {
-        if( !isQuirksModeEnabled )
-        {
-            // semantic check: required elements
-            if( !et.contains("APPLIES") ) {
-                throw new SemanticException( "APPLIES is required", null, 0, 0 );
-            }
-        }
-    }
-    ;
-
-
-    /**
-     * Production for DIT content rule descriptions. It is fault-tolerant
-     * against element ordering.
-     *
-     * <pre>
-     * DITContentRuleDescription = LPAREN WSP
-     *    numericoid                 ; object identifier
-     *    [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
-     *    [ SP "DESC" SP qdstring ]  ; description
-     *    [ SP "OBSOLETE" ]          ; not active
-     *    [ SP "AUX" SP oids ]       ; auxiliary object classes
-     *    [ SP "MUST" SP oids ]      ; attribute types
-     *    [ SP "MAY" SP oids ]       ; attribute types
-     *    [ SP "NOT" SP oids ]       ; attribute types
-     *    extensions WSP RPAREN      ; extensions
-     * </pre>
-    */
-ditContentRuleDescription returns [DitContentRule ditContentRule]
-    {
-        matchedProduction( "ditContentRuleDescription()" );
-        ElementTracker et = new ElementTracker();
-    }
-    :
-    ( oid:STARTNUMERICOID { ditContentRule = new DitContentRule(numericoid(oid.getText())); } )
-    (
-        ( name:NAME { et.track("NAME", name); ditContentRule.setNames(qdescrs(name.getText())); } )
-        |
-        ( desc:DESC { et.track("DESC", desc); ditContentRule.setDescription(qdstring(desc.getText())); } )
-        |
-        ( obsolete:OBSOLETE { et.track("OBSOLETE", obsolete); ditContentRule.setObsolete( true ); } )
-        |
-        ( aux:AUX { et.track("AUX", aux); ditContentRule.setAuxObjectClassOids(oids(aux.getText())); } )
-        |
-        ( must:MUST { et.track("MUST", must); ditContentRule.setMustAttributeTypeOids(oids(must.getText())); } )
-        |
-        ( may:MAY { et.track("MAY", may); ditContentRule.setMayAttributeTypeOids(oids(may.getText())); } )
-        |
-        ( not:NOT { et.track("NOT", not); ditContentRule.setNotAttributeTypeOids(oids(not.getText())); } )
-        |
-        ( extension:EXTENSION { 
-            Extension ex = extension(extension.getText());
-            et.track(ex.key, extension); 
-            ditContentRule.addExtension(ex.key, ex.values); 
-         } )
-    )*
-    RPAR
-    ;
-
-
-    /**
-     * Production for DIT structure rules descriptions. It is fault-tolerant
-     * against element ordering.
-     *
-     * <pre>
-     * DITStructureRuleDescription = LPAREN WSP
-     *   ruleid                     ; rule identifier
-     *   [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
-     *   [ SP "DESC" SP qdstring ]  ; description
-     *   [ SP "OBSOLETE" ]          ; not active
-     *   SP "FORM" SP oid           ; NameForm
-     *   [ SP "SUP" ruleids ]       ; superior rules
-     *   extensions WSP RPAREN      ; extensions
-     *
-     * ruleids = ruleid / ( LPAREN WSP ruleidlist WSP RPAREN )
-     * ruleidlist = ruleid *( SP ruleid )
-     * ruleid = number
-     * </pre>
-    */
-ditStructureRuleDescription returns [DitStructureRule ditStructureRule]
-    {
-        matchedProduction( "ditStructureRuleDescription()" );
-        ElementTracker et = new ElementTracker();
-    }
-    :
-    ( ruleid:STARTNUMERICOID { ditStructureRule = new DitStructureRule(ruleid(ruleid.getText())); } )
-    (
-        ( name:NAME { et.track("NAME", name); ditStructureRule.setNames(qdescrs(name.getText())); } )
-        |
-        ( desc:DESC { et.track("DESC", desc); ditStructureRule.setDescription(qdstring(desc.getText())); } )
-        |
-        ( obsolete:OBSOLETE { et.track("OBSOLETE", obsolete); ditStructureRule.setObsolete( true ); } )
-        |
-        ( form:FORM { et.track("FORM", form); ditStructureRule.setForm(oid(form.getText())); } )
-        |
-        ( sup:SUP { et.track("SUP", sup); ditStructureRule.setSuperRules(ruleids(sup.getText())); } )
-        |
-        ( extension:EXTENSION { 
-            Extension ex = extension(extension.getText());
-            et.track(ex.key, extension); 
-            ditStructureRule.addExtension(ex.key, ex.values); 
-         } )
-    )*
-    RPAR
-    {
-        if( !isQuirksModeEnabled )
-        {
-            // semantic check: required elements
-            if( !et.contains("FORM") ) {
-                throw new SemanticException( "FORM is required", null, 0, 0 );
-            }
-        }
-    }
-    ;
-
-
-    /**
-     * Production for name form descriptions. It is fault-tolerant
-     * against element ordering.
-     *
-     * <pre>
-     * NameFormDescription = LPAREN WSP
-     *    numericoid                 ; object identifier
-     *    [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
-     *    [ SP "DESC" SP qdstring ]  ; description
-     *    [ SP "OBSOLETE" ]          ; not active
-     *    SP "OC" SP oid             ; structural object class
-     *    SP "MUST" SP oids          ; attribute types
-     *    [ SP "MAY" SP oids ]       ; attribute types
-     *    extensions WSP RPAREN      ; extensions
-     * </pre>
-    */
-nameFormDescription returns [NameForm nameForm]
-    {
-        matchedProduction( "nameFormDescription()" );
-        ElementTracker et = new ElementTracker();
-    }
-    :
-    ( oid:STARTNUMERICOID { nameForm = new NameForm(numericoid(oid.getText())); } )
-    (
-        ( name:NAME { et.track("NAME", name); nameForm.setNames(qdescrs(name.getText())); } )
-        |
-        ( desc:DESC { et.track("DESC", desc); nameForm.setDescription(qdstring(desc.getText())); } )
-        |
-        ( obsolete:OBSOLETE { et.track("OBSOLETE", obsolete); nameForm.setObsolete( true ); } )
-        |
-        ( oc:OC { et.track("OC", oc); nameForm.setStructuralObjectClassOid(oid(oc.getText())); } )
-        |
-        ( must:MUST { et.track("MUST", must); nameForm.setMustAttributeTypeOids(oids(must.getText())); } )
-        |
-        ( may:MAY { et.track("MAY", may); nameForm.setMayAttributeTypeOids(oids(may.getText())); } )
-        |
-        ( extension:EXTENSION { 
-            Extension ex = extension(extension.getText());
-            et.track(ex.key, extension); 
-            nameForm.addExtension(ex.key, ex.values); 
-         } )
-    )*
-    RPAR
-    {
-        if( !isQuirksModeEnabled )
-        {
-            // semantic check: required elements
-            if( !et.contains("MUST") ) {
-                throw new SemanticException( "MUST is required", null, 0, 0 );
-            }
-            if( !et.contains("OC") ) {
-                throw new SemanticException( "OC is required", null, 0, 0 );
-            }
-        
-            // semantic check: MUST and MAY must be disjoint
-            //List<String> aList = new ArrayList<String>( nfd.getMustAttributeTypes() );
-            //aList.retainAll( nfd.getMayAttributeTypes() );
-            //if( !aList.isEmpty() ) 
-            //{
-            //    throw new SemanticException( "MUST and MAY must be disjoint, "+aList.get( 0 )+" appears in both", null, 0, 0 );
-            //}
-        }
-    }
-    ;
-    
-
-    /**
-     * Production for comparator descriptions. It is fault-tolerant
-     * against element ordering.
-     *
-     * <pre>
-     * LdapComparator = LPAREN WSP
-     *       numericoid                           ; object identifier
-     *       [ SP "DESC" SP qdstring ]            ; description
-     *       SP "FQCN" SP fqcn                    ; fully qualified class name
-     *       [ SP "BYTECODE" SP base64 ]          ; optional base64 encoded bytecode
-     *       extensions WSP RPAREN                ; extensions
-     * 
-     * base64          = *(4base64-char)
-     * base64-char     = ALPHA / DIGIT / "+" / "/"
-     * fqcn = fqcnComponent 1*( DOT fqcnComponent )
-     * fqcnComponent = ???
-     * </pre>
-    */
-ldapComparator returns [LdapComparatorDescription lcd]
-    {
-        matchedProduction( "ldapComparator()" );
-        ElementTracker et = new ElementTracker();
-    }
-    :
-    ( oid:STARTNUMERICOID { lcd = new LdapComparatorDescription(numericoid(oid.getText())); } )
-    (
-        ( desc:DESC { et.track("DESC", desc); lcd.setDescription(qdstring(desc.getText())); } )
-        |
-        ( fqcn:FQCN { et.track("FQCN", fqcn); lcd.setFqcn(fqcn.getText()); } )
-        |
-        ( bytecode:BYTECODE { et.track("BYTECODE", bytecode); lcd.setBytecode(bytecode.getText()); } )
-        |
-        ( extension:EXTENSION { 
-            Extension ex = extension(extension.getText());
-            et.track(ex.key, extension); 
-            lcd.addExtension(ex.key, ex.values); 
-         } )
-    )*
-    RPAR
-    {
-        if( !isQuirksModeEnabled )
-        {
-            // semantic check: required elements
-            if( !et.contains("FQCN") ) {
-                throw new SemanticException( "FQCN is required", null, 0, 0 );
-            }
-        
-            // semantic check: length should be divisible by 4
-            if( ( lcd.getBytecode() != null ) && ( lcd.getBytecode().length() % 4 != 0 ) ) {
-                throw new SemanticException( "BYTECODE must be divisible by 4", null, 0, 0 );
-            }
-        }
-    }
-    ;
-    
-
-    /**
-     * Production for normalizer descriptions. It is fault-tolerant
-     * against element ordering.
-     *
-     * <pre>
-     * NormalizerDescription = LPAREN WSP
-     *       numericoid                           ; object identifier
-     *       [ SP "DESC" SP qdstring ]            ; description
-     *       SP "FQCN" SP fqcn                    ; fully qualified class name
-     *       [ SP "BYTECODE" SP base64 ]          ; optional base64 encoded bytecode
-     *       extensions WSP RPAREN                ; extensions
-     * 
-     * base64          = *(4base64-char)
-     * base64-char     = ALPHA / DIGIT / "+" / "/"
-     * fqcn = fqcnComponent 1*( DOT fqcnComponent )
-     * fqcnComponent = ???
-     * </pre>
-    */
-normalizerDescription returns [NormalizerDescription nd]
-    {
-        matchedProduction( "normalizerDescription()" );
-        ElementTracker et = new ElementTracker();
-    }
-    :
-    ( oid:STARTNUMERICOID { nd = new NormalizerDescription(numericoid(oid.getText())); } )
-    (
-        ( desc:DESC { et.track("DESC", desc); nd.setDescription(qdstring(desc.getText())); } )
-        |
-        ( fqcn:FQCN { et.track("FQCN", fqcn); nd.setFqcn(fqcn.getText()); } )
-        |
-        ( bytecode:BYTECODE { et.track("BYTECODE", bytecode); nd.setBytecode(bytecode.getText()); } )
-        |
-        ( extension:EXTENSION { 
-            Extension ex = extension(extension.getText());
-            et.track(ex.key, extension); 
-            nd.addExtension(ex.key, ex.values); 
-         } )
-    )*
-    RPAR
-    {
-        if( !isQuirksModeEnabled )
-        {
-            // semantic check: required elements
-            if( !et.contains("FQCN") ) {
-                throw new SemanticException( "FQCN is required", null, 0, 0 );
-            }
-        
-            // semantic check: length should be divisible by 4
-            if( nd.getBytecode() != null && ( nd.getBytecode().length() % 4 != 0 ) ) {
-                throw new SemanticException( "BYTECODE must be divisible by 4", null, 0, 0 );
-            }     
-        }   
-    }
-    ;
-    
-
-    /**
-     * Production for syntax checker descriptions. It is fault-tolerant
-     * against element ordering.
-     *
-     * <pre>
-     * SyntaxCheckerDescription = LPAREN WSP
-     *       numericoid                           ; object identifier
-     *       [ SP "DESC" SP qdstring ]            ; description
-     *       SP "FQCN" SP fqcn                    ; fully qualified class name
-     *       [ SP "BYTECODE" SP base64 ]          ; optional base64 encoded bytecode
-     *       extensions WSP RPAREN                ; extensions
-     * 
-     * base64          = *(4base64-char)
-     * base64-char     = ALPHA / DIGIT / "+" / "/"
-     * fqcn = fqcnComponent 1*( DOT fqcnComponent )
-     * fqcnComponent = ???
-     * </pre>
-    */
-syntaxCheckerDescription returns [SyntaxCheckerDescription scd]
-    {
-        matchedProduction( "syntaxCheckerDescription()" );
-        ElementTracker et = new ElementTracker();
-    }
-    :
-    ( oid:STARTNUMERICOID { scd = new SyntaxCheckerDescription(numericoid(oid.getText())); } )
-    (
-        ( desc:DESC { et.track("DESC", desc); scd.setDescription(qdstring(desc.getText())); } )
-        |
-        ( fqcn:FQCN { et.track("FQCN", fqcn); scd.setFqcn(fqcn.getText()); } )
-        |
-        ( bytecode:BYTECODE { et.track("BYTECODE", bytecode); scd.setBytecode(bytecode.getText()); } )
-        |
-        ( extension:EXTENSION { 
-            Extension ex = extension(extension.getText());
-            et.track(ex.key, extension); 
-            scd.addExtension(ex.key, ex.values); 
-         } )
-    )*
-    RPAR
-    {
-        if( !isQuirksModeEnabled )
-        {
-            // semantic check: required elements
-            if( !et.contains("FQCN") ) {
-                throw new SemanticException( "FQCN is required", null, 0, 0 );
-            }
-        
-            // semantic check: length should be divisible by 4
-            if( scd.getBytecode() != null && ( scd.getBytecode().length() % 4 != 0 ) ) {
-                throw new SemanticException( "BYTECODE must be divisible by 4", null, 0, 0 );
-            }  
-        }      
-    }
-    ;
-    
-
-
-
-noidlen [String s] returns [NoidLen noidlen]
-    {
-        matchedProduction( "noidlen()" );
-        AntlrSchemaValueLexer lexer = new AntlrSchemaValueLexer(new StringReader(s));
-        AntlrSchemaValueParser parser = new AntlrSchemaValueParser(lexer);
-        parser.setParserMonitor(monitor);
-        noidlen = isQuirksModeEnabled ? parser.quirksNoidlen() : parser.noidlen();
-    }
-    :
-    ;
-
-
-extension [String s] returns [Extension extension]
-    {
-        matchedProduction( "extension()" );
-        AntlrSchemaExtensionLexer lexer = new AntlrSchemaExtensionLexer(new StringReader(s));
-        AntlrSchemaExtensionParser parser = new AntlrSchemaExtensionParser(lexer);
-        extension = parser.extension();
-    }
-    :
-    ;
-
-
-numericoid [String s] returns [String numericoid]
-    {
-        matchedProduction( "numericoid()");
-        if(isQuirksModeEnabled)
-        {
-             numericoid = oid(s);
-        }
-        else
-        {
-	        AntlrSchemaValueLexer lexer = new AntlrSchemaValueLexer(new StringReader(s));
-	        AntlrSchemaValueParser parser = new AntlrSchemaValueParser(lexer);
-	        parser.setParserMonitor(monitor);
-	        numericoid = parser.numericoid();
-        }
-    }
-    :
-    ;
-
-oid [String s] returns [String oid]
-    {
-        matchedProduction( "oid()" );
-        List<String> oids = oids(s);
-        if( oids.size() != 1 ) 
-        {
-            throw new SemanticException( "Exactly one OID expected", null, 0, 0 );
-        }
-        oid = oids.get(0);
-    }
-    :
-    ;
-
-oids [String s] returns [List<String> oids]
-    {
-        matchedProduction( "oids()" );
-        if(isQuirksModeEnabled)
-        {
-             oids = qdescrs(s);
-        }
-        else
-        {
-	        AntlrSchemaValueLexer lexer = new AntlrSchemaValueLexer(new StringReader(s));
-	        AntlrSchemaValueParser parser = new AntlrSchemaValueParser(lexer);
-	        parser.setParserMonitor(monitor);
-	        oids = parser.oids();
-	    }
-    }
-    :
-    ;
-
-qdescr [String s] returns [String qdescr]
-    {
-        matchedProduction( "qdescr()" );
-        List<String> qdescrs = qdescrs(s);
-        if( qdescrs.size() != 1 ) 
-        {
-            throw new SemanticException( "Exactly one qdescrs expected", null, 0, 0 );
-        }
-        qdescr = qdescrs.get(0);
-    }
-    :
-    ;
-
-qdescrs [String s] returns [List<String> qdescrs]
-    {
-        matchedProduction( "qdescrs()" );
-        AntlrSchemaValueLexer lexer = new AntlrSchemaValueLexer(new StringReader(s));
-        AntlrSchemaValueParser parser = new AntlrSchemaValueParser(lexer);
-        parser.setParserMonitor(monitor);
-        qdescrs = isQuirksModeEnabled ? parser.quirksQdescrs() : parser.qdescrs();
-    }
-    :
-    ;
-
-qdstring [String s] returns [String qdstring]
-    {
-        matchedProduction( "qdstring()" );
-        List<String> qdstrings = qdstrings(s);
-        if( qdstrings.size() != 1 ) 
-        {
-            throw new SemanticException( "Exactly one qdstrings expected", null, 0, 0 );
-        }
-        qdstring = qdstrings.get(0);
-    }
-    :
-    ;
-
-qdstrings [String s] returns [List<String> qdstrings]
-    {
-        matchedProduction( "qdstrings()" );
-        AntlrSchemaQdstringLexer lexer = new AntlrSchemaQdstringLexer(new StringReader(s));
-        AntlrSchemaQdstringParser parser = new AntlrSchemaQdstringParser(lexer);
-        parser.setParserMonitor(monitor);
-        qdstrings = parser.qdstrings();
-    }
-    :
-    ;
-
-ruleid [String s] returns [Integer ruleid]
-    {
-        matchedProduction( "ruleid()" );
-        AntlrSchemaValueLexer lexer = new AntlrSchemaValueLexer(new StringReader(s));
-        AntlrSchemaValueParser parser = new AntlrSchemaValueParser(lexer);
-        parser.setParserMonitor(monitor);
-        ruleid = parser.ruleid();
-    }
-    :
-    ;
-
-ruleids [String s] returns [List<Integer> ruleids]
-    {
-        matchedProduction( "ruleids()" );
-        AntlrSchemaValueLexer lexer = new AntlrSchemaValueLexer(new StringReader(s));
-        AntlrSchemaValueParser parser = new AntlrSchemaValueParser(lexer);
-        parser.setParserMonitor(monitor);
-        ruleids = parser.ruleids();
-    }
-    :
-    ;
-
-
-    
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/AbstractSchemaParser.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/AbstractSchemaParser.java
index 7764652..8c082e5 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/AbstractSchemaParser.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/AbstractSchemaParser.java
@@ -20,21 +20,18 @@
 package org.apache.directory.api.ldap.model.schema.parsers;
 
 
-import java.io.StringReader;
 import java.text.ParseException;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.directory.api.i18n.I18n;
 import org.apache.directory.api.ldap.model.constants.MetaSchemaConstants;
 import org.apache.directory.api.ldap.model.schema.SchemaObject;
+import org.apache.directory.api.ldap.model.schema.syntaxCheckers.OpenLdapObjectIdentifierMacro;
 import org.apache.directory.api.util.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import antlr.RecognitionException;
-import antlr.TokenStreamException;
-import antlr.TokenStreamRecognitionException;
-
 
 /**
  * Base class of all schema parsers.
@@ -48,28 +45,12 @@ public abstract class AbstractSchemaParser<T extends SchemaObject>
     /** The LoggerFactory used by this class */
     protected static final Logger LOG = LoggerFactory.getLogger( AbstractSchemaParser.class );
 
-    /** the monitor to use for this parser */
-    protected ParserMonitor monitor = new ParserMonitorAdapter();
-
-    /** the antlr generated parser being wrapped */
-    protected ReusableAntlrSchemaParser parser;
-
-    /** the antlr generated lexer being wrapped */
-    protected ReusableAntlrSchemaLexer lexer;
-
-    /** the schema object sub-type */
-    private Class<T> schemaObjectType;
+    /** The fast schemaObject parser */
+    protected OpenLdapSchemaParser fastParser;
 
     /** error code used when schema descritpion is null */
     private I18n errorCodeOnNull;
 
-    /** error code used on parse error when position is known */
-    private I18n errorCodeOnParseExceptionWithPosition;
-
-    /** error code used on parse error when position is unknown */
-    private I18n errorCodeOnParseException;
-
-
     /**
      * Instantiates a new abstract schema parser.
      * 
@@ -82,40 +63,11 @@ public abstract class AbstractSchemaParser<T extends SchemaObject>
         I18n errorCodeOnParseExceptionWithPosition,
         I18n errorCodeOnParseException )
     {
-        this.schemaObjectType = schemaObjectType;
         this.errorCodeOnNull = errorCodeOnNull;
-        this.errorCodeOnParseExceptionWithPosition = errorCodeOnParseExceptionWithPosition;
-        this.errorCodeOnParseException = errorCodeOnParseException;
-        lexer = new ReusableAntlrSchemaLexer( new StringReader( "" ) );
-        parser = new ReusableAntlrSchemaParser( lexer );
-    }
-
-
-    /**
-     * Initializes the plumbing by creating a pipe and coupling the parser/lexer
-     * pair with it. param spec the specification to be parsed
-     *
-     * @param spec the spec
-     */
-    protected void reset( String spec )
-    {
-        StringReader in = new StringReader( spec );
-        lexer.prepareNextInput( in );
-        parser.resetState();
+        fastParser = new OpenLdapSchemaParser();
     }
 
 
-    /**
-     * Sets the parser monitor.
-     * 
-     * @param parserMonitor the new parser monitor
-     */
-    public void setParserMonitor( ParserMonitor parserMonitor )
-    {
-        this.monitor = parserMonitor;
-        parser.setParserMonitor( parserMonitor );
-    }
-
 
     /**
      * Sets the quirks mode. 
@@ -127,7 +79,7 @@ public abstract class AbstractSchemaParser<T extends SchemaObject>
      */
     public void setQuirksMode( boolean enabled )
     {
-        parser.setQuirksMode( enabled );
+        fastParser.setQuirksMode( enabled );
     }
 
 
@@ -138,7 +90,7 @@ public abstract class AbstractSchemaParser<T extends SchemaObject>
      */
     public boolean isQuirksMode()
     {
-        return parser.isQuirksMode();
+        return fastParser.isQuirksMode();
     }
 
 
@@ -149,83 +101,7 @@ public abstract class AbstractSchemaParser<T extends SchemaObject>
      * @return A SchemaObject instance
      * @throws ParseException If the parsing failed
      */
-    public synchronized T parse( String schemaDescription ) throws ParseException
-    {
-        if ( LOG.isDebugEnabled() )
-        {
-            LOG.debug( I18n.msg( I18n.MSG_13718_PARSING_A, schemaObjectType.getClass().getSimpleName(), schemaDescription ) );
-        }
-
-        if ( schemaDescription == null )
-        {
-            LOG.error( I18n.err( errorCodeOnNull ) );
-            throw new ParseException( I18n.err( I18n.ERR_13714_NULL ), 0 );
-        }
-
-        // reset and initialize the parser / lexer pair
-        reset( schemaDescription );
-
-        try
-        {
-            T schemaObject = doParse();
-            schemaObject.setSpecification( schemaDescription );
-
-            // Update the schemaName
-            updateSchemaName( schemaObject );
-
-            return schemaObject;
-        }
-        catch ( RecognitionException re )
-        {
-            throw wrapRecognitionException( schemaDescription, re );
-        }
-        catch ( TokenStreamRecognitionException tsre )
-        {
-            if ( tsre.recog != null )
-            {
-                throw wrapRecognitionException( schemaDescription, tsre.recog );
-            }
-            else
-            {
-                throw wrapTokenStreamException( schemaDescription, tsre );
-            }
-        }
-        catch ( TokenStreamException tse )
-        {
-            throw wrapTokenStreamException( schemaDescription, tse );
-        }
-    }
-
-
-    private ParseException wrapRecognitionException( String schemaDescription, RecognitionException re )
-    {
-        String msg = I18n.err( errorCodeOnParseExceptionWithPosition, schemaDescription, re.getMessage(),
-            re.getColumn() );
-        LOG.error( msg );
-        ParseException parseException = new ParseException( msg, re.getColumn() );
-        parseException.initCause( re );
-        return parseException;
-    }
-
-
-    private ParseException wrapTokenStreamException( String schemaDescription, TokenStreamException tse )
-    {
-        String msg = I18n.err( errorCodeOnParseException, schemaDescription, tse.getMessage() );
-        LOG.error( msg );
-        ParseException parseException = new ParseException( msg, 0 );
-        parseException.initCause( tse );
-        return parseException;
-    }
-
-
-    /**
-     * Parse a SchemaObject description and returns back an instance of SchemaObject.
-     * 
-     * @return A SchemaObject instance
-     * @throws RecognitionException the native antlr exception
-     * @throws TokenStreamException the native antlr exception
-     */
-    protected abstract T doParse() throws RecognitionException, TokenStreamException;
+    public abstract T parse( String schemaDescription ) throws ParseException;
 
 
     /**
@@ -234,7 +110,7 @@ public abstract class AbstractSchemaParser<T extends SchemaObject>
      *
      * @param schemaObject the schema object where the name should be updated
      */
-    private void updateSchemaName( SchemaObject schemaObject )
+    protected void updateSchemaName( SchemaObject schemaObject )
     {
         // Update the Schema if we have the X-SCHEMA extension
         List<String> schemaExtension = schemaObject.getExtension( MetaSchemaConstants.X_SCHEMA_AT );
@@ -257,4 +133,15 @@ public abstract class AbstractSchemaParser<T extends SchemaObject>
             schemaObject.setSchemaName( MetaSchemaConstants.SCHEMA_OTHER );
         }
     }
+    
+    
+    /**
+     * Get the defined macros.
+     * 
+     * @return The map of defined macros
+     */
+    public Map<String, OpenLdapObjectIdentifierMacro> getObjectIdentifiers()
+    {
+        return fastParser.getObjectIdentifierMacros();
+    }
 }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/AttributeTypeDescriptionSchemaParser.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/AttributeTypeDescriptionSchemaParser.java
index 1250f96..281545e 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/AttributeTypeDescriptionSchemaParser.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/AttributeTypeDescriptionSchemaParser.java
@@ -25,9 +25,6 @@ import java.text.ParseException;
 import org.apache.directory.api.i18n.I18n;
 import org.apache.directory.api.ldap.model.schema.AttributeType;
 
-import antlr.RecognitionException;
-import antlr.TokenStreamException;
-
 
 /**
  * A parser for RFC 4512 attribute type descriptions.
@@ -36,7 +33,6 @@ import antlr.TokenStreamException;
  */
 public class AttributeTypeDescriptionSchemaParser extends AbstractSchemaParser<AttributeType>
 {
-
     /**
      * Creates a schema parser instance.
      */
@@ -80,19 +76,14 @@ public class AttributeTypeDescriptionSchemaParser extends AbstractSchemaParser<A
      * @return the parsed AttributeTypeDescription bean
      * @throws ParseException if there are any recognition errors (bad syntax)
      */
-    public AttributeType parseAttributeTypeDescription( String attributeTypeDescription ) throws ParseException
+    public AttributeType parse( String attributeTypeDescription ) throws ParseException
     {
-        return super.parse( attributeTypeDescription );
-    }
+        AttributeType attributeType = fastParser.parseAttributeType( attributeTypeDescription );
+        attributeType.setSpecification( attributeTypeDescription );
 
+        // Update the schemaName
+        updateSchemaName( attributeType );
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected AttributeType doParse() throws RecognitionException, TokenStreamException
-    {
-        return parser.attributeTypeDescription();
+        return attributeType;
     }
-
 }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/ConsoleParserMonitor.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/ConsoleParserMonitor.java
deleted file mode 100644
index 2351aa1..0000000
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/ConsoleParserMonitor.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.directory.api.ldap.model.schema.parsers;
-
-
-/**
- * A console reporting monitor.  Add system property 'maven.eve.schema.parser.trace'
- * to get this monitor to trace parser production execution.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-public class ConsoleParserMonitor implements ParserMonitor
-{
-    /** The maven property to add on the commmand line */
-    public static final String TRACE_KEY = "maven.eve.schema.parser.trace";
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void matchedProduction( String prod )
-    {
-        if ( System.getProperties().containsKey( TRACE_KEY ) )
-        {
-            System.out.println( prod );
-        }
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void startedParse( String s )
-    {
-        if ( System.getProperties().containsKey( TRACE_KEY ) )
-        {
-            System.out.println( s );
-        }
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void finishedParse( String s )
-    {
-        if ( System.getProperties().containsKey( TRACE_KEY ) )
-        {
-            System.out.println( s );
-        }
-    }
-}
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/DitContentRuleDescriptionSchemaParser.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/DitContentRuleDescriptionSchemaParser.java
index 3635130..59287a0 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/DitContentRuleDescriptionSchemaParser.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/DitContentRuleDescriptionSchemaParser.java
@@ -25,10 +25,6 @@ import java.text.ParseException;
 import org.apache.directory.api.i18n.I18n;
 import org.apache.directory.api.ldap.model.schema.DitContentRule;
 
-import antlr.RecognitionException;
-import antlr.TokenStreamException;
-
-
 /**
  * A parser for RFC 4512 DIT content rule descriptions.
  * 
@@ -66,19 +62,14 @@ public class DitContentRuleDescriptionSchemaParser extends AbstractSchemaParser<
      * @return the parsed DITContentRuleDescription bean
      * @throws ParseException if there are any recognition errors (bad syntax)
      */
-    public DitContentRule parseDITContentRuleDescription( String ditContentRuleDescription ) throws ParseException
+    public DitContentRule parse( String ditContentRuleDescription ) throws ParseException
     {
-        return super.parse( ditContentRuleDescription );
-    }
+        DitContentRule ditContentRule = fastParser.parseDitContentRule( ditContentRuleDescription );
+        ditContentRule.setSpecification( ditContentRuleDescription );
 
+        // Update the schemaName
+        updateSchemaName( ditContentRule );
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected DitContentRule doParse() throws RecognitionException, TokenStreamException
-    {
-        return parser.ditContentRuleDescription();
+        return ditContentRule;
     }
-
 }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/DitStructureRuleDescriptionSchemaParser.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/DitStructureRuleDescriptionSchemaParser.java
index 806d663..891eeb5 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/DitStructureRuleDescriptionSchemaParser.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/DitStructureRuleDescriptionSchemaParser.java
@@ -25,9 +25,6 @@ import java.text.ParseException;
 import org.apache.directory.api.i18n.I18n;
 import org.apache.directory.api.ldap.model.schema.DitStructureRule;
 
-import antlr.RecognitionException;
-import antlr.TokenStreamException;
-
 
 /**
  * A parser for RFC 4512 DIT structure rule descriptions.
@@ -68,20 +65,14 @@ public class DitStructureRuleDescriptionSchemaParser extends AbstractSchemaParse
      * @return the parsed DITStructureRuleDescription bean
      * @throws ParseException if there are any recognition errors (bad syntax)
      */
-    public DitStructureRule parseDITStructureRuleDescription( String ditStructureRuleDescription )
-        throws ParseException
+    public DitStructureRule parse( String ditStructureRuleDescription ) throws ParseException
     {
-        return super.parse( ditStructureRuleDescription );
-
-    }
+        DitStructureRule ditStructureRule = fastParser.parseDitStructureRule( ditStructureRuleDescription );
+        ditStructureRule.setSpecification( ditStructureRuleDescription );
 
+        // Update the schemaName
+        updateSchemaName( ditStructureRule );
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected DitStructureRule doParse() throws RecognitionException, TokenStreamException
-    {
-        return parser.ditStructureRuleDescription();
+        return ditStructureRule;
     }
 }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/FastOpenLdapSchemaParser.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/FastOpenLdapSchemaParser.java
deleted file mode 100644
index 12ae6cc..0000000
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/FastOpenLdapSchemaParser.java
+++ /dev/null
@@ -1,2266 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- * 
- *    http://www.apache.org/licenses/LICENSE-2.0
- * 
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- * 
- */
-package org.apache.directory.api.ldap.model.schema.parsers;
-
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.StringReader;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.directory.api.i18n.I18n;
-import org.apache.directory.api.ldap.model.exception.LdapSchemaException;
-import org.apache.directory.api.ldap.model.ldif.LdapLdifException;
-import org.apache.directory.api.ldap.model.schema.AttributeType;
-import org.apache.directory.api.ldap.model.schema.MutableAttributeType;
-import org.apache.directory.api.ldap.model.schema.MutableObjectClass;
-import org.apache.directory.api.ldap.model.schema.ObjectClass;
-import org.apache.directory.api.ldap.model.schema.ObjectClassTypeEnum;
-import org.apache.directory.api.ldap.model.schema.SchemaObject;
-import org.apache.directory.api.ldap.model.schema.UsageEnum;
-import org.apache.directory.api.ldap.model.schema.syntaxCheckers.OpenLdapObjectIdentifierMacro;
-import org.apache.directory.api.util.Strings;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A reusable wrapper for hand parser OpenLDAP schema.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-public class FastOpenLdapSchemaParser
-{
-    /** The LoggerFactory used by this class */
-    protected static final Logger LOG = LoggerFactory.getLogger( FastOpenLdapSchemaParser.class );
-
-    /** the monitor to use for this parser */
-    protected ParserMonitor monitor = new ParserMonitorAdapter();
-
-    /** A flag used to tell the parser if it should be strict or not */
-    private boolean isQuirksModeEnabled = false;
-
-    /** the number of the current line being parsed by the reader */
-    protected int lineNumber;
-
-    /** The list of parsed schema descriptions */
-    private List<Object> schemaDescriptions = new ArrayList<>();
-
-    /** The list of attribute type, initialized by splitParsedSchemaDescriptions() */
-    private List<MutableAttributeType> attributeTypes;
-
-    /** The list of object classes, initialized by splitParsedSchemaDescriptions()*/
-    private List<ObjectClass> objectClasses;
-
-    /** The map of object identifier macros, initialized by splitParsedSchemaDescriptions()*/
-    private Map<String, OpenLdapObjectIdentifierMacro> objectIdentifierMacros = new HashMap<>();
-
-    /** Flag whether object identifier macros should be resolved. */
-    private boolean isResolveObjectIdentifierMacros;
-    
-    private static final boolean QUOTED = true;
-    private static final boolean UN_QUOTED = false;
-    
-    
-    private class Extension
-    {
-        /** The extension key */
-        String key;
-        
-        /** The extension values */
-        List<String> values = new ArrayList<>();
-        
-        /**
-         * {@inheritDoc} 
-         */
-        @Override
-        public String toString()
-        {
-            StringBuilder sb = new StringBuilder();
-            
-            sb.append( key );
-            
-            if ( values.size() > 1 )
-            {
-                boolean isFirst = true;
-                sb.append( "( " );
-                
-                for ( String value : values )
-                {
-                    if ( isFirst )
-                    {
-                        isFirst = false;
-                    }
-                    else
-                    {
-                        sb.append( ' ' );
-                    }
-                    
-                    sb.append( '\'' ) .append( value ).append( '\'' );
-                }
-
-                sb.append( " )" );
-            }
-            else
-            {
-                sb.append( ' ' ).append( '\'' ) .append( values.get( 0 ) ).append( '\'' );
-            }
-            
-            return sb.toString();
-        }
-    }
-    
-    private class NoidLen
-    {
-        /** The syntax OID */
-        String noid;
-        
-        /** The syntax length */
-        long len = 0;
-        
-        /**
-         * {@inheritDoc} 
-         */
-        @Override
-        public String toString()
-        {
-            if ( len > 0 )
-            {
-                return noid + '{' + len + '}';
-            }
-            else
-            {
-                return noid;
-            }
-        }
-    }
-    
-    
-    private class PosSchema
-    {
-        /** The line number in the file */
-        int lineNumber;
-        
-        /** The position in the current line */
-        int start;
-        
-        /** The line being processed */
-        String line;
-        
-        /**
-         * {@inheritDoc} 
-         */
-        @Override
-        public String toString()
-        {
-            if ( line == null )
-            {
-                return "null";
-            }
-            else if ( line.length() < start )
-            {
-                return "EOL";
-            }
-            else
-            {
-                return line.substring( start ); 
-            }
-        }
-    }
-
-    
-    /**
-     * The list of AttributeTypeDescription elements that can be seen 
-     */
-    private enum AttributeTypeElements
-    {
-        NAME(1),
-        DESC(2),
-        OBSOLETE(4),
-        SUP(8),
-        EQUALITY(16),
-        ORDERING(32),
-        SUBSTR(64),
-        SYNTAX(128),
-        SINGLE_VALUE(256),
-        COLLECTIVE(512),
-        NO_USER_MODIFICATION(1024),
-        USAGE(2048);
-        
-        private int value;
-        
-        AttributeTypeElements( int value )
-        {
-            this.value = value;
-        }
-    }
-
-    
-    /**
-     * The list of ObjectClassDescription elements that can be seen 
-     */
-    private enum ObjectClassElements
-    {
-        NAME(1),
-        DESC(2),
-        OBSOLETE(4),
-        SUP(8),
-        MUST(16),
-        MAY(32),
-        ABSTRACT(64),
-        STRUCTURAL(64),
-        AUXILIARY(64);
-        
-        private int value;
-        
-        ObjectClassElements( int value )
-        {
-            this.value = value;
-        }
-    }
-
-    /**
-     * Creates a reusable instance of an OpenLdapSchemaParser.
-     *
-     * @throws IOException if the pipe cannot be formed
-     */
-    public FastOpenLdapSchemaParser() throws IOException
-    {
-        isResolveObjectIdentifierMacros = true;
-        isQuirksModeEnabled = true;
-    }
-
-
-    /**
-     * Reset the parser
-     */
-    public void clear()
-    {
-        if ( attributeTypes != null )
-        {
-            attributeTypes.clear();
-        }
-        
-        if ( objectClasses != null )
-        {
-            objectClasses.clear();
-        }
-        
-        if ( schemaDescriptions != null )
-        {
-            schemaDescriptions.clear();
-        }
-    
-        if ( objectIdentifierMacros != null )
-        {
-            objectIdentifierMacros.clear();
-        }
-    }
-
-
-    /**
-     * Gets the attribute types.
-     * 
-     * @return the attribute types
-     */
-    public List<MutableAttributeType> getAttributeTypes()
-    {
-        return attributeTypes;
-    }
-
-
-    /**
-     * Gets the object class types.
-     * 
-     * @return the object class types
-     */
-    public List<ObjectClass> getObjectClassTypes()
-    {
-        return objectClasses;
-    }
-
-
-    /**
-     * Gets the object identifier macros.
-     * 
-     * @return the object identifier macros
-     */
-    public Map<String, OpenLdapObjectIdentifierMacro> getObjectIdentifierMacros()
-    {
-        return objectIdentifierMacros;
-    }
-
-
-    /**
-     * Splits parsed schema descriptions and resolved
-     * object identifier macros.
-     * 
-     * @throws ParseException the parse exception
-     */
-    private void afterParse() throws ParseException
-    {
-        objectClasses = new ArrayList<>();
-        attributeTypes = new ArrayList<>();
-
-        // split parsed schema descriptions
-        for ( Object obj : schemaDescriptions )
-        {
-            if ( obj instanceof OpenLdapObjectIdentifierMacro )
-            {
-                OpenLdapObjectIdentifierMacro oid = ( OpenLdapObjectIdentifierMacro ) obj;
-                objectIdentifierMacros.put( oid.getName(), oid );
-            }
-            else if ( obj instanceof AttributeType )
-            {
-                MutableAttributeType attributeType = ( MutableAttributeType ) obj;
-
-                attributeTypes.add( attributeType );
-            }
-            else if ( obj instanceof ObjectClass )
-            {
-                ObjectClass objectClass = ( ObjectClass ) obj;
-
-                objectClasses.add( objectClass );
-            }
-        }
-
-        if ( isResolveObjectIdentifierMacros() )
-        {
-            // resolve object identifier macros
-            for ( OpenLdapObjectIdentifierMacro oid : objectIdentifierMacros.values() )
-            {
-                resolveObjectIdentifierMacro( oid );
-            }
-
-            // apply object identifier macros to object classes
-            for ( ObjectClass objectClass : objectClasses )
-            {
-                objectClass.setOid( getResolveOid( objectClass.getOid() ) );
-            }
-
-            // apply object identifier macros to attribute types
-            for ( MutableAttributeType attributeType : attributeTypes )
-            {
-                attributeType.setOid( getResolveOid( attributeType.getOid() ) );
-                attributeType.setSyntaxOid( getResolveOid( attributeType.getSyntaxOid() ) );
-            }
-
-        }
-    }
-
-
-    private String getResolveOid( String oid )
-    {
-        if ( oid != null && oid.indexOf( ':' ) != -1 )
-        {
-            // resolve OID
-            String[] nameAndSuffix = oid.split( ":" );
-            
-            if ( objectIdentifierMacros.containsKey( nameAndSuffix[0] ) )
-            {
-                OpenLdapObjectIdentifierMacro macro = objectIdentifierMacros.get( nameAndSuffix[0] );
-                
-                return macro.getResolvedOid() + "." + nameAndSuffix[1];
-            }
-        }
-        
-        return oid;
-    }
-
-
-    private void resolveObjectIdentifierMacro( OpenLdapObjectIdentifierMacro macro ) throws ParseException
-    {
-        String rawOidOrNameSuffix = macro.getRawOidOrNameSuffix();
-
-        if ( macro.isResolved() )
-        {
-            // finished
-            return;
-        }
-        else if ( rawOidOrNameSuffix.indexOf( ':' ) != -1 )
-        {
-            // resolve OID
-            String[] nameAndSuffix = rawOidOrNameSuffix.split( ":" );
-            
-            if ( objectIdentifierMacros.containsKey( nameAndSuffix[0] ) )
-            {
-                OpenLdapObjectIdentifierMacro parentMacro = objectIdentifierMacros.get( nameAndSuffix[0] );
-                resolveObjectIdentifierMacro( parentMacro );
-                macro.setResolvedOid( parentMacro.getResolvedOid() + "." + nameAndSuffix[1] );
-            }
-            else
-            {
-                throw new ParseException( I18n.err( I18n.ERR_13726_NO_OBJECT_IDENTIFIER_MACRO, nameAndSuffix[0] ), 0 );
-            }
-
-        }
-        else
-        {
-            // no :suffix,
-            if ( objectIdentifierMacros.containsKey( rawOidOrNameSuffix ) )
-            {
-                OpenLdapObjectIdentifierMacro parentMacro = objectIdentifierMacros.get( rawOidOrNameSuffix );
-                resolveObjectIdentifierMacro( parentMacro );
-                macro.setResolvedOid( parentMacro.getResolvedOid() );
-            }
-            else
-            {
-                macro.setResolvedOid( rawOidOrNameSuffix );
-            }
-        }
-    }
-
-
-    /**
-     * Parses an OpenLDAP schemaObject element/object.
-     *
-     * @param schemaObject the String image of a complete schema object
-     * @return the schema object
-     * @throws ParseException If the schemaObject can't be parsed
-     */
-    public SchemaObject parse( String schemaObject ) throws ParseException
-    {
-        if ( ( schemaObject == null ) || Strings.isEmpty( schemaObject.trim() ) )
-        {
-            throw new ParseException( I18n.err( I18n.ERR_13716_NULL_OR_EMPTY_STRING_SCHEMA_OBJECT ), 0 );
-        }
-        
-        try ( Reader reader = new BufferedReader( new StringReader( schemaObject ) ) )
-        {
-            parse( reader );
-            afterParse();
-        }
-        catch ( IOException | LdapSchemaException e )
-        {
-            throw new ParseException( e.getMessage(), 0 );
-        }
-
-        if ( !schemaDescriptions.isEmpty() )
-        {
-            for ( Object obj : schemaDescriptions )
-            {
-                if ( obj instanceof SchemaObject )
-                {
-                    return ( SchemaObject ) obj;
-                }
-            }
-        }
-        
-        return null;
-    }
-
-
-    /**
-     * Parses a stream of OpenLDAP schemaObject elements/objects. Default charset is used.
-     *
-     * @param schemaIn a stream of schema objects
-     * @throws Exception 
-     */
-    public void parse( InputStream schemaIn ) throws Exception
-    {
-        try ( InputStreamReader in = new InputStreamReader( schemaIn, Charset.defaultCharset() ) )
-        {
-            try ( Reader reader = new BufferedReader( in ) )
-            {
-                parse( reader );
-                afterParse();
-            }
-        }
-    }
-    
-    
-    private void skipWhites( Reader reader, PosSchema pos, boolean mandatory ) throws IOException, LdapSchemaException
-    {
-        boolean hasSpace = false;
-        
-        while ( true )
-        {
-            if ( isEmpty( pos ) )
-            {
-                getLine( reader, pos );
-                
-                if ( pos.line == null )
-                {
-                    return;
-                }
-                
-                hasSpace = true;
-                continue;
-            }
-            
-            if ( pos.line == null )
-            {
-                throw new LdapSchemaException( I18n.err( I18n.ERR_13782_END_OF_FILE, pos.lineNumber, pos.start ) );
-            }
-            
-            while ( Character.isWhitespace( pos.line.charAt( pos.start ) ) )
-            {
-                hasSpace = true;
-                pos.start++;
-                
-                if ( isEmpty( pos ) )
-                {
-                    getLine( reader, pos );
-
-                    if ( pos.line == null )
-                    {
-                        return;
-                    }
-                    
-                    continue;
-                }
-            }
-            
-            if ( pos.line.charAt( pos.start ) == '#' )
-            {
-                getLine( reader, pos );
-
-                if ( pos.line == null )
-                {
-                    return;
-                }
-                
-                hasSpace = true;
-                continue;
-            }
-            else
-            {
-                if ( mandatory && !hasSpace )
-                {
-                    throw new LdapSchemaException( I18n.err( I18n.ERR_13783_SPACE_EXPECTED, pos.lineNumber, pos.start ) );
-                }
-                else
-                {
-                    return;
-                }
-            }
-        }
-    }
-    
-    
-    private boolean isComment( PosSchema pos )
-    {
-        if ( isEmpty( pos ) )
-        {
-            return true;
-        }
-        
-        return pos.line.charAt( pos.start ) == '#';
-    }
-    
-    
-    private boolean isEmpty( PosSchema pos )
-    {
-        return ( pos.line == null ) || ( pos.start >= pos.line.length() );
-    }
-    
-    
-    private boolean startsWith( PosSchema pos, String text )
-    {
-        if ( ( pos.line == null ) || ( pos.line.length() - pos.start < text.length() ) )
-        {
-            return false;
-        }
-        
-        return text.equalsIgnoreCase( pos.line.substring( pos.start, pos.start + text.length() ) );
-    }
-    
-    
-    private boolean startsWith( Reader reader, PosSchema pos, char c ) throws IOException, LdapSchemaException
-    {
-        return startsWith( reader, pos, c, UN_QUOTED );
-    }
-    
-    
-    private boolean startsWith( Reader reader, PosSchema pos, char c, boolean quoted ) throws IOException, LdapSchemaException
-    {
-        if ( ( pos.line == null ) || ( pos.line.length() - pos.start < 1 ) )
-        {
-            return false;
-        }
-        
-        if ( quoted )
-        {
-            // Don't read a new line when we are within quotes
-            return pos.line.charAt( pos.start ) == c;
-        }
-
-        while ( isEmpty( pos ) || ( isComment( pos ) ) )
-        {
-            getLine( reader, pos );
-            
-            if ( pos.line == null )
-            {
-                return false;
-            }
-            
-            skipWhites( reader, pos, false );
-            
-            if ( isComment( pos ) )
-            {
-                continue;
-            }
-        }
-        
-        return pos.line.charAt( pos.start ) == c;
-    }
-    
-    
-    private boolean isAlpha( PosSchema pos )
-    {
-        if ( ( pos.line == null ) || ( pos.line.length() - pos.start < 1 ) )
-        {
-            return false;
-        }
-        
-        return Character.isAlphabetic( pos.line.charAt( pos.start ) );
-    }
-    
-    
-    private boolean isDigit( PosSchema pos )
-    {
-        if ( ( pos.line == null ) || ( pos.line.length() - pos.start < 1 ) )
-        {
-            return false;
-        }
-        
-        return Character.isDigit( pos.line.charAt( pos.start ) );
-    }
-
-    
-    private void getLine( Reader reader, PosSchema pos ) throws IOException
-    {
-        pos.line = ( ( BufferedReader ) reader ).readLine();
-        pos.start = 0;
-        
-        if ( pos.line != null )
-        {
-            pos.lineNumber++;
-        }
-    }
-    
-    
-    /**
-     * numericoid   ::= number ( DOT number )+ |
-     * number       ::= DIGIT | LDIGIT DIGIT+
-     * DIGIT        ::= %x30 | LDIGIT       ; "0"-"9"
-     * LDIGIT       ::= %x31-39             ; "1"-"9"
-     * DOT          ::= %x2E                ; period (".")
-     */
-    private String getNumericOid( Reader reader, PosSchema pos ) throws IOException, LdapSchemaException
-    {
-        boolean isDot = true;
-        int start = pos.start;
-        int numberStart = start;
-        boolean firstIsZero = false;
-        boolean isFirstDigit = true;
-        
-        while ( true )
-        {
-            if ( isDigit( pos ) )
-            {
-                if ( firstIsZero )
-                {
-                    throw new LdapSchemaException( I18n.err( I18n.ERR_13784_BAD_OID_TWO_ZEROES, pos.lineNumber, pos.start ) );
-                }
-                    
-                if ( ( pos.line.charAt( pos.start ) == '0' ) && isFirstDigit )
-                {
-                    firstIsZero = true;
-                }
-                
-                isDot = false;
-                pos.start++;
-                isFirstDigit = false;
-            }
-            else if ( startsWith( reader, pos, '.' ) )
-            {
-                if ( isDot )
-                {
-                    // We can't have two consecutive dots or a dot at the beginning
-                    throw new LdapSchemaException( I18n.err( I18n.ERR_13785_BAD_OID_CONSECUTIVE_DOTS, pos.lineNumber, pos.start ) );
-                }
-                
-                firstIsZero = false;
-                isFirstDigit = true;
-                pos.start++;
-                isDot = true;
-            }
-            else
-            {
-                break;
-            }
-        }
-        
-        if ( isDot )
-        {
-            // We can't have two consecutive dots or a dot at the beginning
-            throw new LdapSchemaException( I18n.err( I18n.ERR_13786_BAD_OID_DOT_AT_THE_END, pos.lineNumber, pos.start ) );
-        }
-        
-        return pos.line.substring( start, pos.start );
-    }
-
-    
-    /**
-     * In normal mode :
-     * <pre>
-     * oid          ::= descr | numericoid
-     * descr        ::= keystring
-     * keystring    ::= leadkeychar keychar*
-     * leadkeychar  ::= ALPHA
-     * keychar      ::= ALPHA | DIGIT | HYPHEN
-     * numericoid   ::= number ( DOT number )+ |
-     * number       ::= DIGIT | LDIGIT DIGIT+
-     * ALPHA        ::= %x41-5A | %x61-7A   ; "A"-"Z" / "a"-"z"
-     * DIGIT        ::= %x30 | LDIGIT       ; "0"-"9"
-     * LDIGIT       ::= %x31-39             ; "1"-"9"
-     * DOT          ::= %x2E                ; period (".")
-     * HYPHEN       ::= %x2D                ; hyphen ("-")
-     * </pre>
-     * 
-     * In quirks mode :
-     * <pre>
-     * oid          ::= descr | numericoid
-     * descr        ::= descrQ (COLON numericoid)
-     * descrQ       ::= keystringQ
-     * keystringQ   ::= LkeycharQ keycharQ*
-     * LkeycharQ    ::= ALPHA | HYPHEN | UNDERSCORE | SEMI_COLON | DOT | COLON | SHARP 
-     * keycharQ     ::= ALPHA | DIGIT | HYPHEN | UNDERSCORE | SEMI_COLON | DOT | COLON | SHARP 
-     * numericoid   ::= number ( DOT number )+
-     * number       ::= DIGIT | LDIGIT DIGIT+
-     * ALPHA        ::= %x41-5A | %x61-7A   ; "A"-"Z" / "a"-"z"
-     * DIGIT        ::= %x30 | LDIGIT       ; "0"-"9"
-     * LDIGIT       ::= %x31-39             ; "1"-"9"
-     * HYPHEN       ::= %x2D                ; hyphen ("-")
-     * UNDERSCORE   ::= %x5F                ; underscore ("_")
-     * DOT          ::= %x2E                ; period (".")
-     * COLON        ::= %x3A                ; colon (":")
-     * SEMI_COLON   ::= %x3B                ; semi-colon(";")
-     * SHARP        ::= %x23                ; octothorpe (or sharp sign) ("#")
-     * </pre>
-     */
-    private String getOidAndMacro( Reader reader, PosSchema pos ) throws IOException, LdapSchemaException
-    {
-        if ( isAlpha( pos ) )
-        {
-            // A descr (likely)
-            if ( isQuirksModeEnabled )
-            {
-                // This is a OID name
-                int start = pos.start;
-                char c = pos.line.charAt( pos.start );
-                
-                while ( Character.isDigit( c ) || Character.isAlphabetic( c ) || ( c == '-' ) || ( c == '_' )
-                    || ( c == ';' ) || ( c == '.' ) || ( c == '#' ) )
-                {
-                    pos.start++;
-                    
-                    if ( isEmpty( pos ) )
-                    {
-                        break;
-                    }
-                }
-                
-                String oidName = pos.line.substring( start, pos.start  );
-                
-                // We may have a ':' followed by an OID
-                if ( startsWith( reader, pos, ':' ) )
-                {
-                    pos.start++;
-                    
-                    String oid = getNumericOid( reader, pos );
-                    
-                    return objectIdentifierMacros.get( oidName ).getRawOidOrNameSuffix() + '.' + oid;
-                }
-                else
-                {
-                    // Ok, we may just have an oidName
-                    OpenLdapObjectIdentifierMacro macro = objectIdentifierMacros.get( oidName );
-                    
-                    if ( macro == null )
-                    {
-                        return oidName;
-                    }
-                    else
-                    {
-                        return macro.getRawOidOrNameSuffix();
-                    }
-                }
-            }
-            else
-            {
-                // A simple descr
-                return getDescr( reader, pos );
-            }
-        }
-        else if ( isDigit( pos ) )
-        {
-            // This is a numeric oid
-            return getNumericOid( reader, pos );
-        }
-        else
-        {
-            // This is an error
-            throw new LdapSchemaException( I18n.err( I18n.ERR_13787_OID_EXPECTED, pos.lineNumber, pos.start ) );
-        }
-    }
-
-    
-    /**
-     * In normal mode :
-     * <pre>
-     * oid          ::= descr | numericoid
-     * descr        ::= keystring
-     * keystring    ::= leadkeychar keychar*
-     * leadkeychar  ::= ALPHA
-     * keychar      ::= ALPHA | DIGIT | HYPHEN
-     * numericoid   ::= number ( DOT number )+ |
-     * number       ::= DIGIT | LDIGIT DIGIT+
-     * ALPHA        ::= %x41-5A | %x61-7A   ; "A"-"Z" / "a"-"z"
-     * DIGIT        ::= %x30 | LDIGIT       ; "0"-"9"
-     * LDIGIT       ::= %x31-39             ; "1"-"9"
-     * DOT          ::= %x2E                ; period (".")
-     * HYPHEN       ::= %x2D                ; hyphen ("-")
-     * </pre>
-     * 
-     * In quirks mode :
-     * <pre>
-     * oid          ::= descr | numericoid
-     * descr        ::= descrQ (COLON numericoid)
-     * descrQ       ::= keystringQ
-     * keystringQ   ::= LkeycharQ keycharQ*
-     * LkeycharQ    ::= ALPHA | HYPHEN | UNDERSCORE | SEMI_COLON | DOT | COLON | SHARP 
-     * keycharQ     ::= ALPHA | DIGIT | HYPHEN | UNDERSCORE | SEMI_COLON | DOT | COLON | SHARP 
-     * numericoid   ::= number ( DOT number )+
-     * number       ::= DIGIT | LDIGIT DIGIT+
-     * ALPHA        ::= %x41-5A | %x61-7A   ; "A"-"Z" / "a"-"z"
-     * DIGIT        ::= %x30 | LDIGIT       ; "0"-"9"
-     * LDIGIT       ::= %x31-39             ; "1"-"9"
-     * HYPHEN       ::= %x2D                ; hyphen ("-")
-     * UNDERSCORE   ::= %x5F                ; underscore ("_")
-     * DOT          ::= %x2E                ; period (".")
-     * COLON        ::= %x3A                ; colon (":")
-     * SEMI_COLON   ::= %x3B                ; semi-colon(";")
-     * SHARP        ::= %x23                ; octothorpe (or sharp sign) ("#")
-     * </pre>
-     */
-    private String getOid( Reader reader, PosSchema pos ) throws IOException, LdapSchemaException
-    {
-        if ( isAlpha( pos ) )
-        {
-            // A descr (likely)
-            if ( isQuirksModeEnabled )
-            {
-                // This is a OID name
-                int start = pos.start;
-                char c = pos.line.charAt( pos.start );
-                
-                while ( Character.isAlphabetic( c ) || Character.isDigit( c ) || ( c == '-' )
-                    || ( c == '_' ) || ( c == ';' ) || ( c == '.' ) || ( c == ':' ) || ( c == '#' ) )
-                {
-                    pos.start++;
-                    
-                    if ( isEmpty( pos ) )
-                    {
-                        break;
-                    }
-                    
-                    c = pos.line.charAt( pos.start );
-                }
-                
-                return pos.line.substring( start, pos.start  );
-            }
-            else
-            {
-                // A simple descr
-                return getDescr( reader, pos );
-            }
-        }
-        else if ( isDigit( pos ) )
-        {
-            // This is a numeric oid
-            return getNumericOid( reader, pos );
-        }
-        else
-        {
-            // This is an error
-            throw new LdapSchemaException( I18n.err( I18n.ERR_13787_OID_EXPECTED, pos.lineNumber, pos.start ) );
-        }
-    }
-    
-    
-    /**
-     * In normal mode :
-     * 
-     * <pre>
-     * descr        ::= keystring
-     * keystring    ::= leadkeychar keychar*
-     * leadkeychar  ::= ALPHA
-     * keychar      ::= ALPHA | DIGIT | HYPHEN
-     * numericoid   ::= number ( DOT number )+ |
-     * number       ::= DIGIT | LDIGIT DIGIT+
-     * ALPHA        ::= %x41-5A | %x61-7A   ; "A"-"Z" / "a"-"z"
-     * DIGIT        ::= %x30 | LDIGIT       ; "0"-"9"
-     * LDIGIT       ::= %x31-39             ; "1"-"9"
-     * DOT          ::= %x2E                ; period (".")
-     * HYPHEN       ::= %x2D                ; hyphen ("-")
-     * </pre>
-     * 
-     * In quirksMode :
-     * 
-     * <pre>
-     * descr        ::= descrQ (COLON numericoid)
-     * descrQ       ::= keystringQ
-     * keystringQ   ::= LkeycharQ keycharQ*
-     * LkeycharQ    ::= ALPHA | HYPHEN | UNDERSCORE | SEMI_COLON | DOT | COLON | SHARP 
-     * keycharQ     ::= ALPHA | DIGIT | HYPHEN | UNDERSCORE | SEMI_COLON | DOT | COLON | SHARP 
-     * numericoid   ::= number ( DOT number )+
-     * number       ::= DIGIT | LDIGIT DIGIT+
-     * ALPHA        ::= %x41-5A | %x61-7A   ; "A"-"Z" / "a"-"z"
-     * DIGIT        ::= %x30 | LDIGIT       ; "0"-"9"
-     * LDIGIT       ::= %x31-39             ; "1"-"9"
-     * HYPHEN       ::= %x2D                ; hyphen ("-")
-     * UNDERSCORE   ::= %x5F                ; underscore ("_")
-     * DOT          ::= %x2E                ; period (".")
-     * COLON        ::= %x3A                ; colon (":")
-     * SEMI_COLON   ::= %x3B                ; semi-colon(";")
-     * SHARP        ::= %x23                ; octothorpe (or sharp sign) ("#")
-     * </pre
-     * @throws IOException 
-     */
-    private String getDescr( Reader reader, PosSchema pos ) throws LdapSchemaException, IOException
-    {
-        if ( isQuirksModeEnabled )
-        {
-            int start = pos.start;
-            boolean isFirst = true;
-            
-            while ( !isEmpty( pos ) )
-            {
-                if ( isFirst )
-                {
-                    isFirst = false;
-                    
-                    char c = pos.line.charAt( pos.start );
-                    
-                    if ( Character.isAlphabetic( c ) || ( c == '-' ) || ( c == '_' )
-                        || ( c == ';' ) || ( c == '.' ) || ( c == ':' ) || ( c == '#' ) ) 
-                    {
-                        // leadkeycharQ
-                        pos.start++;
-                    }
-                    else
-                    {
-                        // Error, we are expecting a leadKeychar
-                        throw new LdapSchemaException( I18n.err( I18n.ERR_13788_LEAD_KEY_CHAR_EXPECTED, 
-                            pos.lineNumber, pos.start ) );
-                    }
-                }
-                else
-                {
-                    char c = pos.line.charAt( pos.start );
-                    
-                    if ( Character.isAlphabetic( c ) || Character.isDigit( c ) || ( c == '-' )
-                        || ( c == '_' ) || ( c == ';' ) || ( c == '.' ) || ( c == ':' ) || ( c == '#' ) ) 
-                    {
-                        pos.start++;
-                    }
-                    else
-                    {
-                        // We are done 
-                        return pos.line.substring( start, pos.start );
-                    }
-                }
-            }
-            
-            return pos.line.substring( start, pos.start );
-        }
-        else
-        {
-            int start = pos.start;
-            boolean isFirst = true;
-            
-            while ( !isEmpty( pos ) )
-            {
-                if ( isFirst )
-                {
-                    isFirst = false;
-                    
-                    if ( isAlpha( pos ) ) 
-                    {
-                        // leadkeychar
-                        pos.start++;
-                    }
-                    else
-                    {
-                        // Error, we are expecting a leadKeychar
-                        throw new LdapSchemaException( I18n.err( I18n.ERR_13788_LEAD_KEY_CHAR_EXPECTED, 
-                            pos.lineNumber, pos.start ) );
-                    }
-                }
-                else
-                {
-                    char c = pos.line.charAt( pos.start );
-                    
-                    if ( Character.isAlphabetic( c ) || Character.isDigit( c ) || ( c == '-' ) )
-                    {
-                        pos.start++;
-                    }
-                    else
-                    {
-                        // We are done 
-                        return pos.line.substring( start, pos.start );
-                    }
-                }
-            }
-
-            return pos.line.substring( start, pos.start );
-        }
-    }
-    
-    
-    private String getMacro( Reader reader, PosSchema pos ) throws LdapSchemaException, IOException
-    {
-        if ( isQuirksModeEnabled )
-        {
-            int start = pos.start;
-            boolean isFirst = true;
-            
-            while ( !isEmpty( pos ) )
-            {
-                if ( isFirst )
-                {
-                    isFirst = false;
-                    
-                    char c = pos.line.charAt( pos.start );
-                    
-                    if ( Character.isAlphabetic( c ) || ( c == '-' ) || ( c == '_' ) 
-                        || ( c == ';' ) || ( c == '.' ) || ( c == '#' ) ) 
-                    {
-                        // leadkeycharQ
-                        pos.start++;
-                    }
-                    else
-                    {
-                        // Error, we are expecting a leadKeychar
-                        throw new LdapSchemaException( I18n.err( I18n.ERR_13788_LEAD_KEY_CHAR_EXPECTED, 
-                            pos.lineNumber, pos.start ) );
-                    }
-                }
-                else
-                {
-                    char c = pos.line.charAt( pos.start );
-                    
-                    if ( Character.isAlphabetic( c ) || Character.isDigit( c ) || ( c == '-' ) 
-                        || ( c == '_' ) || ( c == ';' ) || ( c == '.' ) || ( c == '#' ) ) 
-                    {
-                        pos.start++;
-                    }
-                    else
-                    {
-                        // We are done 
-                        return pos.line.substring( start, pos.start );
-                    }
-                }
-            }
-            
-            return pos.line.substring( start, pos.start );
-        }
-        else
-        {
-            int start = pos.start;
-            boolean isFirst = true;
-            
-            while ( !isEmpty( pos ) )
-            {
-                if ( isFirst )
-                {
-                    isFirst = false;
-                    
-                    if ( isAlpha( pos ) ) 
-                    {
-                        // leadkeychar
-                        pos.start++;
-                    }
-                    else
-                    {
-                        // Error, we are expecting a leadKeychar
-                        throw new LdapSchemaException( I18n.err( I18n.ERR_13788_LEAD_KEY_CHAR_EXPECTED, 
-                            pos.lineNumber, pos.start ) );
-                    }
-                }
-                else
-                {
-                    char c = pos.line.charAt( pos.start );
-                    
-                    if ( Character.isAlphabetic( c ) || Character.isDigit( c ) || ( c == '-' ) )
-                    {
-                        pos.start++;
-                    }
-                    else
-                    {
-                        // We are done 
-                        return pos.line.substring( start, pos.start );
-                    }
-                }
-            }
-
-            return pos.line.substring( start, pos.start );
-        }
-    }
-
-    
-    
-    /**
-     * <pre>
-     * qdescr ::== SQUOTE descr SQUOTE
-     * descr ::= keystring
-     * keystring ::= leadkeychar *keychar
-     * leadkeychar ::= ALPHA
-     * keychar ::= ALPHA | DIGIT | HYPHEN
-     * </pre>
-     * 
-     * In quirksMode :
-     * 
-     * <pre>
-     * qdescr ::== SQUOTE descr SQUOTE | descr | SQUOTE numericoid SQUOTE
-     * descr ::= keystring
-     * keystring ::= keychar+
-     * keychar ::= ALPHA | DIGIT | HYPHEN | UNDERSCORE | SEMI_COLON | DOT | COLON | SHARP 
-     * </pre>
-     * @throws IOException 
-     */
-    private String getQDescr( Reader reader, PosSchema pos ) throws LdapSchemaException, IOException
-    {
-        if ( isQuirksModeEnabled )
-        {
-            if ( startsWith( reader, pos, '\'' ) )
-            {
-                pos.start++;
-                int start = pos.start;
-                
-                while ( !startsWith( reader, pos, '\'' ) )
-                {
-                    if ( isEmpty( pos ) )
-                    {
-                        throw new LdapSchemaException( I18n.err( I18n.ERR_13789_SIMPLE_QUOTE_EXPECTED_AT_START, 
-                            pos.lineNumber, pos.start ) );
-                    }
-                    
-                    char c = pos.line.charAt( pos.start );
-                    
-                    if ( Character.isDigit( c ) || Character.isAlphabetic( c ) || ( c == '-' ) || ( c == '_' )
-                        || ( c == ';' ) || ( c == '.' ) || ( c == ':' ) || ( c == '#' ) )
-                    {
-                        pos.start++;
-                    }
-                    else if ( c != '\'' )
-                    {
-                        throw new LdapSchemaException( I18n.err( I18n.ERR_13790_NOT_A_KEYSTRING, pos.lineNumber, pos.start ) );
-                    }
-                }
-                
-                pos.start++;
-                
-                return pos.line.substring( start, pos.start - 1 );
-            }
-            else
-            {
-                int start = pos.start;
-                while ( !isEmpty( pos ) )
-                {
-                    char c = pos.line.charAt( pos.start );
-
-                    if ( Character.isDigit( c ) || Character.isAlphabetic( c ) || ( c == '-' ) || ( c == '_' )
-                        || ( c == ';' ) || ( c == '.' ) || ( c == ':' ) || ( c == '#' ) )
-                    {
-                        pos.start++;
-                    }
-                    else
-                    {
-                        break;
-                    }
-                }
-
-                return pos.line.substring( start, pos.start );
-            }
-        }
-        else
-        {
-            // The first quote
-            if ( !startsWith( reader, pos, '\'' ) )
-            {
-                throw new LdapSchemaException( I18n.err( I18n.ERR_13789_SIMPLE_QUOTE_EXPECTED_AT_START, 
-                    pos.lineNumber, pos.start ) );
-            }
-            
-            pos.start++;
-            int start = pos.start;
-            boolean isFirst = true;
-            
-            while ( !startsWith( reader, pos, '\'' ) )
-            {
-                if ( isFirst )
-                {
-                    isFirst = false;
-                    
-                    if ( isAlpha( pos ) ) 
-                    {
-                        // leadkeychar
-                        pos.start++;
-                    }
-                    else
-                    {
-                        // Error, we are expecting a leadKeychar
-                        throw new LdapSchemaException( I18n.err( I18n.ERR_13788_LEAD_KEY_CHAR_EXPECTED, 
-                            pos.lineNumber, pos.start ) );
-                    }
-                }
-                else
-                {
-                    char c = pos.line.charAt( pos.start );
-                    
-                    if ( Character.isAlphabetic( c ) || Character.isDigit( c ) || ( c == '-' ) )
-                    {
-                        pos.start++;
-                    }
-                    else
-                    {
-                        // This is an error
-                        throw new LdapSchemaException( I18n.err( I18n.ERR_13791_KEYCHAR_EXPECTED, c, 
-                            pos.lineNumber, pos.start ) );
-                    }
-                }
-            }
-            
-            if ( startsWith( reader, pos, '\'' ) )
-            {
-                // We are done, move one char forward to eliminate the simple quote
-                pos.start++;
-                
-                return pos.line.substring( start, pos.start - 1 );
-            }
-            else
-            {
-                // No closing simple quote, this is an error
-                throw new LdapSchemaException( I18n.err( I18n.ERR_13792_SIMPLE_QUOTE_EXPECTED_AT_END, 
-                    pos.lineNumber, pos.start ) );
-            }
-        }
-    }
-    
-    
-    /**
-     * <pre>
-     * qdstring ::== SQUOTE dstring SQUOTE
-     * dstring  ::= ( QS | QQ | QUTF8 )+            ; escaped UTF-8 string
-     * QS       ::= ESC %x35 ( %x43 | %x63 )        ; "\5C" | "\5c", escape char
-     * QQ       ::= ESC %x32 %x37                   ; "\27", simple quote char
-     * QUTF8    ::= QUTF1 | UTFMB
-     * QUTF1    ::= %x00-26 | %x28-5B | %x5D-7F     ; All ascii but ' and \
-     * UTFMB    ::= UTF2 | UTF3 | UTF4
-     * UTF0     ::= %x80-BF
-     * UTF2     ::= %xC2-DF UTF0
-     * UTF3     ::= %xE0 %xA0-BF UTF0 | %xE1-EC UTF0 UTF0 | %xED %x80-9F UTF0 | %xEE-EF UTF0 UTF0
-     * UTF4     ::= %xF0 %x90-BF UTF0 UTF0 | %xF1-F3 UTF0 UTF0 UTF0 | %xF4 %x80-8F UTF0 UTF0
-     * ESC      ::= %x5C                            ; backslash ("\")
-     * </pre>
-     */
-    private String getQDString( Reader reader, PosSchema pos ) throws LdapSchemaException, IOException
-    {
-        // The first quote
-        if ( !startsWith( reader, pos, '\'' ) )
-        {
-            throw new LdapSchemaException( I18n.err( I18n.ERR_13789_SIMPLE_QUOTE_EXPECTED_AT_START, 
-                pos.lineNumber, pos.start ) );
-        }
-        
-        pos.start++;
-        int start = pos.start;
-        
-        while ( !startsWith( reader, pos, '\'', QUOTED ) )
-        {
-            // At the moment, just swallow anything
-            pos.start++;
-        }
-        
-        if ( startsWith( reader, pos, '\'' ) )
-        {
-            // We are done, move one char forward to eliminate the simple quote
-            pos.start++;
-            
-            return pos.line.substring( start, pos.start - 1 );
-        }
-        else
-        {
-            // No closing simple quote, this is an error
-            throw new LdapSchemaException( I18n.err( I18n.ERR_13792_SIMPLE_QUOTE_EXPECTED_AT_END, 
-                pos.lineNumber, pos.start ) );
-        }
-    }
-
-
-    /**
-     * qdescrs ::= qdescr | LPAREN WSP qdescrlist WSP RPAREN
-     * qdescrlist ::= [ qdescr *( SP qdescr ) ]
-     * qdescr ::== SQUOTE descr SQUOTE
-     * descr ::= keystring
-     * keystring ::= leadkeychar *keychar
-     * leadkeychar ::= ALPHA
-     * keychar ::= ALPHA / DIGIT / HYPHEN
-     * @throws LdapSchemaException 
-     * @throws IOException 
-     */
-    private List<String> getQDescrs( Reader reader, PosSchema pos ) throws LdapSchemaException, IOException
-    {
-        List<String> qdescrs = new ArrayList<>();
-        
-        // It may start with a '('
-        if ( startsWith( reader, pos, '(' ) )
-        {
-            pos.start++;
-            
-            // We have more than a name
-            skipWhites( reader, pos, false );
-            
-            while ( !startsWith( reader, pos, ')' ) )
-            {
-                qdescrs.add( getQDescr( reader, pos ) );
-                
-                if ( startsWith( reader, pos, ')' ) )
-                {
-                    break;
-                }
-                
-                skipWhites( reader, pos, true );
-            }
-            
-            if ( !startsWith( reader, pos, ')' ) )
-            {
-                throw new LdapSchemaException( I18n.err( I18n.ERR_13793_NO_CLOSING_PAREN, 
-                    pos.lineNumber, pos.start ) );
-            }
-            
-            pos.start++;
-        }
-        else
-        {
-            // Only one name, read it
-            qdescrs.add( getQDescr( reader, pos ) );
-        }
-        
-        return qdescrs;
-    }
-
-
-    /**
-     * <pre>
-     * qdstrings    ::= qdstring | ( LPAREN WSP qdstringlist WSP RPAREN )
-     * qdstringlist ::= qdstring *( SP qdstring )*
-     * qdstring     ::= SQUOTE dstring SQUOTE
-     * dstring      ::= 1*( QS / QQ / QUTF8 )   ; escaped UTF-8 string
-     * </pre>
-     * @throws LdapSchemaException 
-     * @throws IOException 
-     */
-    private List<String> getQDStrings( Reader reader, PosSchema pos ) throws LdapSchemaException, IOException
-    {
-        List<String> qdStrings = new ArrayList<>();
-        
-        // It may start with a '('
-        if ( startsWith( reader, pos, '(' ) )
-        {
-            pos.start++;
-            
-            // We have more than a name
-            skipWhites( reader, pos, false );
-            
-            while ( !startsWith( reader, pos, ')' ) )
-            {
-                qdStrings.add( getQDString( reader, pos ) );
-                
-                if ( startsWith( reader, pos, ')' ) )
-                {
-                    break;
-                }
-                
-                skipWhites( reader, pos, true );
-            }
-            
-            if ( !startsWith( reader, pos, ')' ) )
-            {
-                throw new LdapSchemaException( I18n.err( I18n.ERR_13793_NO_CLOSING_PAREN, 
-                    pos.lineNumber, pos.start ) );
-            }
-            
-            pos.start++;
-        }
-        else
-        {
-            // Only one name, read it
-            qdStrings.add( getQDString( reader, pos ) );
-        }
-        
-        return qdStrings;
-    }
-
-    
-
-    
-    /**
-     * <pre>
-     * oids     ::= oid | ( LPAREN WSP oidlist WSP RPAREN )
-     * oidlist  ::= oid *( WSP DOLLAR WSP oid )
-     * </pre>
-     */
-    private List<String> getOids( Reader reader, PosSchema pos ) throws LdapSchemaException, IOException
-    {
-        List<String> oids = new ArrayList<>();
-        
-        // It may start with a '('
-        if ( startsWith( reader, pos, '(' ) )
-        {
-            pos.start++;
-            
-            // We have more than a name
-            skipWhites( reader, pos, false );
-            boolean moreExpected = false;
-            
-            while ( !startsWith( reader, pos, ')' ) )
-            {
-                moreExpected = false;
-                
-                oids.add( getOid( reader, pos ) );
-                
-                if ( startsWith( reader, pos, ')' ) )
-                {
-                    break;
-                }
-                
-                skipWhites( reader, pos, false );
-                
-                if ( startsWith( reader, pos, '$' ) )
-                {
-                    pos.start++;
-                    moreExpected = true;
-                }
-
-                skipWhites( reader, pos, false );
-            }
-            
-            if ( !startsWith( reader, pos, ')' ) )
-            {
-                throw new LdapSchemaException( I18n.err( I18n.ERR_13793_NO_CLOSING_PAREN, 
-                    pos.lineNumber, pos.start ) );
-            }
-            
-            if ( moreExpected )
-            {
-                throw new LdapSchemaException( I18n.err( I18n.ERR_13794_MORE_OIDS_EXPECTED, 
-                    pos.lineNumber, pos.start ) );
-            }
-            
-            pos.start++;
-        }
-        else
-        {
-            // Only one name, read it
-            oids.add( getOid( reader, pos ) );
-        }
-        
-        return oids;
-    }
-
-    
-    /**
-     * noidlen = numericoid [ LCURLY len RCURLY ]
-     */
-    private NoidLen getNoidLen( Reader reader, PosSchema pos ) throws LdapSchemaException, IOException
-    {
-        // Get the numericOid
-        String numericOid = getNumericOid( reader, pos );
-        NoidLen noidLen = new NoidLen();
-        noidLen.noid = numericOid;
-
-        // Then the len, if any
-        if ( startsWith( reader, pos, '{' ) )
-        {
-            pos.start++;
-            int start = pos.start;
-            
-            while ( isDigit( pos ) )
-            {
-                pos.start++;
-            }
-            
-            if ( startsWith( reader, pos, '}' ) )
-            {
-                String lenStr = pos.line.substring( start, pos.start );
-                
-                pos.start++;
-                
-                if ( Strings.isEmpty( lenStr ) )
-                {
-                    noidLen.len = -1;
-                }
-                else
-                {
-                    noidLen.len = Integer.parseInt( lenStr );
-                }
-            }
-            else
-            {
-                // The opening curly hasn't been closed
-                throw new LdapSchemaException( I18n.err( I18n.ERR_13795_OPENED_BRACKET_NOT_CLOSED, 
-                    pos.lineNumber, pos.start ) );
-            }
-        }
-
-        return noidLen;
-    }
-    
-    
-    private UsageEnum getUsage( Reader reader, PosSchema pos ) throws LdapSchemaException
-    {
-        if ( isEmpty( pos ) )
-        {
-            throw new LdapSchemaException( I18n.err( I18n.ERR_13796_USAGE_EXPECTED, 
-                pos.lineNumber, pos.start ) );
-        }
-        
-        if ( startsWith( pos, "userApplications" ) )
-        { 
-            return UsageEnum.USER_APPLICATIONS;
-        }
-        else if ( startsWith( pos, "directoryOperation" ) )
-        { 
-            return UsageEnum.DIRECTORY_OPERATION;
-        } 
-        else if ( startsWith( pos, "distributedOperation" ) )
-        { 
-            return UsageEnum.DISTRIBUTED_OPERATION;
-        } 
-        else if ( startsWith( pos, "dSAOperation" ) )
-        { 
-            return UsageEnum.DSA_OPERATION;
-        } 
-        else
-        {
-            throw new LdapSchemaException( I18n.err( I18n.ERR_13797_USAGE_UNKNOWN, 
-                pos.lineNumber, pos.start ) );
-        }
-    }
-
-    
-    /**
-     * Production for matching attribute type descriptions. It is fault-tolerant
-     * against element ordering.
-     *
-     * <pre>
-     * AttributeTypeDescription = LPAREN WSP
-     *     numericoid                    ; object identifier
-     *     [ SP "NAME" SP qdescrs ]      ; short names (descriptors)
-     *     [ SP "DESC" SP qdstring ]     ; description
-     *     [ SP "OBSOLETE" ]             ; not active
-     *     [ SP "SUP" SP oid ]           ; supertype
-     *     [ SP "EQUALITY" SP oid ]      ; equality matching rule
-     *     [ SP "ORDERING" SP oid ]      ; ordering matching rule
-     *     [ SP "SUBSTR" SP oid ]        ; substrings matching rule
-     *     [ SP "SYNTAX" SP noidlen ]    ; value syntax
-     *     [ SP "SINGLE-VALUE" ]         ; single-value
-     *     [ SP "COLLECTIVE" ]           ; collective
-     *     [ SP "NO-USER-MODIFICATION" ] ; not user modifiable
-     *     [ SP "USAGE" SP usage ]       ; usage
-     *     extensions WSP RPAREN         ; extensions
-     * 
-     * usage = "userApplications"     /  ; user
-     *         "directoryOperation"   /  ; directory operational
-     *         "distributedOperation" /  ; DSA-shared operational
-     *         "dSAOperation"            ; DSA-specific operational     
-     * 
-     * extensions = *( SP xstring SP qdstrings )
-     * xstring = "X" HYPHEN 1*( ALPHA / HYPHEN / USCORE ) 
-     * </pre>
-     * @throws IOException 
-     * @throws LdapSchemaException 
-     */
-    private MutableAttributeType parseAttributeType( Reader reader, PosSchema pos ) throws IOException, LdapSchemaException
-    {
-        // Get rid of whites, comments end empty lines
-        skipWhites( reader, pos, false );
-        
-        // we must have a '('
-        if ( pos.line.charAt( pos.start ) != '(' )
-        {
-            return null;
-        }
-        else
-        {
-            pos.start++;
-        }
-        
-        // Get rid of whites, comments end empty lines
-        skipWhites( reader, pos, false );
-        
-        // Now, the OID. 
-        String oid = getOidAndMacro( reader, pos );
-        
-        MutableAttributeType attributeType = new MutableAttributeType( oid );
-        boolean hasSup = false;
-        boolean hasSyntax = false;
-        int elementsSeen = 0;
-        
-        while ( !startsWith( reader, pos, ')' ) )
-        {
-            skipWhites( reader, pos, true );
-
-            if ( startsWith( pos, "NAME" ) )
-            {
-                elementsSeen = check( elementsSeen, AttributeTypeElements.NAME, pos );
-                
-                pos.start += "NAME".length();
-                
-                skipWhites( reader, pos, true );
-
-                attributeType.setNames( getQDescrs( reader, pos ) );
-            }
-            else if ( startsWith( pos, "DESC" ) )
-            {
-                elementsSeen = check( elementsSeen, AttributeTypeElements.DESC, pos );
-
-                pos.start += "DESC".length();
-                
-                skipWhites( reader, pos, true );
-
-                attributeType.setDescription( getQDString( reader, pos ) );
-            }
-            else if ( startsWith( pos, "OBSOLETE" ) )
-            {
-                elementsSeen = check( elementsSeen, AttributeTypeElements.OBSOLETE, pos );
-                
-                pos.start += "OBSOLETE".length();
-                
-                attributeType.setObsolete( true );
-            }
-            else if ( startsWith( pos, "SUP" ) )
-            {
-                elementsSeen = check( elementsSeen, AttributeTypeElements.SUP, pos );
-                
-                pos.start += "SUP".length();
-                
-                skipWhites( reader, pos, true );
-                
-                String superiorOid = getOid( reader, pos );
-
-                attributeType.setSuperiorOid( superiorOid );
-                hasSup = true;
-            }
-            else if ( startsWith( pos, "EQUALITY" ) )
-            {
-                elementsSeen = check( elementsSeen, AttributeTypeElements.EQUALITY, pos );
-                
-                pos.start += "EQUALITY".length();
-                
-                skipWhites( reader, pos, true );
-                
-                String equalityOid = getOid( reader, pos );
-
-                attributeType.setEqualityOid( equalityOid );
-            }
-            else if ( startsWith( pos, "ORDERING" ) )
-            {
-                elementsSeen = check( elementsSeen, AttributeTypeElements.ORDERING, pos );
-                
-                pos.start += "ORDERING".length();
-                
-                skipWhites( reader, pos, true );
-                
-                String orderingOid = getOid( reader, pos );
-
-                attributeType.setOrderingOid( orderingOid );
-            }
-            else if ( startsWith( pos, "SUBSTR" ) )
-            {
-                elementsSeen = check( elementsSeen, AttributeTypeElements.SUBSTR, pos );
-
-                pos.start += "SUBSTR".length();
-                
-                skipWhites( reader, pos, true );
-                
-                String substrOid = getOid( reader, pos );
-
-                attributeType.setSubstringOid( substrOid );
-            }
-            else if ( startsWith( pos, "SYNTAX" ) )
-            {
-                elementsSeen = check( elementsSeen, AttributeTypeElements.SYNTAX, pos );
-                
-                pos.start += "SYNTAX".length();
-                
-                skipWhites( reader, pos, true );
-                
-                NoidLen noidLen = getNoidLen( reader, pos );
-
-                attributeType.setSyntaxOid( noidLen.noid );
-                attributeType.setSyntaxLength( noidLen.len );
-                hasSyntax = true;
-            }
-            else if ( startsWith( pos, "SINGLE-VALUE" ) )
-            {
-                elementsSeen = check( elementsSeen, AttributeTypeElements.SINGLE_VALUE, pos );
-                
-                pos.start += "SINGLE-VALUE".length();
-                
-                attributeType.setSingleValued( true );
-            }
-            else if ( startsWith( pos, "COLLECTIVE" ) )
-            {
-                elementsSeen = check( elementsSeen, AttributeTypeElements.COLLECTIVE, pos );
-                
-                pos.start += "COLLECTIVE".length();
-                
-                attributeType.setCollective( true );
-            }
-            else if ( startsWith( pos, "NO-USER-MODIFICATION\"" ) )
-            {
-                elementsSeen = check( elementsSeen, AttributeTypeElements.NO_USER_MODIFICATION, pos );
-                
-                pos.start += "NO-USER-MODIFICATION\"".length();
-                
-                attributeType.setUserModifiable( false );
-            }
-            else if ( startsWith( pos, "USAGE" ) )
-            {
-                elementsSeen = check( elementsSeen, AttributeTypeElements.USAGE, pos );
-                
-                pos.start += "USAGE".length();
-                
-                skipWhites( reader, pos, true );
-                
-                UsageEnum usage = getUsage( reader, pos );
-
-                attributeType.setUsage( usage );
-            }
-            else if ( startsWith( pos, "X-" ) )
-            {
-                Extension extension = getExtension( reader, pos );
-                attributeType.addExtension( extension.key, extension.values );
-            }
-            else if ( startsWith( reader, pos, ')' ) )
-            {
-                pos.start++;
-                
-                return attributeType;
-            }
-            else
-            {
-                // This is an error
-                throw new LdapSchemaException( I18n.err( I18n.ERR_13798_AT_DESCRIPTION_INVALID, 
-                    pos.lineNumber, pos.start ) );
-            }
-        }
-        
-        if ( startsWith( reader, pos, ')' ) )
-        {
-            pos.start++;
-            
-            // Semantic checks
-            if ( !isQuirksModeEnabled )
-            {
-                if ( !hasSup && !hasSyntax )
-                {
-                    throw new LdapSchemaException( I18n.err( I18n.ERR_13799_SYNTAX_OR_SUP_REQUIRED, 
-                        pos.lineNumber, pos.start ) );
-                }
-
-                if ( attributeType.isCollective() && ( attributeType.getUsage() != UsageEnum.USER_APPLICATIONS ) )
-                {
-                    throw new LdapSchemaException( I18n.err( I18n.ERR_13800_COLLECTIVE_REQUIRES_USER_APPLICATION, 
-                        pos.lineNumber, pos.start ) );
-                }
-            
-                // NO-USER-MODIFICATION requires an operational USAGE.
-                if ( !attributeType.isUserModifiable() && ( attributeType.getUsage() == UsageEnum.USER_APPLICATIONS ) )
-                {
-                    throw new LdapSchemaException( I18n.err( I18n.ERR_13801_NO_USER_MOD_REQUIRE_OPERATIONAL, 
-                        pos.lineNumber, pos.start ) );
-                }
-            }
-            
-            return attributeType;
-        }
-        
-        throw new LdapSchemaException( I18n.err( I18n.ERR_13798_AT_DESCRIPTION_INVALID, 
-            pos.lineNumber, pos.start ) );
-    }
-    
-    
-    private int check( int elementsSeen, AttributeTypeElements element, PosSchema pos ) throws LdapSchemaException
-    {
-        if ( ( elementsSeen & element.value ) != 0 )
-        {
-            throw new LdapSchemaException( I18n.err( I18n.ERR_13780_AT_DESCRIPTION_HAS_ELEMENT_TWICE, element, pos.lineNumber, pos.start ) );
-        }
-        
-        elementsSeen |= element.value;
-        
-        return elementsSeen;
-    }
-    
-    
-    /**
-     * <pre>
-     * extension    ::= xstring SP qdstrings
-     * xstring      ::= "X" HYPHEN ( ALPHA | HYPHEN | USCORE )+
-     * qdstrings    ::= qdstring | ( LPAREN WSP qdstringlist WSP RPAREN )
-     * qdstringlist ::= qdstring *( SP qdstring )*
-     * qdstring     ::= SQUOTE dstring SQUOTE
-     * dstring      ::= 1*( QS / QQ / QUTF8 )   ; escaped UTF-8 string
-     * </pre>
-     * @throws IOException 
-     * @throws LdapSchemaException 
-     */
-    private Extension getExtension( Reader reader, PosSchema pos ) throws LdapSchemaException, IOException
-    {
-        Extension extension = new Extension();
-        
-        // The xstring first
-        extension.key = getXString( reader, pos );
-        
-        skipWhites( reader, pos, true );
-        
-        extension.values = getQDStrings( reader, pos );
-        
-        return extension;
-    }
-    
-    
-    /**
-     * <pre>
-     * xstring      ::= "X" HYPHEN ( ALPHA | HYPHEN | USCORE )+
-     * </pre>
-     */
-    private String getXString( Reader reader, PosSchema pos ) throws LdapSchemaException, IOException
-    {
-        int start = pos.start;
-        
-        if ( startsWith( pos, "X-" ) )
-        {
-            pos.start += 2;
-            
-            // Now parse the remaining string
-            while ( isAlpha( pos ) || startsWith( reader, pos, '-' ) || startsWith( reader, pos, '_' ) )
-            {
-                pos.start++;
-            }
-            
-            return pos.line.substring( start, pos.start );
-        }
-        else
-        {
-            throw new LdapSchemaException( I18n.err( I18n.ERR_13802_EXTENSION_SHOULD_START_WITH_X, 
-                pos.lineNumber, pos.start ) );
-        }
-    }
-    
-    
-    /**
-     * Production for matching ObjectClass descriptions. It is fault-tolerant
-     * against element ordering.
-     * <pre>
-     * ObjectClassDescription = LPAREN WSP
-     *   numericoid                 ; object identifier
-     *   [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
-     *   [ SP "DESC" SP qdstring ]  ; description
-     *   [ SP "OBSOLETE" ]          ; not active
-     *   [ SP "SUP" SP oids ]       ; superior object classes
-     *   [ SP kind ]                ; kind of class
-     *   [ SP "MUST" SP oids ]      ; attribute types
-     *   [ SP "MAY" SP oids ]       ; attribute types
-     *   extensions WSP RPAREN
-     *
-     *   kind = "ABSTRACT" / "STRUCTURAL" / "AUXILIARY"
-     * </pre>
-     */
-    private MutableObjectClass parseObjectClass( Reader reader, PosSchema pos ) throws IOException, LdapSchemaException
-    {
-        // Get rid of whites, comments end empty lines
-        skipWhites( reader, pos, false );
-        
-        // we must have a '('
-        if ( pos.line.charAt( pos.start ) != '(' )
-        {
-            return null;
-        }
-        else
-        {
-            pos.start++;
-        }
-        
-        // Get rid of whites, comments end empty lines
-        skipWhites( reader, pos, false );
-        
-        // Now, the numeric OID
-        String oid = getOid( reader, pos );
-        
-        MutableObjectClass objectClass = new MutableObjectClass( oid );
-        int elementsSeen = 0;
-        
-        while ( !startsWith( reader, pos, ')' ) )
-        {
-            skipWhites( reader, pos, true );
-
-            if ( startsWith( pos, "NAME" ) )
-            {
-                elementsSeen = check( elementsSeen, ObjectClassElements.NAME, pos );
-
-                pos.start += "NAME".length();
-                
-                skipWhites( reader, pos, true );
-
-                List<String> names = getQDescrs( reader, pos );
-                objectClass.setNames( names );
-            }
-            else if ( startsWith( pos, "DESC" ) )
-            {
-                elementsSeen = check( elementsSeen, ObjectClassElements.DESC, pos );
-                
-                pos.start += "DESC".length();
-                
-                skipWhites( reader, pos, true );
-
-                objectClass.setDescription( getQDString( reader, pos ) );
-            }
-            else if ( startsWith( pos, "OBSOLETE" ) )
-            {
-                elementsSeen = check( elementsSeen, ObjectClassElements.OBSOLETE, pos );
-                
-                pos.start += "OBSOLETE".length();
-                
-                objectClass.setObsolete( true );
-            }
-            else if ( startsWith( pos, "SUP" ) )
-            {
-                elementsSeen = check( elementsSeen, ObjectClassElements.SUP, pos );
-                
-                pos.start += "SUP".length();
-                
-                skipWhites( reader, pos, true );
-                
-                List<String> superiorOids = getOids( reader, pos );
-
-                objectClass.setSuperiorOids( superiorOids );
-            }
-            else if ( startsWith( pos, "ABSTRACT" ) )
-            {
-                elementsSeen = check( elementsSeen, ObjectClassElements.ABSTRACT, pos );
-                
-                pos.start += "ABSTRACT".length();
-                
-                objectClass.setType( ObjectClassTypeEnum.ABSTRACT );
-            }
-            else if ( startsWith( pos, "STRUCTURAL" ) )
-            {
-                elementsSeen = check( elementsSeen, ObjectClassElements.STRUCTURAL, pos );
-                
-                pos.start += "STRUCTURAL".length();
-                
-                objectClass.setType( ObjectClassTypeEnum.STRUCTURAL );
-            }
-            else if ( startsWith( pos, "AUXILIARY" ) )
-            {
-                elementsSeen = check( elementsSeen, ObjectClassElements.AUXILIARY, pos );
-                
-                pos.start += "AUXILIARY".length();
-                
-                objectClass.setType( ObjectClassTypeEnum.AUXILIARY );
-            }
-            else if ( startsWith( pos, "MUST" ) )
-            {
-                elementsSeen = check( elementsSeen, ObjectClassElements.MUST, pos );
-                
-                pos.start += "MUST".length();
-                
-                skipWhites( reader, pos, true );
-                
-                List<String> mustAttributeTypes = getOids( reader, pos );
-                objectClass.setMustAttributeTypeOids( mustAttributeTypes );
-            }
-            else if ( startsWith( pos, "MAY" ) )
-            {
-                elementsSeen = check( elementsSeen, ObjectClassElements.MAY, pos );
-                
-                pos.start += "MAY".length();
-                
-                skipWhites( reader, pos, true );
-                
-                List<String> mayAttributeTypes = getOids( reader, pos );
-                objectClass.setMayAttributeTypeOids( mayAttributeTypes );
-            }
-            else if ( startsWith( pos, "X-" ) )
-            {
-                Extension extension = getExtension( reader, pos );
-                objectClass.addExtension( extension.key, extension.values );
-            }
-            else if ( startsWith( reader, pos, ')' ) )
-            {
-                pos.start++;
-                
-                return objectClass;
-            }
-            else
-            {
-                // This is an error
-                throw new LdapSchemaException( I18n.err( I18n.ERR_13803_OC_DESCRIPTION_INVALID, 
-                    pos.lineNumber, pos.start ) );
-            }
-        }
-        
-        return objectClass;
-    }
-    
-    
-    private int check( int elementsSeen, ObjectClassElements element, PosSchema pos ) throws LdapSchemaException
-    {
-        if ( ( elementsSeen & element.value ) != 0 )
-        {
-            throw new LdapSchemaException( I18n.err( I18n.ERR_13781_OC_DESCRIPTION_HAS_ELEMENT_TWICE, element, pos.lineNumber, pos.start ) );
-        }
-        
-        elementsSeen |= element.value;
-        
-        return elementsSeen;
-    }
-
-    
-    /**
-     * Process OpenLDAP macros, like : objectidentifier DUAConfSchemaOID 1.3.6.1.4.1.11.1.3.1.
-     * 
-     * <pre>
-     * objectidentifier ::= 'objectidentifier' descr SP+ macroOid
-     * descr             ::= ALPHA ( ALPHA | DIGIT | HYPHEN )*
-     * macroOid         ::= (descr ':')? oid
-     * </pre>
-     */
-    private void processObjectIdentifier( Reader reader, PosSchema pos ) throws IOException, LdapSchemaException
-    {
-        // Get rid of whites, comments end empty lines
-        skipWhites( reader, pos, false );
-        
-        // Now, the name
-        String name = getDescr( reader, pos );
-        
-        OpenLdapObjectIdentifierMacro macro = new OpenLdapObjectIdentifierMacro();
-        
-        skipWhites( reader, pos, true );
-
-        if ( isEmpty( pos ) )
-        {
-            throw new LdapSchemaException( I18n.err( I18n.ERR_13804_OBJECT_IDENTIFIER_HAS_NO_OID, 
-                pos.lineNumber, pos.start ) );
-        }
-        
-        // Get the descr, if any
-        if ( isAlpha( pos ) )
-        {
-            // A macro
-            String descr = getMacro( reader, pos );
-            
-            if ( isEmpty( pos ) )
-            {
-                throw new LdapSchemaException( I18n.err( I18n.ERR_13804_OBJECT_IDENTIFIER_HAS_NO_OID, 
-                    pos.lineNumber, pos.start ) );
-            }
-            
-            if ( startsWith( reader, pos, ':' ) )
-            {
-                pos.start++;
-                
-                // Now, the OID
-                String numericOid = getNumericOid( reader, pos );
-                String realOid = objectIdentifierMacros.get( descr ).getRawOidOrNameSuffix() + '.' + numericOid;
-                macro.setName( name );
-                macro.setRawOidOrNameSuffix( realOid );
-                
-                objectIdentifierMacros.put( name, macro );
-                
-                return;
-            }
-        }
-        else if ( isDigit( pos ) )
-        {
-            // An oid
-            String numericOid = getNumericOid( reader, pos );
-            macro.setRawOidOrNameSuffix( numericOid );
-            macro.setName( name );
-            
-            objectIdentifierMacros.put( name, macro );
-            
-            return;
-        }
-        else
-        {
-            throw new LdapSchemaException( I18n.err( I18n.ERR_13805_OBJECT_IDENTIFIER_INVALID_OID, 
-                pos.lineNumber, pos.start ) );
-        }
-    }
-    
-    
-    /**
-     * Reads an entry in a ldif buffer, and returns the resulting lines, without
-     * comments, and unfolded.
-     *
-     * The lines represent *one* entry.
-     *
-     * @throws LdapLdifException If something went wrong
-     */
-    private void parse( Reader reader ) throws LdapSchemaException, IOException
-    {
-        PosSchema pos = new PosSchema();
-
-        while ( true )
-        {
-            // Always move forward to the next element, skipping whites, NL and comments
-            skipWhites( reader, pos, false );
-            
-            if ( pos.line == null )
-            {
-                // The end, get out
-                break;
-            }
-            
-            // Ok, we have something which must be one of openLdapObjectIdentifier( "objectidentifier" ), 
-            // openLdapAttributeType ( "attributetype" )  or openLdapObjectClass ( "objectclass" )
-            if ( startsWith( pos, "objectidentifier" ) )
-            {
-                pos.start += "objectidentifier".length();
-                
-                processObjectIdentifier( reader, pos );
-            }
-            else if ( startsWith( pos, "attributetype" ) )
-            {
-                pos.start += "attributetype".length();
-                
-                MutableAttributeType attributeType = parseAttributeType( reader, pos );
-                schemaDescriptions.add( attributeType );
-            }
-            else if ( startsWith( pos, "objectclass" ) )
-            {
-                pos.start += "objectclass".length();
-                
-                MutableObjectClass objectClass = parseObjectClass( reader, pos );
-                schemaDescriptions.add( objectClass );
-            }
-            else
-            {
-                // This is an error
-                throw new LdapSchemaException( I18n.err( I18n.ERR_13806_UNEXPECTED_ELEMENT_READ, 
-                    pos.line.substring( pos.start ), pos.lineNumber, pos.start ) );
-            }
-        }
-    }
-
-
-    /**
-     * Parses a file of OpenLDAP schemaObject elements/objects. Default charset is used.
-     *
-     * @param schemaFile a file of schema objects
-     * @throws IOException If the schemaObject can't be transformed to a byteArrayInputStream
-     * @throws ParseException If the schemaObject can't be parsed
-     */
-    public void parse( File schemaFile ) throws ParseException
-    {
-        try ( InputStream is = Files.newInputStream( Paths.get( schemaFile.getPath() ) ) )
-        {
-            try ( Reader reader = new BufferedReader( new InputStreamReader( is, Charset.defaultCharset() ) ) )
-            {
-                parse( reader );
-                afterParse();
-            }
-            catch ( LdapSchemaException | IOException e )
-            {
-                throw new ParseException( e.getMessage(), 0 );
-            }
-        }
-        catch ( IOException e )
-        {
-            String msg = I18n.err( I18n.ERR_13443_CANNOT_FIND_FILE, schemaFile.getAbsoluteFile() );
-            LOG.error( msg );
-            throw new ParseException( e.getMessage(), 0 );
-        }
-    }
-
-
-    /**
-     * Checks if object identifier macros should be resolved.
-     * 
-     * @return true, object identifier macros should be resolved.
-     */
-    public boolean isResolveObjectIdentifierMacros()
-    {
-        return isResolveObjectIdentifierMacros;
-    }
-
-
-    /**
-     * Sets if object identifier macros should be resolved.
-     * 
-     * @param resolveObjectIdentifierMacros true if object identifier macros should be resolved
-     */
-    public void setResolveObjectIdentifierMacros( boolean resolveObjectIdentifierMacros )
-    {
-        this.isResolveObjectIdentifierMacros = resolveObjectIdentifierMacros;
-    }
-
-    /**
-     * Checks if quirks mode is enabled.
-     * 
-     * @return true, if is quirks mode is enabled
-     */
-    public boolean isQuirksMode()
-    {
-        return isQuirksModeEnabled;
-    }
-
-
-    /**
-     * Sets the quirks mode. 
-     * 
-     * If enabled the parser accepts non-numeric OIDs and some 
-     * special characters in descriptions.
-     * 
-     * @param enabled the new quirks mode
-     */
-    public void setQuirksMode( boolean enabled )
-    {
-        isQuirksModeEnabled = enabled;
-    }
-}
\ No newline at end of file
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/LdapComparatorDescriptionSchemaParser.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/LdapComparatorDescriptionSchemaParser.java
index 0539944..5d17b0a 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/LdapComparatorDescriptionSchemaParser.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/LdapComparatorDescriptionSchemaParser.java
@@ -24,9 +24,6 @@ import java.text.ParseException;
 
 import org.apache.directory.api.i18n.I18n;
 
-import antlr.RecognitionException;
-import antlr.TokenStreamException;
-
 
 /**
  * A parser for ApacheDS comparator descriptions.
@@ -69,19 +66,15 @@ public class LdapComparatorDescriptionSchemaParser extends AbstractSchemaParser<
      * @return the parsed ComparatorDescription bean
      * @throws ParseException if there are any recognition errors (bad syntax)
      */
-    public LdapComparatorDescription parseComparatorDescription( String comparatorDescription ) throws ParseException
+    public LdapComparatorDescription parse( String comparatorDescription ) throws ParseException
     {
-        return super.parse( comparatorDescription );
-    }
+        LdapComparatorDescription comparator = fastParser.parseLdapComparator( comparatorDescription );
+        comparator.setSpecification( comparatorDescription );
 
+        
+        // Update the schemaName
+        updateSchemaName( comparator );
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected LdapComparatorDescription doParse() throws RecognitionException, TokenStreamException
-    {
-        return parser.ldapComparator();
+        return comparator;
     }
-
 }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/LdapSyntaxDescriptionSchemaParser.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/LdapSyntaxDescriptionSchemaParser.java
index caf1d73..2163369 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/LdapSyntaxDescriptionSchemaParser.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/LdapSyntaxDescriptionSchemaParser.java
@@ -25,9 +25,6 @@ import java.text.ParseException;
 import org.apache.directory.api.i18n.I18n;
 import org.apache.directory.api.ldap.model.schema.LdapSyntax;
 
-import antlr.RecognitionException;
-import antlr.TokenStreamException;
-
 
 /**
  * A parser for RFC 4512 LDAP syntx descriptions.
@@ -60,18 +57,14 @@ public class LdapSyntaxDescriptionSchemaParser extends AbstractSchemaParser<Ldap
      * @return the parsed LdapSyntax bean
      * @throws ParseException if there are any recognition errors (bad syntax)
      */
-    public LdapSyntax parseLdapSyntaxDescription( String ldapSyntaxDescription ) throws ParseException
+    public LdapSyntax parse( String ldapSyntaxDescription ) throws ParseException
     {
-        return super.parse( ldapSyntaxDescription );
-    }
+        LdapSyntax ldapSyntax = fastParser.parseLdapSyntax( ldapSyntaxDescription );
+        ldapSyntax.setSpecification( ldapSyntaxDescription );
 
+        // Update the schemaName
+        updateSchemaName( ldapSyntax );
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected LdapSyntax doParse() throws RecognitionException, TokenStreamException
-    {
-        return parser.ldapSyntaxDescription();
+        return ldapSyntax;
     }
 }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/MatchingRuleDescriptionSchemaParser.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/MatchingRuleDescriptionSchemaParser.java
index 103fe2b..6ecc3a7 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/MatchingRuleDescriptionSchemaParser.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/MatchingRuleDescriptionSchemaParser.java
@@ -25,9 +25,6 @@ import java.text.ParseException;
 import org.apache.directory.api.i18n.I18n;
 import org.apache.directory.api.ldap.model.schema.MatchingRule;
 
-import antlr.RecognitionException;
-import antlr.TokenStreamException;
-
 
 /**
  * A parser for RFC 4512 matching rule descriptions.
@@ -65,19 +62,14 @@ public class MatchingRuleDescriptionSchemaParser extends AbstractSchemaParser<Ma
      * @return the parsed MatchingRuleDescription bean
      * @throws ParseException if there are any recognition errors (bad syntax)
      */
-    public MatchingRule parseMatchingRuleDescription( String matchingRuleDescription ) throws ParseException
+    public MatchingRule parse( String matchingRuleDescription ) throws ParseException
     {
-        return super.parse( matchingRuleDescription );
-    }
+        MatchingRule matchingRule = fastParser.parseMatchingRule( matchingRuleDescription );
+        matchingRule.setSpecification( matchingRuleDescription );
 
+        // Update the schemaName
+        updateSchemaName( matchingRule );
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected MatchingRule doParse() throws RecognitionException, TokenStreamException
-    {
-        return parser.matchingRuleDescription();
+        return matchingRule;
     }
-
 }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/MatchingRuleUseDescriptionSchemaParser.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/MatchingRuleUseDescriptionSchemaParser.java
index b8b5f15..41a9f1e 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/MatchingRuleUseDescriptionSchemaParser.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/MatchingRuleUseDescriptionSchemaParser.java
@@ -25,9 +25,6 @@ import java.text.ParseException;
 import org.apache.directory.api.i18n.I18n;
 import org.apache.directory.api.ldap.model.schema.MatchingRuleUse;
 
-import antlr.RecognitionException;
-import antlr.TokenStreamException;
-
 
 /**
  * A parser for RFC 4512 matching rule use descriptions.
@@ -66,19 +63,14 @@ public class MatchingRuleUseDescriptionSchemaParser extends AbstractSchemaParser
      * @return the parsed MatchingRuleUseDescription bean
      * @throws ParseException if there are any recognition errors (bad syntax)
      */
-    public MatchingRuleUse parseMatchingRuleUseDescription( String matchingRuleUseDescription ) throws ParseException
+    public MatchingRuleUse parse( String matchingRuleUseDescription ) throws ParseException
     {
-        return super.parse( matchingRuleUseDescription );
-    }
+        MatchingRuleUse matchingRuleUse = fastParser.parseMatchingRuleUse( matchingRuleUseDescription );
+        matchingRuleUse.setSpecification( matchingRuleUseDescription );
 
+        // Update the schemaName
+        updateSchemaName( matchingRuleUse );
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected MatchingRuleUse doParse() throws RecognitionException, TokenStreamException
-    {
-        return parser.matchingRuleUseDescription();
+        return matchingRuleUse;
     }
-
 }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/NameFormDescriptionSchemaParser.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/NameFormDescriptionSchemaParser.java
index 4d81cf7..c9c1911 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/NameFormDescriptionSchemaParser.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/NameFormDescriptionSchemaParser.java
@@ -25,9 +25,6 @@ import java.text.ParseException;
 import org.apache.directory.api.i18n.I18n;
 import org.apache.directory.api.ldap.model.schema.NameForm;
 
-import antlr.RecognitionException;
-import antlr.TokenStreamException;
-
 
 /**
  * A parser for RFC 4512 name form descriptions
@@ -65,19 +62,14 @@ public class NameFormDescriptionSchemaParser extends AbstractSchemaParser<NameFo
      * @return the parsed NameForm bean
      * @throws ParseException if there are any recognition errors (bad syntax)
      */
-    public NameForm parseNameFormDescription( String nameFormDescription ) throws ParseException
+    public NameForm parse( String nameFormDescription ) throws ParseException
     {
-        return super.parse( nameFormDescription );
-    }
+        NameForm nameForm = fastParser.parseNameForm( nameFormDescription );
+        nameForm.setSpecification( nameFormDescription );
 
+        // Update the schemaName
+        updateSchemaName( nameForm );
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected NameForm doParse() throws RecognitionException, TokenStreamException
-    {
-        return parser.nameFormDescription();
+        return nameForm;
     }
-
 }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/NormalizerDescriptionSchemaParser.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/NormalizerDescriptionSchemaParser.java
index defacda..a10463f 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/NormalizerDescriptionSchemaParser.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/NormalizerDescriptionSchemaParser.java
@@ -24,9 +24,6 @@ import java.text.ParseException;
 
 import org.apache.directory.api.i18n.I18n;
 
-import antlr.RecognitionException;
-import antlr.TokenStreamException;
-
 
 /**
  * A parser for ApacheDS normalizer descriptions.
@@ -69,19 +66,14 @@ public class NormalizerDescriptionSchemaParser extends AbstractSchemaParser<Norm
      * @return the parsed NormalizerDescription bean
      * @throws ParseException if there are any recognition errors (bad syntax)
      */
-    public NormalizerDescription parseNormalizerDescription( String normalizerDescription ) throws ParseException
+    public NormalizerDescription parse( String normalizerDescription ) throws ParseException
     {
-        return super.parse( normalizerDescription );
-    }
+        NormalizerDescription normalizer = fastParser.parseNormalizer( normalizerDescription );
+        normalizer.setSpecification( normalizerDescription );
 
+        // Update the schemaName
+        updateSchemaName( normalizer );
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected NormalizerDescription doParse() throws RecognitionException, TokenStreamException
-    {
-        return parser.normalizerDescription();
+        return normalizer;
     }
-
 }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/ObjectClassDescriptionSchemaParser.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/ObjectClassDescriptionSchemaParser.java
index e9ca3bd..1b96a49 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/ObjectClassDescriptionSchemaParser.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/ObjectClassDescriptionSchemaParser.java
@@ -25,9 +25,6 @@ import java.text.ParseException;
 import org.apache.directory.api.i18n.I18n;
 import org.apache.directory.api.ldap.model.schema.ObjectClass;
 
-import antlr.RecognitionException;
-import antlr.TokenStreamException;
-
 
 /**
  * A parser for RFC 4512 object class descriptons
@@ -71,19 +68,14 @@ public class ObjectClassDescriptionSchemaParser extends AbstractSchemaParser<Obj
      * @return the parsed ObjectClassDescription bean
      * @throws ParseException if there are any recognition errors (bad syntax)
      */
-    public ObjectClass parseObjectClassDescription( String objectClassDescription ) throws ParseException
+    public ObjectClass parse( String objectClassDescription ) throws ParseException
     {
-        return super.parse( objectClassDescription );
-    }
+        ObjectClass objectClass = fastParser.parseObjectClass( objectClassDescription );
+        objectClass.setSpecification( objectClassDescription );
 
+        // Update the schemaName
+        updateSchemaName( objectClass );
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected ObjectClass doParse() throws RecognitionException, TokenStreamException
-    {
-        return parser.objectClassDescription();
+        return objectClass;
     }
-
 }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/OpenLdapSchemaParser.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/OpenLdapSchemaParser.java
index 354e1b7..a77a21f 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/OpenLdapSchemaParser.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/parsers/OpenLdapSchemaParser.java
@@ -20,10 +20,13 @@
 package org.apache.directory.api.ldap.model.schema.parsers;
 
 
+import java.io.BufferedReader;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
 import java.nio.charset.Charset;
 import java.nio.file.Files;
 import java.nio.file.Paths;
@@ -33,29 +36,47 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.directory.api.asn1.util.Oid;
 import org.apache.directory.api.i18n.I18n;
+import org.apache.directory.api.ldap.model.exception.LdapSchemaException;
+import org.apache.directory.api.ldap.model.ldif.LdapLdifException;
 import org.apache.directory.api.ldap.model.schema.AttributeType;
+import org.apache.directory.api.ldap.model.schema.DitContentRule;
+import org.apache.directory.api.ldap.model.schema.DitStructureRule;
+import org.apache.directory.api.ldap.model.schema.LdapSyntax;
+import org.apache.directory.api.ldap.model.schema.MatchingRule;
+import org.apache.directory.api.ldap.model.schema.MatchingRuleUse;
 import org.apache.directory.api.ldap.model.schema.MutableAttributeType;
+import org.apache.directory.api.ldap.model.schema.MutableMatchingRule;
+import org.apache.directory.api.ldap.model.schema.MutableObjectClass;
+import org.apache.directory.api.ldap.model.schema.NameForm;
 import org.apache.directory.api.ldap.model.schema.ObjectClass;
+import org.apache.directory.api.ldap.model.schema.ObjectClassTypeEnum;
 import org.apache.directory.api.ldap.model.schema.SchemaObject;
+import org.apache.directory.api.ldap.model.schema.UsageEnum;
 import org.apache.directory.api.ldap.model.schema.syntaxCheckers.OpenLdapObjectIdentifierMacro;
 import org.apache.directory.api.util.Strings;
-
-import antlr.RecognitionException;
-import antlr.TokenStreamException;
-
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
- * A reusable wrapper for antlr generated OpenLDAP schema parsers.
+ * A reusable wrapper for hand parser OpenLDAP schema.
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
-public class OpenLdapSchemaParser extends AbstractSchemaParser<SchemaObject>
+public class OpenLdapSchemaParser
 {
+    /** The LoggerFactory used by this class */
+    protected static final Logger LOG = LoggerFactory.getLogger( OpenLdapSchemaParser.class );
+
+    /** A flag used to tell the parser if it should be strict or not */
+    private boolean isQuirksModeEnabled = false;
+
+    /** the number of the current line being parsed by the reader */
+    protected int lineNumber;
 
     /** The list of parsed schema descriptions */
-    private List<Object> schemaDescriptions;
+    private List<Object> schemaDescriptions = new ArrayList<>();
 
     /** The list of attribute type, initialized by splitParsedSchemaDescriptions() */
     private List<MutableAttributeType> attributeTypes;
@@ -64,32 +85,406 @@ public class OpenLdapSchemaParser extends AbstractSchemaParser<SchemaObject>
     private List<ObjectClass> objectClasses;
 
     /** The map of object identifier macros, initialized by splitParsedSchemaDescriptions()*/
-    private Map<String, OpenLdapObjectIdentifierMacro> objectIdentifierMacros;
+    private Map<String, OpenLdapObjectIdentifierMacro> objectIdentifierMacros = new HashMap<>();
+    
+    /** Some contant strings used in descriptions */
+    private static final String APPLIES_STR                 = "APPLIES";
+    private static final String ABSTRACT_STR                = "ABSTRACT";
+    private static final String AUX_STR                     = "AUX";
+    private static final String AUXILIARY_STR               = "AUXILIARY";
+    private static final String BYTECODE_STR                = "BYTECODE";
+    private static final String COLLECTIVE_STR              = "COLLECTIVE";
+    private static final String DESC_STR                    = "DESC";
+    private static final String EQUALITY_STR                = "EQUALITY";
+    private static final String FORM_STR                    = "FORM";
+    private static final String FQCN_STR                    = "FQCN";
+    private static final String MAY_STR                     = "MAY";
+    private static final String MUST_STR                    = "MUST";
+    private static final String NAME_STR                    = "NAME";
+    private static final String NO_USER_MODIFICATION_STR    = "NO-USER-MODIFICATION";
+    private static final String NOT_STR                     = "NOT";
+    private static final String OBSOLETE_STR                = "OBSOLETE";
+    private static final String OC_STR                      = "OC";
+    private static final String ORDERING_STR                = "ORDERING";
+    private static final String SINGLE_VALUE_STR            = "SINGLE-VALUE";
+    private static final String STRUCTURAL_STR              = "STRUCTURAL";
+    private static final String SUBSTR_STR                  = "SUBSTR";
+    private static final String SUP_STR                     = "SUP";
+    private static final String SYNTAX_STR                  = "SYNTAX";
+    private static final String USAGE_STR                   = "USAGE";
+    private static final String EXTENSION_PREFIX            = "X-";
+    
+    /** Usage */
+    private static final String DIRECTORY_OPERATION_STR     = "directoryOperation";
+    private static final String DISTRIBUTED_OPERATION_STR   = "distributedOperation";
+    private static final String DSA_OPERATION_STR           = "dSAOperation";
+    private static final String USER_APPLICATIONS_STR       = "userApplications";
+
+    /** Tokens */
+    private static final char COLON         = ':';
+    private static final char DOLLAR        = '$';
+    private static final char DOT           = '.';
+    private static final char EQUAL         = '=';
+    private static final char ESCAPE        = '\\';
+    private static final char HYPHEN        = '-';
+    private static final char LBRACE        = '{';
+    private static final char LPAREN        = '(';
+    private static final char PLUS          = '+';
+    private static final char RBRACE        = '}';
+    private static final char RPAREN        = ')';
+    private static final char SEMI_COLON    = ';';
+    private static final char SHARP         = '#';
+    private static final char SLASH         = '/';
+    private static final char SQUOTE        = '\'';
+    private static final char UNDERSCORE    = '_';
+    private static final char DQUOTE        = '"';
+
 
     /** Flag whether object identifier macros should be resolved. */
     private boolean isResolveObjectIdentifierMacros;
+    
+    private static final boolean UN_QUOTED = false;
+    
+    /** Flag for strict or relaxed mode */
+    private static final boolean STRICT = false;
+    private static final boolean RELAXED = true;
+    
+    private class PosSchema
+    {
+        /** The line number in the file */
+        int lineNumber;
+        
+        /** The position in the current line */
+        int start;
+        
+        /** The line being processed */
+        String line;
+        
+        /**
+         * {@inheritDoc} 
+         */
+        @Override
+        public String toString()
+        {
+            if ( line == null )
+            {
+                return "null";
+            }
+            else if ( line.length() < start )
+            {
+                return "EOL";
+            }
+            else
+            {
+                return line.substring( start ); 
+            }
+        }
+    }
 
 
+    private interface SchemaObjectElements
+    {
+        int getValue();
+    }
+
+    
     /**
-     * Creates a reusable instance of an OpenLdapSchemaParser.
-     *
-     * @throws IOException if the pipe cannot be formed
+     * The list of AttributeTypeDescription elements that can be seen 
      */
-    public OpenLdapSchemaParser() throws IOException
+    private enum AttributeTypeElements implements SchemaObjectElements
     {
-        super( null, null, null, null );
-        isResolveObjectIdentifierMacros = true;
-        super.setQuirksMode( true );
+        NAME(1),
+        DESC(2),
+        OBSOLETE(4),
+        SUP(8),
+        EQUALITY(16),
+        ORDERING(32),
+        SUBSTR(64),
+        SYNTAX(128),
+        SINGLE_VALUE(256),
+        COLLECTIVE(512),
+        NO_USER_MODIFICATION(1024),
+        USAGE(2048);
+        
+        private int value;
+        
+        AttributeTypeElements( int value )
+        {
+            this.value = value;
+        }
+        
+        
+        public int getValue()
+        {
+            return value;
+        }
+    }
+    
+    
+    /**
+     * The list of DitContentRuleDescription elements that can be seen 
+     */
+    private enum DitContentRuleElements implements SchemaObjectElements
+    {
+        NAME(1),
+        DESC(2),
+        OBSOLETE(4),
+        AUX(8),
+        MUST(16),
+        MAY(32),
+        NOT(64);
+        
+        private int value;
+        
+        DitContentRuleElements( int value )
+        {
+            this.value = value;
+        }
+        
+        
+        public int getValue()
+        {
+            return value;
+        }
+    }
+
+
+    /**
+     * The list of DitStructureRuleDescription elements that can be seen 
+     */
+    private enum DitStructureRuleElements implements SchemaObjectElements
+    {
+        NAME(1),
+        DESC(2),
+        OBSOLETE(4),
+        FORM(8),
+        SUP(16);
+        
+        private int value;
+        
+        DitStructureRuleElements( int value )
+        {
+            this.value = value;
+        }
+        
+        
+        public int getValue()
+        {
+            return value;
+        }
+    }
+
+    
+    /**
+     * The list of LdapComparatorDescription elements that can be seen 
+     */
+    private enum LdapComparatorElements implements SchemaObjectElements
+    {
+        DESC(1),
+        FQCN(2),
+        BYTECODE(4);
+        
+        private int value;
+        
+        LdapComparatorElements( int value )
+        {
+            this.value = value;
+        }
+        
+        
+        public int getValue()
+        {
+            return value;
+        }
+    }
+
+    
+    /**
+     * The list of LdapSyntaxDescription elements that can be seen 
+     */
+    private enum LdapSyntaxElements implements SchemaObjectElements
+    {
+        DESC(1);
+        
+        private int value;
+        
+        LdapSyntaxElements( int value )
+        {
+            this.value = value;
+        }
+        
+        
+        public int getValue()
+        {
+            return value;
+        }
+    }
+
+
+    /**
+     * The list of MatchingRuleDescription elements that can be seen 
+     */
+    private enum MatchingRuleElements implements SchemaObjectElements
+    {
+        NAME(1),
+        DESC(2),
+        OBSOLETE(4),
+        SYNTAX(8);
+        
+        private int value;
+        
+        MatchingRuleElements( int value )
+        {
+            this.value = value;
+        }
+        
+        
+        public int getValue()
+        {
+            return value;
+        }
+    }
+
+    
+    /**
+     * The list of MatchingRuleUseDescription elements that can be seen 
+     */
+    private enum MatchingRuleUseElements implements SchemaObjectElements
+    {
+        NAME(1),
+        DESC(2),
+        OBSOLETE(4),
+        APPLIES(8);
+        
+        private int value;
+        
+        MatchingRuleUseElements( int value )
+        {
+            this.value = value;
+        }
+        
+        
+        public int getValue()
+        {
+            return value;
+        }
+    }
+
+    
+    /**
+     * The list of NameFormDescription elements that can be seen 
+     */
+    private enum NameFormElements implements SchemaObjectElements
+    {
+        NAME(1),
+        DESC(2),
+        OBSOLETE(4),
+        OC(8),
+        MUST(16),
+        MAY(32);
+        
+        private int value;
+        
+        NameFormElements( int value )
+        {
+            this.value = value;
+        }
+        
+        
+        public int getValue()
+        {
+            return value;
+        }
+    }
+
+
+    /**
+     * The list of NormalizerDescription elements that can be seen 
+     */
+    private enum NormalizerElements implements SchemaObjectElements
+    {
+        DESC(1),
+        FQCN(2),
+        BYTECODE(4);
+        
+        private int value;
+        
+        NormalizerElements( int value )
+        {
+            this.value = value;
+        }
+        
+        
+        public int getValue()
+        {
+            return value;
+        }
+    }
+
+
+    /**
+     * The list of ObjectClassDescription elements that can be seen 
+     */
+    private enum ObjectClassElements implements SchemaObjectElements
+    {
+        NAME(1),
+        DESC(2),
+        OBSOLETE(4),
+        SUP(8),
+        MUST(16),
+        MAY(32),
+        ABSTRACT(64),
+        STRUCTURAL(64),
+        AUXILIARY(64);
+        
+        private int value;
+        
+        ObjectClassElements( int value )
+        {
+            this.value = value;
+        }
+        
+        
+        public int getValue()
+        {
+            return value;
+        }
+    }
+
+
+    /**
+     * The list of SyntaxCheckerDescription elements that can be seen 
+     */
+    private enum SyntaxCheckerElements implements SchemaObjectElements
+    {
+        DESC(1),
+        FQCN(2),
+        BYTECODE(4);
+        
+        private int value;
+        
+        SyntaxCheckerElements( int value )
+        {
+            this.value = value;
+        }
+        
+        
+        public int getValue()
+        {
+            return value;
+        }
     }
 
 
     /**
-     * {@inheritDoc}
+     * Creates a reusable instance of an OpenLdapSchemaParser.
+     *
+     * @throws IOException if the pipe cannot be formed
      */
-    @Override
-    protected SchemaObject doParse() throws RecognitionException, TokenStreamException
+    public OpenLdapSchemaParser()
     {
-        throw new UnsupportedOperationException( I18n.err( I18n.ERR_13715_OPENLDAP_PARSER_NON_STANDARD ) );
+        isResolveObjectIdentifierMacros = true;
+        isQuirksModeEnabled = false;
     }
 
 
@@ -98,6 +493,25 @@ public class OpenLdapSchemaParser extends AbstractSchemaParser<SchemaObject>
      */
     public void clear()
     {
+        if ( attributeTypes != null )
+        {
+            attributeTypes.clear();
+        }
+        
+        if ( objectClasses != null )
+        {
+            objectClasses.clear();
+        }
+        
+        if ( schemaDescriptions != null )
+        {
+            schemaDescriptions.clear();
+        }
+    
+        if ( objectIdentifierMacros != null )
+        {
+            objectIdentifierMacros.clear();
+        }
     }
 
 
@@ -117,7 +531,7 @@ public class OpenLdapSchemaParser extends AbstractSchemaParser<SchemaObject>
      * 
      * @return the object class types
      */
-    public List<ObjectClass> getObjectClassTypes()
+    public List<ObjectClass> getObjectClasses()
     {
         return objectClasses;
     }
@@ -144,7 +558,6 @@ public class OpenLdapSchemaParser extends AbstractSchemaParser<SchemaObject>
     {
         objectClasses = new ArrayList<>();
         attributeTypes = new ArrayList<>();
-        objectIdentifierMacros = new HashMap<>();
 
         // split parsed schema descriptions
         for ( Object obj : schemaDescriptions )
@@ -195,7 +608,7 @@ public class OpenLdapSchemaParser extends AbstractSchemaParser<SchemaObject>
 
     private String getResolveOid( String oid )
     {
-        if ( oid != null && oid.indexOf( ':' ) != -1 )
+        if ( oid != null && oid.indexOf( COLON ) != -1 )
         {
             // resolve OID
             String[] nameAndSuffix = oid.split( ":" );
@@ -203,6 +616,7 @@ public class OpenLdapSchemaParser extends AbstractSchemaParser<SchemaObject>
             if ( objectIdentifierMacros.containsKey( nameAndSuffix[0] ) )
             {
                 OpenLdapObjectIdentifierMacro macro = objectIdentifierMacros.get( nameAndSuffix[0] );
+                
                 return macro.getResolvedOid() + "." + nameAndSuffix[1];
             }
         }
@@ -220,7 +634,7 @@ public class OpenLdapSchemaParser extends AbstractSchemaParser<SchemaObject>
             // finished
             return;
         }
-        else if ( rawOidOrNameSuffix.indexOf( ':' ) != -1 )
+        else if ( rawOidOrNameSuffix.indexOf( COLON ) != -1 )
         {
             // resolve OID
             String[] nameAndSuffix = rawOidOrNameSuffix.split( ":" );
@@ -261,17 +675,22 @@ public class OpenLdapSchemaParser extends AbstractSchemaParser<SchemaObject>
      * @return the schema object
      * @throws ParseException If the schemaObject can't be parsed
      */
-    @Override
     public SchemaObject parse( String schemaObject ) throws ParseException
     {
         if ( ( schemaObject == null ) || Strings.isEmpty( schemaObject.trim() ) )
         {
             throw new ParseException( I18n.err( I18n.ERR_13716_NULL_OR_EMPTY_STRING_SCHEMA_OBJECT ), 0 );
         }
-
-        // reset and initialize the parser / lexer pair
-        reset( schemaObject );
-        invokeParser( schemaObject );
+        
+        try ( Reader reader = new BufferedReader( new StringReader( schemaObject ) ) )
+        {
+            parse( reader );
+            afterParse();
+        }
+        catch ( IOException | LdapSchemaException e )
+        {
+            throw new ParseException( e.getMessage(), 0 );
+        }
 
         if ( !schemaDescriptions.isEmpty() )
         {
@@ -288,69 +707,5579 @@ public class OpenLdapSchemaParser extends AbstractSchemaParser<SchemaObject>
     }
 
 
-    private void invokeParser( String subject ) throws ParseException
-    {
-        try
-        {
-            monitor.startedParse( "starting parse on:\n" + subject );
-            schemaDescriptions = parser.openLdapSchema();
-            afterParse();
-            monitor.finishedParse( "Done parsing!" );
-        }
-        catch ( RecognitionException re )
-        {
-            String msg = I18n.err( I18n.ERR_15003_PARSER_FAILURE, subject, ExceptionUtils.getFullStackTrace( re ) );
-            throw new ParseException( msg, re.getColumn() );
-        }
-        catch ( TokenStreamException tse )
-        {
-            String msg = I18n.err( I18n.ERR_15003_PARSER_FAILURE, subject, ExceptionUtils.getFullStackTrace( tse ) );
-            throw new ParseException( msg, 0 );
-        }
-    }
-
-
     /**
      * Parses a stream of OpenLDAP schemaObject elements/objects. Default charset is used.
      *
      * @param schemaIn a stream of schema objects
-     * @throws IOException If the schemaObject can't be transformed to a byteArrayInputStream
-     * @throws ParseException If the schemaObject can't be parsed
+     * @throws Exception 
      */
-    public void parse( InputStream schemaIn ) throws IOException, ParseException
+    public void parse( InputStream schemaIn ) throws Exception
     {
-        InputStreamReader in = new InputStreamReader( schemaIn, Charset.defaultCharset() );
-        lexer.prepareNextInput( in );
-        parser.resetState();
-
-        invokeParser( "schema input stream ==> " + schemaIn.toString() );
+        try ( InputStreamReader in = new InputStreamReader( schemaIn, Charset.defaultCharset() ) )
+        {
+            try ( Reader reader = new BufferedReader( in ) )
+            {
+                parse( reader );
+                afterParse();
+            }
+        }
     }
+    
+    
+    private static void skipWhites( Reader reader, PosSchema pos, boolean mandatory ) throws IOException, LdapSchemaException
+    {
+        boolean hasSpace = false;
+        
+        while ( true )
+        {
+            if ( isEmpty( pos ) )
+            {
+                getLine( reader, pos );
+                
+                if ( pos.line == null )
+                {
+                    return;
+                }
+                
+                hasSpace = true;
+                continue;
+            }
+            
+            if ( pos.line == null )
+            {
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13782_END_OF_FILE, pos.lineNumber, pos.start ) );
+            }
+            
+            while ( Character.isWhitespace( pos.line.charAt( pos.start ) ) )
+            {
+                hasSpace = true;
+                pos.start++;
+                
+                if ( isEmpty( pos ) )
+                {
+                    getLine( reader, pos );
 
+                    if ( pos.line == null )
+                    {
+                        return;
+                    }
+                    
+                    continue;
+                }
+            }
+            
+            if ( pos.line.charAt( pos.start ) == SHARP )
+            {
+                getLine( reader, pos );
 
-    /**
-     * Parses a file of OpenLDAP schemaObject elements/objects. Default charset is used.
-     *
-     * @param schemaFile a file of schema objects
-     * @throws IOException If the schemaObject can't be transformed to a byteArrayInputStream
-     * @throws ParseException If the schemaObject can't be parsed
-     */
-    public void parse( File schemaFile ) throws IOException, ParseException
+                if ( pos.line == null )
+                {
+                    return;
+                }
+                
+                hasSpace = true;
+                continue;
+            }
+            else
+            {
+                if ( mandatory && !hasSpace )
+                {
+                    throw new LdapSchemaException( I18n.err( I18n.ERR_13783_SPACE_EXPECTED, pos.lineNumber, pos.start ) );
+                }
+                else
+                {
+                    return;
+                }
+            }
+        }
+    }
+    
+    
+    private static boolean isComment( PosSchema pos )
     {
-        InputStreamReader in = new InputStreamReader(
-            Files.newInputStream( Paths.get( schemaFile.getPath() ) ), Charset.defaultCharset() );
-        lexer.prepareNextInput( in );
-        parser.resetState();
-
-        invokeParser( "schema file ==> " + schemaFile.getAbsolutePath() );
+        if ( isEmpty( pos ) )
+        {
+            return true;
+        }
+        
+        return pos.line.charAt( pos.start ) == SHARP;
     }
-
-
-    /**
-     * Checks if object identifier macros should be resolved.
-     * 
-     * @return true, object identifier macros should be resolved.
-     */
-    public boolean isResolveObjectIdentifierMacros()
+    
+    
+    private static boolean isEmpty( PosSchema pos )
+    {
+        return ( pos.line == null ) || ( pos.start >= pos.line.length() );
+    }
+    
+    
+    private static boolean startsWith( PosSchema pos, String text )
+    {
+        if ( ( pos.line == null ) || ( pos.line.length() - pos.start < text.length() ) )
+        {
+            return false;
+        }
+        
+        return text.equalsIgnoreCase( pos.line.substring( pos.start, pos.start + text.length() ) );
+    }
+    
+    
+    private static boolean startsWith( Reader reader, PosSchema pos, char c ) throws IOException, LdapSchemaException
+    {
+        return startsWith( reader, pos, c, UN_QUOTED );
+    }
+    
+    
+    private static boolean startsWith( Reader reader, PosSchema pos, char c, boolean quoted ) throws IOException, LdapSchemaException
+    {
+        if ( ( pos.line == null ) || ( pos.line.length() - pos.start < 1 ) )
+        {
+            return false;
+        }
+        
+        if ( quoted )
+        {
+            // Don't read a new line when we are within quotes
+            return pos.line.charAt( pos.start ) == c;
+        }
+
+        while ( isEmpty( pos ) || ( isComment( pos ) ) )
+        {
+            getLine( reader, pos );
+            
+            if ( pos.line == null )
+            {
+                return false;
+            }
+            
+            skipWhites( reader, pos, false );
+            
+            if ( isComment( pos ) )
+            {
+                continue;
+            }
+        }
+        
+        return pos.line.charAt( pos.start ) == c;
+    }
+    
+    
+    private static boolean startsWith( PosSchema pos, char c )
+    {
+        if ( ( pos.line == null ) || ( pos.line.length() - pos.start < 1 ) )
+        {
+            return false;
+        }
+        
+        return pos.line.charAt( pos.start ) == c;
+    }
+
+    
+    private static boolean isAlpha( PosSchema pos )
+    {
+        return Character.isAlphabetic( pos.line.charAt( pos.start ) );
+    }
+    
+    
+    private static boolean isDigit( PosSchema pos )
+    {
+        return Character.isDigit( pos.line.charAt( pos.start ) );
+    }
+
+    
+    private static void getLine( Reader reader, PosSchema pos ) throws IOException
+    {
+        pos.line = ( ( BufferedReader ) reader ).readLine();
+        pos.start = 0;
+        
+        if ( pos.line != null )
+        {
+            pos.lineNumber++;
+        }
+    }
+    
+    
+    /**
+     * numericoid   ::= number ( DOT number )+
+     * number       ::= DIGIT | LDIGIT DIGIT+
+     * DIGIT        ::= %x30 | LDIGIT       ; "0"-"9"
+     * LDIGIT       ::= %x31-39             ; "1"-"9"
+     * DOT          ::= %x2E                ; period (".")
+     */
+    private static String getNumericOid( PosSchema pos ) throws LdapSchemaException
+    {
+        int start = pos.start;
+        boolean isDot = false;
+        boolean isFirstZero = false;
+        boolean isFirstDigit = true; 
+        
+        while ( !isEmpty( pos ) )
+        {
+            char c = pos.line.charAt( pos.start );
+            
+            if ( Character.isDigit( c ) )
+            {
+                if ( isFirstZero )
+                {
+                    throw new LdapSchemaException( I18n.err( I18n.ERR_13784_BAD_OID_TWO_ZEROES, pos.lineNumber, pos.start ) );
+                }
+                    
+                if ( ( pos.line.charAt( pos.start ) == '0' ) && isFirstDigit )
+                {
+                    isFirstZero = true;
+                }
+                
+                isDot = false;
+                pos.start++;
+                isFirstDigit = false;
+            }
+            else if ( c == DOT )
+            {
+                if ( isDot )
+                {
+                    // We can't have two consecutive dots or a dot at the beginning
+                    throw new LdapSchemaException( I18n.err( I18n.ERR_13785_BAD_OID_CONSECUTIVE_DOTS, pos.lineNumber, pos.start ) );
+                }
+                
+                isFirstZero = false;
+                isFirstDigit = true;
+                pos.start++;
+                isDot = true;
+            }
+            else
+            {
+                break;
+            }
+        }
+        
+        if ( isDot )
+        {
+            // We can't have two consecutive dots or a dot at the beginning
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13786_BAD_OID_DOT_AT_THE_END, pos.lineNumber, pos.start ) );
+        }
+
+        String oidStr = pos.line.substring( start, pos.start );
+
+        if ( Oid.isOid( oidStr ) )
+        {
+            return oidStr;
+        }
+        else
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13787_OID_EXPECTED, pos.line, pos.start ) );
+        }
+    }
+    
+    
+    /**
+     * partialNumericoid   ::= number ( DOT number )*
+     * number              ::= DIGIT | LDIGIT DIGIT+
+     * DIGIT               ::= %x30 | LDIGIT       ; "0"-"9"
+     * LDIGIT              ::= %x31-39             ; "1"-"9"
+     * DOT                 ::= %x2E                ; period (".")
+     */
+    private static String getPartialNumericOid( PosSchema pos ) throws LdapSchemaException
+    {
+        int start = pos.start;
+        boolean isDot = false;
+        boolean isFirstZero = false;
+        boolean isFirstDigit = true; 
+        
+        while ( !isEmpty( pos ) )
+        {
+            if ( isDigit( pos ) )
+            {
+                if ( isFirstZero )
+                {
+                    throw new LdapSchemaException( I18n.err( I18n.ERR_13784_BAD_OID_TWO_ZEROES, pos.lineNumber, pos.start ) );
+                }
+                    
+                if ( ( pos.line.charAt( pos.start ) == '0' ) && isFirstDigit )
+                {
+                    isFirstZero = true;
+                }
+                
+                isDot = false;
+                pos.start++;
+                isFirstDigit = false;
+            }
+            else if ( startsWith( pos, DOT ) )
+            {
+                if ( isDot )
+                {
+                    // We can't have two consecutive dots or a dot at the beginning
+                    throw new LdapSchemaException( I18n.err( I18n.ERR_13785_BAD_OID_CONSECUTIVE_DOTS, pos.lineNumber, pos.start ) );
+                }
+                
+                isFirstZero = false;
+                isFirstDigit = true;
+                pos.start++;
+                isDot = true;
+            }
+            else
+            {
+                break;
+            }
+        }
+        
+        if ( isDot )
+        {
+            // We can't have two consecutive dots or a dot at the beginning
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13786_BAD_OID_DOT_AT_THE_END, pos.lineNumber, pos.start ) );
+        }
+
+        return pos.line.substring( start, pos.start );
+    }
+
+    
+
+    
+    /**
+     * In relaxed mode :
+     * <pre>
+     * oid          ::= descr | numericoid
+     * descr        ::= descrQ (COLON numericoid)
+     * descrQ       ::= keystringQ
+     * keystringQ   ::= LkeycharQ keycharQ*
+     * LkeycharQ    ::= ALPHA | HYPHEN | UNDERSCORE | SEMI_COLON | DOT | COLON | SHARP 
+     * keycharQ     ::= ALPHA | DIGIT | HYPHEN | UNDERSCORE | SEMI_COLON | DOT | COLON | SHARP 
+     * numericoid   ::= number ( DOT number )+
+     * number       ::= DIGIT | LDIGIT DIGIT+
+     * ALPHA        ::= %x41-5A | %x61-7A   ; "A"-"Z" / "a"-"z"
+     * DIGIT        ::= %x30 | LDIGIT       ; "0"-"9"
+     * LDIGIT       ::= %x31-39             ; "1"-"9"
+     * HYPHEN       ::= %x2D                ; hyphen ("-")
+     * UNDERSCORE   ::= %x5F                ; underscore ("_")
+     * DOT          ::= %x2E                ; period (".")
+     * COLON        ::= %x3A                ; colon (":")
+     * SEMI_COLON   ::= %x3B                ; semi-colon(";")
+     * SHARP        ::= %x23                ; octothorpe (or sharp sign) ("#")
+     * </pre>
+     */
+    private static String getOidAndMacroRelaxed( PosSchema pos, 
+        Map<String, OpenLdapObjectIdentifierMacro> objectIdentifierMacros ) throws LdapSchemaException
+    {
+        if ( isEmpty( pos ) )
+        {
+            return "";
+        }
+
+        // This is a OID name
+        int start = pos.start;
+        char c = pos.line.charAt( pos.start );
+        boolean isDigit = Character.isDigit( c );
+        
+        while ( isDigit || Character.isAlphabetic( c ) || ( c == HYPHEN ) || ( c == UNDERSCORE )
+            || ( c == SEMI_COLON ) || ( c == DOT ) || ( c == SHARP ) )
+        {
+            pos.start++;
+            
+            if ( isEmpty( pos ) )
+            {
+                break;
+            }
+            
+            c = pos.line.charAt( pos.start );
+            isDigit = Character.isDigit( c );
+        }
+        
+        String oidName = pos.line.substring( start, pos.start  );
+        
+        if ( Strings.isEmpty( oidName ) )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13787_OID_EXPECTED, pos.lineNumber, pos.start ) );
+        }
+        
+        // We may have a ':' followed by an OID
+        if ( startsWith( pos, COLON ) )
+        {
+            pos.start++;
+            String oid = getPartialNumericOid( pos );
+            
+            return objectIdentifierMacros.get( oidName ).getRawOidOrNameSuffix() + DOT + oid;
+        }
+        else
+        {
+            // Ok, we may just have an oidName
+            OpenLdapObjectIdentifierMacro macro = objectIdentifierMacros.get( oidName );
+            
+            if ( macro == null )
+            {
+                return oidName;
+            }
+            else
+            {
+                return macro.getRawOidOrNameSuffix();
+            }
+        }
+    }
+
+    
+    /**
+     * In normal mode :
+     * <pre>
+     * oid          ::= descr | numericoid
+     * descr        ::= keystring
+     * keystring    ::= leadkeychar keychar*
+     * leadkeychar  ::= ALPHA
+     * keychar      ::= ALPHA | DIGIT | HYPHEN
+     * numericoid   ::= number ( DOT number )+ |
+     * number       ::= DIGIT | LDIGIT DIGIT+
+     * ALPHA        ::= %x41-5A | %x61-7A   ; "A"-"Z" / "a"-"z"
+     * DIGIT        ::= %x30 | LDIGIT       ; "0"-"9"
+     * LDIGIT       ::= %x31-39             ; "1"-"9"
+     * DOT          ::= %x2E                ; period (".")
+     * HYPHEN       ::= %x2D                ; hyphen ("-")
+     * </pre>
+     */
+    private static String getOidStrict( PosSchema pos ) throws LdapSchemaException
+    {
+        if ( isEmpty( pos ) )
+        {
+            return "";
+        }
+
+        if ( isAlpha( pos ) )
+        {
+            // A descr
+            return getDescrStrict( pos );
+        }
+        else if ( isDigit( pos ) )
+        {
+            // This is a numeric oid
+            return getNumericOid( pos );
+        }
+        else
+        {
+            // This is an error
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13787_OID_EXPECTED, pos.lineNumber, pos.start ) );
+        }
+    }
+
+    
+    /**
+     * In quirks mode :
+     * <pre>
+     * oid          ::= descr-relaxed | numericoid | SQUOTE descr-relaxed SQUOTE |
+     *                  DQUOTE descr-relaxed DQUOTE | SQUOTE numericoid SQUOTE |
+     *                  DQUOTE numericoid DQUOTE
+     * descr-relaxed::= macro (COLON numericoid)
+     * macro        ::= keystring
+     * keystring    ::= Lkeychar  keychar*
+     * Lkeychar     ::= ALPHA | HYPHEN | UNDERSCORE | SEMI_COLON | DOT | COLON | SHARP 
+     * keychar      ::= ALPHA | DIGIT | HYPHEN | UNDERSCORE | SEMI_COLON | DOT | COLON | SHARP 
+     * numericoid   ::= number ( DOT number )+
+     * number       ::= DIGIT | LDIGIT DIGIT+
+     * ALPHA        ::= %x41-5A | %x61-7A   ; "A"-"Z" / "a"-"z"
+     * DIGIT        ::= %x30 | LDIGIT       ; "0"-"9"
+     * LDIGIT       ::= %x31-39             ; "1"-"9"
+     * HYPHEN       ::= %x2D                ; hyphen ("-")
+     * UNDERSCORE   ::= %x5F                ; underscore ("_")
+     * DOT          ::= %x2E                ; period (".")
+     * COLON        ::= %x3A                ; colon (":")
+     * SEMI_COLON   ::= %x3B                ; semi-colon(";")
+     * SHARP        ::= %x23                ; octothorpe (or sharp sign) ("#")
+     * </pre>
+     */
+    private static String getOidRelaxed( PosSchema pos, boolean hadQuote ) throws LdapSchemaException
+    {
+        if ( isEmpty( pos ) )
+        {
+            return "";
+        }
+        
+        boolean hasQuote = false;
+
+        char c = pos.line.charAt( pos.start );
+        
+        if ( c == SQUOTE )
+        {
+            if ( hadQuote )
+            {
+                return "";
+            }
+            
+            hasQuote = true;
+            pos.start++;
+
+            if ( isEmpty( pos ) )
+            {
+                return "";
+            }
+            
+            c = pos.line.charAt( pos.start );
+        }
+        
+        String oid;
+
+        if ( Character.isAlphabetic( c ) )
+        {
+            // This is a OID name
+            oid = getDescrRelaxed( pos );
+        }
+        else if ( Character.isDigit( c ) )
+        {
+            // This is a numeric oid
+            oid = getNumericOid( pos );
+        }
+        else
+        {
+            // This is an error
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13787_OID_EXPECTED, 
+                pos.lineNumber, pos.start ) );
+        }
+        
+        if ( isEmpty( pos ) )
+        {
+            if ( hasQuote || hadQuote )
+            {
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13792_SIMPLE_QUOTE_EXPECTED_AT_END, 
+                    pos.lineNumber, pos.start ) );
+            }
+            else
+            {
+                return oid;
+            }
+        }
+        
+        c = pos.line.charAt( pos.start );
+        
+        if ( ( c == SQUOTE ) && !hadQuote )
+        {
+           if ( hasQuote )
+           {
+               pos.start++;
+           }
+           else
+           {
+               throw new LdapSchemaException( I18n.err( I18n.ERR_13792_SIMPLE_QUOTE_EXPECTED_AT_END, 
+                   pos.lineNumber, pos.start ) );
+           }
+        }
+        
+        return oid;
+    }
+    
+    
+    /**
+     * In strict mode :
+     * 
+     * <pre>
+     * descr        ::= keystring
+     * keystring    ::= leadkeychar keychar*
+     * leadkeychar  ::= ALPHA
+     * keychar      ::= ALPHA | DIGIT | HYPHEN
+     * numericoid   ::= number ( DOT number )+ |
+     * number       ::= DIGIT | LDIGIT DIGIT+
+     * ALPHA        ::= %x41-5A | %x61-7A   ; "A"-"Z" / "a"-"z"
+     * DIGIT        ::= %x30 | LDIGIT       ; "0"-"9"
+     * LDIGIT       ::= %x31-39             ; "1"-"9"
+     * DOT          ::= %x2E                ; period (".")
+     * HYPHEN       ::= %x2D                ; hyphen ("-")
+     * </pre>
+     */
+    private static String getDescrStrict( PosSchema pos ) throws LdapSchemaException
+    {
+        int start = pos.start;
+        boolean isFirst = true;
+        
+        while ( !isEmpty( pos ) )
+        {
+            if ( isFirst )
+            {
+                isFirst = false;
+                
+                if ( isAlpha( pos ) ) 
+                {
+                    // leadkeychar
+                    pos.start++;
+                }
+                else
+                {
+                    // Error, we are expecting a leadKeychar
+                    throw new LdapSchemaException( I18n.err( I18n.ERR_13788_LEAD_KEY_CHAR_EXPECTED, 
+                        pos.lineNumber, pos.start ) );
+                }
+            }
+            else
+            {
+                char c = pos.line.charAt( pos.start );
+                
+                if ( Character.isAlphabetic( c ) || Character.isDigit( c ) || ( c == HYPHEN ) )
+                {
+                    pos.start++;
+                }
+                else
+                {
+                    // We are done 
+                    return pos.line.substring( start, pos.start );
+                }
+            }
+        }
+
+        return pos.line.substring( start, pos.start );
+    }
+    
+    
+    
+    /**
+     * In quirksMode :
+     * 
+     * <pre>
+     * descr        ::= descrQ (COLON numericoid)
+     * descrQ       ::= keystringQ
+     * keystringQ   ::= LkeycharQ keycharQ*
+     * LkeycharQ    ::= ALPHA | HYPHEN | UNDERSCORE | SEMI_COLON | DOT | COLON | SHARP 
+     * keycharQ     ::= ALPHA | DIGIT | HYPHEN | UNDERSCORE | SEMI_COLON | DOT | COLON | SHARP 
+     * numericoid   ::= number ( DOT number )+
+     * number       ::= DIGIT | LDIGIT DIGIT+
+     * ALPHA        ::= %x41-5A | %x61-7A   ; "A"-"Z" / "a"-"z"
+     * DIGIT        ::= %x30 | LDIGIT       ; "0"-"9"
+     * LDIGIT       ::= %x31-39             ; "1"-"9"
+     * HYPHEN       ::= %x2D                ; hyphen ("-")
+     * UNDERSCORE   ::= %x5F                ; underscore ("_")
+     * DOT          ::= %x2E                ; period (".")
+     * COLON        ::= %x3A                ; colon (":")
+     * SEMI_COLON   ::= %x3B                ; semi-colon(";")
+     * SHARP        ::= %x23                ; octothorpe (or sharp sign) ("#")
+     * </pre
+     */
+    private static String getDescrRelaxed( PosSchema pos ) throws LdapSchemaException
+    {
+        int start = pos.start;
+        boolean isFirst = true;
+        
+        while ( !isEmpty( pos ) )
+        {
+            if ( isFirst )
+            {
+                isFirst = false;
+                
+                char c = pos.line.charAt( pos.start );
+                
+                if ( Character.isAlphabetic( c ) || ( c == HYPHEN ) || ( c == UNDERSCORE )
+                    || ( c == SEMI_COLON ) || ( c == DOT ) || ( c == COLON ) || ( c == SHARP ) ) 
+                {
+                    // leadkeycharQ
+                    pos.start++;
+                }
+                else
+                {
+                    // Error, we are expecting a leadKeychar
+                    throw new LdapSchemaException( I18n.err( I18n.ERR_13788_LEAD_KEY_CHAR_EXPECTED, 
+                        pos.lineNumber, pos.start ) );
+                }
+            }
+            else
+            {
+                char c = pos.line.charAt( pos.start );
+                
+                if ( Character.isAlphabetic( c ) || Character.isDigit( c ) || ( c == HYPHEN )
+                    || ( c == UNDERSCORE ) || ( c == SEMI_COLON ) || ( c == DOT ) || ( c == COLON ) || ( c == SHARP ) ) 
+                {
+                    pos.start++;
+                }
+                else
+                {
+                    // We are done 
+                    return pos.line.substring( start, pos.start );
+                }
+            }
+        }
+        
+        return pos.line.substring( start, pos.start );
+    }
+    
+    
+    private String getMacro( PosSchema pos ) throws LdapSchemaException
+    {
+        if ( isQuirksModeEnabled )
+        {
+            int start = pos.start;
+            boolean isFirst = true;
+            
+            while ( !isEmpty( pos ) )
+            {
+                if ( isFirst )
+                {
+                    isFirst = false;
+                    
+                    char c = pos.line.charAt( pos.start );
+                    
+                    if ( Character.isAlphabetic( c ) || ( c == HYPHEN ) || ( c == UNDERSCORE ) 
+                        || ( c == SEMI_COLON ) || ( c == DOT ) || ( c == SHARP ) ) 
+                    {
+                        // leadkeycharQ
+                        pos.start++;
+                    }
+                    else
+                    {
+                        // Error, we are expecting a leadKeychar
+                        throw new LdapSchemaException( I18n.err( I18n.ERR_13788_LEAD_KEY_CHAR_EXPECTED, 
+                            pos.lineNumber, pos.start ) );
+                    }
+                }
+                else
+                {
+                    char c = pos.line.charAt( pos.start );
+                    
+                    if ( Character.isAlphabetic( c ) || Character.isDigit( c ) || ( c == HYPHEN ) 
+                        || ( c == UNDERSCORE ) || ( c == SEMI_COLON ) || ( c == DOT ) || ( c == SHARP ) ) 
+                    {
+                        pos.start++;
+                    }
+                    else
+                    {
+                        // We are done 
+                        return pos.line.substring( start, pos.start );
+                    }
+                }
+            }
+            
+            return pos.line.substring( start, pos.start );
+        }
+        else
+        {
+            int start = pos.start;
+            boolean isFirst = true;
+            
+            while ( !isEmpty( pos ) )
+            {
+                if ( isFirst )
+                {
+                    isFirst = false;
+                    
+                    if ( isAlpha( pos ) ) 
+                    {
+                        // leadkeychar
+                        pos.start++;
+                    }
+                    else
+                    {
+                        // Error, we are expecting a leadKeychar
+                        throw new LdapSchemaException( I18n.err( I18n.ERR_13788_LEAD_KEY_CHAR_EXPECTED, 
+                            pos.lineNumber, pos.start ) );
+                    }
+                }
+                else
+                {
+                    char c = pos.line.charAt( pos.start );
+                    
+                    if ( Character.isAlphabetic( c ) || Character.isDigit( c ) || ( c == HYPHEN ) )
+                    {
+                        pos.start++;
+                    }
+                    else
+                    {
+                        // We are done 
+                        return pos.line.substring( start, pos.start );
+                    }
+                }
+            }
+
+            return pos.line.substring( start, pos.start );
+        }
+    }
+    
+    
+    /**
+     * <pre>
+     * qdescr ::== SQUOTE descr SQUOTE
+     * descr ::= keystring
+     * keystring ::= leadkeychar *keychar
+     * leadkeychar ::= ALPHA
+     * keychar ::= ALPHA | DIGIT | HYPHEN
+     * </pre>
+     * 
+     * In quirksMode :
+     * 
+     * <pre>
+     * qdescr ::== SQUOTE descr SQUOTE | descr | SQUOTE numericoid SQUOTE
+     * descr ::= keystring
+     * keystring ::= keychar+
+     * keychar ::= ALPHA | DIGIT | HYPHEN | UNDERSCORE | SEMI_COLON | DOT | COLON | SHARP 
+     * </pre>
+     * @throws IOException 
+     */
+    private static String getQDescrStrict( Reader reader, PosSchema pos ) throws LdapSchemaException, IOException
+    {
+        // The first quote
+        if ( !startsWith( reader, pos, SQUOTE ) )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13789_SIMPLE_QUOTE_EXPECTED_AT_START, 
+                pos.lineNumber, pos.start ) );
+        }
+        
+        pos.start++;
+        int start = pos.start;
+        boolean isFirst = true;
+        
+        while ( !startsWith( pos, SQUOTE ) )
+        {
+            if ( isFirst )
+            {
+                isFirst = false;
+                
+                if ( !isEmpty( pos ) && isAlpha( pos ) ) 
+                {
+                    // leadkeychar
+                    pos.start++;
+                }
+                else
+                {
+                    // Error, we are expecting a leadKeychar
+                    throw new LdapSchemaException( I18n.err( I18n.ERR_13788_LEAD_KEY_CHAR_EXPECTED, 
+                        pos.lineNumber, pos.start ) );
+                }
+            }
+            else
+            {
+                if ( isEmpty( pos ) )
+                {
+                    // This is an error
+                    throw new LdapSchemaException( I18n.err( I18n.ERR_13792_SIMPLE_QUOTE_EXPECTED_AT_END, 
+                        pos.lineNumber, pos.start ) );
+                }
+                
+                char c = pos.line.charAt( pos.start );
+                
+                if ( Character.isAlphabetic( c ) || Character.isDigit( c ) || ( c == HYPHEN ) )
+                {
+                    pos.start++;
+                }
+                else
+                {
+                    // This is an error
+                    throw new LdapSchemaException( I18n.err( I18n.ERR_13791_KEYCHAR_EXPECTED, c, 
+                        pos.lineNumber, pos.start ) );
+                }
+            }
+        }
+        
+        if ( startsWith( pos, SQUOTE ) )
+        {
+            // We are done, move one char forward to eliminate the simple quote
+            pos.start++;
+            
+            return pos.line.substring( start, pos.start - 1 );
+        }
+        else
+        {
+            // No closing simple quote, this is an error
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13792_SIMPLE_QUOTE_EXPECTED_AT_END, 
+                pos.lineNumber, pos.start ) );
+        }
+    }
+    
+    
+    /**
+     * <pre>
+     * qdescr ::== SQUOTE descr SQUOTE
+     * descr ::= keystring
+     * keystring ::= leadkeychar *keychar
+     * leadkeychar ::= ALPHA
+     * keychar ::= ALPHA | DIGIT | HYPHEN
+     * </pre>
+     * 
+     * In quirksMode :
+     * 
+     * <pre>
+     * qdescr ::== SQUOTE descr SQUOTE | descr | SQUOTE numericoid SQUOTE
+     * descr ::= keystring
+     * keystring ::= keychar+
+     * keychar ::= ALPHA | DIGIT | HYPHEN | UNDERSCORE | SEMI_COLON | DOT | COLON | SHARP 
+     * </pre>
+     * @throws IOException 
+     */
+    private static String getQDescrRelaxed( Reader reader, PosSchema pos ) throws LdapSchemaException, IOException
+    {
+        if ( startsWith( reader, pos, SQUOTE ) )
+        {
+            pos.start++;
+            int start = pos.start;
+            
+            while ( !startsWith( pos, SQUOTE ) )
+            {
+                if ( isEmpty( pos ) )
+                {
+                    throw new LdapSchemaException( I18n.err( I18n.ERR_13789_SIMPLE_QUOTE_EXPECTED_AT_START, 
+                        pos.lineNumber, pos.start ) );
+                }
+                
+                char c = pos.line.charAt( pos.start );
+                
+                if ( Character.isDigit( c ) || Character.isAlphabetic( c ) || ( c == HYPHEN ) || ( c == UNDERSCORE )
+                    || ( c == SEMI_COLON ) || ( c == DOT ) || ( c == COLON ) || ( c == SHARP ) )
+                {
+                    pos.start++;
+                }
+                else if ( c != SQUOTE )
+                {
+                    throw new LdapSchemaException( I18n.err( I18n.ERR_13790_NOT_A_KEYSTRING, pos.lineNumber, pos.start ) );
+                }
+            }
+            
+            pos.start++;
+            
+            return pos.line.substring( start, pos.start - 1 );
+        }
+        else
+        {
+            int start = pos.start;
+            
+            while ( !isEmpty( pos ) )
+            {
+                char c = pos.line.charAt( pos.start );
+
+                if ( Character.isDigit( c ) || Character.isAlphabetic( c ) || ( c == HYPHEN ) || ( c == UNDERSCORE )
+                    || ( c == SEMI_COLON ) || ( c == DOT ) || ( c == COLON ) || ( c == SHARP ) )
+                {
+                    pos.start++;
+                }
+                else
+                {
+                    break;
+                }
+            }
+
+            return pos.line.substring( start, pos.start );
+        }
+    }
+    
+    
+    /**
+     * No relaxed version.
+     * <pre>
+     * qdstring ::== SQUOTE dstring SQUOTE
+     * dstring  ::= ( QS | QQ | QUTF8 )+            ; escaped UTF-8 string
+     * QS       ::= ESC %x35 ( %x43 | %x63 )        ; "\5C" | "\5c", escape char
+     * QQ       ::= ESC %x32 %x37                   ; "\27", simple quote char
+     * QUTF8    ::= QUTF1 | UTFMB
+     * QUTF1    ::= %x00-26 | %x28-5B | %x5D-7F     ; All ascii but ' and \
+     * UTFMB    ::= UTF2 | UTF3 | UTF4
+     * UTF0     ::= %x80-BF
+     * UTF2     ::= %xC2-DF UTF0
+     * UTF3     ::= %xE0 %xA0-BF UTF0 | %xE1-EC UTF0 UTF0 | %xED %x80-9F UTF0 | %xEE-EF UTF0 UTF0
+     * UTF4     ::= %xF0 %x90-BF UTF0 UTF0 | %xF1-F3 UTF0 UTF0 UTF0 | %xF4 %x80-8F UTF0 UTF0
+     * ESC      ::= %x5C                            ; backslash ("\")
+     * </pre>
+     */
+    private static String getQDString( Reader reader, PosSchema pos ) throws LdapSchemaException, IOException
+    {
+        // The first quote
+        if ( !startsWith( reader, pos, SQUOTE ) )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13789_SIMPLE_QUOTE_EXPECTED_AT_START, 
+                pos.lineNumber, pos.start ) );
+        }
+        
+        pos.start++;
+        int start = pos.start;
+        int nbEscapes = 0;
+        
+        while ( !isEmpty( pos ) && !startsWith( pos, SQUOTE ) )
+        {
+            // At the moment, just swallow anything
+            if ( startsWith( pos, ESCAPE ) )
+            {
+                nbEscapes++;
+            }
+            
+            pos.start++;
+            
+        }
+        
+        if ( startsWith( pos, SQUOTE ) )
+        {
+            // We are done, move one char forward to eliminate the simple quote
+            pos.start++;
+            
+            // Now, un-escape the escaped chars
+            char[] unescaped = new char[pos.start - 1 - start - nbEscapes * 2];
+            int newPos = 0;
+            
+            for ( int i = start; i < pos.start - 1; i++ )
+            {
+                char c = pos.line.charAt( i );
+                
+                if ( c == ESCAPE )
+                {
+                    if ( i + 2 > pos.start )
+                    {
+                        // Error : not enough hex value
+                        throw new LdapSchemaException( I18n.err( I18n.ERR_13792_SIMPLE_QUOTE_EXPECTED_AT_END, 
+                            pos.lineNumber, pos.start ) );
+                    }
+                    
+                    int u = Character.digit( pos.line.charAt( i + 1 ), 16 );
+                    int l = Character.digit( pos.line.charAt( i + 2 ), 16 );
+
+                    unescaped[newPos] = ( char ) ( ( u << 4 ) + l );
+                    i += 2;
+                }
+                else
+                {
+                    unescaped[newPos] = c;
+                }
+                
+                newPos++;
+            }
+            
+            return new String( unescaped );
+        }
+        else
+        {
+            // No closing simple quote, this is an error
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13792_SIMPLE_QUOTE_EXPECTED_AT_END, 
+                pos.lineNumber, pos.start ) );
+        }
+    }
+
+
+    /**
+     * qdescrs ::= qdescr | LPAREN WSP qdescrlist WSP RPAREN
+     * qdescrlist ::= [ qdescr *( SP qdescr ) ]
+     * qdescr ::== SQUOTE descr SQUOTE
+     * descr ::= keystring
+     * keystring ::= leadkeychar *keychar
+     * leadkeychar ::= ALPHA
+     * keychar ::= ALPHA / DIGIT / HYPHEN
+     * @throws LdapSchemaException 
+     * @throws IOException 
+     */
+    private static List<String> getQDescrs( Reader reader, PosSchema pos, boolean relaxed ) throws LdapSchemaException, IOException
+    {
+        List<String> qdescrs = new ArrayList<>();
+        
+        // It may start with a '('
+        if ( startsWith( reader, pos, LPAREN ) )
+        {
+            pos.start++;
+            
+            // We have more than a name
+            skipWhites( reader, pos, false );
+            
+            while ( !startsWith( reader, pos, RPAREN ) )
+            {
+                String qdescr;
+                
+                if ( relaxed )
+                {
+                    qdescr = getQDescrRelaxed( reader, pos );
+                }
+                else
+                {
+                    qdescr = getQDescrStrict( reader, pos );
+                }
+                
+                qdescrs.add( qdescr );
+                
+                if ( startsWith( reader, pos, RPAREN ) )
+                {
+                    break;
+                }
+                
+                skipWhites( reader, pos, true );
+            }
+            
+            if ( !startsWith( reader, pos, RPAREN ) )
+            {
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13793_NO_CLOSING_PAREN, 
+                    pos.lineNumber, pos.start ) );
+            }
+            
+            pos.start++;
+        }
+        else
+        {
+            // Only one name, read it
+            String qDescr;
+            
+            if ( relaxed )
+            {
+                qDescr = getQDescrRelaxed( reader, pos );
+            }
+            else
+            {
+                qDescr = getQDescrStrict( reader, pos );
+            }
+            
+            if ( Strings.isEmpty( qDescr ) )
+            {
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13732_NAME_CANNOT_BE_NULL, pos.lineNumber, pos.start ) );
+            }
+            
+            qdescrs.add( qDescr );
+        }
+        
+        return qdescrs;
+    }
+
+
+    /**
+     * <pre>
+     * qdstrings    ::= qdstring | ( LPAREN WSP qdstringlist WSP RPAREN )
+     * qdstringlist ::= qdstring *( SP qdstring )*
+     * qdstring     ::= SQUOTE dstring SQUOTE
+     * dstring      ::= 1*( QS / QQ / QUTF8 )   ; escaped UTF-8 string
+     * </pre>
+     * @throws LdapSchemaException 
+     * @throws IOException 
+     */
+    private static List<String> getQDStrings( Reader reader, PosSchema pos ) 
+        throws LdapSchemaException, IOException
+    {
+        List<String> qdStrings = new ArrayList<>();
+        
+        // It may start with a '('
+        if ( startsWith( reader, pos, LPAREN ) )
+        {
+            pos.start++;
+            
+            // We have more than a name
+            skipWhites( reader, pos, false );
+            
+            while ( !startsWith( reader, pos, RPAREN ) )
+            {
+                qdStrings.add( getQDString( reader, pos ) );
+                
+                if ( startsWith( reader, pos, RPAREN ) )
+                {
+                    break;
+                }
+                
+                skipWhites( reader, pos, true );
+            }
+            
+            if ( !startsWith( reader, pos, RPAREN ) )
+            {
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13793_NO_CLOSING_PAREN, 
+                    pos.lineNumber, pos.start ) );
+            }
+            
+            pos.start++;
+        }
+        else
+        {
+            // Only one name, read it
+            qdStrings.add( getQDString( reader, pos ) );
+        }
+        
+        return qdStrings;
+    }
+
+    
+    /**
+     * <pre>
+     * oids     ::= oid | ( LPAREN WSP oidlist WSP RPAREN )
+     * oidlist  ::= oid *( WSP DOLLAR WSP oid )
+     * </pre>
+     */
+    private static List<String> getOidsStrict( Reader reader, PosSchema pos ) throws LdapSchemaException, IOException
+    {
+        List<String> oids = new ArrayList<>();
+        
+        // It may start with a '('
+        if ( startsWith( reader, pos, LPAREN ) )
+        {
+            pos.start++;
+            
+            // We have more than a name
+            skipWhites( reader, pos, false );
+            boolean moreExpected = false;
+            
+            while ( !startsWith( reader, pos, RPAREN ) )
+            {
+                moreExpected = false;
+                
+                oids.add( getOidStrict( pos ) );
+                
+                if ( startsWith( reader, pos, RPAREN ) )
+                {
+                    break;
+                }
+                
+                skipWhites( reader, pos, false );
+                
+                if ( startsWith( reader, pos, DOLLAR ) )
+                {
+                    pos.start++;
+                    moreExpected = true;
+                }
+
+                skipWhites( reader, pos, false );
+            }
+            
+            if ( !startsWith( reader, pos, RPAREN ) )
+            {
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13793_NO_CLOSING_PAREN, 
+                    pos.lineNumber, pos.start ) );
+            }
+            
+            if ( moreExpected )
+            {
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13794_MORE_OIDS_EXPECTED, 
+                    pos.lineNumber, pos.start ) );
+            }
+            
+            pos.start++;
+        }
+        else
+        {
+            // Only one name, read it
+            oids.add( getOidStrict( pos ) );
+        }
+        
+        return oids;
+    }
+
+    
+    /**
+     * <pre>
+     * oids     ::= oid | ( LPAREN WSP oidlist WSP RPAREN )
+     * oidlist  ::= oid *( WSP DOLLAR WSP oid )
+     * </pre>
+     */
+    private static List<String> getOidsRelaxed( Reader reader, PosSchema pos ) throws LdapSchemaException, IOException
+    {
+        List<String> oids = new ArrayList<>();
+        
+        // It may start with a '('
+        if ( startsWith( reader, pos, LPAREN ) )
+        {
+            pos.start++;
+            
+            // We have more than a name
+            skipWhites( reader, pos, false );
+            boolean moreExpected = false;
+            
+            while ( !startsWith( reader, pos, RPAREN ) )
+            {
+                moreExpected = false;
+                
+                oids.add( getOidRelaxed( pos, UN_QUOTED ) );
+                
+                if ( startsWith( reader, pos, RPAREN ) )
+                {
+                    break;
+                }
+                
+                skipWhites( reader, pos, false );
+                
+                if ( startsWith( reader, pos, DOLLAR ) )
+                {
+                    pos.start++;
+                    moreExpected = true;
+                }
+
+                skipWhites( reader, pos, false );
+            }
+            
+            if ( !startsWith( reader, pos, RPAREN ) )
+            {
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13793_NO_CLOSING_PAREN, 
+                    pos.lineNumber, pos.start ) );
+            }
+            
+            if ( moreExpected )
+            {
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13794_MORE_OIDS_EXPECTED, 
+                    pos.lineNumber, pos.start ) );
+            }
+            
+            pos.start++;
+        }
+        else
+        {
+            // Only one name, read it
+            oids.add( getOidRelaxed( pos, UN_QUOTED ) );
+        }
+        
+        return oids;
+    }
+
+    
+    /**
+     * noidlen = oidStrict [ LCURLY len RCURLY ]
+     */
+    private static void getNoidLenStrict( MutableAttributeType attributeType, PosSchema pos ) throws LdapSchemaException
+    {
+        // Get the oid
+        String oid = getOidStrict( pos );
+        
+        if ( oid.length() == 0 )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13828_MISSING_SYNTAX_OID, pos.line, pos.start ) );
+        }
+        
+        attributeType.setSyntaxOid( oid );
+
+        // Then the len, if any
+        if ( startsWith( pos, LBRACE ) )
+        {
+            pos.start++;
+            int start = pos.start;
+            
+            while ( !isEmpty( pos ) && isDigit( pos ) )
+            {
+                pos.start++;
+            }
+            
+            if ( startsWith( pos, RBRACE ) )
+            {
+                String lenStr = pos.line.substring( start, pos.start );
+                
+                if ( lenStr.length() == 0 )
+                {
+                    throw new LdapSchemaException( I18n.err( I18n.ERR_13827_EMPTY_SYNTAX_LEN, pos.line, pos.start ) );
+                }
+                
+                pos.start++;
+                
+                if ( Strings.isEmpty( lenStr ) )
+                {
+                    attributeType.setSyntaxLength( -1L );
+                }
+                else
+                {
+                    attributeType.setSyntaxLength( Long.parseLong( lenStr ) );
+                }
+            }
+            else
+            {
+                // The opening curly hasn't been closed
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13795_OPENED_BRACKET_NOT_CLOSED, 
+                    pos.lineNumber, pos.start ) );
+            }
+        }
+    }
+
+    
+    /**
+     * noidlen = oidRelaxed [ LCURLY len RCURLY ]
+     */
+    private static void getNoidLenRelaxed( MutableAttributeType attributeType, PosSchema pos ) throws LdapSchemaException
+    {
+        // Check for quotes
+        boolean hasQuote = false;
+
+        char c = pos.line.charAt( pos.start );
+        
+        if ( c == SQUOTE )
+        {
+            hasQuote = true;
+            pos.start++;
+
+            if ( isEmpty( pos ) )
+            {
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13792_SIMPLE_QUOTE_EXPECTED_AT_END, 
+                    pos.lineNumber, pos.start ) );
+            }
+        }
+
+        // Get the oid
+        String oid = getOidRelaxed( pos, hasQuote );
+        
+        if ( oid.length() == 0 )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13828_MISSING_SYNTAX_OID, pos.line, pos.start ) );
+        }
+        
+        attributeType.setSyntaxOid( oid );
+
+        // Then the len, if any
+        if ( startsWith( pos, LBRACE ) )
+        {
+            pos.start++;
+            int start = pos.start;
+            
+            while ( !isEmpty( pos ) && isDigit( pos ) )
+            {
+                pos.start++;
+            }
+            
+            if ( startsWith( pos, RBRACE ) )
+            {
+                String lenStr = pos.line.substring( start, pos.start );
+                
+                pos.start++;
+                
+                if ( Strings.isEmpty( lenStr ) )
+                {
+                    attributeType.setSyntaxLength( -1L );
+                }
+                else
+                {
+                    attributeType.setSyntaxLength( Long.parseLong( lenStr ) );
+                }
+            }
+            else
+            {
+                // The opening curly hasn't been closed
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13795_OPENED_BRACKET_NOT_CLOSED, 
+                    pos.lineNumber, pos.start ) );
+            }
+        }
+        
+        if ( hasQuote )
+        {
+            if ( isEmpty( pos ) )
+            {
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13792_SIMPLE_QUOTE_EXPECTED_AT_END, 
+                    pos.lineNumber, pos.start ) );
+            }
+            
+            c = pos.line.charAt( pos.start );
+            
+            if ( c == SQUOTE )
+            {
+               pos.start++;
+           }
+           else
+           {
+               throw new LdapSchemaException( I18n.err( I18n.ERR_13792_SIMPLE_QUOTE_EXPECTED_AT_END, 
+                   pos.lineNumber, pos.start ) );
+           }
+        }
+    }
+    
+
+    
+    /**
+     * <pre>
+     * ruleid ::= number
+     * number ::= DIGIT | LDIGIT DIGIT+
+     * DIGIT  ::= [0-9]
+     * LDIGIT ::= [1-9]
+     */
+    private static int getRuleId( PosSchema pos ) throws LdapSchemaException
+    {
+        int start = pos.start;
+
+        while ( !isEmpty( pos ) && isDigit( pos ) )
+        {
+            pos.start++;
+        }
+        
+        if ( start == pos.start )
+        {
+            // No ruleID
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13811_INVALID_RULE_ID, 
+                pos.lineNumber, pos.start ) );
+        }
+
+        String lenStr = pos.line.substring( start, pos.start );
+        
+        return Integer.parseInt( lenStr );
+    }
+
+    
+    /**
+     * <pre>
+     * ruleids      ::= ruleid | ( LPAREN WSP ruleidlist WSP RPAREN )
+     * ruleidlist   ::= ruleid ( SP ruleid )*
+     * </pre>
+     */
+    private static List<Integer> getRuleIds( Reader reader, PosSchema pos ) throws LdapSchemaException, IOException
+    {
+        List<Integer> ruleIds = new ArrayList<>();
+        
+        // It may start with a '('
+        if ( startsWith( reader, pos, LPAREN ) )
+        {
+            pos.start++;
+            
+            // We may have more than a ruleid
+            skipWhites( reader, pos, false );
+            boolean moreExpected = false;
+            
+            while ( !startsWith( reader, pos, RPAREN ) )
+            {
+                moreExpected = false;
+                
+                ruleIds.add( getRuleId( pos ) );
+                
+                if ( startsWith( reader, pos, RPAREN ) )
+                {
+                    break;
+                }
+                
+                skipWhites( reader, pos, false );
+                
+                if ( startsWith( reader, pos, DOLLAR ) )
+                {
+                    pos.start++;
+                    moreExpected = true;
+                }
+
+                skipWhites( reader, pos, false );
+            }
+            
+            if ( !startsWith( reader, pos, RPAREN ) )
+            {
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13793_NO_CLOSING_PAREN, 
+                    pos.lineNumber, pos.start ) );
+            }
+            
+            if ( moreExpected )
+            {
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13813_MORE_RULE_IDS_EXPECTED, 
+                    pos.lineNumber, pos.start ) );
+            }
+            
+            pos.start++;
+        }
+        else
+        {
+            // Only one ruleId, read it
+            ruleIds.add( getRuleId( pos ) );
+        }
+        
+        return ruleIds;
+    }
+    
+    
+    private static UsageEnum getUsageStrict( PosSchema pos ) throws LdapSchemaException
+    {
+        if ( isEmpty( pos ) )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13796_USAGE_EXPECTED, 
+                pos.lineNumber, pos.start ) );
+        }
+        
+        if ( startsWith( pos, USER_APPLICATIONS_STR ) )
+        { 
+            pos.start += USER_APPLICATIONS_STR.length();
+            
+            return UsageEnum.USER_APPLICATIONS;
+        }
+        else if ( startsWith( pos, DIRECTORY_OPERATION_STR ) )
+        {
+            pos.start += DIRECTORY_OPERATION_STR.length();
+            
+            return UsageEnum.DIRECTORY_OPERATION;
+        }
+        else if ( startsWith( pos, DISTRIBUTED_OPERATION_STR ) )
+        { 
+            pos.start += DISTRIBUTED_OPERATION_STR.length();
+            
+            return UsageEnum.DISTRIBUTED_OPERATION;
+        }
+        else if ( startsWith( pos, DSA_OPERATION_STR ) )
+        { 
+            pos.start += DSA_OPERATION_STR.length();
+
+            return UsageEnum.DSA_OPERATION;
+        }
+        else
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13797_USAGE_UNKNOWN, 
+                pos.lineNumber, pos.start ) );
+        }
+    }
+    
+    
+    private static UsageEnum getUsageRelaxed( PosSchema pos ) throws LdapSchemaException
+    {
+        if ( isEmpty( pos ) )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13796_USAGE_EXPECTED, 
+                pos.lineNumber, pos.start ) );
+        }
+        
+        boolean isSQuoted = false;
+        boolean isDQuoted = false;
+        
+        if ( pos.line.charAt( pos.start ) == SQUOTE )
+        {
+            isSQuoted = true;
+            pos.start++;
+
+            if ( isEmpty( pos ) )
+            {
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13796_USAGE_EXPECTED, 
+                    pos.lineNumber, pos.start ) );
+            }
+        }
+        else if ( pos.line.charAt( pos.start ) == DQUOTE )
+        {
+            isDQuoted = true;
+            pos.start++;
+
+            if ( isEmpty( pos ) )
+            {
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13796_USAGE_EXPECTED, 
+                    pos.lineNumber, pos.start ) );
+            }
+        }
+
+        UsageEnum usage = UsageEnum.USER_APPLICATIONS;
+
+        if ( startsWith( pos, USER_APPLICATIONS_STR ) )
+        { 
+            pos.start += USER_APPLICATIONS_STR.length();
+            
+            usage = UsageEnum.USER_APPLICATIONS;
+        }
+        else if ( startsWith( pos, DIRECTORY_OPERATION_STR ) )
+        {
+            pos.start += DIRECTORY_OPERATION_STR.length();
+            
+            usage = UsageEnum.DIRECTORY_OPERATION;
+        } 
+        else if ( startsWith( pos, DISTRIBUTED_OPERATION_STR ) )
+        { 
+            pos.start += DISTRIBUTED_OPERATION_STR.length();
+            
+            usage = UsageEnum.DISTRIBUTED_OPERATION;
+        } 
+        else if ( startsWith( pos, DSA_OPERATION_STR ) )
+        { 
+            pos.start += DSA_OPERATION_STR.length();
+
+            usage = UsageEnum.DSA_OPERATION;
+        } 
+        else
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13797_USAGE_UNKNOWN, 
+                pos.lineNumber, pos.start ) );
+        }
+        
+        if ( isSQuoted )
+        {
+            if ( isEmpty( pos ) )
+            {
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13796_USAGE_EXPECTED, 
+                    pos.lineNumber, pos.start ) );
+            }
+            
+            if ( pos.line.charAt( pos.start ) != SQUOTE )
+            {
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13792_SIMPLE_QUOTE_EXPECTED_AT_END, 
+                    pos.lineNumber, pos.start ) );
+            }
+            
+            pos.start++;
+        }
+        else if ( isDQuoted )
+        {
+            if ( isEmpty( pos ) )
+            {
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13796_USAGE_EXPECTED, 
+                    pos.lineNumber, pos.start ) );
+            }
+            
+            if ( pos.line.charAt( pos.start ) != DQUOTE )
+            {
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13792_SIMPLE_QUOTE_EXPECTED_AT_END, 
+                    pos.lineNumber, pos.start ) );
+            }
+            
+            pos.start++;
+        }
+        
+        return usage;
+    }
+
+    
+    /**
+     * <pre>
+     * extension    ::= xstring SP qdstrings
+     * xstring      ::= "X" HYPHEN ( ALPHA | HYPHEN | USCORE )+
+     * qdstrings    ::= qdstring | ( LPAREN WSP qdstringlist WSP RPAREN )
+     * qdstringlist ::= qdstring *( SP qdstring )*
+     * qdstring     ::= SQUOTE dstring SQUOTE
+     * dstring      ::= 1*( QS / QQ / QUTF8 )   ; escaped UTF-8 string
+     * </pre>
+     * @throws IOException 
+     * @throws LdapSchemaException 
+     */
+    private static void processExtension( Reader reader, PosSchema pos, SchemaObject schemaObject ) 
+        throws LdapSchemaException, IOException
+    {
+        // The xstring first
+        String extensionKey = getXString( pos );
+        
+        skipWhites( reader, pos, true );
+        
+        List<String> extensionValues = getQDStrings( reader, pos );
+        
+        if ( schemaObject.hasExtension( extensionKey ) )
+        {
+            throw new LdapSchemaException( 
+                I18n.err( I18n.ERR_13780_SCHEMA_OBJECT_DESCRIPTION_HAS_ELEMENT_TWICE, extensionKey, 
+                pos.lineNumber, pos.start ) );
+        }
+
+        schemaObject.addExtension( extensionKey, extensionValues );
+    }
+    
+    
+    /**
+     * <pre>
+     * xstring      ::= "X" HYPHEN ( ALPHA | HYPHEN | USCORE )+
+     * </pre>
+     */
+    private static String getXString( PosSchema pos ) throws LdapSchemaException
+    {
+        int start = pos.start;
+        
+        if ( startsWith( pos, EXTENSION_PREFIX ) )
+        {
+            pos.start += 2;
+            
+            // Now parse the remaining string
+            while ( !isEmpty( pos ) && ( isAlpha( pos ) || startsWith( pos, HYPHEN ) || startsWith( pos, UNDERSCORE ) ) )
+            {
+                pos.start++;
+            }
+            
+            return pos.line.substring( start, pos.start );
+        }
+        else
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13802_EXTENSION_SHOULD_START_WITH_X, 
+                pos.lineNumber, pos.start ) );
+        }
+    }
+    
+    
+    /**
+     * A FQCN
+     * <pre>
+     * FQCN ::= FQCN_IDENTIFIER ( '.' FQCN_IDENTIFIER )*
+     * FQCN_IDENTIFIER ::= ( JavaLetter ( JavaLetterOrDigit )*
+     */
+    private static String getFqcn( PosSchema pos ) throws LdapSchemaException
+    {
+        if ( ( pos.line == null ) || ( pos.line.length() - pos.start < 1 ) )
+        {
+            return "";
+        }
+
+        int start = pos.start;
+        boolean isFirst = true;
+        boolean dotSeen = false;
+        
+        while ( true )
+        {
+            char c = pos.line.charAt( pos.start );
+            
+            if ( isFirst )
+            {
+                if ( !Character.isJavaIdentifierStart( c ) )
+                {
+                    throw new LdapSchemaException( I18n.err( I18n.ERR_13822_INVALID_FQCN_BAD_IDENTIFIER_START, 
+                        pos.lineNumber, pos.start ) );
+                }
+                
+                isFirst = false;
+                dotSeen = false;
+                pos.start++;
+            }
+            else
+            {
+                if ( c == DOT ) 
+                {
+                    if ( dotSeen )
+                    {
+                        throw new LdapSchemaException( I18n.err( I18n.ERR_13823_INVALID_FQCN_DOUBLE_DOT, 
+                            pos.lineNumber, pos.start ) );
+                    }
+                    else
+                    {
+                        isFirst = true;
+                        dotSeen = true;
+                        pos.start++;
+                    }
+                }
+                else
+                {
+                    if ( Character.isJavaIdentifierPart( c ) )
+                    {
+                        pos.start++;
+                        dotSeen = false;
+                    }
+                    else
+                    {
+                        return pos.line.substring( start, pos.start );
+                    }
+                }
+            }
+            
+            if ( pos.line.length() - pos.start < 1 )
+            {
+                return pos.line.substring( start, pos.start );
+            }
+        }
+    }
+
+    
+    /**
+     * A base64 string
+     * <pre>
+     * byteCode ::= ( [a-z] | [A-Z] | [0-9] | '+' | '/' | '=' )*
+     */
+    private static String getByteCode( PosSchema pos )
+    {
+        if ( ( pos.line == null ) || ( pos.line.length() - pos.start < 1 ) )
+        {
+            return "";
+        }
+
+        int start = pos.start;
+        
+        
+        while ( !isEmpty( pos ) && ( isAlpha( pos ) || isDigit( pos ) || startsWith( pos, PLUS ) 
+            || startsWith( pos, SLASH ) || startsWith( pos, EQUAL ) ) )
+        {
+            pos.start++;
+            
+            if ( ( pos.line == null ) || ( pos.line.length() - pos.start < 1 ) )
+            {
+                return pos.line.substring( start, pos.start );
+            }
+        }
+        
+        return pos.line.substring( start, pos.start );
+    }
+    
+    
+    private static int checkElement( int elementsSeen, SchemaObjectElements element, PosSchema pos ) throws LdapSchemaException
+    {
+        if ( ( elementsSeen & element.getValue() ) != 0 )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13780_SCHEMA_OBJECT_DESCRIPTION_HAS_ELEMENT_TWICE, 
+                element, pos.lineNumber, pos.start ) );
+        }
+        
+        elementsSeen |= element.getValue();
+        
+        return elementsSeen;
+    }
+
+    
+    /**
+     * Production for matching attribute type descriptions. It is fault-tolerant
+     * against element ordering.
+     *
+     * <pre>
+     * AttributeTypeDescription = LPAREN WSP
+     *     numericoid                    ; object identifier
+     *     [ SP "NAME" SP qdescrs ]      ; short names (descriptors)
+     *     [ SP "DESC" SP qdstring ]     ; description
+     *     [ SP "OBSOLETE" ]             ; not active
+     *     [ SP "SUP" SP oid ]           ; supertype
+     *     [ SP "EQUALITY" SP oid ]      ; equality matching rule
+     *     [ SP "ORDERING" SP oid ]      ; ordering matching rule
+     *     [ SP "SUBSTR" SP oid ]        ; substrings matching rule
+     *     [ SP "SYNTAX" SP noidlen ]    ; value syntax
+     *     [ SP "SINGLE-VALUE" ]         ; single-value
+     *     [ SP "COLLECTIVE" ]           ; collective
+     *     [ SP "NO-USER-MODIFICATION" ] ; not user modifiable
+     *     [ SP "USAGE" SP usage ]       ; usage
+     *     extensions WSP RPAREN         ; extensions
+     * 
+     * usage = "userApplications"     /  ; user
+     *         "directoryOperation"   /  ; directory operational
+     *         "distributedOperation" /  ; DSA-shared operational
+     *         "dSAOperation"            ; DSA-specific operational     
+     * 
+     * extensions = *( SP xstring SP qdstrings )
+     * xstring = "X" HYPHEN 1*( ALPHA / HYPHEN / USCORE ) 
+     * </pre>
+     * 
+     * @param attributeTypeDescription The String containing the AttributeTypeDescription
+     * @return An instance of AttributeType
+     * @throws ParseException If the element was invalid
+     */
+    public AttributeType parseAttributeType( String attributeTypeDescription ) throws ParseException
+    {
+        if ( ( attributeTypeDescription == null ) || Strings.isEmpty( attributeTypeDescription.trim() ) )
+        {
+            throw new ParseException( I18n.err( I18n.ERR_13716_NULL_OR_EMPTY_STRING_SCHEMA_OBJECT ), 0 );
+        }
+        
+        try ( Reader reader = new BufferedReader( new StringReader( attributeTypeDescription ) ) )
+        {
+            PosSchema pos = new PosSchema();
+
+            if ( isQuirksModeEnabled )
+            {
+                return parseAttributeTypeRelaxed( reader, pos, objectIdentifierMacros );
+            }
+            else
+            {
+                return parseAttributeTypeStrict( reader, pos, objectIdentifierMacros );
+            }
+        }
+        catch ( IOException | LdapSchemaException e )
+        {
+            throw new ParseException( e.getMessage(), 0 );
+        }
+    }
+
+    
+    /**
+     * Production for matching attribute type descriptions. It is fault-tolerant
+     * against element ordering. It's strict.
+     *
+     * <pre>
+     * AttributeTypeDescription = LPAREN WSP
+     *     numericoid                    ; object identifier
+     *     [ SP "NAME" SP qdescrs ]      ; short names (descriptors)
+     *     [ SP "DESC" SP qdstring ]     ; description
+     *     [ SP "OBSOLETE" ]             ; not active
+     *     [ SP "SUP" SP oid ]           ; supertype
+     *     [ SP "EQUALITY" SP oid ]      ; equality matching rule
+     *     [ SP "ORDERING" SP oid ]      ; ordering matching rule
+     *     [ SP "SUBSTR" SP oid ]        ; substrings matching rule
+     *     [ SP "SYNTAX" SP noidlen ]    ; value syntax
+     *     [ SP "SINGLE-VALUE" ]         ; single-value
+     *     [ SP "COLLECTIVE" ]           ; collective
+     *     [ SP "NO-USER-MODIFICATION" ] ; not user modifiable
+     *     [ SP "USAGE" SP usage ]       ; usage
+     *     extensions WSP RPAREN         ; extensions
+     * 
+     * usage = "userApplications"     /  ; user
+     *         "directoryOperation"   /  ; directory operational
+     *         "distributedOperation" /  ; DSA-shared operational
+     *         "dSAOperation"            ; DSA-specific operational     
+     * 
+     * extensions = *( SP xstring SP qdstrings )
+     * xstring = "X" HYPHEN 1*( ALPHA / HYPHEN / USCORE ) 
+     * </pre>
+     * @throws IOException 
+     * @throws LdapSchemaException 
+     */
+    private static AttributeType parseAttributeTypeStrict( Reader reader, PosSchema pos,
+        Map<String, OpenLdapObjectIdentifierMacro> objectIdentifierMacros ) throws IOException, LdapSchemaException
+    {
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // we must have a '('
+        if ( pos.line.charAt( pos.start ) != LPAREN )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13829_NO_OPENING_PAREN, 
+                pos.lineNumber, pos.start ) );
+        }
+        else
+        {
+            pos.start++;
+        }
+        
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // Now, the OID. 
+        String oid = getOidAndMacroRelaxed( pos, objectIdentifierMacros );
+        
+        // Check that the OID is valid
+        if ( !Oid.isOid( oid ) )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13787_OID_EXPECTED, pos.lineNumber, pos.start ) );
+        }
+        
+        MutableAttributeType attributeType = new MutableAttributeType( oid );
+        boolean hasSup = false;
+        boolean hasSyntax = false;
+        int elementsSeen = 0;
+        
+        while ( true )
+        {
+            if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+                break;
+            }
+            
+            skipWhites( reader, pos, true );
+
+            if ( startsWith( pos, NAME_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.NAME, pos );
+                
+                pos.start += NAME_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                attributeType.setNames( getQDescrs( reader, pos, STRICT ) );
+            }
+            else if ( startsWith( pos, DESC_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.DESC, pos );
+
+                pos.start += DESC_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                attributeType.setDescription( getQDString( reader, pos ) );
+            }
+            else if ( startsWith( pos, OBSOLETE_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.OBSOLETE, pos );
+                
+                pos.start += OBSOLETE_STR.length();
+                
+                attributeType.setObsolete( true );
+            }
+            else if ( startsWith( pos, SUP_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.SUP, pos );
+                
+                pos.start += SUP_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                String superiorOid = getOidStrict( pos );
+
+                attributeType.setSuperiorOid( superiorOid );
+                hasSup = true;
+            }
+            else if ( startsWith( pos, EQUALITY_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.EQUALITY, pos );
+                
+                pos.start += EQUALITY_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                String equalityOid = getOidStrict( pos );
+
+                attributeType.setEqualityOid( equalityOid );
+            }
+            else if ( startsWith( pos, ORDERING_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.ORDERING, pos );
+                
+                pos.start += ORDERING_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                String orderingOid = getOidStrict( pos );
+
+                attributeType.setOrderingOid( orderingOid );
+            }
+            else if ( startsWith( pos, SUBSTR_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.SUBSTR, pos );
+
+                pos.start += SUBSTR_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                String substrOid = getOidStrict( pos );
+
+                attributeType.setSubstringOid( substrOid );
+            }
+            else if ( startsWith( pos, SYNTAX_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.SYNTAX, pos );
+                
+                pos.start += SYNTAX_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                getNoidLenStrict( attributeType, pos );
+
+                hasSyntax = true;
+            }
+            else if ( startsWith( pos, SINGLE_VALUE_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.SINGLE_VALUE, pos );
+                
+                pos.start += SINGLE_VALUE_STR.length();
+                
+                attributeType.setSingleValued( true );
+            }
+            else if ( startsWith( pos, COLLECTIVE_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.COLLECTIVE, pos );
+                
+                pos.start += COLLECTIVE_STR.length();
+                
+                attributeType.setCollective( true );
+            }
+            else if ( startsWith( pos, NO_USER_MODIFICATION_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.NO_USER_MODIFICATION, pos );
+                
+                pos.start += NO_USER_MODIFICATION_STR.length();
+                
+                attributeType.setUserModifiable( false );
+            }
+            else if ( startsWith( pos, USAGE_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.USAGE, pos );
+                
+                pos.start += USAGE_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                UsageEnum usage = getUsageStrict( pos );
+
+                attributeType.setUsage( usage );
+            }
+            else if ( startsWith( pos, EXTENSION_PREFIX ) )
+            {
+                processExtension( reader, pos, attributeType );
+            }
+            else if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+                break;
+            }
+            else
+            {
+                // This is an error
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13798_AT_DESCRIPTION_INVALID, 
+                    pos.lineNumber, pos.start ) );
+            }
+        }
+        
+        // Semantic checks
+        if ( !hasSup && !hasSyntax )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13799_SYNTAX_OR_SUP_REQUIRED, 
+                pos.lineNumber, pos.start ) );
+        }
+
+        if ( attributeType.isCollective() && ( attributeType.getUsage() != UsageEnum.USER_APPLICATIONS ) )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13800_COLLECTIVE_REQUIRES_USER_APPLICATION, 
+                pos.lineNumber, pos.start ) );
+        }
+    
+        // NO-USER-MODIFICATION requires an operational USAGE.
+        if ( !attributeType.isUserModifiable() && ( attributeType.getUsage() == UsageEnum.USER_APPLICATIONS ) )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13801_NO_USER_MOD_REQUIRE_OPERATIONAL, 
+                pos.lineNumber, pos.start ) );
+        }
+        
+        return attributeType;
+    }
+    
+    
+    /**
+     * Production for matching attribute type descriptions. It is fault-tolerant
+     * against element ordering. It's relaxed.
+     *
+     * <pre>
+     * AttributeTypeDescription = LPAREN WSP
+     *     numericoid                    ; object identifier
+     *     [ SP "NAME" SP qdescrs ]      ; short names (descriptors)
+     *     [ SP "DESC" SP qdstring ]     ; description
+     *     [ SP "OBSOLETE" ]             ; not active
+     *     [ SP "SUP" SP oid ]           ; supertype
+     *     [ SP "EQUALITY" SP oid ]      ; equality matching rule
+     *     [ SP "ORDERING" SP oid ]      ; ordering matching rule
+     *     [ SP "SUBSTR" SP oid ]        ; substrings matching rule
+     *     [ SP "SYNTAX" SP noidlen ]    ; value syntax
+     *     [ SP "SINGLE-VALUE" ]         ; single-value
+     *     [ SP "COLLECTIVE" ]           ; collective
+     *     [ SP "NO-USER-MODIFICATION" ] ; not user modifiable
+     *     [ SP "USAGE" SP usage ]       ; usage
+     *     extensions WSP RPAREN         ; extensions
+     * 
+     * usage = "userApplications"     /  ; user
+     *         "directoryOperation"   /  ; directory operational
+     *         "distributedOperation" /  ; DSA-shared operational
+     *         "dSAOperation"            ; DSA-specific operational     
+     * 
+     * extensions = *( SP xstring SP qdstrings )
+     * xstring = "X" HYPHEN 1*( ALPHA / HYPHEN / USCORE ) 
+     * </pre>
+     * @throws IOException 
+     * @throws LdapSchemaException 
+     */
+    private static AttributeType parseAttributeTypeRelaxed( Reader reader, PosSchema pos,
+        Map<String, OpenLdapObjectIdentifierMacro> objectIdentifierMacros ) throws IOException, LdapSchemaException
+    {
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // we must have a '('
+        if ( pos.line.charAt( pos.start ) != LPAREN )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13829_NO_OPENING_PAREN, 
+                pos.lineNumber, pos.start ) );
+        }
+        else
+        {
+            pos.start++;
+        }
+        
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // Now, the OID. 
+        String oid = getOidAndMacroRelaxed( pos, objectIdentifierMacros );
+        
+        MutableAttributeType attributeType = new MutableAttributeType( oid );
+        int elementsSeen = 0;
+        
+        while ( true )
+        {
+            if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+                break;
+            }
+            
+            skipWhites( reader, pos, true );
+
+            if ( startsWith( pos, NAME_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.NAME, pos );
+                
+                pos.start += NAME_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                attributeType.setNames( getQDescrs( reader, pos, RELAXED ) );
+            }
+            else if ( startsWith( pos, DESC_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.DESC, pos );
+
+                pos.start += DESC_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                attributeType.setDescription( getQDString( reader, pos ) );
+            }
+            else if ( startsWith( pos, OBSOLETE_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.OBSOLETE, pos );
+                
+                pos.start += OBSOLETE_STR.length();
+                
+                attributeType.setObsolete( true );
+            }
+            else if ( startsWith( pos, SUP_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.SUP, pos );
+                
+                pos.start += SUP_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                String superiorOid = getOidRelaxed( pos, false );
+
+                attributeType.setSuperiorOid( superiorOid );
+            }
+            else if ( startsWith( pos, EQUALITY_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.EQUALITY, pos );
+                
+                pos.start += EQUALITY_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                String equalityOid = getOidRelaxed( pos, false );
+
+                attributeType.setEqualityOid( equalityOid );
+            }
+            else if ( startsWith( pos, ORDERING_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.ORDERING, pos );
+                
+                pos.start += ORDERING_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                String orderingOid = getOidRelaxed( pos, false );
+
+                attributeType.setOrderingOid( orderingOid );
+            }
+            else if ( startsWith( pos, SUBSTR_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.SUBSTR, pos );
+
+                pos.start += SUBSTR_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                String substrOid = getOidRelaxed( pos, false );
+
+                attributeType.setSubstringOid( substrOid );
+            }
+            else if ( startsWith( pos, SYNTAX_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.SYNTAX, pos );
+                
+                pos.start += SYNTAX_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                getNoidLenRelaxed( attributeType, pos );
+            }
+            else if ( startsWith( pos, SINGLE_VALUE_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.SINGLE_VALUE, pos );
+                
+                pos.start += SINGLE_VALUE_STR.length();
+                
+                attributeType.setSingleValued( true );
+            }
+            else if ( startsWith( pos, COLLECTIVE_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.COLLECTIVE, pos );
+                
+                pos.start += COLLECTIVE_STR.length();
+                
+                attributeType.setCollective( true );
+            }
+            else if ( startsWith( pos, NO_USER_MODIFICATION_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.NO_USER_MODIFICATION, pos );
+                
+                pos.start += NO_USER_MODIFICATION_STR.length();
+                
+                attributeType.setUserModifiable( false );
+            }
+            else if ( startsWith( pos, USAGE_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, AttributeTypeElements.USAGE, pos );
+                
+                pos.start += USAGE_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                UsageEnum usage = getUsageRelaxed( pos );
+
+                attributeType.setUsage( usage );
+            }
+            else if ( startsWith( pos, EXTENSION_PREFIX ) )
+            {
+                processExtension( reader, pos, attributeType );
+            }
+            else if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+                break;
+            }
+            else
+            {
+                // This is an error
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13798_AT_DESCRIPTION_INVALID, 
+                    pos.lineNumber, pos.start ) );
+            }
+        }
+        
+        return attributeType;
+    }
+
+    
+    /**
+     * Production for matching DitContentRule descriptions. It is fault-tolerant
+     * against element ordering.
+     *
+     * <pre>
+     * DITContentRuleDescription = LPAREN WSP
+     *    numericoid                 ; object identifier
+     *    [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
+     *    [ SP "DESC" SP qdstring ]  ; description
+     *    [ SP "OBSOLETE" ]          ; not active
+     *    [ SP "AUX" SP oids ]       ; auxiliary object classes
+     *    [ SP "MUST" SP oids ]      ; attribute types
+     *    [ SP "MAY" SP oids ]       ; attribute types
+     *    [ SP "NOT" SP oids ]       ; attribute types
+     *    extensions WSP RPAREN      ; extensions
+     * </pre>
+     * 
+     * @param ditContentRuleDescription The String containing the DitContentRuleDescription
+     * @return An instance of ditContentRule
+     * @throws ParseException If the element was invalid
+     */
+    public DitContentRule parseDitContentRule( String ditContentRuleDescription ) throws ParseException
+    {
+        if ( ( ditContentRuleDescription == null ) || Strings.isEmpty( ditContentRuleDescription.trim() ) )
+        {
+            throw new ParseException( I18n.err( I18n.ERR_13716_NULL_OR_EMPTY_STRING_SCHEMA_OBJECT ), 0 );
+        }
+        
+        try ( Reader reader = new BufferedReader( new StringReader( ditContentRuleDescription ) ) )
+        {
+            PosSchema pos = new PosSchema();
+
+            if ( isQuirksModeEnabled )
+            {
+                return parseDitContentRuleRelaxed( reader, pos, objectIdentifierMacros );
+            }
+            else
+            {
+                return parseDitContentRuleStrict( reader, pos, objectIdentifierMacros );
+            }
+        }
+        catch ( IOException | LdapSchemaException e )
+        {
+            throw new ParseException( e.getMessage(), 0 );
+        }
+    }
+
+    
+    /**
+     * Production for DitContentRule descriptions. It is fault-tolerant
+     * against element ordering.
+     *
+     * <pre>
+     * DITContentRuleDescription = LPAREN WSP
+     *    numericoid                 ; object identifier
+     *    [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
+     *    [ SP "DESC" SP qdstring ]  ; description
+     *    [ SP "OBSOLETE" ]          ; not active
+     *    [ SP "AUX" SP oids ]       ; auxiliary object classes
+     *    [ SP "MUST" SP oids ]      ; attribute types
+     *    [ SP "MAY" SP oids ]       ; attribute types
+     *    [ SP "NOT" SP oids ]       ; attribute types
+     *    extensions WSP RPAREN      ; extensions
+     * </pre>
+     */
+    private static DitContentRule parseDitContentRuleStrict( Reader reader, PosSchema pos,
+        Map<String, OpenLdapObjectIdentifierMacro> objectIdentifierMacros ) throws IOException, LdapSchemaException
+    {
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // we must have a '('
+        if ( pos.line.charAt( pos.start ) != LPAREN )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13829_NO_OPENING_PAREN, 
+                pos.lineNumber, pos.start ) );
+        }
+        else
+        {
+            pos.start++;
+        }
+        
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // Now, the OID. 
+        String oid = getOidAndMacroRelaxed( pos, objectIdentifierMacros );
+        
+        // Check that the OID is valid
+        if ( !Oid.isOid( oid ) )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13787_OID_EXPECTED, pos.lineNumber, pos.start ) );
+        }
+        
+        DitContentRule ditContentRule = new DitContentRule( oid );
+        int elementsSeen = 0;
+        
+        while ( true )
+        {
+            if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+                break;
+            }
+            
+            skipWhites( reader, pos, true );
+            
+            if ( startsWith( pos, NAME_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitContentRuleElements.NAME, pos );
+
+                pos.start += NAME_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                ditContentRule.setNames( getQDescrs( reader, pos, STRICT ) );
+            }
+            else if ( startsWith( pos, DESC_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitContentRuleElements.DESC, pos );
+
+                pos.start += DESC_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                ditContentRule.setDescription( getQDString( reader, pos ) );
+            }
+            else if ( startsWith( pos, OBSOLETE_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitContentRuleElements.OBSOLETE, pos );
+
+                pos.start += OBSOLETE_STR.length();
+                
+                ditContentRule.setObsolete( true );
+            }
+            else if ( startsWith( pos, AUX_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitContentRuleElements.AUX, pos );
+
+                pos.start += AUX_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                List<String> aux = getOidsStrict( reader, pos );
+                
+                ditContentRule.setAuxObjectClassOids( aux );
+            }
+            else if ( startsWith( pos, MUST_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitContentRuleElements.MUST, pos );
+
+                pos.start += MUST_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                List<String> must = getOidsStrict( reader, pos );
+                
+                ditContentRule.setMustAttributeTypeOids( must );
+            }
+            else if ( startsWith( pos, MAY_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitContentRuleElements.MAY, pos );
+
+                pos.start += MAY_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                List<String> may = getOidsStrict( reader, pos );
+                
+                ditContentRule.setMayAttributeTypeOids( may );
+            }
+            else if ( startsWith( pos, NOT_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitContentRuleElements.NOT, pos );
+
+                pos.start += NOT_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                List<String> not = getOidsStrict( reader, pos );
+                
+                ditContentRule.setNotAttributeTypeOids( not );
+            }
+            else if ( startsWith( pos, EXTENSION_PREFIX ) )
+            {
+                processExtension( reader, pos, ditContentRule );
+            }
+            else if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+
+                break;
+            }
+            else
+            {
+                // This is an error
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13809_DCR_DESCRIPTION_INVALID, 
+                    pos.lineNumber, pos.start ) );
+            }
+        }
+        
+        return ditContentRule;
+    }
+
+    
+    /**
+     * Production for DitContentRule descriptions. It is fault-tolerant
+     * against element ordering.
+     *
+     * <pre>
+     * DITContentRuleDescription = LPAREN WSP
+     *    numericoid                 ; object identifier
+     *    [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
+     *    [ SP "DESC" SP qdstring ]  ; description
+     *    [ SP "OBSOLETE" ]          ; not active
+     *    [ SP "AUX" SP oids ]       ; auxiliary object classes
+     *    [ SP "MUST" SP oids ]      ; attribute types
+     *    [ SP "MAY" SP oids ]       ; attribute types
+     *    [ SP "NOT" SP oids ]       ; attribute types
+     *    extensions WSP RPAREN      ; extensions
+     * </pre>
+     */
+    private static DitContentRule parseDitContentRuleRelaxed( Reader reader, PosSchema pos,
+        Map<String, OpenLdapObjectIdentifierMacro> objectIdentifierMacros ) throws IOException, LdapSchemaException
+    {
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // we must have a '('
+        if ( pos.line.charAt( pos.start ) != LPAREN )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13829_NO_OPENING_PAREN, 
+                pos.lineNumber, pos.start ) );
+        }
+        else
+        {
+            pos.start++;
+        }
+        
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // Now, the OID. 
+        String oid = getOidAndMacroRelaxed( pos, objectIdentifierMacros );
+        // Now, the OID. 
+        
+        DitContentRule ditContentRule = new DitContentRule( oid );
+        int elementsSeen = 0;
+        
+        while ( true )
+        {
+            if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+                break;
+            }
+            
+            skipWhites( reader, pos, true );
+
+            if ( startsWith( pos, NAME_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitContentRuleElements.NAME, pos );
+
+                pos.start += NAME_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                ditContentRule.setNames( getQDescrs( reader, pos, RELAXED ) );
+            }
+            else if ( startsWith( pos, DESC_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitContentRuleElements.DESC, pos );
+
+                pos.start += DESC_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                ditContentRule.setDescription( getQDString( reader, pos ) );
+            }
+            else if ( startsWith( pos, OBSOLETE_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitContentRuleElements.OBSOLETE, pos );
+
+                pos.start += OBSOLETE_STR.length();
+                
+                ditContentRule.setObsolete( true );
+            }
+            else if ( startsWith( pos, AUX_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitContentRuleElements.AUX, pos );
+
+                pos.start += AUX_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                List<String> aux = getOidsRelaxed( reader, pos );
+                
+                ditContentRule.setAuxObjectClassOids( aux );
+            }
+            else if ( startsWith( pos, MUST_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitContentRuleElements.MUST, pos );
+
+                pos.start += MUST_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                List<String> must = getOidsRelaxed( reader, pos );
+                
+                ditContentRule.setMustAttributeTypeOids( must );
+            }
+            else if ( startsWith( pos, MAY_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitContentRuleElements.MAY, pos );
+
+                pos.start += MAY_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                List<String> may = getOidsRelaxed( reader, pos );
+                
+                ditContentRule.setMayAttributeTypeOids( may );
+            }
+            else if ( startsWith( pos, NOT_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitContentRuleElements.NOT, pos );
+
+                pos.start += NOT_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                List<String> not = getOidsRelaxed( reader, pos );
+                
+                ditContentRule.setNotAttributeTypeOids( not );
+            }
+            else if ( startsWith( pos, EXTENSION_PREFIX ) )
+            {
+                processExtension( reader, pos, ditContentRule );
+            }
+            else if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+
+                break;
+            }
+            else
+            {
+                // This is an error
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13809_DCR_DESCRIPTION_INVALID, 
+                    pos.lineNumber, pos.start ) );
+            }
+        }
+        
+        return ditContentRule;
+    }
+
+    
+    /**
+     * Production for matching DitStructureRule descriptions. It is fault-tolerant
+     * against element ordering.
+     *
+     * <pre>
+     * DITStructureRuleDescription = LPAREN WSP
+     *   ruleid                     ; rule identifier
+     *   [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
+     *   [ SP "DESC" SP qdstring ]  ; description
+     *   [ SP "OBSOLETE" ]          ; not active
+     *   SP "FORM" SP oid           ; NameForm
+     *   [ SP "SUP" ruleids ]       ; superior rules
+     *   extensions WSP RPAREN      ; extensions
+     *
+     * ruleids = ruleid / ( LPAREN WSP ruleidlist WSP RPAREN )
+     * ruleidlist = ruleid *( SP ruleid )
+     * ruleid = number
+     * </pre>
+     * 
+     * @param ditStructureRuleDescription The String containing the DitStructureRuleDescription
+     * @return An instance of DitStructureRule
+     * @throws ParseException If the element was invalid
+     */
+    public DitStructureRule parseDitStructureRule( String ditStructureRuleDescription ) throws ParseException
+    {
+        if ( ( ditStructureRuleDescription == null ) || Strings.isEmpty( ditStructureRuleDescription.trim() ) )
+        {
+            throw new ParseException( I18n.err( I18n.ERR_13716_NULL_OR_EMPTY_STRING_SCHEMA_OBJECT ), 0 );
+        }
+        
+        try ( Reader reader = new BufferedReader( new StringReader( ditStructureRuleDescription ) ) )
+        {
+            PosSchema pos = new PosSchema();
+
+            if ( isQuirksModeEnabled )
+            {
+                return parseDitStructureRuleRelaxed( reader, pos, objectIdentifierMacros );
+            }
+            else
+            {
+                return parseDitStructureRuleStrict( reader, pos );
+            }
+        }
+        catch ( IOException | LdapSchemaException e )
+        {
+            throw new ParseException( e.getMessage(), 0 );
+        }
+    }
+
+    
+    /**
+     * Production for DitStructureRule descriptions. It is fault-tolerant
+     * against element ordering.
+     *
+     * <pre>
+     * DITStructureRuleDescription = LPAREN WSP
+     *   ruleid                     ; rule identifier
+     *   [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
+     *   [ SP "DESC" SP qdstring ]  ; description
+     *   [ SP "OBSOLETE" ]          ; not active
+     *   SP "FORM" SP oid           ; NameForm
+     *   [ SP "SUP" ruleids ]       ; superior rules
+     *   extensions WSP RPAREN      ; extensions
+     *
+     * ruleids = ruleid / ( LPAREN WSP ruleidlist WSP RPAREN )
+     * ruleidlist = ruleid *( SP ruleid )
+     * ruleid = number
+     * </pre>
+     */
+    private static DitStructureRule parseDitStructureRuleStrict( Reader reader, PosSchema pos ) 
+        throws IOException, LdapSchemaException
+    {
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // we must have a '('
+        if ( pos.line.charAt( pos.start ) != LPAREN )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13829_NO_OPENING_PAREN, 
+                pos.lineNumber, pos.start ) );
+        }
+        else
+        {
+            pos.start++;
+        }
+        
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // Now, the ruleID. 
+        int ruleId = getRuleId( pos );
+        
+        DitStructureRule ditStructureRule = new DitStructureRule( ruleId );
+        int elementsSeen = 0;
+        boolean hasForm = false;
+        
+        while ( true )
+        {
+            if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+                break;
+            }
+            
+            skipWhites( reader, pos, true );
+            
+            if ( startsWith( pos, NAME_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitStructureRuleElements.NAME, pos );
+
+                pos.start += NAME_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                ditStructureRule.setNames( getQDescrs( reader, pos, STRICT ) );
+            }
+            else if ( startsWith( pos, DESC_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitStructureRuleElements.DESC, pos );
+
+                pos.start += DESC_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                ditStructureRule.setDescription( getQDString( reader, pos ) );
+            }
+            else if ( startsWith( pos, OBSOLETE_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitStructureRuleElements.OBSOLETE, pos );
+
+                pos.start += OBSOLETE_STR.length();
+                
+                ditStructureRule.setObsolete( true );
+            }
+            else if ( startsWith( pos, FORM_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitStructureRuleElements.FORM, pos );
+
+                pos.start += FORM_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                String form = getOidStrict( pos );
+                
+                ditStructureRule.setForm( form );
+                hasForm = true;
+            }
+            else if ( startsWith( pos, SUP_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitStructureRuleElements.SUP, pos );
+
+                pos.start += SUP_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                List<Integer> superRules = getRuleIds( reader, pos );
+                
+                ditStructureRule.setSuperRules( superRules );
+            }
+            else if ( startsWith( pos, EXTENSION_PREFIX ) )
+            {
+                processExtension( reader, pos, ditStructureRule );
+            }
+            else if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+                break;
+            }
+            else
+            {
+                // This is an error
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13809_DCR_DESCRIPTION_INVALID, 
+                    pos.lineNumber, pos.start ) );
+            }
+        }
+        
+        // Semantic checks
+        if ( !hasForm )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13812_FORM_REQUIRED, 
+                pos.lineNumber, pos.start ) );
+        }
+
+        return ditStructureRule;
+    }
+
+    
+    /**
+     * Production for DitStructureRule descriptions. It is fault-tolerant
+     * against element ordering.
+     *
+     * <pre>
+     * DITStructureRuleDescription = LPAREN WSP
+     *   ruleid                     ; rule identifier
+     *   [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
+     *   [ SP "DESC" SP qdstring ]  ; description
+     *   [ SP "OBSOLETE" ]          ; not active
+     *   SP "FORM" SP oid           ; NameForm
+     *   [ SP "SUP" ruleids ]       ; superior rules
+     *   extensions WSP RPAREN      ; extensions
+     *
+     * ruleids = ruleid / ( LPAREN WSP ruleidlist WSP RPAREN )
+     * ruleidlist = ruleid *( SP ruleid )
+     * ruleid = number
+     * </pre>
+     */
+    private static DitStructureRule parseDitStructureRuleRelaxed( Reader reader, PosSchema pos,
+        Map<String, OpenLdapObjectIdentifierMacro> objectIdentifierMacros ) 
+            throws IOException, LdapSchemaException
+    {
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // we must have a '('
+        if ( pos.line.charAt( pos.start ) != LPAREN )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13829_NO_OPENING_PAREN, 
+                pos.lineNumber, pos.start ) );
+        }
+        else
+        {
+            pos.start++;
+        }
+        
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // Now, the ruleID. 
+        int ruleId = getRuleId( pos );
+        
+        DitStructureRule ditStructureRule = new DitStructureRule( ruleId );
+        int elementsSeen = 0;
+        boolean hasForm = false;
+        
+        while ( true )
+        {
+            if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+                break;
+            }
+            
+            skipWhites( reader, pos, true );
+            
+            if ( startsWith( pos, NAME_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitStructureRuleElements.NAME, pos );
+
+                pos.start += NAME_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                ditStructureRule.setNames( getQDescrs( reader, pos, RELAXED ) );
+            }
+            else if ( startsWith( pos, DESC_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitStructureRuleElements.DESC, pos );
+
+                pos.start += DESC_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                ditStructureRule.setDescription( getQDString( reader, pos ) );
+            }
+            else if ( startsWith( pos, OBSOLETE_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitStructureRuleElements.OBSOLETE, pos );
+
+                pos.start += OBSOLETE_STR.length();
+                
+                ditStructureRule.setObsolete( true );
+            }
+            else if ( startsWith( pos, FORM_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitStructureRuleElements.FORM, pos );
+
+                pos.start += FORM_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                String form = getOidRelaxed( pos, UN_QUOTED );
+                
+                ditStructureRule.setForm( form );
+                hasForm = true;
+            }
+            else if ( startsWith( pos, SUP_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, DitStructureRuleElements.SUP, pos );
+
+                pos.start += SUP_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                List<Integer> superRules = getRuleIds( reader, pos );
+                
+                ditStructureRule.setSuperRules( superRules );
+            }
+            else if ( startsWith( pos, EXTENSION_PREFIX ) )
+            {
+                processExtension( reader, pos, ditStructureRule );
+            }
+            else if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+                break;
+            }
+            else
+            {
+                // This is an error
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13809_DCR_DESCRIPTION_INVALID, 
+                    pos.lineNumber, pos.start ) );
+            }
+        }
+
+        if ( !hasForm )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13812_FORM_REQUIRED, 
+                pos.lineNumber, pos.start ) );
+        }
+
+        return ditStructureRule;
+    }
+
+    
+    /**
+     * Production for LdapComparator descriptions. It is fault-tolerant
+     * against element ordering.
+     *
+     * <pre>
+     * LdapComparatorDescription = LPAREN WSP
+     *       numericoid                           ; object identifier
+     *       [ SP "DESC" SP qdstring ]            ; description
+     *       SP "FQCN" SP fqcn                    ; fully qualified class name
+     *       [ SP "BYTECODE" SP base64 ]          ; optional base64 encoded bytecode
+     *       extensions WSP RPAREN                ; extensions
+     * 
+     * base64          = *(4base64-char)
+     * base64-char     = ALPHA / DIGIT / "+" / "/"
+     * fqcn = fqcnComponent 1*( DOT fqcnComponent )
+     * fqcnComponent = ???
+     * </pre>
+     * 
+     * @param ldapComparatorDescription The String containing the LdapComparatorDescription
+     * @return An instance of LdapComparatorDescription
+     * @throws ParseException If the element was invalid
+     */
+    public LdapComparatorDescription parseLdapComparator( String ldapComparatorDescription ) throws ParseException
+    {
+        if ( ( ldapComparatorDescription == null ) || Strings.isEmpty( ldapComparatorDescription.trim() ) )
+        {
+            throw new ParseException( I18n.err( I18n.ERR_13716_NULL_OR_EMPTY_STRING_SCHEMA_OBJECT ), 0 );
+        }
+        
+        try ( Reader reader = new BufferedReader( new StringReader( ldapComparatorDescription ) ) )
+        {
+            PosSchema pos = new PosSchema();
+
+            if ( isQuirksModeEnabled )
+            {
+                return parseLdapComparatorRelaxed( reader, pos, objectIdentifierMacros );
+            }
+            else
+            {
+                return parseLdapComparatorStrict( reader, pos, objectIdentifierMacros );
+            }
+        }
+        catch ( IOException | LdapSchemaException e )
+        {
+            throw new ParseException( e.getMessage(), 0 );
+        }
+    }
+
+    
+    /**
+     * Production for LdapComparator descriptions. It is fault-tolerant
+     * against element ordering.
+     *
+     * <pre>
+     * LdapComparatorDescription = LPAREN WSP
+     *       numericoid                           ; object identifier
+     *       [ SP "DESC" SP qdstring ]            ; description
+     *       SP "FQCN" SP fqcn                    ; fully qualified class name
+     *       [ SP "BYTECODE" SP base64 ]          ; optional base64 encoded bytecode
+     *       extensions WSP RPAREN                ; extensions
+     * 
+     * base64          = *(4base64-char)
+     * base64-char     = ALPHA / DIGIT / "+" / "/"
+     * fqcn = fqcnComponent 1*( DOT fqcnComponent )
+     * fqcnComponent = ???
+     * </pre>
+     */
+    private static LdapComparatorDescription parseLdapComparatorStrict( Reader reader, PosSchema pos,
+        Map<String, OpenLdapObjectIdentifierMacro> objectIdentifierMacros ) throws IOException, LdapSchemaException
+    {
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // we must have a '('
+        if ( pos.line.charAt( pos.start ) != LPAREN )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13829_NO_OPENING_PAREN, 
+                pos.lineNumber, pos.start ) );
+        }
+        else
+        {
+            pos.start++;
+        }
+        
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // Now, the OID. 
+        String oid = getOidAndMacroRelaxed( pos, objectIdentifierMacros );
+        
+        // Check that the OID is valid
+        if ( !Oid.isOid( oid ) )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13787_OID_EXPECTED, pos.lineNumber, pos.start ) );
+        }
+        
+        LdapComparatorDescription ldapComparator = new LdapComparatorDescription( oid );
+        int elementsSeen = 0;
+        boolean hasFqcn = false;
+        boolean hasByteCode = false;
+        
+        while ( true )
+        {
+            if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+                break;
+            }
+            
+            skipWhites( reader, pos, true );
+            
+            if ( startsWith( pos, DESC_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, LdapComparatorElements.DESC, pos );
+
+                pos.start += DESC_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                ldapComparator.setDescription( getQDString( reader, pos ) );
+            }
+            else if ( startsWith( pos, FQCN_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, LdapComparatorElements.FQCN, pos );
+
+                pos.start += FQCN_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                String fqcn = getFqcn( pos );
+                ldapComparator.setFqcn( fqcn );
+                hasFqcn = true;
+            }
+            else if ( startsWith( pos, BYTECODE_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, LdapComparatorElements.BYTECODE, pos );
+
+                pos.start += BYTECODE_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                String byteCode = getByteCode( pos );
+                ldapComparator.setBytecode( byteCode );
+                hasByteCode = true;
+            }
+            else if ( startsWith( pos, EXTENSION_PREFIX ) )
+            {
+                processExtension( reader, pos, ldapComparator );
+            }
+            else if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+                break;
+            }
+            else
+            {
+                // This is an error
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13825_COMP_DESCRIPTION_INVALID, 
+                    pos.lineNumber, pos.start ) );
+            }
+        }
+        
+        // Semantic checks
+        if ( !hasFqcn )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13819_FQCN_REQUIRED, 
+                pos.lineNumber, pos.start ) );
+        }
+
+        if ( ( hasByteCode ) && ( ldapComparator.getBytecode().length() % 4 != 0 ) )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13820_BYTE_CODE_REQUIRED, 
+                pos.lineNumber, pos.start ) );
+        }
+
+        return ldapComparator;
+    }
+
+    
+    /**
+     * Production for LdapComparator descriptions. It is fault-tolerant
+     * against element ordering.
+     *
+     * <pre>
+     * LdapComparatorDescription = LPAREN WSP
+     *       numericoid                           ; object identifier
+     *       [ SP "DESC" SP qdstring ]            ; description
+     *       SP "FQCN" SP fqcn                    ; fully qualified class name
+     *       [ SP "BYTECODE" SP base64 ]          ; optional base64 encoded bytecode
+     *       extensions WSP RPAREN                ; extensions
+     * 
+     * base64          = *(4base64-char)
+     * base64-char     = ALPHA / DIGIT / "+" / "/"
+     * fqcn = fqcnComponent 1*( DOT fqcnComponent )
+     * fqcnComponent = ???
+     * </pre>
+     */
+    private static LdapComparatorDescription parseLdapComparatorRelaxed( Reader reader, PosSchema pos,
+        Map<String, OpenLdapObjectIdentifierMacro> objectIdentifierMacros ) 
+            throws IOException, LdapSchemaException
+    {
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // we must have a '('
+        if ( pos.line.charAt( pos.start ) != LPAREN )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13829_NO_OPENING_PAREN, 
+                pos.lineNumber, pos.start ) );
+        }
+        else
+        {
+            pos.start++;
+        }
+        
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // Now, the OID. 
+        String oid = getOidAndMacroRelaxed( pos, objectIdentifierMacros );
+        
+        LdapComparatorDescription ldapComparator = new LdapComparatorDescription( oid );
+        int elementsSeen = 0;
+        
+        while ( true )
+        {
+            if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+                break;
+            }
+            
+            skipWhites( reader, pos, true );
+            
+            if ( startsWith( pos, DESC_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, LdapComparatorElements.DESC, pos );
+
+                pos.start += DESC_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                ldapComparator.setDescription( getQDString( reader, pos ) );
+            }
+            else if ( startsWith( pos, FQCN_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, LdapComparatorElements.FQCN, pos );
+
+                pos.start += FQCN_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                String fqcn = getFqcn( pos );
+                ldapComparator.setFqcn( fqcn );
+            }
+            else if ( startsWith( pos, BYTECODE_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, LdapComparatorElements.BYTECODE, pos );
+
+                pos.start += BYTECODE_STR.length();
+                
+                skipWhites( reader, pos, true );
+                
+                String byteCode = getByteCode( pos );
+                ldapComparator.setBytecode( byteCode );
+            }
+            else if ( startsWith( pos, EXTENSION_PREFIX ) )
+            {
+                processExtension( reader, pos, ldapComparator );
+            }
+            else if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+                break;
+            }
+            else
+            {
+                // This is an error
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13825_COMP_DESCRIPTION_INVALID, 
+                    pos.lineNumber, pos.start ) );
+            }
+        }
+
+        return ldapComparator;
+    }
+
+    
+    /**
+     * Production for matching ldap syntax descriptions. It is fault-tolerant
+     * against element ordering.
+     *
+     * <pre>
+     * SyntaxDescription = LPAREN WSP
+     *    numericoid                 ; object identifier
+     *    [ SP "DESC" SP qdstring ]  ; description
+     *    extensions WSP RPAREN      ; extensions
+     * </pre>
+     * 
+     * @param ldapSyntaxDescription The String containing the Ldap Syntax description
+     * @return An instance of LdapSyntax
+     * @throws ParseException If the element was invalid
+     */
+    public LdapSyntax parseLdapSyntax( String ldapSyntaxDescription ) throws ParseException
+    {
+        if ( ( ldapSyntaxDescription == null ) || Strings.isEmpty( ldapSyntaxDescription.trim() ) )
+        {
+            throw new ParseException( I18n.err( I18n.ERR_13716_NULL_OR_EMPTY_STRING_SCHEMA_OBJECT ), 0 );
+        }
+        
+        try ( Reader reader = new BufferedReader( new StringReader( ldapSyntaxDescription ) ) )
+        {
+            PosSchema pos = new PosSchema();
+
+            if ( isQuirksModeEnabled )
+            {
+                return parseLdapSyntaxRelaxed( reader, pos, objectIdentifierMacros );
+            }
+            else
+            {
+                return parseLdapSyntaxStrict( reader, pos, objectIdentifierMacros );
+            }
+        }
+        catch ( IOException | LdapSchemaException e )
+        {
+            throw new ParseException( e.getMessage(), 0 );
+        }
+    }
+
+    
+    /**
+     * Production for matching ldap syntax descriptions. It is fault-tolerant
+     * against element ordering.
+     *
+     * <pre>
+     * SyntaxDescription = LPAREN WSP
+     *    numericoid                 ; object identifier
+     *    [ SP "DESC" SP qdstring ]  ; description
+     *    extensions WSP RPAREN      ; extensions
+     * </pre>
+     */
+    private static LdapSyntax parseLdapSyntaxStrict( Reader reader, PosSchema pos,
+        Map<String, OpenLdapObjectIdentifierMacro> objectIdentifierMacros ) throws IOException, LdapSchemaException
+    {
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // we must have a '('
+        if ( pos.line.charAt( pos.start ) != LPAREN )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13829_NO_OPENING_PAREN, 
+                pos.lineNumber, pos.start ) );
+        }
+        else
+        {
+            pos.start++;
+        }
+        
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // Now, the OID. 
+        String oid = getOidAndMacroRelaxed( pos, objectIdentifierMacros );
+        
+        // Check that the OID is valid
+        if ( !Oid.isOid( oid ) )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13787_OID_EXPECTED, pos.lineNumber, pos.start ) );
+        }
+        
+        LdapSyntax ldapSyntax = new LdapSyntax( oid );
+        int elementsSeen = 0;
+        
+        while ( true )
+        {
+            if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+                break;
+            }
+            
+            skipWhites( reader, pos, true );
+            
+            if ( startsWith( pos, DESC_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, LdapSyntaxElements.DESC, pos );
+
+                pos.start += DESC_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                ldapSyntax.setDescription( getQDString( reader, pos ) );
+            }
+            else if ( startsWith( pos, EXTENSION_PREFIX ) )
+            {
+                processExtension( reader, pos, ldapSyntax );
+            }
+            else if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+                break;
+            }
+            else
+            {
+                // This is an error
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13807_SYN_DESCRIPTION_INVALID, 
+                    pos.lineNumber, pos.start ) );
+            }
+        }
+        
+        return ldapSyntax;
+    }
+
+    
+    /**
+     * Production for matching ldap syntax descriptions. It is fault-tolerant
+     * against element ordering.
+     *
+     * <pre>
+     * SyntaxDescription = LPAREN WSP
+     *    numericoid                 ; object identifier
+     *    [ SP "DESC" SP qdstring ]  ; description
+     *    extensions WSP RPAREN      ; extensions
+     * </pre>
+     */
+    private static LdapSyntax parseLdapSyntaxRelaxed( Reader reader, PosSchema pos,
+        Map<String, OpenLdapObjectIdentifierMacro> objectIdentifierMacros ) throws IOException, LdapSchemaException
+    {
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // we must have a '('
+        if ( pos.line.charAt( pos.start ) != LPAREN )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13829_NO_OPENING_PAREN, 
+                pos.lineNumber, pos.start ) );
+        }
+        else
+        {
+            pos.start++;
+        }
+        
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // Now, the OID. 
+        String oid = getOidAndMacroRelaxed( pos, objectIdentifierMacros );
+        
+        LdapSyntax ldapSyntax = new LdapSyntax( oid );
+        int elementsSeen = 0;
+        
+        while ( true )
+        {
+            if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+                break;
+            }
+            
+            skipWhites( reader, pos, true );
+            
+            if ( startsWith( pos, DESC_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, LdapSyntaxElements.DESC, pos );
+
+                pos.start += DESC_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                ldapSyntax.setDescription( getQDString( reader, pos ) );
+            }
+            else if ( startsWith( pos, EXTENSION_PREFIX ) )
+            {
+                processExtension( reader, pos, ldapSyntax );
+            }
+            else if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+                break;
+            }
+            else
+            {
+                // This is an error
+                throw new LdapSchemaException( I18n.err( I18n.ERR_13807_SYN_DESCRIPTION_INVALID, 
+                    pos.lineNumber, pos.start ) );
+            }
+        }
+        
+        return ldapSyntax;
+    }
+    
+    
+    /**
+     * Production for matching MatchingRule descriptions. It is fault-tolerant
+     * against element ordering.
+     *
+     * <pre>
+     * MatchingRuleDescription = LPAREN WSP
+     *    numericoid                 ; object identifier
+     *    [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
+     *    [ SP "DESC" SP qdstring ]  ; description
+     *    [ SP "OBSOLETE" ]          ; not active
+     *    SP "SYNTAX" SP numericoid  ; assertion syntax
+     *    extensions WSP RPAREN      ; extensions
+     * </pre>
+     * 
+     * @param matchingRuleDescription The String containing the MatchingRuledescription
+     * @return An instance of MatchingRule
+     * @throws ParseException If the element was invalid
+     */
+    public MatchingRule parseMatchingRule( String matchingRuleDescription ) throws ParseException
+    {
+        if ( ( matchingRuleDescription == null ) || Strings.isEmpty( matchingRuleDescription.trim() ) )
+        {
+            throw new ParseException( I18n.err( I18n.ERR_13716_NULL_OR_EMPTY_STRING_SCHEMA_OBJECT ), 0 );
+        }
+        
+        try ( Reader reader = new BufferedReader( new StringReader( matchingRuleDescription ) ) )
+        {
+            PosSchema pos = new PosSchema();
+
+            if ( isQuirksModeEnabled )
+            {
+                return parseMatchingRuleRelaxed( reader, pos, objectIdentifierMacros );
+            }
+            else
+            {
+                return parseMatchingRuleStrict( reader, pos, objectIdentifierMacros );
+            }
+        }
+        catch ( IOException | LdapSchemaException e )
+        {
+            throw new ParseException( e.getMessage(), 0 );
+        }
+    }
+
+    
+    /**
+     * Production for matching rule descriptions. It is fault-tolerant
+     * against element ordering.
+     *
+     * <pre>
+     * MatchingRuleDescription = LPAREN WSP
+     *    numericoid                 ; object identifier
+     *    [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
+     *    [ SP "DESC" SP qdstring ]  ; description
+     *    [ SP "OBSOLETE" ]          ; not active
+     *    SP "SYNTAX" SP numericoid  ; assertion syntax
+     *    extensions WSP RPAREN      ; extensions
+     * </pre>
+     */
+    private static MatchingRule parseMatchingRuleStrict( Reader reader, PosSchema pos, 
+        Map<String, OpenLdapObjectIdentifierMacro> objectIdentifierMacros ) throws IOException, LdapSchemaException
+    {
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // we must have a '('
+        if ( pos.line.charAt( pos.start ) != LPAREN )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13829_NO_OPENING_PAREN, 
+                pos.lineNumber, pos.start ) );
+        }
+        else
+        {
+            pos.start++;
+        }
+        
+        // Get rid of whites, comments end empty lines
+        skipWhites( reader, pos, false );
+        
+        // Now, the OID. 
+        String oid = getOidAndMacroRelaxed( pos, objectIdentifierMacros );
+        
+        // Check that the OID is valid
+        if ( !Oid.isOid( oid ) )
+        {
+            throw new LdapSchemaException( I18n.err( I18n.ERR_13787_OID_EXPECTED, pos.lineNumber, pos.start ) );
+        }
+        
+        MutableMatchingRule matchingRule = new MutableMatchingRule( oid );
+        int elementsSeen = 0;
+        boolean hasSyntax = false;
+        
+        while ( true )
+        {
+            if ( startsWith( reader, pos, RPAREN ) )
+            {
+                pos.start++;
+                break;
+            }
+            
+            skipWhites( reader, pos, true );
+            
+            if ( startsWith( pos, NAME_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, MatchingRuleElements.NAME, pos );
+
+                pos.start += NAME_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                matchingRule.setNames( getQDescrs( reader, pos, STRICT ) );
+            }
+            else if ( startsWith( pos, DESC_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, MatchingRuleElements.DESC, pos );
+
+                pos.start += DESC_STR.length();
+                
+                skipWhites( reader, pos, true );
+
+                matchingRule.setDescription( getQDString( reader, pos ) );
+            }
+            else if ( startsWith( pos, OBSOLETE_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, MatchingRuleElements.OBSOLETE, pos );
+
+                pos.start += OBSOLETE_STR.length();
+                
+                matchingRule.setObsolete( true );
+            }
+            else if ( startsWith( pos, SYNTAX_STR ) )
+            {
+                elementsSeen = checkElement( elementsSeen, MatchingRuleElements.SYNTAX, pos );
+
+                pos.start += SYNTAX_STR.length();
+                
... 9004 lines suppressed ...

-- 
To stop receiving notification emails like this one, please contact
elecharny@apache.org.