public ElisionMap EditSpans(ITextSnapshot sourceSnapshot,
                                    NormalizedSpanCollection spansToElide,
                                    NormalizedSpanCollection spansToExpand,
                                    out FrugalList <TextChange> textChanges)
        {
            textChanges = new FrugalList <TextChange>();
            NormalizedSpanCollection beforeSourceSpans = new NormalizedSnapshotSpanCollection(GetSourceSpans(sourceSnapshot, 0, this.spanCount));

            NormalizedSpanCollection afterElisionSourceSpans = NormalizedSpanCollection.Difference(beforeSourceSpans, spansToElide);
            NormalizedSpanCollection elisionChangeSpans      = NormalizedSpanCollection.Difference(beforeSourceSpans, afterElisionSourceSpans);

            foreach (Span s in elisionChangeSpans)
            {
                textChanges.Add(TextChange.Create(this.root.MapFromSourceSnapshotToNearest(s.Start, 0),
                                                  BufferFactoryService.StringRebuilderFromSnapshotAndSpan(sourceSnapshot, s),
                                                  StringRebuilder.Empty,
                                                  sourceSnapshot));
            }

            NormalizedSpanCollection afterExpansionSourceSpans = NormalizedSpanCollection.Union(afterElisionSourceSpans, spansToExpand);
            NormalizedSpanCollection expansionChangeSpans      = NormalizedSpanCollection.Difference(afterExpansionSourceSpans, afterElisionSourceSpans);

            foreach (Span s in expansionChangeSpans)
            {
                textChanges.Add(TextChange.Create(this.root.MapFromSourceSnapshotToNearest(s.Start, 0),
                                                  StringRebuilder.Empty,
                                                  BufferFactoryService.StringRebuilderFromSnapshotAndSpan(sourceSnapshot, s),
                                                  sourceSnapshot));
            }

            return(textChanges.Count > 0 ? new ElisionMap(sourceSnapshot, afterExpansionSourceSpans) : this);
        }
        private void ConstructChanges()
        {
            var diffs = differ.GetDifferences();

            List <TextChange> changes = new List <TextChange>();
            int pos = this.textPosition;

            // each difference generates a text change
            foreach (Difference diff in diffs)
            {
                pos += GetMatchSize(diffs.LeftSequence, diff.Before);
                TextChange change = TextChange.Create(pos,
                                                      BufferFactoryService.StringRebuilderFromSnapshotSpans(diffs.LeftSequence, diff.Left),
                                                      BufferFactoryService.StringRebuilderFromSnapshotSpans(diffs.RightSequence, diff.Right),
                                                      this.currentSnapshot);
                changes.Add(change);
                pos += change.OldLength;
            }
            this.normalizedChanges = NormalizedTextChangeCollection.Create(changes);
        }