public void ConvertTest()
        {
            string msg = "ChineseWordConverter.Convert 測試失敗: ";

            var target = new ChineseWordConverter(
                new ZhuyinReverseConverter(new ZhuyinReverseConversionProvider()));

            ContextTagManager context = new ContextTagManager();

            // 測試結合韻。
            string             text      = "我";
            Stack <char>       charStack = new Stack <char>(text);
            List <BrailleWord> expected  = new List <BrailleWord>();
            BrailleWord        brWord    = new BrailleWord(text, " ㄨㄛˇ", "1208");

            expected.Add(brWord);
            List <BrailleWord> actual = target.Convert(charStack, context);

            CollectionAssert.AreEqual(expected, actual, msg + text);
            charStack.Clear();

            // 測試單音字:要在音調記號前加一個空方。
            text      = "智";
            charStack = new Stack <char>(text);
            brWord    = new BrailleWord(text, "ㄓ  ˋ", "013110");
            expected.Clear();
            expected.Add(brWord);
            actual = target.Convert(charStack, context);
            CollectionAssert.AreEqual(expected, actual, msg + text);
            charStack.Clear();

            // 測試無特殊規則的注音。
            text      = "你";
            charStack = new Stack <char>(text);
            brWord    = new BrailleWord(text, "ㄋㄧ ˇ", "1D2108");
            expected.Clear();
            expected.Add(brWord);
            actual = target.Convert(charStack, context);
            CollectionAssert.AreEqual(expected, actual, msg + text);
            charStack.Clear();

            // 測試標點符號。
            text      = ":";
            charStack = new Stack <char>(text);
            brWord    = new BrailleWord(text, "   ˉ", "1212");
            expected.Clear();
            expected.Add(brWord);
            actual = target.Convert(charStack, context);
            CollectionAssert.AreEqual(expected, actual, msg + text);
            charStack.Clear();

            // 測試全形空白
            text      = " ";
            charStack = new Stack <char>(text);
            brWord    = new BrailleWord(text, "   ˉ", "00");
            expected.Clear();
            expected.Add(brWord);
            actual = target.Convert(charStack, context);
            CollectionAssert.AreEqual(expected, actual, msg + text);
            charStack.Clear();

            // 測試簡體字。
            text      = "实";
            charStack = new Stack <char>(text);
            brWord    = new BrailleWord(text, "ㄕ  ˊ", "0A3102");
            expected.Clear();
            expected.Add(brWord);
            actual = target.Convert(charStack, context);
            CollectionAssert.AreEqual(expected, actual, msg + text);
            charStack.Clear();

            // 測試無法轉換的字元:/
            text      = "/";
            charStack = new Stack <char>(text);
            expected  = null;
            actual    = target.Convert(charStack, context);
            CollectionAssert.AreEqual(expected, actual, msg + text);
            charStack.Clear();
        }
        /// <summary>
        /// 把一個明眼字元轉換成點字(BrailleWord)。
        /// 原則上,能夠在這裡處理掉點字特殊規則的,就盡量在這裡處理掉,
        /// 特別是不可斷行分開的點字,例如:一個中文字的所有點字碼、特殊單音字附加的「ㄦ」等等。
        /// </summary>
        /// <param name="reader">字串流。</param>
        /// <returns>若成功轉換成點字,則傳回已轉換的點字 BrailleWord 物件串列,否則傳回 null。</returns>
        /// <remarks>若轉換成功,則已轉換的字元會從串流中讀出,否則該字元仍會保留在串流中。</remarks>
        public List <BrailleWord> ConvertWord(Stack <char> chars)
        {
            List <BrailleWord> brWordList = null;

            // Two-pass 處理(因為有些點字必須再交給其它點字轉換器,故需兩次)。
            for (int pass = 0; pass < 2; pass++)
            {
                if (chars.Count < 1)
                {
                    break;
                }

                // 1. 轉換情境標籤。NOTE: 情境標籤一定要先處理!
                if (chars.Count > 0 && m_ContextTagConverter != null)
                {
                    brWordList = m_ContextTagConverter.Convert(chars, m_ContextTagManager);
                    if (brWordList != null && brWordList.Count > 0)
                    {
                        return(brWordList);
                    }
                }

                // 2. 轉換座標符號
                if (chars.Count > 0 && m_CoordConverter != null && m_ContextTagManager.IsActive(ContextTagNames.Coordinate))
                {
                    brWordList = m_CoordConverter.Convert(chars, m_ContextTagManager);
                    if (brWordList != null && brWordList.Count > 0)
                    {
                        return(brWordList);
                    }
                }

                // 3. 轉換數學符號。
                if (chars.Count > 0 && m_ContextTagManager.IsActive(ContextTagNames.Math) && m_MathConverter != null)
                {
                    brWordList = m_MathConverter.Convert(chars, m_ContextTagManager);
                    if (brWordList != null && brWordList.Count > 0)
                    {
                        return(brWordList);
                    }
                }

                // 4. 轉換表格符號。
                if (chars.Count > 0 && m_ContextTagManager.IsActive(ContextTagNames.Table) && m_TableConverter != null)
                {
                    brWordList = m_TableConverter.Convert(chars, m_ContextTagManager);
                    if (brWordList != null && brWordList.Count > 0)
                    {
                        return(brWordList);
                    }
                }

                // 5. 轉換音標符號.
                if (chars.Count > 0 && m_ContextTagManager.IsActive(ContextTagNames.Phonetic) && m_PhoneticConverter != null)
                {
                    brWordList = m_PhoneticConverter.Convert(chars, m_ContextTagManager);
                    if (brWordList != null && brWordList.Count > 0)
                    {
                        return(brWordList);
                    }
                }

                // 6. 轉換中文。
                if (chars.Count > 0 && m_ChineseConverter != null)
                {
                    // 若成功轉換成點字,就不再 pass 給其它轉換器。
                    brWordList = m_ChineseConverter.Convert(chars, m_ContextTagManager);
                    if (brWordList != null && brWordList.Count > 0)
                    {
                        return(brWordList);
                    }
                }

                // 7. 轉換英文。
                if (chars.Count > 0 && m_EnglishConverter != null)
                {
                    // 若成功轉換成點字,就不再 pass 給其它轉換器。
                    brWordList = m_EnglishConverter.Convert(chars, m_ContextTagManager);
                    if (brWordList != null && brWordList.Count > 0)
                    {
                        return(brWordList);
                    }
                }
            }

            if (chars.Count > 0)
            {
                // 其它註冊的轉換器。
                foreach (WordConverter cvt in m_Converters)
                {
                    // 若其中一個轉換器成功轉換成點字,就不再 pass 給其它轉換器。
                    brWordList = cvt.Convert(chars, m_ContextTagManager);
                    if (brWordList != null && brWordList.Count > 0)
                    {
                        return(brWordList);
                    }
                }
            }

            // TODO: 碰到無法轉換成點字的情況時,觸發事件通知呼叫端處理,例如:顯示在在訊息視窗裡。

            return(null);
        }