gt:     final List<String> errorMessages = new ArrayList<>(5);
context: /*
   * Copyright 2020 Ping Identity Corporation
   * All Rights Reserved.
   */
  /*
   * Copyright 2020 Ping Identity Corporation
   *
   * Licensed 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.
   */
  /*
   * Copyright (C) 2020 Ping Identity Corporation
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License (GPLv2 only)
   * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
   * as published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, see <http://www.gnu.org/licenses>.
   */
  package com.unboundid.ldap.sdk.schema;
  
  
  
  import java.io.File;
  import java.text.ParseException;
  import java.util.ArrayList;
  import java.util.EnumSet;
  import java.util.List;
  import java.util.Set;
  import java.util.regex.Pattern;
  
  import org.testng.annotations.BeforeClass;
  import org.testng.annotations.Test;
  
  import com.unboundid.ldap.sdk.Entry;
  import com.unboundid.ldap.sdk.LDAPSDKTestCase;
  import com.unboundid.ldif.LDIFWriter;
  import com.unboundid.util.StaticUtils;
  
  
  
  /**
   * This class provides a set of test cases for the {@code SchemaValidator}
   * enum.
   */
  public class SchemaValidatorTestCase
         extends LDAPSDKTestCase
  {
    // An entry that contains a minimal schema definition.
    private Entry minimalSchemaEntry = null;
  
    // A file that holds a minimal schema definition.
    private File minimalSchemaFile = null;
  
    // THe lines that make up the minimal schema definition.
    private String[] minimalSchemaLines = null;
  
  
  
    /**
     * Creates an entry with a minimal set of schema definitions.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @BeforeClass()
    public void setUp()
           throws Exception
    {
      minimalSchemaLines = new String[]
      {
        "dn: cn=schema",
        "objectClass: top",
        "objectClass: ldapSubEntry",
        "objectClass: subschema",
        "cn: schema",
        "ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type " +
             "Description' )",
        "ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
        "ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule " +
             "Description' )",
        "ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.17 " +
             "DESC 'DIT Structure Rule Description' )",
        "ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
        "ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'INTEGER' )",
        "ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule " +
             "Description' )",
        "ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use " +
             "Description' )",
        "ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form " +
             "Description' )",
        "ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class " +
             "Description' )",
        "ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
        "ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax " +
             "Description' )",
        "ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring " +
             "Assertion' )",
        "matchingRules: ( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
        "matchingRules: ( 1.3.6.1.4.1.1466.109.114.3 NAME " +
             "'caseIgnoreIA5SubstringsMatch' " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
        "matchingRules: ( 2.5.13.0 NAME 'objectIdentifierMatch' " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
        "matchingRules: ( 2.5.13.2 NAME 'caseIgnoreMatch' " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
        "matchingRules: ( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
        "matchingRules: ( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
        "matchingRules: ( 2.5.13.29 NAME 'integerFirstComponentMatch' " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
        "matchingRules: ( 2.5.13.30 " +
             "NAME 'objectIdentifierFirstComponentMatch' " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
        "attributeTypes: ( 2.5.4.0 NAME 'objectClass' " +
             "EQUALITY objectIdentifierMatch " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
        "attributeTypes: ( 2.5.4.41 NAME 'name' EQUALITY caseIgnoreMatch " +
             "SUBSTR caseIgnoreSubstringsMatch " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
        "attributeTypes: ( 2.5.4.3 NAME 'cn' SUP name )",
        "attributeTypes: ( 0.9.2342.19200300.100.1.25 NAME 'dc' " +
             "EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )",
        "attributeTypes: ( 2.5.21.6 NAME 'objectClasses' " +
             "EQUALITY objectIdentifierFirstComponentMatch " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.37 USAGE directoryOperation )",
        "attributeTypes: ( 2.5.21.5 NAME 'attributeTypes' " +
             "EQUALITY objectIdentifierFirstComponentMatch " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.3 USAGE directoryOperation )",
        "attributeTypes: ( 2.5.21.4 NAME 'matchingRules' " +
             "EQUALITY objectIdentifierFirstComponentMatch " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.30 USAGE directoryOperation )",
        "attributeTypes: ( 2.5.21.8 NAME 'matchingRuleUse' " +
             "EQUALITY objectIdentifierFirstComponentMatch " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.31 USAGE directoryOperation )",
        "attributeTypes: ( 1.3.6.1.4.1.1466.101.120.16 NAME 'ldapSyntaxes' " +
             "EQUALITY objectIdentifierFirstComponentMatch",
        "  SYNTAX 1.3.6.1.4.1.1466.115.121.1.54 USAGE directoryOperation )",
        "attributeTypes: ( 2.5.21.2 NAME 'dITContentRules' " +
             "EQUALITY objectIdentifierFirstComponentMatch " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.16 USAGE directoryOperation )",
        "attributeTypes: ( 2.5.21.1 NAME 'dITStructureRules' " +
             "EQUALITY integerFirstComponentMatch " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.17",
        "  USAGE directoryOperation )",
        "attributeTypes: ( 2.5.21.7 NAME 'nameForms' " +
             "EQUALITY objectIdentifierFirstComponentMatch " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.35",
        "  USAGE directoryOperation )",
        "objectClasses: ( 2.5.6.0 NAME 'top' ABSTRACT MUST objectClass )",
        "objectClasses: ( 2.16.840.1.113719.2.142.6.1.1 NAME 'ldapSubEntry' " +
             "SUP top STRUCTURAL MAY cn )",
        "objectClasses: ( 2.5.20.1 NAME 'subschema' AUXILIARY " +
             "MAY ( dITStructureRules $ nameForms $ ditContentRules $ " +
             "objectClasses $ attributeTypes $ matchingRules $ " +
             "matchingRuleUse ) )",
        "objectClasses: ( 0.9.2342.19200300.100.4.13 NAME 'domain' SUP top " +
             "STRUCTURAL MUST dc )"
      };
  
      minimalSchemaEntry = new Entry(minimalSchemaLines);
      minimalSchemaFile = createTempFile(minimalSchemaLines);
    }
  
  
  
    /**
     * Tests to verify the default configuration.
     */
    @Test()
    public void testDefaultConfiguration()
    {
      final SchemaValidator schemaValidator = new SchemaValidator();
  
      assertNull(schemaValidator.getSchemaFileNamePattern());
  
      assertTrue(schemaValidator.ignoreSchemaFilesNotMatchingFileNamePattern());
  
      assertFalse(schemaValidator.allowMultipleEntriesPerFile());
  
      assertFalse(schemaValidator.allowSchemaFilesInSubDirectories());
  
      assertTrue(schemaValidator.ensureSchemaEntryIsValid());
  
      assertNotNull(schemaValidator.getAllowedSchemaElementTypes());
      assertFalse(schemaValidator.getAllowedSchemaElementTypes().isEmpty());
      assertEquals(schemaValidator.getAllowedSchemaElementTypes(),
           EnumSet.allOf(SchemaElementType.class));
  
      assertNotNull(schemaValidator.getAllowReferencesToUndefinedElementTypes());
      assertTrue(
           schemaValidator.getAllowReferencesToUndefinedElementTypes().isEmpty());
  
      assertFalse(schemaValidator.allowRedefiningElements());
  
      assertTrue(schemaValidator.allowElementsWithoutNames());
  
      assertFalse(schemaValidator.allowNonNumericOIDsUsingName());
  
      assertFalse(schemaValidator.allowNonNumericOIDsNotUsingName());
  
      assertTrue(schemaValidator.useStrictOIDValidation());
  
      assertFalse(schemaValidator.allowNamesWithInitialDigit());
  
      assertFalse(schemaValidator.allowNamesWithInitialHyphen());
  
      assertFalse(schemaValidator.allowNamesWithUnderscore());
  
      assertFalse(schemaValidator.allowEmptyDescription());
  
      assertNotNull(schemaValidator.getAttributeSyntaxes());
      assertTrue(schemaValidator.getAttributeSyntaxes().isEmpty());
  
      assertFalse(schemaValidator.allowAttributeTypesWithoutSyntax());
  
      assertNotNull(schemaValidator.getMatchingRuleDefinitions());
  
      assertTrue(
           schemaValidator.allowAttributeTypesWithoutEqualityMatchingRule());
  
      assertTrue(schemaValidator.allowMultipleSuperiorObjectClasses());
  
      assertFalse(schemaValidator.allowStructuralObjectClassWithoutSuperior());
  
      assertFalse(schemaValidator.allowInvalidObjectClassInheritance());
  
      assertTrue(schemaValidator.allowCollectiveAttributes());
  
      assertTrue(schemaValidator.allowObsoleteElements());
    }
  
  
  
    /**
     * Tests to ensure that the default standard schema that ships with the LDAP
     * SDK is considered valid with the default settings.
     */
    @Test()
    public void testDefaultStandardSchema()
    {
      final SchemaValidator schemaValidator = new SchemaValidator();
  
      final File sourceRootDir = new File(System.getProperty("basedir"));
      final File schemaFile = StaticUtils.constructPath(sourceRootDir,
           "resource", "standard-schema.ldif");
  
      final List<String> errorMessages = new ArrayList<>(5);
      final Schema schema = schemaValidator.validateSchema(schemaFile, null,
           errorMessages);
  
      assertNotNull(schema);
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
    }
  
  
  
    /**
     * Tests to ensure that the minimal schema is considered valid on its own.
     */
    @Test()
    public void testMinimalSchema()
    {
      final SchemaValidator schemaValidator = new SchemaValidator();
  
      final List<String> errorMessages = new ArrayList<>(5);
      final Schema schema = schemaValidator.validateSchema(minimalSchemaFile,
           null, errorMessages);
  
      assertNotNull(schema);
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
    }
  
  
  
    /**
     * Tests the behavior with a directory containing multiple schema files,
     * including the use of a file name pattern.
     *
     * @throws  Exception  If an unexpected problem occurs.
      */
    @Test()
    public void testMultipleSchemaFilesInDirectory()
           throws Exception
    {
      final File schemaDir = createTempDir();
  
      final File schemaFile1 = new File(schemaDir, "01-first.ldif");
      StaticUtils.writeFile(schemaFile1, minimalSchemaLines);
  
      final File schemaFile2 = new File(schemaDir, "second.ldif");
      StaticUtils.writeFile(schemaFile2,
           "dn: cn=schema",
           "objectClass: top",
           "objectClass: ldapSubEntry",
           "objectClass: subschema",
           "cn: schema",
           "attributeTypes: ( 1.2.3.4 NAME 'test-at' " +
                "EQUALITY caseIgnoreMatch " +
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )");
  
      SchemaValidator schemaValidator = new SchemaValidator();
  
      final List<String> errorMessages = new ArrayList<>(5);
      Schema schema = schemaValidator.validateSchema(schemaDir, null,
           errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getAttributeType("test-at"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setSchemaFileNamePattern(
           Pattern.compile("^\\d\\d-.+\\.ldif$"), true);
  
      schema = schemaValidator.validateSchema(schemaDir, null,
           errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNull(schema.getAttributeType("test-at"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setSchemaFileNamePattern(
           Pattern.compile("^\\d\\d-.+\\.ldif$"), false);
  
      schema = schemaValidator.validateSchema(schemaDir, null,
           errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNull(schema.getAttributeType("test-at"));
  
      assertFalse(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setSchemaFileNamePattern(
           Pattern.compile("^a.*$"), true);
  
      schema = schemaValidator.validateSchema(schemaDir, null,
           errorMessages);
  
      assertNull(schema);
  
      assertFalse(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setSchemaFileNamePattern(
           Pattern.compile("^a.*$"), false);
  
      schema = schemaValidator.validateSchema(schemaDir, null,
           errorMessages);
  
      assertNull(schema);
  
      assertFalse(errorMessages.isEmpty());
  
  
      assertTrue(schemaFile2.delete());
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setSchemaFileNamePattern(
           Pattern.compile("^a.*$"), true);
  
      schema = schemaValidator.validateSchema(schemaFile1, null,
           errorMessages);
  
  
      assertNull(schema);
  
      assertFalse(errorMessages.isEmpty());
    }
  
  
  
    /**
     * Tests with a nonexistent path.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testNonexistentPath()
           throws Exception
    {
      final File schemaFile = createTempFile();
      assertTrue(schemaFile.delete());
  
      final SchemaValidator schemaValidator = new SchemaValidator();
  
      final List<String> errorMessages = new ArrayList<>(5);
      final Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNull(schema);
  
      assertFalse(errorMessages.isEmpty());
    }
  
  
  
    /**
     * Tests with an empty file.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testEmptyFile()
           throws Exception
    {
      final File schemaFile = createTempFile();
      final SchemaValidator schemaValidator = new SchemaValidator();
  
      final List<String> errorMessages = new ArrayList<>(5);
      final Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNull(schema);
  
      assertFalse(errorMessages.isEmpty());
    }
  
  
  
    /**
     * Tests with an empty directory.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testEmptyDirectory()
           throws Exception
    {
      final File schemaDir = createTempDir();
      final SchemaValidator schemaValidator = new SchemaValidator();
  
      final List<String> errorMessages = new ArrayList<>(5);
      final Schema schema =
           schemaValidator.validateSchema(schemaDir, null, errorMessages);
  
      assertNull(schema);
  
      assertFalse(errorMessages.isEmpty());
    }
  
  
  
    /**
     * Tests with a file that contains a malformed entry.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testMalformedLDIFFile()
           throws Exception
    {
      final File schemaFile = createTempFile("this is not a valid LDIF file");
      final SchemaValidator schemaValidator = new SchemaValidator();
  
      final List<String> errorMessages = new ArrayList<>(5);
      final Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNull(schema);
  
      assertFalse(errorMessages.isEmpty());
    }
  
  
  
    /**
     * Tests with multiple entries in the same schema file.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testMultipleEntriesPerFile()
           throws Exception
    {
      final File schemaFile = createTempFile();
      try (LDIFWriter writer = new LDIFWriter(schemaFile))
      {
        writer.writeEntry(minimalSchemaEntry);
        writer.writeEntry(new Entry(
             "dn: cn=schema",
             "objectClass: top",
             "objectClass: ldapSubEntry",
             "objectClass: subschema",
             "cn: schema",
             "attributeTypes: ( 1.2.3.4 NAME 'test-at' " +
                  "EQUALITY caseIgnoreMatch " +
                  "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )"));
      }
  
  
      SchemaValidator schemaValidator = new SchemaValidator();
      assertFalse(schemaValidator.allowMultipleEntriesPerFile());
  
      final List<String> errorMessages = new ArrayList<>(5);
      Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNull(schema.getAttributeType("test-at"));
  
      assertFalse(errorMessages.isEmpty());
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setAllowMultipleEntriesPerFile(true);
      assertTrue(schemaValidator.allowMultipleEntriesPerFile());
  
      errorMessages.clear();
      schema = schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getAttributeType("test-at"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
    }
  
  
  
    /**
     * Tests with schema files in subdirectories.  In this case, there will be
     * one file in the specified directory and one file in a subdirectory.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testSchemaFilesInSubdirectories()
           throws Exception
    {
      final File schemaDir = createTempDir();
  
      final File schemaFile1 = new File(schemaDir, "first.ldif");
      StaticUtils.writeFile(schemaFile1, minimalSchemaLines);
  
      final File subdirectory = new File(schemaDir, "subdirectory");
      assertTrue(subdirectory.mkdir());
  
      final File schemaFile2 = new File(subdirectory, "second.ldif");
      StaticUtils.writeFile(schemaFile2,
           "dn: cn=schema",
           "objectClass: top",
           "objectClass: ldapSubEntry",
           "objectClass: subschema",
           "cn: schema",
           "attributeTypes: ( 1.2.3.4 NAME 'test-at' " +
                "EQUALITY caseIgnoreMatch " +
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )");
  
  
      SchemaValidator schemaValidator = new SchemaValidator();
      assertFalse(schemaValidator.allowSchemaFilesInSubDirectories());
  
      final List<String> errorMessages = new ArrayList<>(5);
      Schema schema =
           schemaValidator.validateSchema(schemaDir, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNull(schema.getAttributeType("test-at"));
  
      assertFalse(errorMessages.isEmpty());
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setAllowSchemaFilesInSubDirectories(true);
      assertTrue(schemaValidator.allowSchemaFilesInSubDirectories());
  
      errorMessages.clear();
      schema = schemaValidator.validateSchema(schemaDir, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getAttributeType("test-at"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
    }
  
  
  
    /**
     * Tests with schema files in subdirectories.  In this case, there will be
     * only files in subdirectories.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testSchemaFilesOnlyInSubdirectories()
           throws Exception
    {
      final File schemaDir = createTempDir();
  
      final File subDir1 = new File(schemaDir, "subdirectory1");
      subDir1.mkdir();
  
      final File schemaFile1 = new File(subDir1, "first.ldif");
      StaticUtils.writeFile(schemaFile1, minimalSchemaLines);
  
      final File subDir2 = new File(schemaDir, "subdirectory2");
      subDir2.mkdir();
  
      final File schemaFile2 = new File(subDir2, "second.ldif");
      StaticUtils.writeFile(schemaFile2,
           "dn: cn=schema",
           "objectClass: top",
           "objectClass: ldapSubEntry",
           "objectClass: subschema",
           "cn: schema",
           "attributeTypes: ( 1.2.3.4 NAME 'test-at' " +
                "EQUALITY caseIgnoreMatch " +
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )");
  
  
      SchemaValidator schemaValidator = new SchemaValidator();
      assertFalse(schemaValidator.allowSchemaFilesInSubDirectories());
  
      final List<String> errorMessages = new ArrayList<>(5);
      Schema schema =
           schemaValidator.validateSchema(schemaDir, null, errorMessages);
  
      assertNull(schema);
  
      assertFalse(errorMessages.isEmpty());
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setAllowSchemaFilesInSubDirectories(true);
      assertTrue(schemaValidator.allowSchemaFilesInSubDirectories());
  
      errorMessages.clear();
      schema = schemaValidator.validateSchema(schemaDir, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getAttributeType("test-at"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
    }
  
  
  
    /**
     * Tests the behavior with regard to ensuring that the schema entry is valid.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testEnsureSchemaEntryIsValid()
           throws Exception
    {
      final Entry schemaEntry = minimalSchemaEntry.duplicate();
      schemaEntry.addAttribute("description", "test description");
  
      final File schemaFile = createTempFile(schemaEntry.toLDIF());
  
      SchemaValidator schemaValidator = new SchemaValidator();
      assertTrue(schemaValidator.ensureSchemaEntryIsValid());
  
      final List<String> errorMessages = new ArrayList<>(5);
      Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
  
      assertFalse(errorMessages.isEmpty());
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setEnsureSchemaEntryIsValid(false);
      assertFalse(schemaValidator.ensureSchemaEntryIsValid());
  
      errorMessages.clear();
      schema = schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
    }
  
  
  
    /**
     * Tests the behavior for a schema entry that has attribute syntax definitions
     * when they are not allowed.
     */
    @Test()
    public void testAttributeSyntaxNotAllowed()
    {
      final SchemaValidator schemaValidator = new SchemaValidator();
      assertEquals(schemaValidator.getAllowedSchemaElementTypes(),
           EnumSet.allOf(SchemaElementType.class));
  
      final Set<SchemaElementType> allowedElementTypes =
           EnumSet.allOf(SchemaElementType.class);
      allowedElementTypes.remove(SchemaElementType.ATTRIBUTE_SYNTAX);
  
      schemaValidator.setAllowedSchemaElementTypes(allowedElementTypes);
      assertEquals(schemaValidator.getAllowedSchemaElementTypes(),
           allowedElementTypes);
  
      final List<String> errorMessages = new ArrayList<>(5);
      final Schema schema =
           schemaValidator.validateSchema(minimalSchemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
  
      assertFalse(errorMessages.isEmpty());
    }
  
  
  
    /**
     * Tests the behavior for a schema entry that a malformed attribute syntax
     * definition.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testMalformedAttributeSyntax()
           throws Exception
    {
      final Entry schemaEntry = minimalSchemaEntry.duplicate();
      schemaEntry.addAttribute(Schema.ATTR_ATTRIBUTE_TYPE, "malformed");
  
      final File schemaFile = createTempFile(schemaEntry.toLDIF());
  
      final SchemaValidator schemaValidator = new SchemaValidator();
  
      final List<String> errorMessages = new ArrayList<>(5);
      final Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
  
      assertFalse(errorMessages.isEmpty());
    }
  
  
  
    /**
     * Tests the behavior for a schema entry that has an attribute syntax with a
     * numeric OID that passes lenient validation but not strict validation.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testAttributeSyntaxWithOIDNotStrictlyValid()
           throws Exception
    {
      final Entry schemaEntry = minimalSchemaEntry.duplicate();
      schemaEntry.addAttribute(Schema.ATTR_ATTRIBUTE_SYNTAX,
           "( 1 DESC 'Not a strictly valid OID' )");
  
      final File schemaFile = createTempFile(schemaEntry.toLDIF());
  
      SchemaValidator schemaValidator = new SchemaValidator();
      assertFalse(schemaValidator.allowNonNumericOIDsUsingName());
      assertFalse(schemaValidator.allowNonNumericOIDsNotUsingName());
      assertTrue(schemaValidator.useStrictOIDValidation());
  
      final List<String> errorMessages = new ArrayList<>(5);
      Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getAttributeSyntax("1"));
  
      assertFalse(errorMessages.isEmpty());
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setOIDValidation(false, false, false);
      assertFalse(schemaValidator.allowNonNumericOIDsUsingName());
      assertFalse(schemaValidator.allowNonNumericOIDsNotUsingName());
      assertFalse(schemaValidator.useStrictOIDValidation());
  
      errorMessages.clear();
  
      schema = schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getAttributeSyntax("1"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
    }
  
  
  
    /**
     * Tests the behavior for a schema entry that has an attribute syntax with a
     * non-numeric OID.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testAttributeSyntaxWithNonNumericOID()
           throws Exception
    {
      final Entry schemaEntry = minimalSchemaEntry.duplicate();
      schemaEntry.addAttribute(Schema.ATTR_ATTRIBUTE_SYNTAX,
           "( non-numeric DESC 'Non-numeric OID' )");
  
      final File schemaFile = createTempFile(schemaEntry.toLDIF());
  
      SchemaValidator schemaValidator = new SchemaValidator();
      assertFalse(schemaValidator.allowNonNumericOIDsUsingName());
      assertFalse(schemaValidator.allowNonNumericOIDsNotUsingName());
      assertTrue(schemaValidator.useStrictOIDValidation());
  
      final List<String> errorMessages = new ArrayList<>(5);
      Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getAttributeSyntax("non-numeric"));
  
      assertFalse(errorMessages.isEmpty());
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setOIDValidation(false, true, false);
      assertFalse(schemaValidator.allowNonNumericOIDsUsingName());
      assertTrue(schemaValidator.allowNonNumericOIDsNotUsingName());
      assertFalse(schemaValidator.useStrictOIDValidation());
  
      errorMessages.clear();
  
      schema = schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getAttributeSyntax("non-numeric"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
    }
  
  
  
    /**
     * Tests the behavior for a schema entry that has an attribute syntax with an
     * empty description.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testAttributeSyntaxWithEmptyDescription()
           throws Exception
    {
      final Entry schemaEntry = minimalSchemaEntry.duplicate();
      schemaEntry.addAttribute(Schema.ATTR_ATTRIBUTE_SYNTAX,
           "( 1.2.3.4 DESC '' )");
  
      final File schemaFile = createTempFile(schemaEntry.toLDIF());
  
      SchemaValidator schemaValidator = new SchemaValidator();
      assertFalse(schemaValidator.allowEmptyDescription());
  
      final List<String> errorMessages = new ArrayList<>(5);
      Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getAttributeSyntax("1.2.3.4"));
  
      assertFalse(errorMessages.isEmpty());
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setAllowEmptyDescription(true);
      assertTrue(schemaValidator.allowEmptyDescription());
  
      errorMessages.clear();
  
      schema = schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getAttributeSyntax("1.2.3.4"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
    }
  
  
  
    /**
     * Tests the behavior for a duplicate attribute syntax definition.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testRedefinedAttributeSyntax()
           throws Exception
    {
      final File schemaDir = createTempDir();
  
      final File schemaFile1 = new File(schemaDir, "01-first.ldif");
      StaticUtils.writeFile(schemaFile1, minimalSchemaLines);
  
      final File schemaFile2 = new File(schemaDir, "second.ldif");
      StaticUtils.writeFile(schemaFile2,
           "dn: cn=schema",
           "objectClass: top",
           "objectClass: ldapSubEntry",
           "objectClass: subschema",
           "cn: schema",
           "ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type " +
                "Description' )");
  
      SchemaValidator schemaValidator = new SchemaValidator();
      assertFalse(schemaValidator.allowRedefiningElements());
  
      final List<String> errorMessages = new ArrayList<>(5);
      Schema schema =
           schemaValidator.validateSchema(schemaDir, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getAttributeSyntax("1.3.6.1.4.1.1466.115.121.1.3"));
  
      assertFalse(errorMessages.isEmpty());
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setAllowRedefiningElements(true);
      assertTrue(schemaValidator.allowRedefiningElements());
  
      errorMessages.clear();
  
      schema = schemaValidator.validateSchema(schemaDir, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getAttributeSyntax("1.3.6.1.4.1.1466.115.121.1.3"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
    }
  
  
  
    /**
     * Tests the behavior for a schema entry that has matching rule definitions
     * when they are not allowed.
     */
    @Test()
    public void testMatchingRuleNotAllowed()
    {
      final SchemaValidator schemaValidator = new SchemaValidator();
      assertEquals(schemaValidator.getAllowedSchemaElementTypes(),
           EnumSet.allOf(SchemaElementType.class));
  
      final Set<SchemaElementType> allowedElementTypes =
           EnumSet.allOf(SchemaElementType.class);
      allowedElementTypes.remove(SchemaElementType.MATCHING_RULE);
  
      schemaValidator.setAllowedSchemaElementTypes(allowedElementTypes);
      assertEquals(schemaValidator.getAllowedSchemaElementTypes(),
           allowedElementTypes);
  
      final List<String> errorMessages = new ArrayList<>(5);
      final Schema schema =
           schemaValidator.validateSchema(minimalSchemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
  
      assertFalse(errorMessages.isEmpty());
    }
  
  
  
    /**
     * Tests the behavior for a schema entry that a malformed matching rule
     * definition.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testMalformedMatchingRule()
           throws Exception
    {
      final Entry schemaEntry = minimalSchemaEntry.duplicate();
      schemaEntry.addAttribute(Schema.ATTR_MATCHING_RULE, "malformed");
  
      final File schemaFile = createTempFile(schemaEntry.toLDIF());
  
      final SchemaValidator schemaValidator = new SchemaValidator();
  
      final List<String> errorMessages = new ArrayList<>(5);
      final Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
  
      assertFalse(errorMessages.isEmpty());
    }
  
  
  
    /**
     * Tests the behavior for a schema entry that has a matching rule with a
     * numeric OID that passes lenient validation but not strict validation.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testMatchingRuleWithOIDNotStrictlyValid()
           throws Exception
    {
      final Entry schemaEntry = minimalSchemaEntry.duplicate();
      schemaEntry.addAttribute(Schema.ATTR_MATCHING_RULE,
           "( 1 NAME 'test-mr' " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )");
  
      final File schemaFile = createTempFile(schemaEntry.toLDIF());
  
      SchemaValidator schemaValidator = new SchemaValidator();
      assertFalse(schemaValidator.allowNonNumericOIDsUsingName());
      assertFalse(schemaValidator.allowNonNumericOIDsNotUsingName());
      assertTrue(schemaValidator.useStrictOIDValidation());
  
      final List<String> errorMessages = new ArrayList<>(5);
      Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("1"));
  
      assertFalse(errorMessages.isEmpty());
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setOIDValidation(false, false, false);
      assertFalse(schemaValidator.allowNonNumericOIDsUsingName());
      assertFalse(schemaValidator.allowNonNumericOIDsNotUsingName());
      assertFalse(schemaValidator.useStrictOIDValidation());
  
      errorMessages.clear();
  
      schema = schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("1"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
    }
  
  
  
    /**
     * Tests the behavior for a schema entry that has a matching rule with a
     * non-numeric OID that is its name followed by "-oid".
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testMatchingRuleWithNonNumericOIDUsingName()
           throws Exception
    {
      final Entry schemaEntry = minimalSchemaEntry.duplicate();
      schemaEntry.addAttribute(Schema.ATTR_MATCHING_RULE,
           "( test-mr-oid NAME 'test-mr' " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )");
  
      final File schemaFile = createTempFile(schemaEntry.toLDIF());
  
      SchemaValidator schemaValidator = new SchemaValidator();
      assertFalse(schemaValidator.allowNonNumericOIDsUsingName());
      assertFalse(schemaValidator.allowNonNumericOIDsNotUsingName());
      assertTrue(schemaValidator.useStrictOIDValidation());
  
      final List<String> errorMessages = new ArrayList<>(5);
      Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("test-mr-oid"));
  
      assertFalse(errorMessages.isEmpty());
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setOIDValidation(true, false, false);
      assertTrue(schemaValidator.allowNonNumericOIDsUsingName());
      assertFalse(schemaValidator.allowNonNumericOIDsNotUsingName());
      assertFalse(schemaValidator.useStrictOIDValidation());
  
      errorMessages.clear();
  
      schema = schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("test-mr-oid"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
    }
  
  
  
    /**
     * Tests the behavior for a schema entry that has a matching rule with a
     * non-numeric OID that is something other than its name followed by "-oid".
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testMatchingRuleWithNonNumericOIDNotUsingName()
           throws Exception
    {
      final Entry schemaEntry = minimalSchemaEntry.duplicate();
      schemaEntry.addAttribute(Schema.ATTR_MATCHING_RULE,
           "( non-numeric-oid NAME 'test-mr' " +
             "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )");
  
      final File schemaFile = createTempFile(schemaEntry.toLDIF());
  
      SchemaValidator schemaValidator = new SchemaValidator();
      assertFalse(schemaValidator.allowNonNumericOIDsUsingName());
      assertFalse(schemaValidator.allowNonNumericOIDsNotUsingName());
      assertTrue(schemaValidator.useStrictOIDValidation());
  
      final List<String> errorMessages = new ArrayList<>(5);
      Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("non-numeric-oid"));
  
      assertFalse(errorMessages.isEmpty());
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setOIDValidation(false, true, false);
      assertFalse(schemaValidator.allowNonNumericOIDsUsingName());
      assertTrue(schemaValidator.allowNonNumericOIDsNotUsingName());
      assertFalse(schemaValidator.useStrictOIDValidation());
  
      errorMessages.clear();
  
      schema = schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("non-numeric-oid"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
    }
  
  
  
    /**
     * Tests the behavior for a schema entry that has a matching rule without a
     * name.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testMatchingRuleWithoutName()
           throws Exception
    {
      final Entry schemaEntry = minimalSchemaEntry.duplicate();
      schemaEntry.addAttribute(Schema.ATTR_MATCHING_RULE,
           "( 1.2.3.4 SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )");
  
      final File schemaFile = createTempFile(schemaEntry.toLDIF());
  
      SchemaValidator schemaValidator = new SchemaValidator();
      assertTrue(schemaValidator.allowElementsWithoutNames());
  
      final List<String> errorMessages = new ArrayList<>(5);
      Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("1.2.3.4"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setAllowElementsWithoutNames(false);
      assertFalse(schemaValidator.allowElementsWithoutNames());
  
      errorMessages.clear();
  
      schema = schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("1.2.3.4"));
  
      assertFalse(errorMessages.isEmpty());
    }
  
  
  
    /**
     * Tests the behavior for a schema entry that has a matching rule with a name
     * that starts with a digit.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testMatchingRuleNameStartsWithDigit()
           throws Exception
    {
      final Entry schemaEntry = minimalSchemaEntry.duplicate();
      schemaEntry.addAttribute(Schema.ATTR_MATCHING_RULE,
           "( 1.2.3.4 NAME '1test-mr' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )");
  
      final File schemaFile = createTempFile(schemaEntry.toLDIF());
  
      SchemaValidator schemaValidator = new SchemaValidator();
      assertFalse(schemaValidator.allowNamesWithInitialDigit());
  
      final List<String> errorMessages = new ArrayList<>(5);
      Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("1.2.3.4"));
      assertNotNull(schema.getMatchingRule("1test-mr"));
  
      assertFalse(errorMessages.isEmpty());
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setAllowNamesWithInitialDigit(true);
      assertTrue(schemaValidator.allowNamesWithInitialDigit());
  
      errorMessages.clear();
  
      schema = schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("1.2.3.4"));
      assertNotNull(schema.getMatchingRule("1test-mr"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
    }
  
  
  
    /**
     * Tests the behavior for a schema entry that has a matching rule with a name
     * that starts with a hyphen.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testMatchingRuleNameStartsWithHyphen()
           throws Exception
    {
      final Entry schemaEntry = minimalSchemaEntry.duplicate();
      schemaEntry.addAttribute(Schema.ATTR_MATCHING_RULE,
           "( 1.2.3.4 NAME '-test-mr' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )");
  
      final File schemaFile = createTempFile(schemaEntry.toLDIF());
  
      SchemaValidator schemaValidator = new SchemaValidator();
      assertFalse(schemaValidator.allowNamesWithInitialHyphen());
  
      final List<String> errorMessages = new ArrayList<>(5);
      Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("1.2.3.4"));
      assertNotNull(schema.getMatchingRule("-test-mr"));
  
      assertFalse(errorMessages.isEmpty());
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setAllowNamesWithInitialHyphen(true);
      assertTrue(schemaValidator.allowNamesWithInitialHyphen());
  
      errorMessages.clear();
  
      schema = schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("1.2.3.4"));
      assertNotNull(schema.getMatchingRule("-test-mr"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
    }
  
  
  
    /**
     * Tests the behavior for a schema entry that has a matching rule with a name
     * that contains underscore characters.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testMatchingRuleNameContainsUnderscore()
           throws Exception
    {
      final Entry schemaEntry = minimalSchemaEntry.duplicate();
      schemaEntry.addAttribute(Schema.ATTR_MATCHING_RULE,
           "( 1.2.3.4 NAME '_test_mr' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )");
  
      final File schemaFile = createTempFile(schemaEntry.toLDIF());
  
      SchemaValidator schemaValidator = new SchemaValidator();
      assertFalse(schemaValidator.allowNamesWithUnderscore());
  
      final List<String> errorMessages = new ArrayList<>(5);
      Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("1.2.3.4"));
      assertNotNull(schema.getMatchingRule("_test_mr"));
  
      assertFalse(errorMessages.isEmpty());
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setAllowNamesWithUnderscore(true);
      assertTrue(schemaValidator.allowNamesWithUnderscore());
  
      errorMessages.clear();
  
      schema = schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("1.2.3.4"));
      assertNotNull(schema.getMatchingRule("_test_mr"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
    }
  
  
  
    /**
     * Tests the behavior for a schema entry that has a matching rule with an
     * empty description.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testMatchingRuleWithEmptyDescription()
           throws Exception
    {
      final Entry schemaEntry = minimalSchemaEntry.duplicate();
      schemaEntry.addAttribute(Schema.ATTR_MATCHING_RULE,
           "( 1.2.3.4 NAME 'test-mr' DESC '' " +
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )");
  
      final File schemaFile = createTempFile(schemaEntry.toLDIF());
  
      SchemaValidator schemaValidator = new SchemaValidator();
      assertFalse(schemaValidator.allowEmptyDescription());
  
      final List<String> errorMessages = new ArrayList<>(5);
      Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("1.2.3.4"));
  
      assertFalse(errorMessages.isEmpty());
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setAllowEmptyDescription(true);
      assertTrue(schemaValidator.allowEmptyDescription());
  
      errorMessages.clear();
  
      schema = schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("1.2.3.4"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
    }
  
  
  
    /**
     * Tests the behavior for a schema entry that has a matching rule that is
     * declared OBSOLETE.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testMatchingRuleObsolete()
           throws Exception
    {
      final Entry schemaEntry = minimalSchemaEntry.duplicate();
      schemaEntry.addAttribute(Schema.ATTR_MATCHING_RULE,
           "( 1.2.3.4 NAME 'test-mr' OBSOLETE " +
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )");
  
      final File schemaFile = createTempFile(schemaEntry.toLDIF());
  
      SchemaValidator schemaValidator = new SchemaValidator();
      assertTrue(schemaValidator.allowObsoleteElements());
  
      final List<String> errorMessages = new ArrayList<>(5);
      Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("1.2.3.4"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setAllowObsoleteElements(false);
      assertFalse(schemaValidator.allowObsoleteElements());
  
      errorMessages.clear();
  
      schema = schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("1.2.3.4"));
  
      assertFalse(errorMessages.isEmpty());
    }
  
  
  
    /**
     * Tests the behavior for a schema entry that has a matching rule that has a
     * syntax OID that has a non-numeric OID.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testMatchingRuleNonNumericSyntaxOID()
           throws Exception
    {
      final Entry schemaEntry = minimalSchemaEntry.duplicate();
      schemaEntry.addAttribute(Schema.ATTR_ATTRIBUTE_SYNTAX,
           "( non-numeric-syntax-oid DESC 'Syntax with non-numeric OID' )");
      schemaEntry.addAttribute(Schema.ATTR_MATCHING_RULE,
           "( 1.2.3.4 NAME 'test-mr' " +
                "SYNTAX non-numeric-syntax-oid )");
  
      final File schemaFile = createTempFile(schemaEntry.toLDIF());
  
      SchemaValidator schemaValidator = new SchemaValidator();
      assertFalse(schemaValidator.allowNonNumericOIDsNotUsingName());
  
      final List<String> errorMessages = new ArrayList<>(5);
      Schema schema =
           schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("1.2.3.4"));
  
      assertFalse(errorMessages.isEmpty());
  
  
      schemaValidator = new SchemaValidator();
      schemaValidator.setOIDValidation(false, true, false);
      assertTrue(schemaValidator.allowNonNumericOIDsNotUsingName());
  
      errorMessages.clear();
  
      schema = schemaValidator.validateSchema(schemaFile, null, errorMessages);
  
      assertNotNull(schema);
      assertNotNull(schema.getAttributeType("dc"));
      assertNotNull(schema.getMatchingRule("1.2.3.4"));
  
      assertTrue(errorMessages.isEmpty(),
           StaticUtils.linesToString(errorMessages));
    }
  
  
  
    /**
     * Tests the behavior for a schema entry that has a matching rule that
     * references an undefined syntax.
     *
     * @throws  Exception  If an unexpected problem occurs.
     */
    @Test()
    public void testMatchingRuleReferencingUndefinedSyntax()
           throws Exception
    {
      final File additionalSchemaFile = createTempFile(
           "dn: cn=schema",
           "objectClass: top",
           "objectClass: ldapSubEntry",
           "objectClass: subschema",
           "cn: schema",
           "matchingRules: ( 1.2.3.4 NAME 'test-mr' SYNTAX 1.2.3.5 )");
  
      SchemaValidator schemaValidator = new SchemaValidator();
      assertTrue(schemaValidator.getAllowReferencesToUndefinedElementTypes().
           isEmpty());
  
      final Schema existingSchema = Schema.parseSchemaEntry(minimalSchemaEntry);
  
  