internal override ReadOnlyCollection <SnapshotSpan> MapReplacementSpanToSourceSnapshots(Span replacementSpan, ITextBuffer excludedBuffer) { // This is exactly like ordinary span mapping, except that empty source spans at the ends of the replacementSpan are included. FrugalList <SnapshotSpan> mappedSpans = new FrugalList <SnapshotSpan>(); int rover = FindLowestSpanIndexOfPosition(replacementSpan.Start); int roverHi = FindHighestSpanIndexOfPosition(replacementSpan.End); // sourceSpans[rover] contains span.Start SnapshotSpan sourceSpan = this.sourceSpans[rover]; { SnapshotPoint mappedStart = sourceSpan.Start + (replacementSpan.Start - this.cumulativeLengths[rover]); int mappedLength = mappedStart.Position + replacementSpan.Length < sourceSpan.End ? replacementSpan.Length : sourceSpan.End.Position - mappedStart; SnapshotSpan mappedSpan = new SnapshotSpan(mappedStart, mappedLength); if (mappedSpan.Length > 0 || mappedSpan.Snapshot.TextBuffer != excludedBuffer) { mappedSpans.Add(new SnapshotSpan(mappedStart, mappedLength)); } } // walk forward until we cover the entire span while (rover < roverHi) { rover++; sourceSpan = this.sourceSpans[rover]; SnapshotSpan mappedSpan = replacementSpan.End >= this.cumulativeLengths[rover + 1] ? sourceSpan : new SnapshotSpan(sourceSpan.Snapshot, new Span(sourceSpan.Start, replacementSpan.End - this.cumulativeLengths[rover])); if (mappedSpan.Length > 0 || mappedSpan.Snapshot.TextBuffer != excludedBuffer) { mappedSpans.Add(mappedSpan); } } Debug.Assert(replacementSpan.Length == mappedSpans.Sum((SnapshotSpan s) => s.Length), "Inconsistency in MapReplacementSpanToSourceSnapshots"); return(new ReadOnlyCollection <SnapshotSpan>(mappedSpans)); }