//------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal Methods

        // returns the range that is visible in the RichEdit window
        internal ITextRange GetVisibleRange()
        {
            // get a range from the center point of the client rectangle
            Rect       rect  = BoundingRectangle;
            int        x     = ((int)rect.Left + (int)rect.Right) / 2;
            int        y     = ((int)rect.Top + (int)rect.Bottom) / 2;
            ITextRange range = _document.RangeFromPoint(x, y);

            // expand it to fill the window.
            range.Expand(TomUnit.tomWindow);

            // There is a bug with RichEdit 3.0.  The expand to tomWindow may gets 0 as the range's cpBegin (Start).
            // So need to trim off what is outside of the window.
            int start = range.Start;

            // The ITextRange::SetRange method sets this range's Start = min(cp1, cp2) and End = max(cp1, cp2).
            // If the range is a nondegenerate selection, cp2 is the active end; if it's a degenerate selection,
            // the ambiguous cp is displayed at the start of the line (rather than at the end of the previous line).
            // Set the end to the start and the start to the end to create an ambiguous cp.
            range.SetRange(range.End, range.Start);
            bool gotPoint = WindowsRichEditRange.RangeGetPoint(range, TomGetPoint.tomStart, out x, out y);

            while (!gotPoint || !Misc.PtInRect(ref rect, x, y))
            {
                range.MoveStart(TomUnit.tomWord, 1);
                gotPoint = WindowsRichEditRange.RangeGetPoint(range, TomGetPoint.tomStart, out x, out y);
            }

            if (start != range.Start)
            {
                // The trimming was done based on the left edge of the range.  The last visiable partial
                // character/word has been also added back into the range, need to remove it.  Do the comparing
                // against the characters right edge and the window rectangle.
                ITextRange rangeAdjust = _document.Range(0, range.Start - 1);
                gotPoint = WindowsRichEditRange.RangeGetPoint(rangeAdjust, TomGetPoint.TA_BOTTOM | TomGetPoint.TA_RIGHT, out x, out y);

                while (gotPoint && Misc.PtInRect(ref rect, x, y) && rangeAdjust.Start != rangeAdjust.End)
                {
                    rangeAdjust.MoveEnd(TomUnit.tomCharacter, -1);
                    range.MoveStart(TomUnit.tomCharacter, -1);
                    gotPoint = WindowsRichEditRange.RangeGetPoint(rangeAdjust, TomGetPoint.TA_BOTTOM | TomGetPoint.TA_RIGHT, out x, out y);
                }
            }

            // There is a bug with RichEdit 3.0.  The expand to tomWindow gets the last cp of the bottom
            // line in the window as the range's cpLim (End).  The cpLim may be passed the right side of
            // the window.
            // So need to trim off what is on the right side of the window.
            int end = range.End;

            gotPoint = WindowsRichEditRange.RangeGetPoint(range, TomGetPoint.TA_RIGHT, out x, out y);
            while (!gotPoint || !Misc.PtInRect(ref rect, x, y))
            {
                range.MoveEnd(TomUnit.tomWord, -1);
                gotPoint = WindowsRichEditRange.RangeGetPoint(range, TomGetPoint.TA_RIGHT, out x, out y);
            }

            if (end != range.End)
            {
                // The trimming was done based on the right edge of the range.  The last visiable partial
                // character/word has been also trimmed so add it back to the range.  Do the comparing
                // against the characters left edge and the window rectangle.
                ITextRange rangeAdjust = _document.Range(range.End, end);
                do
                {
                    if (range.MoveEnd(TomUnit.tomCharacter, 1) == 0)
                    {
                        break;
                    }
                    rangeAdjust.MoveStart(TomUnit.tomCharacter, 1);
                    gotPoint = WindowsRichEditRange.RangeGetPoint(rangeAdjust, TomGetPoint.tomStart, out x, out y);
                } while (gotPoint && Misc.PtInRect(ref rect, x, y));
            }

            return(range);
        }