/// <summary>
        /// Outlines comments that define sections such as
        /// # NAME ---
        /// </summary>
        /// <returns>True if names changed and outline regions need to be rebuilt</returns>
        private void OutlineSections(AstRoot ast, OutliningContext context)
        {
            // Collect comments that define sections
            var snapshot = EditorTree.TextSnapshot;
            var sections = ast.Comments.Where(c => {
                var text = snapshot.GetText(new Span(c.Start, c.Length));
                // Section looks like # [NAME] --------
                return(text.TrimEnd().EndsWithOrdinal("---") && text.IndexOfAny(CharExtensions.LineBreakChars) < 0);
            }).ToArray();

            // Construct collapsible regions
            var ranges = new List <ITextRange>();

            for (int i = 0; i < sections.Length; i++)
            {
                var startLine = snapshot.GetLineFromPosition(sections[i].Start);
                int end       = -1;

                var text        = snapshot.GetText(new Span(sections[i].Start, sections[i].Length));
                var displayText = text.Substring(0, text.IndexOfOrdinal("---")).Trim();

                if (i < sections.Length - 1)
                {
                    var endLineNumber = snapshot.GetLineNumberFromPosition(sections[i + 1].Start);
                    if (endLineNumber > startLine.LineNumber)
                    {
                        end = snapshot.GetLineFromLineNumber(endLineNumber - 1).End;
                    }
                }
                else
                {
                    end = snapshot.Length;
                }

                if (end > startLine.Start)
                {
                    ranges.Add(sections[i]);

                    // Trim trailing whitespace in user-defined regions
                    var range = TextRange.FromBounds(startLine.Start, end);
                    text = snapshot.GetText(new Span(range.Start, range.Length));
                    var trimBy = text.Length - text.TrimEnd().Length;
                    range = TextRange.FromBounds(range.Start, range.End - trimBy);

                    context.Regions.Add(new ROutlineRegion(EditorDocument.TextBuffer, range, displayText));
                }
            }

            // Track changes in section names
            _forceRegionsChange = _sections != null && _sections.Changed;

            _sections?.Dispose();
            _sections = new RSectionsCollection(EditorTree, ranges);
        }
        /// <summary>
        /// Outlines comments that define sections such as
        /// # NAME ---
        /// </summary>
        /// <returns>True if names changed and outline regions need to be rebuilt</returns>
        private void OutlineSections(AstRoot ast, OutliningContext context) {
            // Collect comments that define sections
            var snapshot = EditorTree.TextSnapshot;
            var sections = ast.Comments.Where(c => {
                var text = snapshot.GetText(new Span(c.Start, c.Length));
                // Section looks like # [NAME] --------
                return text.TrimEnd().EndsWithOrdinal("---") && text.IndexOfAny(CharExtensions.LineBreakChars) < 0;
            }).ToArray();

            // Construct collapsible regions
            var ranges = new List<ITextRange>();
            for (int i = 0; i < sections.Length; i++) {
                var startLine = snapshot.GetLineFromPosition(sections[i].Start);
                int end = -1;

                var text = snapshot.GetText(new Span(sections[i].Start, sections[i].Length));
                var displayText = text.Substring(0, text.IndexOfOrdinal("---")).Trim();

                if (i < sections.Length - 1) {
                    var endLineNumber = snapshot.GetLineNumberFromPosition(sections[i + 1].Start);
                    if (endLineNumber > startLine.LineNumber) {
                        end = snapshot.GetLineFromLineNumber(endLineNumber - 1).End;
                    }
                } else {
                    end = snapshot.Length;
                }

                if (end > startLine.Start) {
                    ranges.Add(sections[i]);

                    // Trim trailing whitespace in user-defined regions
                    var range = TextRange.FromBounds(startLine.Start, end);
                    text = snapshot.GetText(new Span(range.Start, range.Length));
                    var trimBy = text.Length - text.TrimEnd().Length;
                    range = TextRange.FromBounds(range.Start, range.End - trimBy);

                    context.Regions.Add(new ROutlineRegion(EditorDocument.TextBuffer, range, displayText));
                }
            }

            // Track changes in section names
            _forceRegionsChange = _sections != null && _sections.Changed;

            _sections?.Dispose();
            _sections = new RSectionsCollection(EditorTree, ranges);
        }