private MappingSpanSnapshot(ITextSnapshot root, SnapshotSpan anchor, SpanTrackingMode trackingMode, IBufferGraph graph)
        {
            //Anchor and root are expected to be from concurrent snapshots
            ITextSnapshot correspondingAnchorSnapshot = MappingHelper.FindCorrespondingSnapshot(root, anchor.Snapshot.TextBuffer);

            _root = root;
            if (correspondingAnchorSnapshot != null)
            {
                _anchor = anchor.TranslateTo(correspondingAnchorSnapshot, trackingMode);
            }
            else
            {
                _anchor     = anchor;
                _unmappable = true;
            }
            _trackingMode = trackingMode;
            _graph        = graph;
        }
        public NormalizedSnapshotSpanCollection GetSpans(Predicate <ITextBuffer> match)
        {
            if (_unmappable)
            {
                return(NormalizedSnapshotSpanCollection.Empty);
            }

            //Try mapping down first.
            FrugalList <SnapshotSpan> mappedSpans = new FrugalList <SnapshotSpan>();

            MappingHelper.MapDownToFirstMatchNoTrack(_anchor, match, mappedSpans);
            if (mappedSpans.Count == 0)
            {
                //Unable to map down ... try mapping up.
                this.MapUpToBufferNoTrack(match, mappedSpans);
            }

            return(new NormalizedSnapshotSpanCollection(mappedSpans));
        }
        public NormalizedSnapshotSpanCollection GetSpans(ITextBuffer targetBuffer)
        {
            if (targetBuffer == null)
            {
                throw new ArgumentNullException("targetBuffer");
            }

            if (_unmappable)
            {
                return(NormalizedSnapshotSpanCollection.Empty);
            }

            if (targetBuffer.Properties.ContainsProperty("IdentityMapping"))
            {
                // text buffer properties uses the hybrid dictionary, which requires TWO lookups to determine that
                // a key is not present. Since this test usually fails, do it the hard way (the second lookup shows up
                // in scrolling profiles).
                ITextBuffer doppelganger = (ITextBuffer)targetBuffer.Properties["IdentityMapping"];
                if (doppelganger == _anchor.Snapshot.TextBuffer)
                {
                    // We are mapping up from a doppelganger buffer; the coordinates will be the same. We
                    // just need to figure out the right snapshot.
                    ITextSnapshot targetSnapshot = MappingHelper.FindCorrespondingSnapshot(_root, targetBuffer);
                    return(new NormalizedSnapshotSpanCollection(new SnapshotSpan(targetSnapshot, _anchor.Span)));
                }
            }

            //Try mapping down first.
            FrugalList <SnapshotSpan> mappedSpans = new FrugalList <SnapshotSpan>();

            MappingHelper.MapDownToBufferNoTrack(_anchor, targetBuffer, mappedSpans);
            if (mappedSpans.Count == 0)
            {
                //Unable to map down ... try mapping up.
                this.MapUpToBufferNoTrack(targetBuffer, mappedSpans);
            }

            return(new NormalizedSnapshotSpanCollection(mappedSpans));
        }
        public SnapshotPoint?GetPoint(Predicate <ITextBuffer> match, PositionAffinity affinity)
        {
            if (match == null)
            {
                throw new ArgumentNullException(nameof(match));
            }
            if (_unmappable)
            {
                return(null);
            }

            //Try mapping down first.
            SnapshotPoint?mappedPoint = MappingHelper.MapDownToFirstMatchNoTrack(_anchor, match, affinity);

            if (!mappedPoint.HasValue)
            {
                //Unable to map down ... try mapping up.
                return(this.MapUpToFirstMatchNoTrack(match, affinity));
            }

            return(mappedPoint);
        }
        public SnapshotPoint?GetPoint(ITextBuffer targetBuffer, PositionAffinity affinity)
        {
            if (targetBuffer == null)
            {
                throw new ArgumentNullException(nameof(targetBuffer));
            }
            if (_unmappable)
            {
                return(null);
            }

            //Try mapping down first.
            SnapshotPoint?mappedPoint = MappingHelper.MapDownToBufferNoTrack(_anchor, targetBuffer, affinity);

            if (!mappedPoint.HasValue)
            {
                //Unable to map down ... try mapping up.
                return(this.MapUpToBufferNoTrack(targetBuffer, affinity));
            }

            return(mappedPoint);
        }