/// <summary>
        /// Parse TtsXmlComment list.
        /// </summary>
        /// <param name="node">XmlNode.</param>
        /// <param name="nsmgr">XmlNamespaceManager.</param>
        public void Parse(XmlNode node, XmlNamespaceManager nsmgr)
        {
            Helper.ThrowIfNull(node);
            Helper.ThrowIfNull(nsmgr);

            XmlNodeList xmlCommentNodes = node.SelectNodes(@"tts:comment", nsmgr);
            _ttsXmlCommentDict.Clear();
            foreach (XmlNode commentNode in xmlCommentNodes)
            {
                TtsXmlComment ttsXmlComment = new TtsXmlComment();
                ttsXmlComment.Parse(commentNode);
                ttsXmlComment.Tag = this;
                if (_ttsXmlCommentDict.ContainsKey(ttsXmlComment.Name))
                {
                    throw new InvalidDataException(Helper.NeutralFormat(
                        "Duplicate comment name [{0}].", ttsXmlComment.Name));
                }

                if (!_ttsXmlCommentDict.ContainsKey(ttsXmlComment.Name))
                {
                    _ttsXmlCommentDict.Add(ttsXmlComment.Name, new Collection<TtsXmlComment>());
                }

                _ttsXmlCommentDict[ttsXmlComment.Name].Add(ttsXmlComment);
            }

            XmlNodeList xmlStatusNodes = node.SelectNodes(@"tts:status", nsmgr);
            _ttsXmlStatusDict.Clear();
            foreach (XmlNode statusNode in xmlStatusNodes)
            {
                TtsXmlStatus ttsXmlStatus = new TtsXmlStatus();
                ttsXmlStatus.Parse(statusNode);
                ttsXmlStatus.Tag = this;
                if (_ttsXmlStatusDict.ContainsKey(ttsXmlStatus.Name))
                {
                    throw new InvalidDataException(Helper.NeutralFormat(
                        "Duplicate comment name [{0}].", ttsXmlStatus.Name));
                }

                if (!_ttsXmlStatusDict.ContainsKey(ttsXmlStatus.Name))
                {
                    _ttsXmlStatusDict.Add(ttsXmlStatus.Name, new Collection<TtsXmlStatus>());
                }

                _ttsXmlStatusDict[ttsXmlStatus.Name].Add(ttsXmlStatus);
            }

            XmlNodeList xmlVQIssuesNodes = node.SelectNodes(@"tts:issue", nsmgr);
            _ttsXmlVQIssueCollection.Clear();
            foreach (XmlNode ttsXmlNode in xmlVQIssuesNodes)
            {
                TtsXmlVQIssue xmlVQIssue = new TtsXmlVQIssue();
                xmlVQIssue.Parse(ttsXmlNode);
                _ttsXmlVQIssueCollection.Add(xmlVQIssue);
            }
        }
        /// <summary>
        /// Append comment.
        /// </summary>
        /// <param name="comment">Comment to append.</param>
        /// <param name="canBeMultiValue">Whether the comment can be mutlti value.</param>
        public void AppendComment(TtsXmlComment comment, bool canBeMultiValue)
        {
            if (comment == null)
            {
                throw new ArgumentNullException("comment");
            }

            if (string.IsNullOrEmpty(comment.Name))
            {
                throw new ArgumentNullException("comment");
            }

            if (!_ttsXmlCommentDict.ContainsKey(comment.Name))
            {
                _ttsXmlCommentDict.Add(comment.Name, new Collection<TtsXmlComment>());
            }

            if (!canBeMultiValue)
            {
                _ttsXmlCommentDict[comment.Name].Clear();
            }

            comment.Tag = this;
            _ttsXmlCommentDict[comment.Name].Add(comment);
        }
        /// <summary>
        /// Parse Comments from XML reader.
        /// </summary>
        /// <param name="reader">Xml reader.</param>
        public void Parse(XmlReader reader)
        {
            Helper.ThrowIfNull(reader);

            if (reader.IsEmptyElement)
            {
                return;
            }

            _ttsXmlCommentDict.Clear();
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element && reader.Name == "comment")
                {
                    TtsXmlComment ttsXmlComment = new TtsXmlComment();
                    ttsXmlComment.Parse(reader);
                    ttsXmlComment.Tag = this;
                    if (_ttsXmlCommentDict.ContainsKey(ttsXmlComment.Name))
                    {
                        throw new InvalidDataException(Helper.NeutralFormat(
                            "Duplicate comment name [{0}].", ttsXmlComment.Name));
                    }

                    if (!_ttsXmlCommentDict.ContainsKey(ttsXmlComment.Name))
                    {
                        _ttsXmlCommentDict.Add(ttsXmlComment.Name, new Collection<TtsXmlComment>());
                    }

                    _ttsXmlCommentDict[ttsXmlComment.Name].Add(ttsXmlComment);
                }
                else if (reader.NodeType == XmlNodeType.Element && reader.Name == "status")
                {
                    TtsXmlStatus ttsXmlStatus = new TtsXmlStatus();
                    ttsXmlStatus.Parse(reader);
                    ttsXmlStatus.Tag = this;

                    if (!_ttsXmlStatusDict.ContainsKey(ttsXmlStatus.Name))
                    {
                        _ttsXmlStatusDict.Add(ttsXmlStatus.Name, new Collection<TtsXmlStatus>());
                    }

                    _ttsXmlStatusDict[ttsXmlStatus.Name].Add(ttsXmlStatus);
                }
                else if (reader.NodeType == XmlNodeType.Element && reader.Name == "issue")
                {
                    TtsXmlVQIssue ttsVqIssue = new TtsXmlVQIssue();
                    ttsVqIssue.Parse(reader);
                    _ttsXmlVQIssueCollection.Add(ttsVqIssue);
                }
                else if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "comments")
                {
                    break;
                }
            }
        }