/// <summary>選択中の類語グループに基づき、類語一覧を更新する</summary>
        /// <param name="groupId">取得対象のグループID</param>
        private void UpdateDisplaySynonymWords(int groupId)
        {
            // 呼ばれるのは、類語ウィンドウで類語の更新がされたときか、メインウィンドウで類語グループ選択が変更されたとき
            // そのため、いずれにせよ一旦表示中の類語一覧をクリアしてしまった方が良い
            DisplaySynonymWords.Clear();

            if (_model == null)
            {
                return;
            }

            SynonymWordEntity[] entities = _model.GetSynonymWordEntities(groupId);
            if (entities == null || entities.Any() == false)
            {
                // todo:ログ
                Logger.Error(CLASS_NAME, "UpdateDisplaySynonymWords", "search synonym entites are null!");
            }

            // 表示用のEntityに入れ直して反映させる
            foreach (SynonymWordEntity entity in entities)
            {
                if (entity == null)
                {
                    continue;
                }

                DisplaySynonymWord displaySynonymWord = new DisplaySynonymWord()
                {
                    WordID      = entity.WordID,
                    SynonymWord = entity.Word
                };
                DisplaySynonymWords.Add(displaySynonymWord);
            }
        }
        /// <summary>類語グループ一覧、類語一覧、類語検索結果を最新の状態に更新する</summary>
        private void UpdateSynonymArea(bool isInitialize = false)
        {
            UpdateDisplaySynonymGroups();

            // 類語グループを選択していて、当該グループが削除されずに存在している場合は更新
            if (IsExistSynonymGroupID(_selectedSynonymGroupId))
            {
                UpdateDisplaySynonymWords(_selectedSynonymGroupId);
            }
            else if (isInitialize == false)
            {
                // 類語グループを選択していないか、選択していたが削除されてなくなっている場合、クリア処理をかける
                // 初回起動時は選択していないこと確定なので、除外する
                DisplaySynonymWords.Clear();
            }

            // todo:タイミングどうするか
            // 類語検索結果は一旦クリアする
            DisplaySynonymSearchResults.Clear();
        }
        /// <summary>類語検索処理</summary>
        /// <param name="parameter"></param>
        private void ExecuteSynonymSearch(object parameter)
        {
            Logger.Info(CLASS_NAME, "ExecuteSynonymSearch", "start");

            if (_model == null)
            {
                Logger.Fatal(CLASS_NAME, "ExecuteSynonymSearch", "_model is null!");
                return;
            }

            // 表示するモノがないか、空テキストなら検索する意味がない
            if (_model.TextDocument == null ||
                string.IsNullOrEmpty(_model.TextDocument.Text))
            {
                Logger.Error(CLASS_NAME, "ExecuteSynonymSearch", "target text is null or empty!");
                return;
            }

            // 検索するべき類語のすべてを配列に変換
            DisplaySynonymWord[] synonymWords = new DisplaySynonymWord[DisplaySynonymWords.Count];
            DisplaySynonymWords.CopyTo(synonymWords, 0);

            // 類語検索はmodelに依頼
            DisplaySynonymSearchResult[] synonymSearchResults = _model.SynonymSearch(synonymWords, TextDocument.Text);

            // 現状、特に表示しているモノとの整合性は考えずに更新する
            // メモリの負荷が大きくなってきたら、別途検討することにする
            DisplaySynonymSearchResults.Clear();
            foreach (DisplaySynonymSearchResult result in synonymSearchResults)
            {
                DisplaySynonymSearchResults.Add(result);
            }

            // 検索結果にハイライトをかける
            string[] searchWords = new string[DisplaySynonymWords.Count];
            for (int i = 0; i < DisplaySynonymWords.Count; ++i)
            {
                searchWords[i] = DisplaySynonymWords[i].SynonymWord;
            }
            _model.ApplyHighlightToTargets(searchWords, ApplyHighlightKind.SynonymSearch);
        }