private static void PrepareRowSelector( RowSelectorDecorator decorator, DependencyObject container, Rect containerRect, FrameworkElement referenceElement )
    {
      Debug.Assert( decorator != null );

      DataGridControl.SetContainer( decorator, container );

      var rowSelector = decorator.RowSelector;
      if( rowSelector != null )
      {
        rowSelector.ReferenceElement = referenceElement;
        rowSelector.ContainerRect = containerRect;
      }
    }
    private static void ClearRowSelector( RowSelectorDecorator decorator )
    {
      Debug.Assert( decorator != null );

      DataGridControl.ClearContainer( decorator );

      var rowSelector = decorator.RowSelector;
      if( rowSelector != null )
      {
        rowSelector.ReferenceElement = null;
        rowSelector.ContainerRect = RowSelectorPane.EmptyRect;
      }
    }
    private RowSelectorDecorator RecycleOrCreateRowSelector( DependencyObject container )
    {
      RowSelectorDecorator decorator;

      // Try to re-use a RowSelector that is schedule to be clean up.
      if( m_pendingCleanup.Count > 0 )
      {
        int index = m_pendingCleanup.Count - 1;

        for( int i = index; i >= 0; i-- )
        {
          decorator = m_pendingCleanup[ i ];
          if( DataGridControl.GetContainer( decorator ) == container )
          {
            index = i;
            break;
          }
        }

        decorator = m_pendingCleanup[ index ];
        m_pendingCleanup.RemoveAt( index );
      }
      // Try to recycle a RowSelector from the recycling pool.
      else if( m_recyclingQueue.Count > 0 )
      {
        decorator = m_recyclingQueue.Dequeue();
      }
      else
      {
        decorator = new RowSelectorDecorator();

        this.InternalChildren.Add( decorator );
      }

      return decorator;
    }
    private bool IsRowSelectorVisible( RowSelectorDecorator decorator )
    {
      Debug.Assert( decorator != null );
      if( decorator.RowSelector == null )
        return false;

      var container = DataGridControl.GetContainer( decorator );
      if( container == null )
        return false;

      return m_visibleSelectors.ContainsKey( container );
    }
    private Geometry GetClipRegion( RowSelectorDecorator decorator, Rect arrangeRect, FrameworkElement referenceElement )
    {
      if( referenceElement == null )
        return null;

      var rowSelector = decorator.RowSelector;
      if( rowSelector == null )
        return null;

      GeneralTransform referenceElementToRowSelectorPaneTransform = referenceElement.TransformToVisual( this );
      Rect referenceElementRegion = referenceElementToRowSelectorPaneTransform.TransformBounds( new Rect( 0, 0, referenceElement.ActualWidth, referenceElement.ActualHeight ) );
      RectangleGeometry clipRegion = null;

      if( this.Orientation == Orientation.Vertical )
      {
        UIElement container = rowSelector.DataContext as UIElement;

        if( ( container != null ) && ( container.Clip != null ) )
        {
          Rect containerClipBounds = container.Clip.Bounds;

          // In this case, we will use the container's clip properties (Top and Bottom).
          clipRegion = new RectangleGeometry( new Rect( 0d, containerClipBounds.Y, arrangeRect.Width, containerClipBounds.Height ) );
        }
        else if( ( arrangeRect.Top < referenceElementRegion.Top ) || ( arrangeRect.Bottom > referenceElementRegion.Bottom ) )
        {
          double x = 0d;
          double y = Math.Max( referenceElementRegion.Top - arrangeRect.Top, 0 );

          double width = arrangeRect.Width;
          double height = Math.Max( 0, arrangeRect.Height - y - Math.Max( 0, arrangeRect.Bottom - referenceElementRegion.Bottom ) );

          clipRegion = new RectangleGeometry( new Rect( x, y, width, height ) );
        }
      }
      else
      {
        UIElement container = rowSelector.DataContext as UIElement;

        if( ( container != null ) && ( container.Clip != null ) )
        {
          Rect containerClipBounds = container.Clip.Bounds;

          // In this case, we will use the container's clip properties (Left and Right).
          clipRegion = new RectangleGeometry( new Rect( containerClipBounds.X, 0d, containerClipBounds.Width, arrangeRect.Height ) );
        }
        else if( ( arrangeRect.Left < referenceElementRegion.Left ) || ( arrangeRect.Right > referenceElementRegion.Right ) )
        {
          double x = Math.Max( referenceElementRegion.Left - arrangeRect.Left, 0 );
          double y = 0d;

          double width = arrangeRect.Width - x - Math.Max( 0, arrangeRect.Right - referenceElementRegion.Right );
          double height = arrangeRect.Height;

          clipRegion = new RectangleGeometry( new Rect( x, y, width, height ) );
        }
      }

      return clipRegion;
    }
    private Size GetAvailableSize( RowSelectorDecorator decorator, Size availableSize )
    {
      var rowSelector = decorator.RowSelector;
      if( rowSelector == null )
        return RowSelectorPane.EmptySize;

      var containerRect = rowSelector.ContainerRect;

      if( this.Orientation == Orientation.Vertical )
        return new Size( availableSize.Width, containerRect.Height );

      return new Size( containerRect.Width, availableSize.Height );
    }
    private Rect GetArrangeRect( RowSelectorDecorator decorator, Size finalSize )
    {
      var rowSelector = decorator.RowSelector;
      if( rowSelector == null )
        return RowSelectorPane.EmptyRect;

      var container = rowSelector.DataContext as FrameworkElement;
      Debug.Assert( container != null );

      var coordinatesTransform = container.TransformToVisual( this );
      var origin = coordinatesTransform.Transform( RowSelectorPane.OriginPoint );

      if( this.Orientation == Orientation.Vertical )
        return new Rect( 0, origin.Y, finalSize.Width, container.ActualHeight );

      return new Rect( origin.X, 0, container.ActualWidth, finalSize.Height );
    }