protected override void DoProcess(BaseSentenceAlgorithmData sourceData, BaseSentenceAlgorithmData result)
        {
            Debug.Assert(result.Sentence != null);
            result.HelperData = new SubjectPredicateСorrelationHelperData(Info.InternalName);
            var hlpData = (SubjectPredicateСorrelationHelperData) result.HelperData;
            Debug.Assert(_predicateIds != null);

            var subjectIds = sourceData.HelperData.ColumnValues<int>(HelperDataSubjectUpdateStage1SubjectId.Name).Distinct().ToList();

            foreach (var subjectId in subjectIds)
            {
                var subjectSentenceElement = result.Sentence.Elements.Find(x => x.Id == subjectId);
                var predicateId = _findPredicateForSubject(result.Sentence, subjectId);
                Log.InfoFormat("Рассматриваем подлежащее Id = {0}, Текст = {1}", subjectSentenceElement.Id,
                    subjectSentenceElement.Text);
                if (predicateId <= 0) continue;
                {
                    var predicateSentenceElement = result.Sentence.Elements.Find(x => x.Id == predicateId);
                    Log.InfoFormat("  Найдено управляющее КСО Сказуемое (3): Id = {0}, Текст = {1}",
                        predicateSentenceElement.Id, predicateSentenceElement.Text);
                    hlpData.AddOrUpdateCustomRow(subjectSentenceElement.GUID,
                        subjectSentenceElement.Id,
                        predicateSentenceElement.Order);
                }
            }

            if (hlpData.Rows.Count == 0 && sourceData.HelperData.Rows.Count > 0 && !_predicateIds.Any())
            {
                Log.InfoFormat("В предложении не нашлось сказуемых. Добавляем фантом 'быть'...");
                var recoveredPredicatesHelperData = new RecoveredPredicatesHelperData("Восстановленные подлежащих");
                var postProcessingHelpData = new SubjectsPostProcessingHelperData("Постпроцессинг подлежащих");
                foreach (var subjectId in subjectIds)
                {
                    var subjectSentenceElement = result.Sentence.Elements.Find(x => x.Id == subjectId);
                    Log.InfoFormat(
                        "Ищем согласованные определения или причастия среди потомков подлежащего: Id = {0}, Текст = {1}",
                        subjectSentenceElement.Id, subjectSentenceElement.Text);
                    var adjectiveOrParticipleChildList = new List<SentenceElement>();
                    foreach (var subjectChild in result.Sentence.SyntacticChildren(subjectId).FindAll(x => x.Order > subjectSentenceElement.Order))
                    {
                        if (_checkForArgeedWithSubject(subjectChild))
                        {
                            Log.InfoFormat("Найдено соглаосванное причастие или определение: Id = {0}, Текст = {1}",
                                subjectChild.Id, subjectChild.Text);
                            adjectiveOrParticipleChildList.Add(subjectChild);
                        }
                    }

                    var adjectiveOrParticipleChildWithMaxOrder = adjectiveOrParticipleChildList.OrderBy(x => x.Order).Last();
                    Log.InfoFormat(
                        "Найденное согласованное определение или причастие для добавления нового сказуемого: Id = {0}, Текст = {1}",
                        adjectiveOrParticipleChildWithMaxOrder.Id, adjectiveOrParticipleChildWithMaxOrder.Text);

                    Log.InfoFormat("Добавляем новое сказуемое быть. Order = {0}",
                        adjectiveOrParticipleChildWithMaxOrder.Order);
                    // уменьшаем Order, т.е. добавляем после слова, которое перед причастием/определением
                    var addedPredicate = _addPredicate(result.Sentence, adjectiveOrParticipleChildWithMaxOrder.Order - 1);

                    recoveredPredicatesHelperData.AddOrUpdateCustomRow(
                        adjectiveOrParticipleChildWithMaxOrder.GUID,
                        subjectSentenceElement.Id,
                        adjectiveOrParticipleChildWithMaxOrder.Id,
                        addedPredicate.Order,
                        addedPredicate.Id,
                        subjectSentenceElement.Id);

                    _performPostProcessing(postProcessingHelpData, addedPredicate, adjectiveOrParticipleChildWithMaxOrder,
                        subjectSentenceElement);
                }

                result.HelperDataElements.Add(recoveredPredicatesHelperData);

                result.HelperDataElements.Add(postProcessingHelpData);
            }
            else
                Log.Info("Условия для добавления сказуемого быть не выполнены");
        }
        private void _performPostProcessing(SubjectsPostProcessingHelperData hlpData, SentenceElement addedPredicate, SentenceElement adjectiveOrParticiple, SentenceElement subjectSentenceElement)
        {
            var oldSubjectSyntacticParent = subjectSentenceElement.SyntacticParentWordId;
            var oldAdjectiveOrParticipleSyntacticParent = adjectiveOrParticiple.SyntacticParentWordId;
            var oldAdjectiveOrParticipleSyntacticRole = adjectiveOrParticiple.SyntacticRole.Value;
            var oldAdjectiveOrParticipleSurfaceSlot = adjectiveOrParticiple.SurfaceSlot;

            subjectSentenceElement.SyntacticParentWordId = addedPredicate.Id;
            subjectSentenceElement.SyntacticParentWordGUID = addedPredicate.GUID;

            adjectiveOrParticiple.SyntacticParentWordId = addedPredicate.Id;
            adjectiveOrParticiple.SyntacticParentWordGUID = addedPredicate.GUID;

            adjectiveOrParticiple.SyntacticRole = SyntacticRole.Complement;
            adjectiveOrParticiple.SurfaceSlot = Consts.SurfaceSlotDefinedValues.ComplementAttributive;

            hlpData.AddOrUpdateCustomRow(
                adjectiveOrParticiple.GUID,
                oldAdjectiveOrParticipleSyntacticParent + "-->" + adjectiveOrParticiple.SyntacticParentWordId,
                oldAdjectiveOrParticipleSyntacticRole + "-->" + adjectiveOrParticiple.SyntacticRole.Value,
                oldAdjectiveOrParticipleSurfaceSlot + "-->" + adjectiveOrParticiple.SurfaceSlot
                );

            hlpData.AddOrUpdateCustomRow(
                subjectSentenceElement.GUID,
                oldSubjectSyntacticParent + "-->" + subjectSentenceElement.SyntacticParentWordId,
                string.Empty,
                string.Empty
                );
        }