/// <summary>
        /// Remove unit from unit list map.
        /// </summary>
        /// <param name="language">Language of the unit.</param>
        /// <param name="type">Type of the unit.</param>
        /// <param name="sentenceId">Sentence ID of the unit.</param>
        /// <param name="indexInSentence">Unit index in sentence.</param>
        /// <returns>Removed UnitItem.</returns>
        public UnitItem RemoveUnit(Language language, UnitList.UnitListType type,
            string sentenceId, int indexInSentence)
        {
            string uniListKey = UnitList.GetKey(language, type);
            if (_unitListMap.ContainsKey(uniListKey))
            {
                UnitList unitList = _unitListMap[uniListKey];
                return unitList.RemoveUnit(sentenceId, indexInSentence);
            }

            return null;
        }
        /// <summary>
        /// Add unit to unit list map.
        /// </summary>
        /// <param name="language">Language of the unit.</param>
        /// <param name="type">Type of the unit.</param>
        /// <param name="unit">Unit to be added.</param>
        public void AddUnit(Language language, UnitList.UnitListType type,
            UnitItem unit)
        {
            string unitListKey = UnitList.GetKey(language, type);

            if (!_unitListMap.ContainsKey(unitListKey))
            {
                UnitList unitList = new UnitList();
                unitList.Language = language;
                unitList.UnitType = type;
                _unitListMap.Add(unitListKey, unitList);

                unitList.AddUnit(unit);
            }
            else
            {
                UnitList unitList = _unitListMap[unitListKey];
                unitList.AddUnit(unit);
            }
        }
        /// <summary>
        /// Load configuration from file.
        /// </summary>
        /// <param name="filePath">XML configuration file path.</param>
        public void Load(string filePath)
        {
            // Check the configuration file first
            try
            {
                XmlHelper.Validate(filePath, ConfigSchema);
            }
            catch (InvalidDataException ide)
            {
                string message = string.Format(CultureInfo.InvariantCulture,
                    "The configuration file [{0}] error is found.",
                    filePath);
                throw new InvalidDataException(message, ide);
            }

            // Load configuration
            XmlDocument dom = new XmlDocument();
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(dom.NameTable);
            nsmgr.AddNamespace("tts", ConfigSchema.TargetNamespace);
            dom.Load(filePath);

            XmlNodeList unitListNodes = dom.DocumentElement.SelectNodes(@"tts:unitList", nsmgr);

            _unitListMap.Clear();
            foreach (XmlNode unitListNode in unitListNodes)
            {
                UnitList unitList = new UnitList();
                unitList.Parse(unitListNode, nsmgr);
                _unitListMap.Add(unitList.Id, unitList);
            }

            XmlNode dropSentencesNode = dom.DocumentElement.SelectSingleNode(@"tts:dropSentences", nsmgr);

            if (dropSentencesNode != null)
            {
                _dropSentenceList.Parse(dropSentencesNode, nsmgr);
            }
        }
        /// <summary>
        /// Whether unit list map contains the unit list with the specified language and type.
        /// </summary>
        /// <param name="language">Language of the UnitList.</param>
        /// <param name="type">Type of the UnitList.</param>
        /// <param name="unitKey">UnitKey of the UnitItem.</param>
        /// <returns>Whether contains the specified unit.</returns>
        public bool ContainsKey(Language language, UnitList.UnitListType type, string unitKey)
        {
            string unitListKey = UnitList.GetKey(language, type);

            if (_unitListMap.ContainsKey(unitListKey) &&
                _unitListMap[unitListKey].Units.ContainsKey(unitKey))
            {
                return true;
            }

            return false;
        }
        /// <summary>
        /// Append UnitList to an existing UnitList.
        /// </summary>
        /// <param name="unitList">UnitList to be appended.</param>
        public void Append(UnitList unitList)
        {
            if (unitList == null)
            {
                throw new ArgumentNullException("unitList");
            }

            if (unitList.Units == null)
            {
                string message = Helper.NeutralFormat("The Units of unit list should not be null.");
                throw new ArgumentNullException("unitList", message);
            }

            if (unitList.Units.Keys == null)
            {
                string message = Helper.NeutralFormat("The Units.Keys of unit list should not be null.");
                throw new ArgumentNullException("unitList", message);
            }

            if (unitList.Language != _language || unitList.UnitType != _type)
            {
                return;
            }

            foreach (string unitKey in unitList.Units.Keys)
            {
                UnitItem unitItem = unitList.Units[unitKey];
                AddUnit(unitItem);
            }
        }