From 8e70f4ef79ebeda003854f977b85b22e9a9df0ad Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Mon, 30 Nov 2009 16:29:09 +0000
Subject: [PATCH] Initial import of SDK unit tests.

---
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/SubstringMatchingRuleTest.java              |  266 ++
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/TelexSyntaxTest.java                        |   65 
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/SyntaxTestCase.java                         |   98 +
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/AttributeDescriptionTest.java                      |  393 ++++
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/UUIDSyntaxTest.java                         |   74 
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/util/StaticUtilsTest.java                          |  100 +
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactEqualityMatchingRuleTest.java      |   85 
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/EnumSyntaxTestCase.java                     |  145 +
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/SchemaTestCase.java                         |   42 
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactIA5EqualityMatchingRuleTest.java   |   89 
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/MatchingRuleUseSyntaxTest.java              |   73 
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/UTCTimeSyntaxTest.java                      |  112 +
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/GuideSyntaxTest.java                        |   70 
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/OpenDSTestCase.java                                |  137 +
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/MatchingRuleTest.java                       |  136 +
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreIA5EqualityMatchingRuleTest.java  |   82 
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreEqualityMatchingRuleTest.java     |   92 +
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/OrderingMatchingRuleTest.java               |  135 +
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/DITContentRuleSyntaxTest.java               |   94 +
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreOrderingMatchingRuleTest.java     |   89 
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/ApproximateMatchingRuleTest.java            |  165 +
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/OtherMailboxSyntaxTest.java                 |   63 
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/BitStringSyntaxTest.java                    |   64 
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/BitStringEqualityMatchingRuleTest.java      |   79 
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/AbstractSchemaElementTestCase.java          |  202 ++
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactOrderingMatchingRuleTest.java      |   77 
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactSubstringMatchingRuleTest.java     |  154 +
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/SortedEntryTest.java                               |   88 
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreIA5SubstringMatchingRuleTest.java |  174 +
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/LinkedAttributeTest.java                           |   70 
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactIA5SubstringMatchingRuleTest.java  |  155 +
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/AttributeTypeSyntaxTest.java                |  101 +
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/AttributeTypeTest.java                      |  666 +++++++
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CoreSchemaTest.java                         |   47 
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/GeneralizedTimeSyntaxTest.java              |  212 ++
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/LDAPSyntaxTest.java                         |  125 +
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/RegexSyntaxTestCase.java                    |  102 +
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/BooleanEqualityMatchingRuleTest.java        |   85 
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreSubstringMatchingRuleTest.java    |  171 +
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/MatchingRuleSyntaxTest.java                 |   73 
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/IA5StringSyntaxTest.java                    |   64 
 opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/SubstitutionSyntaxTestCase.java             |  149 +
 42 files changed, 5,463 insertions(+), 0 deletions(-)

diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/AttributeDescriptionTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/AttributeDescriptionTest.java
new file mode 100644
index 0000000..851bd26
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/AttributeDescriptionTest.java
@@ -0,0 +1,393 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.sdk;
+
+
+
+import java.util.Iterator;
+
+import org.opends.sdk.schema.Schema;
+import org.opends.sdk.util.LocalizedIllegalArgumentException;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Test {@code AttributeDescription}.
+ */
+@Test(groups = { "precommit", "types", "sdk" }, sequential = true)
+public final class AttributeDescriptionTest extends OpenDSTestCase
+{
+  @DataProvider(name = "dataForValueOfNoSchema")
+  public Object[][] dataForValueOfNoSchema()
+  {
+    // Value, type, options, containsOptions("foo")
+    return new Object[][] {
+        { "cn", "cn", new String[0], false },
+        { " cn ", "cn", new String[0], false },
+        { "  cn  ", "cn", new String[0], false },
+        { "CN", "CN", new String[0], false },
+        { "1", "1", new String[0], false },
+        { "1.2", "1.2", new String[0], false },
+        { "1.2.3", "1.2.3", new String[0], false },
+        { "111.222.333", "111.222.333", new String[0], false },
+        { "objectClass", "objectClass", new String[0], false },
+        { "cn;foo", "cn", new String[] { "foo" }, true },
+        { "cn;FOO", "cn", new String[] { "FOO" }, true },
+        { "cn;bar", "cn", new String[] { "bar" }, false },
+        { "cn;BAR", "cn", new String[] { "BAR" }, false },
+        { "cn;foo;bar", "cn", new String[] { "foo", "bar" }, true },
+        { "cn;FOO;bar", "cn", new String[] { "FOO", "bar" }, true },
+        { "cn;foo;BAR", "cn", new String[] { "foo", "BAR" }, true },
+        { "cn;FOO;BAR", "cn", new String[] { "FOO", "BAR" }, true },
+        { "cn;bar;FOO", "cn", new String[] { "bar", "FOO" }, true },
+        { "cn;BAR;foo", "cn", new String[] { "BAR", "foo" }, true },
+        { "cn;bar;FOO", "cn", new String[] { "bar", "FOO" }, true },
+        { "cn;BAR;FOO", "cn", new String[] { "BAR", "FOO" }, true },
+        { " cn;BAR;FOO ", "cn", new String[] { "BAR", "FOO" }, true },
+        { "  cn;BAR;FOO  ", "cn", new String[] { "BAR", "FOO" }, true },
+        { "cn;xxx;yyy;zzz", "cn", new String[] { "xxx", "yyy", "zzz" },
+            false },
+        { "cn;zzz;YYY;xxx", "cn", new String[] { "zzz", "YYY", "xxx" },
+            false }, };
+  }
+
+
+
+  @Test(dataProvider = "dataForValueOfNoSchema")
+  public void testValueOfNoSchema(String ad, String at,
+      String[] options, boolean containsFoo)
+  {
+    AttributeDescription attributeDescription =
+        AttributeDescription.valueOf(ad, Schema.getEmptySchema());
+
+    Assert.assertEquals(attributeDescription.toString(), ad);
+
+    Assert.assertEquals(attributeDescription.getAttributeType()
+        .getNameOrOID(), at);
+
+    Assert.assertFalse(attributeDescription.isObjectClass());
+
+    if (options.length == 0)
+    {
+      Assert.assertFalse(attributeDescription.hasOptions());
+    }
+    else
+    {
+      Assert.assertTrue(attributeDescription.hasOptions());
+    }
+
+    Assert.assertFalse(attributeDescription.containsOption("dummy"));
+    if (containsFoo)
+    {
+      Assert.assertTrue(attributeDescription.containsOption("foo"));
+      Assert.assertTrue(attributeDescription.containsOption("FOO"));
+      Assert.assertTrue(attributeDescription.containsOption("FoO"));
+    }
+    else
+    {
+      Assert.assertFalse(attributeDescription.containsOption("foo"));
+      Assert.assertFalse(attributeDescription.containsOption("FOO"));
+      Assert.assertFalse(attributeDescription.containsOption("FoO"));
+    }
+
+    for (String option : options)
+    {
+      Assert.assertTrue(attributeDescription.containsOption(option));
+    }
+
+    Iterator<String> iterator =
+        attributeDescription.getOptions().iterator();
+    for (int i = 0; i < options.length; i++)
+    {
+      Assert.assertTrue(iterator.hasNext());
+      Assert.assertEquals(iterator.next(), options[i]);
+    }
+    Assert.assertFalse(iterator.hasNext());
+  }
+
+
+
+  @DataProvider(name = "dataForCompareNoSchema")
+  public Object[][] dataForCompareNoSchema()
+  {
+    // AD1, AD2, compare result, isSubtype, isSuperType
+    return new Object[][] { { "cn", "cn", 0, true, true },
+        { "cn", "CN", 0, true, true }, { "CN", "cn", 0, true, true },
+        { "CN", "CN", 0, true, true },
+        { "cn", "commonName", -1, false, false },
+        { "commonName", "cn", 1, false, false },
+        { "commonName", "commonName", 0, true, true },
+        { "cn", "cn;foo", -1, false, true },
+        { "cn;foo", "cn", 1, true, false },
+        { "cn;foo", "cn;foo", 0, true, true },
+        { "CN;FOO", "cn;foo", 0, true, true },
+        { "cn;foo", "CN;FOO", 0, true, true },
+        { "CN;FOO", "CN;FOO", 0, true, true },
+        { "cn;foo", "cn;bar", 1, false, false },
+        { "cn;bar", "cn;foo", -1, false, false },
+
+        { "cn;xxx;yyy", "cn", 1, true, false },
+        { "cn;xxx;yyy", "cn;yyy", 1, true, false },
+        { "cn;xxx;yyy", "cn;xxx", 1, true, false },
+        { "cn;xxx;yyy", "cn;xxx;yyy", 0, true, true },
+        { "cn;xxx;yyy", "cn;yyy;xxx", 0, true, true },
+
+        { "cn", "cn;xxx;yyy", -1, false, true },
+        { "cn;yyy", "cn;xxx;yyy", -1, false, true },
+        { "cn;xxx", "cn;xxx;yyy", -1, false, true },
+        { "cn;xxx;yyy", "cn;xxx;yyy", 0, true, true },
+        { "cn;yyy;xxx", "cn;xxx;yyy", 0, true, true }, };
+  }
+
+
+
+  @Test(dataProvider = "dataForCompareNoSchema")
+  public void testCompareNoSchema(String ad1, String ad2, int compare,
+      boolean isSubType, boolean isSuperType)
+  {
+    AttributeDescription attributeDescription1 =
+        AttributeDescription.valueOf(ad1, Schema.getEmptySchema());
+
+    AttributeDescription attributeDescription2 =
+        AttributeDescription.valueOf(ad2, Schema.getEmptySchema());
+
+    // Identity.
+    Assert.assertTrue(attributeDescription1
+        .equals(attributeDescription1));
+    Assert.assertTrue(attributeDescription1
+        .compareTo(attributeDescription1) == 0);
+    Assert.assertTrue(attributeDescription1
+        .isSubTypeOf(attributeDescription1));
+    Assert.assertTrue(attributeDescription1
+        .isSuperTypeOf(attributeDescription1));
+
+    if (compare == 0)
+    {
+      Assert.assertTrue(attributeDescription1
+          .equals(attributeDescription2));
+      Assert.assertTrue(attributeDescription2
+          .equals(attributeDescription1));
+      Assert.assertTrue(attributeDescription1
+          .compareTo(attributeDescription2) == 0);
+      Assert.assertTrue(attributeDescription2
+          .compareTo(attributeDescription1) == 0);
+
+      Assert.assertTrue(attributeDescription1
+          .isSubTypeOf(attributeDescription2));
+      Assert.assertTrue(attributeDescription1
+          .isSuperTypeOf(attributeDescription2));
+      Assert.assertTrue(attributeDescription2
+          .isSubTypeOf(attributeDescription1));
+      Assert.assertTrue(attributeDescription2
+          .isSuperTypeOf(attributeDescription1));
+    }
+    else
+    {
+      Assert.assertFalse(attributeDescription1
+          .equals(attributeDescription2));
+      Assert.assertFalse(attributeDescription2
+          .equals(attributeDescription1));
+
+      if (compare < 0)
+      {
+        Assert.assertTrue(attributeDescription1
+            .compareTo(attributeDescription2) < 0);
+        Assert.assertTrue(attributeDescription2
+            .compareTo(attributeDescription1) > 0);
+      }
+      else
+      {
+        Assert.assertTrue(attributeDescription1
+            .compareTo(attributeDescription2) > 0);
+        Assert.assertTrue(attributeDescription2
+            .compareTo(attributeDescription1) < 0);
+      }
+
+      Assert.assertEquals(attributeDescription1
+          .isSubTypeOf(attributeDescription2), isSubType);
+
+      Assert.assertEquals(attributeDescription1
+          .isSuperTypeOf(attributeDescription2), isSuperType);
+    }
+  }
+
+
+
+  @DataProvider(name = "dataForValueOfInvalidAttributeDescriptions")
+  public Object[][] dataForValueOfInvalidAttributeDescriptions()
+  {
+    return new Object[][] { { "" }, { " " }, { ";" }, { " ; " },
+        { "0cn" }, { "cn." }, { "cn;foo+bar" }, { "cn;foo;foo+bar" },
+        { ";foo" }, { "cn;" }, { "cn;;foo" }, { "cn; ;foo" },
+        { "cn;foo;" }, { "cn;foo; " }, { "cn;foo;;bar" },
+        { "cn;foo; ;bar" }, { "cn;foo;bar;;" }, { "1a" }, { "1.a" },
+        { "1-" }, { "1.1a" }, { "1.1.a" }, };
+  }
+
+
+
+  // FIXME: none of these pass! The valueOf method is far to lenient.
+  @Test(dataProvider = "dataForValueOfInvalidAttributeDescriptions",
+      expectedExceptions = LocalizedIllegalArgumentException.class)
+  public void testValueOfInvalidAttributeDescriptions(String ad)
+  {
+    AttributeDescription.valueOf(ad, Schema.getEmptySchema());
+  }
+
+
+
+  @DataProvider(name = "dataForValueOfCoreSchema")
+  public Object[][] dataForValueOfCoreSchema()
+  {
+    // Value, type, isObjectClass
+    return new Object[][] { { "cn", "cn", false },
+        { "CN", "cn", false }, { "commonName", "cn", false },
+        { "objectclass", "objectClass", true }, };
+  }
+
+
+
+  @Test(dataProvider = "dataForValueOfCoreSchema")
+  public void testValueOfCoreSchema(String ad, String at,
+      boolean isObjectClass)
+  {
+    AttributeDescription attributeDescription =
+        AttributeDescription.valueOf(ad, Schema.getCoreSchema());
+
+    Assert.assertEquals(attributeDescription.toString(), ad);
+
+    Assert.assertEquals(attributeDescription.getAttributeType()
+        .getNameOrOID(), at);
+
+    Assert.assertEquals(attributeDescription.isObjectClass(),
+        isObjectClass);
+
+    Assert.assertFalse(attributeDescription.hasOptions());
+    Assert.assertFalse(attributeDescription.containsOption("dummy"));
+
+    Iterator<String> iterator =
+        attributeDescription.getOptions().iterator();
+    Assert.assertFalse(iterator.hasNext());
+  }
+
+
+
+  @DataProvider(name = "dataForCompareCoreSchema")
+  public Object[][] dataForCompareCoreSchema()
+  {
+    // AD1, AD2, compare result, isSubtype, isSuperType
+    return new Object[][] { { "cn", "cn", 0, true, true },
+        { "cn", "commonName", 0, true, true },
+        { " cn", "commonName ", 0, true, true },
+        { "commonName", "cn", 0, true, true },
+        { "commonName", "commonName", 0, true, true },
+        { "cn", "objectClass", 1, false, false },
+        { "objectClass", "cn", -1, false, false },
+        { "name", "cn", 1, false, true },
+        { "cn", "name", -1, true, false },
+        { "name;foo", "cn", 1, false, false },
+        { "cn;foo", "name", -1, true, false },
+        { "name", "cn;foo", 1, false, true },
+        { "cn", "name;foo", -1, false, false }, };
+  }
+
+
+
+  @Test(dataProvider = "dataForCompareCoreSchema")
+  public void testCompareCoreSchema(String ad1, String ad2,
+      int compare, boolean isSubType, boolean isSuperType)
+  {
+    AttributeDescription attributeDescription1 =
+        AttributeDescription.valueOf(ad1, Schema.getCoreSchema());
+
+    AttributeDescription attributeDescription2 =
+        AttributeDescription.valueOf(ad2, Schema.getCoreSchema());
+
+    // Identity.
+    Assert.assertTrue(attributeDescription1
+        .equals(attributeDescription1));
+    Assert.assertTrue(attributeDescription1
+        .compareTo(attributeDescription1) == 0);
+    Assert.assertTrue(attributeDescription1
+        .isSubTypeOf(attributeDescription1));
+    Assert.assertTrue(attributeDescription1
+        .isSuperTypeOf(attributeDescription1));
+
+    if (compare == 0)
+    {
+      Assert.assertTrue(attributeDescription1
+          .equals(attributeDescription2));
+      Assert.assertTrue(attributeDescription2
+          .equals(attributeDescription1));
+      Assert.assertTrue(attributeDescription1
+          .compareTo(attributeDescription2) == 0);
+      Assert.assertTrue(attributeDescription2
+          .compareTo(attributeDescription1) == 0);
+
+      Assert.assertTrue(attributeDescription1
+          .isSubTypeOf(attributeDescription2));
+      Assert.assertTrue(attributeDescription1
+          .isSuperTypeOf(attributeDescription2));
+      Assert.assertTrue(attributeDescription2
+          .isSubTypeOf(attributeDescription1));
+      Assert.assertTrue(attributeDescription2
+          .isSuperTypeOf(attributeDescription1));
+    }
+    else
+    {
+      Assert.assertFalse(attributeDescription1
+          .equals(attributeDescription2));
+      Assert.assertFalse(attributeDescription2
+          .equals(attributeDescription1));
+
+      if (compare < 0)
+      {
+        Assert.assertTrue(attributeDescription1
+            .compareTo(attributeDescription2) < 0);
+        Assert.assertTrue(attributeDescription2
+            .compareTo(attributeDescription1) > 0);
+      }
+      else
+      {
+        Assert.assertTrue(attributeDescription1
+            .compareTo(attributeDescription2) > 0);
+        Assert.assertTrue(attributeDescription2
+            .compareTo(attributeDescription1) < 0);
+      }
+
+      Assert.assertEquals(attributeDescription1
+          .isSubTypeOf(attributeDescription2), isSubType);
+
+      Assert.assertEquals(attributeDescription1
+          .isSuperTypeOf(attributeDescription2), isSuperType);
+    }
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/LinkedAttributeTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/LinkedAttributeTest.java
new file mode 100644
index 0000000..04211a9
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/LinkedAttributeTest.java
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.sdk;
+
+
+
+import org.opends.sdk.schema.Schema;
+import org.opends.sdk.util.ByteString;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Test {@code BasicAttribute}.
+ */
+@Test(groups = { "precommit", "types", "sdk" }, sequential = true)
+public final class LinkedAttributeTest extends OpenDSTestCase
+{
+  @Test
+  public void SmokeTest() throws Exception
+  {
+    // TODO: write a proper test suite.
+    AbstractAttribute attribute = new LinkedAttribute(
+        AttributeDescription.valueOf("ALTSERVER", Schema
+            .getCoreSchema()));
+
+    attribute.add(1);
+    attribute.add("a value");
+    attribute.add(ByteString.valueOf("another value"));
+
+    System.out.println(attribute);
+
+    System.out.println(attribute.contains(1));
+    System.out.println(attribute.contains("a value"));
+    System.out.println(attribute.contains(ByteString
+        .valueOf("another value")));
+
+    attribute.remove(1);
+    System.out.println(attribute);
+    attribute.remove("a value");
+    System.out.println(attribute);
+    attribute.remove(ByteString.valueOf("another value"));
+    System.out.println(attribute);
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/OpenDSTestCase.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/OpenDSTestCase.java
new file mode 100644
index 0000000..633d487
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/OpenDSTestCase.java
@@ -0,0 +1,137 @@
+package org.opends.sdk;
+
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.Test;
+import org.opends.server.TestCaseUtils;
+
+import java.util.IdentityHashMap;
+import java.util.Set;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+/**
+ * This class defines a base test case that should be subclassed by all
+ * unit tests used by OpenDS.
+ * <p>
+ * This class adds the ability to print error messages and automatically
+ * have them include the class name.
+ */
+@Test(sequential=true)
+public abstract class OpenDSTestCase 
+{
+   @BeforeSuite
+  public final void suppressOutput() {
+    TestCaseUtils.suppressOutput();
+  }
+
+  @AfterSuite
+  public final void shutdownServer() {
+    TestCaseUtils.unsupressOutput();
+  }
+
+  //
+  // This is all a HACK to reduce the amount of memory that's consumed.
+  //
+  // This could be a problem if a subclass references a @DataProvider in
+  // a super-class that provides static parameters, i.e. the parameters are
+  // not regenerated for each invocation of the DataProvider.
+  //
+
+  /** A list of all parameters that were generated by a @DataProvider
+   *  and passed to a test method of this class.  TestListener helps us
+   *  keep this so that once all of the tests are finished, we can clear
+   *  it out in an @AfterClass method.  We can't just clear it out right
+   *  away in the TestListener because some methods share a @DataProvider.*/
+  private final IdentityHashMap<Object[],Object> successfulTestParams = new IdentityHashMap<Object[],Object>();
+
+  /** These are test parameters from a test that has failed.  We need to
+   *  keep these around because the test report expects to find them when
+   *  printing out failures. */
+  private final IdentityHashMap<Object[],Object> failedTestParams = new IdentityHashMap<Object[],Object>();
+
+  /**
+   * Adds testParams to the list of all test parameters, so it can be
+   * null'ed out later if it's not part.
+   */
+  void addParamsFromSuccessfulTests(Object[] testParams) {
+    if (testParams != null) {
+      successfulTestParams.put(testParams, testParams);
+    }
+  }
+
+  /**
+   * Adds testParams to the list of all failed test parameters, so that we
+   * know to NOT null it out later.
+   */
+  void addParamsFromFailedTest(Object[] testParams) {
+    if (testParams != null) {
+      failedTestParams.put(testParams, testParams);
+    }
+  }
+
+  /**
+   * null out all test parameters except the ones used in failed tests
+   * since we might need these again.
+   */
+  @AfterClass(alwaysRun = true)
+  public void clearSuccessfulTestParams() {
+    Set<Object[]> paramsSet = successfulTestParams.keySet();
+    if (paramsSet == null) {  // Can this ever happen?
+      return;
+    }
+    for (Object[] params: paramsSet) {
+      if (failedTestParams.containsKey(params)) {
+        continue;
+      }
+
+      for (int i = 0; i < params.length; i++) {
+        params[i] = null;
+      }
+    }
+    successfulTestParams.clear();
+    failedTestParams.clear();
+  }
+
+  /**
+   * The member variables of a test class can prevent lots of memory from being
+   * reclaimed, so we use reflection to null out all of the member variables
+   * after the tests have run.  Since all tests must inherit from
+   * DirectoryServerTestCase, TestNG guarantees that this method runs after
+   * all of the subclass methods, so this isn't too dangerous.
+   */
+  @AfterClass(alwaysRun = true)
+  public void nullMemberVariablesAfterTest() {
+    Class cls = this.getClass();
+    // Iterate through all of the fields in all subclasses of
+    // DirectoryServerTestCase, but not DirectoryServerTestCase itself.
+    while (OpenDSTestCase.class.isAssignableFrom(cls) &&
+           !OpenDSTestCase.class.equals(cls))
+    {
+      Field fields[] = cls.getDeclaredFields();
+      for (int i = 0; i < fields.length; i++) {
+        Field field = fields[i];
+        int modifiers = field.getModifiers();
+        Class fieldClass = field.getType();
+        // If it's a non-static non-final non-primitive type, then null it out
+        // so that the garbage collector can reclaim it and everything it
+        // references.
+        if (!fieldClass.isPrimitive() &&
+            !fieldClass.isEnum()      &&
+            !Modifier.isFinal(modifiers) &&
+            !Modifier.isStatic(modifiers))
+        {
+          field.setAccessible(true);
+          try {
+            field.set(this, null);
+          } catch (IllegalAccessException e) {
+            // We're only doing this to save memory, so it's no big deal
+            // if we can't set it.
+          }
+        }
+      }
+      cls = cls.getSuperclass();
+    }
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/SortedEntryTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/SortedEntryTest.java
new file mode 100644
index 0000000..f0e572c
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/SortedEntryTest.java
@@ -0,0 +1,88 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.sdk;
+
+
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Test {@code BasicAttribute}.
+ */
+@Test(groups = { "precommit", "types", "sdk" }, sequential = true)
+public final class SortedEntryTest extends OpenDSTestCase
+{
+  @Test
+  public void SmokeTest() throws Exception
+  {
+    Entry entry1 = new SortedEntry(
+        "dn: cn=Joe Bloggs,dc=example,dc=com",
+        "objectClass: top",
+        "objectClass: person",
+        "cn: Joe Bloggs",
+        "sn: Bloggs",
+        "givenName: Joe",
+        "description: A description");
+
+    Entry entry2 = new SortedEntry(
+        "dn: cn=Joe Bloggs,dc=example,dc=com",
+        "changetype: add",
+        "objectClass: top",
+        "objectClass: person",
+        "cn: Joe Bloggs",
+        "sn: Bloggs",
+        "givenName: Joe",
+        "description: A description");
+
+    Assert.assertEquals(entry1, entry2);
+
+    for (Entry e : new Entry[] { entry1, entry2 })
+    {
+      Assert.assertEquals(e.getName(), DN
+          .valueOf("cn=Joe Bloggs,dc=example,dc=com"));
+      Assert.assertEquals(e.getAttributeCount(), 5);
+
+      Assert.assertEquals(e.getAttribute("objectClass").size(), 2);
+      Assert.assertTrue(e.containsObjectClass("top"));
+      Assert.assertTrue(e.containsObjectClass("person"));
+      Assert.assertFalse(e.containsObjectClass("foo"));
+
+      Assert.assertTrue(e.containsAttribute("objectClass"));
+      Assert.assertTrue(e.containsAttribute("cn"));
+      Assert.assertTrue(e.containsAttribute("sn"));
+      Assert.assertTrue(e.containsAttribute("givenName"));
+      Assert.assertTrue(e.containsAttribute("description"));
+
+      Assert.assertEquals(e.getAttribute("cn").firstValueAsString(), "Joe Bloggs");
+      Assert.assertEquals(e.getAttribute("sn").firstValueAsString(), "Bloggs");
+    }
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/AbstractSchemaElementTestCase.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/AbstractSchemaElementTestCase.java
new file mode 100644
index 0000000..504d6dd
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/AbstractSchemaElementTestCase.java
@@ -0,0 +1,202 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.opends.sdk.DecodeException;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Abstract schema element tests.
+ */
+public abstract class AbstractSchemaElementTestCase extends
+    SchemaTestCase
+{
+  protected static final Map<String, List<String>> EMPTY_PROPS =
+      Collections.emptyMap();
+  protected static final List<String> EMPTY_NAMES =
+      Collections.emptyList();
+
+
+
+  protected abstract SchemaElement getElement(String description,
+      Map<String, List<String>> extraProperties) throws SchemaException;
+
+
+
+  @DataProvider(name = "equalsTestData")
+  public abstract Object[][] createEqualsTestData()
+      throws SchemaException, DecodeException;
+
+
+
+  /**
+   * Check that the equals operator works as expected.
+   * 
+   * @param e1
+   *          The first element
+   * @param e2
+   *          The second element
+   * @param result
+   *          The expected result.
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test(dataProvider = "equalsTestData")
+  public final void testEquals(SchemaElement e1, SchemaElement e2,
+      boolean result) throws Exception
+  {
+
+    Assert.assertEquals(e1.equals(e2), result);
+    Assert.assertEquals(e2.equals(e1), result);
+  }
+
+
+
+  /**
+   * Check that the hasCode method operator works as expected.
+   * 
+   * @param e1
+   *          The first element
+   * @param e2
+   *          The second element
+   * @param result
+   *          The expected result.
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test(dataProvider = "equalsTestData")
+  public final void testHashCode(SchemaElement e1, SchemaElement e2,
+      boolean result) throws Exception
+  {
+
+    Assert.assertEquals(e1.hashCode() == e2.hashCode(), result);
+  }
+
+
+
+  /**
+   * Check that the {@link SchemaElement#getDescription()} method
+   * returns <code>null</code> when there is no description.
+   * 
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public final void testGetDescriptionDefault() throws Exception
+  {
+    SchemaElement e = getElement("", EMPTY_PROPS);
+    Assert.assertEquals(e.getDescription(), "");
+  }
+
+
+
+  /**
+   * Check that the {@link SchemaElement#getDescription()} method
+   * returns a description.
+   * 
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public final void testGetDescription() throws Exception
+  {
+    SchemaElement e = getElement("hello", EMPTY_PROPS);
+    Assert.assertEquals(e.getDescription(), "hello");
+  }
+
+
+
+  /**
+   * Check that the {@link SchemaElement#getExtraProperty(String)}
+   * method returns <code>null</code> when there is no property.
+   * 
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public final void testGetExtraPropertyDefault() throws Exception
+  {
+    SchemaElement e = getElement("", EMPTY_PROPS);
+    Assert.assertNull(e.getExtraProperty("test"));
+  }
+
+
+
+  /**
+   * Check that the {@link SchemaElement#getExtraProperty(String)}
+   * method returns values.
+   * 
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public final void testGetExtraProperty() throws Exception
+  {
+    List<String> values = new ArrayList<String>();
+    values.add("one");
+    values.add("two");
+    Map<String, List<String>> props =
+        Collections.singletonMap("test", values);
+    SchemaElement e = getElement("", props);
+
+    Assert.assertNotNull(e.getExtraProperty("test"));
+    int i = 0;
+    for (String value : e.getExtraProperty("test"))
+    {
+      Assert.assertEquals(value, values.get(i));
+      i++;
+    }
+  }
+
+
+
+  /**
+   * Check that the {@link SchemaElement#getExtraPropertyNames()}
+   * method.
+   * 
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public final void testGetExtraPropertyNames() throws Exception
+  {
+    SchemaElement e = getElement("", EMPTY_PROPS);
+    Assert.assertNull(e.getExtraProperty("test"));
+    Assert.assertFalse(e.getExtraPropertyNames().iterator().hasNext());
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/ApproximateMatchingRuleTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/ApproximateMatchingRuleTest.java
new file mode 100644
index 0000000..b5946c4
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/ApproximateMatchingRuleTest.java
@@ -0,0 +1,165 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.AMR_DOUBLE_METAPHONE_NAME;
+import static org.testng.Assert.assertEquals;
+
+import org.opends.sdk.ConditionResult;
+import org.opends.sdk.util.ByteString;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Approximate matching rule tests.
+ */
+public class ApproximateMatchingRuleTest extends SchemaTestCase
+{
+  MatchingRule metaphone =
+      Schema.getCoreSchema().getMatchingRule(AMR_DOUBLE_METAPHONE_NAME);
+
+
+
+  /**
+   * Build the data for the approximateMatchingRules test.
+   */
+  @DataProvider(name = "approximatematchingrules")
+  public Object[][] createapproximateMatchingRuleTest()
+  {
+    // fill this table with tables containing :
+    // - the name of the approxiamtematchingrule to test
+    // - 2 values that must be tested for matching
+    // - a boolean indicating if the values match or not
+    return new Object[][] {
+        { metaphone, "celebre", "selebre", ConditionResult.TRUE },
+        { metaphone, "cygale", "sigale", ConditionResult.TRUE },
+        { metaphone, "cigale", "sigale", ConditionResult.TRUE },
+        { metaphone, "accacia", "akacia", ConditionResult.TRUE },
+        { metaphone, "cigale", "sigale", ConditionResult.TRUE },
+        { metaphone, "bertucci", "bertuchi", ConditionResult.TRUE },
+        { metaphone, "manger", "manjer", ConditionResult.TRUE },
+        { metaphone, "gyei", "kei", ConditionResult.TRUE },
+        { metaphone, "agnostique", "aknostic", ConditionResult.TRUE },
+        { metaphone, "ghang", "kang", ConditionResult.TRUE },
+        { metaphone, "affiche", "afiche", ConditionResult.TRUE },
+        { metaphone, "succeed", "sukid", ConditionResult.TRUE },
+        { metaphone, "McCarthur", "macarthur", ConditionResult.TRUE },
+        { metaphone, "czet", "set", ConditionResult.TRUE },
+        { metaphone, "re\u00C7u", "ressu", ConditionResult.TRUE },
+        { metaphone, "ni\u00D1o", "nino", ConditionResult.TRUE },
+        { metaphone, "bateaux", "bateau", ConditionResult.TRUE },
+        { metaphone, "witz", "wits", ConditionResult.TRUE },
+        { metaphone, "barre", "bare", ConditionResult.TRUE },
+        { metaphone, "write", "rite", ConditionResult.TRUE },
+        { metaphone, "the", "ze", ConditionResult.FALSE },
+        { metaphone, "motion", "mochion", ConditionResult.TRUE },
+        { metaphone, "bois", "boi", ConditionResult.TRUE },
+        { metaphone, "schi", "chi", ConditionResult.TRUE },
+        { metaphone, "escalier", "eskalier", ConditionResult.TRUE },
+        { metaphone, "science", "sience", ConditionResult.TRUE },
+        { metaphone, "school", "skool", ConditionResult.TRUE },
+        { metaphone, "swap", "sap", ConditionResult.TRUE },
+        { metaphone, "szize", "size", ConditionResult.TRUE },
+        { metaphone, "shoek", "choek", ConditionResult.FALSE },
+        { metaphone, "sugar", "chugar", ConditionResult.TRUE },
+        { metaphone, "isle", "ile", ConditionResult.TRUE },
+        { metaphone, "yle", "ysle", ConditionResult.TRUE },
+        { metaphone, "focaccia", "focashia", ConditionResult.TRUE },
+        { metaphone, "machine", "mashine", ConditionResult.TRUE },
+        { metaphone, "michael", "mikael", ConditionResult.TRUE },
+        { metaphone, "abba", "aba", ConditionResult.TRUE },
+        { metaphone, "caesar", "saesar", ConditionResult.TRUE },
+        { metaphone, "femme", "fame", ConditionResult.TRUE },
+        { metaphone, "panne", "pane", ConditionResult.TRUE },
+        { metaphone, "josa", "josa", ConditionResult.TRUE },
+        { metaphone, "jose", "hose", ConditionResult.TRUE },
+        { metaphone, "hello", "hello", ConditionResult.TRUE },
+        { metaphone, "hello", "ello", ConditionResult.FALSE },
+        { metaphone, "bag", "bak", ConditionResult.TRUE },
+        { metaphone, "bagg", "bag", ConditionResult.TRUE },
+        { metaphone, "tagliaro", "takliaro", ConditionResult.TRUE },
+        { metaphone, "biaggi", "biaji", ConditionResult.TRUE },
+        { metaphone, "bioggi", "bioji", ConditionResult.TRUE },
+        { metaphone, "rough", "rouf", ConditionResult.TRUE },
+        { metaphone, "ghislane", "jislane", ConditionResult.TRUE },
+        { metaphone, "ghaslane", "kaslane", ConditionResult.TRUE },
+        { metaphone, "odd", "ot", ConditionResult.TRUE },
+        { metaphone, "edgar", "etkar", ConditionResult.TRUE },
+        { metaphone, "edge", "eje", ConditionResult.TRUE },
+        { metaphone, "accord", "akord", ConditionResult.TRUE },
+        { metaphone, "noize", "noise", ConditionResult.TRUE },
+        { metaphone, "orchid", "orkid", ConditionResult.TRUE },
+        { metaphone, "chemistry", "kemistry", ConditionResult.TRUE },
+        { metaphone, "chianti", "kianti", ConditionResult.TRUE },
+        { metaphone, "bacher", "baker", ConditionResult.TRUE },
+        { metaphone, "achtung", "aktung", ConditionResult.TRUE },
+        { metaphone, "Writing", "riting", ConditionResult.TRUE },
+        { metaphone, "xeon", "zeon", ConditionResult.TRUE },
+        { metaphone, "lonely", "loneli", ConditionResult.TRUE },
+        { metaphone, "bellaton", "belatton", ConditionResult.TRUE },
+        { metaphone, "pate", "patte", ConditionResult.TRUE },
+        { metaphone, "voiture", "vouatur", ConditionResult.TRUE },
+        { metaphone, "garbage", "garbedge", ConditionResult.TRUE },
+        { metaphone, "algorithme", "algorizm", ConditionResult.TRUE },
+        { metaphone, "testing", "testng", ConditionResult.TRUE },
+        { metaphone, "announce", "annonce", ConditionResult.TRUE },
+        { metaphone, "automaticly", "automatically",
+            ConditionResult.TRUE },
+        { metaphone, "modifyd", "modified", ConditionResult.TRUE },
+        { metaphone, "bouteille", "butaille", ConditionResult.TRUE },
+        { metaphone, "xeon", "zeon", ConditionResult.TRUE },
+        { metaphone, "achtung", "aktung", ConditionResult.TRUE },
+        { metaphone, "throttle", "throddle", ConditionResult.TRUE },
+        { metaphone, "thimble", "thimblle", ConditionResult.TRUE },
+        { metaphone, "", "", ConditionResult.TRUE }, };
+  }
+
+
+
+  /**
+   * Test the normalization and the approximate comparison.
+   */
+  @Test(dataProvider = "approximatematchingrules")
+  public void approximateMatchingRules(MatchingRule rule,
+      String value1, String value2, ConditionResult result)
+      throws Exception
+  {
+    // normalize the 2 provided values
+    ByteString normalizedValue1 =
+        rule.normalizeAttributeValue(ByteString.valueOf(value1));
+
+    // check that the approximatelyMatch return the expected result.
+    ConditionResult liveResult =
+        rule.getAssertion(ByteString.valueOf(value2)).matches(
+            normalizedValue1);
+    assertEquals(result, liveResult);
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/AttributeTypeSyntaxTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/AttributeTypeSyntaxTest.java
new file mode 100644
index 0000000..08dbbf5
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/AttributeTypeSyntaxTest.java
@@ -0,0 +1,101 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.SYNTAX_ATTRIBUTE_TYPE_OID;
+
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * Attribute type syntax tests.
+ */
+public class AttributeTypeSyntaxTest extends SyntaxTestCase
+{
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected Syntax getRule()
+  {
+    return Schema.getCoreSchema().getSyntax(SYNTAX_ATTRIBUTE_TYPE_OID);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "acceptableValues")
+  public Object[][] createAcceptableValues()
+  {
+    return new Object[][] {
+        {
+            "(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE SUP cn "
+                + " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch"
+                + " SUBSTR caseIgnoreSubstringsMatch"
+                + " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
+                + " USAGE userApplications )", true },
+        {
+            "(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE "
+                + " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch"
+                + " SUBSTR caseIgnoreSubstringsMatch"
+                + " X-APPROX 'equalLengthApproximateMatch'"
+                + " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
+                + " COLLECTIVE USAGE userApplications )", true },
+        { "(1.2.8.5 NAME 'testtype' DESC 'full type')", true },
+        { "(1.2.8.5 USAGE directoryOperation )", true },
+        {
+            "(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE SUP cn "
+                + " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch"
+                + " SUBSTR caseIgnoreSubstringsMatch"
+                + " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
+                + " COLLECTIVE USAGE badUsage )", false },
+        {
+            "(1.2.8.a.b NAME 'testtype' DESC 'full type' OBSOLETE "
+                + " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch"
+                + " SUBSTR caseIgnoreSubstringsMatch"
+                + " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
+                + " COLLECTIVE USAGE directoryOperation )", false },
+        {
+            "(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE SUP cn "
+                + " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch"
+                + " SUBSTR caseIgnoreSubstringsMatch"
+                + " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
+                + " BADTOKEN USAGE directoryOperation )", false },
+        {
+            "1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE "
+                + " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch"
+                + " SUBSTR caseIgnoreSubstringsMatch"
+                + " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
+                + " NO-USER-MODIFICATION USAGE userApplications", false }, };
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/AttributeTypeTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/AttributeTypeTest.java
new file mode 100644
index 0000000..dbc9538
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/AttributeTypeTest.java
@@ -0,0 +1,666 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.*;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.opends.messages.Message;
+import org.opends.sdk.DecodeException;
+import org.opends.server.types.CommonSchemaElements;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Attribute type tests.
+ */
+public class AttributeTypeTest extends AbstractSchemaElementTestCase
+{
+  private Schema schema;
+
+
+
+  public AttributeTypeTest() throws Exception
+  {
+    SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
+    builder.addAttributeType("1.2.1", EMPTY_NAMES, "", true, null,
+        null, null, null, null, "1.3.6.1.4.1.1466.115.121.1.27", true,
+        false, false, AttributeUsage.USER_APPLICATIONS, EMPTY_PROPS,
+        false);
+    builder
+        .addAttributeType(
+            "( 1.2.2 OBSOLETE SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE "
+                + " COLLECTIVE X-ORIGIN ( 'Sun Java System Identity Management' "
+                + "'user defined' ) X-SCHEMA-FILE '98sunEmp.ldif')",
+            false);
+    builder.addAttributeType("1.2.3", Collections
+        .singletonList("testType"), "", false, "1.2.2", null, null,
+        null, null, "1.3.6.1.4.1.1466.115.121.1.27", false, true,
+        false, AttributeUsage.USER_APPLICATIONS, EMPTY_PROPS, false);
+    builder.addAttributeType(
+        "( 1.2.4 NAME 'testType' SUP 1.2.3 SINGLE-VALUE COLLECTIVE )",
+        false);
+    List<String> names = new LinkedList<String>();
+    names.add("testType");
+    names.add("testnamealias");
+    names.add("anothernamealias");
+    builder.addAttributeType("1.2.5", names, "", false, null,
+        EMR_CASE_IGNORE_LIST_OID, null, SMR_CASE_IGNORE_LIST_OID,
+        AMR_DOUBLE_METAPHONE_OID, SYNTAX_INTEGER_OID, false, false,
+        true, AttributeUsage.DSA_OPERATION, EMPTY_PROPS, false);
+    builder
+        .addAttributeType(
+            "( 1.2.6 NAME ( 'testType' 'testnamealias' 'anothernamealias1' ) "
+                + " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SUP anothernamealias"
+                + " USAGE dSAOperation NO-USER-MODIFICATION )", false);
+    List<Message> warnings = new LinkedList<Message>();
+    schema = builder.toSchema(warnings);
+    if (!warnings.isEmpty())
+    {
+      throw new Exception("Base schema not valid!");
+    }
+  }
+
+
+
+  protected SchemaElement getElement(String description,
+      Map<String, List<String>> extraProperties) throws SchemaException
+  {
+    SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
+    builder.addAttributeType("1.2.3", Collections
+        .singletonList("testType"), description, false, null, null,
+        null, null, null, "1.3.6.1.4.1.1466.115.121.1.27", false,
+        false, false, AttributeUsage.DSA_OPERATION, extraProperties,
+        false);
+    return builder.toSchema().getAttributeType("1.2.3");
+  }
+
+
+
+  @DataProvider(name = "equalsTestData")
+  public Object[][] createEqualsTestData() throws SchemaException,
+      DecodeException
+  {
+    return new Object[][] {
+        { schema.getAttributeType("1.2.3"),
+            schema.getAttributeType("1.2.3"), true },
+        { schema.getAttributeType("1.2.4"),
+            schema.getAttributeType("1.2.3"), false } };
+  }
+
+
+
+  /**
+   * Check that the simple constructor throws an NPE when mandatory
+   * parameters are not specified.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test(expectedExceptions = IllegalArgumentException.class)
+  public void testNoSupNorSyntax1() throws Exception
+  {
+    SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
+    builder.addAttributeType("1.2.1", EMPTY_NAMES, "", true, null,
+        null, null, null, null, null, false, false, false,
+        AttributeUsage.DSA_OPERATION, EMPTY_PROPS, false);
+    builder
+        .addAttributeType(
+            "( 1.2.2 OBSOLETE SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )",
+            false);
+  }
+
+
+
+  /**
+   * Check that the simple constructor throws an NPE when mandatory
+   * parameters are not specified.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test(expectedExceptions = IllegalArgumentException.class)
+  public void testNoSupNorSyntax2() throws Exception
+  {
+    SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
+    builder.addAttributeType("( 1.2.2 OBSOLETE SINGLE-VALUE )", false);
+  }
+
+
+
+  /**
+   * Check that the primary name is added to the set of names.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public final void testConstructorPrimaryName() throws Exception
+  {
+    AttributeType d = schema.getAttributeType("1.2.3");
+
+    Assert.assertTrue(d.hasName("testType"));
+    Assert.assertFalse(d.hasName("xxx"));
+
+    d = schema.getAttributeType("1.2.4");
+
+    Assert.assertTrue(d.hasName("testType"));
+    Assert.assertFalse(d.hasName("xxx"));
+
+  }
+
+
+
+  /**
+   * Check that the type names are accessible.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public final void testConstructorTypeNames() throws Exception
+  {
+    AttributeType d = schema.getAttributeType("1.2.5");
+
+    Assert.assertTrue(d.hasName("testType"));
+    Assert.assertTrue(d.hasName("testnamealias"));
+    Assert.assertTrue(d.hasName("anothernamealias"));
+
+    d = schema.getAttributeType("1.2.6");
+
+    Assert.assertTrue(d.hasName("testType"));
+    Assert.assertTrue(d.hasName("testnamealias"));
+    Assert.assertTrue(d.hasName("anothernamealias1"));
+  }
+
+
+
+  /**
+   * Check that the {@link CommonSchemaElements#getNameOrOID()} method.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public final void testGetNameOrOIDReturnsOID() throws Exception
+  {
+    AttributeType d = schema.getAttributeType("1.2.1");
+
+    Assert.assertEquals(d.getNameOrOID(), "1.2.1");
+
+    d = schema.getAttributeType("1.2.2");
+
+    Assert.assertEquals(d.getNameOrOID(), "1.2.2");
+  }
+
+
+
+  /**
+   * Check that the {@link CommonSchemaElements#getNameOrOID()} method.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public final void testGetNameOrOIDReturnsPrimaryName()
+      throws Exception
+  {
+    AttributeType d = schema.getAttributeType("1.2.3");
+    Assert.assertEquals(d.getNameOrOID(), "testType");
+    d = schema.getAttributeType("1.2.4");
+    Assert.assertEquals(d.getNameOrOID(), "testType");
+  }
+
+
+
+  /**
+   * Check that the {@link CommonSchemaElements#getNormalizedNames()}
+   * method.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public final void testGetNormalizedNames() throws Exception
+  {
+    AttributeType d = schema.getAttributeType("1.2.5");
+    Iterator<String> i = d.getNames().iterator();
+    Assert.assertEquals(i.next(), "testType");
+    Assert.assertEquals(i.next(), "testnamealias");
+    Assert.assertEquals(i.next(), "anothernamealias");
+
+    d = schema.getAttributeType("1.2.6");
+    i = d.getNames().iterator();
+    Assert.assertEquals(i.next(), "testType");
+    Assert.assertEquals(i.next(), "testnamealias");
+    Assert.assertEquals(i.next(), "anothernamealias1");
+  }
+
+
+
+  /**
+   * Check that the {@link CommonSchemaElements#getOID()} method.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public final void testGetOID() throws Exception
+  {
+    AttributeType d = schema.getAttributeType("1.2.3");
+    Assert.assertEquals(d.getOID(), "1.2.3");
+    d = schema.getAttributeType("1.2.4");
+    Assert.assertEquals(d.getOID(), "1.2.4");
+
+  }
+
+
+
+  /**
+   * Check that the {@link CommonSchemaElements#hasNameOrOID(String)}
+   * method.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public final void testHasNameOrOID() throws Exception
+  {
+    AttributeType d = schema.getAttributeType("1.2.3");
+
+    Assert.assertTrue(d.hasNameOrOID("testType"));
+    Assert.assertTrue(d.hasNameOrOID("1.2.3"));
+    Assert.assertFalse(d.hasNameOrOID("x.y.z"));
+    d = schema.getAttributeType("1.2.4");
+
+    Assert.assertTrue(d.hasNameOrOID("testType"));
+    Assert.assertTrue(d.hasNameOrOID("1.2.4"));
+    Assert.assertFalse(d.hasNameOrOID("x.y.z"));
+  }
+
+
+
+  /**
+   * Check that the {@link CommonSchemaElements#isObsolete()} method.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public final void testIsObsolete() throws Exception
+  {
+    AttributeType d = schema.getAttributeType("1.2.3");
+    Assert.assertFalse(d.isObsolete());
+    d = schema.getAttributeType("1.2.4");
+    Assert.assertFalse(d.isObsolete());
+
+    d = schema.getAttributeType("1.2.1");
+    Assert.assertTrue(d.isObsolete());
+    d = schema.getAttributeType("1.2.2");
+    Assert.assertTrue(d.isObsolete());
+  }
+
+
+
+  /**
+   * Check constructor sets the default usage correctly.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public void testConstructorDefaultUsage() throws Exception
+  {
+    AttributeType d = schema.getAttributeType("1.2.2");
+
+    Assert.assertEquals(d.getUsage(), AttributeUsage.USER_APPLICATIONS);
+  }
+
+
+
+  /**
+   * Check constructor sets the syntax correctly.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public void testConstructorSyntax() throws Exception
+  {
+    AttributeType d = schema.getAttributeType("1.2.2");
+
+    Assert.assertEquals(d.getSyntax().getOID(),
+        "1.3.6.1.4.1.1466.115.121.1.15");
+  }
+
+
+
+  /**
+   * Check constructor inherits the syntax from the parent type when
+   * required.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test(dependsOnMethods = "testConstructorSyntax")
+  public void testConstructorInheritsSyntax() throws Exception
+  {
+    AttributeType parent = schema.getAttributeType("1.2.3");
+
+    AttributeType child = schema.getAttributeType("1.2.4");
+
+    Assert.assertEquals(parent.getSyntax(), child.getSyntax());
+
+    parent = schema.getAttributeType("1.2.2");
+
+    child = schema.getAttributeType("1.2.3");
+    Assert.assertFalse(parent.getSyntax().equals(child.getSyntax()));
+
+    // Make sure paren't s syntax was not inherited in this case
+    child = schema.getAttributeType("1.2.6");
+    Assert.assertEquals(child.getSyntax().getOID(),
+        SYNTAX_DIRECTORY_STRING_OID);
+  }
+
+
+
+  /**
+   * Check constructor sets the default matching rules correctly.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public void testConstructorDefaultMatchingRules() throws Exception
+  {
+    AttributeType type = schema.getAttributeType("1.2.1");
+
+    Syntax syntax = schema.getSyntax("1.3.6.1.4.1.1466.115.121.1.27");
+    Assert.assertEquals(type.getApproximateMatchingRule(), syntax
+        .getApproximateMatchingRule());
+    Assert.assertEquals(type.getEqualityMatchingRule(), syntax
+        .getEqualityMatchingRule());
+    Assert.assertEquals(type.getOrderingMatchingRule(), syntax
+        .getOrderingMatchingRule());
+    Assert.assertEquals(type.getSubstringMatchingRule(), syntax
+        .getSubstringMatchingRule());
+  }
+
+
+
+  /**
+   * Check constructor sets the matching rules correctly.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public void testConstructorMatchingRules() throws Exception
+  {
+    AttributeType type = schema.getAttributeType("1.2.5");
+
+    Assert.assertEquals(type.getEqualityMatchingRule().getOID(),
+        EMR_CASE_IGNORE_LIST_OID);
+    Assert.assertEquals(type.getOrderingMatchingRule().getOID(), type
+        .getSyntax().getOrderingMatchingRule().getOID());
+    Assert.assertEquals(type.getSubstringMatchingRule().getOID(),
+        SMR_CASE_IGNORE_LIST_OID);
+    Assert.assertEquals(type.getApproximateMatchingRule().getOID(),
+        AMR_DOUBLE_METAPHONE_OID);
+  }
+
+
+
+  /**
+   * Check constructor inherits the matching rules from the parent type
+   * when required.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test(dependsOnMethods = "testConstructorMatchingRules")
+  public void testConstructorInheritsMatchingRules() throws Exception
+  {
+    AttributeType parent = schema.getAttributeType("1.2.5");
+
+    AttributeType child = schema.getAttributeType("1.2.6");
+
+    Assert.assertEquals(parent.getApproximateMatchingRule(), child
+        .getApproximateMatchingRule());
+    Assert.assertEquals(parent.getEqualityMatchingRule(), child
+        .getEqualityMatchingRule());
+    // It should inherit ordering rule from parent's syntax since parent
+    // didn't specify an ordering matching rule.
+    Assert.assertEquals(parent.getSyntax().getOrderingMatchingRule(),
+        child.getOrderingMatchingRule());
+    Assert.assertEquals(parent.getSubstringMatchingRule(), child
+        .getSubstringMatchingRule());
+  }
+
+
+
+  /**
+   * Check that the {@link AttributeType#isCollective()} method.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public void testIsCollective() throws Exception
+  {
+    AttributeType type = schema.getAttributeType("1.2.2");
+    Assert.assertTrue(type.isCollective());
+    type = schema.getAttributeType("1.2.3");
+    Assert.assertTrue(type.isCollective());
+    type = schema.getAttributeType("1.2.6");
+    Assert.assertFalse(type.isCollective());
+    type = schema.getAttributeType("1.2.5");
+    Assert.assertFalse(type.isCollective());
+  }
+
+
+
+  /**
+   * Check that the {@link AttributeType#isNoUserModification()} method.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public void testIsNoUserModification() throws Exception
+  {
+    AttributeType type = schema.getAttributeType("1.2.5");
+    Assert.assertTrue(type.isNoUserModification());
+    type = schema.getAttributeType("1.2.6");
+    Assert.assertTrue(type.isNoUserModification());
+    type = schema.getAttributeType("1.2.3");
+    Assert.assertFalse(type.isNoUserModification());
+    type = schema.getAttributeType("1.2.4");
+    Assert.assertFalse(type.isNoUserModification());
+  }
+
+
+
+  /**
+   * Check that the {@link AttributeType#isSingleValue()} method.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public void testIsSingleValue() throws Exception
+  {
+    AttributeType type = schema.getAttributeType("1.2.1");
+    Assert.assertTrue(type.isSingleValue());
+    type = schema.getAttributeType("1.2.2");
+    Assert.assertTrue(type.isSingleValue());
+    type = schema.getAttributeType("1.2.5");
+    Assert.assertFalse(type.isSingleValue());
+    type = schema.getAttributeType("1.2.6");
+    Assert.assertFalse(type.isSingleValue());
+  }
+
+
+
+  /**
+   * Check that the {@link AttributeType#getUsage()} method.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public void testGetAttributeUsage() throws Exception
+  {
+    AttributeType type = schema.getAttributeType("1.2.1");
+    Assert.assertEquals(type.getUsage(),
+        AttributeUsage.USER_APPLICATIONS);
+    type = schema.getAttributeType("1.2.6");
+    Assert.assertEquals(type.getUsage(), AttributeUsage.DSA_OPERATION);
+  }
+
+
+
+  /**
+   * Check that the {@link AttributeType#getSuperiorType()} method.
+   *
+   * @throws Exception
+   *           If the test failed unexpectedly.
+   */
+  @Test
+  public void testGetSuperiorType() throws Exception
+  {
+    AttributeType type = schema.getAttributeType("1.2.3");
+    Assert.assertEquals(type.getSuperiorType().getOID(), "1.2.2");
+    type = schema.getAttributeType("1.2.4");
+    Assert.assertEquals(type.getSuperiorType().getOID(), "1.2.3");
+  }
+
+
+
+  public void testInheritFromNonCollective() throws Exception
+  {
+    // Collective can't inherit from non-collective
+    SchemaBuilder builder = new SchemaBuilder(schema);
+    builder
+        .addAttributeType(
+            "(1.2.8.5 NAME 'testtype' DESC 'full type' "
+                + " OBSOLETE SUP 1.2.5 "
+                + " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch"
+                + " SUBSTR caseIgnoreSubstringsMatch"
+                + " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
+                + " COLLECTIVE USAGE userApplications )", false);
+    List<Message> warnings = new LinkedList<Message>();
+    builder.toSchema(warnings);
+    Assert.assertFalse(warnings.isEmpty());
+  }
+
+
+
+  public void testCollectiveOperational() throws Exception
+  {
+    // Collective can't be operational
+    SchemaBuilder builder = new SchemaBuilder(schema);
+    builder
+        .addAttributeType(
+            "(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE "
+                + " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch"
+                + " SUBSTR caseIgnoreSubstringsMatch"
+                + " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
+                + " COLLECTIVE USAGE directoryOperation )", false);
+    List<Message> warnings = new LinkedList<Message>();
+    builder.toSchema(warnings);
+    Assert.assertFalse(warnings.isEmpty());
+  }
+
+
+
+  public void testInheritFromUserAppUsage() throws Exception
+  {
+    // directoryOperation can't inherit from userApplications
+    SchemaBuilder builder = new SchemaBuilder(schema);
+    builder
+        .addAttributeType(
+            "(1.2.8.5 NAME 'testtype' DESC 'full type' "
+                + " OBSOLETE SUP 1.2.1 "
+                + " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch"
+                + " SUBSTR caseIgnoreSubstringsMatch"
+                + " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
+                + " NO-USER-MODIFICATION USAGE directoryOperation )",
+            false);
+    List<Message> warnings = new LinkedList<Message>();
+    builder.toSchema(warnings);
+    Assert.assertFalse(warnings.isEmpty());
+  }
+
+
+
+  public void testNoUserModNonOperational() throws Exception
+  {
+    // NO-USER-MODIFICATION can't have non-operational usage
+    SchemaBuilder builder = new SchemaBuilder(schema);
+    builder
+        .addAttributeType(
+            "(1.2.8.5 NAME 'testtype' DESC 'full type' OBSOLETE "
+                + " EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch"
+                + " SUBSTR caseIgnoreSubstringsMatch"
+                + " SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
+                + " NO-USER-MODIFICATION USAGE userApplications )",
+            false);
+    List<Message> warnings = new LinkedList<Message>();
+    builder.toSchema(warnings);
+    Assert.assertFalse(warnings.isEmpty());
+  }
+
+
+
+  public void testADSyntax() throws Exception
+  {
+    // AD uses single quotes around OIDs
+    SchemaBuilder builder = new SchemaBuilder(schema);
+    builder
+        .addAttributeType(
+            "(1.2.8.5 NAME 'testtype' DESC 'full type' "
+                + " SUP '1.2.5' "
+                + " EQUALITY 'caseIgnoreMatch' "
+                + " SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' USAGE dSAOperation )",
+            false);
+    List<Message> warnings = new LinkedList<Message>();
+    builder.toSchema(warnings);
+    Assert.assertFalse(warnings.isEmpty());
+  }
+
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/BitStringEqualityMatchingRuleTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/BitStringEqualityMatchingRuleTest.java
new file mode 100644
index 0000000..5f81133
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/BitStringEqualityMatchingRuleTest.java
@@ -0,0 +1,79 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.EMR_BIT_STRING_OID;
+
+import org.opends.sdk.ConditionResult;
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * Test the BitStringEqualityMatchingRule.
+ */
+public class BitStringEqualityMatchingRuleTest extends MatchingRuleTest
+{
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "matchingRuleInvalidAttributeValues")
+  public Object[][] createMatchingRuleInvalidAttributeValues()
+  {
+    return new Object[][] { { "\'a\'B" }, { "0" }, { "010101" },
+        { "\'10101" }, { "\'1010\'A" }, };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "matchingrules")
+  public Object[][] createMatchingRuleTest()
+  {
+    return new Object[][] {
+        { "\'0\'B", "\'0\'B", ConditionResult.TRUE },
+        { "\'1\'B", "\'1\'B", ConditionResult.TRUE },
+        { "\'0\'B", "\'1\'B", ConditionResult.FALSE }, };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected MatchingRule getRule()
+  {
+    return Schema.getCoreSchema().getMatchingRule(EMR_BIT_STRING_OID);
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/BitStringSyntaxTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/BitStringSyntaxTest.java
new file mode 100644
index 0000000..4ef06b3
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/BitStringSyntaxTest.java
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.SYNTAX_BIT_STRING_OID;
+
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * Bit string syntax tests.
+ */
+public class BitStringSyntaxTest extends SyntaxTestCase
+{
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected Syntax getRule()
+  {
+    return Schema.getCoreSchema().getSyntax(SYNTAX_BIT_STRING_OID);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "acceptableValues")
+  public Object[][] createAcceptableValues()
+  {
+    return new Object[][] { { "'0101'B", true }, { "'1'B", true },
+        { "'0'B", true }, { "invalid", false }, { "1", false },
+        { "'010100000111111010101000'B", true }, };
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/BooleanEqualityMatchingRuleTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/BooleanEqualityMatchingRuleTest.java
new file mode 100644
index 0000000..e5d3306
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/BooleanEqualityMatchingRuleTest.java
@@ -0,0 +1,85 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.EMR_BOOLEAN_OID;
+
+import org.opends.sdk.ConditionResult;
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * Test the BooleanEqualityMatchingRule.
+ */
+public class BooleanEqualityMatchingRuleTest extends MatchingRuleTest
+{
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "matchingrules")
+  public Object[][] createMatchingRuleTest()
+  {
+    return new Object[][] { { "TRUE", "true", ConditionResult.TRUE },
+        { "YES", "true", ConditionResult.TRUE },
+        { "ON", "true", ConditionResult.TRUE },
+        { "1", "true", ConditionResult.TRUE },
+        { "FALSE", "false", ConditionResult.TRUE },
+        { "NO", "false", ConditionResult.TRUE },
+        { "OFF", "false", ConditionResult.TRUE },
+        { "0", "false", ConditionResult.TRUE },
+        { "TRUE", "false", ConditionResult.FALSE }, };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "matchingRuleInvalidAttributeValues")
+  public Object[][] createMatchingRuleInvalidAttributeValues()
+  {
+    return new Object[][] { { "garbage" }, };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected MatchingRule getRule()
+  {
+    return Schema.getCoreSchema().getMatchingRule(EMR_BOOLEAN_OID);
+  }
+
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactEqualityMatchingRuleTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactEqualityMatchingRuleTest.java
new file mode 100644
index 0000000..b6bfa48
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactEqualityMatchingRuleTest.java
@@ -0,0 +1,85 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.EMR_CASE_EXACT_OID;
+
+import org.opends.sdk.ConditionResult;
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * Test the CaseExactEqualityMatchingRule.
+ */
+public class CaseExactEqualityMatchingRuleTest extends MatchingRuleTest
+{
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "matchingRuleInvalidAttributeValues")
+  public Object[][] createMatchingRuleInvalidAttributeValues()
+  {
+    return new Object[][] {};
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "matchingrules")
+  public Object[][] createMatchingRuleTest()
+  {
+    return new Object[][] {
+        { "12345678", "12345678", ConditionResult.TRUE },
+        { "12345678\u2163", "12345678\u2163", ConditionResult.TRUE },
+        { "ABC45678", "ABC45678", ConditionResult.TRUE },
+        { "  ABC45678  ", "ABC45678", ConditionResult.TRUE },
+        { "ABC   45678", "ABC 45678", ConditionResult.TRUE },
+        { "   ", " ", ConditionResult.TRUE },
+        { "", "", ConditionResult.TRUE },
+        { "ABC45678", "abc45678", ConditionResult.FALSE }, };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected MatchingRule getRule()
+  {
+    return Schema.getCoreSchema().getMatchingRule(EMR_CASE_EXACT_OID);
+  }
+
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactIA5EqualityMatchingRuleTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactIA5EqualityMatchingRuleTest.java
new file mode 100644
index 0000000..5d0b89d
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactIA5EqualityMatchingRuleTest.java
@@ -0,0 +1,89 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.EMR_CASE_EXACT_IA5_OID;
+
+import org.opends.sdk.ConditionResult;
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * Test the CaseExactIA5EqualityMatchingRule.
+ */
+public class CaseExactIA5EqualityMatchingRuleTest extends
+    MatchingRuleTest
+{
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "matchingRuleInvalidAttributeValues")
+  public Object[][] createMatchingRuleInvalidAttributeValues()
+  {
+    return new Object[][] { { "12345678\uFFFD" }, };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "matchingrules")
+  public Object[][] createMatchingRuleTest()
+  {
+    return new Object[][] {
+        { "12345678", "12345678", ConditionResult.TRUE },
+        { "ABC45678", "ABC45678", ConditionResult.TRUE },
+        { "ABC45678", "abc45678", ConditionResult.FALSE },
+        { "\u0020foo\u0020bar\u0020\u0020", "foo bar",
+            ConditionResult.TRUE },
+        { "test\u00AD\u200D", "test", ConditionResult.TRUE },
+        { "foo\u000Bbar", "foo\u0020bar", ConditionResult.TRUE },
+        { "foo\u070Fbar", "foobar", ConditionResult.TRUE },
+
+    };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected MatchingRule getRule()
+  {
+    return Schema.getCoreSchema().getMatchingRule(
+        EMR_CASE_EXACT_IA5_OID);
+  }
+
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactIA5SubstringMatchingRuleTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactIA5SubstringMatchingRuleTest.java
new file mode 100644
index 0000000..8e0b902
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactIA5SubstringMatchingRuleTest.java
@@ -0,0 +1,155 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.SMR_CASE_EXACT_IA5_OID;
+
+import org.opends.sdk.ConditionResult;
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * Test the CaseExactIA5SubstringMatchingRule.
+ */
+public class CaseExactIA5SubstringMatchingRuleTest extends
+    SubstringMatchingRuleTest
+{
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "substringMiddleMatchData")
+  public Object[][] createSubstringMiddleMatchData()
+  {
+    return new Object[][] {
+        { "this is a value", new String[] { "this" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "is" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "a" }, ConditionResult.TRUE },
+        { "this is a value", new String[] { "value" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { " " }, ConditionResult.TRUE },
+        { "this is a value",
+            new String[] { "this", "is", "a", "value" },
+            ConditionResult.TRUE },
+        // The matching rule requires ordered non overlapping substrings
+        // Issue #730 was not valid.
+        { "this is a value", new String[] { "value", "this" },
+            ConditionResult.FALSE },
+        { "this is a value", new String[] { "this", "this is" },
+            ConditionResult.FALSE },
+        { "this is a value", new String[] { "his is", "a val", },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "not", },
+            ConditionResult.FALSE },
+        { "this is a value", new String[] { "THIS", },
+            ConditionResult.FALSE },
+        { "this is a value", new String[] { "this", "not" },
+            ConditionResult.FALSE },
+        { "this is a value", new String[] { "    " },
+            ConditionResult.TRUE }, };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected MatchingRule getRule()
+  {
+    return Schema.getCoreSchema().getMatchingRule(
+        SMR_CASE_EXACT_IA5_OID);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "substringInitialMatchData")
+  public Object[][] createSubstringInitialMatchData()
+  {
+    return new Object[][] {
+        { "this is a value", "this", ConditionResult.TRUE },
+        { "this is a value", "th", ConditionResult.TRUE },
+        { "this is a value", "t", ConditionResult.TRUE },
+        { "this is a value", "is", ConditionResult.FALSE },
+        { "this is a value", "a", ConditionResult.FALSE },
+        { "this is a value", "value", ConditionResult.FALSE },
+        { "this is a value", " ", ConditionResult.FALSE },
+        { "this is a value", "NOT", ConditionResult.FALSE },
+        { "this is a value", "THIS", ConditionResult.FALSE }, };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "substringFinalMatchData")
+  public Object[][] createSubstringFinalMatchData()
+  {
+    return new Object[][] {
+        { "this is a value", "value", ConditionResult.TRUE },
+        { "this is a value", "alue", ConditionResult.TRUE },
+        { "this is a value", "ue", ConditionResult.TRUE },
+        { "this is a value", "e", ConditionResult.TRUE },
+        { "this is a value", "valu", ConditionResult.FALSE },
+        { "this is a value", "this", ConditionResult.FALSE },
+        { "this is a value", " ", ConditionResult.FALSE },
+        { "this is a value", "VALUE", ConditionResult.FALSE },
+        { "this is a VALUE", "value", ConditionResult.FALSE },
+        { "end with space    ", " ", ConditionResult.FALSE },
+        { "end with space    ", "space", ConditionResult.TRUE }, };
+  }
+
+
+
+  @DataProvider(name = "substringInvalidAttributeValues")
+  public Object[][] createMatchingRuleInvalidAttributeValues()
+  {
+    return new Object[][] { { "12345678\uFFFD" }, };
+  }
+
+
+
+  @DataProvider(name = "substringInvalidAssertionValues")
+  public Object[][] createMatchingRuleInvalidAssertionValues()
+  {
+    return new Object[][] { { "12345678\uFFFD", new String[0], null },
+        { null, new String[] { "12345678\uFFFD" }, null },
+        { null, new String[0], "12345678\uFFFD" }, };
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactOrderingMatchingRuleTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactOrderingMatchingRuleTest.java
new file mode 100644
index 0000000..a133c75
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactOrderingMatchingRuleTest.java
@@ -0,0 +1,77 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.OMR_CASE_EXACT_OID;
+
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * Test the CaseExactOrderingMatchingRule.
+ */
+public class CaseExactOrderingMatchingRuleTest extends
+    OrderingMatchingRuleTest
+{
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "OrderingMatchingRuleInvalidValues")
+  public Object[][] createOrderingMatchingRuleInvalidValues()
+  {
+    return new Object[][] {};
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "Orderingmatchingrules")
+  public Object[][] createOrderingMatchingRuleTestData()
+  {
+    return new Object[][] { { "12345678", "02345678", 1 },
+        { "abcdef", "bcdefa", -1 }, { "abcdef", "abcdef", 0 }, };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected MatchingRule getRule()
+  {
+    return Schema.getCoreSchema().getMatchingRule(OMR_CASE_EXACT_OID);
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactSubstringMatchingRuleTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactSubstringMatchingRuleTest.java
new file mode 100644
index 0000000..7313ce7
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseExactSubstringMatchingRuleTest.java
@@ -0,0 +1,154 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.SMR_CASE_EXACT_OID;
+
+import org.opends.sdk.ConditionResult;
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * Test the CaseExactSubstringMatchingRule class.
+ */
+public class CaseExactSubstringMatchingRuleTest extends
+    SubstringMatchingRuleTest
+{
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "substringMiddleMatchData")
+  public Object[][] createSubstringMiddleMatchData()
+  {
+    return new Object[][] {
+        { "this is a value", new String[] { "this" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "is" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "a" }, ConditionResult.TRUE },
+        { "this is a value", new String[] { "value" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { " " }, ConditionResult.TRUE },
+        { "this is a value",
+            new String[] { "this", "is", "a", "value" },
+            ConditionResult.TRUE },
+        // The matching rule requires ordered non overlapping
+        // substrings.
+        // Issue #730 was not valid.
+        { "this is a value", new String[] { "value", "this" },
+            ConditionResult.FALSE },
+        { "this is a value", new String[] { "this", "this is" },
+            ConditionResult.FALSE },
+        { "this is a value", new String[] { "his is", "a val", },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "not", },
+            ConditionResult.FALSE },
+        { "this is a value", new String[] { "THIS", },
+            ConditionResult.FALSE },
+        { "this is a value", new String[] { "this", "not" },
+            ConditionResult.FALSE },
+        { "this is a value", new String[] { "    " },
+            ConditionResult.TRUE }, };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected MatchingRule getRule()
+  {
+    return Schema.getCoreSchema().getMatchingRule(SMR_CASE_EXACT_OID);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "substringInitialMatchData")
+  public Object[][] createSubstringInitialMatchData()
+  {
+    return new Object[][] {
+        { "this is a value", "this", ConditionResult.TRUE },
+        { "this is a value", "th", ConditionResult.TRUE },
+        { "this is a value", "t", ConditionResult.TRUE },
+        { "this is a value", "is", ConditionResult.FALSE },
+        { "this is a value", "a", ConditionResult.FALSE },
+        { "this is a value", "value", ConditionResult.FALSE },
+        { "this is a value", " ", ConditionResult.FALSE },
+        { "this is a value", "NOT", ConditionResult.FALSE },
+        { "this is a value", "THIS", ConditionResult.FALSE }, };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "substringFinalMatchData")
+  public Object[][] createSubstringFinalMatchData()
+  {
+    return new Object[][] {
+        { "this is a value", "value", ConditionResult.TRUE },
+        { "this is a value", "alue", ConditionResult.TRUE },
+        { "this is a value", "ue", ConditionResult.TRUE },
+        { "this is a value", "e", ConditionResult.TRUE },
+        { "this is a value", "valu", ConditionResult.FALSE },
+        { "this is a value", "this", ConditionResult.FALSE },
+        { "this is a value", " ", ConditionResult.FALSE },
+        { "this is a value", "VALUE", ConditionResult.FALSE },
+        { "this is a VALUE", "value", ConditionResult.FALSE },
+        { "end with space    ", " ", ConditionResult.FALSE },
+        { "end with space    ", "space", ConditionResult.TRUE }, };
+  }
+
+
+
+  @DataProvider(name = "substringInvalidAttributeValues")
+  public Object[][] createMatchingRuleInvalidAttributeValues()
+  {
+    return new Object[][] {};
+  }
+
+
+
+  @DataProvider(name = "substringInvalidAssertionValues")
+  public Object[][] createMatchingRuleInvalidAssertionValues()
+  {
+    return new Object[][] {};
+  }
+
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreEqualityMatchingRuleTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreEqualityMatchingRuleTest.java
new file mode 100644
index 0000000..3985194
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreEqualityMatchingRuleTest.java
@@ -0,0 +1,92 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.EMR_CASE_IGNORE_OID;
+
+import org.opends.sdk.ConditionResult;
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * Test the CaseIgnoreEqualityMatchingRule.
+ */
+public class CaseIgnoreEqualityMatchingRuleTest extends
+    MatchingRuleTest
+{
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "matchingRuleInvalidAttributeValues")
+  public Object[][] createMatchingRuleInvalidAttributeValues()
+  {
+    return new Object[][] {};
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "matchingrules")
+  public Object[][] createMatchingRuleTest()
+  {
+    return new Object[][] {
+        { " string ", "string", ConditionResult.TRUE },
+        { "string ", "string", ConditionResult.TRUE },
+        { " string", "string", ConditionResult.TRUE },
+        { "    ", " ", ConditionResult.TRUE },
+        { "Z", "z", ConditionResult.TRUE },
+        { "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890",
+            "abcdefghijklmnopqrstuvwxyz1234567890",
+            ConditionResult.TRUE },
+        { "foo\u0020bar\u0020\u0020", "foo bar", ConditionResult.TRUE },
+        { "test\u00AD\u200D", "test", ConditionResult.TRUE },
+        { "foo\u070Fbar", "foobar", ConditionResult.TRUE },
+        // Case-folding data below.
+        { "foo\u0149bar", "foo\u02BC\u006Ebar", ConditionResult.TRUE },
+        { "foo\u017Bbar", "foo\u017Cbar", ConditionResult.TRUE },
+
+    };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected MatchingRule getRule()
+  {
+    return Schema.getCoreSchema().getMatchingRule(EMR_CASE_IGNORE_OID);
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreIA5EqualityMatchingRuleTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreIA5EqualityMatchingRuleTest.java
new file mode 100644
index 0000000..58c44ca
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreIA5EqualityMatchingRuleTest.java
@@ -0,0 +1,82 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.EMR_CASE_IGNORE_IA5_OID;
+
+import org.opends.sdk.ConditionResult;
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * Test the CaseExactIA5EqualityMatchingRule.
+ */
+public class CaseIgnoreIA5EqualityMatchingRuleTest extends
+    MatchingRuleTest
+{
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "matchingRuleInvalidAttributeValues")
+  public Object[][] createMatchingRuleInvalidAttributeValues()
+  {
+    return new Object[][] { { "12345678\uFFFD" }, };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "matchingrules")
+  public Object[][] createMatchingRuleTest()
+  {
+    return new Object[][] {
+        { "12345678", "12345678", ConditionResult.TRUE },
+        { "ABC45678", "ABC45678", ConditionResult.TRUE },
+        { "ABC45678", "abc45678", ConditionResult.TRUE }, };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected MatchingRule getRule()
+  {
+    return Schema.getCoreSchema().getMatchingRule(
+        EMR_CASE_IGNORE_IA5_OID);
+  }
+
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreIA5SubstringMatchingRuleTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreIA5SubstringMatchingRuleTest.java
new file mode 100644
index 0000000..751153b
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreIA5SubstringMatchingRuleTest.java
@@ -0,0 +1,174 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.SMR_CASE_IGNORE_IA5_OID;
+
+import org.opends.sdk.ConditionResult;
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * Test the CaseIgnoreIA5SubstringMatchingRule.
+ */
+public class CaseIgnoreIA5SubstringMatchingRuleTest extends
+    SubstringMatchingRuleTest
+{
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "substringMiddleMatchData")
+  public Object[][] createSubstringMiddleMatchData()
+  {
+    return new Object[][] {
+        { "this is a value", new String[] { "this" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "is" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "a" }, ConditionResult.TRUE },
+        { "this is a value", new String[] { "value" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "THIS" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "IS" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "A" }, ConditionResult.TRUE },
+        { "this is a value", new String[] { "VALUE" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { " " }, ConditionResult.TRUE },
+        { "this is a value",
+            new String[] { "this", "is", "a", "value" },
+            ConditionResult.TRUE },
+        // The matching rule requires ordered non overlapping
+        // substrings.
+        // Issue #730 was not valid.
+        { "this is a value", new String[] { "value", "this" },
+            ConditionResult.FALSE },
+        { "this is a value", new String[] { "this", "this is" },
+            ConditionResult.FALSE },
+        { "this is a value",
+            new String[] { "this", "IS", "a", "VALue" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "his IS", "A val", },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "not", },
+            ConditionResult.FALSE },
+        { "this is a value", new String[] { "this", "not" },
+            ConditionResult.FALSE },
+        { "this is a value", new String[] { "    " },
+            ConditionResult.TRUE }, };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected MatchingRule getRule()
+  {
+    return Schema.getCoreSchema().getMatchingRule(
+        SMR_CASE_IGNORE_IA5_OID);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "substringInitialMatchData")
+  public Object[][] createSubstringInitialMatchData()
+  {
+    return new Object[][] {
+        { "this is a value", "this", ConditionResult.TRUE },
+        { "this is a value", "th", ConditionResult.TRUE },
+        { "this is a value", "t", ConditionResult.TRUE },
+        { "this is a value", "is", ConditionResult.FALSE },
+        { "this is a value", "a", ConditionResult.FALSE },
+        { "this is a value", "TH", ConditionResult.TRUE },
+        { "this is a value", "T", ConditionResult.TRUE },
+        { "this is a value", "IS", ConditionResult.FALSE },
+        { "this is a value", "A", ConditionResult.FALSE },
+        { "this is a value", "VALUE", ConditionResult.FALSE },
+        { "this is a value", " ", ConditionResult.FALSE },
+        { "this is a value", "NOT", ConditionResult.FALSE },
+        { "this is a value", "THIS", ConditionResult.TRUE }, };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "substringFinalMatchData")
+  public Object[][] createSubstringFinalMatchData()
+  {
+    return new Object[][] {
+        { "this is a value", "value", ConditionResult.TRUE },
+        { "this is a value", "alue", ConditionResult.TRUE },
+        { "this is a value", "ue", ConditionResult.TRUE },
+        { "this is a value", "e", ConditionResult.TRUE },
+        { "this is a value", "valu", ConditionResult.FALSE },
+        { "this is a value", "this", ConditionResult.FALSE },
+        { "this is a value", "VALUE", ConditionResult.TRUE },
+        { "this is a value", "AlUe", ConditionResult.TRUE },
+        { "this is a value", "UE", ConditionResult.TRUE },
+        { "this is a value", "E", ConditionResult.TRUE },
+        { "this is a value", "valu", ConditionResult.FALSE },
+        { "this is a value", "THIS", ConditionResult.FALSE },
+        { "this is a value", " ", ConditionResult.FALSE },
+        { "this is a VALUE", "value", ConditionResult.TRUE },
+        { "end with space    ", " ", ConditionResult.FALSE },
+        { "end with space    ", "space", ConditionResult.TRUE },
+        { "end with space    ", "SPACE", ConditionResult.TRUE }, };
+  }
+
+
+
+  @DataProvider(name = "substringInvalidAttributeValues")
+  public Object[][] createMatchingRuleInvalidAttributeValues()
+  {
+    return new Object[][] { { "12345678\uFFFD" }, };
+  }
+
+
+
+  @DataProvider(name = "substringInvalidAssertionValues")
+  public Object[][] createMatchingRuleInvalidAssertionValues()
+  {
+    return new Object[][] { { "12345678\uFFFD", new String[0], null },
+        { null, new String[] { "12345678\uFFFD" }, null },
+        { null, new String[0], "12345678\uFFFD" }, };
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreOrderingMatchingRuleTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreOrderingMatchingRuleTest.java
new file mode 100644
index 0000000..e0f8291
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreOrderingMatchingRuleTest.java
@@ -0,0 +1,89 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.OMR_CASE_IGNORE_OID;
+
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * Test the CaseIgnoreOrderingMatchingRule.
+ */
+public class CaseIgnoreOrderingMatchingRuleTest extends
+    OrderingMatchingRuleTest
+{
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "OrderingMatchingRuleInvalidValues")
+  public Object[][] createOrderingMatchingRuleInvalidValues()
+  {
+    return new Object[][] {};
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "Orderingmatchingrules")
+  public Object[][] createOrderingMatchingRuleTestData()
+  {
+    return new Object[][] { { "12345678", "02345678", 1 },
+        { "abcdef", "bcdefa", -1 }, { "abcdef", "abcdef", 0 },
+        { "abcdef", "ABCDEF", 0 },
+        { "abcdef", "aCcdef", -1 },
+        { "aCcdef", "abcdef", 1 },
+        { "foo\u0020bar\u0020\u0020", "foo bar", 0 },
+        { "test\u00AD\u200D", "test", 0 },
+        { "foo\u070Fbar", "foobar", 0 },
+        // Case-folding data below.
+        { "foo\u0149bar", "foo\u02BC\u006Ebar", 0 },
+        { "foo\u017Bbar", "foo\u017Cbar", 0 },
+        { "foo\u017Bbar", "goo\u017Cbar", -1 },
+        // issue# 3583
+        { "a", "\u00f8", -1 }, };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected MatchingRule getRule()
+  {
+    return Schema.getCoreSchema().getMatchingRule(OMR_CASE_IGNORE_OID);
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreSubstringMatchingRuleTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreSubstringMatchingRuleTest.java
new file mode 100644
index 0000000..6a5165e
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CaseIgnoreSubstringMatchingRuleTest.java
@@ -0,0 +1,171 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.SMR_CASE_IGNORE_OID;
+
+import org.opends.sdk.ConditionResult;
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * Test the CaseIgnoreSubstringMatchingRule.
+ */
+public class CaseIgnoreSubstringMatchingRuleTest extends
+    SubstringMatchingRuleTest
+{
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "substringMiddleMatchData")
+  public Object[][] createSubstringMiddleMatchData()
+  {
+    return new Object[][] {
+        { "this is a value", new String[] { "this" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "is" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "a" }, ConditionResult.TRUE },
+        { "this is a value", new String[] { "value" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "THIS" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "IS" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "A" }, ConditionResult.TRUE },
+        { "this is a value", new String[] { "VALUE" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { " " }, ConditionResult.TRUE },
+        { "this is a value",
+            new String[] { "this", "is", "a", "value" },
+            ConditionResult.TRUE },
+        // The matching rule requires ordered non overlapping
+        // substrings.
+        // Issue #730 was not valid.
+        { "this is a value", new String[] { "value", "this" },
+            ConditionResult.FALSE },
+        { "this is a value", new String[] { "this", "this is" },
+            ConditionResult.FALSE },
+        { "this is a value",
+            new String[] { "this", "IS", "a", "VALue" },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "his IS", "A val", },
+            ConditionResult.TRUE },
+        { "this is a value", new String[] { "not", },
+            ConditionResult.FALSE },
+        { "this is a value", new String[] { "this", "not" },
+            ConditionResult.FALSE },
+        { "this is a value", new String[] { "    " },
+            ConditionResult.TRUE }, };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected MatchingRule getRule()
+  {
+    return Schema.getCoreSchema().getMatchingRule(SMR_CASE_IGNORE_OID);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "substringInitialMatchData")
+  public Object[][] createSubstringInitialMatchData()
+  {
+    return new Object[][] {
+        { "this is a value", "this", ConditionResult.TRUE },
+        { "this is a value", "th", ConditionResult.TRUE },
+        { "this is a value", "t", ConditionResult.TRUE },
+        { "this is a value", "is", ConditionResult.FALSE },
+        { "this is a value", "a", ConditionResult.FALSE },
+        { "this is a value", "TH", ConditionResult.TRUE },
+        { "this is a value", "T", ConditionResult.TRUE },
+        { "this is a value", "IS", ConditionResult.FALSE },
+        { "this is a value", "A", ConditionResult.FALSE },
+        { "this is a value", "VALUE", ConditionResult.FALSE },
+        { "this is a value", " ", ConditionResult.FALSE },
+        { "this is a value", "NOT", ConditionResult.FALSE },
+        { "this is a value", "THIS", ConditionResult.TRUE }, };
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "substringFinalMatchData")
+  public Object[][] createSubstringFinalMatchData()
+  {
+    return new Object[][] {
+        { "this is a value", "value", ConditionResult.TRUE },
+        { "this is a value", "alue", ConditionResult.TRUE },
+        { "this is a value", "ue", ConditionResult.TRUE },
+        { "this is a value", "e", ConditionResult.TRUE },
+        { "this is a value", "valu", ConditionResult.FALSE },
+        { "this is a value", "this", ConditionResult.FALSE },
+        { "this is a value", "VALUE", ConditionResult.TRUE },
+        { "this is a value", "AlUe", ConditionResult.TRUE },
+        { "this is a value", "UE", ConditionResult.TRUE },
+        { "this is a value", "E", ConditionResult.TRUE },
+        { "this is a value", "valu", ConditionResult.FALSE },
+        { "this is a value", "THIS", ConditionResult.FALSE },
+        { "this is a value", " ", ConditionResult.FALSE },
+        { "this is a VALUE", "value", ConditionResult.TRUE },
+        { "end with space    ", " ", ConditionResult.FALSE },
+        { "end with space    ", "space", ConditionResult.TRUE },
+        { "end with space    ", "SPACE", ConditionResult.TRUE }, };
+  }
+
+
+
+  @DataProvider(name = "substringInvalidAttributeValues")
+  public Object[][] createMatchingRuleInvalidAttributeValues()
+  {
+    return new Object[][] {};
+  }
+
+
+
+  @DataProvider(name = "substringInvalidAssertionValues")
+  public Object[][] createMatchingRuleInvalidAssertionValues()
+  {
+    return new Object[][] {};
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CoreSchemaTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CoreSchemaTest.java
new file mode 100644
index 0000000..e581616
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/CoreSchemaTest.java
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Core schema tests
+ */
+public class CoreSchemaTest extends SchemaTestCase
+{
+  @Test
+  public final void testCoreSchemaWarnings()
+  {
+    // Make sure core schema doesn't have any warnings.
+    Assert.assertTrue(CoreSchemaImpl.CORE_SCHEMA_WARNINGS.isEmpty());
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/DITContentRuleSyntaxTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/DITContentRuleSyntaxTest.java
new file mode 100644
index 0000000..b46fb19
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/DITContentRuleSyntaxTest.java
@@ -0,0 +1,94 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.SYNTAX_DIT_CONTENT_RULE_OID;
+
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * DIT content rule syntax tests.
+ */
+public class DITContentRuleSyntaxTest extends SyntaxTestCase
+{
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected Syntax getRule()
+  {
+    return Schema.getCoreSchema()
+        .getSyntax(SYNTAX_DIT_CONTENT_RULE_OID);
+  }
+
+
+
+  @Override
+  @DataProvider(name = "acceptableValues")
+  public Object[][] createAcceptableValues()
+  {
+    return new Object[][] {
+        {
+            "( 2.5.6.4 DESC 'content rule for organization' NOT "
+                + "( x121Address $ telexNumber ) )", true },
+        {
+            "( 2.5.6.4 NAME 'full rule' DESC 'rule with all possible fields' "
+                + " OBSOLETE" + " AUX ( posixAccount )"
+                + " MUST ( cn $ sn )" + " MAY ( dc )"
+                + " NOT ( x121Address $ telexNumber ) )", true },
+        {
+            "( 2.5.6.4 NAME 'full rule' DESC 'ommit parenthesis' "
+                + " OBSOLETE" + " AUX posixAccount " + " MUST cn "
+                + " MAY dc " + " NOT x121Address )", true },
+        {
+            "( 2.5.6.4 NAME 'full rule' DESC 'use numeric OIDs' "
+                + " OBSOLETE" + " AUX 1.3.6.1.1.1.2.0" + " MUST cn "
+                + " MAY dc " + " NOT x121Address )", true },
+        {
+            "( 2.5.6.4 NAME 'full rule' DESC 'illegal OIDs' "
+                + " OBSOLETE" + " AUX 2.5.6.." + " MUST cn "
+                + " MAY dc " + " NOT x121Address )", false },
+        {
+            "( 2.5.6.4 NAME 'full rule' DESC 'illegal OIDs' "
+                + " OBSOLETE" + " AUX 2.5.6.x" + " MUST cn "
+                + " MAY dc " + " NOT x121Address )", false },
+        {
+            "( 2.5.6.4 NAME 'full rule' DESC 'missing closing parenthesis' "
+                + " OBSOLETE" + " AUX posixAccount" + " MUST cn "
+                + " MAY dc " + " NOT x121Address", false },
+        {
+            "( 2.5.6.4 NAME 'full rule' DESC 'extra parameterss' "
+                + " MUST cn "
+                + " X-name ( 'this is an extra parameter' ) )", true },
+
+    };
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/EnumSyntaxTestCase.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/EnumSyntaxTestCase.java
new file mode 100644
index 0000000..0fc52d3
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/EnumSyntaxTestCase.java
@@ -0,0 +1,145 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.OMR_OID_GENERIC_ENUM;
+
+import org.opends.sdk.ConditionResult;
+import org.opends.sdk.DecodeException;
+import org.opends.sdk.util.ByteString;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Enum syntax tests.
+ */
+public class EnumSyntaxTestCase extends SyntaxTestCase
+{
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected Syntax getRule() throws SchemaException, DecodeException
+  {
+    SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
+    builder.addEnumerationSyntax("3.3.3", "Day Of The Week", false, "monday",
+        "tuesday", "wednesday", "thursday", "friday", "saturday",
+        "sunday");
+    return builder.toSchema().getSyntax("3.3.3");
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "acceptableValues")
+  public Object[][] createAcceptableValues()
+  {
+    return new Object[][] { { "arbit-day", false },
+        { "wednesday", true }, };
+  }
+
+
+
+  @Test
+  public void testDuplicateEnum() throws SchemaException,
+      DecodeException
+  {
+    // This should be handled silently.
+    SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
+    builder
+        .addSyntax(
+            "( 3.3.3  DESC 'Day Of The Week' "
+                + " X-ENUM  ( 'monday' 'tuesday'   'wednesday'  'thursday'  'friday' "
+                + " 'saturday' 'monday') )", true);
+    builder.toSchema();
+  }
+
+
+
+  @Test
+  public void testDecode() throws SchemaException, DecodeException
+  {
+    SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
+    builder
+        .addSyntax(
+            "( 3.3.3  DESC 'Day Of The Week' "
+                + " X-ENUM  ( 'monday' 'tuesday'   'wednesday'  'thursday'  'friday' "
+                + " 'saturday' 'sunday') )", true);
+    Schema schema = builder.toSchema();
+    Syntax syntax = schema.getSyntax("3.3.3");
+    MatchingRule rule = syntax.getOrderingMatchingRule();
+    Assert.assertEquals(rule.getGreaterOrEqualAssertion(
+        ByteString.valueOf("monday")).matches(
+        rule.normalizeAttributeValue(ByteString.valueOf("thursday"))),
+        ConditionResult.TRUE);
+    Assert.assertEquals(rule.getLessOrEqualAssertion(
+        ByteString.valueOf("monday")).matches(
+        rule.normalizeAttributeValue(ByteString.valueOf("thursday"))),
+        ConditionResult.FALSE);
+    Assert.assertEquals(rule.getGreaterOrEqualAssertion(
+        ByteString.valueOf("tuesday")).matches(
+        rule.normalizeAttributeValue(ByteString.valueOf("monday"))),
+        ConditionResult.FALSE);
+    Assert.assertEquals(rule.getLessOrEqualAssertion(
+        ByteString.valueOf("tuesday")).matches(
+        rule.normalizeAttributeValue(ByteString.valueOf("monday"))),
+        ConditionResult.TRUE);
+    Assert.assertEquals(rule.getGreaterOrEqualAssertion(
+        ByteString.valueOf("tuesday")).matches(
+        rule.normalizeAttributeValue(ByteString.valueOf("tuesday"))),
+        ConditionResult.TRUE);
+    Assert.assertEquals(rule.getLessOrEqualAssertion(
+        ByteString.valueOf("tuesday")).matches(
+        rule.normalizeAttributeValue(ByteString.valueOf("tuesday"))),
+        ConditionResult.TRUE);
+    Assert
+        .assertEquals(rule.getAssertion(ByteString.valueOf("tuesday"))
+            .matches(
+                rule.normalizeAttributeValue(ByteString
+                    .valueOf("monday"))), ConditionResult.TRUE);
+    Assert.assertEquals(
+        rule.getAssertion(ByteString.valueOf("monday"))
+            .matches(
+                rule.normalizeAttributeValue(ByteString
+                    .valueOf("thursday"))), ConditionResult.FALSE);
+    Assert.assertEquals(
+        rule.getAssertion(ByteString.valueOf("tuesday"))
+            .matches(
+                rule.normalizeAttributeValue(ByteString
+                    .valueOf("tuesday"))), ConditionResult.FALSE);
+    Assert.assertNotNull(schema.getMatchingRule(OMR_OID_GENERIC_ENUM
+        + ".3.3.3"));
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/GeneralizedTimeSyntaxTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/GeneralizedTimeSyntaxTest.java
new file mode 100644
index 0000000..7091724
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/GeneralizedTimeSyntaxTest.java
@@ -0,0 +1,212 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.SYNTAX_GENERALIZED_TIME_OID;
+import static org.opends.server.util.ServerConstants.TIME_ZONE_UTC;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+import org.opends.server.schema.GeneralizedTimeSyntax;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Generalized time syntax tests.
+ */
+public class GeneralizedTimeSyntaxTest extends SyntaxTestCase
+{
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected Syntax getRule()
+  {
+    return Schema.getCoreSchema()
+        .getSyntax(SYNTAX_GENERALIZED_TIME_OID);
+  }
+
+
+
+  @Override
+  @DataProvider(name = "acceptableValues")
+  public Object[][] createAcceptableValues()
+  {
+    return new Object[][] { { "2006090613Z", true },
+        { "20060906135030+01", true }, { "200609061350Z", true },
+        { "20060906135030Z", true }, { "20061116135030Z", true },
+        { "20061126135030Z", true }, { "20061231235959Z", true },
+        { "20060906135030+0101", true },
+        { "20060906135030+2359", true },
+        { "20060906135030+3359", false },
+        { "20060906135030+2389", false },
+        { "20060906135030+2361", false }, { "20060906135030+", false },
+        { "20060906135030+0", false }, { "20060906135030+010", false },
+        { "20061200235959Z", false }, { "2006121a235959Z", false },
+        { "2006122a235959Z", false }, { "20060031235959Z", false },
+        { "20061331235959Z", false }, { "20062231235959Z", false },
+        { "20061232235959Z", false }, { "2006123123595aZ", false },
+        { "200a1231235959Z", false }, { "2006j231235959Z", false },
+        { "200612-1235959Z", false }, { "20061231#35959Z", false },
+        { "2006", false }, };
+  }
+
+
+
+  /**
+   * Create data for format(...) tests.
+   * 
+   * @return Returns test data.
+   */
+  @DataProvider(name = "createFormatData")
+  public Object[][] createFormatData()
+  {
+    return new Object[][] {
+        // Note that Calendar months run from 0-11,
+        // and that there was no such year as year 0 (1 BC -> 1 AD).
+        { 1, 0, 1, 0, 0, 0, 0, "00010101000000.000Z" },
+        { 9, 0, 1, 0, 0, 0, 0, "00090101000000.000Z" },
+        { 10, 0, 1, 0, 0, 0, 0, "00100101000000.000Z" },
+        { 99, 0, 1, 0, 0, 0, 0, "00990101000000.000Z" },
+        { 100, 0, 1, 0, 0, 0, 0, "01000101000000.000Z" },
+        { 999, 0, 1, 0, 0, 0, 0, "09990101000000.000Z" },
+        { 1000, 0, 1, 0, 0, 0, 0, "10000101000000.000Z" },
+        { 2000, 0, 1, 0, 0, 0, 0, "20000101000000.000Z" },
+        { 2099, 0, 1, 0, 0, 0, 0, "20990101000000.000Z" },
+        { 2000, 8, 1, 0, 0, 0, 0, "20000901000000.000Z" },
+        { 2000, 9, 1, 0, 0, 0, 0, "20001001000000.000Z" },
+        { 2000, 10, 1, 0, 0, 0, 0, "20001101000000.000Z" },
+        { 2000, 11, 1, 0, 0, 0, 0, "20001201000000.000Z" },
+        { 2000, 0, 9, 0, 0, 0, 0, "20000109000000.000Z" },
+        { 2000, 0, 10, 0, 0, 0, 0, "20000110000000.000Z" },
+        { 2000, 0, 19, 0, 0, 0, 0, "20000119000000.000Z" },
+        { 2000, 0, 20, 0, 0, 0, 0, "20000120000000.000Z" },
+        { 2000, 0, 29, 0, 0, 0, 0, "20000129000000.000Z" },
+        { 2000, 0, 30, 0, 0, 0, 0, "20000130000000.000Z" },
+        { 2000, 0, 31, 0, 0, 0, 0, "20000131000000.000Z" },
+        { 2000, 0, 1, 9, 0, 0, 0, "20000101090000.000Z" },
+        { 2000, 0, 1, 10, 0, 0, 0, "20000101100000.000Z" },
+        { 2000, 0, 1, 19, 0, 0, 0, "20000101190000.000Z" },
+        { 2000, 0, 1, 20, 0, 0, 0, "20000101200000.000Z" },
+        { 2000, 0, 1, 23, 0, 0, 0, "20000101230000.000Z" },
+        { 2000, 0, 1, 0, 9, 0, 0, "20000101000900.000Z" },
+        { 2000, 0, 1, 0, 10, 0, 0, "20000101001000.000Z" },
+        { 2000, 0, 1, 0, 59, 0, 0, "20000101005900.000Z" },
+        { 2000, 0, 1, 0, 0, 9, 0, "20000101000009.000Z" },
+        { 2000, 0, 1, 0, 0, 10, 0, "20000101000010.000Z" },
+        { 2000, 0, 1, 0, 0, 59, 0, "20000101000059.000Z" },
+        { 2000, 0, 1, 0, 0, 0, 9, "20000101000000.009Z" },
+        { 2000, 0, 1, 0, 0, 0, 10, "20000101000000.010Z" },
+        { 2000, 0, 1, 0, 0, 0, 99, "20000101000000.099Z" },
+        { 2000, 0, 1, 0, 0, 0, 100, "20000101000000.100Z" },
+        { 2000, 0, 1, 0, 0, 0, 999, "20000101000000.999Z" }, };
+  }
+
+
+
+  /**
+   * Tests
+   * {@link org.opends.server.schema.GeneralizedTimeSyntax#format(long)}
+   * .
+   * 
+   * @param yyyy
+   *          The year.
+   * @param MM
+   *          The month.
+   * @param dd
+   *          The day.
+   * @param HH
+   *          The hour.
+   * @param mm
+   *          The minute.
+   * @param ss
+   *          The second.
+   * @param SSS
+   *          The milli-seconds.
+   * @param expected
+   *          The expected generalized time formatted string.
+   * @throws Exception
+   *           If an unexpected error occurred.
+   */
+  @Test(dataProvider = "createFormatData")
+  public void testFormatLong(int yyyy, int MM, int dd, int HH, int mm,
+      int ss, int SSS, String expected) throws Exception
+  {
+    Calendar calendar =
+        new GregorianCalendar(TimeZone.getTimeZone(TIME_ZONE_UTC));
+    calendar.set(yyyy, MM, dd, HH, mm, ss);
+    calendar.set(Calendar.MILLISECOND, SSS);
+    long time = calendar.getTimeInMillis();
+    String actual = GeneralizedTimeSyntax.format(time);
+    Assert.assertEquals(actual, expected);
+  }
+
+
+
+  /**
+   * Tests {@link GeneralizedTimeSyntax#format(java.util.Date)}.
+   * 
+   * @param yyyy
+   *          The year.
+   * @param MM
+   *          The month.
+   * @param dd
+   *          The day.
+   * @param HH
+   *          The hour.
+   * @param mm
+   *          The minute.
+   * @param ss
+   *          The second.
+   * @param SSS
+   *          The milli-seconds.
+   * @param expected
+   *          The expected generalized time formatted string.
+   * @throws Exception
+   *           If an unexpected error occurred.
+   */
+  @Test(dataProvider = "createFormatData")
+  public void testFormatDate(int yyyy, int MM, int dd, int HH, int mm,
+      int ss, int SSS, String expected) throws Exception
+  {
+    Calendar calendar =
+        new GregorianCalendar(TimeZone.getTimeZone(TIME_ZONE_UTC));
+    calendar.set(yyyy, MM, dd, HH, mm, ss);
+    calendar.set(Calendar.MILLISECOND, SSS);
+    Date time = new Date(calendar.getTimeInMillis());
+    String actual = GeneralizedTimeSyntax.format(time);
+    Assert.assertEquals(actual, expected);
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/GuideSyntaxTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/GuideSyntaxTest.java
new file mode 100644
index 0000000..241c9a1
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/GuideSyntaxTest.java
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.SYNTAX_GUIDE_OID;
+
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * Guide syntax tests.
+ */
+public class GuideSyntaxTest extends SyntaxTestCase
+{
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected Syntax getRule()
+  {
+    return Schema.getCoreSchema().getSyntax(SYNTAX_GUIDE_OID);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "acceptableValues")
+  public Object[][] createAcceptableValues()
+  {
+    return new Object[][] { { "sn$EQ|!(sn$EQ)", true },
+        { "!(sn$EQ)", true }, { "person#sn$EQ", true },
+        { "(sn$EQ)", true }, { "sn$EQ", true }, { "sn$SUBSTR", true },
+        { "sn$GE", true }, { "sn$LE", true }, { "sn$ME", false },
+        { "?true", true }, { "?false", true }, { "true|sn$GE", false },
+        { "sn$APPROX", true }, { "sn$EQ|(sn$EQ)", true },
+        { "sn$EQ|(sn$EQ", false }, { "sn$EQ|(sn$EQ)|sn$EQ", true },
+        { "sn$EQ|(cn$APPROX&?false)", true },
+        { "sn$EQ|(cn$APPROX&|?false)", false }, };
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/IA5StringSyntaxTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/IA5StringSyntaxTest.java
new file mode 100644
index 0000000..b4c2656
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/IA5StringSyntaxTest.java
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.SYNTAX_IA5_STRING_OID;
+
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * IA5 string syntax tests.
+ */
+public class IA5StringSyntaxTest extends SyntaxTestCase
+{
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected Syntax getRule()
+  {
+    return Schema.getCoreSchema().getSyntax(SYNTAX_IA5_STRING_OID);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "acceptableValues")
+  public Object[][] createAcceptableValues()
+  {
+    return new Object[][] { { "12345678", true },
+        { "12345678\u2163", false }, };
+  }
+
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/LDAPSyntaxTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/LDAPSyntaxTest.java
new file mode 100644
index 0000000..dd4c068
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/LDAPSyntaxTest.java
@@ -0,0 +1,125 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.SYNTAX_LDAP_SYNTAX_OID;
+
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * LDAP syntax tests.
+ */
+public class LDAPSyntaxTest extends SyntaxTestCase
+{
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected Syntax getRule()
+  {
+    return Schema.getCoreSchema().getSyntax(SYNTAX_LDAP_SYNTAX_OID);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "acceptableValues")
+  public Object[][] createAcceptableValues()
+  {
+    return new Object[][] {
+        {
+            "( 2.5.4.3 DESC 'full syntax description' "
+                + "X-9EN ('this' 'is' 'a' 'test'))", false },
+        {
+            "( 2.5.4.3 DESC 'full syntax description' "
+                + "(X-name 'this", false },
+        {
+            "( 2.5.4.3 DESC 'full syntax description' "
+                + "(X-name 'this'", false },
+        {
+            "( 2.5.4.3 DESC 'full syntax description' "
+                + "Y-name 'this')", false },
+        {
+            "( 2.5.4.3 DESC 'full syntax description' "
+                + "X-name 'this' 'is')", false },
+        { "( 2.5.4.3 DESC 'full syntax description' " + "X-name )",
+            false },
+        {
+            "( 2.5.4.3 DESC 'full syntax description' "
+                + "X- ('this' 'is' 'a' 'test'))", false },
+        {
+            "( 2.5.4.3 DESC 'full syntax description' "
+                + "X-name ('this' 'is' 'a' 'test') X-name-a 'this' X-name-b ('this')",
+            false },
+        {
+            "( 2.5.4.3 DESC 'full syntax description' "
+                + "X-name ('this' 'is' 'a' 'test') X-name-a 'this' X-name-b ('this'",
+            false },
+        {
+            "( 2.5.4.3 DESC 'full syntax description' "
+                + "X-name ('this' 'is' 'a' 'test') X-name-a 'this' X-name-b ('this'))))",
+            false },
+        {
+            "( 2.5.4.3 DESC 'full syntax description' "
+                + "X-name ('this' 'is' 'a' 'test') X-name-a  X-name-b ('this'))))",
+            false },
+        {
+            "( 2.5.4.3 DESC 'full syntax description' "
+                + "X-name ('this' 'is' 'a' 'test') X-name-a  'X-name-b' ('this'))))",
+            false },
+        {
+            "( 2.5.4.3 DESC 'full syntax description' "
+                + "X-name ('this' 'is' 'a' 'test') X-name-a 'this' X-name-b ('this'))",
+            true },
+        {
+            "( 2.5.4.3 DESC 'full syntax description' "
+                + "X-a-_eN_- ('this' 'is' 'a' 'test'))", true },
+        {
+            "( 2.5.4.3 DESC 'full syntax description' "
+                + "X-name ('this'))", true },
+        {
+            "( 2.5.4.3 DESC 'full syntax description' "
+                + "X-name 'this')", true },
+        {
+            "( 2.5.4.3 DESC 'full syntax description' "
+                + "X-name 'this' X-name-a 'test')", true },
+        { "( 2.5.4.3 DESC 'full syntax description' )", true },
+        { "   (    2.5.4.3    DESC  ' syntax description'    )", true },
+        { "( 2.5.4.3 DESC syntax description )", false },
+        { "($%^*&!@ DESC 'syntax description' )", false },
+        { "(temp-oid DESC 'syntax description' )", true },
+        { "2.5.4.3 DESC 'syntax description' )", false },
+        { "(2.5.4.3 DESC 'syntax description' ", false }, };
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/MatchingRuleSyntaxTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/MatchingRuleSyntaxTest.java
new file mode 100644
index 0000000..9e93b59
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/MatchingRuleSyntaxTest.java
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.SYNTAX_MATCHING_RULE_OID;
+
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * Matching rule syntax tests.
+ */
+public class MatchingRuleSyntaxTest extends SyntaxTestCase
+{
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected Syntax getRule()
+  {
+    return Schema.getCoreSchema().getSyntax(SYNTAX_MATCHING_RULE_OID);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "acceptableValues")
+  public Object[][] createAcceptableValues()
+  {
+    return new Object[][] {
+        {
+            "( 1.2.3.4 NAME 'full matching rule' "
+                + " DESC 'description of matching rule' OBSOLETE "
+                + " SYNTAX 1.3.6.1.4.1.1466.115.121.1.17 "
+                + " X-name ( 'this is an extension' ) )", true },
+        {
+            "( 1.2.3.4 NAME 'missing closing parenthesis' "
+                + " DESC 'description of matching rule' "
+                + " SYNTAX 1.3.6.1.4.1.1466.115.121.1.17 "
+                + " X-name ( 'this is an extension' ) ", false }, };
+  }
+
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/MatchingRuleTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/MatchingRuleTest.java
new file mode 100644
index 0000000..221293f
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/MatchingRuleTest.java
@@ -0,0 +1,136 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.testng.Assert.assertEquals;
+
+import org.opends.sdk.Assertion;
+import org.opends.sdk.ConditionResult;
+import org.opends.sdk.DecodeException;
+import org.opends.sdk.util.ByteString;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Test The equality matching rules and the equality matching rule api.
+ */
+public abstract class MatchingRuleTest extends SchemaTestCase
+{
+  /**
+   * Generate data for the Matching Rule test.
+   * 
+   * @return the data for the equality matching rule test.
+   */
+  @DataProvider(name = "matchingrules")
+  public abstract Object[][] createMatchingRuleTest();
+
+
+
+  /**
+   * Generate invalid attribute values for the Matching Rule test.
+   * 
+   * @return the data for the EqualityMatchingRulesInvalidValuestest.
+   */
+  @DataProvider(name = "matchingRuleInvalidAttributeValues")
+  public abstract Object[][] createMatchingRuleInvalidAttributeValues();
+
+
+
+  /**
+   * Generate invalid assertion values for the Matching Rule test.
+   * 
+   * @return the data for the EqualityMatchingRulesInvalidValuestest.
+   */
+  @DataProvider(name = "matchingRuleInvalidAssertionValues")
+  public Object[][] createMatchingRuleInvalidAssertionValues()
+  {
+    return createMatchingRuleInvalidAttributeValues();
+  }
+
+
+
+  /**
+   * Get an instance of the matching rule.
+   * 
+   * @return An instance of the matching rule to test.
+   */
+  protected abstract MatchingRule getRule();
+
+
+
+  /**
+   * Test the normalization and the comparison of valid values.
+   */
+  @Test(dataProvider = "matchingrules")
+  public void matchingRules(String value1, String value2,
+      ConditionResult result) throws Exception
+  {
+    MatchingRule rule = getRule();
+
+    // normalize the 2 provided values and check that they are equals
+    ByteString normalizedValue1 =
+        rule.normalizeAttributeValue(ByteString.valueOf(value1));
+    Assertion assertion = rule.getAssertion(ByteString.valueOf(value2));
+
+    ConditionResult liveResult = assertion.matches(normalizedValue1);
+    assertEquals(result, liveResult);
+  }
+
+
+
+  /**
+   * Test that invalid values are rejected.
+   */
+  @Test(expectedExceptions = DecodeException.class, dataProvider = "matchingRuleInvalidAttributeValues")
+  public void matchingRulesInvalidAttributeValues(String value)
+      throws Exception
+  {
+    // Get the instance of the rule to be tested.
+    MatchingRule rule = getRule();
+
+    rule.normalizeAttributeValue(ByteString.valueOf(value));
+  }
+
+
+
+  /**
+   * Test that invalid values are rejected.
+   */
+  @Test(expectedExceptions = DecodeException.class, dataProvider = "matchingRuleInvalidAssertionValues")
+  public void matchingRulesInvalidAssertionValues(String value)
+      throws Exception
+  {
+    // Get the instance of the rule to be tested.
+    MatchingRule rule = getRule();
+
+    rule.getAssertion(ByteString.valueOf(value));
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/MatchingRuleUseSyntaxTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/MatchingRuleUseSyntaxTest.java
new file mode 100644
index 0000000..60a1568
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/MatchingRuleUseSyntaxTest.java
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.SYNTAX_MATCHING_RULE_USE_OID;
+
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * Matching rule use syntax tests.
+ */
+public class MatchingRuleUseSyntaxTest extends SyntaxTestCase
+{
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected Syntax getRule()
+  {
+    return Schema.getCoreSchema().getSyntax(
+        SYNTAX_MATCHING_RULE_USE_OID);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "acceptableValues")
+  public Object[][] createAcceptableValues()
+  {
+    return new Object[][] {
+        {
+            "( 2.5.13.10 NAME 'full matching rule' "
+                + " DESC 'description of matching rule' OBSOLETE "
+                + " APPLIES 2.5.4.3 "
+                + " X-name 'this is an extension' )", true },
+        {
+            "( 2.5.13.10 NAME 'missing closing parenthesis' "
+                + " DESC 'description of matching rule' "
+                + " SYNTAX 2.5.4.3 "
+                + " X-name ( 'this is an extension' ) ", false }, };
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/OrderingMatchingRuleTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/OrderingMatchingRuleTest.java
new file mode 100644
index 0000000..d0b8880
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/OrderingMatchingRuleTest.java
@@ -0,0 +1,135 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import org.opends.sdk.Assertion;
+import org.opends.sdk.ConditionResult;
+import org.opends.sdk.DecodeException;
+import org.opends.sdk.util.ByteString;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Ordering matching rule tests.
+ */
+public abstract class OrderingMatchingRuleTest extends SchemaTestCase
+{
+  /**
+   * Create data for the OrderingMatchingRules test.
+   * 
+   * @return The data for the OrderingMatchingRules test.
+   */
+  @DataProvider(name = "Orderingmatchingrules")
+  public abstract Object[][] createOrderingMatchingRuleTestData();
+
+
+
+  /**
+   * Test the comparison of valid values.
+   */
+  @Test(dataProvider = "Orderingmatchingrules")
+  public void OrderingMatchingRules(String value1, String value2,
+      int result) throws Exception
+  {
+    // Make sure that the specified class can be instantiated as a task.
+    MatchingRule ruleInstance = getRule();
+
+    ByteString normalizedValue1 =
+        ruleInstance
+            .normalizeAttributeValue(ByteString.valueOf(value1));
+    ByteString normalizedValue2 =
+        ruleInstance
+            .normalizeAttributeValue(ByteString.valueOf(value2));
+
+    // Test the comparator
+    int comp =
+        ruleInstance.comparator().compare(normalizedValue1,
+            normalizedValue2);
+    if (comp == 0)
+      Assert.assertEquals(comp, result);
+    else if (comp > 0)
+      Assert.assertTrue(result > 0);
+    else if (comp < 0)
+      Assert.assertTrue(result < 0);
+
+    Assertion a =
+        ruleInstance.getGreaterOrEqualAssertion(ByteString
+            .valueOf(value2));
+    Assert.assertEquals(a.matches(normalizedValue1),
+        result >= 0 ? ConditionResult.TRUE : ConditionResult.FALSE);
+
+    a =
+        ruleInstance
+            .getLessOrEqualAssertion(ByteString.valueOf(value2));
+    Assert.assertEquals(a.matches(normalizedValue1),
+        result <= 0 ? ConditionResult.TRUE : ConditionResult.FALSE);
+
+    a = ruleInstance.getAssertion(ByteString.valueOf(value2));
+    Assert.assertEquals(a.matches(normalizedValue1),
+        result < 0 ? ConditionResult.TRUE : ConditionResult.FALSE);
+  }
+
+
+
+  /**
+   * Get the Ordering matching Rules that is to be tested.
+   * 
+   * @return The Ordering matching Rules that is to be tested.
+   */
+  protected abstract MatchingRule getRule();
+
+
+
+  /**
+   * Create data for the OrderingMatchingRulesInvalidValues test.
+   * 
+   * @return The data for the OrderingMatchingRulesInvalidValues test.
+   */
+  @DataProvider(name = "OrderingMatchingRuleInvalidValues")
+  public abstract Object[][] createOrderingMatchingRuleInvalidValues();
+
+
+
+  /**
+   * Test that invalid values are rejected.
+   */
+  @Test(expectedExceptions = DecodeException.class, dataProvider = "OrderingMatchingRuleInvalidValues")
+  public void OrderingMatchingRulesInvalidValues(String value)
+      throws Exception
+  {
+    // Make sure that the specified class can be instantiated as a task.
+    MatchingRule ruleInstance = getRule();
+
+    // normalize the 2 provided values
+    ruleInstance.normalizeAttributeValue(ByteString.valueOf(value));
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/OtherMailboxSyntaxTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/OtherMailboxSyntaxTest.java
new file mode 100644
index 0000000..70a0641
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/OtherMailboxSyntaxTest.java
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.SYNTAX_OTHER_MAILBOX_OID;
+
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * Other mailbox syntax tests.
+ */
+public class OtherMailboxSyntaxTest extends SyntaxTestCase
+{
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected Syntax getRule()
+  {
+    return Schema.getCoreSchema().getSyntax(SYNTAX_OTHER_MAILBOX_OID);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "acceptableValues")
+  public Object[][] createAcceptableValues()
+  {
+    return new Object[][] { { "MyMail$Mymailbox", true },
+        { "MyMailMymailbox", false }, };
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/RegexSyntaxTestCase.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/RegexSyntaxTestCase.java
new file mode 100644
index 0000000..d9b1330
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/RegexSyntaxTestCase.java
@@ -0,0 +1,102 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.opends.messages.Message;
+import org.opends.sdk.DecodeException;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Regex syntax tests.
+ */
+public class RegexSyntaxTestCase extends SyntaxTestCase
+{
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected Syntax getRule() throws SchemaException, DecodeException
+  {
+    SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
+    builder.addPatternSyntax("1.1.1",
+        "Host and Port in the format of HOST:PORT", Pattern
+            .compile("^[a-z-A-Z]+:[0-9.]+\\d$"), false);
+    return builder.toSchema().getSyntax("1.1.1");
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "acceptableValues")
+  public Object[][] createAcceptableValues()
+  {
+    return new Object[][] { { "invalid regex", false },
+        { "host:0.0.0", true }, };
+  }
+
+
+
+  public void testInvalidPattern() throws SchemaException,
+      DecodeException
+  {
+    // This should fail due to invalid pattern.
+    SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
+    builder.addSyntax(
+        "( 1.1.1 DESC 'Host and Port in the format of HOST:PORT' "
+            + " X-PATTERN '^[a-z-A-Z+:[0-@.]+\\d$' )", true);
+    List<Message> warnings = new LinkedList<Message>();
+    builder.toSchema(warnings);
+    Assert.assertFalse(warnings.isEmpty());
+  }
+
+
+
+  @Test
+  public void testDecode() throws SchemaException, DecodeException
+  {
+    // This should fail due to invalid pattern.
+    SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
+    builder.addSyntax(
+        "( 1.1.1 DESC 'Host and Port in the format of HOST:PORT' "
+            + " X-PATTERN '^[a-z-A-Z]+:[0-9.]+\\d$' )", true);
+    builder.toSchema();
+  }
+
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/SchemaTestCase.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/SchemaTestCase.java
new file mode 100644
index 0000000..e1346bd
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/SchemaTestCase.java
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import org.opends.sdk.OpenDSTestCase;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * An abstract class that all schema unit test should extend.
+ */
+@Test(groups = { "precommit", "schema", "sdk" }, sequential = true)
+public abstract class SchemaTestCase extends OpenDSTestCase
+{
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/SubstitutionSyntaxTestCase.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/SubstitutionSyntaxTestCase.java
new file mode 100644
index 0000000..2af3329
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/SubstitutionSyntaxTestCase.java
@@ -0,0 +1,149 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.SYNTAX_IA5_STRING_OID;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.opends.messages.Message;
+import org.opends.sdk.DecodeException;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Substitution syntax tests.
+ */
+public class SubstitutionSyntaxTestCase extends SyntaxTestCase
+{
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected Syntax getRule() throws SchemaException, DecodeException
+  {
+    // Use IA5String syntax as our substitute.
+    SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
+    builder.addSubstitutionSyntax("9.9.9", "Unimplemented Syntax",
+        SYNTAX_IA5_STRING_OID, false);
+    return builder.toSchema().getSyntax("9.9.9");
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "acceptableValues")
+  public Object[][] createAcceptableValues()
+  {
+    return new Object[][] { { "12345678", true },
+        { "12345678\u2163", false }, };
+  }
+
+
+
+  public void testSelfSubstitute1() throws SchemaException,
+      DecodeException
+  {
+    SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
+    builder.addSyntax("( 1.3.6.1.4.1.1466.115.121.1.15 "
+        + " DESC 'Replacing DirectorySyntax'  "
+        + " X-SUBST '1.3.6.1.4.1.1466.115.121.1.15' )", true);
+    List<Message> warnings = new LinkedList<Message>();
+    builder.toSchema(warnings);
+    Assert.assertFalse(warnings.isEmpty());
+  }
+
+
+
+  public void testSelfSubstitute2() throws SchemaException
+  {
+    SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
+    builder.addSubstitutionSyntax("1.3.6.1.4.1.1466.115.121.1.15",
+        "Replacing DirectorySyntax", "1.3.6.1.4.1.1466.115.121.1.15",
+        true);
+    List<Message> warnings = new LinkedList<Message>();
+    builder.toSchema(warnings);
+    Assert.assertFalse(warnings.isEmpty());
+  }
+
+
+
+  public void testUndefinedSubstitute1() throws SchemaException,
+      DecodeException
+  {
+    SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
+    builder.addSyntax("( 1.3.6.1.4.1.1466.115.121.1.15 "
+        + " DESC 'Replacing DirectorySyntax'  " + " X-SUBST '1.1.1' )",
+        true);
+    List<Message> warnings = new LinkedList<Message>();
+    builder.toSchema(warnings);
+    Assert.assertFalse(warnings.isEmpty());
+  }
+
+
+
+  public void testUndefinedSubstitute2() throws SchemaException
+  {
+    SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
+    builder.addSubstitutionSyntax("1.3.6.1.4.1.1466.115.121.1.15",
+        "Replacing DirectorySyntax", "1.1.1", true);
+    List<Message> warnings = new LinkedList<Message>();
+    builder.toSchema(warnings);
+    Assert.assertFalse(warnings.isEmpty());
+  }
+
+
+
+  @Test(expectedExceptions = SchemaException.class)
+  public void testSubstituteCore1() throws SchemaException,
+      DecodeException
+  {
+    SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
+    builder.addSyntax("( 1.3.6.1.4.1.1466.115.121.1.26 "
+        + " DESC 'Replacing DirectorySyntax'  " + " X-SUBST '9.9.9' )",
+        true);
+  }
+
+
+
+  @Test(expectedExceptions = SchemaException.class)
+  public void testSubstituteCore2() throws SchemaException
+  {
+    SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
+    builder.addSubstitutionSyntax("1.3.6.1.4.1.1466.115.121.1.26",
+        "Replacing DirectorySyntax", "9.9.9", true);
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/SubstringMatchingRuleTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/SubstringMatchingRuleTest.java
new file mode 100644
index 0000000..163e4c7
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/SubstringMatchingRuleTest.java
@@ -0,0 +1,266 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.testng.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opends.sdk.ConditionResult;
+import org.opends.sdk.DecodeException;
+import org.opends.sdk.util.ByteSequence;
+import org.opends.sdk.util.ByteString;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Abstract class for building test for the substring matching rules.
+ * This class is intended to be extended by one class for each substring
+ * matching rules.
+ */
+public abstract class SubstringMatchingRuleTest extends SchemaTestCase
+{
+  /**
+   * Generate data for the test of the middle string match.
+   * 
+   * @return the data for the test of the middle string match.
+   */
+  @DataProvider(name = "substringMiddleMatchData")
+  public abstract Object[][] createSubstringMiddleMatchData();
+
+
+
+  /**
+   * Generate data for the test of the initial string match.
+   * 
+   * @return the data for the test of the initial string match.
+   */
+  @DataProvider(name = "substringInitialMatchData")
+  public abstract Object[][] createSubstringInitialMatchData();
+
+
+
+  /**
+   * Generate data for the test of the final string match.
+   * 
+   * @return the data for the test of the final string match.
+   */
+  @DataProvider(name = "substringInitialMatchData")
+  public abstract Object[][] createSubstringFinalMatchData();
+
+
+
+  /**
+   * Generate invalid attribute values for the Matching Rule test.
+   * 
+   * @return the data for the EqualityMatchingRulesInvalidValuestest.
+   */
+  @DataProvider(name = "substringInvalidAttributeValues")
+  public abstract Object[][] createMatchingRuleInvalidAttributeValues();
+
+
+
+  /**
+   * Generate invalid assertion values for the Matching Rule test.
+   * 
+   * @return the data for the EqualityMatchingRulesInvalidValuestest.
+   */
+  @DataProvider(name = "substringInvalidAssertionValues")
+  public abstract Object[][] createMatchingRuleInvalidAssertionValues();
+
+
+
+  /**
+   * Get an instance of the matching rule.
+   * 
+   * @return An instance of the matching rule to test.
+   */
+  protected abstract MatchingRule getRule();
+
+
+
+  /**
+   * Test the normalization and the middle substring match.
+   */
+  @Test(dataProvider = "substringMiddleMatchData")
+  public void middleMatchingRules(String value, String[] middleSubs,
+      ConditionResult result) throws Exception
+  {
+    MatchingRule rule = getRule();
+
+    // normalize the 2 provided values and check that they are equals
+    ByteString normalizedValue =
+        rule.normalizeAttributeValue(ByteString.valueOf(value));
+
+    StringBuilder printableMiddleSubs = new StringBuilder();
+    List<ByteSequence> middleList =
+        new ArrayList<ByteSequence>(middleSubs.length);
+    printableMiddleSubs.append("*");
+    for (String middleSub : middleSubs)
+    {
+      printableMiddleSubs.append(middleSub);
+      printableMiddleSubs.append("*");
+      middleList.add(ByteString.valueOf(middleSub));
+    }
+
+    if (rule.getAssertion(null, middleList, null).matches(
+        normalizedValue) != result
+        || rule.getAssertion(ByteString.valueOf(printableMiddleSubs))
+            .matches(normalizedValue) != result)
+    {
+      fail("middle substring matching rule " + rule
+          + " does not give expected result (" + result
+          + ") for values : " + value + " and " + printableMiddleSubs);
+    }
+  }
+
+
+
+  /**
+   * Test the normalization and the initial substring match.
+   */
+  @Test(dataProvider = "substringInitialMatchData")
+  public void initialMatchingRules(String value, String initial,
+      ConditionResult result) throws Exception
+  {
+    MatchingRule rule = getRule();
+
+    // normalize the 2 provided values and check that they are equals
+    ByteString normalizedValue =
+        rule.normalizeAttributeValue(ByteString.valueOf(value));
+
+    if (rule.getAssertion(ByteString.valueOf(initial), null, null)
+        .matches(normalizedValue) != result
+        || rule.getAssertion(ByteString.valueOf(initial + "*"))
+            .matches(normalizedValue) != result)
+    {
+      fail("initial substring matching rule " + rule
+          + " does not give expected result (" + result
+          + ") for values : " + value + " and " + initial);
+    }
+  }
+
+
+
+  /**
+   * Test the normalization and the final substring match.
+   */
+  @Test(dataProvider = "substringFinalMatchData")
+  public void finalMatchingRules(String value, String finalValue,
+      ConditionResult result) throws Exception
+  {
+    MatchingRule rule = getRule();
+
+    // normalize the 2 provided values and check that they are equals
+    ByteString normalizedValue =
+        rule.normalizeAttributeValue(ByteString.valueOf(value));
+
+    if (rule.getAssertion(null, null, ByteString.valueOf(finalValue))
+        .matches(normalizedValue) != result
+        || rule.getAssertion(ByteString.valueOf("*" + finalValue))
+            .matches(normalizedValue) != result)
+    {
+      fail("final substring matching rule " + rule
+          + " does not give expected result (" + result
+          + ") for values : " + value + " and " + finalValue);
+    }
+  }
+
+
+
+  /**
+   * Test that invalid values are rejected.
+   */
+  @Test(expectedExceptions = DecodeException.class, dataProvider = "substringInvalidAttributeValues")
+  public void substringInvalidAttributeValues(String value)
+      throws Exception
+  {
+    // Get the instance of the rule to be tested.
+    MatchingRule rule = getRule();
+
+    rule.normalizeAttributeValue(ByteString.valueOf(value));
+  }
+
+
+
+  /**
+   * Test that invalid values are rejected.
+   */
+  @Test(expectedExceptions = DecodeException.class, dataProvider = "substringInvalidAssertionValues")
+  public void matchingRulesInvalidAssertionValues(String subInitial,
+      String[] anys, String subFinal) throws Exception
+  {
+    // Get the instance of the rule to be tested.
+    MatchingRule rule = getRule();
+
+    List<ByteSequence> anyList =
+        new ArrayList<ByteSequence>(anys.length);
+    for (String middleSub : anys)
+    {
+      anyList.add(ByteString.valueOf(middleSub));
+    }
+    rule.getAssertion(subInitial == null ? null : ByteString
+        .valueOf(subInitial), anyList, subFinal == null ? null
+        : ByteString.valueOf(subFinal));
+  }
+
+
+
+  /**
+   * Test that invalid values are rejected.
+   */
+  @Test(expectedExceptions = DecodeException.class, dataProvider = "substringInvalidAssertionValues")
+  public void matchingRulesInvalidAssertionValuesString(
+      String subInitial, String[] anys, String subFinal)
+      throws Exception
+  {
+    // Get the instance of the rule to be tested.
+    MatchingRule rule = getRule();
+
+    StringBuilder assertionString = new StringBuilder();
+    if (subInitial != null)
+    {
+      assertionString.append(subInitial);
+    }
+    assertionString.append("*");
+    for (String middleSub : anys)
+    {
+      assertionString.append(middleSub);
+      assertionString.append("*");
+    }
+    if (subFinal != null)
+    {
+      assertionString.append(subFinal);
+    }
+    rule.getAssertion(ByteString.valueOf(assertionString.toString()));
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/SyntaxTestCase.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/SyntaxTestCase.java
new file mode 100644
index 0000000..09b8757
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/SyntaxTestCase.java
@@ -0,0 +1,98 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.testng.Assert.fail;
+
+import org.opends.messages.MessageBuilder;
+import org.opends.sdk.DecodeException;
+import org.opends.sdk.util.ByteString;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Syntax tests.
+ */
+public abstract class SyntaxTestCase extends SchemaTestCase
+{
+  /**
+   * Create data for the testAcceptableValues test. This should be a
+   * table of tables with 2 elements. The first one should be the value
+   * to test, the second the expected result of the test.
+   * 
+   * @return a table containing data for the testAcceptableValues Test.
+   */
+  @DataProvider(name = "acceptableValues")
+  public abstract Object[][] createAcceptableValues();
+
+
+
+  /**
+   * Get an instance of the attribute syntax that muste be tested.
+   * 
+   * @return An instance of the attribute syntax that muste be tested.
+   */
+  protected abstract Syntax getRule() throws SchemaException,
+      DecodeException;
+
+
+
+  /**
+   * Test the normalization and the approximate comparison.
+   */
+  @Test(dataProvider = "acceptableValues")
+  public void testAcceptableValues(String value, Boolean result)
+      throws Exception
+  {
+    // Make sure that the specified class can be instantiated as a task.
+    Syntax syntax = getRule();
+
+    MessageBuilder reason = new MessageBuilder();
+    // test the valueIsAcceptable method
+    Boolean liveResult =
+        syntax.valueIsAcceptable(ByteString.valueOf(value), reason);
+
+    if (liveResult != result)
+      fail(syntax + ".valueIsAcceptable gave bad result for " + value
+          + "reason : " + reason);
+
+    // call the getters
+    syntax.getApproximateMatchingRule();
+    syntax.getDescription();
+    syntax.getEqualityMatchingRule();
+    syntax.getOID();
+    syntax.getOrderingMatchingRule();
+    syntax.getSubstringMatchingRule();
+    syntax.hashCode();
+    syntax.isHumanReadable();
+    syntax.toString();
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/TelexSyntaxTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/TelexSyntaxTest.java
new file mode 100644
index 0000000..f1122b1
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/TelexSyntaxTest.java
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.SYNTAX_TELEX_OID;
+
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * Telex syntax tests.
+ */
+public class TelexSyntaxTest extends SyntaxTestCase
+{
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected Syntax getRule()
+  {
+    return Schema.getCoreSchema().getSyntax(SYNTAX_TELEX_OID);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "acceptableValues")
+  public Object[][] createAcceptableValues()
+  {
+    return new Object[][] { { "123$france$456", true },
+        { "abcdefghijk$lmnopqr$stuvwxyz", true },
+        { "12345$67890$()+,-./:? ", true }, };
+  }
+
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/UTCTimeSyntaxTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/UTCTimeSyntaxTest.java
new file mode 100644
index 0000000..0357844
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/UTCTimeSyntaxTest.java
@@ -0,0 +1,112 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.SYNTAX_UTC_TIME_OID;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Date;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * UTC time syntax tests.
+ */
+public class UTCTimeSyntaxTest extends SyntaxTestCase
+{
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected Syntax getRule()
+  {
+    return Schema.getCoreSchema().getSyntax(SYNTAX_UTC_TIME_OID);
+  }
+
+
+
+  @Override
+  @DataProvider(name = "acceptableValues")
+  public Object[][] createAcceptableValues()
+  {
+    return new Object[][] {
+        // tests for the UTC time syntax.
+        { "060906135030+01", true }, { "0609061350Z", true },
+        { "060906135030Z", true }, { "061116135030Z", true },
+        { "061126135030Z", true }, { "061231235959Z", true },
+        { "060906135030+0101", true }, { "060906135030+2359", true },
+        { "060906135060+0101", true }, { "060906135061+0101", false },
+        { "060906135030+3359", false }, { "060906135030+2389", false },
+        { "062231235959Z", false }, { "061232235959Z", false },
+        { "06123123595aZ", false }, { "0a1231235959Z", false },
+        { "06j231235959Z", false }, { "0612-1235959Z", false },
+        { "061231#35959Z", false }, { "2006", false },
+        { "062106135030+0101", false }, { "060A06135030+0101", false },
+        { "061A06135030+0101", false }, { "060936135030+0101", false },
+        { "06090A135030+0101", false }, { "06091A135030+0101", false },
+        { "060900135030+0101", false }, { "060906335030+0101", false },
+        { "0609061A5030+0101", false }, { "0609062A5030+0101", false },
+        { "060906137030+0101", false }, { "060906135A30+0101", false },
+        { "060906135", false }, { "0609061350", false },
+        { "060906135070+0101", false }, { "06090613503A+0101", false },
+        { "06090613503", false }, { "0609061350Z0", false },
+        { "0609061350+0", false }, { "0609061350+000A", false },
+        { "0609061350+A00A", false }, { "060906135030Z0", false },
+        { "060906135030+010", false }, { "060906135030+010A", false },
+        { "060906135030+0A01", false }, { "060906135030+2501", false },
+        { "060906135030+0170", false }, { "060906135030+010A", false },
+        { "060906135030+A00A", false }, { "060906135030Q", false },
+        { "060906135030+", false }, };
+  }
+
+
+
+  /**
+   * Tests the {@code createUTCTimeValue} and {@code decodeUTCTimeValue}
+   * methods.
+   * 
+   * @throws Exception
+   *           If an unexpected problem occurs.
+   */
+  @Test()
+  public void testCreateAndDecodeUTCTimeValue() throws Exception
+  {
+    Date d = new Date();
+    String timeValue = UTCTimeSyntaxImpl.createUTCTimeValue(d);
+    Date decodedDate = UTCTimeSyntaxImpl.decodeUTCTimeValue(timeValue);
+
+    // UTCTime does not have support for sub-second values, so we need
+    // to make
+    // sure that the decoded value is within 1000 milliseconds.
+    assertTrue(Math.abs(d.getTime() - decodedDate.getTime()) < 1000);
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/UUIDSyntaxTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/UUIDSyntaxTest.java
new file mode 100644
index 0000000..5335a90
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/schema/UUIDSyntaxTest.java
@@ -0,0 +1,74 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.sdk.schema;
+
+
+
+import static org.opends.server.schema.SchemaConstants.SYNTAX_UUID_OID;
+
+import org.testng.annotations.DataProvider;
+
+
+
+/**
+ * UUID syntax tests.
+ */
+public class UUIDSyntaxTest extends SyntaxTestCase
+{
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected Syntax getRule()
+  {
+    return Schema.getCoreSchema().getSyntax(SYNTAX_UUID_OID);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @DataProvider(name = "acceptableValues")
+  public Object[][] createAcceptableValues()
+  {
+    return new Object[][] {
+        { "12345678-9ABC-DEF0-1234-1234567890ab", true },
+        { "12345678-9abc-def0-1234-1234567890ab", true },
+        { "12345678-9abc-def0-1234-1234567890ab", true },
+        { "12345678-9abc-def0-1234-1234567890ab", true },
+        { "02345678-9abc-def0-1234-1234567890ab", true },
+        { "12345678-9abc-def0-1234-1234567890ab", true },
+        { "12345678-9abc-def0-1234-1234567890ab", true },
+        { "02345678-9abc-def0-1234-1234567890ab", true },
+        { "G2345678-9abc-def0-1234-1234567890ab", false },
+        { "g2345678-9abc-def0-1234-1234567890ab", false },
+        { "12345678/9abc/def0/1234/1234567890ab", false },
+        { "12345678-9abc-def0-1234-1234567890a", false }, };
+  }
+}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/util/StaticUtilsTest.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/util/StaticUtilsTest.java
new file mode 100644
index 0000000..4e53528
--- /dev/null
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/util/StaticUtilsTest.java
@@ -0,0 +1,100 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.sdk.util;
+
+
+
+import org.opends.sdk.OpenDSTestCase;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Test {@code StaticUtils}.
+ */
+@Test(groups = { "precommit", "types", "sdk" }, sequential = true)
+public final class StaticUtilsTest extends OpenDSTestCase
+{
+  @DataProvider(name = "dataForToLowerCase")
+  public Object[][] dataForToLowerCase()
+  {
+    // Value, toLowerCase or null if identity
+    return new Object[][] {
+        { "", null },
+        { " ", null },
+        { "   ", null },
+        { "12345", null },
+        {
+            "abcdefghijklmnopqrstuvwxyz1234567890`~!@#$%^&*()_-+={}|[]\\:\";'<>?,./",
+            null },
+        {
+            "Aabcdefghijklmnopqrstuvwxyz1234567890`~!@#$%^&*()_-+={}|[]\\:\";'<>?,./",
+            "aabcdefghijklmnopqrstuvwxyz1234567890`~!@#$%^&*()_-+={}|[]\\:\";'<>?,./" },
+        {
+            "abcdefghijklmnopqrstuvwxyz1234567890`~!@#$%^&*()_-+={}|[]\\:\";'<>?,./A",
+            "abcdefghijklmnopqrstuvwxyz1234567890`~!@#$%^&*()_-+={}|[]\\:\";'<>?,./a" },
+        { "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz" },
+        { "\u00c7edilla", "\u00e7edilla" },
+        { "ced\u00cdlla", "ced\u00edlla" }, };
+  }
+
+
+
+  @Test(dataProvider = "dataForToLowerCase")
+  public void testToLowerCaseString(String s, String expected)
+  {
+    String actual = StaticUtils.toLowerCase(s);
+    if (expected == null)
+    {
+      Assert.assertSame(actual, s);
+    }
+    else
+    {
+      Assert.assertEquals(actual, expected);
+    }
+  }
+
+
+
+  @Test(dataProvider = "dataForToLowerCase")
+  public void testToLowerCaseStringBuilder(String s, String expected)
+  {
+    StringBuilder builder = new StringBuilder();
+    String actual = StaticUtils.toLowerCase(s, builder).toString();
+    if (expected == null)
+    {
+      Assert.assertEquals(actual, s);
+    }
+    else
+    {
+      Assert.assertEquals(actual, expected);
+    }
+  }
+}

--
Gitblit v1.10.0