private IOrderedEnumerable<SentenceWord> dependantWords(Stage3ResultElement element)
        {
            var result = new List<SentenceWord>();

            result.AddRange(element.ChainWordsIds.All.Values.Select(i => _sentence.WordList.Find(word => word.Id == i)));
            result.Add(_sentence.WordList.Find(x => x.Id == element.Id));

            return
                result.OrderBy(word => word.Order);
        }
        private void shrinkResultBySimpleSentence(Stage3ResultElement res)
        {
            int simpleSentenceNrForFirstWord = -1;

            var firstChainWordInSimpleSentence = _simpleSentenceStage3Result.Items.Find(x => x.Id == res.Id || x.ChainWordsIds.All.Values.Contains(res.Id));
            if (firstChainWordInSimpleSentence != null)
                simpleSentenceNrForFirstWord = firstChainWordInSimpleSentence.SimpleSentenceNr;

            if (simpleSentenceNrForFirstWord >= 0)
            {
                var tree = res.ChainWordsIds.DeepCopy();
                foreach (var chainWordId in res.ChainWordsIds.All.Values)
                {
                    var simpleSentenceNrForWord = _simpleSentenceStage3Result.Items.Find(x => x.Id == chainWordId || x.ChainWordsIds.All.Values.Contains(chainWordId)).SimpleSentenceNr;
                    if (simpleSentenceNrForWord != simpleSentenceNrForFirstWord)
                        tree.Remove(chainWordId);
                }
                res.ChainWordsIds = tree.DeepCopy();
            }
        }
        private List<SentenceWord> _getChildWordsForWordById(int wordId, int[] excludeIds)
        {
            var list = new List<SentenceWord>();

            SentenceWord item = _stage1Result.Items.Find(x => x.Id == wordId);
            if (item == null)
                item = _sentence.WordList.Find(x => x.Id == wordId);
            Debug.Assert(item != null);

            foreach (var childWord in _sentence.WordList.FindAll(x => x.DOM == item.Id && !excludeIds.Contains(x.Id)))
            {
                var itemToAdd = new Stage3ResultElement();
                itemToAdd.CopyFromSourceWord(childWord);
                list.Add(itemToAdd);
            }

            return list;
        }
        private void CreateDependantChain(int parentWordId, SentenceWord sourceWord, int[] excludeIds, ObjectType Type, Stage3ResultElement existingItem)
        {
            var words = _sentence.WordList;
            bool canAddItem = true;
            Stage3ResultElement addItem;
            if (existingItem == null)
            {
                addItem = new Stage3ResultElement();
                addItem.CopyFromSourceWord(sourceWord);
                addItem.DOM = parentWordId;
                addItem.ObjectType = Type;
            }
            else
            {
                addItem = existingItem;
            }

            // ищем Вторые слова
            List<SentenceWord> secondWords = _getChildWordsForWordById(sourceWord.Id, excludeIds);
            if (secondWords.Count > 0)
            {
                foreach (var secondWord in secondWords)
                {
                    // Каждое найденное Второе слово проверяется на наличие тэгов LINK = сочин или LINK = соч-союзн
                    bool hasSecondWordSochinLink = secondWord.Link.Value == LinkType.Sochin.Value || secondWord.Link.Value == LinkType.SochSouz.Value;

                    if (!hasSecondWordSochinLink)
                    {
                        bool firstWordLink = addItem.Link.Value == LinkType.PassAnal.Value || addItem.Link.Value == LinkType.Analit.Value || addItem.Link.Value == LinkType.Predl.Value;

                        if (!firstWordLink)
                        {
                            secondWord.LoadChainList(excludeIds, ref words, false, true);
                            if (existingItem != null)
                                addItem.ChainWordsIds.AddChild(sourceWord.Id);
                            addItem.ChainWordsIds.AddChild(secondWord.ChainWordsIds);
                        }
                        else
                        {
                            List<SentenceWord> thirdWords = _getChildWordsForWordById(secondWord.Id, excludeIds);
                            if (thirdWords.Count > 0)
                            {
                                foreach (var thirdWord in thirdWords)
                                {
                                    bool hasThirdWordSochinLink = thirdWord.Link.Value == LinkType.Sochin.Value || thirdWord.Link.Value == LinkType.SochSouz.Value;

                                    if (!hasThirdWordSochinLink)
                                    {
                                        thirdWord.LoadChainList(excludeIds, ref words, false, true);
                                        var node = addItem.ChainWordsIds.AddChild(thirdWord.Id);
                                        node.AddChild(thirdWord.ChainWordsIds);

                                    }
                                    else
                                    {   // сначала
                                        CreateDependantChain(parentWordId, thirdWord, excludeIds, Type, null);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        if (secondWord.Link.Value == LinkType.Sochin.Value)
                            CreateDependantChain(parentWordId, secondWord, excludeIds, Type, null);
                        if (secondWord.Link.Value == LinkType.SochSouz.Value)
                        {
                            CreateDependantChain(parentWordId, secondWord, excludeIds, Type, addItem);
                            canAddItem = false;
                        }

                    }
                }
            }
            if (canAddItem)
                Result.Items.Add(addItem);
        }