public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
		{
			if(destinationType==null)
				throw new ArgumentNullException("destinationType");

			if((destinationType==typeof(InstanceDescriptor)) && (value is DocumentDockContainer))
			{
				DocumentDockContainer doc=(DocumentDockContainer)value;
				Type[] constructorParams=null;
				MemberInfo constructorMemberInfo = null;
				object[] constructorValues = null;

				if(doc.Documents.Count==0)
				{
					constructorParams = new Type[0];
					constructorMemberInfo = typeof(DocumentDockContainer).GetConstructor(constructorParams);
					constructorValues = new object[0];
				}
				else
				{
					constructorParams = new Type[2] { typeof(DocumentBaseContainer[]), typeof(eOrientation) } ;
					constructorMemberInfo = typeof(DocumentDockContainer).GetConstructor(constructorParams);
					DocumentBaseContainer[] documentsArray = new DocumentBaseContainer[doc.Documents.Count];
					doc.Documents.CopyTo(documentsArray);
					constructorValues=new object[2] {documentsArray,doc.Orientation};
				}

				if(constructorMemberInfo!=null)
				{
					return new InstanceDescriptor(constructorMemberInfo, constructorValues);
				}
			}

			return base.ConvertTo(context, culture, value, destinationType);
		}
		/// <summary>
		/// Creates new instance of the object and initializes it with specified values.
		/// </summary>
		/// <param name="documents">Array of documents to host in this container.</param>
		/// <param name="orientation">Container orientation</param>
		public DocumentDockContainer(DocumentBaseContainer[] documents, eOrientation orientation)
		{
			m_Orientation=orientation;
			m_Documents.Owner=this;
			m_Documents.DocumentAdded+=new EventHandler(DocumentAdded);
			m_Documents.DocumentRemoved+=new EventHandler(DocumentRemoved);

			if(documents!=null)
			{
				foreach(DocumentBaseContainer doc in documents)
					m_Documents.Add(doc);
			}
		}
		/// <summary>
		/// Occurs when height is being set on child document.
		/// </summary>
		/// <param name="doc">Reference document being changed</param>
		/// <param name="height">Height in pixels</param>
		/// <returns>True if width was applied by parent otherwise false</returns>
		protected internal override bool OnSetHeight(DocumentBaseContainer doc, int height)
		{
			bool ret=false;
			if(m_Orientation!=eOrientation.Vertical || height<doc.MinimumSize.Height && doc.MinimumSize.Height>0)
				return ret;

			DocumentBaseContainer pairDoc=null;
			DocumentBaseContainer previousDoc=null;

			int refIndex=m_Documents.IndexOf(doc);

			// Lock in the display size if it is set
			for(int i=0;i<m_Documents.Count;i++)
			{
				DocumentBaseContainer dc=m_Documents[i];
                if (!dc.Visible) continue;
				if(dc.DisplayBounds.Height>0)
					dc.SetLayoutBounds(dc.DisplayBounds);
				if(i>refIndex && dc.Visible && pairDoc==null)
					pairDoc=dc;
				else if(i<refIndex && dc.Visible)
					previousDoc=dc;
			}

			if(pairDoc==null) pairDoc=previousDoc;

			int diff=doc.LayoutBounds.Height-height;
			if(pairDoc!=null && pairDoc.LayoutBounds.Height>0 && pairDoc.LayoutBounds.Height+diff>0 && 
				(pairDoc.LayoutBounds.Height+diff>=pairDoc.MinimumSize.Height || pairDoc.MinimumSize.Height==0))
			{
				pairDoc.SetLayoutBounds(new Rectangle(pairDoc.LayoutBounds.X,pairDoc.LayoutBounds.Y,pairDoc.LayoutBounds.Width,pairDoc.LayoutBounds.Height+diff));
				ret=true;
			}
            else if (pairDoc == null && previousDoc != null && previousDoc.LayoutBounds.Height > 0 && previousDoc.LayoutBounds.Height + diff > 0 &&
                (previousDoc.LayoutBounds.Height + diff >= previousDoc.MinimumSize.Height || previousDoc.MinimumSize.Height == 0))
            {
                doc.SetLayoutBounds(new Rectangle(doc.LayoutBounds.X, doc.LayoutBounds.Y, doc.LayoutBounds.Width, height));
                previousDoc.SetLayoutBounds(new Rectangle(previousDoc.LayoutBounds.X, previousDoc.LayoutBounds.Y, previousDoc.LayoutBounds.Width, 0));
                ret = true;
            }
			return ret;
		}
		/// <summary>
		/// Occurs when width is being set on child document.
		/// </summary>
		/// <param name="doc">Reference document being changed</param>
		/// <param name="width">Width in pixels</param>
		/// <returns>True if width was applied by parent otherwise false</returns>
		protected internal override bool OnSetWidth(DocumentBaseContainer doc, int width)
		{
			bool ret=false;
			if(m_Orientation!=eOrientation.Horizontal || width<doc.MinimumSize.Width && doc.MinimumSize.Width>0)
				return ret;

			DocumentBaseContainer pairDoc=null;
			DocumentBaseContainer previousDoc=null;

			int refIndex=m_Documents.IndexOf(doc);

			// Lock in the display size if it is set
			for(int i=0;i<m_Documents.Count;i++)
			{
				DocumentBaseContainer dc=m_Documents[i];
                if (!dc.Visible) continue;
				if(dc.DisplayBounds.Width>0)
					dc.SetLayoutBounds(dc.DisplayBounds);
				if(i>refIndex && dc.Visible && pairDoc==null)
					pairDoc=dc;
				else if(i<refIndex && dc.Visible)
					previousDoc=dc;
			}

			int diff=doc.LayoutBounds.Width-width;
			if(pairDoc!=null && pairDoc.LayoutBounds.Width>0 && pairDoc.LayoutBounds.Width+diff>0 && 
				(pairDoc.LayoutBounds.Width+diff>=pairDoc.MinimumSize.Width || pairDoc.MinimumSize.Width==0))
			{
				pairDoc.SetLayoutBounds(new Rectangle(pairDoc.LayoutBounds.X,pairDoc.LayoutBounds.Y,pairDoc.LayoutBounds.Width+diff,pairDoc.LayoutBounds.Height));
				ret=true;
			}
            else if (pairDoc == null && previousDoc != null && previousDoc.LayoutBounds.Width > 0 && previousDoc.LayoutBounds.Width + diff > 0 &&
                (previousDoc.LayoutBounds.Width + diff >= previousDoc.MinimumSize.Width || previousDoc.MinimumSize.Width == 0))
            {
                doc.SetLayoutBounds(new Rectangle(doc.LayoutBounds.X, doc.LayoutBounds.Y, width, doc.LayoutBounds.Height));
                // Resetting previous document width caused problem with ever growing bar when Width of single bar is set
                // Reason is that resetting width here will cause the new space in container to be proportionally allocated thus setting single bar width which is intent of this function never works
                //previousDoc.SetLayoutBounds(new Rectangle(previousDoc.LayoutBounds.X, previousDoc.LayoutBounds.Y, 0, previousDoc.LayoutBounds.Height));
                ret = true;
            }

			return ret;
		}
		/// <summary>
		/// Occurs when width is being set on child document.
		/// </summary>
		/// <param name="doc">Reference document being changed</param>
		/// <param name="width">Width in pixels</param>
		/// <returns>True if width was applied by parent otherwise false</returns>
		protected internal virtual bool OnSetWidth(DocumentBaseContainer doc, int width){return false;}
		/// <summary>
		/// Removes specified object from the collection.
		/// </summary>
		/// <param name="value"></param>
		public void Remove(DocumentBaseContainer value) 
		{
			List.Remove(value);
		}
		/// <summary>
		/// Inserts new object into the collection.
		/// </summary>
		/// <param name="index">Position of the object.</param>
		/// <param name="value">Object to insert.</param>
		public void Insert(int index, DocumentBaseContainer value) 
		{
			List.Insert(index, value);
		}
		public void OnMouseDown(MouseEventArgs e)
		{
			int x=e.X, y=e.Y;
			if(e.Button==MouseButtons.Left)
			{
				m_MouseDownPoint=new Point(x,y);
				DocumentDockContainer context=this.GetContainerFromRoot(x,y);
                
                if(context!=null)
				{
					m_ResizeDocument=this.GetClosestDocument(context,x,y);
					if(m_ResizeDocument==null)
						return;
					m_ResizeDockContainer=context;
					if(!m_ResizePreview)
					{
						CreateSplitter();
						SplitterMouseMove(x,y);
					}
				}
                else if (m_Container != null && m_Container.Dock != DockStyle.Fill)
                {
                    m_ResizeDockContainer = m_DocumentDockContainer;
                    if (!m_ResizePreview)
                    {
                        CreateSplitter();
                        SplitterMouseMove(x, y);
                    }
                }
			}
		}
		/// <summary>
		/// Adds new object to the collection.
		/// </summary>
		/// <param name="tab">Object to add.</param>
		/// <returns>Index of newly added object.</returns>
		public int Add(DocumentBaseContainer tab)
		{
			return List.Add(tab);
		}
		/// <summary>
		/// Adds new objects to the collection.
		/// </summary>
		/// <param name="documents">Array of documents to add.</param>
		public void AddRange(DocumentBaseContainer[] documents)
		{
			foreach(DocumentBaseContainer doc in documents)
				List.Add(doc);
		}
		/// <summary>
		/// Copies contained items to the DocumentBaseContainer array.
		/// </summary>
		/// <param name="array">Array to copy to.</param>
		internal void CopyTo(DocumentBaseContainer[] array)
		{
			List.CopyTo(array,0);
		}
		/// <summary>
		/// Copies collection into the specified array.
		/// </summary>
		/// <param name="array">Array to copy collection to.</param>
		/// <param name="index">Starting index.</param>
		public void CopyTo(DocumentBaseContainer[] array, int index) 
		{
			List.CopyTo(array, index);
		}
		/// <summary>
		/// Occurs when height is being set on child document.
		/// </summary>
		/// <param name="doc">Reference document being changed</param>
		/// <param name="height">Height in pixels</param>
		/// <returns>True if width was applied by parent otherwise false</returns>
		protected internal virtual bool OnSetHeight(DocumentBaseContainer doc, int height){return false;}
        /// <summary>
        /// Docks specified bar by appending it to the container. Bar will be added according to the container's orientation.
        /// </summary>
        /// <param name="barToDock">Bar to dock.</param>
        /// <param name="dockSide">Side to dock bar at.</param>
		public void Dock(Bar referenceBar, Bar barToDock, eDockSide dockSide)
		{
			if(dockSide==eDockSide.None && barToDock.Parent==m_Container)
			{
				ApplyBarStyle(barToDock);
				return;
			}

			if(barToDock.Parent is DockSite && ((DockSite)barToDock.Parent).DocumentDockContainer!=null)
				((DockSite)barToDock.Parent).GetDocumentUIManager().UnDock(barToDock);
			else if(barToDock.Parent is DockSite && barToDock.Parent!=m_Container)
				((DockSite)barToDock.Parent).RemoveBar(barToDock);
            else if (barToDock.Parent != null && barToDock.Parent != m_Container)
            {
                if (barToDock.Parent is FloatingContainer)
                {
                    barToDock.RemoveFromFloatingContainer();
                    barToDock.SetBarState(eBarState.Docked);
                }
                else
                    barToDock.Parent.Controls.Remove(barToDock);
            }

			if(!m_LoadingLayout)
			{
				// TODO: Add Docking as Document, i.e. add DockContainerItems from barToDock...
				DocumentBarContainer doc=this.CreateDocumentBarContainer(barToDock);
                DocumentBaseContainer referenceDoc = this.GetDocumentFromBar(referenceBar);

                if (referenceBar == null || dockSide == eDockSide.None || referenceBar == barToDock || referenceDoc == null)
				{
                    if (m_Container.Dock == DockStyle.Fill)
                        m_DocumentDockContainer.Documents.Add(doc);
                    else
                    {
                        eOrientation containerOrientation = eOrientation.Horizontal; // Needed container orientation
                        if (m_Container.Dock == DockStyle.Top || m_Container.Dock == DockStyle.Bottom)
                            containerOrientation = eOrientation.Vertical;

                        // Switch orientation when adding new bar if possible
                        if (m_DocumentDockContainer.Orientation != containerOrientation)
                        {
                            if (m_DocumentDockContainer.Documents.Count <= 1)
                            {
                                m_DocumentDockContainer.Orientation = containerOrientation;
                                if (IsAddedInFront(dockSide))
                                    m_DocumentDockContainer.Documents.Insert(0, doc);
                                else
                                    m_DocumentDockContainer.Documents.Add(doc);
                            }
                            else
                            {
                                DocumentBaseContainer[] docs = new DocumentBaseContainer[m_DocumentDockContainer.Documents.Count];
                                m_DocumentDockContainer.Documents.CopyTo(docs);
                                m_DocumentDockContainer.Documents.Clear();

                                DocumentDockContainer newParent = new DocumentDockContainer(docs, m_DocumentDockContainer.Orientation);
								newParent.SetLayoutBounds(m_DocumentDockContainer.DisplayBounds);
                                m_DocumentDockContainer.Orientation = containerOrientation;
                                m_DocumentDockContainer.Documents.Add(newParent);
                                if (IsAddedInFront(dockSide))
                                    m_DocumentDockContainer.Documents.Insert(0, doc);
                                else
                                    m_DocumentDockContainer.Documents.Add(doc);
                            }
                        }
                        else
                        {
                            if (IsAddedInFront(dockSide))
                                m_DocumentDockContainer.Documents.Insert(0, doc);
                            else
                                m_DocumentDockContainer.Documents.Add(doc);
                        }
                    }
				}
				else
				{
					DocumentDockContainer parent=referenceDoc.Parent as DocumentDockContainer;

					referenceDoc.SetLayoutBounds(Rectangle.Empty);
					doc.SetLayoutBounds(Rectangle.Empty);

					if((parent.Orientation==eOrientation.Horizontal && (dockSide==eDockSide.Left || dockSide==eDockSide.Right)) ||
						(parent.Orientation==eOrientation.Vertical && (dockSide==eDockSide.Top || dockSide==eDockSide.Bottom)))
					{
						if(dockSide==eDockSide.Right || dockSide==eDockSide.Bottom)
							parent.Documents.Insert(parent.Documents.IndexOf(referenceDoc)+1,doc);
						else
							parent.Documents.Insert(parent.Documents.IndexOf(referenceDoc),doc);
					}
					else if(parent.Documents.Count==1)
					{
						// Orientation of the parent dock container can be changed
						if(parent.Orientation==eOrientation.Vertical)
							parent.Orientation=eOrientation.Horizontal;
						else
							parent.Orientation=eOrientation.Vertical;

						if(dockSide==eDockSide.Right || dockSide==eDockSide.Bottom)
							parent.Documents.Insert(parent.Documents.IndexOf(referenceDoc)+1,doc);
						else
							parent.Documents.Insert(parent.Documents.IndexOf(referenceDoc),doc);
					}
					else
					{
						// New DocumentDockContainer needs to be inserted with appropriate orientation and referenceBar needs
						// to be moved into it.
						DocumentDockContainer newParent=new DocumentDockContainer();
						if(parent.Orientation==eOrientation.Horizontal)
							newParent.Orientation=eOrientation.Vertical;
						else
							newParent.Orientation=eOrientation.Horizontal;

						parent.Documents.Insert(parent.Documents.IndexOf(referenceDoc),newParent);
						parent.Documents.Remove(referenceDoc);
	                    
						if(dockSide==eDockSide.Right || dockSide==eDockSide.Bottom)
						{
							newParent.Documents.Add(referenceDoc);
							newParent.Documents.Add(doc);
						}
						else
						{
							newParent.Documents.Add(doc);
							newParent.Documents.Add(referenceDoc);
						}
					}
				}

                AdjustContainerSize(barToDock, false);
			}

			if(m_Container!=null)
			{
				if(barToDock.Parent==null)
					m_Container.Controls.Add(barToDock);
                ApplyBarStyle(barToDock);	
				m_Container.RecalcLayout();
			}
			else
				ApplyBarStyle(barToDock);
		}
		/// <summary>
		/// Returns index of the object inside of the collection.
		/// </summary>
		/// <param name="value">Reference to the object.</param>
		/// <returns>Index of the object.</returns>
		public int IndexOf(DocumentBaseContainer value) 
		{
			return List.IndexOf(value);
		}
		private void RemoveEmptyContainers(DocumentDockContainer parent)
		{
			while(parent.Documents.Count==0 && parent.Parent!=null && parent.Parent is DocumentDockContainer ||
				parent.Parent!=null && parent.Parent is DocumentDockContainer && ((DocumentDockContainer)parent.Parent).Documents.Count==1)
			{
				if(parent.Parent!=null && parent.Parent is DocumentDockContainer && ((DocumentDockContainer)parent.Parent).Documents.Count==1)
				{
					// Removes the instances where DocumentDockContainer hosts another one and only one DocumentDockContainer object
					DocumentDockContainer p=parent.Parent as DocumentDockContainer;
					p.Documents.Remove(parent);
					p.Orientation=parent.Orientation;
					DocumentBaseContainer[] documents=new DocumentBaseContainer[parent.Documents.Count];
					parent.Documents.CopyTo(documents);
					p.Documents.AddRange(documents);
					parent=p;
				}
				else
				{
					DocumentDockContainer p=parent.Parent as DocumentDockContainer;
					p.Documents.Remove(parent);
					parent=p;
				}
			}
		}
		/// <summary>
		/// Returns whether collection contains specified object.
		/// </summary>
		/// <param name="value">Object to look for.</param>
		/// <returns>true if object is part of the collection, otherwise false.</returns>
		public bool Contains(DocumentBaseContainer value) 
		{
			return List.Contains(value);
		}
		public void OnMouseUp(MouseEventArgs e)
		{
			if(m_ResizeDockContainer!=null && !m_MouseDownPoint.IsEmpty)
			{
				ResizeTo(e.X,e.Y);
			}

			m_MouseDownPoint=Point.Empty;
			m_ResizeDockContainer=null;
			m_ResizeDocument=null;
			DestroySplitter();
		}
		/// <summary>
		/// Sets the parent document.
		/// </summary>
		/// <param name="parent">Parent container.</param>
		internal void SetParent(DocumentBaseContainer parent)
		{
			m_Parent=parent;
		}