public void CopyFromSourceWord(Stage1ResultElement sourceWord)
 {
     base.CopyFromSourceWord(sourceWord);
     ObjectType = sourceWord.ObjectType;
     IsRestoredFromServicePart = sourceWord.IsRestoredFromServicePart;
     ServiceParts = sourceWord.ServiceParts;
 }
        private void findWordsWithSochLink()
        {
            foreach (var word in _sentence.WordList.FindAll(x => x.ConjuctedWithId > -1))
            {
                Stage1ResultElement item = new Stage1ResultElement();
                item.CopyFromSourceWord(word);
                item.ObjectType = ObjectType.HasForwardLink;
                item.IsRestoredFromServicePart = false;

                if (Result.Items.Find(x => x.Id == item.Id) == null)
                    Result.Items.Add(item);

                foreach (var relatedWord in _sentence.WordList.FindAll(x => x.Id == item.ConjuctedWithId))
                {
                    Stage1ResultElement dItem = new Stage1ResultElement();
                    dItem.CopyFromSourceWord(relatedWord);
                    dItem.ObjectType = ObjectType.LastWord;
                    dItem.IsRestoredFromServicePart = false;

                    if (Result.Items.Find(x => x.Id == dItem.Id) == null)
                        Result.Items.Add(dItem);
                }
            }
        }
        private Stage1ResultElement _searchForAnotherItemAndAddIt(Stage1ResultElement cItem, int rowId)
        {
            // добавляем текущий
            Stage3ResultElement item = new Stage3ResultElement();
            item.CopyFromSourceWord(cItem);
            item.ServiceParts = cItem.ServiceParts;
            item.RowId = rowId;
            if (Result.Items.Find(x => x.Id == item.Id) == null)
                Result.Items.Add(item);

            // ищем следующий
            cItem = _stage1Result.Items.Find(x => x.ConjuctedWithId == cItem.Id || cItem.ServiceParts.Select(y => y.Id).Contains(x.ConjuctedWithId) && x.Id != cItem.Id);
            if (cItem != null)
                _searchForAnotherItemAndAddIt(cItem, rowId);

            return cItem;
        }
        private void findPrepositionsAndAuxVerbs(List<int> allResultIds)
        {
            // из всех текущих id выбираем такие, которые являются предлогами или всп.глаголами
            List<int> idsToAnalyze = new List<int>();
            foreach (var resultId in allResultIds)
            {
                if (_sentence.WordList.Exists(x => x.Id == resultId && (x.IsAuxVerb || x.IsPreposition)))
                    idsToAnalyze.Add(resultId);
            }

            foreach (var wordId in idsToAnalyze)
            {
                // найдем в текущих результатах такой элемент, id которого либо равен исследуемому, либо в его ServiceParts присутствует исследуемый id - чтобы знать куда добавлять инфу
                var resultItem = Result.Items.Find(x => x.Id == wordId);
                if (resultItem == null)
                {
                    foreach (var i in Result.Items)
                    {
                        if (i.ServiceParts.Exists(x => x.Id == wordId))
                            resultItem = i;
                    }
                }
                Debug.Assert(resultItem != null);

                //ищем дочернее слово для предлога или всп.глагола
                List<SentenceWord> childWords = _sentence.WordList.FindAll(x => x.DOM == wordId);
                SentenceWord childWord = null;
                if ((childWords.Count > 0) && (_sentence.WordList.Find(x => x.Id == wordId).IsAuxVerb))
                    foreach (var cw in childWords)
                    {
                        if (cw.Link.Value == LinkType.Analit.Value)
                        {
                            childWord = cw;
                            break;
                        }
                    }
                else
                    childWord = childWords.FirstOrDefault();

                if (childWord != null)
                {
                    // если дочернего слова нет в списке предварительных ОЧ, то добавляем его вместо текущего ОЧ, присоединяя к нему СЧР
                    if (!allResultIds.Exists(x => x == childWord.Id))
                    {
                        Stage1ResultElement itemToAdd = new Stage1ResultElement();
                        itemToAdd.IsRestoredFromServicePart = true;
                        itemToAdd.CopyFromSourceWord(childWord);
                        if (itemToAdd.ServiceParts.Find(x => x.Id == wordId) == null)
                            itemToAdd.ServiceParts.Add(_sentence.WordList.Find(x => x.Id == wordId));
                        Result.Items.Remove(resultItem);

                        // специально переопределяем id соединенного слова, ставим его таким же как у родительской СЧР (пригодится на этапе 3)
                        if (itemToAdd.ConjuctedWithId == -1)
                            itemToAdd.ConjuctedWithId = resultItem.ConjuctedWithId;

                        Result.Items.Add(itemToAdd);
                    }
                    // а если такое слово есть, то берем его и объединяем с предлогом
                    else
                    {
                        var existResult = Result.Items.Find(x => x.Id == childWord.Id);

                        if (existResult != null)
                        {
                            if (existResult.ServiceParts.Find(x => x.Id == wordId) == null)
                                existResult.ServiceParts.Add(_sentence.WordList.Find(x => x.Id == wordId));
                        }
                        Result.Items.RemoveAll(x => x.Id == wordId);
                    }
                }
            }
        }