File: winforms\Managed\System\WinForms\ToolStripPanelRow.cs
Project: ndp\fx\src\System.Windows.Forms.csproj (System.Windows.Forms)
//#define DEBUG_PAINT
//------------------------------------------------------------------------------
// <copyright file="ToolStripPanelRow.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>                                                                
//------------------------------------------------------------------------------
/*
*/
namespace System.Windows.Forms {
    using System.Drawing;
    using System.Windows.Forms.Layout;
    using System.Collections.Specialized;
    using System.Collections;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
 
    /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow"]/*' />
    [ToolboxItem(false)]
    public class ToolStripPanelRow : Component, IArrangedElement {
        private Rectangle bounds = Rectangle.Empty;
        private ToolStripPanel parent = null;
        private BitVector32 state = new BitVector32();
        private PropertyStore propertyStore = new PropertyStore();  // Contains all properties that are not always set.
        private int suspendCount = 0;
        private ToolStripPanelRowManager rowManager = null;
 
 
        private const int MINALLOWEDWIDTH = 50;
        private int minAllowedWidth = MINALLOWEDWIDTH;
 
        private static readonly int stateVisible = BitVector32.CreateMask();
        private static readonly int stateDisposing = BitVector32.CreateMask(stateVisible);
        private static readonly int stateLocked = BitVector32.CreateMask(stateDisposing);
        private static readonly int stateInitialized = BitVector32.CreateMask(stateLocked);
        private static readonly int stateCachedBoundsMode = BitVector32.CreateMask(stateInitialized);
        private static readonly int stateInLayout = BitVector32.CreateMask(stateCachedBoundsMode);
        
        
        
              
 
        private static readonly int PropControlsCollection = PropertyStore.CreateKey();
        
#if DEBUG
        internal static TraceSwitch ToolStripPanelRowCreationDebug = new TraceSwitch("ToolStripPanelRowCreationDebug", "Debug code for rafting row creation");
#else
        internal static TraceSwitch ToolStripPanelRowCreationDebug ;
#endif
 
#if DEBUG
        private static int rowCreationCount = 0;
        private int thisRowID;
#endif
 
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.ToolStripPanelRow"]/*' />
        public ToolStripPanelRow(ToolStripPanel parent) : this(parent, true){
        }
 
 
        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        internal ToolStripPanelRow(ToolStripPanel parent, bool visible) {
#if DEBUG
            thisRowID = ++rowCreationCount;
#endif            
            if (DpiHelper.EnableToolStripHighDpiImprovements) {
                minAllowedWidth = DpiHelper.LogicalToDeviceUnitsX(MINALLOWEDWIDTH);
            }
 
            this.parent = parent;
            this.state[stateVisible] = visible;
            this.state[stateDisposing | stateLocked| stateInitialized] = false;
 
            Debug.WriteLineIf(ToolStripPanelRowCreationDebug.TraceVerbose, "Created new ToolStripPanelRow");
 
            using (LayoutTransaction lt = new LayoutTransaction(parent, this, null)) {
                this.Margin = DefaultMargin;
                CommonProperties.SetAutoSize(this, true);
            }
            
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.Bounds"]/*' />
        public Rectangle Bounds {
            get {
                return bounds;
            }
        }
        
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), SRDescription(SR.ControlControlsDescr), SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
        public Control[] Controls {
            get {
                Control[] controls = new Control[ControlsInternal.Count];
                ControlsInternal.CopyTo(controls,0);
                return controls;
            }
        }
 
            
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.Controls"]/*' />
        /// <devdoc>
        /// Collection of child controls.
        /// </devdoc>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), SRDescription(SR.ControlControlsDescr)]
        internal ToolStripPanelRowControlCollection ControlsInternal {
            get {
                ToolStripPanelRowControlCollection controlsCollection = (ToolStripPanelRowControlCollection)Properties.GetObject(PropControlsCollection);
 
                if (controlsCollection == null) {
                    controlsCollection = CreateControlsInstance();
                    Properties.SetObject(PropControlsCollection, controlsCollection);
                }
 
                return controlsCollection;
            }
        }
 
        internal ArrangedElementCollection Cells {
            get { 
                return ControlsInternal.Cells;
            }
        }
 
        internal bool CachedBoundsMode {
            get {
                return state[stateCachedBoundsMode];
            }
            set {
                state[stateCachedBoundsMode] = value;
            }
        }
 
 
 
        private ToolStripPanelRowManager RowManager {
            get {
                if (rowManager == null) {
                    rowManager = (Orientation == Orientation.Horizontal) ? new HorizontalRowManager(this) as ToolStripPanelRowManager 
                                                                         : new VerticalRowManager(this) as ToolStripPanelRowManager;
                    Initialized = true;
                }
 
                return rowManager;
            }
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.DefaultMargin"]/*' />
        protected virtual Padding DefaultMargin {
            get { 
                ToolStripPanelCell cell = RowManager.GetNextVisibleCell(0, /*forward*/true);
                if (cell != null && cell.DraggedControl != null) {
                    if (cell.DraggedControl.Stretch) {
                        Padding padding = ToolStripPanel.RowMargin;
                        // clear out the padding.
                        if (Orientation == Orientation.Horizontal) {
                            padding.Left = 0;
                            padding.Right = 0;
                        }
                        else {
                            padding.Top = 0;
                            padding.Bottom = 0;
                        }
                        return padding;
                    }
                }
                return ToolStripPanel.RowMargin; 
 
            }
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.DefaultPadding"]/*' />
        protected virtual Padding DefaultPadding {
            get { return Padding.Empty; }
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.DisplayRectangle"]/*' />
        public Rectangle DisplayRectangle {
            get {
                return RowManager.DisplayRectangle;
            }
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.LayoutEngine"]/*' />
        public LayoutEngine LayoutEngine {
            get {
                return FlowLayout.Instance;
            }
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.Locked"]/*' />
        internal bool Locked {
            get {
                return state[stateLocked];
            }           
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.Initialized "]/*' />
        private bool Initialized {
            get {
                return state[stateInitialized];
            }
            set {
                state[stateInitialized] = value;
            }
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.Margin"]/*' />
        public Padding Margin {
            get { return CommonProperties.GetMargin(this); }
            set { if (Margin != value ) CommonProperties.SetMargin(this, value); }
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.Padding"]/*' />
        public virtual Padding Padding {
            get { return CommonProperties.GetPadding(this, DefaultPadding); }
            set {
                if (Padding != value) CommonProperties.SetPadding(this, value);
            }
        }
 
        internal Control ParentInternal {
            get {
                return parent;
            }         
        }
 
        /// <devdoc>
        ///     Retrieves our internal property storage object. If you have a property
        ///     whose value is not always set, you should store it in here to save
        ///     space.
        /// </devdoc>
        internal PropertyStore Properties {
            get {
                return propertyStore;
            }
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.ToolStripPanel"]/*' />
        public ToolStripPanel ToolStripPanel {
            get {
                return parent;
            }
        }
 
        internal bool Visible {
            get {
                return state[stateVisible];
                }       
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.Orientation"]/*' />
        public Orientation Orientation {
            get {
                return ToolStripPanel.Orientation;
            }
        }
 
#if DEBUG
        internal void Debug_PrintRowID() {
            Debug.Write(thisRowID.ToString(CultureInfo.CurrentCulture));
        }
#endif
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.CanMove"]/*' />
        /// <devdoc>
        /// returns true if there is enough space to "raft" the control
        /// ow returns false
        /// </devdoc>
        public bool CanMove(ToolStrip toolStripToDrag) {
            return !ToolStripPanel.Locked && !Locked && RowManager.CanMove(toolStripToDrag);
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.CreateControlsInstance"]/*' />
        private ToolStripPanelRowControlCollection CreateControlsInstance() {
            return new ToolStripPanelRowControlCollection(this);
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.Dispose"]/*' />
        protected override void Dispose(bool disposing) {
            try {
                if (disposing) {
                    
                    Debug.WriteLineIf(ToolStripPanelRowCreationDebug.TraceVerbose, "Disposed ToolStripPanelRow");
                    state[stateDisposing] = true;
                    this.ControlsInternal.Clear();
                }
            }
            finally {
                state[stateDisposing] = false;
                base.Dispose(disposing);
            }
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.OnControlAdded"]/*' />
        protected internal virtual void OnControlAdded(Control control, int index) {
 
        
            // if previously added - remove.
            ISupportToolStripPanel controlToBeDragged = control as ISupportToolStripPanel;
            
            if (controlToBeDragged != null) {
                controlToBeDragged.ToolStripPanelRow = this;
            }
            RowManager.OnControlAdded(control, index);
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.OnOrientationChanged"]/*' />
        protected internal virtual void OnOrientationChanged() {
            this.rowManager = null;
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.OnBoundsChanged"]/*' />
        protected void OnBoundsChanged(Rectangle oldBounds, Rectangle newBounds) {
            ((IArrangedElement)this).PerformLayout((IArrangedElement)this, PropertyNames.Size);
 
            RowManager.OnBoundsChanged(oldBounds,newBounds);
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.OnControlRemoved"]/*' />
        protected internal virtual void OnControlRemoved(Control control, int index) {
            if (!state[stateDisposing]) {
                this.SuspendLayout();
                RowManager.OnControlRemoved(control, index);
 
                // if previously added - remove.
                ISupportToolStripPanel controlToBeDragged = control as ISupportToolStripPanel;
 
				if (controlToBeDragged != null && controlToBeDragged.ToolStripPanelRow  == this) {
                    controlToBeDragged.ToolStripPanelRow = null;
                }
 
                this.ResumeLayout(true);
                if (this.ControlsInternal.Count <= 0) {
                    ToolStripPanel.RowsInternal.Remove(this);
                    Dispose();
                }
            }
        }
 
        internal Size GetMinimumSize(ToolStrip toolStrip) {
            if (toolStrip.MinimumSize == Size.Empty) {
                return new Size(minAllowedWidth,minAllowedWidth);
            }
            else {
                return toolStrip.MinimumSize;
            }
        }
 
        private void ApplyCachedBounds() {
            for (int i = 0; i < this.Cells.Count; i++) {
                IArrangedElement element = Cells[i] as IArrangedElement;
                if (element.ParticipatesInLayout) {
                    ToolStripPanelCell cell = element as ToolStripPanelCell;
                    element.SetBounds(cell.CachedBounds, BoundsSpecified.None);
//                    Debug.Assert( cell.Control == null || cell.CachedBounds.Location == cell.Control.Bounds.Location, "CachedBounds out of sync with bounds!");
                }           
            }
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.OnLayout"]/*' />
        protected virtual void OnLayout(LayoutEventArgs e) {
            if (Initialized && !state[stateInLayout]) {
             state[stateInLayout] = true;
             try {
                    this.Margin = DefaultMargin;
                    CachedBoundsMode = true;
                    try {
                        // dont layout in the constructor that's just tacky.
                        bool parentNeedsLayout = LayoutEngine.Layout(this, e);
                    }
                    finally {
                        CachedBoundsMode = false;
                    }
 
                    ToolStripPanelCell cell = RowManager.GetNextVisibleCell(this.Cells.Count -1, /*forward*/false);
                    if (cell == null) {
                        ApplyCachedBounds();
                    }
                    else if (Orientation == Orientation.Horizontal) {
                        OnLayoutHorizontalPostFix();
                    }
                    else {
                        OnLayoutVerticalPostFix();
                    }
               
                }
                 finally {
                    state[stateInLayout] = false;
                }
            }
        }
 
     
        
        private void OnLayoutHorizontalPostFix() {
 
            ToolStripPanelCell cell = RowManager.GetNextVisibleCell(this.Cells.Count -1, /*forward*/false);
            if (cell == null) {
                ApplyCachedBounds();
                return;
            }
            // figure out how much space we actually need to free.
            int spaceToFree = cell.CachedBounds.Right - RowManager.DisplayRectangle.Right;
            
            if (spaceToFree <= 0) {
                // we're all good. Just apply the cached bounds.
                ApplyCachedBounds();
                return;
            }
            // STEP 1 remove empty space in the row.
 
            // since layout sisuspended, we'll need to watch changes to the margin 
            // as a result of calling FreeSpaceFromRow.
            int[] margins = new int[Cells.Count];
            for (int i = 0; i < Cells.Count; i++) {
                ToolStripPanelCell c = Cells[i] as ToolStripPanelCell;
                margins[i] = c.Margin.Left;
            }
 
            spaceToFree -= RowManager.FreeSpaceFromRow(spaceToFree);
 
            // now apply those changes to the cached bounds.
            for (int i = 0; i < Cells.Count; i++) {
                ToolStripPanelCell c = Cells[i] as ToolStripPanelCell;
                Rectangle cachedBounds = c.CachedBounds;
                cachedBounds.X -= Math.Max(0, margins[i] - c.Margin.Left);
                c.CachedBounds = cachedBounds;
            }
            
            if (spaceToFree <= 0) {
                ApplyCachedBounds();
                return;
            }
 
            
            
            // STEP 2 change the size of the remaing ToolStrips from Right to Left.
            int[] cellOffsets = null;                        
            for (int i = Cells.Count-1; i >= 0; i--) {
                ToolStripPanelCell currentCell =Cells[i] as ToolStripPanelCell;
                if (currentCell.Visible) {
                    Size minSize = GetMinimumSize(currentCell.Control as ToolStrip);
                    Rectangle cachedBounds = currentCell.CachedBounds;
 
                    // found some space to free.
                    if (cachedBounds.Width > minSize.Width) {
                        spaceToFree -= (cachedBounds.Width - minSize.Width);
                        // make sure we dont take more space than we need - if spaceToFree is less than 0, add back in.
                        cachedBounds.Width =  (spaceToFree < 0) ? minSize.Width + -spaceToFree : minSize.Width;
 
                        // we're not reperforming a layout, so we need to adjust the next cell
                        for (int j = i+1; j < Cells.Count; j++) {
                            if (cellOffsets == null) {
                                cellOffsets = new int[Cells.Count];
                            }
                            cellOffsets[j] += Math.Max(0,currentCell.CachedBounds.Width-cachedBounds.Width);
                        }
                        currentCell.CachedBounds = cachedBounds;
                    }
                }
                if (spaceToFree <= 0) {
                    break;
                }
            }
 
            // fixup for items before it shrinking.
            if (cellOffsets != null) {
                for (int i = 0; i < Cells.Count; i++) {
                   ToolStripPanelCell c = Cells[i] as ToolStripPanelCell;
                   Rectangle cachedBounds = c.CachedBounds;
                   cachedBounds.X -= cellOffsets[i];
                   c.CachedBounds = cachedBounds;
               }
            }
 
            ApplyCachedBounds();
          
        }
 
        
        private void OnLayoutVerticalPostFix() {
            
          ToolStripPanelCell cell = RowManager.GetNextVisibleCell(this.Cells.Count -1, /*forward*/false);
          // figure out how much space we actually need to free.
          int spaceToFree = cell.CachedBounds.Bottom - RowManager.DisplayRectangle.Bottom;
          
          if (spaceToFree <= 0) {
              // we're all good. Just apply the cached bounds.
              ApplyCachedBounds();
              return;
          }
           // STEP 1 remove empty space in the row.
 
           // since layout sisuspended, we'll need to watch changes to the margin 
           // as a result of calling FreeSpaceFromRow.
           int[] margins = new int[Cells.Count];
           for (int i = 0; i < Cells.Count; i++) {
               ToolStripPanelCell c = Cells[i] as ToolStripPanelCell;
               margins[i] = c.Margin.Top;
           }
 
           spaceToFree -= RowManager.FreeSpaceFromRow(spaceToFree);
 
           // now apply those changes to the cached bounds.
           for (int i = 0; i < Cells.Count; i++) {
               ToolStripPanelCell c = Cells[i] as ToolStripPanelCell;
               Rectangle cachedBounds = c.CachedBounds;
               cachedBounds.X = Math.Max(0, cachedBounds.X - margins[i] - c.Margin.Top);
               c.CachedBounds = cachedBounds;
           }
           
           if (spaceToFree <= 0) {
               ApplyCachedBounds();
               return;
           }
 
           
           
           // STEP 2 change the size of the remaing ToolStrips from Bottom to Top.
           int[] cellOffsets = null;                        
           for (int i = Cells.Count-1; i >= 0; i--) {
               ToolStripPanelCell currentCell =Cells[i] as ToolStripPanelCell;
               if (currentCell.Visible) {
                   Size minSize = GetMinimumSize(currentCell.Control as ToolStrip);
                   Rectangle cachedBounds = currentCell.CachedBounds;
 
                   // found some space to free.
                   if (cachedBounds.Height > minSize.Height) {
                       spaceToFree -= (cachedBounds.Height - minSize.Height);
                       // make sure we dont take more space than we need - if spaceToFree is less than 0, add back in.
                       cachedBounds.Height =  (spaceToFree < 0) ? minSize.Height + -spaceToFree : minSize.Height;
 
                       // we're not reperforming a layout, so we need to adjust the next cell
                       for (int j = i+1; j < Cells.Count; j++) {
                           if (cellOffsets == null) {
                               cellOffsets = new int[Cells.Count];
                           }
                           cellOffsets[j] += Math.Max(0,currentCell.CachedBounds.Height-cachedBounds.Height);
                       }
                       currentCell.CachedBounds = cachedBounds;
                   }
               }
               if (spaceToFree <= 0) {
                   break;
               }
           }
 
           // fixup for items before it shrinking.
           if (cellOffsets != null) {
               for (int i = 0; i < Cells.Count; i++) {
                  ToolStripPanelCell c = Cells[i] as ToolStripPanelCell;
                  Rectangle cachedBounds = c.CachedBounds;
                  cachedBounds.Y -= cellOffsets[i];
                  c.CachedBounds = cachedBounds;
              }
           }
 
           ApplyCachedBounds();
         
       }
 
#if DEBUG_PAINT
        internal void PaintColumns(PaintEventArgs e) {
            Graphics g = e.Graphics;
            
            using (Pen pen = new Pen(Color.Green)) {
                g.DrawRectangle(pen, this.DisplayRectangle);
            }
 
            foreach (ToolStripPanelCell c in this.Cells) {
                Rectangle inner = c.Bounds;
                Rectangle b = LayoutUtils.InflateRect(inner, c.Margin);
                if ((b.Width > 0) && (b.Height > 0)) {
                    using(Brush brush = new System.Drawing.Drawing2D.LinearGradientBrush(b, ProfessionalColors.ButtonSelectedGradientBegin, ProfessionalColors.ButtonSelectedGradientEnd, System.Drawing.Drawing2D.LinearGradientMode.Horizontal)) {
                        g.FillRectangle(brush, b);
                        g.DrawRectangle(SystemPens.ControlDarkDark, b.X, b.Y, b.Width -1, b.Height -1);
                        g.DrawRectangle(Pens.HotPink, inner.X, inner.Y, inner.Width -1, inner.Height -1);
                        if (c.Control != null) {
                            g.DrawString("BAD\r\n" + c.Control.Name, ToolStripPanel.Font, SystemBrushes.ControlText, inner); 
                        }
                        else {
                            g.DrawString("BAD\r\n" + "NULL control", ToolStripPanel.Font, SystemBrushes.ControlText, inner); 
 
                        }
                    }
                }
            }
        }
#endif
 
        private void SetBounds(Rectangle bounds) {
            if (bounds != this.bounds) {
                Rectangle oldBounds = this.bounds;
 
                this.bounds = bounds;
                OnBoundsChanged(oldBounds, bounds);
            }
        }
 
        private void SuspendLayout() {
            suspendCount++;
        }
 
        private void ResumeLayout(bool performLayout) {
            suspendCount--;
            if (performLayout) {
                ((IArrangedElement)this).PerformLayout(this, null);
            }
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.IArrangedElement.Children"]/*' />
        /// <devdoc>
        /// </devdoc>
        /// <internalonly/>
        ArrangedElementCollection IArrangedElement.Children {
            get {
                return Cells;
            }
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.IArrangedElement.Container"]/*' />
        /// <devdoc>
        /// Should not be exposed as this returns an unexposed type.
        /// </devdoc>
        /// <internalonly/>
        IArrangedElement IArrangedElement.Container {
            get {
                return this.ToolStripPanel;
            }
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.IArrangedElement.DisplayRectangle"]/*' />
        /// <devdoc>
        /// 
 
 
        Rectangle IArrangedElement.DisplayRectangle {
            get {
                Rectangle displayRectangle = this.Bounds;
 
                return displayRectangle;
            }
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.IArrangedElement.ParticipatesInLayout"]/*' />
        /// <devdoc>
        /// 
 
 
        bool IArrangedElement.ParticipatesInLayout {
            get {
                return Visible;
            }
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.IArrangedElement.Properties"]/*' />
        /// <internalonly/>
        PropertyStore IArrangedElement.Properties {
            get {
                return this.Properties;
            }
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.IArrangedElement.GetPreferredSize"]/*' />
        /// <internalonly/>
        Size IArrangedElement.GetPreferredSize(Size constrainingSize) {
            Size preferredSize = LayoutEngine.GetPreferredSize(this, constrainingSize - Padding.Size) + Padding.Size;
 
            if (Orientation == Orientation.Horizontal && ParentInternal != null) {
                preferredSize.Width = DisplayRectangle.Width;
            }
            else {
                preferredSize.Height = DisplayRectangle.Height;
            }
 
            return preferredSize;
        }
 
        // Sets the bounds for an element.
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.IArrangedElement.SetBounds"]/*' />
        /// <internalonly/>
        void IArrangedElement.SetBounds(Rectangle bounds, BoundsSpecified specified) {
            // in this case the parent is telling us to refresh our bounds - dont 
            // call PerformLayout
            SetBounds(bounds);
        }
 
       
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.IArrangedElement.PerformLayout"]/*' />
        /// <devdoc>
        /// 
 
 
        void IArrangedElement.PerformLayout(IArrangedElement container, string propertyName) {
            if (suspendCount <= 0) {
                OnLayout(new LayoutEventArgs(container, propertyName));
            }
        }
 
            #region MouseStuff
 
#if DEBUG
      internal static readonly TraceSwitch ToolStripPanelMouseDebug = new TraceSwitch("ToolStripPanelMouse", "Debug WinBar WM_MOUSEACTIVATE code");
#else
        internal static readonly TraceSwitch ToolStripPanelMouseDebug;
#endif
 
     
        internal Rectangle DragBounds {
            get {
                return RowManager.DragBounds;
            }
        }
 
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRow.MoveControl"]/*' />
        internal void MoveControl(ToolStrip movingControl, Point startClientLocation, Point endClientLocation) {
            RowManager.MoveControl(movingControl, startClientLocation, endClientLocation);
        }
 
        // 
 
 
        internal void JoinRow(ToolStrip toolStripToDrag, Point locationToDrag) {
            RowManager.JoinRow(toolStripToDrag, locationToDrag);
        }
 
        internal void LeaveRow(ToolStrip toolStripToDrag) {
            RowManager.LeaveRow(toolStripToDrag);
            if (ControlsInternal.Count == 0) {
                ToolStripPanel.RowsInternal.Remove(this);
                Dispose();
            }
        }
 
        [Conditional("DEBUG")]
        private void PrintPlacements(int index) {
          /*  Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "Results:\r\n\t-------");
            Debug.Indent();
            Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "ToolStripPanelRow: " + this.Bounds.ToString());
 
            float sumColWidths = 0F;
            int sumWidths = 0;
 
            for (int i = 0; i < this.Controls.Count - 1; i++) {
                string indicator = (i == index) ? "*" : " ";
 
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, String.Format("{0} {1} Column Width {2} Control Size {3}", indicator, this.Controls[i].Name, TableLayoutSettings.ColumnStyles[i].Width, this.Controls[i].Bounds));
                sumColWidths += TableLayoutSettings.ColumnStyles[i].Width;
                sumWidths += this.Controls[i].Width;
            }
 
            Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "Total Column Width " + sumColWidths.ToString() + " Total control widths " + sumWidths.ToString());
            Debug.Unindent();
            */
        }
            #endregion
 
 
        private abstract class ToolStripPanelRowManager {
            private FlowLayoutSettings flowLayoutSettings = null;
 
            private ToolStripPanelRow owner = null;
 
            public ToolStripPanelRowManager(ToolStripPanelRow owner) {
                this.owner = owner;
            }
 
            public virtual bool CanMove(ToolStrip toolStripToDrag) {
                ISupportToolStripPanel raftingControl = toolStripToDrag as ISupportToolStripPanel;
                if (raftingControl != null) {
                   if (raftingControl.Stretch) {
                        Debug.WriteLineIf(ToolStripPanelRow.ToolStripPanelRowCreationDebug.TraceVerbose, "TSP RM CanMove returns false - the item moving is stretched.");
                        return false;
                   }
                }
                foreach (Control c in Row.ControlsInternal) {
                     raftingControl = c as ISupportToolStripPanel;
                     if (raftingControl != null) {
                        if (raftingControl.Stretch) {
                             Debug.WriteLineIf(ToolStripPanelRow.ToolStripPanelRowCreationDebug.TraceVerbose, "TSP RM CanMove returns false - the row already contains a stretched item.");
                             return false;
                        }
                     }
                }
                return true;
            }
 
            public virtual Rectangle DragBounds {
                get { return Rectangle.Empty; }
            }
 
            public virtual Rectangle DisplayRectangle {
                get { return Rectangle.Empty; }
            }
 
            public ToolStripPanel ToolStripPanel {
                get { return owner.ToolStripPanel; }
            }
 
            public ToolStripPanelRow Row {
                get { return owner; }
            }
 
            public FlowLayoutSettings FlowLayoutSettings {
                get {
                    if (flowLayoutSettings == null) {
                        flowLayoutSettings = new FlowLayoutSettings(owner);
                    }
 
                    return flowLayoutSettings;
                }
            }
 
            protected internal virtual int FreeSpaceFromRow(int spaceToFree) {
                return 0;
            }
 
            protected virtual int Grow(int index, int growBy) {
                int freedSpace = 0;
                if (index >= 0 && index < Row.ControlsInternal.Count - 1) {
                    ToolStripPanelCell cell = (ToolStripPanelCell)Row.Cells[index];
                    if (cell.Visible) {
                        freedSpace = cell.Grow(growBy);
                    }
                }
                return freedSpace;                
            }
 
            public ToolStripPanelCell GetNextVisibleCell(int index, bool forward) {
                if (forward) {
                    for (int i = index; i < Row.Cells.Count; i++) {
                        ToolStripPanelCell cell = Row.Cells[i] as ToolStripPanelCell;
                        if ((cell.Visible || (owner.parent.Visible && cell.ControlInDesignMode)) && cell.ToolStripPanelRow == this.owner) {
                            return cell;
                        }
                    }
                }
                else {
                    for (int i = index; i >=0; i--) {
                        ToolStripPanelCell cell = Row.Cells[i] as ToolStripPanelCell;
                        if ((cell.Visible || (owner.parent.Visible && cell.ControlInDesignMode)) && cell.ToolStripPanelRow == this.owner) {
                            return cell;
                        }
                    }
 
                }
                return null;
                
            }
          
            /// <devdoc>
            /// grows all controls after the index to be their preferred size.
            /// reports back how much space was used.
            /// </devdoc>
            protected virtual int GrowControlsAfter(int index, int growBy) {
               if (growBy < 0) {
                   Debug.Fail("why was a negative number given to growControlsAfter?");
                   return 0;
               }
 
               int spaceToFree = growBy;
 
               for (int i = index + 1; i < Row.ControlsInternal.Count; i++) {
                   // grow the n+1 item first if it was previously shrunk.
                   int freedSpace = Grow(i, spaceToFree);
 
                   if (freedSpace >= 0) {
                       spaceToFree -= freedSpace;
                       if (spaceToFree <= 0) {
                           return growBy;
                       }
                   }
               }
 
               return growBy - spaceToFree;
            }
 
            /// <devdoc>
            /// grows all controls before the index to be their preferred size.
            /// reports back how much space was used.
            /// </devdoc>
            protected virtual int GrowControlsBefore(int index, int growBy) {
               if (growBy < 0) {
                   Debug.Fail("why was a negative number given to growControlsAfter?");
                   return 0;
               }
 
               int spaceToFree = growBy;
 
               // grow the n-1 item first if it was previously shrunk.
               for (int i = index - 1; i >= 0; i--) {
                   spaceToFree -= Grow(i, spaceToFree);
                   if (spaceToFree <= 0) {
                       return growBy; // we've already gotten all the free space.
                   }
               }
 
               return growBy - spaceToFree;
            }
 
            
 
            public virtual void MoveControl(ToolStrip movingControl, Point startClientLocation, Point endClientLocation) {
           //     ToolStripPanel.Join(movingControl, endScreenLocation);
            }
            public virtual void LeaveRow(ToolStrip toolStripToDrag) {
            }
 
            public virtual void JoinRow(ToolStrip toolStripToDrag, Point locationToDrag) {
            }
 
            protected internal virtual void OnControlAdded(Control c, int index) {
            }
 
            protected internal virtual void OnControlRemoved(Control c, int index) {
            }
 
            protected internal virtual void OnBoundsChanged(Rectangle oldBounds, Rectangle newBounds) {
            }
        }
 
        private class HorizontalRowManager : ToolStripPanelRowManager {
            private const int DRAG_BOUNDS_INFLATE = 4;
 
         
            public HorizontalRowManager(ToolStripPanelRow owner): base (owner) {
                owner.SuspendLayout();
                FlowLayoutSettings.WrapContents = false;
                FlowLayoutSettings.FlowDirection = FlowDirection.LeftToRight;
                owner.ResumeLayout(false);
            }
           
            public override Rectangle DisplayRectangle {
                get {
                    Rectangle displayRect = ((IArrangedElement)Row).DisplayRectangle;
 
                    if (ToolStripPanel != null) {
                        Rectangle raftingDisplayRectangle = ToolStripPanel.DisplayRectangle;
                  
                        if ((!ToolStripPanel.Visible || LayoutUtils.IsZeroWidthOrHeight(raftingDisplayRectangle)) && (ToolStripPanel.ParentInternal != null)){
                      
                            // if were layed out before we're visible we have the wrong display rectangle, so we need to calculate it.
                            displayRect.Width = ToolStripPanel.ParentInternal.DisplayRectangle.Width - (ToolStripPanel.Margin.Horizontal + ToolStripPanel.Padding.Horizontal) - Row.Margin.Horizontal;
                        }
                        else {
                            displayRect.Width = raftingDisplayRectangle.Width - Row.Margin.Horizontal;
                  
                        }
                    }
 
                    return displayRect;
                }
            }
 
            public override Rectangle DragBounds {
                get {
                    Rectangle dragBounds = Row.Bounds;
                    int index = ToolStripPanel.RowsInternal.IndexOf(Row);
 
                    if (index > 0) {
                        Rectangle previousRowBounds = ToolStripPanel.RowsInternal[index - 1].Bounds;
                        int y = previousRowBounds.Y + previousRowBounds.Height - (previousRowBounds.Height >> 2);
 
                        dragBounds.Height += dragBounds.Y - y;
                        dragBounds.Y = y;
                    }
 
                    if (index < ToolStripPanel.RowsInternal.Count - 1) {
                        Rectangle nextRowBounds = ToolStripPanel.RowsInternal[index + 1].Bounds;
 
                        dragBounds.Height += (nextRowBounds.Height >> 2) + Row.Margin.Bottom + ToolStripPanel.RowsInternal[index + 1].Margin.Top;
                    }
 
                    dragBounds.Width += Row.Margin.Horizontal + ToolStripPanel.Padding.Horizontal +5;
                    dragBounds.X -= Row.Margin.Left + ToolStripPanel.Padding.Left +4;
                    return dragBounds;
                }
            }
            
            /// <devdoc>
            ///  returns true if there is enough space to "raft" the control
            ///  ow returns false
            /// </devdoc>
            public override bool CanMove(ToolStrip toolStripToDrag) {
 
                if (base.CanMove(toolStripToDrag)) {
                    Size totalSize = Size.Empty;
 
                    for (int i = 0; i < Row.ControlsInternal.Count; i++ ){
                        totalSize += Row.GetMinimumSize(Row.ControlsInternal[i] as ToolStrip); 
                    }
 
                    totalSize += Row.GetMinimumSize(toolStripToDrag as ToolStrip); 
                    return totalSize.Width < DisplayRectangle.Width;
                }
                Debug.WriteLineIf(ToolStripPanelRow.ToolStripPanelRowCreationDebug.TraceVerbose, "HorizontalRM.CanMove returns false - not enough room");              
                return false;
            }
            
            protected internal override int FreeSpaceFromRow(int spaceToFree) {
               int requiredSpace = spaceToFree;
               // take a look at the last guy.  if his right edge exceeds
               // the new bounds, then we should go ahead and push him into view.
             
               if (spaceToFree > 0){
                   // we should shrink the last guy and then move him.
                   ToolStripPanelCell lastCellOnRow = GetNextVisibleCell(Row.Cells.Count-1,  /*forward*/false);
                   if (lastCellOnRow == null) {
                        return 0;
                   }
                   Padding cellMargin = lastCellOnRow.Margin;
    
                   // only check margin.left as we are only concerned with getting right edge of
                   // the toolstrip into view. (space after the fact doesnt count).
                    if (cellMargin.Left >= spaceToFree) {
                       cellMargin.Left -= spaceToFree;
                       cellMargin.Right = 0;
                       spaceToFree = 0;
    
                   }
                   else {
                       spaceToFree -= lastCellOnRow.Margin.Left;  
                       cellMargin.Left = 0;
                       cellMargin.Right = 0;
                   }
                   lastCellOnRow.Margin = cellMargin;
                   
                   // start moving the toolstrips before this guy.
                   spaceToFree -= MoveLeft(Row.Cells.Count -1, spaceToFree);
    
                   if (spaceToFree > 0) {
                       spaceToFree -= lastCellOnRow.Shrink(spaceToFree);
                   }
                }
                return requiredSpace - Math.Max(0,spaceToFree);
           }
 
            public override void MoveControl(ToolStrip movingControl, Point clientStartLocation, Point clientEndLocation) {
                if (Row.Locked) {
                    return;
                }
 
                if (DragBounds.Contains(clientEndLocation)) {
                    int index = Row.ControlsInternal.IndexOf(movingControl);
                    int deltaX = clientEndLocation.X - clientStartLocation.X;
 
                    if (deltaX < 0) {
                        // moving to the left
                        MoveLeft(index, deltaX * -1);
                    }
                    else {
                        MoveRight(index, deltaX);
                    }
                }
                else  {
                    base.MoveControl(movingControl, clientStartLocation, clientEndLocation);
                }
            }
 
            private int MoveLeft(int index, int spaceToFree) {
 
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveLeft: " + spaceToFree.ToString(CultureInfo.InvariantCulture));
                int freedSpace = 0;
                          
                Row.SuspendLayout();
                try {
                    if (spaceToFree == 0 || index < 0) {
                        Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveLeft Early EXIT - 0 ");           
                        return 0;
                    }
 
                    
                    // remove all margins starting from the index.
                    for (int i = index; i >= 0; i--) {
                        ToolStripPanelCell cell = (ToolStripPanelCell)Row.Cells[i];
                        if (!cell.Visible && !cell.ControlInDesignMode) {
                            continue;
                        }
                        int requiredSpace = spaceToFree - freedSpace;
 
                        Padding cellMargin = cell.Margin;
                        
                        if (cellMargin.Horizontal >= requiredSpace) {
                            freedSpace += requiredSpace;
                             
                            cellMargin.Left -= requiredSpace;
                            cellMargin.Right = 0;
                            cell.Margin = cellMargin;
                            
                        }
                        else {
                            freedSpace += cell.Margin.Horizontal;
                            cellMargin.Left = 0;
                            cellMargin.Right = 0;
                            cell.Margin = cellMargin;
                        }
 
                        if (freedSpace >= spaceToFree) {
                            // add the space we freed to the next guy.
                            if (index +1 < Row.Cells.Count) {
                                cell = GetNextVisibleCell(index+1, /*forward*/true);
                                if (cell != null) {
                                    cellMargin = cell.Margin;
                                    cellMargin.Left += spaceToFree;
                                    cell.Margin = cellMargin;
                                }
                            }
                            
                            Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveLeft Recovered (Margin only): " + spaceToFree.ToString(CultureInfo.InvariantCulture));
                            return spaceToFree;
                        }
                    }
                }
                finally {
                    Row.ResumeLayout(true);
                }
                
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveLeft Recovered Partial (Shrink): " + freedSpace.ToString(CultureInfo.InvariantCulture));
                return freedSpace;
            }
 
            private int MoveRight(int index, int spaceToFree) {
 
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveRight: " + spaceToFree.ToString(CultureInfo.InvariantCulture));
                int freedSpace = 0;     
                Row.SuspendLayout();
                try {
                
                    if (spaceToFree == 0 || index < 0 || index >= Row.ControlsInternal.Count) {
                        Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveRight Early EXIT - 0 ");           
                        return 0;
                    }
 
                    
                    ToolStripPanelCell cell;
                    Padding cellMargin;
 
                    // remove all margins after this point in the index.
                    for (int i = index+1; i < Row.Cells.Count; i++) {
                        cell = (ToolStripPanelCell)Row.Cells[i];
                        if (!cell.Visible && !cell.ControlInDesignMode) {
                            continue;
                        }
                        int requiredSpace = spaceToFree - freedSpace;
 
                        cellMargin = cell.Margin;
                        
                        if (cellMargin.Horizontal >= requiredSpace) {
                            freedSpace += requiredSpace;
                             
                            cellMargin.Left -= requiredSpace;
                            cellMargin.Right = 0;
                            cell.Margin = cellMargin;
                            
                        }
                        else {
                            freedSpace += cell.Margin.Horizontal;
                            cellMargin.Left = 0;
                            cellMargin.Right = 0;
                            cell.Margin = cellMargin;
                        }
 
                        break;
                    }
 
                    // add in the space at the end of the row.
                    if (Row.Cells.Count > 0 && (spaceToFree > freedSpace)) {
                        ToolStripPanelCell lastCell = GetNextVisibleCell(Row.Cells.Count -1, /*forward*/false);
                        if (lastCell != null) {
                            freedSpace += DisplayRectangle.Right - lastCell.Bounds.Right;
                        }
                        else {
                            freedSpace += DisplayRectangle.Width;
                        }
                        
                    }
 
 
                    // set the margin of the control that's moving.
                    if (spaceToFree <= freedSpace) {
                        // add the space we freed to the first guy.
                        cell = GetNextVisibleCell(index, /*forward*/true);
                        if (cell == null) {
                            cell = Row.Cells[index] as ToolStripPanelCell;
                        }
                        Debug.Assert(cell != null, "Dont expect cell to be null here, what's going on?");
 
                        if (cell != null) {
                            cellMargin = cell.Margin;
                            cellMargin.Left += spaceToFree;
                            cell.Margin = cellMargin;
                        }
                        Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveRight Recovered (Margin only): " + spaceToFree.ToString(CultureInfo.InvariantCulture));
                        return spaceToFree;
                    }
 
                    // Now start shrinking.
                    for (int i = index+1; i < Row.Cells.Count; i++) {
                        cell = (ToolStripPanelCell)Row.Cells[i];
                        if (!cell.Visible && !cell.ControlInDesignMode) {
                            continue;
                        }
                        int requiredSpace = spaceToFree - freedSpace;
                        freedSpace += cell.Shrink(requiredSpace);
                        
                         if (spaceToFree >= freedSpace) {
                            Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveRight Recovered (Shrink): " + spaceToFree.ToString(CultureInfo.InvariantCulture));
                            Row.ResumeLayout(true);
                            return spaceToFree;
                         }
 
                    }
 
                    if (Row.Cells.Count == 1) {
                        cell = GetNextVisibleCell(index,/*forward*/true);
                        if (cell != null) {
                            cellMargin = cell.Margin;
                            cellMargin.Left += freedSpace;
                            cell.Margin = cellMargin;
                        }
                    }
 
                }
                finally {
                    Row.ResumeLayout(true);
                }
 
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveRight Recovered Partial (Shrink): " + freedSpace.ToString(CultureInfo.InvariantCulture));
 
                return freedSpace;
            }
 
            
            public override void LeaveRow(ToolStrip toolStripToDrag) {
                // this code is here to properly add space to the next control when the
                // toolStripToDrag has been removed from the row.
                Row.SuspendLayout();
                int index = Row.ControlsInternal.IndexOf(toolStripToDrag);
                if (index >= 0) {
                    if (index < Row.ControlsInternal.Count -1 /*not the last one in the row*/) {
                        ToolStripPanelCell cell = (ToolStripPanelCell)Row.Cells[index];
                        if (cell.Visible) {
                            int spaceOccupiedByCell = cell.Margin.Horizontal + cell.Bounds.Width;
 
                            // add the space occupied by the cell to the next one.
                            ToolStripPanelCell nextCell = GetNextVisibleCell(index+1, /*forward*/true);
                            if (nextCell != null) {
                                Padding nextCellMargin = nextCell.Margin;
                                nextCellMargin.Left += spaceOccupiedByCell;
                                nextCell.Margin = nextCellMargin;
                            }
                        }
                    }
                    // remove the control from the row.
                    ((IList)Row.Cells).RemoveAt(index);
                }
                Row.ResumeLayout(true);
            }
            
            protected internal override void OnControlAdded(Control control, int index) {
            }
 
            protected internal override void OnControlRemoved(Control control, int index) {
            }
 
            public override void JoinRow(ToolStrip toolStripToDrag, Point locationToDrag) {
 
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "Horizontal JoinRow called " );
                int index;
                
 
                if (!Row.ControlsInternal.Contains(toolStripToDrag)) {
                    Row.SuspendLayout();
           
                    try {                 
                         if (Row.ControlsInternal.Count > 0) {
                            
                            // walk through the columns and determine which column you want to insert into.
                            for (index = 0; index < Row.Cells.Count; index++) {
                                ToolStripPanelCell cell = Row.Cells[index] as ToolStripPanelCell;
                                if (!cell.Visible && !cell.ControlInDesignMode) {
                                    continue;
                                }
                                
                                //  [:   ]  [: x  ]
                                if (Row.Cells[index].Bounds.Contains(locationToDrag)) {
                                    break;
                                }
 
                                // take into account the following scenarios
                                //  [:   ]  x [:   ]
                                // x [:  ]    [:   ]
                                if (Row.Cells[index].Bounds.X >= locationToDrag.X) {
                                    break;
                                }
 
                            }
 
                            Control controlToPushAside = Row.ControlsInternal[index];
                            // Plop the new control in the midst of the row in question.
                            if (index < Row.ControlsInternal.Count) {
                                Row.ControlsInternal.Insert(index, toolStripToDrag);
                            }
                            else {
                                Row.ControlsInternal.Add(toolStripToDrag);
                            }
 
                            // since layout is suspended the control may not be set to its preferred size yet
                            int controlToDragWidth = (toolStripToDrag.AutoSize) ? toolStripToDrag.PreferredSize.Width : toolStripToDrag.Width;
                            
                    
                            //
                            // now make it look like it belongs in the row.
                            //
                            // PUSH the controls after it to the right
                            
                            int requiredSpace = controlToDragWidth;
                            if (index == 0) {
                                // make sure we account for the left side
                                requiredSpace += locationToDrag.X;
                            }
                            int freedSpace = 0;
                            
                            if (index < Row.ControlsInternal.Count -1) {
                                ToolStripPanelCell nextCell = (ToolStripPanelCell)Row.Cells[index+1];
                                Padding nextCellMargin =  nextCell.Margin;
                    
                                // if we've already got the empty space
                                // (available to us via the margin) use that.
                                if (nextCellMargin.Left > requiredSpace) {
                                    nextCellMargin.Left -= requiredSpace;
                                    nextCell.Margin = nextCellMargin;
                                    freedSpace = requiredSpace;
                                }
                                else {
                                    // otherwise we've got to 
                                    // push all controls after this point to the right 
                                    // this dumps the extra stuff into the margin of index+1
                                    freedSpace = MoveRight(index+1, requiredSpace - freedSpace);
                    
                                    // refetch the margin for "index+1" and remove the freed space 
                                    // from it - we want to actually put this to use on the control
                                    // before this one - we're making room for the control at 
                                    // position "index"
                                    if (freedSpace > 0) {
                                        nextCellMargin =  nextCell.Margin;
                                        nextCellMargin.Left = Math.Max(0, nextCellMargin.Left - freedSpace);
                                        nextCell.Margin = nextCellMargin; 
                                    }
                               
                                }
                                
                    
                            }
                            else {
                                // we're adding to the end.
                                ToolStripPanelCell nextCell = GetNextVisibleCell(Row.Cells.Count-2,  /*forward*/false);
                                ToolStripPanelCell lastCell = GetNextVisibleCell(Row.Cells.Count-1,  /*forward*/false);
                           
                                // count the stuff at the end of the row as freed space
                                if (nextCell != null && lastCell != null) {
                                    Padding lastCellMargin = lastCell.Margin;
                                    lastCellMargin.Left = Math.Max(0,locationToDrag.X - nextCell.Bounds.Right);
                                    lastCell.Margin = lastCellMargin;
                                    freedSpace=requiredSpace;
                                }                            
                            }
                            
                            // If we still need more space, then...
                            // PUSH the controls before it to the left
                            if (freedSpace < requiredSpace && index > 0) {
                                freedSpace = MoveLeft(index - 1, requiredSpace - freedSpace);
                            }
                    
                            if (index == 0) {
                                // if the index is zero and there were controls in the row
                                // we need to take care of pushing over the new cell.
                                if (freedSpace - controlToDragWidth > 0) {
                                    ToolStripPanelCell newCell = Row.Cells[index] as ToolStripPanelCell;
                                    Padding newCellMargin =  newCell.Margin;
                                    newCellMargin.Left = freedSpace - controlToDragWidth;
                                    newCell.Margin = newCellMargin;
                                }
                            }
                                
                                
                            
                           
                        }
                        else {
                            
                            // we're adding to the beginning.
                            Row.ControlsInternal.Add(toolStripToDrag);
  
#if DEBUG
                            ISupportToolStripPanel ctg = toolStripToDrag as ISupportToolStripPanel;
                            ToolStripPanelRow newPanelRow = ctg.ToolStripPanelRow;
                            Debug.Assert(newPanelRow == Row, "we should now be in the new panel row.");
#endif
                            if (Row.Cells.Count >0 || toolStripToDrag.IsInDesignMode) {                            
                                // we're adding to the beginning.
                                ToolStripPanelCell cell = GetNextVisibleCell(Row.Cells.Count-1, /*forward*/false);
                                if (cell == null && toolStripToDrag.IsInDesignMode) {
                                    cell = (ToolStripPanelCell)Row.Cells[Row.Cells.Count-1];
                                }
 
                                if (cell != null) {
                                    Padding cellMargin = cell.Margin;
                                    cellMargin.Left = Math.Max(0,locationToDrag.X-Row.Margin.Left);
                                    cell.Margin = cellMargin;
                                }
                            }
 
                            
                          
                        }
                    }
                    finally {
                        Row.ResumeLayout(true);
                    }
                }                    
            }
 
            protected internal override void OnBoundsChanged(Rectangle oldBounds, Rectangle newBounds) {
               base.OnBoundsChanged(oldBounds, newBounds);
            }
 
            
            
        }
   
        private class VerticalRowManager : ToolStripPanelRowManager {
            
            private const int DRAG_BOUNDS_INFLATE = 4;
          
            public VerticalRowManager(ToolStripPanelRow owner): base (owner) {
                owner.SuspendLayout();
                FlowLayoutSettings.WrapContents = false;
                FlowLayoutSettings.FlowDirection = FlowDirection.TopDown;
                owner.ResumeLayout(false);
            }
            
 
            public override Rectangle DisplayRectangle {
                get {
                    Rectangle displayRect = ((IArrangedElement)Row).DisplayRectangle;
 
                    if (ToolStripPanel != null) {
                        Rectangle raftingDisplayRectangle = ToolStripPanel.DisplayRectangle;
                        
                        if ((!ToolStripPanel.Visible || LayoutUtils.IsZeroWidthOrHeight(raftingDisplayRectangle)) && (ToolStripPanel.ParentInternal != null)){
                            // if were layed out before we're visible we have the wrong display rectangle, so we need to calculate it.
                            displayRect.Height = ToolStripPanel.ParentInternal.DisplayRectangle.Height - (ToolStripPanel.Margin.Vertical + ToolStripPanel.Padding.Vertical) - Row.Margin.Vertical;
                        }
                        else {
                            displayRect.Height = raftingDisplayRectangle.Height - Row.Margin.Vertical;
                        }
                    }
 
                    return displayRect;
                }
            }
            public override Rectangle DragBounds {
                get {
                    Rectangle dragBounds = Row.Bounds;
                    int index = ToolStripPanel.RowsInternal.IndexOf(Row);
 
                    /// 
                    if (index > 0) {
                        Rectangle previousRowBounds = ToolStripPanel.RowsInternal[index - 1].Bounds;
                        int x = previousRowBounds.X + previousRowBounds.Width - (previousRowBounds.Width >> 2);
 
                        dragBounds.Width += dragBounds.X - x;
                        dragBounds.X = x;
                    }
 
                    if (index < ToolStripPanel.RowsInternal.Count - 1) {
                        Rectangle nextRowBounds = ToolStripPanel.RowsInternal[index + 1].Bounds;
 
                        dragBounds.Width += (nextRowBounds.Width >> 2) + Row.Margin.Right + ToolStripPanel.RowsInternal[index + 1].Margin.Left;
                    }
 
                    dragBounds.Height += Row.Margin.Vertical + ToolStripPanel.Padding.Vertical +5;
                    dragBounds.Y -= Row.Margin.Top+ ToolStripPanel.Padding.Top +4;
 
 
                    return dragBounds;
                }
            }
 
            /// <devdoc>
            ///  returns true if there is enough space to "raft" the control
            ///  ow returns false
            /// </devdoc>
            public override bool CanMove(ToolStrip toolStripToDrag) {
 
                 if (base.CanMove(toolStripToDrag)) {
                    Size totalSize = Size.Empty;
 
                    for (int i = 0; i < Row.ControlsInternal.Count; i++ ){
                        totalSize += Row.GetMinimumSize(Row.ControlsInternal[i] as ToolStrip); 
                    }
 
                    totalSize += Row.GetMinimumSize(toolStripToDrag);
                    return totalSize.Height < DisplayRectangle.Height;
                }
             
                Debug.WriteLineIf(ToolStripPanelRow.ToolStripPanelRowCreationDebug.TraceVerbose, "VerticalRM.CanMove returns false - not enough room");              
                return false;
            }
            protected internal override int FreeSpaceFromRow(int spaceToFree) {
                  int requiredSpace = spaceToFree;
                  // take a look at the last guy.  if his right edge exceeds
                  // the new bounds, then we should go ahead and push him into view.
                
                  if (spaceToFree > 0){
                      // we should shrink the last guy and then move him.
                      ToolStripPanelCell lastCellOnRow = GetNextVisibleCell(Row.Cells.Count-1,  /*forward*/false);
                      if (lastCellOnRow == null) {
                         return 0;
                      }
                      Padding cellMargin = lastCellOnRow.Margin;
            
                      // only check margin.left as we are only concerned with getting right edge of
                      // the toolstrip into view. (space after the fact doesnt count).
                       if (cellMargin.Top >= spaceToFree) {
                          cellMargin.Top -= spaceToFree;
                          cellMargin.Bottom = 0;
                          spaceToFree = 0;
            
                      }
                      else {
                          spaceToFree -= lastCellOnRow.Margin.Top;  
                          cellMargin.Top = 0;
                          cellMargin.Bottom = 0;
                      }
                      lastCellOnRow.Margin = cellMargin;
                      
                      // start moving the toolstrips before this guy.
                      spaceToFree -= MoveUp(Row.Cells.Count -1, spaceToFree);
            
                      if (spaceToFree > 0) {
                          spaceToFree -= lastCellOnRow.Shrink(spaceToFree);
                      }
                   }
                   return requiredSpace - Math.Max(0,spaceToFree);
            }
 
            
           
            public override void MoveControl(ToolStrip movingControl, Point clientStartLocation, Point clientEndLocation) {
 
                if (Row.Locked) {
                    return;
                }
                if (DragBounds.Contains(clientEndLocation)) {
                   int index = Row.ControlsInternal.IndexOf(movingControl);
                   int deltaY = clientEndLocation.Y - clientStartLocation.Y;
 
                   if (deltaY < 0) {
                       // moving to the left
                       MoveUp(index, deltaY * -1);
                   }
                   else {
                       MoveDown(index, deltaY);
                   }
               }
               else {
                    base.MoveControl(movingControl, clientStartLocation, clientEndLocation);
               }
            }
 
 
 
            private int MoveUp(int index, int spaceToFree) {
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveUp: " + spaceToFree.ToString(CultureInfo.InvariantCulture));
                int freedSpace = 0;
                          
                Row.SuspendLayout();
                try {
                    if (spaceToFree == 0 || index < 0) {
                        Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveUp Early EXIT - 0 ");           
                        return 0;
                    }
 
                    
                    // remove all margins starting from the index.
                    for (int i = index; i >= 0; i--) {
                        ToolStripPanelCell cell = (ToolStripPanelCell)Row.Cells[i];
                        if (!cell.Visible && !cell.ControlInDesignMode) {
                            continue;
                        }
                        int requiredSpace = spaceToFree - freedSpace;
 
                        Padding cellMargin = cell.Margin;
                        
                        if (cellMargin.Vertical >= requiredSpace) {
                            freedSpace += requiredSpace;
                             
                            cellMargin.Top -= requiredSpace;
                            cellMargin.Bottom = 0;
                            cell.Margin = cellMargin;
                            
                        }
                        else {
                            freedSpace += cell.Margin.Vertical;
                            cellMargin.Top = 0;
                            cellMargin.Bottom = 0;
                            cell.Margin = cellMargin;
                        }
 
                        if (freedSpace >= spaceToFree) {
                            // add the space we freed to the next guy.
                            if (index +1 < Row.Cells.Count) {
                                cell = GetNextVisibleCell(index+1, /*forward*/true);
                                if (cell != null) {
                                    cellMargin = cell.Margin;
                                    cellMargin.Top += spaceToFree;
                                    cell.Margin = cellMargin;
                                }
                            }
                            
                            Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveUp Recovered (Margin only): " + spaceToFree.ToString(CultureInfo.InvariantCulture));
                            return spaceToFree;
                        }
                    }
                }
                finally {
                    Row.ResumeLayout(true);
                }
                
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveLeft Recovered Partial (Shrink): " + freedSpace.ToString(CultureInfo.InvariantCulture));
 
                return freedSpace;
            }
 
            private int MoveDown(int index, int spaceToFree) {
            
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveDown: " + spaceToFree.ToString(CultureInfo.InvariantCulture));
                int freedSpace = 0;     
                Row.SuspendLayout();
                try {
                
                    if (spaceToFree == 0 || index < 0 || index >= Row.ControlsInternal.Count) {
                        Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveDown Early EXIT - 0 ");           
                        return 0;
                    }
 
                    
                    ToolStripPanelCell cell;
                    Padding cellMargin;
 
                    // remove all margins after this point in the index.
                    for (int i = index+1; i < Row.Cells.Count; i++) {
                        cell = (ToolStripPanelCell)Row.Cells[i];
                        if (!cell.Visible && !cell.ControlInDesignMode) {
                            continue;
                        }
 
                        int requiredSpace = spaceToFree - freedSpace;
 
                        cellMargin = cell.Margin;
                        
                        if (cellMargin.Vertical >= requiredSpace) {
                            freedSpace += requiredSpace;
                             
                            cellMargin.Top -= requiredSpace;
                            cellMargin.Bottom = 0;
                            cell.Margin = cellMargin;
                            
                        }
                        else {
                            freedSpace += cell.Margin.Vertical;
                            cellMargin.Top = 0;
                            cellMargin.Bottom = 0;
                            cell.Margin = cellMargin;
                        }
 
                        break;
                    }
 
                    // add in the space at the end of the row.
                    if (Row.Cells.Count > 0 && (spaceToFree > freedSpace)) {
                        ToolStripPanelCell lastCell = GetNextVisibleCell(Row.Cells.Count -1, /*forward*/false);
                        if (lastCell != null) {
                            freedSpace += DisplayRectangle.Bottom - lastCell.Bounds.Bottom;
                        }
                        else { 
                            freedSpace += DisplayRectangle.Height;
                        }
                    }
 
                    // set the margin of the control that's moving.
                    if (spaceToFree <= freedSpace) {
                        // add the space we freed to the first guy.
                        cell = (ToolStripPanelCell)Row.Cells[index];
                        cellMargin = cell.Margin;
                        cellMargin.Top += spaceToFree;
                        cell.Margin = cellMargin;
                        
                        Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveDown Recovered (Margin only): " + spaceToFree.ToString(CultureInfo.InvariantCulture));
                        return spaceToFree;
                    }
 
                    // Now start shrinking.
                    for (int i = index+1; i < Row.Cells.Count; i++) {
                        cell = (ToolStripPanelCell)Row.Cells[i];
                        if (!cell.Visible && !cell.ControlInDesignMode) {
                            continue;
                        }                       
                        int requiredSpace = spaceToFree - freedSpace;
                        freedSpace += cell.Shrink(requiredSpace);
                        
                         if (spaceToFree >= freedSpace) {
                            Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveDown Recovered (Shrink): " + spaceToFree.ToString(CultureInfo.InvariantCulture));
                            Row.ResumeLayout(true);
                            return spaceToFree;
                         }
 
                    }
 
                    if (Row.Cells.Count == 1) {
                        cell = GetNextVisibleCell(index,/*forward*/true);
                        if (cell != null) {
                            cellMargin = cell.Margin;
                            cellMargin.Top += freedSpace;
                            cell.Margin = cellMargin;
                        }
                    }
 
                }
                finally {
                    Row.ResumeLayout(true);
                }
 
                int recoveredSpace = spaceToFree - freedSpace;
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveDown Recovered Partial (Shrink): " + recoveredSpace.ToString(CultureInfo.InvariantCulture));
                    
                return recoveredSpace;
            }
 
            protected internal override void OnBoundsChanged(Rectangle oldBounds, Rectangle newBounds) {
    
                base.OnBoundsChanged(oldBounds, newBounds);
                
                // if our bounds have changed - we should shove the toolbars up so they're in view.
                if (Row.Cells.Count > 0) {
    
                    // take a look at the last guy.  if his right edge exceeds
                    // the new bounds, then we should go ahead and push him into view.
                    ToolStripPanelCell lastCell = GetNextVisibleCell(Row.Cells.Count -1, /*forward=*/false);
                    int spaceToFree = (lastCell != null)?  lastCell.Bounds.Bottom - newBounds.Height : 0;
                  
                    if (spaceToFree > 0){
                        // we should shrink the last guy and then move him.
                        ToolStripPanelCell lastCellOnRow = GetNextVisibleCell(Row.Cells.Count-1,  /*forward*/false);
                        
                        Padding cellMargin = lastCellOnRow.Margin;
    
                        // only check margin.left as we are only concerned with getting bottom edge of
                        // the toolstrip into view. (space after the fact doesnt count).
                         if (cellMargin.Top >= spaceToFree) {
                             
                            cellMargin.Top -= spaceToFree;
                            cellMargin.Bottom = 0;
                            lastCellOnRow.Margin = cellMargin;
                            spaceToFree = 0;
    
                        }
                        else {
                            spaceToFree -= lastCellOnRow.Margin.Top;  
                            cellMargin.Top = 0;
                            cellMargin.Bottom = 0;
                            lastCellOnRow.Margin = cellMargin;
                        }
                        spaceToFree -= lastCellOnRow.Shrink(spaceToFree);
                        // start moving the toolstrips before this guy.
                        MoveUp(Row.Cells.Count -1, spaceToFree);
                     }
                   
                }
                
            }
    
         
    
 
            protected internal override void OnControlRemoved(Control c, int index) {
            
            }
 
            protected internal override void OnControlAdded(Control control, int index) {
             
            }
 
      
            public override void JoinRow(ToolStrip toolStripToDrag, Point locationToDrag) {
            
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "Vertical JoinRow called " );
                int index;
            
                if (!Row.ControlsInternal.Contains(toolStripToDrag)) {
                    Row.SuspendLayout();
                    try {
                        if (Row.ControlsInternal.Count > 0) {
            
                            
                            // walk through the columns and determine which column you want to insert into.
                            for (index = 0; index < Row.Cells.Count; index++) {
                                ToolStripPanelCell cell = Row.Cells[index] as ToolStripPanelCell;
                                if (!cell.Visible && !cell.ControlInDesignMode) {
                                    continue;
                                }
                                //  [:   ]  [: x  ]
                                if (cell.Bounds.Contains(locationToDrag)) {
                                    break;
                                }
            
                                // take into account the following scenarios
                                //  [:   ]  x [:   ]
                                // x [:  ]    [:   ]                
                                if (cell.Bounds.Y >= locationToDrag.Y) {
                                    break;
                                }
            
                            }
            
                            Control controlToPushAside = Row.ControlsInternal[index];
                            // Plop the new control in the midst of the row in question.
                            if (index < Row.ControlsInternal.Count) {
                                Row.ControlsInternal.Insert(index, toolStripToDrag);
                            }
                            else {
                                Row.ControlsInternal.Add(toolStripToDrag);
                            }
                            
                            // since layout is suspended the control may not be set to its preferred size yet
                            int controlToDragWidth = (toolStripToDrag.AutoSize) ? toolStripToDrag.PreferredSize.Height : toolStripToDrag.Height;
        
                            //
                            // now make it look like it belongs in the row.
                            //
                            // PUSH the controls after it to the right
                            
                            int requiredSpace = controlToDragWidth;
                            
                            if (index == 0) {
                                // make sure we account for the left side
                                requiredSpace += locationToDrag.Y;
                            }
                            int freedSpace = 0;
                            
                            if (index < Row.ControlsInternal.Count -1) {
                                
                                ToolStripPanelCell nextCell = GetNextVisibleCell(index+1,  /*forward*/true);
                                if (nextCell != null) {
                                    Padding nextCellMargin =  nextCell.Margin;
                
                                    // if we've already got the empty space
                                    // (available to us via the margin) use that.
                                    if (nextCellMargin.Top > requiredSpace) {
                                        nextCellMargin.Top -= requiredSpace;
                                        nextCell.Margin = nextCellMargin;                                         
                                        freedSpace = requiredSpace;
                                    }
                                    else {
                                        // otherwise we've got to 
                                        // push all controls after this point to the right 
                                        // this dumps the extra stuff into the margin of index+1
                                        freedSpace = MoveDown(index+1, requiredSpace - freedSpace);
                
                                        // refetch the margin for "index+1" and remove the freed space 
                                        // from it - we want to actually put this to use on the control
                                        // before this one - we're making room for the control at 
                                        // position "index"
                                        if (freedSpace > 0) {
                                            nextCellMargin =  nextCell.Margin;
                                            nextCellMargin.Top -= freedSpace;
                                            nextCell.Margin = nextCellMargin; 
                                        }
                                   
                                    }
                                }
                                
                    
                            }
                            else {
                                 // we're adding to the end.
                                ToolStripPanelCell nextCell = GetNextVisibleCell(Row.Cells.Count-2,  /*forward*/false);
                                ToolStripPanelCell lastCell = GetNextVisibleCell(Row.Cells.Count-1,  /*forward*/false);
                           
                                // count the stuff at the end of the row as freed space
                                if (nextCell != null && lastCell != null) {
                                    Padding lastCellMargin =  lastCell.Margin;
                                    lastCellMargin.Top = Math.Max(0,locationToDrag.Y - nextCell.Bounds.Bottom);
                                    lastCell.Margin = lastCellMargin;
                                    freedSpace=requiredSpace;
                                }     
                                           
                            }
                            
                            // If we still need more space, then...
                            // PUSH the controls before it to the left
                            if (freedSpace < requiredSpace && index > 0) {
                                freedSpace = MoveUp(index - 1, requiredSpace - freedSpace);
                            }
 
                            
                            if (index == 0) {
                                // if the index is zero and there were controls in the row
                                // we need to take care of pushing over the new cell.
                                if (freedSpace - controlToDragWidth > 0) {
                                    ToolStripPanelCell newCell = Row.Cells[index] as ToolStripPanelCell;
                                    Padding newCellMargin =  newCell.Margin;
                                    newCellMargin.Top = freedSpace - controlToDragWidth;
                                    newCell.Margin = newCellMargin;
                                }
                            }
                           
                        }
                        else {
                            
                            // we're adding to the beginning.
                            Row.ControlsInternal.Add(toolStripToDrag);
 
#if DEBUG
                            ISupportToolStripPanel ctg = toolStripToDrag as ISupportToolStripPanel;
                            ToolStripPanelRow newPanelRow = ctg.ToolStripPanelRow;
                            Debug.Assert(newPanelRow == Row, "we should now be in the new panel row.");
#endif
                            if (Row.Cells.Count >0) {                            
                                ToolStripPanelCell cell = GetNextVisibleCell(Row.Cells.Count-1, /*forward*/false);
                                if (cell != null) {
                                    Padding cellMargin = cell.Margin;
                                    cellMargin.Top = Math.Max(0,locationToDrag.Y-Row.Margin.Top);
                                    cell.Margin = cellMargin;
                                }
                            }
                        }
                    }
                    finally {
                        Row.ResumeLayout(true);
                    }
                }
            }
        
            public override void LeaveRow(ToolStrip toolStripToDrag) {
                // this code is here to properly add space to the next control when the
                // toolStripToDrag has been removed from the row.
                Row.SuspendLayout();
                int index = Row.ControlsInternal.IndexOf(toolStripToDrag);
                if (index >= 0) {
                    if (index < Row.ControlsInternal.Count -1 /*not the last one in the row*/) {
                
                        ToolStripPanelCell cell = (ToolStripPanelCell)Row.Cells[index];
                        if (cell.Visible) {
                            int spaceOccupiedByCell = cell.Margin.Vertical + cell.Bounds.Height;
                
                            // add the space occupied by the cell to the next one.
                            ToolStripPanelCell nextCell = GetNextVisibleCell(index+1, /*forward*/true);
                            if (nextCell != null) {
                                Padding nextCellMargin = nextCell.Margin;
                                nextCellMargin.Top += spaceOccupiedByCell;
                                nextCell.Margin = nextCellMargin;
                            }
                        }
                    }
                    // remove the control from the row.
                    ((IList)Row.Cells).RemoveAt(index);
                }
                Row.ResumeLayout(true);
            }
        }
      
        
 
        /// <devdoc>
        /// ToolStripPanelRowControlCollection
        ///
        /// this class represents the collection of controls on a particular row.
        /// when you add and remove controls from this collection - you also add and remove
        /// controls to and from the ToolStripPanel.Control's collection (which happens 
        /// to be externally readonly.)
        /// 
        /// This class is used to represent the IArrangedElement.Children for the ToolStripPanelRow -
        /// which means that this collection represents the IArrangedElements to layout for 
        /// a particular ToolStripPanelRow.
        ///
        /// We need to keep copies of the controls in both the ToolStripPanelRowControlCollection and
        /// the ToolStripPanel.Control collection  as the ToolStripPanel.Control collection
        /// is responsible for parenting and unparenting the controls (ToolStripPanelRows do NOT derive from 
        /// Control and thus are NOT hwnd backed).
        /// </devdoc>
        /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRowControlCollection"]/*' />
        internal class ToolStripPanelRowControlCollection : ArrangedElementCollection, IList, IEnumerable {
            private ToolStripPanelRow owner;
            private ArrangedElementCollection cellCollection;
            
            /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRowControlCollection.ToolStripPanelRowControlCollection"]/*' />
            public ToolStripPanelRowControlCollection(ToolStripPanelRow owner) {
                this.owner = owner;
            }
 
 
            /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRowControlCollection.ToolStripPanelRowControlCollection1"]/*' />
            public ToolStripPanelRowControlCollection(ToolStripPanelRow owner, Control[] value) {
                this.owner = owner;
                AddRange(value);
            }
 
            /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRowControlCollection.this"]/*' />
            public new virtual Control this[int index] {
                get {
                    return GetControl(index);
                }
            }
 
            public ArrangedElementCollection Cells {
                get { 
                    if (cellCollection == null) {
                        cellCollection = new ArrangedElementCollection(InnerList);
                    }
                    return cellCollection;
                }
            }
    
 
            /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRowControlCollection.ToolStripPanel"]/*' />
            public ToolStripPanel ToolStripPanel {
                get {
                    return owner.ToolStripPanel;
                }
            }
 
            /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRowControlCollection.Add"]/*' />
            /// <devdoc>
            /// <para>[To be supplied.]</para>
            /// </devdoc>
            [EditorBrowsable(EditorBrowsableState.Never)]
            public int Add(Control value) {
                ISupportToolStripPanel control = value as ISupportToolStripPanel;
                
                if (value == null) {
                    throw new ArgumentNullException("value");
                }
                if (control == null) {
                    throw new NotSupportedException(SR.GetString(SR.TypedControlCollectionShouldBeOfType, typeof(ToolStrip).Name));                 
                }
 
                int index = InnerList.Add(control.ToolStripPanelCell);
 
                OnAdd(control, index);
                return index;
            }
 
            /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRowControlCollection.AddRange"]/*' />
            /// <devdoc>
            /// <para>[To be supplied.]</para>
            /// </devdoc>
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
            [EditorBrowsable(EditorBrowsableState.Never)]
            public void AddRange(Control[] value) {
                if (value == null) {
                    throw new ArgumentNullException("value");
                }
 
                ToolStripPanel currentOwner = ToolStripPanel;
 
                if (currentOwner != null) {
                    currentOwner.SuspendLayout();
                }
 
                try {
                    for (int i = 0; i < value.Length; i++) {
                        this.Add(value[i]);
                    }
                }
                finally {
                    if (currentOwner != null) {
                        currentOwner.ResumeLayout();
                    }
                }
            }
 
            /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRowControlCollection.Contains"]/*' />
            /// <devdoc>
            /// <para>[To be supplied.]</para>
            /// </devdoc>
            public bool Contains(Control value) {
                for (int i = 0; i < Count; i++) {
                    if (GetControl(i) == value) {
                        return true;
                    }
                }
                return false;
            }
 
            /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRowControlCollection.Clear"]/*' />
            /// <devdoc>
            /// <para>[To be supplied.]</para>
            /// </devdoc>
            public virtual void Clear() {
                if (owner != null) {
                    ToolStripPanel.SuspendLayout();
                }
 
                try {
                    while (Count != 0) {
                        RemoveAt(Count - 1);
                    }
                }
                finally {
                    if (owner != null) {
                        ToolStripPanel.ResumeLayout();
                    }
                }
            }
 
            public override IEnumerator GetEnumerator() { return new ToolStripPanelCellToControlEnumerator(InnerList); }
 
            private Control GetControl(int index) {
                Control control = null;
                ToolStripPanelCell cell = null;
 
                if (index < Count && index >= 0) {
                    cell  = (ToolStripPanelCell)(InnerList[index]);
                    control = (cell != null) ? cell.Control : null;
                }
                return control;
 
            }
            private int IndexOfControl(Control c) {
                for (int i = 0; i < Count; i++) {
                    ToolStripPanelCell cell  = (ToolStripPanelCell)(InnerList[i]);
                    if (cell.Control == c) {
                        return i;
                    }
                }
                return -1;
                
            }
           
           
                
 
            void IList.Clear() { Clear(); }
 
            bool IList.IsFixedSize { get { return InnerList.IsFixedSize; } }
 
            bool IList.Contains(object value) { return InnerList.Contains(value); }
 
            bool IList.IsReadOnly { get { return InnerList.IsReadOnly; } }
 
            void IList.RemoveAt(int index) { RemoveAt(index); }
 
            void IList.Remove(object value) { Remove(value as Control); }
 
            int IList.Add(object value) { return Add(value as Control); }
 
            int IList.IndexOf(object value) { return IndexOf(value as Control); }
 
            void IList.Insert(int index, object value) { Insert(index, value as Control); }
 
            /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRowControlCollection.IndexOf"]/*' />
            /// <devdoc>
            /// <para>[To be supplied.]</para>
            /// </devdoc>
            public int IndexOf(Control value) {
                for (int i = 0; i < Count; i++) {
                    if (GetControl(i) == value) {
                        return i;
                    }
                }
                return -1;
            }
 
            /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRowControlCollection.Insert"]/*' />
            /// <devdoc>
            /// <para>[To be supplied.]</para>
            /// </devdoc>
            [EditorBrowsable(EditorBrowsableState.Never)]
            public void Insert(int index, Control value) {
                if (value == null) {
                    throw new ArgumentNullException("value");
                }
                ISupportToolStripPanel control = value as ISupportToolStripPanel;
                if (control == null) {
                    throw new NotSupportedException(SR.GetString(SR.TypedControlCollectionShouldBeOfType, typeof(ToolStrip).Name));
                }
 
                InnerList.Insert(index, control.ToolStripPanelCell);
                OnAdd(control, index);
            }
 
            /// <devdoc>
            ///  Do proper cleanup of ownership, etc.
            /// </devdoc>
            private void OnAfterRemove(Control control, int index) {
                if (owner != null) {
                    // unfortunately we dont know the index of the control in the ToolStripPanel's 
                    // control collection, as all rows share this collection.
                    // To unparent this control we need to use Remove instead  of RemoveAt.
                    using (LayoutTransaction t = new LayoutTransaction(ToolStripPanel, control, PropertyNames.Parent)) {
                        owner.ToolStripPanel.Controls.Remove(control);
                        owner.OnControlRemoved(control, index);
                    }
                }
            }
 
            private void OnAdd(ISupportToolStripPanel controlToBeDragged, int index) {
                if (owner != null) {
                    LayoutTransaction layoutTransaction = null;
                    if (ToolStripPanel != null && ToolStripPanel.ParentInternal != null) {
                        layoutTransaction = new LayoutTransaction(ToolStripPanel, ToolStripPanel.ParentInternal, PropertyNames.Parent);
 
                    }
                    try {
 
                        if (controlToBeDragged != null) {
                            
                            controlToBeDragged.ToolStripPanelRow = owner;
 
                            Control control = controlToBeDragged as Control;
 
                            if (control != null) {
                                control.ParentInternal = owner.ToolStripPanel;
                                owner.OnControlAdded(control, index);
                            }
                        }                      
                         
                    } 
                    finally {
                        if (layoutTransaction != null) {
                            layoutTransaction.Dispose();
                        }
                    }
 
                }
            }
 
            /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRowControlCollection.Remove"]/*' />
            /// <devdoc>
            /// <para>[To be supplied.]</para>
            /// </devdoc>
            
            [EditorBrowsable(EditorBrowsableState.Never)]
            public void Remove(Control value) {
                int index = IndexOfControl(value);
                RemoveAt(index);
            }
 
            /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRowControlCollection.RemoveAt"]/*' />
            /// <devdoc>
            /// <para>[To be supplied.]</para>
            /// </devdoc>
            [EditorBrowsable(EditorBrowsableState.Never)]
            public void RemoveAt(int index) {
                if (index >= 0 && index < Count) {
                    Control control = GetControl(index);
                    ToolStripPanelCell cell = InnerList[index] as ToolStripPanelCell;
                    InnerList.RemoveAt(index);
                    OnAfterRemove(control, index);
                }
            }
 
            /// <include file='doc\ToolStripPanelRow.uex' path='docs/doc[@for="ToolStripPanelRowControlCollection.CopyTo"]/*' />
            /// <devdoc>
            /// <para>[To be supplied.]</para>
            /// </devdoc>
            [EditorBrowsable(EditorBrowsableState.Never)]
            public void CopyTo(Control[] array, int index) {
                if (array == null) {
                    throw new ArgumentNullException("array");
                }
 
                if (index < 0) {
                    throw new ArgumentOutOfRangeException("index");
                }
 
                if (index >= array.Length || InnerList.Count > array.Length - index) {
                    throw new ArgumentException(SR.GetString(SR.ToolStripPanelRowControlCollectionIncorrectIndexLength));
                }
 
                for (int i = 0; i < InnerList.Count; i++) {
                    array[index++] = GetControl(i);                  
                }                
            }
            
            /// We want to pretend like we're only holding controls... so everywhere we've returned controls.
            /// but the problem is if you do a foreach, you'll get the cells not the controls.  So we've got
            /// to sort of write a wrapper class around the ArrayList enumerator.
            private class ToolStripPanelCellToControlEnumerator : IEnumerator, ICloneable {                            
                private IEnumerator arrayListEnumerator; 
 
                internal ToolStripPanelCellToControlEnumerator(ArrayList list) {
                    arrayListEnumerator = ((IEnumerable)list).GetEnumerator();
                }
           
                public virtual Object Current {
                    get {
                        ToolStripPanelCell cell = arrayListEnumerator.Current as ToolStripPanelCell;
                        Debug.Assert(cell != null, "Expected ToolStripPanel cells only!!!" + arrayListEnumerator.Current.GetType().ToString());
                        return (cell == null) ? null : cell.Control;
                    }
                }
            
            
                public Object Clone() {
                    return MemberwiseClone();
                }
            
                public virtual bool MoveNext() {
                    return arrayListEnumerator.MoveNext();
                }
            
                public virtual void Reset() {
                    arrayListEnumerator.Reset();
                }
            }
        }
    }
}