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

        #region Internal Methods

        // Static implementation for the bounding rectangle. This is used by
        // ElementProviderFromPoint to avoid to have to create for a simple
        // boundary check
        // param "item", ID for the scrollbar bit
        // param "sbFlag", SBS_ WindowLong equivallent flag
        static internal Rect GetBoundingRectangle(IntPtr hwnd, ProxyFragment parent, WindowsScrollBar.ScrollBarItem item, int sbFlag)
        {
            NativeMethods.ScrollInfo si = new NativeMethods.ScrollInfo();
            si.cbSize = Marshal.SizeOf(si.GetType());
            si.fMask  = NativeMethods.SIF_RANGE;

            // If the scroll bar is disabled, we cannot have a thumb and large Increment/Decrement)
            bool fDisableScrollBar = !WindowsScrollBar.IsScrollBarWithThumb(hwnd, sbFlag);

            if (fDisableScrollBar && (item == WindowsScrollBar.ScrollBarItem.LargeDecrement || item == WindowsScrollBar.ScrollBarItem.Thumb || item == WindowsScrollBar.ScrollBarItem.LargeDecrement))
            {
                return(Rect.Empty);
            }

            // If fails assume that the hwnd is invalid
            if (!Misc.GetScrollInfo(hwnd, sbFlag, ref si))
            {
                return(Rect.Empty);
            }

            int idObject = sbFlag == NativeMethods.SB_VERT ? NativeMethods.OBJID_VSCROLL : sbFlag == NativeMethods.SB_HORZ ? NativeMethods.OBJID_HSCROLL : NativeMethods.OBJID_CLIENT;

            NativeMethods.ScrollBarInfo sbi = new NativeMethods.ScrollBarInfo();
            sbi.cbSize = Marshal.SizeOf(sbi.GetType());

            if (!Misc.GetScrollBarInfo(hwnd, idObject, ref sbi))
            {
                return(Rect.Empty);
            }

            if (parent != null && parent._parent != null)
            {
                //
                // Builds prior to Vista 5359 failed to correctly account for RTL scrollbar layouts.
                //
                if ((Environment.OSVersion.Version.Major < 6) && (Misc.IsLayoutRTL(parent._parent._hwnd)))
                {
                    // Right to left mirroring style
                    Rect rcParent = parent._parent.BoundingRectangle;
                    int  width    = sbi.rcScrollBar.right - sbi.rcScrollBar.left;

                    if (sbFlag == NativeMethods.SB_VERT)
                    {
                        int offset = (int)rcParent.Right - sbi.rcScrollBar.right;
                        sbi.rcScrollBar.left  = (int)rcParent.Left + offset;
                        sbi.rcScrollBar.right = sbi.rcScrollBar.left + width;
                    }
                    else
                    {
                        int offset = sbi.rcScrollBar.left - (int)rcParent.Left;
                        sbi.rcScrollBar.right = (int)rcParent.Right - offset;
                        sbi.rcScrollBar.left  = sbi.rcScrollBar.right - width;
                    }
                }
            }

            // When the scroll bar is for a listbox within a combo and it is hidden, then
            // GetScrollBarInfo returns true but the rectangle is boggus!
            // 32 bits * 32 bits > 64 values
            //
            // Note that this test must come after the rectangle has been normalized for RTL or it will fail
            //
            long area = (sbi.rcScrollBar.right - sbi.rcScrollBar.left) * (sbi.rcScrollBar.bottom - sbi.rcScrollBar.top);

            if (area <= 0 || area > 1000 * 1000)
            {
                // Ridiculous value assume error
                return(Rect.Empty);
            }

            if (WindowsScrollBar.IsScrollBarVertical(hwnd, sbFlag))
            {
                return(GetVerticalScrollbarBitBoundingRectangle(hwnd, item, sbi));
            }
            else
            {
                return(GetHorizontalScrollbarBitBoundingRectangle(hwnd, item, sbi));
            }
        }