/// <summary>
        /// Appends a punctuation word in the end of given utterance.
        /// </summary>
        /// <param name="utterance">
        /// The given utterance.
        /// </param>
        /// <param name="scriptWord">
        /// The script word.
        /// </param>
        /// <returns>
        /// The phoneme count of the given word.
        /// </returns>
        /// <exception cref="InvalidDataException">
        /// Exception.
        /// </exception>
        private int AppendPunctuationWord(TtsUtterance utterance, ScriptWord scriptWord)
        {
            TtsWord word = utterance.AppendNewWord();
            word.LangId = (ushort)scriptWord.Language;
            word.BreakLevel = (TtsBreakLevel)scriptWord.Break;
            word.Emphasis = (TtsEmphasis)scriptWord.Emphasis;
            word.WordText = scriptWord.Grapheme;
            word.NETypeText = scriptWord.NETypeText;
            word.WordType = TtsWordType.WT_PUNCTUATION;

            // There is no phoneme for punctuation word.
            return 0;
        }
        /// <summary>
        /// Appends a normal word in the end of given utterance.
        /// </summary>
        /// <param name="utterance">
        /// The given utterance.
        /// </param>
        /// <param name="scriptWord">
        /// The script word.
        /// </param>
        /// <returns>
        /// The phoneme count of the given word.
        /// </returns>
        /// <exception cref="InvalidDataException">
        /// Exception.
        /// </exception>
        private int AppendNormalWord(TtsUtterance utterance, ScriptWord scriptWord)
        {
            TtsWord word = utterance.AppendNewWord();
            word.LangId = (ushort)scriptWord.Language;
            word.BreakLevel = (TtsBreakLevel)scriptWord.Break;
            word.Emphasis = (TtsEmphasis)scriptWord.Emphasis;
            word.WordText = scriptWord.Grapheme;
            word.NETypeText = scriptWord.NETypeText;
            word.WordRegularText = scriptWord.RegularText;
            word.WordType = TtsWordType.WT_NORMAL;
            word.AcousticDomain = DomainExtension.MapToEnum(scriptWord.AcousticDomainTag);
            word.WordExpansion = scriptWord.Expansion;
            word.ReadablePronunciation = scriptWord.Pronunciation;
            if (!string.IsNullOrEmpty(scriptWord.Pronunciation))
            {
                word.PhoneIds = Phoneme.PronunciationToPhoneIds(Pronunciation.RemoveUnitBoundary(scriptWord.Pronunciation));
            }

            if (NeedPos)
            {
                // Checks pos.
                if (string.IsNullOrEmpty(scriptWord.PosString))
                {
                    throw new InvalidDataException(
                        Helper.NeutralFormat("No POS found in sentence \"{0}\" for word \"{1}\"",
                            scriptWord.Sentence.ScriptItem.Id, scriptWord.Grapheme));
                }

                // Sets pos value.
                word.Pos = (ushort)PosSet.Items[scriptWord.PosString];
                string taggingPos = PosSet.CategoryTaggingPOS[scriptWord.PosString];
                word.POSTaggerPos = (ushort)PosSet.Items[taggingPos];
            }

            // Gets the normal phoneme count.
            ErrorSet errorSet = new ErrorSet();
            int count = scriptWord.GetNormalPhoneNames(PhoneSet, errorSet).Count;
            if (errorSet.Count > 0)
            {
                throw new InvalidDataException(
                    Helper.NeutralFormat("Invalid phone found in sentence \"{0}\" for word \"{1}\"",
                        scriptWord.Sentence.ScriptItem.Id, scriptWord.Grapheme));
            }

            word.TextOffset = (uint)scriptWord.OffsetInString;
            word.TextLength = (uint)scriptWord.LengthInString;

            return count;
        }
        /// <summary>
        /// Appends a silence word in then end of given utterance.
        /// </summary>
        /// <param name="utterance">
        /// The given utterance.
        /// </param>
        /// <param name="phone">
        /// The phone name.
        /// </param>
        /// <returns>
        /// The phoneme count of the silence word.
        /// </returns>
        private int AppendSilenceWord(TtsUtterance utterance, string phone)
        {
            Debug.Assert(Offline.Phoneme.IsSilenceFeature(phone), "Silence word should have phone: short pause or silence");

            TtsWord word = utterance.AppendNewWord();
            word.PhoneIds = Phoneme.PronunciationToPhoneIds(Offline.Phoneme.ToRuntime(phone));
            word.LangId = (ushort)PhoneSet.Language;
            word.WordType = TtsWordType.WT_SILENCE;
            word.Pos = 0;

            // Modify the silence word's break level to make it consistent with runtime engine
            if (word.Previous != null)
            {
                word.BreakLevel = word.Previous.BreakLevel;
            }
            else
            {
                word.BreakLevel = TtsBreakLevel.BK_IDX_SENTENCE;
            }

            return 1;
        }