/// <summary>
        /// Returns a StandardCodeSequence from a recursively collapsed or flatted StandardValidTerm.
        /// </summary>
        /// <param name="standardValidTerm"></param>
        /// <returns></returns>
        public static StandardCodeSequence ToStandardCodeSequence(StandardValidTerm standardValidTerm)
        {
            const int codeValueLength   = 16;
            const int codeMeaningLength = 64;

            var standardCodeSequence   = CollapseStandardValidTerm(standardValidTerm);
            var codeValue              = standardCodeSequence.CodeValue;
            var codeMeaning            = standardCodeSequence.CodeMeaning;
            var codingSchemeDesignator = standardCodeSequence.CodingSchemeDesignator;
            var codingSchemeVersion    = standardCodeSequence.CodingSchemeVersion;

            if (standardValidTerm.StandardValidTerms.Count > 0)
            {
                codeValue = ToHex(codeValue);
                if (codeValue.Length > codeValueLength)
                {
                    codeValue = codeValue.Substring(0, codeValueLength);
                }
                if (codeMeaning.Length > codeMeaningLength)
                {
                    codeMeaning = codeMeaning.Substring(0, codeMeaningLength);
                }
            }

            return(new StandardCodeSequence(
                       codeValue,
                       codeMeaning,
                       codingSchemeDesignator,
                       codingSchemeVersion));
        }
        /// <summary>
        /// Recursively flattens a hierarchy of valid terms into a single StandardCodeSequence
        /// by concatenating the codeValue and codeMeaning fields.
        /// </summary>
        /// <param name="standardValidTerm"></param>
        /// <returns></returns>
        private static StandardCodeSequence CollapseStandardValidTerm(StandardValidTerm standardValidTerm)
        {
            var          codeValue = standardValidTerm.StandardCodeSequence.CodeValue;
            var          codingSchemeDesignator = standardValidTerm.StandardCodeSequence.CodingSchemeDesignator;
            var          codingSchemeVersion    = standardValidTerm.StandardCodeSequence.CodingSchemeVersion;
            var          codeMeaning            = standardValidTerm.StandardCodeSequence.CodeMeaning;
            const string delimiter = ", ";

            if (standardValidTerm.StandardValidTerms.Count > 0)
            {
                codingSchemeDesignator = COLLAPSED_VALID_TERM_CODING_SCHEME_DESIGNATOR;
            }

            foreach (var childStandardValidTerm in standardValidTerm.StandardValidTerms)
            {
                var standardCodeSequence = CollapseStandardValidTerm(childStandardValidTerm);
                if (!string.IsNullOrEmpty(standardCodeSequence.CodeValue))
                {
                    codeValue += delimiter + standardCodeSequence.CodeValue;
                }
                if (!string.IsNullOrEmpty(standardCodeSequence.CodeMeaning))
                {
                    codeMeaning += delimiter + standardCodeSequence.CodeMeaning;
                }
            }

            return(new StandardCodeSequence(codeValue, codeMeaning, codingSchemeDesignator, codingSchemeVersion));
        }
        public override bool Equals(object obj)
        {
            if (obj == null || !(obj is StandardValidTerm))
            {
                return(false);
            }

            StandardValidTerm validTerm = (StandardValidTerm)obj;

            return((_standardCodeSequence == null
                                                ? validTerm._standardCodeSequence == null
                                                : _standardCodeSequence.Equals(validTerm._standardCodeSequence)) &&
                   (_standardValidTerms == null
                                                ? validTerm._standardValidTerms == null
                                                : CollectionUtils.Equal <StandardValidTerm>(_standardValidTerms, validTerm._standardValidTerms, true)));
        }
        /// <summary>
        /// Recursevely traverses given <paramref name="validTerm"/> and appends Code Meanings to the given <paramref name="sb"/>.
        /// This effectively flattens <paramref name="validTerm"/> to a string.
        /// </summary>
        /// <param name="validTerm">Standard Valid Term to traverse</param>
        /// <param name="sb">String Builder taht receives the values</param>
        public static StringBuilder ToStringBuilder(StandardValidTerm validTerm, StringBuilder sb)
        {
            if (validTerm == null || sb == null)
            {
                return(sb);
            }

            if (sb.Length > 0)
            {
                sb.Append(" ");
            }
            sb.Append(validTerm.StandardCodeSequence.CodeMeaning);
            foreach (var standardValidTerm in validTerm.StandardValidTerms)
            {
                ToStringBuilder(standardValidTerm, sb);
            }

            return(sb);
        }
        /// <summary>
        /// Recursively flattens a hierarchy of valid terms into a single StandardCodeSequence
        /// by concatenating the codeValue and codeMeaning fields.
        /// </summary>
        /// <param name="standardValidTerm"></param>
        /// <returns></returns>
        private static StandardCodeSequence CollapseStandardValidTerm(StandardValidTerm standardValidTerm)
        {
            var codeValue = standardValidTerm.StandardCodeSequence.CodeValue;
            var codingSchemeDesignator = standardValidTerm.StandardCodeSequence.CodingSchemeDesignator;
            var codingSchemeVersion = standardValidTerm.StandardCodeSequence.CodingSchemeVersion;
            var codeMeaning = standardValidTerm.StandardCodeSequence.CodeMeaning;
            const string delimiter = ", ";

            if (standardValidTerm.StandardValidTerms.Count > 0)
                codingSchemeDesignator = COLLAPSED_VALID_TERM_CODING_SCHEME_DESIGNATOR;

            foreach (var childStandardValidTerm in standardValidTerm.StandardValidTerms)
            {
                var standardCodeSequence = CollapseStandardValidTerm(childStandardValidTerm);
                if (!string.IsNullOrEmpty(standardCodeSequence.CodeValue))
                    codeValue += delimiter + standardCodeSequence.CodeValue;
                if (!string.IsNullOrEmpty(standardCodeSequence.CodeMeaning))
                    codeMeaning += delimiter + standardCodeSequence.CodeMeaning;
            }

            return new StandardCodeSequence(codeValue, codeMeaning, codingSchemeDesignator, codingSchemeVersion);
        }
        /// <summary>
        /// Recursevely traverses given <paramref name="validTerm"/> and appends Code Meanings to the given <paramref name="sb"/>.
        /// This effectively flattens <paramref name="validTerm"/> to a string.
        /// </summary>
        /// <param name="validTerm">Standard Valid Term to traverse</param>
        /// <param name="sb">String Builder taht receives the values</param>
        public static StringBuilder ToStringBuilder(StandardValidTerm validTerm, StringBuilder sb)
        {
            if (validTerm == null || sb == null)
                return sb;

            if (sb.Length > 0)
                sb.Append(" ");
            sb.Append(validTerm.StandardCodeSequence.CodeMeaning);
            foreach (var standardValidTerm in validTerm.StandardValidTerms)
                ToStringBuilder(standardValidTerm, sb);

            return sb;
        }
        /// <summary>
        /// Returns a StandardCodeSequence from a recursively collapsed or flatted StandardValidTerm.
        /// </summary>
        /// <param name="standardValidTerm"></param>
        /// <returns></returns>
        public static StandardCodeSequence ToStandardCodeSequence(StandardValidTerm standardValidTerm)
        {
            const int codeValueLength = 16;
            const int codeMeaningLength = 64;

            var standardCodeSequence = CollapseStandardValidTerm(standardValidTerm);
            var codeValue = standardCodeSequence.CodeValue;
            var codeMeaning = standardCodeSequence.CodeMeaning;
            var codingSchemeDesignator = standardCodeSequence.CodingSchemeDesignator;
            var codingSchemeVersion = standardCodeSequence.CodingSchemeVersion;

            if (standardValidTerm.StandardValidTerms.Count > 0)
            {
                codeValue = ToHex(codeValue);
                if (codeValue.Length > codeValueLength)
                    codeValue = codeValue.Substring(0, codeValueLength);
                if (codeMeaning.Length > codeMeaningLength)
                    codeMeaning = codeMeaning.Substring(0, codeMeaningLength);
            }

            return new StandardCodeSequence(
                codeValue,
                codeMeaning,
                codingSchemeDesignator,
                codingSchemeVersion);
        }