public void ValidateContentRulesRequirements(DirectoryEntries childrens, IEnumerable <IObjectOnServer> serverObjects)
        {
            bool isContent = true;

            //Setting some excluded attributes.
            SetContainer <string> ExcludedAttributes = new SetContainer <string>();

            ExcludedAttributes.Add("creationTime");
            ExcludedAttributes.Add("forceLogoff");
            ExcludedAttributes.Add("lockoutDuration");
            ExcludedAttributes.Add("lockOutObservationWindow");
            ExcludedAttributes.Add("lockoutThreshold");
            ExcludedAttributes.Add("maxPwdAge");
            ExcludedAttributes.Add("minPwdAge");
            ExcludedAttributes.Add("minPwdLength");
            ExcludedAttributes.Add("modifiedCountAtLastProm");
            ExcludedAttributes.Add("nextRid");
            ExcludedAttributes.Add("pwdProperties");
            ExcludedAttributes.Add("pwdHistoryLength");
            ExcludedAttributes.Add("objectSid");
            ExcludedAttributes.Add("serverState");
            ExcludedAttributes.Add("uASCompat");
            ExcludedAttributes.Add("modifiedCount");


            //For each domain NC object...
            foreach (DirectoryEntry entry in childrens)
            {
                SetContainer <string> mustContain = new SetContainer <string>();
                SetContainer <string> mayContain  = new SetContainer <string>();

                //Get super class chain.
                object[] superClasses = (object[])entry.Properties[StandardNames.objectClass.ToLower()].Value;

                //For each super class...
                foreach (string superClass in superClasses)
                {
                    foreach (IObjectOnServer serverObj in serverObjects)
                    {
                        //Get the object from server.
                        if (serverObj.Name.StartsWith(superClass))
                        {
                            //Collect all must and may contain attribute value.
                            if (serverObj.Properties.ContainsKey(StandardNames.mustContain.ToLower()))
                            {
                                foreach (object value in serverObj.Properties[StandardNames.mustContain.ToLower()])
                                {
                                    mustContain.Add((string)value);
                                }
                            }
                            if (serverObj.Properties.ContainsKey(StandardNames.systemMustContain.ToLower()))
                            {
                                foreach (object value in serverObj.Properties[StandardNames.systemMustContain.ToLower()])
                                {
                                    mustContain.Add((string)value);
                                }
                            }

                            if (serverObj.Properties.ContainsKey(StandardNames.mayContain.ToLower()))
                            {
                                foreach (object value in serverObj.Properties[StandardNames.mayContain.ToLower()])
                                {
                                    mayContain.Add((string)value);
                                }
                            }
                            if (serverObj.Properties.ContainsKey(StandardNames.systemMayContain.ToLower()))
                            {
                                foreach (object value in serverObj.Properties[StandardNames.systemMayContain.ToLower()])
                                {
                                    mayContain.Add((string)value);
                                }
                            }
                            break;
                        }
                    }
                }

                //For all property name of this object, it should be present in either must or may contain
                //attribute list.
                foreach (string attribute in entry.Properties.PropertyNames)
                {
                    if (!ExcludedAttributes.Contains(attribute))
                    {
                        //This attribute is in must contain list.
                        if (mustContain.Contains(attribute))
                        {
                            mustContain.Remove(attribute);
                        }
                        //This attribute is not in must and may contian list.
                        else if (!mayContain.Contains(attribute))
                        {
                            isContent = false;
                            break;
                        }
                    }
                }

                //This is for checking whether some must contain attributes are missed.
                if (mustContain.Count > 0)
                {
                    isContent = false;
                }

                if (!isContent)
                {
                    break;
                }
            }
            //MS-ADTS-Schema_R152.
            DataSchemaSite.CaptureRequirementIfIsTrue(
                isContent,
                152,
                @"In the content rules union of values in the mustContain and systemMustContain attributes specifies the 
                attributes that are required to be present on an object instance of the class in question.");

            //MS-ADTS-Schema_R153.
            DataSchemaSite.CaptureRequirementIfIsTrue(
                isContent,
                153,
                @"In the content rules  the union of values in the mustContain, systemMustContain, mayContain, and 
                systemMayContain attributes specifies the attributes that are allowed to be present on an object 
                instance of the class in question.");
        }
        /// <summary>
        /// This method validates the requirements under
        /// LDSConsistencyRules Scenario.
        /// </summary>
        public void ValidateLDSConsistencyRules()
        {
            #region MS-ADTS-Schema_R73

            //The objectClass attribute of the attributeSchema equals the sequence [top, attributeSchema ]
            //Expected Sequence setting...
            Sequence <object> actualSeq        = new Sequence <object>();
            Sequence <object> expectedSeq      = new Sequence <object>();
            ModelObject       objectFromModel  = null;
            string            requiredObjectDN = String.Empty;
            DirectoryEntry    serverObject;
            expectedSeq = expectedSeq.Add("top".ToLower()).Add("classSchema".ToLower());

            //Get attributeSchema from Server.
            requiredObjectDN = "CN=Attribute-Schema,CN=Schema,CN=Configuration," + adAdapter.LDSRootObjectName;
            if (!adAdapter.GetLdsObjectByDN(requiredObjectDN, out serverObject))
            {
                DataSchemaSite.Assume.IsTrue(false, requiredObjectDN + " Object is not found in server");
            }
            actualSeq = new Sequence <object>();
            foreach (string valueString in serverObject.Properties[StandardNames.objectClass.ToLower()])
            {
                actualSeq = actualSeq.Add(valueString.ToLower());
            }
            //MS-ADTS-Schema_R73.
            DataSchemaSite.CaptureRequirementIfAreEqual <Sequence <object> >(
                expectedSeq,
                actualSeq,
                73,
                "The objectClass attribute of the attributeSchema equals the sequence [top, classSchema ].");

            #endregion

            #region MS-ADTS-Schema_R157
            //The objectClass attribute of the classSchema equals the sequence [top, classSchema ].
            //Expected Sequence setting...
            expectedSeq = new Sequence <object>();
            expectedSeq = expectedSeq.Add("top".ToLower()).Add("classSchema".ToLower());

            //Get classSchema from Server.
            requiredObjectDN = "CN=Class-Schema,CN=Schema,CN=Configuration," + adAdapter.LDSRootObjectName;
            if (!adAdapter.GetLdsObjectByDN(requiredObjectDN, out serverObject))
            {
                DataSchemaSite.Assume.IsTrue(false, requiredObjectDN + " Object is not found in server");
            }
            actualSeq = new Sequence <object>();
            foreach (string valueString in serverObject.Properties[StandardNames.objectClass.ToLower()])
            {
                actualSeq = actualSeq.Add(valueString.ToLower());
            }

            //MS-ADTS-Schema_R157.
            DataSchemaSite.CaptureRequirementIfAreEqual <Sequence <object> >(
                expectedSeq,
                actualSeq,
                157,
                "The objectClass attribute of the classSchema equals the sequence [top, classSchema ].");

            #endregion

            #region MS-ADTS-Schema_R169

            //The subClassOf attribute of the classSchema Specifies governsID of the superclass of the class.
            //Get classSchema from Model.
            objectFromModel = adamModel.GetClass("classSchema");
            if (objectFromModel == null)
            {
                DataSchemaSite.Assume.IsNotNull(objectFromModel, "Class classSchema is not existing in Model");
            }
            string expectedValue = (string)objectFromModel[StandardNames.subClassOf].UnderlyingValues.ToArray()[0];

            #endregion

            #region MS-ADTS-Schema_R129-142,179

            //Inheritance requirements
            IEnumerable <IObjectOnServer> serverObjects = (IEnumerable <IObjectOnServer>)adAdapter.GetAllLdsSchemaClasses();
            if (serverObjects == null)
            {
                DataSchemaSite.Assume.IsNotNull(serverObjects, "Class objects are not existing in Model");
            }

            //This method will validate the requirements MS-ADTS-Schema_R129-142,179
            ValidateInheritanceRequirements(serverObjects, false);

            serverObjects = null;

            #endregion

            #region MS-ADTS-Schema_R143-146

            //Covering ObjectClass requirements
            //Get domain NC for validation.
            DirectoryEntry domainEntry;
            if (!adAdapter.GetLdsObjectByDN("CN=Configuration," + adAdapter.LDSRootObjectName, out domainEntry))
            {
                DataSchemaSite.Assume.IsTrue(
                    false,
                    "CN=Configuration,"
                    + adAdapter.LDSRootObjectName
                    + " Object is not found in server");
            }

            //This method validates teh requirements MS-ADTS-Schema_R143-146
            ValidateObjectClassRequirements(domainEntry.Children, false);
            domainEntry = null;

            #endregion

            #region MS-ADTS-Schema_R149,175

            //Coverring StructureRule requirements
            serverObjects = adAdapter.GetAllLdsSchemaClasses();
            if (serverObjects == null)
            {
                DataSchemaSite.Assume.IsNotNull(serverObjects, "Class objects are not existing in Model");
            }

            //This method validates the requirements MS-ADTS-Schema_R149,175
            ValidateStructureRulesRequirements(serverObjects, false);

            #endregion

            #region MS-ADTS-Schema_R152,153
            //Covering ContentRule requirements

            //Get the domain NC objects.
            if (!adAdapter.GetLdsObjectByDN("CN=Configuration," + adAdapter.LDSRootObjectName, out domainEntry))
            {
                DataSchemaSite.Assert.IsTrue(false, "Configuration Object is not found in server");
            }

            //This method validates the requirements MS-ADTS-Schema_R152,153.
            ValidateContentRulesRequirements(domainEntry.Children, serverObjects);

            #endregion

            #region MS-ADTS-Schema_R177
            //The systemAuxiliaryClass attribute of the classSchema Specifies governsIDs of the classes that can
            //be parents of the class within an NC tree, where the parent-child relationships are required for
            //system operation.

            DirectoryEntry        classSchemaObj;
            bool                  isAuxiliary         = false;
            SetContainer <string> auxiliaryClassValue = new SetContainer <string>();

            //Get class-schema class from server.
            if (!adAdapter.GetLdsObjectByDN(
                    "CN=Class-Schema,CN=Schema,CN=Configuration," + adAdapter.LDSRootObjectName,
                    out classSchemaObj))
            {
                DataSchemaSite.Assume.IsTrue(
                    false,
                    "CN=Class-Schema,CN=Schema,CN=Configuration,"
                    + adAdapter.rootDomainDN
                    + " Object is not found in server");
            }

            //Collect its auxiliary class value.
            if (classSchemaObj.Properties.Contains("auxiliaryclass"))
            {
                //auxiliaryClassValue.Add
                foreach (string value in classSchemaObj.Properties["auxiliaryclass"])
                {
                    auxiliaryClassValue.Add(value);
                }
            }

            //Collect its system auxiliary class value.
            if (classSchemaObj.Properties.Contains("systemauxiliaryclass"))
            {
                //AuxiliaryClassValue.Add
                foreach (string value in classSchemaObj.Properties["systemauxiliaryclass"])
                {
                    auxiliaryClassValue.Add(value);
                }
            }

            if (auxiliaryClassValue.Count != 0)
            {
                //For each auxiliary class...
                foreach (string auxClass in auxiliaryClassValue)
                {
                    isAuxiliary = false;
                    foreach (IObjectOnServer serverObj in serverObjects)
                    {
                        //Get it from server.
                        if (serverObj.Name.Equals(auxClass))
                        {
                            //Get server object governsID.
                            string governsID = (string)serverObj.Properties[StandardNames.governsId.ToLower()][0];

                            //It should be eqal to the auxiliary class name of the class.
                            if (governsID.Equals(auxClass))
                            {
                                isAuxiliary = true;
                                continue;
                            }
                        }
                    }
                    if (isAuxiliary)
                    {
                        continue;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            #endregion
        }
        /// <summary>
        /// This method validates the requirements under
        /// ConsistencyRules Scenario.
        /// </summary>
        public void ValidateConsistencyRules()
        {
            #region MS-ADTS-Schema_R73
            //The objectClass attribute of the attributeSchema equals the sequence [top, attributeSchema ]
            //Expected Sequence setting...
            Sequence <string> expectedSeq = new Sequence <string>();
            Sequence <string> actualSeq   = new Sequence <string>();
            DirectoryEntry    serverObject;
            string            requiredObjectDN = String.Empty;

            expectedSeq.Add("top");
            expectedSeq.Add("classSchema");

            //Get attributeSchema from Server.
            requiredObjectDN = "CN=Attribute-Schema,CN=Schema,CN=Configuration," + adAdapter.rootDomainDN;
            if (!adAdapter.GetObjectByDN(requiredObjectDN, out serverObject))
            {
                DataSchemaSite.Assume.IsTrue(false, requiredObjectDN + " Object is not found in server");
            }
            foreach (string valueString in serverObject.Properties[StandardNames.objectClass.ToLower()])
            {
                actualSeq.Add(valueString.ToLower());
            }

            //MS-ADTS-Schema_R73.
            DataSchemaSite.CaptureRequirementIfAreEqual <Sequence <string> >(
                expectedSeq,
                actualSeq,
                73,
                "The objectClass attribute of the attributeSchema equals the sequence [top, classSchema ].");

            #endregion

            #region MS-ADTS-Schema_R157
            //The objectClass attribute of the classSchema equals the sequence [top, classSchema ].
            //Get classSchema from Server.
            requiredObjectDN = "CN=Class-Schema,CN=Schema,CN=Configuration," + adAdapter.rootDomainDN;
            if (!adAdapter.GetObjectByDN(requiredObjectDN, out serverObject))
            {
                DataSchemaSite.Assume.IsTrue(false, requiredObjectDN + " Object is not found in server");
            }
            actualSeq = new Sequence <string>();
            foreach (string valueString in serverObject.Properties[StandardNames.objectClass.ToLower()])
            {
                actualSeq.Add(valueString.ToLower());
            }

            //MS-ADTS-Schema_R157.
            DataSchemaSite.CaptureRequirementIfAreEqual <Sequence <string> >(
                expectedSeq,
                actualSeq,
                157,
                "The objectClass attribute of the classSchema equals the sequence [top, classSchema ].");

            #endregion

            #region MS-ADTS-Schema_R128-133,136-142,179

            //Inheritance rule requirements
            IEnumerable <IObjectOnServer> serverObjects = adAdapter.GetAllSchemaClasses();
            if (serverObjects == null)
            {
                DataSchemaSite.Assume.IsNotNull(serverObjects, "Class objects are not existing in Server");
            }

            DataSchemaSite.Log.Add(LogEntryKind.Comment, "Begin ValidateInheritanceRequirements");
            //This method will validate the requirements MS-ADTS-Schema_R128-133,136-142,179.
            ValidateInheritanceRequirements(serverObjects, true);

            #endregion

            #region MS-ADTS-Schema_R143-146

            //Covering ObjectClass requirements
            //Get domain NC for validation.
            DirectoryEntry domainEntry;
            if (!adAdapter.GetObjectByDN(adAdapter.rootDomainDN, out domainEntry))
            {
                DataSchemaSite.Assume.IsTrue(false, adAdapter.rootDomainDN + " Object is not found in server");
            }
            DataSchemaSite.Log.Add(LogEntryKind.Comment, "Begin ValidateObjectClassRequirements");
            //This method validates teh requirements MS-ADTS-Schema_R143-146
            ValidateObjectClassRequirements(domainEntry.Children, true);

            #endregion

            #region MS-ADTS-Schema_R149,175
            //Coverring StructureRule requirements
            DataSchemaSite.Log.Add(LogEntryKind.Comment, "Begin ValidateStructureRulesRequirements");
            //This method validates the requirements MS-ADTS-Schema_R149,175
            ValidateStructureRulesRequirements(serverObjects, true);

            #endregion

            #region MS-ADTS-Schema_R152,153
            //Covering ContentRule requirements
            DataSchemaSite.Log.Add(LogEntryKind.Comment, "Begin ValidateContentRulesRequirements");
            //This method validates the requirements MS-ADTS-Schema_R152,153.
            ValidateContentRulesRequirements(domainEntry.Children, serverObjects);

            #endregion

            #region MS-ADTS-Schema_R177
            //The systemAuxiliaryClass attribute of the classSchema Specifies governsIDs of the classes that can
            //be parents of the class within an NC tree, where the parent-child relationships are required for
            //system operation.
            DirectoryEntry        classSchemaObj;
            bool                  isAuxiliary         = false;
            SetContainer <string> auxiliaryClassValue = new SetContainer <string>();

            //Get class-schema class from server.
            if (!adAdapter.GetObjectByDN("CN=Class-Schema,CN=Schema,CN=Configuration," + adAdapter.rootDomainDN, out classSchemaObj))
            {
                DataSchemaSite.Assume.IsTrue(
                    false,
                    "CN=Class-Schema,CN=Schema,CN=Configuration,"
                    + adAdapter.rootDomainDN
                    + " Object is not found in server");
            }

            //Collect its auxiliary class value.
            if (classSchemaObj.Properties.Contains("auxiliaryclass"))
            {
                //AuxiliaryClassValue.Add
                foreach (string value in classSchemaObj.Properties["auxiliaryclass"])
                {
                    auxiliaryClassValue.Add(value);
                }
            }

            //Collect its system auxiliary class value.
            if (classSchemaObj.Properties.Contains("systemauxiliaryclass"))
            {
                //AuxiliaryClassValue.Add
                foreach (string value in classSchemaObj.Properties["systemauxiliaryclass"])
                {
                    auxiliaryClassValue.Add(value);
                }
            }

            if (auxiliaryClassValue.Count != 0)
            {
                //For each auxiliary class...
                foreach (string auxClass in auxiliaryClassValue)
                {
                    isAuxiliary = false;
                    foreach (IObjectOnServer serverObj in serverObjects)
                    {
                        //Get it from server.
                        if (serverObj.Name.Equals(auxClass))
                        {
                            //Get server object governsID.
                            string governsID = (string)serverObj.Properties[StandardNames.governsId.ToLower()][0];

                            //It should be eqal to the auxiliary class name of the class.
                            if (governsID.Equals(auxClass))
                            {
                                isAuxiliary = true;
                                continue;
                            }
                        }
                    }
                    if (isAuxiliary)
                    {
                        continue;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            //MS-ADTS-Schema_R177.
            DataSchemaSite.Log.Add(LogEntryKind.Comment, "SystemAuxiliaryClass TDI is resolved");

            #endregion
        }
        /// <summary>
        ///  Check objectClass.
        /// </summary>
        /// <param name="obj">ModelObject.</param>
        public static void CheckObjectClass(ModelObject obj)
        {
            string dn          = (string)obj[StandardNames.shortName];
            Value  objectClass = obj[StandardNames.objectClass];

            if (objectClass == null)
            {
                Checks.Fail("'{0}' must have object class", dn);

                return;
            }

            // Check for resolution and last/first element compliance
            int count = 0;
            Sequence <string> classes = obj.GetAllClassIds();
            bool resolveOk            = true;

            foreach (string classId in classes)
            {
                ModelObject classObject;
                //The object must be present in Schema NC.
                if (!obj.dc.TryGetClass(classId, out classObject))
                {
                    Checks.Fail("'{0}' has undefined object class '{1}'", dn, classId);
                    resolveOk = false;
                    continue;
                }
                //Checking for the first class is Top
                if (count == 0 && classId != StandardNames.top)
                {
                    Checks.Fail("'{0}' first object class must be top", dn);
                    resolveOk = false;
                }
                //Checking for the last class is Structural class.
                if (count == objectClass.UnderlyingValues.Count - 1)
                {
                    ObjectClassCategory category = (ObjectClassCategory)(int)classObject[StandardNames.objectClassCategory];

                    if (category != ObjectClassCategory.StructuralClass)
                    {
                        Checks.Fail("'{0}' last object class must be structural");
                        resolveOk = false;
                    }
                }
                count++;
            }
            if (!resolveOk)
            {
                return;
            }

            // Check for superclass chaining
            // Checks that if the value of object class is [top,ac_1,...,ac_n,sc_1,...,sc_n],
            // then sc_n is the most specific structural class, sc_1...scn_(n-1) is the super class chain of sc_n (excluding top),
            // and ac_n is the next auxilary class before that, where ac_1...acn(n-1) is that classes chain excluding classes
            // which have been seen already before (where there can be a number of ac anchors here).
            SetContainer <string> includedClasses = new SetContainer <string>();
            int i = classes.Count - 1;

            while (i > 0)
            {
                string classId = classes[i--];
                if (includedClasses.Contains(classId))
                {
                    Checks.Fail("'{0}' object class contains repeated entries", dn);
                    break;
                }
                includedClasses.Add(classId);
                ObjectClassCategory category = (ObjectClassCategory)(int)obj.dc.GetClass(classId)[StandardNames.objectClassCategory];
                if (i == classes.Count - 2)
                {
                    // Most specific class must be structural
                    if (category != ObjectClassCategory.StructuralClass)
                    {
                        Checks.Fail("'{0}' object class most specific class must be structural", dn);
                    }
                }

                //If the server is Pre Windows 2003.
                foreach (string clId in GetSuperClassChain(obj.dc, classId).Revert())
                {
                    if (includedClasses.Contains(clId))
                    {
                        // Already included in a previous chain
                        continue;
                    }
                    includedClasses.Add(clId);
                    if (i <= 0)
                    {
                        Checks.Fail(
                            "'{0}' object class does not contain chain of super classes of '{1}' (classes missing)",
                            dn,
                            classId);
                        break;
                    }
                    if (classes[i--] != clId)
                    {
                        Checks.Fail(
                            "'{0}' object class does not contain chain of super classes '{1}' (found unexpected '{2}')",
                            dn,
                            classId,
                            classes[i + 1]);
                        break;
                    }
                }
            }
        }