private IOrderedEnumerable<SentenceWord> _simpleSentenceWords(Stage3ResultElement algResult)
 {
     return algResult.ChainWordsIds.All.Values.Select(wordId => _sentence.WordList.Find(word => word.Id == wordId)).
         Concat(_sentence.WordList.FindAll(word => word.Id == algResult.Id)).
         OrderBy(word => word.Order);
 }
        public override void ProcessSentence(Sentence sentence)
        {
            _sentence = sentence;

            Debug.Assert(_stage1Results.Items != null);

            List<SentenceWord> words = sentence.WordList;

            // берем результат 1-го этапа и для каждого элемента восстанавливаем цепочку синтаксической связи
            int currentNr = 1;
            Dictionary<int, int> conjuctionsToDelete = new Dictionary<int, int>();
            foreach (var sentenceWordStage1 in _stage1Results.Items)
            {
                Stage3ResultElement item = new Stage3ResultElement();
                item.CopyFromSourceWord(sentenceWordStage1);
                // находим зависимые от вершины слова с определенными тегами
                List<SentenceWord> relatedWords = _sentence.WordList.FindAll(x => x.DOM == sentenceWordStage1.Id
                    && (x.Link.Value == LinkType.SentSoch.Value
                    || x.Link.Value == LinkType.PodchSouz.Value
                    || x.Link.Value == LinkType.InfSouz.Value
                    || x.Link.Value == LinkType.Eksplet.Value
                    || x.Link.Value == LinkType.Relyat.Value
                    ));
                int[] excludeIds = relatedWords.Select(x => x.Id).ToArray();

                item.LoadChainList(excludeIds, ref words);
                item.SimpleSentenceNr = currentNr;

                // если вершина сочинительная, то добавляем родительский для нее союз
                if (sentenceWordStage1.Link.Value == LinkType.PodchSouz.Value || sentenceWordStage1.Link.Value == LinkType.InfSouz.Value)
                {
                    int parentConjuctionId = _sentence.WordList.Find(x => x.Id == sentenceWordStage1.DOM).Id;
                    item.ChainWordsIds.InsertChild(parentConjuctionId);

                    if (!conjuctionsToDelete.ContainsKey(parentConjuctionId))
                        conjuctionsToDelete.Add(parentConjuctionId, currentNr);
                }

                Result.Items.Add(item);
                currentNr++;
            }

            // теперь удаляем найденные союзы из предложений, в которых они были изначально
            foreach (var item in conjuctionsToDelete)
            {
                Stage3ResultElement stage3Item = Result.Items.Find(x => (x.SimpleSentenceNr != item.Value) && x.ChainWordsIds.Values.Contains(item.Key));

                if (stage3Item != null)
                {
                    // удаляем союз вместе с его потенциальными потомками
                    INode<int> nodeToDelete = stage3Item.ChainWordsIds.Nodes.ToList().Find(x => x.Data == item.Key);
                    stage3Item.ChainWordsIds.Remove(nodeToDelete.Data);
                }
                else
                    Debug.WriteLine("Ошибка в перенавешивании союза из одного ПП в другое");
            }

            //пересобираем результаты в зависимости от порядковых номеров первых членов предложения
            SortedList<int, int> minWordOrder = new SortedList<int, int>();
            // номера ПП определяются по минимальному порядковому номеру слов в выбранном предложении
            foreach (var item in Result.Items)
            {
                List<int> sentenceWordOrders = item.ChainWordsIds.All.Values.ToList();
                sentenceWordOrders.Add(item.Order);
                sentenceWordOrders.Sort();

                if (item.Order <= sentenceWordOrders[0])
                    minWordOrder.Add(item.Order, sentenceWordOrders[0]);
                else
                    if (!minWordOrder.Keys.Contains(sentenceWordOrders[0]))
                    minWordOrder.Add(sentenceWordOrders[0], item.Order);
            }

            int lastNr = 1;
            foreach (var dictItem in minWordOrder)
            {
                var item = Result.Items.Find(x => x.Order == dictItem.Key);
                if (item == null)
                    item = Result.Items.Find(x => x.Order == dictItem.Value);
                item.SimpleSentenceNr = lastNr;
                lastNr++;
            }
            Result.Items = Result.Items.OrderBy(x => x.SimpleSentenceNr).ToList();
        }