ITextRangeProvider [] ITextProvider.GetSelection()
        {
            // we must have called EnsureTextDocument() before arriving here.
            Debug.Assert(_document != null);

            // clone a range from the documents selection
            ITextRange     range     = null;
            ITextSelection selection = _document.Selection;

            if (selection != null)
            {
                // duplicate the selection range since we don't want their modifications to affect the selection
                range = selection.GetDuplicate();

                // for future reference: active endpoint is
                // ((selection.Flags & TomSelectionFlags.tomSelStartActive) == TomSelectionFlags.tomSelStartActive) ? TextPatternRangeEndpoint.Start : TextPatternRangeEndpoint.End;
            }

            if (range == null)
            {
                return new ITextRangeProvider[] { }
            }
            ;
            else
            {
                return new ITextRangeProvider[] { new WindowsRichEditRange(range, this) }
            };
        }

        ITextRangeProvider [] ITextProvider.GetVisibleRanges()
        {
            ITextRange range = GetVisibleRange();

            if (range == null)
            {
                return new ITextRangeProvider[] { }
            }
            ;
            else
            {
                return new ITextRangeProvider[] { new WindowsRichEditRange(range, this) }
            };
        }

        ITextRangeProvider ITextProvider.RangeFromChild(IRawElementProviderSimple childElement)
        {
            // we don't have any children so this call must be in error.
            // if we implement children for hyperlinks and embedded objects then we'll need to change this.
            throw new InvalidOperationException(SR.Get(SRID.RichEditTextPatternHasNoChildren, GetType().FullName));
        }

        ITextRangeProvider ITextProvider.RangeFromPoint(Point screenLocation)
        {
            // we must have called EnsureTextDocument() before arriving here.
            Debug.Assert(_document != null);

            // TextPattern has verified that the point is inside our client area so we don't need to check for that.

            // get the degenerate range at the point
            // we're assuming ITextDocument::RangeFromPoint always returns a degenerate range
            ITextRange range = _document.RangeFromPoint((int)screenLocation.X, (int)screenLocation.Y);

            Debug.Assert(range.Start == range.End);

            // if you wanted to get the character under the point instead of the degenerate range nearest
            // the point, then you would add:

            //// if the point is within the character to the right then expand the degenerate range to
            //// include the character.
            //Rect rect;
            //range.MoveEnd(TomUnit.tomCharacter, 1);
            //rect = WindowsRichEditRange.GetSingleLineRangeRectangle(range, BoundingRectangle);
            //if (!rect.Contains(screenLocation))
            //{
            //    // if the point is within the character to the left then expand the degenerate range
            //    // to include the character.
            //    range.Collapse(TomStartEnd.tomStart);
            //    range.MoveStart(TomUnit.tomCharacter, -1);
            //    rect = WindowsRichEditRange.GetSingleLineRangeRectangle(range, BoundingRectangle);
            //    if (!rect.Contains(screenLocation))
            //    {
            //        // the point is not in an adjacent character cell so leave it degenerate.
            //        range.Collapse(TomStartEnd.tomEnd);
            //    }
            //}

            return(range != null ? new WindowsRichEditRange(range, this) : null);
        }

        #endregion TextPattern Methods

        #region TextPattern Properties

        ITextRangeProvider ITextProvider.DocumentRange
        {
            get
            {
                // we must have called EnsureTextDocument() before arriving here.
                Debug.Assert(_document != null);

                // create a text range that covers the entire main story.
                ITextRange range = _document.Range(0, 0);
                range.SetRange(0, range.StoryLength);
                return(new WindowsRichEditRange(range, this));
            }
        }


        SupportedTextSelection ITextProvider.SupportedTextSelection
        {
            get
            {
                return(SupportedTextSelection.Single);
            }
        }