public static global::System.Xml.Schema.XmlSchemaComplexType GetTypedDataSetSchema(global::System.Xml.Schema.XmlSchemaSet xs)
 {
     ReqTable ds = new ReqTable();
     global::System.Xml.Schema.XmlSchemaComplexType type = new global::System.Xml.Schema.XmlSchemaComplexType();
     global::System.Xml.Schema.XmlSchemaSequence sequence = new global::System.Xml.Schema.XmlSchemaSequence();
     global::System.Xml.Schema.XmlSchemaAny any = new global::System.Xml.Schema.XmlSchemaAny();
     any.Namespace = ds.Namespace;
     sequence.Items.Add(any);
     type.Particle = sequence;
     global::System.Xml.Schema.XmlSchema dsSchema = ds.GetSchemaSerializable();
     if (xs.Contains(dsSchema.TargetNamespace)) {
         global::System.IO.MemoryStream s1 = new global::System.IO.MemoryStream();
         global::System.IO.MemoryStream s2 = new global::System.IO.MemoryStream();
         try {
             global::System.Xml.Schema.XmlSchema schema = null;
             dsSchema.Write(s1);
             for (global::System.Collections.IEnumerator schemas = xs.Schemas(dsSchema.TargetNamespace).GetEnumerator(); schemas.MoveNext(); ) {
                 schema = ((global::System.Xml.Schema.XmlSchema)(schemas.Current));
                 s2.SetLength(0);
                 schema.Write(s2);
                 if ((s1.Length == s2.Length)) {
                     s1.Position = 0;
                     s2.Position = 0;
                     for (; ((s1.Position != s1.Length)
                                 && (s1.ReadByte() == s2.ReadByte())); ) {
                         ;
                     }
                     if ((s1.Position == s1.Length)) {
                         return type;
                     }
                 }
             }
         }
         finally {
             if ((s1 != null)) {
                 s1.Close();
             }
             if ((s2 != null)) {
                 s2.Close();
             }
         }
     }
     xs.Add(dsSchema);
     return type;
 }
 public static global::System.Xml.Schema.XmlSchemaComplexType GetTypedTableSchema(global::System.Xml.Schema.XmlSchemaSet xs)
 {
     global::System.Xml.Schema.XmlSchemaComplexType type = new global::System.Xml.Schema.XmlSchemaComplexType();
     global::System.Xml.Schema.XmlSchemaSequence sequence = new global::System.Xml.Schema.XmlSchemaSequence();
     ReqTable ds = new ReqTable();
     global::System.Xml.Schema.XmlSchemaAny any1 = new global::System.Xml.Schema.XmlSchemaAny();
     any1.Namespace = "http://www.w3.org/2001/XMLSchema";
     any1.MinOccurs = new decimal(0);
     any1.MaxOccurs = decimal.MaxValue;
     any1.ProcessContents = global::System.Xml.Schema.XmlSchemaContentProcessing.Lax;
     sequence.Items.Add(any1);
     global::System.Xml.Schema.XmlSchemaAny any2 = new global::System.Xml.Schema.XmlSchemaAny();
     any2.Namespace = "urn:schemas-microsoft-com:xml-diffgram-v1";
     any2.MinOccurs = new decimal(1);
     any2.ProcessContents = global::System.Xml.Schema.XmlSchemaContentProcessing.Lax;
     sequence.Items.Add(any2);
     global::System.Xml.Schema.XmlSchemaAttribute attribute1 = new global::System.Xml.Schema.XmlSchemaAttribute();
     attribute1.Name = "namespace";
     attribute1.FixedValue = ds.Namespace;
     type.Attributes.Add(attribute1);
     global::System.Xml.Schema.XmlSchemaAttribute attribute2 = new global::System.Xml.Schema.XmlSchemaAttribute();
     attribute2.Name = "tableTypeName";
     attribute2.FixedValue = "RequirementDataTable";
     type.Attributes.Add(attribute2);
     type.Particle = sequence;
     global::System.Xml.Schema.XmlSchema dsSchema = ds.GetSchemaSerializable();
     if (xs.Contains(dsSchema.TargetNamespace)) {
         global::System.IO.MemoryStream s1 = new global::System.IO.MemoryStream();
         global::System.IO.MemoryStream s2 = new global::System.IO.MemoryStream();
         try {
             global::System.Xml.Schema.XmlSchema schema = null;
             dsSchema.Write(s1);
             for (global::System.Collections.IEnumerator schemas = xs.Schemas(dsSchema.TargetNamespace).GetEnumerator(); schemas.MoveNext(); ) {
                 schema = ((global::System.Xml.Schema.XmlSchema)(schemas.Current));
                 s2.SetLength(0);
                 schema.Write(s2);
                 if ((s1.Length == s2.Length)) {
                     s1.Position = 0;
                     s2.Position = 0;
                     for (; ((s1.Position != s1.Length)
                                 && (s1.ReadByte() == s2.ReadByte())); ) {
                         ;
                     }
                     if ((s1.Position == s1.Length)) {
                         return type;
                     }
                 }
             }
         }
         finally {
             if ((s1 != null)) {
                 s1.Close();
             }
             if ((s2 != null)) {
                 s2.Close();
             }
         }
     }
     xs.Add(dsSchema);
     return type;
 }
        //validate derived requirement
        private bool ValidateDerivedRequirement(ReqTable.RequirementRow derivedReq)
        {
            //ignore original requirement without derivation.
            if (derivedReq.IsDerivedNull() ||
                string.IsNullOrEmpty(derivedReq.Derived.Trim()))
            {
                return false;
            }

            //////////////////////if ((deltaScopes.Count > 0 && !deltaScopes.Contains(derivedReq.Delta)))
            //////////////////////{
            //////////////////////    return false;
            //////////////////////}

            bool validateResult = true;
            if (!requirementsToVerify.ContainsKey(derivedReq.REQ_ID))
            {
                if (!validationErrors.ContainsKey(derivedReq.REQ_ID))
                {
                    //error: derived requirement cannot be informative
                    if (informativeReqs.Contains(derivedReq.REQ_ID))
                    {
                        validationErrors.Add(derivedReq.REQ_ID, RSValidationRules.DERIVEDREQISINFORMATIVE);
                    }
                    //error: derived requirement cannot be out-of-scope
                    else if (scopeRules[ReportingParameters.outScopeRule].Contains(derivedReq.Scope.ToLower()))
                    {
                        validationErrors.Add(derivedReq.REQ_ID, RSValidationRules.DERIVEDREQOUTOFSCOPE);

                    }
                    //error: derived requirement is deleted, non-testable or unverified.
                    else if (string.Compare(derivedReq.Verification, VerificationValues.DELETED) == 0)
                    {
                        validationErrors.Add(derivedReq.REQ_ID, RSValidationRules.DERIVEDREQNOTTESTABLE);
                        validateResult = false;
                    }
                    else if (string.Compare(derivedReq.Verification, VerificationValues.NONTESTABLE) == 0 ||
                        string.Compare(derivedReq.Verification, VerificationValues.UNVERIFIED) == 0)
                    {
                        //derived requirement can only be tast case or adapter.
                        validationErrors.Add(derivedReq.REQ_ID, RSValidationRules.DERIVEDREQNOTTESTABLE);
                    }
                }
            }

            return validateResult;
        }
        //validate original requirement
        private bool ValidateOriginalRequirement(ReqTable.RequirementRow derivedReq, string originalId)
        {
            bool isLegal = true;
            //error: cannot derive from deleted
            if (requirementsDeleted.ContainsKey(originalId))
            {
                if (!validationErrors.ContainsKey(derivedReq.REQ_ID))
                {
                    validationErrors.Add(derivedReq.REQ_ID, RSValidationRules.DERIVEFROMDELETED);
                }
                isLegal = false;
            }
            //check the original requirement is normative and testable.
            else if (requirementsNotToVerify.ContainsKey(originalId))
            {
                //error: cannot derive from informative
                if (informativeReqs.Contains(originalId))
                {
                    //we ignore informative+unverified requirement,
                    //and not count this kind of requirement to coverage.
                    if (!validationErrors.ContainsKey(derivedReq.REQ_ID) &&
                        string.Compare(RequirementVerifications[originalId], VerificationValues.UNVERIFIED, true) != 0)
                    {
                        derivedFromInformativeReqs.Add(derivedReq.REQ_ID);
                        validationErrors.Add(derivedReq.REQ_ID, RSValidationRules.DERIVEFROMINFORMATIVE);
                    }
                }
            }
            else
            {
                switch (RequirementVerifications[originalId])
                {
                    case VerificationValues.UNVERIFIED:
                        {
                            //warning: cannot derive from normative, unverified.
                            //should still add to derived requirement table.
                            if (!validationWarnings.ContainsKey(derivedReq.REQ_ID))
                            {
                                validationWarnings.Add(derivedReq.REQ_ID, RSValidationRules.DERIVEFROMUNVERIFIED);
                            }
                            break;
                        }
                    default:
                        {
                            //do nothing
                            break;
                        }
                }
            }

            return isLegal;
        }
        /// <summary>
        /// compute requirement using new rule
        /// </summary>
        /// <param name="row">The requirement row contians scope column</param>
        private void ComputRequirementV2(ReqTable.RequirementRow row)
        {
            List<string> ltStrings = new List<string>();
            if (row.IsScopeNull() && !row.IsActorNull())
            {
                throw new InvalidOperationException("Using Actor and Scope together is not supported.");
            }

            row.Scope = row.Scope.Trim();
            string keyword = "none";
            if (string.Compare(row.Scope, keyword, true) == 0)
            {
                throw new InvalidOperationException(
                    string.Format("'None' keyword should not be the value of scope in requirement {0}", row.REQ_ID));
            }

            if (scopeRules[ReportingParameters.inScopeRule].Contains(row.Scope.ToLower()) &&
                    scopeRules[ReportingParameters.outScopeRule].Contains(row.Scope.ToLower()))
            {
                throw new InvalidOperationException(
                    string.Format("Value {0} for InScope and OutOfScope parameters is duplicated.", row.Scope));
            }
            else if (!scopeRules[ReportingParameters.inScopeRule].Contains(row.Scope.ToLower()) &&
                    !scopeRules[ReportingParameters.outScopeRule].Contains(row.Scope.ToLower()))
            {
                throw new InvalidOperationException(
                    string.Format("Unexpected scope value in Requirement {0}.", row.REQ_ID));
            }
            else if (scopeRules[ReportingParameters.inScopeRule].Contains(row.Scope.ToLower()))
            {
                //in-scope requirement
                if (string.Compare("Normative", row.IsNormative, true) == 0)
                {
                    switch (row.Verification)
                    {
                        case VerificationValues.ADAPTER:
                        case VerificationValues.TESTCASE:
                        case VerificationValues.UNVERIFIED:
                            {
                                    if ((deltaScopes.Count > 0 && !deltaScopes.Contains(row.Delta)))
                                {
                                    if (row.IsDerivedNull() || string.IsNullOrEmpty(row.Derived))
                                    {
                                        //original requirement is out of delta scope
                                        ltStrings.Add(row.Description);
                                        ltStrings.Add(row.Doc_Sect);
                                        ltStrings.Add(row.Scope);
                                        requirementsNotToVerify.Add(row.REQ_ID, ltStrings);
                                        oriReqOutOfDeltaScope.Add(row.REQ_ID);
                                    }
                                    else
                                    {
                                        //in-scope, normative, testable requirement
                                        ltStrings.Add(row.Description);
                                        ltStrings.Add(row.Doc_Sect);
                                        ltStrings.Add(row.Scope);
                                        requirementsToVerify.Add(row.REQ_ID, ltStrings);
                                    }
                                }
                                else
                                {
                                    ltStrings.Add(row.Description);
                                    ltStrings.Add(row.Doc_Sect);
                                    ltStrings.Add(row.Scope);
                                    requirementsToVerify.Add(row.REQ_ID, ltStrings);
                                }
                                break;
                            }
                        default:
                            {
                                //in-scope, normative, un-testable requirement
                                ltStrings.Add(row.Description);
                                ltStrings.Add(row.Doc_Sect);
                                ltStrings.Add(row.Scope);
                                requirementsNotToVerify.Add(row.REQ_ID, ltStrings);
                                break;
                            }
                    }
                }
                else
                {
                    //informative requirement should be ignore.
                    ltStrings.Add(row.Description);
                    ltStrings.Add(row.Doc_Sect);
                    ltStrings.Add(row.Scope);
                    requirementsNotToVerify.Add(row.REQ_ID, ltStrings);
                    informativeReqs.Add(row.REQ_ID);
                }
            }
            else
            {
                if (string.Compare("Informative", row.IsNormative, true) == 0)
                {
                    informativeReqs.Add(row.REQ_ID);
                }
                ltStrings.Add(row.Description);
                ltStrings.Add(row.Doc_Sect);
                ltStrings.Add(row.Scope);
                //out of scope requirement should not to verify
                requirementsNotToVerify.Add(row.REQ_ID, ltStrings);
                if (string.Compare(VerificationValues.ADAPTER, row.Verification, true) == 0 ||
                    string.Compare(VerificationValues.TESTCASE, row.Verification, true) == 0)
                {
                    //out of scope requirement should not mark as testable.
                    if (!validationErrors.ContainsKey(row.REQ_ID))
                    {
                        validationErrors.Add(row.REQ_ID, RSValidationRules.OUTOFSCOPEISTESTABLE);
                    }
                }
            }
        }
        private void Load(IList<string> reqFilenames)
        {
            try
            {
                ReqTable requirementTable = null;
                ReqTable tempTable = new ReqTable();
                foreach (string reqfile in reqFilenames)
                {
                    if (requirementTable == null)
                    {
                        requirementTable = new ReqTable();
                        requirementTable.ReadXml(XmlReader.Create(reqfile, new XmlReaderSettings() { XmlResolver = null }));
                    }
                    else
                    {
                        tempTable.ReadXml(XmlReader.Create(reqfile, new XmlReaderSettings() { XmlResolver = null }));
                        requirementTable.Merge(tempTable);
                        tempTable.Clear();
                    }
                }
                tempTable.Dispose();

                bool newVersion = false;
                // Now requirementTable contains all requirement tables from user's input
                // to simplify the coding, ReportingTool assumes all of them are user's required.
                foreach (ReqTable.RequirementRow row in requirementTable.Requirement)
                {
                    //remove all start or end spacese.
                    row.REQ_ID = row.REQ_ID.Trim();
                    row.Verification = row.Verification.Trim();

                    //translate the blank to new for delta value
                    if (row.IsDeltaNull() || string.IsNullOrEmpty(row.Delta.Trim()))
                    {
                        row.Delta = "new";
                    }
                    else
                    {
                        row.Delta = row.Delta.ToLower().Trim();
                    }

                    //cache all requirements and verifications.
                    this.reqVerifications.Add(row.REQ_ID, row.Verification);

                    if (string.Compare(row.Verification, VerificationValues.DELETED, true) == 0)
                    {
                        List<string> ltStrings = new List<string>();
                        ltStrings.Add(row.Description);
                        ltStrings.Add(row.Doc_Sect);
                        ltStrings.Add(row.Scope);
                        requirementsDeleted.Add(row.REQ_ID, ltStrings);
                        continue;
                    }

                    TotalCount++;
                    if (row.IsActorNull() && row.IsScopeNull())
                    {
                        throw new InvalidOperationException(
                            String.Format("Column Actor or Scope is expected at {0}", row.REQ_ID));
                    }

                    if (!row.IsScopeNull() && TotalCount == 1)
                    {
                        //estimate RS version from the first requirement
                        newVersion = true;
                    }

                    if (newVersion)
                    {
                        ComputRequirementV2(row);
                    }
                    else
                    {
                        ComputRequirementV1(row);
                    }
                }

                //make sure there is no duplicated id in RS Req_Id column.
                MakeSureNoDuplicateId();

                if (newVersion)
                {
                    //compute derived requirements and original requirements
                    foreach (ReqTable.RequirementRow row in requirementTable.Requirement)
                    {
                        if (ValidateDerivedRequirement(row))
                        {
                            ComputeDerivedRequirement(row);
                        }
                    }
                }

                //filter the requirement which only derived from informative requirement(s)
                foreach(string derivedId in derivedFromInformativeReqs)
                {
                    DerivedRequirement derivedReq = derivedRequirements[derivedId];
                    foreach (string originalId in derivedReq.OriginalReqs)
                    {
                        if (!informativeReqs.Contains(originalId))
                        {
                            validationErrors.Remove(derivedId);
                        }
                    }
                }

                foreach (string invalidOriReq in oriReqOutOfDeltaScope)
                {
                    RemoveDerivedRequirmentRelationship(invalidOriReq);
                }

                requirementTable.Dispose();

                //find the loop in the requirement table and throw exception when loops exist.
                FindLoop();
            }
            catch (Exception e)
            {
                throw new InvalidOperationException(
                    String.Format("[ERROR] Unable to get requirement data from specified requirement table files. Details:\r\n{0}", e.Message + e.StackTrace));
            }
        }
        /// <summary>
        /// compute requirement using old rule
        /// </summary>
        /// <param name="row">The requirement row contains actor column</param>
        private void ComputRequirementV1(ReqTable.RequirementRow row)
        {
            List<string> ltStrings = new List<string>();
            if (row.IsActorNull() && !row.IsScopeNull())
            {
                throw new InvalidOperationException("Using Actor and Scope together is not supported.");
            }
            if (scopeMode)
            {
                throw new InvalidOperationException("Scope is not supported in old version of RS");
            }
            if (deltaScopes.Count > 0)
            {
                throw new InvalidOperationException("Delta scope is not supported in old version of RS");
            }
            if (
                        (String.Compare(row.IsNormative, "Normative", false) == 0)
                        && (String.Compare(row.Actor, "Client", false) != 0)
                        && (String.Compare(row.Verification, "Non-testable", false) != 0)
                        )
            {
                // all requirements that are normative & non-client & testable
                ltStrings.Add(row.Description);
                ltStrings.Add(row.Doc_Sect);
                ltStrings.Add(row.Scope);
                requirementsToVerify.Add(row.REQ_ID, ltStrings);
            }
            else
            {
                ltStrings.Add(row.Description);
                ltStrings.Add(row.Doc_Sect);
                ltStrings.Add(row.Scope);

                requirementsNotToVerify.Add(row.REQ_ID, ltStrings);

            }
        }
        private void ComputeDerivedRequirement(ReqTable.RequirementRow row)
        {
            if (row.IsDerivedNull() || String.Compare(row.Verification, VerificationValues.DELETED, true) == 0)
            {
                return;
            }
            string derivedReqs = row.Derived;
            if (!string.IsNullOrEmpty(derivedReqs.Trim()))
            {
                string[] originalReqs = derivedReqs.Split(new char[] { ',' });
                if (originalReqs != null)
                {
                    foreach (string originalReq in originalReqs)
                    {
                        if (string.IsNullOrEmpty(originalReq.Trim()))
                        {
                            continue;
                        }
                        string[] terms = originalReq.Split(new char[] { ':' });
                        if (terms == null || terms.Length > 2)
                        {
                            throw new FormatException(
                                string.Format("The format of derived text {0} in Requirement {1}:\"{2}\" is not correct,"
                                + "the correct format should be Req_ID plus :i :p or :c as suffix.",
                                originalReq, row.REQ_ID, row.Description));
                        }
                        string originalId = terms[0].Trim();
                        if (string.IsNullOrEmpty(originalId))
                        {
                            throw new FormatException(
                                string.Format("The originalID cannot be null or empty in Requirement {1}:\"{2}\"",
                                row.REQ_ID, row.Description));
                        }

                        //check the original requirement exists.
                        originalId = GetRequirementId(originalId, true);
                        if (string.IsNullOrEmpty(originalId))
                        {
                            if (!validationErrors.ContainsKey(row.REQ_ID))
                            {
                                validationErrors.Add(row.REQ_ID,
                                    string.Format(RSValidationRules.DERIVEFROMNONEXIST, terms[0]));
                            }
                            continue;
                        }

                        if (terms.Length == 2)
                        {
                            //treat "R1: " as default
                            if (string.IsNullOrEmpty(terms[1].Trim()))
                            {
                                AddDerivedRequirement("i", originalId, row);
                            }
                            else
                            {
                                AddDerivedRequirement(terms[1].Trim(), originalId, row);
                            }
                        }
                        else
                        {
                            //default type is :i
                            AddDerivedRequirement("i", originalId, row);
                        }
                    }
                }
            }
        }
        //build the graph of derived requirements.
        private void AddDerivedRequirement(string type, string originalId, ReqTable.RequirementRow row)
        {
            if (!ValidateOriginalRequirement(row, originalId))
            {
                //error occurs, should not be added to build derived graph.
                return;
            }
            //add original requirement id to the current requirement's original id list.
            if (!derivedRequirements.ContainsKey(row.REQ_ID))
            {
                DerivedRequirement derivedReq
                    = new DerivedRequirement(row.REQ_ID, CoveredStatus.Unverified);
                derivedReq.AddOriginalRequirement(originalId);
                derivedRequirements.Add(row.REQ_ID, derivedReq);
            }
            else
            {
                if (!derivedRequirements[row.REQ_ID].OriginalReqs.Contains(originalId))
                {
                    DerivedRequirement derivedReq = derivedRequirements[row.REQ_ID];
                    derivedReq.AddOriginalRequirement(originalId);
                    derivedRequirements[row.REQ_ID] = derivedReq;
                }
            }

            //add all derived requirements for current requirement
            //to the derived dictionary of original requirement
            switch (type.ToLower())
            {
                case "i":
                    AddDerived(originalId, row, DerivedType.Inferred);
                    break;
                case "p":
                    AddDerived(originalId, row, DerivedType.Partial);
                    break;
                case "c":
                    AddDerived(originalId, row, DerivedType.Cases);
                    break;
                default:
                    throw new FormatException(
                        string.Format("Unexpected derived type \"{0}\" is found in derived text in Requirement {1}:\"{2}\"," +
                        "the type must be one of i, c or p.", type, row.REQ_ID, row.Description));
            }
        }
Exemplo n.º 10
0
 private void AddDerived(string originalId, ReqTable.RequirementRow row, DerivedType type)
 {
     if (!derivedRequirements.ContainsKey(originalId))
     {
         DerivedRequirement originalReq
             = new DerivedRequirement(originalId, CoveredStatus.Unverified);
         originalReq.AddDerivedRequirement(row.REQ_ID, type);
         derivedRequirements.Add(originalId, originalReq);
     }
     else
     {
         if (!derivedRequirements[originalId].DerivedReqs.ContainsKey(row.REQ_ID))
         {
             DerivedRequirement originalReq = derivedRequirements[originalId];
             originalReq.AddDerivedRequirement(row.REQ_ID, type);
             derivedRequirements[originalId] = originalReq;
         }
     }
 }
Exemplo n.º 11
0
        private void Load(IList <string> reqFilenames)
        {
            try
            {
                ReqTable requirementTable = null;
                ReqTable tempTable        = new ReqTable();
                foreach (string reqfile in reqFilenames)
                {
                    if (requirementTable == null)
                    {
                        requirementTable = new ReqTable();
                        requirementTable.ReadXml(XmlReader.Create(reqfile, new XmlReaderSettings()
                        {
                            XmlResolver = null
                        }));
                    }
                    else
                    {
                        tempTable.ReadXml(XmlReader.Create(reqfile, new XmlReaderSettings()
                        {
                            XmlResolver = null
                        }));
                        requirementTable.Merge(tempTable);
                        tempTable.Clear();
                    }
                }
                tempTable.Dispose();

                bool newVersion = false;
                // Now requirementTable contains all requirement tables from user's input
                // to simplify the coding, ReportingTool assumes all of them are user's required.
                foreach (ReqTable.RequirementRow row in requirementTable.Requirement)
                {
                    //remove all start or end spacese.
                    row.REQ_ID       = row.REQ_ID.Trim();
                    row.Verification = row.Verification.Trim();

                    //translate the blank to new for delta value
                    if (row.IsDeltaNull() || string.IsNullOrEmpty(row.Delta.Trim()))
                    {
                        row.Delta = "new";
                    }
                    else
                    {
                        row.Delta = row.Delta.ToLower().Trim();
                    }

                    //cache all requirements and verifications.
                    this.reqVerifications.Add(row.REQ_ID, row.Verification);

                    if (string.Compare(row.Verification, VerificationValues.DELETED, true) == 0)
                    {
                        List <string> ltStrings = new List <string>();
                        ltStrings.Add(row.Description);
                        ltStrings.Add(row.Doc_Sect);
                        ltStrings.Add(row.Scope);
                        requirementsDeleted.Add(row.REQ_ID, ltStrings);
                        continue;
                    }

                    TotalCount++;
                    if (row.IsActorNull() && row.IsScopeNull())
                    {
                        throw new InvalidOperationException(
                                  String.Format("Column Actor or Scope is expected at {0}", row.REQ_ID));
                    }

                    if (!row.IsScopeNull() && TotalCount == 1)
                    {
                        //estimate RS version from the first requirement
                        newVersion = true;
                    }

                    if (newVersion)
                    {
                        ComputRequirementV2(row);
                    }
                    else
                    {
                        ComputRequirementV1(row);
                    }
                }

                //make sure there is no duplicated id in RS Req_Id column.
                MakeSureNoDuplicateId();

                if (newVersion)
                {
                    //compute derived requirements and original requirements
                    foreach (ReqTable.RequirementRow row in requirementTable.Requirement)
                    {
                        if (ValidateDerivedRequirement(row))
                        {
                            ComputeDerivedRequirement(row);
                        }
                    }
                }

                //filter the requirement which only derived from informative requirement(s)
                foreach (string derivedId in derivedFromInformativeReqs)
                {
                    DerivedRequirement derivedReq = derivedRequirements[derivedId];
                    foreach (string originalId in derivedReq.OriginalReqs)
                    {
                        if (!informativeReqs.Contains(originalId))
                        {
                            validationErrors.Remove(derivedId);
                        }
                    }
                }

                foreach (string invalidOriReq in oriReqOutOfDeltaScope)
                {
                    RemoveDerivedRequirmentRelationship(invalidOriReq);
                }

                requirementTable.Dispose();

                //find the loop in the requirement table and throw exception when loops exist.
                FindLoop();
            }
            catch (Exception e)
            {
                throw new InvalidOperationException(
                          String.Format("[ERROR] Unable to get requirement data from specified requirement table files. Details:\r\n{0}", e.Message + e.StackTrace));
            }
        }