public async Task ProcessAsync(int documentId, DocumentParseResult documentResult, CancellationToken cancellationToken = default)
        {
            var linearResult   = LinearParseResult.FromHierarchyParseResult(documentResult.RootHierarchyResult);
            var verseRelations = ProcessLinearResult(linearResult);

            await this.analyticsContext.DoInTransactionAsync(async (token) =>
            {
                this.analyticsContext.VerseRelationRepository.AddRange(verseRelations);
                await this.analyticsContext.SaveChangesAsync(token);
                return(true);
            }, cancellationToken);
        }
        private IEnumerable <VerseRelation> ProcessLinearResult(LinearParseResult linearResult)
        {
            var verseRelations = new List <VerseRelation>();

            foreach (var paragraph in linearResult.Paragraphs)
            {
                var paragraphNode = linearResult.Paragraphs.Find(paragraph);

                var paragraphVerseRelations = FindParagraphVerseRelations(paragraphNode);

                for (var currentVerseIndex = 0; currentVerseIndex < paragraph.ParagraphResult.VerseEntries.Count; currentVerseIndex++)
                {
                    var verseEntry = paragraphNode.Value.ParagraphResult.VerseEntries[currentVerseIndex];

                    verseRelations.AddRange(ProcessVerseEntryInsideParagraph(verseEntry, currentVerseIndex, paragraphNode));
                    verseRelations.AddRange(ProcessVerseEntryInsideAllDocument(verseEntry, paragraphNode, paragraphVerseRelations));
                }
            }

            return(verseRelations);
        }