context: using System;
  using System.Collections.Generic;
  using System.Text;
  using System.Collections.ObjectModel;
  using System.Drawing;
  using System.Windows.Forms;
  using System.Runtime.Serialization;
  using System.Security.Permissions;
  
  namespace Aga.Controls.Tree
  {
  	[Serializable]
  	public class TreeNodeAdv : ISerializable
  	{
  		#region NodeCollection
  		private class NodeCollection : Collection<TreeNodeAdv>
  		{
  			private TreeNodeAdv _owner;
  
  			public NodeCollection(TreeNodeAdv owner)
  			{
  				_owner = owner;
  			}
  
  			protected override void ClearItems()
  			{
  				while (this.Count != 0)
  					this.RemoveAt(this.Count - 1);
  			}
  
  			protected override void InsertItem(int index, TreeNodeAdv item)
  			{
  				if (item == null)
  					throw new ArgumentNullException("item");
  
  				if (item.Parent != _owner)
  				{
  					if (item.Parent != null)
  						item.Parent.Nodes.Remove(item);
  					item._parent = _owner;
  					item._index = index;
  					for (int i = index; i < Count; i++)
  						this[i]._index++;
  					base.InsertItem(index, item);
  				}
  				
  				if (_owner.Tree != null && _owner.Tree.Model == null) {
  					_owner.Tree.SmartFullUpdate();
  				}
  			}
  
  			protected override void RemoveItem(int index)
  			{
  				TreeNodeAdv item = this[index];
  				item._parent = null;
  				item._index = -1;
  				for (int i = index + 1; i < Count; i++)
  					this[i]._index--;
  				base.RemoveItem(index);
  				
  				if (_owner.Tree != null && _owner.Tree.Model == null) {
  					_owner.Tree.UpdateSelection();
  					_owner.Tree.SmartFullUpdate();
  				}
  			}
  
  			protected override void SetItem(int index, TreeNodeAdv item)
  			{
  				if (item == null)
  					throw new ArgumentNullException("item");
  				RemoveAt(index);
  				InsertItem(index, item);
  			}
  		}
  		#endregion
  
  		#region Events
  		
  		public event EventHandler<TreeViewAdvEventArgs> Collapsing;
  		internal protected virtual void OnCollapsing()
  		{
  			if (Collapsing != null)
  				Collapsing(this, new TreeViewAdvEventArgs(this));
  		}
  
  		public event EventHandler<TreeViewAdvEventArgs> Collapsed;
  		internal protected virtual void OnCollapsed()
  		{
  			if (Collapsed != null)
  				Collapsed(this, new TreeViewAdvEventArgs(this));
  		}
  
  		public event EventHandler<TreeViewAdvEventArgs> Expanding;
  		internal protected virtual void OnExpanding()
  		{
  			if (Expanding != null)
  				Expanding(this, new TreeViewAdvEventArgs(this));
  		}
  
  		public event EventHandler<TreeViewAdvEventArgs> Expanded;
  		internal protected virtual void OnExpanded()
  		{
  			if (Expanded != null)
  				Expanded(this, new TreeViewAdvEventArgs(this));
  		}
  		
  		#endregion
  		
  		#region Properties
  
  		private TreeViewAdv _tree;
  		public TreeViewAdv Tree
  		{
  			get { return _tree; }
  		}
  
  		private int _row;
  		internal int Row
  		{
  			get { return _row; }
  			set { _row = value; }
  		}
  
  		private int _index = -1;
  		public int Index
  		{
  			get
  			{
  				return _index;
  			}
  		}
  
  		private bool _isSelected;
  		public bool IsSelected
  		{
  			get { return _isSelected; }
  			set 
  			{
  				if (_isSelected != value)
  				{
  					if (Tree.IsMyNode(this))
  					{
  						//_tree.OnSelectionChanging
  						if (value)
  						{
  							if (!_tree.Selection.Contains(this))
  								_tree.Selection.Add(this);
  
  							if (_tree.Selection.Count == 1)
  								_tree.CurrentNode = this;
  						}
  						else
  							_tree.Selection.Remove(this);
  						_tree.UpdateView();
  						_tree.OnSelectionChanged();
  					}
  					_isSelected = value;
  				}
  			}
  		}
  
  		/// <summary>
  		/// Returns true if all parent nodes of this node are expanded.
  		/// </summary>
  		internal bool IsVisible
  		{
  			get
  			{
  				TreeNodeAdv node = _parent;
  				while (node != null)
  				{
  					if (!node.IsExpanded)
  						return false;
  					node = node.Parent;
  				}
  				return true;
  			}
  		}
  
  		private bool _isLeaf;
  		public bool IsLeaf
  		{
  			get { return _isLeaf; }
  			internal protected set { _isLeaf = value; }
  		}
  
  		private bool _isExpandedOnce;
  		public bool IsExpandedOnce
  		{
  			get { return _isExpandedOnce; }
  			internal protected set { _isExpandedOnce = value; }
  		}
  
  		private bool _isExpanded;
  		public bool IsExpanded
  		{
              get { return _isExpanded; }
              set 
  			{
  				if (value)
  					Expand();
  				else
  					Collapse();
  			}
  		}
  
  		internal void AssignIsExpanded(bool value)
  		{
  			_isExpanded = value;
  		}
  
  		private TreeNodeAdv _parent;
  		public TreeNodeAdv Parent
  		{
  			get { return _parent; }
  		}
  
  		public int Level
  		{
  			get
  			{
  				if (_parent == null)
  					return 0;
  				else
  					return _parent.Level + 1;
  			}
  		}
  
  		public TreeNodeAdv NextNode
  		{
  			get
  			{
  				if (_parent != null)
  				{
  					int index = Index;
  					if (index < _parent.Nodes.Count - 1)
  						return _parent.Nodes[index + 1];
  				}
  				return null;
  			}
  		}
  
  		internal TreeNodeAdv BottomNode
  		{
  			get
  			{
  				TreeNodeAdv parent = this.Parent;
  				if (parent != null)
  				{
  					if (parent.NextNode != null)
  						return parent.NextNode;
  					else
  						return parent.BottomNode;
  				}
  				return null;
  			}
  		}
  
  		internal TreeNodeAdv NextVisibleNode
  		{
  			get
  			{
  				if (IsExpanded && Nodes.Count > 0)
  					return Nodes[0];
  				else
  				{
  					TreeNodeAdv nn = NextNode;
  					if (nn != null)
  						return nn;
  					else
  						return BottomNode;
  				}
  			}
  		}
  
  		public bool CanExpand
  		{
  			get
  			{
  				// return (Nodes.Count > 0 || (!IsExpandedOnce && !IsLeaf));
  				return !IsLeaf;
  			}
  		}
  
  		private object _tag;
  		public object Tag
  		{
  			get { return _tag; }
  		}
  
  		private Collection<TreeNodeAdv> _nodes;
  		internal Collection<TreeNodeAdv> Nodes
  		{
  			get { return _nodes; }
  		}
  
  		private IList<TreeNodeAdv> _children;
  		public IList<TreeNodeAdv> Children
  		{
  			get
  			{
  				return _children;
  			}
  		}
  
  		private int? _rightBounds;
  		internal int? RightBounds
  		{
  			get { return _rightBounds; }
  
gt: 			set { _rightBounds = value; }