uwekeim

Extended Generic Tree Collection

Apr 25th, 2012
289
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Reflection;
  6. using System.Diagnostics;
  7. using System.Diagnostics.CodeAnalysis;
  8. using System.IO;
  9. using System.Runtime.Serialization;
  10. using System.Xml.Serialization;
  11. using System.Security.Permissions;
  12.  
  13. [assembly: SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", Scope = "member", Target = "Common.NodeTree`1+EnumeratorBase`1.Count", MessageId = "o")]
  14. [assembly: SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", Scope = "member", Target = "Common.NodeTree`1+BaseEnumerableCollectionPair+BaseNodesEnumerableCollection.Count", MessageId = "o")]
  15. [assembly: SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Scope = "member", Target = "Common.NodeTree`1.GetNodeTree(Common.INode`1<T>):Common.NodeTree`1<T>")]
  16. [assembly: SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Scope = "member", Target = "Common.NodeTree`1.GetNodeTree(Common.ITree`1<T>):Common.NodeTree`1<T>")]
  17. [assembly: SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Scope = "member", Target = "Common.NodeTree`1.NewTree():Common.ITree`1<T>")]
  18. [assembly: SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Scope = "member", Target = "Common.NodeTree`1.NewNode():Common.INode`1<T>")]
  19. [assembly: SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Scope = "member", Target = "Common.NodeTree`1.XmlAdapterTag")]
  20. [assembly: SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Scope = "member", Target = "Common.NodeTree`1.XmlDeserialize(System.IO.Stream):Common.ITree`1<T>")]
  21. [assembly: SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Scope = "member", Target = "Common.IEnumerableCollectionPair`1.Nodes")]
  22. [assembly: SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Scope = "member", Target = "Common.NodeTree`1.Nodes")]
  23. [assembly: SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Scope = "member", Target = "Common.NodeTree`1+AllEnumerator.Nodes")]
  24. [assembly: SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Scope = "member", Target = "Common.NodeTree`1+BaseEnumerableCollectionPair.Nodes")]
  25. [assembly: SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Scope = "member", Target = "Common.NodeTree`1+BaseEnumerableCollectionPair+BaseNodesEnumerableCollection.GetEnumerator():System.Collections.Generic.IEnumerator`1<Common.INode`1<T>>")]
  26. [assembly: SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Scope = "type", Target = "Common.NodeTree`1+AllEnumerator")]
  27. [assembly: SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Scope = "type", Target = "Common.NodeTree`1+BaseEnumerableCollectionPair")]
  28. [assembly: SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Scope = "type", Target = "Common.NodeTree`1+RootObject")]
  29. [assembly: SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Scope = "type", Target = "Common.NodeTree`1+NodeXmlSerializationAdapter")]
  30. [assembly: SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Scope = "type", Target = "Common.NodeTree`1+NodeXmlSerializationAdapter+IXmlCollection")]
  31. [assembly: SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Scope = "type", Target = "Common.NodeTree`1+TreeXmlSerializationAdapter")]
  32. [assembly: SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Scope = "member", Target = "Common.NodeTree`1.Dispose():System.Void")]
  33. [assembly: SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Scope = "member", Target = "Common.NodeTree`1.Finalize():System.Void")]
  34. [assembly: SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Scope = "member", Target = "Common.NodeTree`1+BaseEnumerableCollectionPair+BaseNodesEnumerableCollection.Dispose():System.Void")]
  35. [assembly: SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Scope = "member", Target = "Common.NodeTree`1+BaseEnumerableCollectionPair+BaseNodesEnumerableCollection.Finalize():System.Void")]
  36. [assembly: SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Common.NodeTree`1.XmlAdapterTag")]
  37. [assembly: SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Scope = "member", Target = "Common.NodeTree`1+NodeXmlSerializationAdapter.Children")]
  38.  
  39. namespace Common
  40. {
  41.     //-----------------------------------------------------------------------------
  42.     // IDeepCopy
  43.  
  44.     public interface IDeepCopy
  45.     {
  46.         object CreateDeepCopy();
  47.     }
  48.  
  49.     //-----------------------------------------------------------------------------
  50.     // IEnumerableCollection
  51.  
  52.     public interface IEnumerableCollection<T> : IEnumerable<T>, ICollection
  53.     {
  54.         bool Contains(T item);
  55.     }
  56.  
  57.     //-----------------------------------------------------------------------------
  58.     // IEnumerableCollectionPair
  59.  
  60.     public interface IEnumerableCollectionPair<T>
  61.     {
  62.         IEnumerableCollection<INode<T>> Nodes { get; }
  63.         IEnumerableCollection<T> Values { get; }
  64.         INode<T> Find(T item);
  65.         INode<T> Find(Predicate<T> predicate);
  66.     }
  67.  
  68.     //-----------------------------------------------------------------------------
  69.     // EventArgs
  70.  
  71.     public class NodeTreeDataEventArgs<T> : EventArgs
  72.     {
  73.         private T _Data = default(T);
  74.  
  75.         public T Data { get { return _Data; } }
  76.  
  77.         public NodeTreeDataEventArgs(T data)
  78.         {
  79.             _Data = data;
  80.         }
  81.     }
  82.  
  83.     public class NodeTreeNodeEventArgs<T> : EventArgs
  84.     {
  85.         private INode<T> _Node = null;
  86.  
  87.         public INode<T> Node { get { return _Node; } }
  88.  
  89.         public NodeTreeNodeEventArgs(INode<T> node)
  90.         {
  91.             _Node = node;
  92.         }
  93.     }
  94.  
  95.     public enum NodeTreeInsertOperation
  96.     {
  97.         Previous,
  98.         Next,
  99.         Child,
  100.         Tree
  101.     }
  102.  
  103.     public class NodeTreeInsertEventArgs<T> : EventArgs
  104.     {
  105.         private NodeTreeInsertOperation _Operation;
  106.         public NodeTreeInsertOperation Operation { get { return _Operation; } }
  107.  
  108.         private INode<T> _Node = null;
  109.         public INode<T> Node { get { return _Node; } }
  110.  
  111.         public NodeTreeInsertEventArgs(NodeTreeInsertOperation operation, INode<T> node)
  112.         {
  113.             _Operation = operation;
  114.             _Node = node;
  115.         }
  116.     }
  117.  
  118.     //-----------------------------------------------------------------------------
  119.     // INode<T>
  120.  
  121.     /// <summary>
  122.     /// Uwe Keim start.
  123.     /// </summary>
  124.     public delegate string ToStringRecursiveAction<in T>(T obj);
  125.     /// <summary>
  126.     /// Uwe Keim end.
  127.     /// </summary>
  128.  
  129.     public interface INode<T> : IEnumerableCollectionPair<T>, IDisposable//, ICollection<T>
  130.     {
  131.         T Data { get; set; }
  132.  
  133.         string ToStringRecursive();
  134.         /// <summary>
  135.         /// Uwe Keim start.
  136.         /// </summary>
  137.         string ToStringRecursive(ToStringRecursiveAction<INode<T>> action);
  138.         /// <summary>
  139.         /// Uwe Keim end.
  140.         /// </summary>
  141.  
  142.         int Depth { get; }
  143.         int BranchIndex { get; }
  144.         int BranchCount { get; }
  145.  
  146.         int Count { get; }
  147.         int DirectChildCount { get; }
  148.  
  149.         INode<T> Parent { get; }
  150.         INode<T> Previous { get; }
  151.         INode<T> Next { get; }
  152.         INode<T> Child { get; }
  153.  
  154.         ITree<T> Tree { get; }
  155.  
  156.         INode<T> Root { get; }
  157.         INode<T> Top { get; }
  158.         INode<T> First { get; }
  159.         INode<T> Last { get; }
  160.  
  161.         INode<T> LastChild { get; }
  162.  
  163.         bool IsTree { get; }
  164.         bool IsRoot { get; }
  165.         bool IsTop { get; }
  166.         bool HasParent { get; }
  167.         bool HasPrevious { get; }
  168.         bool HasNext { get; }
  169.         bool HasChild { get; }
  170.         bool IsFirst { get; }
  171.         bool IsLast { get; }
  172.  
  173.         INode<T> this[T item] { get; }
  174.  
  175.         bool Contains(INode<T> item);
  176.         bool Contains(T item);
  177.  
  178.         INode<T> InsertPrevious(T o);
  179.         INode<T> InsertNext(T o);
  180.         INode<T> InsertChild(T o);
  181.         INode<T> Add(T o);
  182.         INode<T> AddChild(T o);
  183.  
  184.         void InsertPrevious(ITree<T> tree);
  185.         void InsertNext(ITree<T> tree);
  186.         void InsertChild(ITree<T> tree);
  187.         void Add(ITree<T> tree);
  188.         void AddChild(ITree<T> tree);
  189.  
  190.         ITree<T> Cut(T o);
  191.         ITree<T> Copy(T o);
  192.         ITree<T> DeepCopy(T o);
  193.         bool Remove(T o);
  194.  
  195.         ITree<T> Cut();
  196.         ITree<T> Copy();
  197.         ITree<T> DeepCopy();
  198.         void Remove();
  199.  
  200.         bool CanMoveToParent { get; }
  201.         bool CanMoveToPrevious { get; }
  202.         bool CanMoveToNext { get; }
  203.         bool CanMoveToChild { get; }
  204.         bool CanMoveToFirst { get; }
  205.         bool CanMoveToLast { get; }
  206.  
  207.         void MoveToParent();
  208.         void MoveToPrevious();
  209.         void MoveToNext();
  210.         void MoveToChild();
  211.         void MoveToFirst();
  212.         void MoveToLast();
  213.  
  214.         IEnumerableCollectionPair<T> All { get; }
  215.         IEnumerableCollectionPair<T> AllChildren { get; }
  216.         IEnumerableCollectionPair<T> DirectChildren { get; }
  217.         IEnumerableCollectionPair<T> DirectChildrenInReverse { get; }
  218.  
  219.         void SortAllChildren();
  220.         void SortAllChildren(Comparison<T> comparison);
  221.         void SortAllChildren(IComparer<T> comparer);
  222.  
  223.         void SortDirectChildren();
  224.         void SortDirectChildren(Comparison<T> comparison);
  225.         void SortDirectChildren(IComparer<T> comparer);
  226.  
  227.         event EventHandler<NodeTreeDataEventArgs<T>> Validate;
  228.         event EventHandler<NodeTreeDataEventArgs<T>> Setting;
  229.         event EventHandler<NodeTreeDataEventArgs<T>> SetDone;
  230.         event EventHandler<NodeTreeInsertEventArgs<T>> Inserting;
  231.         event EventHandler<NodeTreeInsertEventArgs<T>> Inserted;
  232.         event EventHandler Cutting;
  233.         event EventHandler CutDone;
  234.         event EventHandler<NodeTreeNodeEventArgs<T>> Copying;
  235.         event EventHandler<NodeTreeNodeEventArgs<T>> Copied;
  236.         event EventHandler<NodeTreeNodeEventArgs<T>> DeepCopying;
  237.         event EventHandler<NodeTreeNodeEventArgs<T>> DeepCopied;
  238.     }
  239.  
  240.     //-----------------------------------------------------------------------------
  241.     // ITree<T>
  242.  
  243.     public interface ITree<T> : IEnumerableCollectionPair<T>, IDisposable//, ICollection<T>
  244.     {
  245.         Type DataType { get; }
  246.  
  247.         IEqualityComparer<T> DataComparer { get; set; }
  248.  
  249.         void XmlSerialize(Stream stream);
  250.  
  251.         void Clear();
  252.         int Count { get; }
  253.         int DirectChildCount { get; }
  254.  
  255.         INode<T> Root { get; }
  256.  
  257.         INode<T> this[T o] { get; }
  258.  
  259.         string ToStringRecursive();
  260.         /// <summary>
  261.         /// Uwe Keim start.
  262.         /// </summary>
  263.         string ToStringRecursive(ToStringRecursiveAction<INode<T>> action);
  264.         /// <summary>
  265.         /// Uwe Keim end.
  266.         /// </summary>
  267.  
  268.         bool Contains(T item);
  269.         bool Contains(INode<T> item);
  270.  
  271.         INode<T> InsertChild(T o);
  272.         INode<T> AddChild(T o);
  273.  
  274.         void InsertChild(ITree<T> tree);
  275.         void AddChild(ITree<T> tree);
  276.  
  277.         ITree<T> Cut(T o);
  278.         ITree<T> Copy(T o);
  279.         ITree<T> DeepCopy(T o);
  280.         bool Remove(T o);
  281.  
  282.         ITree<T> Copy();
  283.         ITree<T> DeepCopy();
  284.  
  285.         IEnumerableCollectionPair<T> All { get; }
  286.         IEnumerableCollectionPair<T> AllChildren { get; }
  287.         IEnumerableCollectionPair<T> DirectChildren { get; }
  288.         IEnumerableCollectionPair<T> DirectChildrenInReverse { get; }
  289.  
  290.         void SortAllChildren();
  291.         void SortAllChildren(Comparison<T> comparison);
  292.         void SortAllChildren(IComparer<T> comparer);
  293.  
  294.         event EventHandler<NodeTreeDataEventArgs<T>> Validate;
  295.         event EventHandler Clearing;
  296.         event EventHandler Cleared;
  297.         event EventHandler<NodeTreeDataEventArgs<T>> Setting;
  298.         event EventHandler<NodeTreeDataEventArgs<T>> SetDone;
  299.         event EventHandler<NodeTreeInsertEventArgs<T>> Inserting;
  300.         event EventHandler<NodeTreeInsertEventArgs<T>> Inserted;
  301.         event EventHandler Cutting;
  302.         event EventHandler CutDone;
  303.         event EventHandler<NodeTreeNodeEventArgs<T>> Copying;
  304.         event EventHandler<NodeTreeNodeEventArgs<T>> Copied;
  305.         event EventHandler<NodeTreeNodeEventArgs<T>> DeepCopying;
  306.         event EventHandler<NodeTreeNodeEventArgs<T>> DeepCopied;
  307.     }
  308.  
  309.     //-----------------------------------------------------------------------------
  310.     // NodeTree
  311.  
  312.     [Serializable]
  313.     public class NodeTree<T> : INode<T>, ITree<T>, ISerializable
  314.     {
  315.         private T _Data = default(T);
  316.  
  317.         private NodeTree<T> _Parent = null;
  318.         private NodeTree<T> _Previous = null;
  319.         private NodeTree<T> _Next = null;
  320.         private NodeTree<T> _Child = null;
  321.  
  322.         protected NodeTree() { }
  323.  
  324.         ~NodeTree()
  325.         {
  326.             Dispose(false);
  327.         }
  328.  
  329.         public void Dispose()
  330.         {
  331.             Dispose(true);
  332.  
  333.             GC.SuppressFinalize(this);
  334.         }
  335.  
  336.         protected virtual void Dispose(bool disposing)
  337.         {
  338.             if (disposing)
  339.             {
  340.                 if (_EventHandlerList != null) _EventHandlerList.Dispose();
  341.             }
  342.         }
  343.  
  344.         //-----------------------------------------------------------------------------
  345.         // Instantiation
  346.  
  347.         public static ITree<T> NewTree()
  348.         {
  349.             return new RootObject();
  350.         }
  351.  
  352.         public static ITree<T> NewTree(IEqualityComparer<T> dataComparer)
  353.         {
  354.             return new RootObject(dataComparer);
  355.         }
  356.  
  357.         protected static INode<T> NewNode()
  358.         {
  359.             return new NodeTree<T>();
  360.         }
  361.  
  362.         protected virtual NodeTree<T> CreateTree()
  363.         {
  364.             return new RootObject();
  365.         }
  366.  
  367.         protected virtual NodeTree<T> CreateNode()
  368.         {
  369.             return new NodeTree<T>();
  370.         }
  371.  
  372.         //-----------------------------------------------------------------------------
  373.         // ToString
  374.  
  375.         /// <summary>Obtains the <see cref="String"/> representation of this instance.</summary>
  376.         /// <returns>The <see cref="String"/> representation of this instance.</returns>
  377.         /// <remarks>
  378.         /// <p>
  379.         /// This method returns a <see cref="String"/> that represents this instance.
  380.         /// </p>
  381.         /// </remarks>
  382.         public override string ToString()
  383.         {
  384.             T data = Data;
  385.             if (data == null) return String.Empty;
  386.             return data.ToString();
  387.         }
  388.  
  389.         /// <summary>
  390.         /// Uwe Keim start.
  391.         /// </summary>
  392.         public virtual string ToStringRecursive(
  393.             ToStringRecursiveAction<INode<T>> action)
  394.         {
  395.             var s = string.Empty;
  396.  
  397.             foreach (NodeTree<T> node in All.Nodes)
  398.             {
  399.                 s += action(node);
  400.             }
  401.  
  402.             return s;
  403.         }
  404.  
  405.         public virtual string ToStringRecursive()
  406.         {
  407.             return ToStringRecursive(
  408.                 node => new string('\t', node.Depth) +
  409.                     node +
  410.                         Environment.NewLine);
  411.         }
  412.         /*
  413.         public virtual string ToStringRecursive()
  414.         {
  415.             string s = String.Empty;
  416.  
  417.             foreach (NodeTree<T> node in All.Nodes)
  418.                 s += new String('\t', node.Depth) + node + Environment.NewLine;
  419.  
  420.             return s;
  421.         }*/
  422.         /// <summary>
  423.         /// Uwe Keim end.
  424.         /// </summary>
  425.  
  426.         //-----------------------------------------------------------------------------
  427.         // Counts
  428.  
  429.         public virtual int Depth
  430.         {
  431.             get
  432.             {
  433.                 int i = -1;
  434.  
  435.                 for (INode<T> node = this; !node.IsRoot; node = node.Parent) i++;
  436.  
  437.                 return i;
  438.             }
  439.         }
  440.  
  441.         public virtual int BranchIndex
  442.         {
  443.             get
  444.             {
  445.                 int i = -1;
  446.  
  447.                 for (INode<T> node = this; node != null; node = node.Previous) i++;
  448.  
  449.                 return i;
  450.             }
  451.         }
  452.  
  453.         public virtual int BranchCount
  454.         {
  455.             get
  456.             {
  457.                 int i = 0;
  458.  
  459.                 for (INode<T> node = First; node != null; node = node.Next) i++;
  460.  
  461.                 return i;
  462.             }
  463.         }
  464.  
  465.         //-----------------------------------------------------------------------------
  466.         // DeepCopyData
  467.  
  468.         [ReflectionPermission(SecurityAction.Demand, Unrestricted = true)]
  469.         protected virtual T DeepCopyData(T data)
  470.         {
  471.             //if ( ! Root.IsTree ) throw new InvalidOperationException( "This is not a tree" );
  472.  
  473.             if (data == null) { Debug.Assert(true); return default(T); }
  474.  
  475.             // IDeepCopy
  476.             IDeepCopy deepCopy = data as IDeepCopy;
  477.             if (deepCopy != null) return (T)deepCopy.CreateDeepCopy();
  478.  
  479.             // ICloneable
  480.             ICloneable cloneable = data as ICloneable;
  481.             if (cloneable != null) return (T)cloneable.Clone();
  482.  
  483.             // Copy constructor
  484.             ConstructorInfo ctor = data.GetType().GetConstructor(
  485.                  BindingFlags.Instance | BindingFlags.Public,
  486.                  null, new Type[] { typeof(T) }, null);
  487.             if (ctor != null) return (T)ctor.Invoke(new object[] { data });
  488.             //return ( T ) Activator.CreateInstance( typeof( T ), new object[] { data } );
  489.  
  490.             // give up
  491.             return data;
  492.         }
  493.  
  494.         //-----------------------------------------------------------------------------
  495.         // RootObject
  496.  
  497.         [Serializable]
  498.         protected class RootObject : NodeTree<T>
  499.         {
  500.             private int _Version = 0;
  501.             protected override int Version
  502.             {
  503.                 get { return _Version; }
  504.                 set { _Version = value; }
  505.             }
  506.  
  507.             private IEqualityComparer<T> _DataComparer;
  508.             public override IEqualityComparer<T> DataComparer
  509.             {
  510.                 get
  511.                 {
  512.                     if (_DataComparer == null) _DataComparer = EqualityComparer<T>.Default;
  513.  
  514.                     return _DataComparer;
  515.                 }
  516.  
  517.                 set { _DataComparer = value; }
  518.             }
  519.  
  520.             public RootObject()
  521.             {
  522.             }
  523.  
  524.             public RootObject(IEqualityComparer<T> dataComparer)
  525.             {
  526.                 _DataComparer = dataComparer;
  527.             }
  528.  
  529.             /// <summary>Obtains the <see cref="String"/> representation of this instance.</summary>
  530.             /// <returns>The <see cref="String"/> representation of this instance.</returns>
  531.             /// <remarks>
  532.             /// <p>
  533.             /// This method returns a <see cref="String"/> that represents this instance.
  534.             /// </p>
  535.             /// </remarks>
  536.             public override string ToString() { return "ROOT: " + DataType.Name; }
  537.  
  538.             // Save
  539.             /// <summary>Populates a SerializationInfo with the data needed to serialize the target T.</summary>
  540.             /// <param name="info">The SerializationInfo to populate with data.</param>
  541.             /// <param name="context">The destination for this serialization.</param>
  542.             /// <remarks>
  543.             /// <p>This method is called during serialization.</p>
  544.             /// <p>Do not call this method directly.</p>
  545.             /// </remarks>
  546.             [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
  547.             public override void GetObjectData(SerializationInfo info, StreamingContext context)
  548.             {
  549.                 base.GetObjectData(info, context);
  550.  
  551.                 info.AddValue("RootObjectVersion", 1);
  552.                 //info.AddValue( "DataType", _DataType );
  553.             }
  554.  
  555.             // Load
  556.             /// <summary>Initializes a new instance of the class during deserialization.</summary>
  557.             /// <param name="info">The SerializationInfo populated with data.</param>
  558.             /// <param name="context">The source for this serialization.</param>
  559.             /// <remarks>
  560.             /// <p>This method is called during deserialization.</p>
  561.             /// <p>Do not call this method directly.</p>
  562.             /// </remarks>
  563.             protected RootObject(SerializationInfo info, StreamingContext context)
  564.                 : base(info, context)
  565.             {
  566.                 int iVersion = info.GetInt32("RootObjectVersion");
  567.                 if (iVersion != 1) throw new SerializationException("Unknown version");
  568.  
  569.                 //_DataType = info.GetValue( "DataType", typeof( Type ) ) as Type;
  570.             }
  571.         }
  572.  
  573.         //-----------------------------------------------------------------------------
  574.         // GetRootObject
  575.  
  576.         protected virtual RootObject GetRootObject
  577.         {
  578.             get
  579.             {
  580.                 return (RootObject)Root;
  581.             }
  582.         }
  583.  
  584.         //-----------------------------------------------------------------------------
  585.         // DataComparer
  586.  
  587.         public virtual IEqualityComparer<T> DataComparer
  588.         {
  589.             get
  590.             {
  591.                 if (!Root.IsTree) throw new InvalidOperationException("This is not a Tree");
  592.  
  593.                 return GetRootObject.DataComparer;
  594.             }
  595.  
  596.             set
  597.             {
  598.                 if (!Root.IsTree) throw new InvalidOperationException("This is not a Tree");
  599.  
  600.                 GetRootObject.DataComparer = value;
  601.             }
  602.         }
  603.  
  604.         //-----------------------------------------------------------------------------
  605.         // Version
  606.  
  607.         protected virtual int Version
  608.         {
  609.             get
  610.             {
  611.                 INode<T> root = Root;
  612.  
  613.                 if (!root.IsTree) throw new InvalidOperationException("This is not a Tree");
  614.  
  615.                 return GetNodeTree(root).Version;
  616.             }
  617.  
  618.             set
  619.             {
  620.                 INode<T> root = Root;
  621.  
  622.                 if (!root.IsTree) throw new InvalidOperationException("This is not a Tree");
  623.  
  624.                 GetNodeTree(root).Version = value;
  625.             }
  626.         }
  627.  
  628.         protected bool HasChanged(int version) { return (Version != version); }
  629.  
  630.         protected void IncrementVersion()
  631.         {
  632.             INode<T> root = Root;
  633.  
  634.             if (!root.IsTree) throw new InvalidOperationException("This is not a Tree");
  635.  
  636.             GetNodeTree(root).Version++;
  637.         }
  638.  
  639.         //-----------------------------------------------------------------------------
  640.         // ISerializable
  641.  
  642.         // Save
  643.         /// <summary>Populates a SerializationInfo with the data needed to serialize the target T.</summary>
  644.         /// <param name="info">The SerializationInfo to populate with data.</param>
  645.         /// <param name="context">The destination for this serialization.</param>
  646.         /// <remarks>
  647.         /// <p>This method is called during serialization.</p>
  648.         /// <p>Do not call this method directly.</p>
  649.         /// </remarks>
  650.         [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
  651.         public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
  652.         {
  653.             info.AddValue("NodeTreeVersion", 1);
  654.             info.AddValue("Data", _Data);
  655.             info.AddValue("Parent", _Parent);
  656.             info.AddValue("Previous", _Previous);
  657.             info.AddValue("Next", _Next);
  658.             info.AddValue("Child", _Child);
  659.         }
  660.  
  661.         // Load
  662.         /// <summary>Initializes a new instance of the class during deserialization.</summary>
  663.         /// <param name="info">The SerializationInfo populated with data.</param>
  664.         /// <param name="context">The source for this serialization.</param>
  665.         /// <remarks>
  666.         /// <p>This method is called during deserialization.</p>
  667.         /// <p>Do not call this method directly.</p>
  668.         /// </remarks>
  669.         protected NodeTree(SerializationInfo info, StreamingContext context)
  670.         {
  671.             int iVersion = info.GetInt32("NodeTreeVersion");
  672.             if (iVersion != 1) throw new SerializationException("Unknown version");
  673.  
  674.             _Data = (T)info.GetValue("Data", typeof(T));
  675.             _Parent = (NodeTree<T>)info.GetValue("Parent", typeof(NodeTree<T>));
  676.             _Previous = (NodeTree<T>)info.GetValue("Previous", typeof(NodeTree<T>));
  677.             _Next = (NodeTree<T>)info.GetValue("Next", typeof(NodeTree<T>));
  678.             _Child = (NodeTree<T>)info.GetValue("Child", typeof(NodeTree<T>));
  679.         }
  680.  
  681.         //-----------------------------------------------------------------------------
  682.         // XmlSerialization
  683.  
  684.         public virtual void XmlSerialize(Stream stream)
  685.         {
  686.             XmlSerializer xmlSerializer;
  687.  
  688.             try
  689.             {
  690.                 xmlSerializer = new XmlSerializer(typeof(TreeXmlSerializationAdapter));
  691.             }
  692.             catch (Exception x)
  693.             {
  694.                 Debug.Assert(x == null); // false
  695.                 throw;
  696.             }
  697.  
  698.             try
  699.             {
  700.                 xmlSerializer.Serialize(stream, new TreeXmlSerializationAdapter(XmlAdapterTag, this));
  701.             }
  702.             catch (Exception x)
  703.             {
  704.                 Debug.Assert(x == null); // false
  705.                 throw;
  706.             }
  707.  
  708.         }
  709.  
  710.         public static ITree<T> XmlDeserialize(Stream stream)
  711.         {
  712.             XmlSerializer xmlSerializer;
  713.  
  714.             try
  715.             {
  716.                 xmlSerializer = new XmlSerializer(typeof(TreeXmlSerializationAdapter));
  717.             }
  718.             catch (Exception x)
  719.             {
  720.                 Debug.Assert(x == null); // false
  721.                 throw;
  722.             }
  723.  
  724.             object o;
  725.  
  726.             try
  727.             {
  728.                 o = xmlSerializer.Deserialize(stream);
  729.             }
  730.             catch (Exception x)
  731.             {
  732.                 Debug.Assert(x == null); // false
  733.                 throw;
  734.             }
  735.  
  736.             TreeXmlSerializationAdapter adapter = (TreeXmlSerializationAdapter)o;
  737.  
  738.             ITree<T> tree = adapter.Tree;
  739.  
  740.             return tree;
  741.         }
  742.  
  743.         //-----------------------------------------------------------------------------
  744.  
  745.         protected static readonly object XmlAdapterTag = new object();
  746.  
  747.         [XmlType("Tree")]
  748.         public class TreeXmlSerializationAdapter
  749.         {
  750.             private int _Version = 0;
  751.  
  752.             [XmlAttribute]
  753.             public int Version
  754.             {
  755.                 get { return 1; }
  756.                 set { _Version = value; }
  757.             }
  758.  
  759.             private ITree<T> _Tree;
  760.  
  761.             [XmlIgnore]
  762.             public ITree<T> Tree
  763.             {
  764.                 get { return _Tree; }
  765.             }
  766.  
  767.             private TreeXmlSerializationAdapter()
  768.             {
  769.             }
  770.  
  771.             public TreeXmlSerializationAdapter(object tag, ITree<T> tree)
  772.             {
  773.                 if (!ReferenceEquals(XmlAdapterTag, tag)) throw new InvalidOperationException("Don't use this class");
  774.  
  775.                 _Tree = tree;
  776.             }
  777.  
  778.             public NodeXmlSerializationAdapter Root
  779.             {
  780.                 get
  781.                 {
  782.                     return new NodeXmlSerializationAdapter(XmlAdapterTag, _Tree.Root);
  783.                 }
  784.  
  785.                 set
  786.                 {
  787.                     _Tree = NodeTree<T>.NewTree();
  788.  
  789.                     ReformTree(_Tree.Root, value);
  790.                 }
  791.             }
  792.  
  793.             private void ReformTree(INode<T> parent, NodeXmlSerializationAdapter node)
  794.             {
  795.                 foreach (NodeXmlSerializationAdapter child in node.Children)
  796.                 {
  797.                     INode<T> n = parent.AddChild(child.Data);
  798.  
  799.                     ReformTree(n, child);
  800.                 }
  801.             }
  802.  
  803.         }
  804.  
  805.         [XmlType("Node")]
  806.         public class NodeXmlSerializationAdapter
  807.         {
  808.             private int _Version = 0;
  809.  
  810.             [XmlAttribute]
  811.             public int Version
  812.             {
  813.                 get { return 1; }
  814.                 set { _Version = value; }
  815.             }
  816.  
  817.             private INode<T> _Node;
  818.  
  819.             private IXmlCollection _Children = new ChildCollection();
  820.  
  821.             [XmlIgnore]
  822.             public INode<T> Node
  823.             {
  824.                 get { return _Node; }
  825.             }
  826.  
  827.             // Load
  828.             private NodeXmlSerializationAdapter()
  829.             {
  830.                 _Node = NodeTree<T>.NewNode();
  831.             }
  832.  
  833.             // Save
  834.             public NodeXmlSerializationAdapter(object tag, INode<T> node)
  835.             {
  836.                 if (!ReferenceEquals(XmlAdapterTag, tag)) throw new InvalidOperationException("Don't use this class");
  837.  
  838.                 _Node = node;
  839.  
  840.                 foreach (INode<T> child in node.DirectChildren.Nodes)
  841.                     _Children.Add(new NodeXmlSerializationAdapter(XmlAdapterTag, child));
  842.             }
  843.  
  844.             public T Data
  845.             {
  846.                 get { return _Node.Data; }
  847.  
  848.                 set
  849.                 {
  850.                     GetNodeTree(_Node)._Data = value;
  851.                 }
  852.             }
  853.  
  854.             public IXmlCollection Children
  855.             {
  856.                 get { return _Children; }
  857.                 set { Debug.Assert(value == null); }
  858.             }
  859.  
  860.             public interface IXmlCollection : ICollection
  861.             {
  862.                 NodeXmlSerializationAdapter this[int index] { get; }
  863.  
  864.                 void Add(NodeXmlSerializationAdapter item);
  865.             }
  866.  
  867.             private class ChildCollection : List<NodeXmlSerializationAdapter>, IXmlCollection { }
  868.         }
  869.  
  870.  
  871.         //-----------------------------------------------------------------------------
  872.         // INode<T>
  873.  
  874.         public T Data
  875.         {
  876.             get
  877.             {
  878.                 return _Data;
  879.             }
  880.  
  881.             set
  882.             {
  883.                 if (IsRoot) throw new InvalidOperationException("This is a Root");
  884.  
  885.                 OnSetting(this, value);
  886.  
  887.                 _Data = value;
  888.  
  889.                 OnSetDone(this, value);
  890.             }
  891.         }
  892.  
  893.         public INode<T> Parent { get { return _Parent; } }
  894.         public INode<T> Previous { get { return _Previous; } }
  895.         public INode<T> Next { get { return _Next; } }
  896.         public INode<T> Child { get { return _Child; } }
  897.  
  898.         //-----------------------------------------------------------------------------
  899.  
  900.         public ITree<T> Tree
  901.         {
  902.             get
  903.             {
  904.                 return (ITree<T>)Root;
  905.             }
  906.         }
  907.  
  908.         public INode<T> Root
  909.         {
  910.             get
  911.             {
  912.                 INode<T> node = this;
  913.  
  914.                 while (node.Parent != null)
  915.                     node = node.Parent;
  916.  
  917.                 return node;
  918.             }
  919.         }
  920.  
  921.         public INode<T> Top
  922.         {
  923.             get
  924.             {
  925.                 if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  926.                 //if ( this.IsRoot ) throw new InvalidOperationException( "This is a Root" );
  927.                 if (this.IsRoot) return null;
  928.  
  929.                 INode<T> node = this;
  930.  
  931.                 while (node.Parent.Parent != null)
  932.                     node = node.Parent;
  933.  
  934.                 return node;
  935.             }
  936.         }
  937.  
  938.         public INode<T> First
  939.         {
  940.             get
  941.             {
  942.                 INode<T> node = this;
  943.  
  944.                 while (node.Previous != null)
  945.                     node = node.Previous;
  946.  
  947.                 return node;
  948.             }
  949.         }
  950.  
  951.         public INode<T> Last
  952.         {
  953.             get
  954.             {
  955.                 INode<T> node = this;
  956.  
  957.                 while (node.Next != null)
  958.                     node = node.Next;
  959.  
  960.                 return node;
  961.             }
  962.         }
  963.  
  964.         public INode<T> LastChild
  965.         {
  966.             get
  967.             {
  968.                 if (Child == null) return null;
  969.                 return Child.Last;
  970.             }
  971.         }
  972.  
  973.         //-----------------------------------------------------------------------------
  974.  
  975.         public bool HasPrevious { get { return Previous != null; } }
  976.         public bool HasNext { get { return Next != null; } }
  977.         public bool HasChild { get { return Child != null; } }
  978.         public bool IsFirst { get { return Previous == null; } }
  979.         public bool IsLast { get { return Next == null; } }
  980.  
  981.         public bool IsTree
  982.         {
  983.             get
  984.             {
  985.                 if (!IsRoot) return false;
  986.                 return this is RootObject;
  987.             }
  988.         }
  989.  
  990.         public bool IsRoot
  991.         {
  992.             get
  993.             {
  994.                 bool b = (Parent == null);
  995.  
  996.                 if (b)
  997.                 {
  998.                     Debug.Assert(Previous == null);
  999.                     Debug.Assert(Next == null);
  1000.                 }
  1001.  
  1002.                 return b;
  1003.             }
  1004.         }
  1005.  
  1006.         public bool HasParent
  1007.         {
  1008.             get
  1009.             {
  1010.                 //if ( IsRoot ) throw new InvalidOperationException( "This is a Root" );
  1011.                 if (IsRoot) return false;
  1012.                 return Parent.Parent != null;
  1013.             }
  1014.         }
  1015.  
  1016.         public bool IsTop
  1017.         {
  1018.             get
  1019.             {
  1020.                 //if ( IsRoot ) throw new InvalidOperationException( "This is a Root" );
  1021.                 if (IsRoot) return false;
  1022.                 return Parent.Parent == null;
  1023.             }
  1024.         }
  1025.  
  1026.         //-----------------------------------------------------------------------------
  1027.  
  1028.         public virtual INode<T> this[T item]
  1029.         {
  1030.             get
  1031.             {
  1032.                 if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1033.  
  1034.                 IEqualityComparer<T> comparer = DataComparer;
  1035.  
  1036.                 foreach (INode<T> n in All.Nodes)
  1037.                     if (comparer.Equals(n.Data, item))
  1038.                         return n;
  1039.  
  1040.                 return null;
  1041.             }
  1042.         }
  1043.  
  1044.         public virtual bool Contains(INode<T> item)
  1045.         {
  1046.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1047.  
  1048.             return All.Nodes.Contains(item);
  1049.         }
  1050.  
  1051.         public virtual bool Contains(T item)
  1052.         {
  1053.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1054.  
  1055.             return All.Values.Contains(item);
  1056.         }
  1057.  
  1058.         public virtual INode<T> Find(T item)
  1059.         {
  1060.             return All.Find(item);
  1061.         }
  1062.  
  1063.         public virtual INode<T> Find(Predicate<T> predicate)
  1064.         {
  1065.             return All.Find(predicate);
  1066.         }
  1067.  
  1068.         //-----------------------------------------------------------------------------
  1069.  
  1070.         public INode<T> InsertPrevious(T o)
  1071.         {
  1072.             if (this.IsRoot) throw new InvalidOperationException("This is a Root");
  1073.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1074.  
  1075.             NodeTree<T> newNode = CreateNode();
  1076.             newNode._Data = o;
  1077.  
  1078.             this.InsertPreviousCore(newNode);
  1079.  
  1080.             return newNode;
  1081.         }
  1082.  
  1083.         public INode<T> InsertNext(T o)
  1084.         {
  1085.             if (this.IsRoot) throw new InvalidOperationException("This is a Root");
  1086.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1087.  
  1088.             NodeTree<T> newNode = CreateNode();
  1089.             newNode._Data = o;
  1090.  
  1091.             this.InsertNextCore(newNode);
  1092.  
  1093.             return newNode;
  1094.         }
  1095.  
  1096.         public INode<T> InsertChild(T o)
  1097.         {
  1098.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1099.  
  1100.             NodeTree<T> newNode = CreateNode();
  1101.             newNode._Data = o;
  1102.  
  1103.             this.InsertChildCore(newNode);
  1104.  
  1105.             return newNode;
  1106.         }
  1107.  
  1108.         public INode<T> Add(T o)
  1109.         {
  1110.             if (this.IsRoot) throw new InvalidOperationException("This is a Root");
  1111.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1112.  
  1113.             return this.Last.InsertNext(o);
  1114.         }
  1115.  
  1116.         public INode<T> AddChild(T o)
  1117.         {
  1118.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1119.  
  1120.             if (Child == null)
  1121.                 return InsertChild(o);
  1122.             else
  1123.                 return Child.Add(o);
  1124.         }
  1125.  
  1126.         //-----------------------------------------------------------------------------
  1127.  
  1128.         public void InsertPrevious(ITree<T> tree)
  1129.         {
  1130.             if (this.IsRoot) throw new InvalidOperationException("This is a Root");
  1131.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1132.  
  1133.             NodeTree<T> newTree = GetNodeTree(tree);
  1134.  
  1135.             if (!newTree.IsRoot) throw new ArgumentException("Tree is not a Root");
  1136.             if (!newTree.IsTree) throw new ArgumentException("Tree is not a tree");
  1137.  
  1138.             for (INode<T> n = newTree.Child; n != null; n = n.Next)
  1139.             {
  1140.                 NodeTree<T> node = GetNodeTree(n);
  1141.                 NodeTree<T> copy = node.CopyCore();
  1142.                 InsertPreviousCore(copy);
  1143.             }
  1144.         }
  1145.  
  1146.         public void InsertNext(ITree<T> tree)
  1147.         {
  1148.             if (this.IsRoot) throw new InvalidOperationException("This is a Root");
  1149.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1150.  
  1151.             NodeTree<T> newTree = GetNodeTree(tree);
  1152.  
  1153.             if (!newTree.IsRoot) throw new ArgumentException("Tree is not a Root");
  1154.             if (!newTree.IsTree) throw new ArgumentException("Tree is not a tree");
  1155.  
  1156.             for (INode<T> n = newTree.LastChild; n != null; n = n.Previous)
  1157.             {
  1158.                 NodeTree<T> node = GetNodeTree(n);
  1159.                 NodeTree<T> copy = node.CopyCore();
  1160.                 InsertNextCore(copy);
  1161.             }
  1162.         }
  1163.  
  1164.         public void InsertChild(ITree<T> tree)
  1165.         {
  1166.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1167.  
  1168.             NodeTree<T> newTree = GetNodeTree(tree);
  1169.  
  1170.             if (!newTree.IsRoot) throw new ArgumentException("Tree is not a Root");
  1171.             if (!newTree.IsTree) throw new ArgumentException("Tree is not a tree");
  1172.  
  1173.             for (INode<T> n = newTree.LastChild; n != null; n = n.Previous)
  1174.             {
  1175.                 NodeTree<T> node = GetNodeTree(n);
  1176.                 NodeTree<T> copy = node.CopyCore();
  1177.                 InsertChildCore(copy);
  1178.             }
  1179.         }
  1180.  
  1181.         public void Add(ITree<T> tree)
  1182.         {
  1183.             if (this.IsRoot) throw new InvalidOperationException("This is a Root");
  1184.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1185.  
  1186.             this.Last.InsertNext(tree);
  1187.         }
  1188.  
  1189.         public void AddChild(ITree<T> tree)
  1190.         {
  1191.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1192.  
  1193.             if (this.Child == null)
  1194.                 this.InsertChild(tree);
  1195.             else
  1196.                 this.Child.Add(tree);
  1197.         }
  1198.  
  1199.         //-----------------------------------------------------------------------------
  1200.  
  1201.         protected virtual void InsertPreviousCore(INode<T> newINode)
  1202.         {
  1203.             if (this.IsRoot) throw new InvalidOperationException("This is a Root");
  1204.             if (!newINode.IsRoot) throw new ArgumentException("Node is not a Root");
  1205.             if (newINode.IsTree) throw new ArgumentException("Node is a tree");
  1206.  
  1207.             IncrementVersion();
  1208.  
  1209.             OnInserting(this, NodeTreeInsertOperation.Previous, newINode);
  1210.  
  1211.             NodeTree<T> newNode = GetNodeTree(newINode);
  1212.  
  1213.             newNode._Parent = this._Parent;
  1214.             newNode._Previous = this._Previous;
  1215.             newNode._Next = this;
  1216.             this._Previous = newNode;
  1217.  
  1218.             if (newNode.Previous != null)
  1219.             {
  1220.                 NodeTree<T> Previous = GetNodeTree(newNode.Previous);
  1221.                 Previous._Next = newNode;
  1222.             }
  1223.             else // this is a first node
  1224.             {
  1225.                 NodeTree<T> Parent = GetNodeTree(newNode.Parent);
  1226.                 Parent._Child = newNode;
  1227.             }
  1228.  
  1229.             OnInserted(this, NodeTreeInsertOperation.Previous, newINode);
  1230.         }
  1231.  
  1232.         protected virtual void InsertNextCore(INode<T> newINode)
  1233.         {
  1234.             if (this.IsRoot) throw new InvalidOperationException("This is a Root");
  1235.             if (!newINode.IsRoot) throw new ArgumentException("Node is not a Root");
  1236.             if (newINode.IsTree) throw new ArgumentException("Node is a tree");
  1237.  
  1238.             IncrementVersion();
  1239.  
  1240.             OnInserting(this, NodeTreeInsertOperation.Next, newINode);
  1241.  
  1242.             NodeTree<T> newNode = GetNodeTree(newINode);
  1243.  
  1244.             newNode._Parent = this._Parent;
  1245.             newNode._Previous = this;
  1246.             newNode._Next = this._Next;
  1247.             this._Next = newNode;
  1248.  
  1249.             if (newNode.Next != null)
  1250.             {
  1251.                 NodeTree<T> Next = GetNodeTree(newNode.Next);
  1252.                 Next._Previous = newNode;
  1253.             }
  1254.  
  1255.             OnInserted(this, NodeTreeInsertOperation.Next, newINode);
  1256.         }
  1257.  
  1258.         protected virtual void InsertChildCore(INode<T> newINode)
  1259.         {
  1260.             if (!newINode.IsRoot) throw new ArgumentException("Node is not a Root");
  1261.             if (newINode.IsTree) throw new ArgumentException("Node is a tree");
  1262.  
  1263.             IncrementVersion();
  1264.  
  1265.             OnInserting(this, NodeTreeInsertOperation.Child, newINode);
  1266.  
  1267.             NodeTree<T> newNode = GetNodeTree(newINode);
  1268.  
  1269.             newNode._Parent = this;
  1270.             newNode._Next = this._Child;
  1271.             this._Child = newNode;
  1272.  
  1273.             if (newNode.Next != null)
  1274.             {
  1275.                 NodeTree<T> Next = GetNodeTree(newNode.Next);
  1276.                 Next._Previous = newNode;
  1277.             }
  1278.  
  1279.             OnInserted(this, NodeTreeInsertOperation.Child, newINode);
  1280.         }
  1281.  
  1282.         protected virtual void AddCore(INode<T> newINode)
  1283.         {
  1284.             if (this.IsRoot) throw new InvalidOperationException("This is a Root");
  1285.  
  1286.             NodeTree<T> lastNode = GetNodeTree(Last);
  1287.  
  1288.             lastNode.InsertNextCore(newINode);
  1289.         }
  1290.  
  1291.         protected virtual void AddChildCore(INode<T> newINode)
  1292.         {
  1293.             if (this.Child == null)
  1294.                 this.InsertChildCore(newINode);
  1295.             else
  1296.             {
  1297.                 NodeTree<T> childNode = GetNodeTree(Child);
  1298.  
  1299.                 childNode.AddCore(newINode);
  1300.             }
  1301.         }
  1302.  
  1303.         //-----------------------------------------------------------------------------
  1304.  
  1305.         public ITree<T> Cut(T o)
  1306.         {
  1307.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1308.  
  1309.             INode<T> n = this[o];
  1310.             if (n == null) return null;
  1311.             return n.Cut();
  1312.         }
  1313.  
  1314.         public ITree<T> Copy(T o)
  1315.         {
  1316.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1317.  
  1318.             INode<T> n = this[o];
  1319.             if (n == null) return null;
  1320.             return n.Copy();
  1321.         }
  1322.  
  1323.         public ITree<T> DeepCopy(T o)
  1324.         {
  1325.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1326.  
  1327.             INode<T> n = this[o];
  1328.             if (n == null) return null;
  1329.             return n.DeepCopy();
  1330.         }
  1331.  
  1332.         public bool Remove(T o)
  1333.         {
  1334.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1335.  
  1336.             INode<T> n = this[o];
  1337.             if (n == null) return false;
  1338.  
  1339.             n.Remove();
  1340.             return true;
  1341.         }
  1342.  
  1343.         //-----------------------------------------------------------------------------
  1344.  
  1345.         private NodeTree<T> BoxInTree(NodeTree<T> node)
  1346.         {
  1347.             if (!node.IsRoot) throw new ArgumentException("Node is not a Root");
  1348.             if (node.IsTree) throw new ArgumentException("Node is a tree");
  1349.  
  1350.             NodeTree<T> tree = CreateTree();
  1351.  
  1352.             tree.AddChildCore(node);
  1353.  
  1354.             return tree;
  1355.         }
  1356.  
  1357.         public ITree<T> Cut()
  1358.         {
  1359.             if (this.IsRoot) throw new InvalidOperationException("This is a Root");
  1360.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1361.  
  1362.             NodeTree<T> node = CutCore();
  1363.  
  1364.             return BoxInTree(node);
  1365.         }
  1366.  
  1367.         public ITree<T> Copy()
  1368.         {
  1369.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1370.  
  1371.             if (IsTree)
  1372.             {
  1373.                 NodeTree<T> NewTree = CopyCore();
  1374.  
  1375.                 return NewTree;
  1376.             }
  1377.             else
  1378.             {
  1379.                 NodeTree<T> NewNode = CopyCore();
  1380.  
  1381.                 return BoxInTree(NewNode);
  1382.             }
  1383.         }
  1384.  
  1385.         public ITree<T> DeepCopy()
  1386.         {
  1387.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1388.  
  1389.             if (IsTree)
  1390.             {
  1391.                 NodeTree<T> NewTree = DeepCopyCore();
  1392.  
  1393.                 return NewTree;
  1394.             }
  1395.             else
  1396.             {
  1397.                 NodeTree<T> NewNode = DeepCopyCore();
  1398.  
  1399.                 return BoxInTree(NewNode);
  1400.             }
  1401.         }
  1402.  
  1403.         public void Remove()
  1404.         {
  1405.             if (this.IsRoot) throw new InvalidOperationException("This is a Root");
  1406.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1407.  
  1408.             RemoveCore();
  1409.         }
  1410.  
  1411.         //-----------------------------------------------------------------------------
  1412.  
  1413.         protected virtual NodeTree<T> CutCore()
  1414.         {
  1415.             if (this.IsRoot) throw new InvalidOperationException("This is a Root");
  1416.  
  1417.             IncrementVersion();
  1418.  
  1419.             OnCutting(this);
  1420.  
  1421.             INode<T> OldRoot = Root;
  1422.  
  1423.             if (this._Next != null)
  1424.                 this._Next._Previous = this._Previous;
  1425.  
  1426.             if (this.Previous != null)
  1427.                 this._Previous._Next = this._Next;
  1428.             else // this is a first node
  1429.             {
  1430.                 Debug.Assert(Parent.Child == this);
  1431.                 this._Parent._Child = this._Next;
  1432.                 Debug.Assert(this.Next == null || this.Next.Previous == null);
  1433.             }
  1434.  
  1435.             this._Parent = null;
  1436.             this._Previous = null;
  1437.             this._Next = null;
  1438.  
  1439.             OnCutDone(OldRoot, this);
  1440.  
  1441.             return this;
  1442.         }
  1443.  
  1444.         protected virtual NodeTree<T> CopyCore()
  1445.         {
  1446.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1447.             if (IsRoot && !IsTree) throw new InvalidOperationException("This is a Root");
  1448.  
  1449.             if (IsTree)
  1450.             {
  1451.                 NodeTree<T> NewTree = CreateTree();
  1452.  
  1453.                 OnCopying(this, NewTree);
  1454.  
  1455.                 CopyChildNodes(this, NewTree, false);
  1456.  
  1457.                 OnCopied(this, NewTree);
  1458.  
  1459.                 return NewTree;
  1460.             }
  1461.             else
  1462.             {
  1463.                 NodeTree<T> NewNode = CreateNode();
  1464.  
  1465.                 NewNode._Data = Data;
  1466.  
  1467.                 OnCopying(this, NewNode);
  1468.  
  1469.                 CopyChildNodes(this, NewNode, false);
  1470.  
  1471.                 OnCopied(this, NewNode);
  1472.  
  1473.                 return NewNode;
  1474.             }
  1475.         }
  1476.  
  1477.         protected virtual NodeTree<T> DeepCopyCore()
  1478.         {
  1479.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  1480.             if (IsRoot && !IsTree) throw new InvalidOperationException("This is a Root");
  1481.  
  1482.             if (IsTree)
  1483.             {
  1484.                 NodeTree<T> NewTree = CreateTree();
  1485.  
  1486.                 OnCopying(this, NewTree);
  1487.  
  1488.                 CopyChildNodes(this, NewTree, true);
  1489.  
  1490.                 OnCopied(this, NewTree);
  1491.  
  1492.                 return NewTree;
  1493.             }
  1494.             else
  1495.             {
  1496.                 NodeTree<T> NewNode = CreateNode();
  1497.  
  1498.                 NewNode._Data = DeepCopyData(Data);
  1499.  
  1500.                 OnDeepCopying(this, NewNode);
  1501.  
  1502.                 CopyChildNodes(this, NewNode, true);
  1503.  
  1504.                 OnDeepCopied(this, NewNode);
  1505.  
  1506.                 return NewNode;
  1507.             }
  1508.         }
  1509.  
  1510.         private void CopyChildNodes(INode<T> oldNode, NodeTree<T> newNode, bool bDeepCopy)
  1511.         {
  1512.             NodeTree<T> previousNewChildNode = null;
  1513.  
  1514.             for (INode<T> oldChildNode = oldNode.Child; oldChildNode != null; oldChildNode = oldChildNode.Next)
  1515.             {
  1516.                 NodeTree<T> newChildNode = CreateNode();
  1517.  
  1518.                 if (!bDeepCopy)
  1519.                     newChildNode._Data = oldChildNode.Data;
  1520.                 else
  1521.                     newChildNode._Data = DeepCopyData(oldChildNode.Data);
  1522.  
  1523.                 //              if ( ! bDeepCopy )
  1524.                 //                  OnCopying( oldChildNode, newChildNode );
  1525.                 //              else
  1526.                 //                  OnDeepCopying( oldChildNode, newChildNode );
  1527.  
  1528.                 if (oldChildNode.Previous == null) newNode._Child = newChildNode;
  1529.  
  1530.                 newChildNode._Parent = newNode;
  1531.                 newChildNode._Previous = previousNewChildNode;
  1532.                 if (previousNewChildNode != null) previousNewChildNode._Next = newChildNode;
  1533.  
  1534.                 //              if ( ! bDeepCopy )
  1535.                 //                  OnCopied( oldChildNode, newChildNode );
  1536.                 //              else
  1537.                 //                  OnDeepCopied( oldChildNode, newChildNode );
  1538.  
  1539.                 CopyChildNodes(oldChildNode, newChildNode, bDeepCopy);
  1540.  
  1541.                 previousNewChildNode = newChildNode;
  1542.             }
  1543.         }
  1544.  
  1545.  
  1546.         protected virtual void RemoveCore()
  1547.         {
  1548.             if (this.IsRoot) throw new InvalidOperationException("This is a Root");
  1549.  
  1550.             CutCore();
  1551.         }
  1552.  
  1553.         //-----------------------------------------------------------------------------
  1554.  
  1555.         public bool CanMoveToParent
  1556.         {
  1557.             get
  1558.             {
  1559.                 if (this.IsRoot) return false;
  1560.                 if (this.IsTop) return false;
  1561.  
  1562.                 return true;
  1563.             }
  1564.         }
  1565.  
  1566.         public bool CanMoveToPrevious
  1567.         {
  1568.             get
  1569.             {
  1570.                 if (this.IsRoot) return false;
  1571.                 if (this.IsFirst) return false;
  1572.  
  1573.                 return true;
  1574.             }
  1575.         }
  1576.  
  1577.         public bool CanMoveToNext
  1578.         {
  1579.             get
  1580.             {
  1581.                 if (this.IsRoot) return false;
  1582.                 if (this.IsLast) return false;
  1583.  
  1584.                 return true;
  1585.             }
  1586.         }
  1587.  
  1588.         public bool CanMoveToChild
  1589.         {
  1590.             get
  1591.             {
  1592.                 if (this.IsRoot) return false;
  1593.                 if (this.IsFirst) return false;
  1594.  
  1595.                 return true;
  1596.             }
  1597.         }
  1598.  
  1599.         public bool CanMoveToFirst
  1600.         {
  1601.             get
  1602.             {
  1603.                 if (this.IsRoot) return false;
  1604.                 if (this.IsFirst) return false;
  1605.  
  1606.                 return true;
  1607.             }
  1608.         }
  1609.  
  1610.         public bool CanMoveToLast
  1611.         {
  1612.             get
  1613.             {
  1614.                 if (this.IsRoot) return false;
  1615.                 if (this.IsLast) return false;
  1616.  
  1617.                 return true;
  1618.             }
  1619.         }
  1620.  
  1621.         //-----------------------------------------------------------------------------
  1622.  
  1623.         public void MoveToParent()
  1624.         {
  1625.             if (!CanMoveToParent) throw new InvalidOperationException("Cannot move to Parent");
  1626.  
  1627.             NodeTree<T> parentNode = GetNodeTree(this.Parent);
  1628.  
  1629.             NodeTree<T> thisNode = this.CutCore();
  1630.  
  1631.             parentNode.InsertNextCore(thisNode);
  1632.         }
  1633.  
  1634.         public void MoveToPrevious()
  1635.         {
  1636.             if (!CanMoveToPrevious) throw new InvalidOperationException("Cannot move to Previous");
  1637.  
  1638.             NodeTree<T> previousNode = GetNodeTree(this.Previous);
  1639.  
  1640.             NodeTree<T> thisNode = this.CutCore();
  1641.  
  1642.             previousNode.InsertPreviousCore(thisNode);
  1643.         }
  1644.  
  1645.         public void MoveToNext()
  1646.         {
  1647.             if (!CanMoveToNext) throw new InvalidOperationException("Cannot move to Next");
  1648.  
  1649.             NodeTree<T> nextNode = GetNodeTree(this.Next);
  1650.  
  1651.             NodeTree<T> thisNode = this.CutCore();
  1652.  
  1653.             nextNode.InsertNextCore(thisNode);
  1654.         }
  1655.  
  1656.         public void MoveToChild()
  1657.         {
  1658.             if (!CanMoveToChild) throw new InvalidOperationException("Cannot move to Child");
  1659.  
  1660.             NodeTree<T> previousNode = GetNodeTree(this.Previous);
  1661.  
  1662.             NodeTree<T> thisNode = this.CutCore();
  1663.  
  1664.             previousNode.AddChildCore(thisNode);
  1665.         }
  1666.  
  1667.         public void MoveToFirst()
  1668.         {
  1669.             if (!CanMoveToFirst) throw new InvalidOperationException("Cannot move to first");
  1670.  
  1671.             NodeTree<T> firstNode = GetNodeTree(this.First);
  1672.  
  1673.             NodeTree<T> thisNode = this.CutCore();
  1674.  
  1675.             firstNode.InsertPreviousCore(thisNode);
  1676.         }
  1677.  
  1678.  
  1679.         public void MoveToLast()
  1680.         {
  1681.             if (!CanMoveToLast) throw new InvalidOperationException("Cannot move to last");
  1682.  
  1683.             NodeTree<T> lastNode = GetNodeTree(this.Last);
  1684.  
  1685.             NodeTree<T> thisNode = this.CutCore();
  1686.  
  1687.             lastNode.InsertNextCore(thisNode);
  1688.         }
  1689.  
  1690.         //-----------------------------------------------------------------------------
  1691.         // Enumerators
  1692.  
  1693.         public virtual IEnumerableCollection<INode<T>> Nodes
  1694.         {
  1695.             get
  1696.             {
  1697.                 return All.Nodes;
  1698.             }
  1699.         }
  1700.  
  1701.         public virtual IEnumerableCollection<T> Values
  1702.         {
  1703.             get
  1704.             {
  1705.                 return All.Values;
  1706.             }
  1707.         }
  1708.  
  1709.         //-----------------------------------------------------------------------------
  1710.         // BaseEnumerableCollectionPair
  1711.  
  1712.         protected abstract class BaseEnumerableCollectionPair : IEnumerableCollectionPair<T>
  1713.         {
  1714.             private NodeTree<T> _Root = null;
  1715.  
  1716.             protected NodeTree<T> Root
  1717.             {
  1718.                 get { return _Root; }
  1719.                 set { _Root = value; }
  1720.             }
  1721.  
  1722.             protected BaseEnumerableCollectionPair(NodeTree<T> root)
  1723.             {
  1724.                 _Root = root;
  1725.             }
  1726.  
  1727.             // Nodes
  1728.             public abstract IEnumerableCollection<INode<T>> Nodes { get; }
  1729.  
  1730.             protected abstract class BaseNodesEnumerableCollection : IEnumerableCollection<INode<T>>, IEnumerator<INode<T>>
  1731.             {
  1732.                 private int _Version = 0;
  1733.                 private object _SyncRoot = new object();
  1734.  
  1735.                 private NodeTree<T> _Root = null;
  1736.                 protected NodeTree<T> Root
  1737.                 {
  1738.                     get { return _Root; }
  1739.                     set { _Root = value; }
  1740.                 }
  1741.  
  1742.                 private INode<T> _CurrentNode = null;
  1743.                 protected INode<T> CurrentNode
  1744.                 {
  1745.                     get { return _CurrentNode; }
  1746.                     set { _CurrentNode = value; }
  1747.                 }
  1748.  
  1749.                 private bool _BeforeFirst = true;
  1750.                 protected bool BeforeFirst
  1751.                 {
  1752.                     get { return _BeforeFirst; }
  1753.                     set { _BeforeFirst = value; }
  1754.                 }
  1755.  
  1756.                 private bool _AfterLast = false;
  1757.                 protected bool AfterLast
  1758.                 {
  1759.                     get { return _AfterLast; }
  1760.                     set { _AfterLast = value; }
  1761.                 }
  1762.  
  1763.                 protected BaseNodesEnumerableCollection(NodeTree<T> root)
  1764.                 {
  1765.                     _Root = root;
  1766.                     _CurrentNode = root;
  1767.  
  1768.                     _Version = _Root.Version;
  1769.                 }
  1770.  
  1771.                 ~BaseNodesEnumerableCollection()
  1772.                 {
  1773.                     Dispose(false);
  1774.                 }
  1775.  
  1776.                 protected abstract BaseNodesEnumerableCollection CreateCopy();
  1777.  
  1778.                 protected virtual bool HasChanged { get { return _Root.HasChanged(_Version); } }
  1779.  
  1780.                 // IDisposable
  1781.                 public void Dispose()
  1782.                 {
  1783.                     Dispose(true);
  1784.  
  1785.                     GC.SuppressFinalize(this);
  1786.                 }
  1787.  
  1788.                 protected virtual void Dispose(bool disposing)
  1789.                 {
  1790.                 }
  1791.  
  1792.                 // IEnumerable
  1793.                 IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
  1794.  
  1795.                 // IEnumerable<INode<T>>
  1796.                 public virtual IEnumerator<INode<T>> GetEnumerator()
  1797.                 {
  1798.                     Reset();
  1799.  
  1800.                     return this;
  1801.                 }
  1802.  
  1803.                 // ICollection
  1804.                 public virtual int Count
  1805.                 {
  1806.                     get
  1807.                     {
  1808.                         BaseNodesEnumerableCollection e = CreateCopy();
  1809.  
  1810.                         int i = 0;
  1811.                         foreach (INode<T> o in e) i++;
  1812.                         return i;
  1813.                     }
  1814.                 }
  1815.  
  1816.                 public virtual bool IsSynchronized { get { return false; } }
  1817.  
  1818.                 public virtual object SyncRoot { get { return _SyncRoot; } }
  1819.  
  1820.                 void ICollection.CopyTo(Array array, int index)
  1821.                 {
  1822.                     if (array == null) throw new ArgumentNullException("array");
  1823.                     if (array.Rank > 1) throw new ArgumentException("array is multidimensional", "array");
  1824.                     if (index < 0) throw new ArgumentOutOfRangeException("index");
  1825.  
  1826.                     int count = Count;
  1827.  
  1828.                     if (count > 0)
  1829.                         if (index >= array.Length) throw new ArgumentException("index is out of bounds", "index");
  1830.  
  1831.                     if (index + count > array.Length) throw new ArgumentException("Not enough space in array", "array");
  1832.  
  1833.                     BaseNodesEnumerableCollection e = CreateCopy();
  1834.  
  1835.                     foreach (INode<T> n in e)
  1836.                         array.SetValue(n, index++);
  1837.                 }
  1838.  
  1839.                 public virtual void CopyTo(T[] array, int index)
  1840.                 {
  1841.                     ((ICollection)this).CopyTo(array, index);
  1842.                 }
  1843.  
  1844.                 // ICollectionEnumerable<INode<T>>
  1845.                 public virtual bool Contains(INode<T> item)
  1846.                 {
  1847.                     BaseNodesEnumerableCollection e = CreateCopy();
  1848.  
  1849.                     IEqualityComparer<INode<T>> comparer = EqualityComparer<INode<T>>.Default;
  1850.  
  1851.                     foreach (INode<T> n in e)
  1852.                         if (comparer.Equals(n, item))
  1853.                             return true;
  1854.  
  1855.                     return false;
  1856.                 }
  1857.  
  1858.                 // IEnumerator
  1859.                 object IEnumerator.Current
  1860.                 {
  1861.                     get { return Current; }
  1862.                 }
  1863.  
  1864.                 // IEnumerator<INode<T>>
  1865.                 public virtual void Reset()
  1866.                 {
  1867.                     if (HasChanged) throw new InvalidOperationException("Tree has been modified.");
  1868.  
  1869.                     _CurrentNode = _Root;
  1870.  
  1871.                     _BeforeFirst = true;
  1872.                     _AfterLast = false;
  1873.                 }
  1874.  
  1875.                 public virtual bool MoveNext()
  1876.                 {
  1877.                     if (HasChanged) throw new InvalidOperationException("Tree has been modified.");
  1878.  
  1879.                     _BeforeFirst = false;
  1880.  
  1881.                     return true;
  1882.                 }
  1883.  
  1884.                 public virtual INode<T> Current
  1885.                 {
  1886.                     get
  1887.                     {
  1888.                         if (_BeforeFirst) throw new InvalidOperationException("Enumeration has not started.");
  1889.                         if (_AfterLast) throw new InvalidOperationException("Enumeration has finished.");
  1890.  
  1891.                         return _CurrentNode;
  1892.                     }
  1893.                 }
  1894.  
  1895.             }
  1896.  
  1897.             // Find
  1898.             public virtual INode<T> Find(T data)
  1899.             {
  1900.                 IEqualityComparer<T> comparer = _Root.DataComparer;
  1901.  
  1902.                 INode<T> retval = null;
  1903.  
  1904.                 foreach (INode<T> node in this.Nodes)
  1905.                     if (comparer.Equals(node.Data, data))
  1906.                         if (retval != null)
  1907.                         {
  1908.                             Debug.Assert(false, "Multiple matches");
  1909.                             return null;
  1910.                         }
  1911.                         else retval = node;
  1912.  
  1913.                 return retval;
  1914.             }
  1915.  
  1916.             public virtual INode<T> Find(Predicate<T> predicate)
  1917.             {
  1918.                 INode<T> retval = null;
  1919.  
  1920.                 foreach (INode<T> node in this.Nodes)
  1921.                     if (predicate(node.Data))
  1922.                         if (retval != null)
  1923.                         {
  1924.                             Debug.Assert(false, "Multiple matches");
  1925.                             return null;
  1926.                         }
  1927.                         else retval = node;
  1928.  
  1929.                 return retval;
  1930.             }
  1931.  
  1932.  
  1933.             // Values
  1934.             public virtual IEnumerableCollection<T> Values
  1935.             {
  1936.                 get
  1937.                 {
  1938.                     return new ValuesEnumerableCollection(_Root.DataComparer, this.Nodes);
  1939.                 }
  1940.             }
  1941.  
  1942.             private class ValuesEnumerableCollection : IEnumerableCollection<T>, IEnumerator<T>
  1943.             {
  1944.                 IEqualityComparer<T> _DataComparer;
  1945.                 private IEnumerableCollection<INode<T>> _Nodes;
  1946.                 private IEnumerator<INode<T>> _Enumerator;
  1947.  
  1948.                 public ValuesEnumerableCollection(IEqualityComparer<T> dataComparer, IEnumerableCollection<INode<T>> nodes)
  1949.                 {
  1950.                     _DataComparer = dataComparer;
  1951.                     _Nodes = nodes;
  1952.                     _Enumerator = _Nodes.GetEnumerator();
  1953.                 }
  1954.  
  1955.                 protected ValuesEnumerableCollection(ValuesEnumerableCollection o)
  1956.                 {
  1957.                     _Nodes = o._Nodes;
  1958.                     _Enumerator = _Nodes.GetEnumerator();
  1959.                 }
  1960.  
  1961.                 protected virtual ValuesEnumerableCollection CreateCopy()
  1962.                 {
  1963.                     return new ValuesEnumerableCollection(this);
  1964.                 }
  1965.  
  1966.                 // IDisposable
  1967.                 ~ValuesEnumerableCollection()
  1968.                 {
  1969.                     Dispose(false);
  1970.                 }
  1971.  
  1972.                 public void Dispose()
  1973.                 {
  1974.                     Dispose(true);
  1975.  
  1976.                     GC.SuppressFinalize(this);
  1977.                 }
  1978.  
  1979.                 protected virtual void Dispose(bool disposing)
  1980.                 {
  1981.                 }
  1982.  
  1983.                 // IEnumerable
  1984.                 IEnumerator IEnumerable.GetEnumerator()
  1985.                 {
  1986.                     return GetEnumerator();
  1987.                 }
  1988.  
  1989.                 // IEnumerable<T>
  1990.                 public virtual IEnumerator<T> GetEnumerator()
  1991.                 {
  1992.                     Reset();
  1993.  
  1994.                     return this;
  1995.                 }
  1996.  
  1997.                 // ICollection
  1998.                 public virtual int Count
  1999.                 {
  2000.                     get
  2001.                     {
  2002.                         return _Nodes.Count;
  2003.                     }
  2004.                 }
  2005.  
  2006.                 public virtual bool IsSynchronized { get { return false; } }
  2007.  
  2008.                 public virtual object SyncRoot { get { return _Nodes.SyncRoot; } }
  2009.  
  2010.                 public virtual void CopyTo(Array array, int index)
  2011.                 {
  2012.                     if (array == null) throw new ArgumentNullException("array");
  2013.                     if (array.Rank > 1) throw new ArgumentException("array is multidimensional", "array");
  2014.                     if (index < 0) throw new ArgumentOutOfRangeException("index");
  2015.  
  2016.                     int count = Count;
  2017.  
  2018.                     if (count > 0)
  2019.                         if (index >= array.Length) throw new ArgumentException("index is out of bounds", "index");
  2020.  
  2021.                     if (index + count > array.Length) throw new ArgumentException("Not enough space in array", "array");
  2022.  
  2023.                     ValuesEnumerableCollection e = CreateCopy();
  2024.  
  2025.                     foreach (T n in e)
  2026.                         array.SetValue(n, index++);
  2027.                 }
  2028.  
  2029.                 // IEnumerableCollection<T>
  2030.                 public virtual bool Contains(T item)
  2031.                 {
  2032.                     ValuesEnumerableCollection e = CreateCopy();
  2033.  
  2034.                     foreach (T n in e)
  2035.                         if (_DataComparer.Equals(n, item))
  2036.                             return true;
  2037.  
  2038.                     return false;
  2039.                 }
  2040.  
  2041.                 // IEnumerator
  2042.                 object IEnumerator.Current
  2043.                 {
  2044.                     get { return Current; }
  2045.                 }
  2046.  
  2047.                 // IEnumerator<T> Members
  2048.                 public virtual void Reset()
  2049.                 {
  2050.                     _Enumerator.Reset();
  2051.                 }
  2052.  
  2053.                 public virtual bool MoveNext()
  2054.                 {
  2055.                     return _Enumerator.MoveNext();
  2056.                 }
  2057.  
  2058.                 public virtual T Current
  2059.                 {
  2060.                     get
  2061.                     {
  2062.                         if (_Enumerator == null) { Debug.Assert(false); return default(T); }
  2063.                         if (_Enumerator.Current == null) { Debug.Assert(false); return default(T); }
  2064.  
  2065.                         return _Enumerator.Current.Data;
  2066.                     }
  2067.                 }
  2068.             }
  2069.         }
  2070.  
  2071.         //-----------------------------------------------------------------------------
  2072.         // AllEnumerator
  2073.  
  2074.         public IEnumerableCollectionPair<T> All { get { return new AllEnumerator(this); } }
  2075.  
  2076.         protected class AllEnumerator : BaseEnumerableCollectionPair
  2077.         {
  2078.             public AllEnumerator(NodeTree<T> root) : base(root) { }
  2079.  
  2080.             public override IEnumerableCollection<INode<T>> Nodes
  2081.             {
  2082.                 get
  2083.                 {
  2084.                     return new NodesEnumerableCollection(Root);
  2085.                 }
  2086.             }
  2087.  
  2088.             protected class NodesEnumerableCollection : BaseNodesEnumerableCollection
  2089.             {
  2090.                 private bool _First = true;
  2091.  
  2092.                 public NodesEnumerableCollection(NodeTree<T> root) : base(root) { }
  2093.  
  2094.                 protected NodesEnumerableCollection(NodesEnumerableCollection o) : base(o.Root) { }
  2095.  
  2096.                 protected override BaseNodesEnumerableCollection CreateCopy()
  2097.                 {
  2098.                     return new NodesEnumerableCollection(this);
  2099.                 }
  2100.  
  2101.                 public override void Reset()
  2102.                 {
  2103.                     base.Reset();
  2104.  
  2105.                     _First = true;
  2106.                 }
  2107.  
  2108.                 public override bool MoveNext()
  2109.                 {
  2110.                     if (!base.MoveNext()) goto hell;
  2111.  
  2112.                     if (CurrentNode == null) throw new InvalidOperationException("Current is null");
  2113.  
  2114.                     if (CurrentNode.IsRoot)
  2115.                     {
  2116.                         CurrentNode = CurrentNode.Child;
  2117.                         if (CurrentNode == null) goto hell;
  2118.                     }
  2119.  
  2120.                     if (_First) { _First = false; return true; }
  2121.  
  2122.                     if (CurrentNode.Child != null) { CurrentNode = CurrentNode.Child; return true; }
  2123.  
  2124.                     for (; CurrentNode.Parent != null; CurrentNode = CurrentNode.Parent)
  2125.                     {
  2126.                         if (CurrentNode == Root) goto hell;
  2127.                         if (CurrentNode.Next != null) { CurrentNode = CurrentNode.Next; return true; }
  2128.                     }
  2129.  
  2130.                 hell:
  2131.  
  2132.                     AfterLast = true;
  2133.                     return false;
  2134.                 }
  2135.             }
  2136.  
  2137.         }
  2138.  
  2139.         //-----------------------------------------------------------------------------
  2140.         // AllChildrenEnumerator
  2141.  
  2142.         public IEnumerableCollectionPair<T> AllChildren { get { return new AllChildrenEnumerator(this); } }
  2143.  
  2144.         private class AllChildrenEnumerator : BaseEnumerableCollectionPair
  2145.         {
  2146.             public AllChildrenEnumerator(NodeTree<T> root) : base(root) { }
  2147.  
  2148.             public override IEnumerableCollection<INode<T>> Nodes
  2149.             {
  2150.                 get
  2151.                 {
  2152.                     return new NodesEnumerableCollection(Root);
  2153.                 }
  2154.             }
  2155.  
  2156.             protected class NodesEnumerableCollection : BaseNodesEnumerableCollection
  2157.             {
  2158.                 public NodesEnumerableCollection(NodeTree<T> root) : base(root) { }
  2159.  
  2160.                 protected NodesEnumerableCollection(NodesEnumerableCollection o) : base(o.Root) { }
  2161.  
  2162.                 protected override BaseNodesEnumerableCollection CreateCopy()
  2163.                 {
  2164.                     return new NodesEnumerableCollection(this);
  2165.                 }
  2166.  
  2167.                 public override bool MoveNext()
  2168.                 {
  2169.                     if (!base.MoveNext()) goto hell;
  2170.  
  2171.                     if (CurrentNode == null) throw new InvalidOperationException("Current is null");
  2172.  
  2173.                     if (CurrentNode.Child != null) { CurrentNode = CurrentNode.Child; return true; }
  2174.  
  2175.                     for (; CurrentNode.Parent != null; CurrentNode = CurrentNode.Parent)
  2176.                     {
  2177.                         if (CurrentNode == Root) goto hell;
  2178.                         if (CurrentNode.Next != null) { CurrentNode = CurrentNode.Next; return true; }
  2179.                     }
  2180.  
  2181.                 hell:
  2182.  
  2183.                     AfterLast = true;
  2184.                     return false;
  2185.                 }
  2186.             }
  2187.         }
  2188.  
  2189.         //-----------------------------------------------------------------------------
  2190.         // DirectChildrenEnumerator
  2191.  
  2192.         public IEnumerableCollectionPair<T> DirectChildren { get { return new DirectChildrenEnumerator(this); } }
  2193.  
  2194.         private class DirectChildrenEnumerator : BaseEnumerableCollectionPair
  2195.         {
  2196.             public DirectChildrenEnumerator(NodeTree<T> root) : base(root) { }
  2197.  
  2198.             public override IEnumerableCollection<INode<T>> Nodes
  2199.             {
  2200.                 get
  2201.                 {
  2202.                     return new NodesEnumerableCollection(Root);
  2203.                 }
  2204.             }
  2205.  
  2206.             protected class NodesEnumerableCollection : BaseNodesEnumerableCollection
  2207.             {
  2208.                 public NodesEnumerableCollection(NodeTree<T> root) : base(root) { }
  2209.  
  2210.                 protected NodesEnumerableCollection(NodesEnumerableCollection o) : base(o.Root) { }
  2211.  
  2212.                 protected override BaseNodesEnumerableCollection CreateCopy()
  2213.                 {
  2214.                     return new NodesEnumerableCollection(this);
  2215.                 }
  2216.  
  2217.                 public override int Count
  2218.                 {
  2219.                     get
  2220.                     {
  2221.                         return Root.DirectChildCount;
  2222.                     }
  2223.                 }
  2224.  
  2225.                 public override bool MoveNext()
  2226.                 {
  2227.                     if (!base.MoveNext()) goto hell;
  2228.  
  2229.                     if (CurrentNode == null) throw new InvalidOperationException("Current is null");
  2230.  
  2231.                     if (CurrentNode == Root)
  2232.                         CurrentNode = Root.Child;
  2233.                     else
  2234.                         CurrentNode = CurrentNode.Next;
  2235.  
  2236.                     if (CurrentNode != null) return true;
  2237.  
  2238.                 hell:
  2239.  
  2240.                     AfterLast = true;
  2241.                     return false;
  2242.                 }
  2243.             }
  2244.         }
  2245.  
  2246.         //-----------------------------------------------------------------------------
  2247.         // DirectChildrenInReverseEnumerator
  2248.  
  2249.         public IEnumerableCollectionPair<T> DirectChildrenInReverse { get { return new DirectChildrenInReverseEnumerator(this); } }
  2250.  
  2251.         private class DirectChildrenInReverseEnumerator : BaseEnumerableCollectionPair
  2252.         {
  2253.             public DirectChildrenInReverseEnumerator(NodeTree<T> root) : base(root) { }
  2254.  
  2255.             public override IEnumerableCollection<INode<T>> Nodes
  2256.             {
  2257.                 get
  2258.                 {
  2259.                     return new NodesEnumerableCollection(Root);
  2260.                 }
  2261.             }
  2262.  
  2263.             protected class NodesEnumerableCollection : BaseNodesEnumerableCollection
  2264.             {
  2265.                 public NodesEnumerableCollection(NodeTree<T> root) : base(root) { }
  2266.  
  2267.                 protected NodesEnumerableCollection(NodesEnumerableCollection o) : base(o.Root) { }
  2268.  
  2269.                 protected override BaseNodesEnumerableCollection CreateCopy()
  2270.                 {
  2271.                     return new NodesEnumerableCollection(this);
  2272.                 }
  2273.  
  2274.                 public override int Count
  2275.                 {
  2276.                     get
  2277.                     {
  2278.                         return Root.DirectChildCount;
  2279.                     }
  2280.                 }
  2281.  
  2282.                 public override bool MoveNext()
  2283.                 {
  2284.                     if (!base.MoveNext()) goto hell;
  2285.  
  2286.                     if (CurrentNode == null) throw new InvalidOperationException("Current is null");
  2287.  
  2288.                     if (CurrentNode == Root)
  2289.                         CurrentNode = Root.LastChild;
  2290.                     else
  2291.                         CurrentNode = CurrentNode.Previous;
  2292.  
  2293.                     if (CurrentNode != null) return true;
  2294.  
  2295.                 hell:
  2296.  
  2297.                     AfterLast = true;
  2298.                     return false;
  2299.                 }
  2300.             }
  2301.         }
  2302.  
  2303.         //-----------------------------------------------------------------------------
  2304.         // DirectChildCount
  2305.  
  2306.         public int DirectChildCount
  2307.         {
  2308.             get
  2309.             {
  2310.                 int i = 0;
  2311.  
  2312.                 for (INode<T> n = this.Child; n != null; n = n.Next) i++;
  2313.  
  2314.                 return i;
  2315.             }
  2316.         }
  2317.  
  2318.         //-----------------------------------------------------------------------------
  2319.         // ITree<T>
  2320.  
  2321.         public virtual Type DataType
  2322.         {
  2323.             get
  2324.             {
  2325.                 return typeof(T);
  2326.             }
  2327.         }
  2328.  
  2329.         public void Clear()
  2330.         {
  2331.             if (!this.IsRoot) throw new InvalidOperationException("This is not a Root");
  2332.             if (!this.IsTree) throw new InvalidOperationException("This is not a tree");
  2333.  
  2334.             OnClearing(this);
  2335.  
  2336.             _Child = null;
  2337.  
  2338.             OnCleared(this);
  2339.         }
  2340.  
  2341.         //-----------------------------------------------------------------------------
  2342.         // GetNodeTree
  2343.  
  2344.         protected static NodeTree<T> GetNodeTree(ITree<T> tree)
  2345.         {
  2346.             if (tree == null) throw new ArgumentNullException("Tree is null");
  2347.  
  2348.             return (NodeTree<T>)tree; // can throw an InvalidCastException.
  2349.         }
  2350.  
  2351.         protected static NodeTree<T> GetNodeTree(INode<T> node)
  2352.         {
  2353.             if (node == null) throw new ArgumentNullException("Node is null");
  2354.  
  2355.             return (NodeTree<T>)node; // can throw an InvalidCastException.
  2356.         }
  2357.  
  2358.         //-----------------------------------------------------------------------------
  2359.         // ICollection
  2360.  
  2361.         //      public virtual bool IsSynchronized { get { return false; } } // Not thread safe
  2362.  
  2363.         //      public virtual T SyncRoot { get { return this; } } // Not sure about this!
  2364.  
  2365.         public virtual int Count
  2366.         {
  2367.             get
  2368.             {
  2369.                 int i = IsRoot ? 0 : 1;
  2370.  
  2371.                 for (INode<T> n = this.Child; n != null; n = n.Next)
  2372.                     i += n.Count;
  2373.  
  2374.                 return i;
  2375.             }
  2376.         }
  2377.  
  2378.         public virtual bool IsReadOnly { get { return false; } }
  2379.  
  2380.         //-----------------------------------------------------------------------------
  2381.         // Sorting
  2382.  
  2383.         public virtual void SortAllChildren()
  2384.         {
  2385.             foreach (INode<T> node in All.Nodes) node.SortDirectChildren();
  2386.         }
  2387.  
  2388.         public virtual void SortAllChildren(Comparison<T> comparison)
  2389.         {
  2390.             foreach (INode<T> node in All.Nodes) node.SortDirectChildren(comparison);
  2391.         }
  2392.  
  2393.         public virtual void SortAllChildren(IComparer<T> comparer)
  2394.         {
  2395.             foreach (INode<T> node in All.Nodes) node.SortDirectChildren(comparer);
  2396.         }
  2397.  
  2398.         public virtual void SortDirectChildren()
  2399.         {
  2400.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  2401.  
  2402.             if (DirectChildCount < 2) return;
  2403.  
  2404.             List<INode<T>> children = new List<INode<T>>(DirectChildren.Nodes);
  2405.  
  2406.             children.Sort();
  2407.  
  2408.             SortDirectChildrenCore(children);
  2409.         }
  2410.  
  2411.         public virtual void SortDirectChildren(Comparison<T> comparison)
  2412.         {
  2413.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  2414.  
  2415.             if (DirectChildCount < 2) return;
  2416.  
  2417.             List<INode<T>> children = new List<INode<T>>(DirectChildren.Nodes);
  2418.  
  2419.             children.Sort((x, y) => comparison(x.Data, y.Data));
  2420.  
  2421.             SortDirectChildrenCore(children);
  2422.         }
  2423.  
  2424.         public virtual void SortDirectChildren(IComparer<T> comparer)
  2425.         {
  2426.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  2427.  
  2428.             if (DirectChildCount < 2) return;
  2429.  
  2430.             List<INode<T>> children = new List<INode<T>>(DirectChildren.Nodes);
  2431.  
  2432.             NodeComparer<T> nodeComparer = new NodeComparer<T>(comparer);
  2433.  
  2434.             children.Sort(nodeComparer);
  2435.  
  2436.             SortDirectChildrenCore(children);
  2437.         }
  2438.  
  2439.         class NodeComparer<T> : IComparer<INode<T>>
  2440.         {
  2441.             IComparer<T> _DataComparer = null;
  2442.  
  2443.             public NodeComparer(IComparer<T> dataComparer)
  2444.             {
  2445.                 _DataComparer = dataComparer;
  2446.             }
  2447.  
  2448.             public int Compare(INode<T> x, INode<T> y)
  2449.             {
  2450.                 return _DataComparer.Compare(x.Data, y.Data);
  2451.             }
  2452.         }
  2453.  
  2454.         void SortDirectChildrenCore(List<INode<T>> children)
  2455.         {
  2456.             _Child = null;
  2457.  
  2458.             NodeTree<T> previous = null;
  2459.             foreach (INode<T> iChild in children)
  2460.             {
  2461.                 NodeTree<T> child = GetNodeTree(iChild);
  2462.  
  2463.                 child._Parent = this;
  2464.  
  2465.                 child._Previous = null;
  2466.                 child._Next = null;
  2467.  
  2468.                 if (_Child == null)
  2469.                 {
  2470.                     _Child = child;
  2471.                 }
  2472.                 else
  2473.                 {
  2474.                     previous._Next = child;
  2475.                     child._Previous = previous;
  2476.                 }
  2477.  
  2478.                 previous = child;
  2479.             }
  2480.         }
  2481.  
  2482.         //-----------------------------------------------------------------------------
  2483.         // Events
  2484.  
  2485.         private EventHandlerList _EventHandlerList;
  2486.  
  2487.         protected EventHandlerList EventHandlerList
  2488.         {
  2489.             get { return _EventHandlerList; }
  2490.             //set { _EventHandlerList = value; }
  2491.         }
  2492.  
  2493.         protected EventHandlerList GetCreateEventHandlerList()
  2494.         {
  2495.             if (_EventHandlerList == null) _EventHandlerList = new EventHandlerList();
  2496.  
  2497.             return _EventHandlerList;
  2498.         }
  2499.  
  2500.         private static readonly object _ValidateEventKey = new object();
  2501.         private static readonly object _ClearingEventKey = new object();
  2502.         private static readonly object _ClearedEventKey = new object();
  2503.         private static readonly object _SettingEventKey = new object();
  2504.         private static readonly object _SetDoneEventKey = new object();
  2505.         private static readonly object _InsertingEventKey = new object();
  2506.         private static readonly object _InsertedEventKey = new object();
  2507.         private static readonly object _CuttingEventKey = new object();
  2508.         private static readonly object _CutDoneEventKey = new object();
  2509.         private static readonly object _CopyingEventKey = new object();
  2510.         private static readonly object _CopiedEventKey = new object();
  2511.         private static readonly object _DeepCopyingEventKey = new object();
  2512.         private static readonly object _DeepCopiedEventKey = new object();
  2513.  
  2514.         protected static object ValidateEventKey { get { return _ValidateEventKey; } }
  2515.         protected static object ClearingEventKey { get { return _ClearingEventKey; } }
  2516.         protected static object ClearedEventKey { get { return _ClearedEventKey; } }
  2517.         protected static object SettingEventKey { get { return _SettingEventKey; } }
  2518.         protected static object SetDoneEventKey { get { return _SetDoneEventKey; } }
  2519.         protected static object InsertingEventKey { get { return _InsertingEventKey; } }
  2520.         protected static object InsertedEventKey { get { return _InsertedEventKey; } }
  2521.         protected static object CuttingEventKey { get { return _CuttingEventKey; } }
  2522.         protected static object CutDoneEventKey { get { return _CutDoneEventKey; } }
  2523.         protected static object CopyingEventKey { get { return _CopyingEventKey; } }
  2524.         protected static object CopiedEventKey { get { return _CopiedEventKey; } }
  2525.         protected static object DeepCopyingEventKey { get { return _DeepCopyingEventKey; } }
  2526.         protected static object DeepCopiedEventKey { get { return _DeepCopiedEventKey; } }
  2527.  
  2528.         public event EventHandler<NodeTreeDataEventArgs<T>> Validate
  2529.         {
  2530.             add
  2531.             {
  2532.                 GetCreateEventHandlerList().AddHandler(ValidateEventKey, value);
  2533.             }
  2534.  
  2535.             remove
  2536.             {
  2537.                 GetCreateEventHandlerList().RemoveHandler(ValidateEventKey, value);
  2538.             }
  2539.         }
  2540.  
  2541.         public event EventHandler Clearing
  2542.         {
  2543.             add
  2544.             {
  2545.                 GetCreateEventHandlerList().AddHandler(ClearingEventKey, value);
  2546.             }
  2547.  
  2548.             remove
  2549.             {
  2550.                 GetCreateEventHandlerList().RemoveHandler(ClearingEventKey, value);
  2551.             }
  2552.         }
  2553.  
  2554.         public event EventHandler Cleared
  2555.         {
  2556.             add
  2557.             {
  2558.                 GetCreateEventHandlerList().AddHandler(ClearedEventKey, value);
  2559.             }
  2560.  
  2561.             remove
  2562.             {
  2563.                 GetCreateEventHandlerList().RemoveHandler(ClearedEventKey, value);
  2564.             }
  2565.         }
  2566.  
  2567.         public event EventHandler<NodeTreeDataEventArgs<T>> Setting
  2568.         {
  2569.             add
  2570.             {
  2571.                 GetCreateEventHandlerList().AddHandler(SettingEventKey, value);
  2572.             }
  2573.  
  2574.             remove
  2575.             {
  2576.                 GetCreateEventHandlerList().RemoveHandler(SettingEventKey, value);
  2577.             }
  2578.         }
  2579.  
  2580.         public event EventHandler<NodeTreeDataEventArgs<T>> SetDone
  2581.         {
  2582.             add
  2583.             {
  2584.                 GetCreateEventHandlerList().AddHandler(SetDoneEventKey, value);
  2585.             }
  2586.  
  2587.             remove
  2588.             {
  2589.                 GetCreateEventHandlerList().RemoveHandler(SetDoneEventKey, value);
  2590.             }
  2591.         }
  2592.  
  2593.         public event EventHandler<NodeTreeInsertEventArgs<T>> Inserting
  2594.         {
  2595.             add
  2596.             {
  2597.                 GetCreateEventHandlerList().AddHandler(InsertingEventKey, value);
  2598.             }
  2599.  
  2600.             remove
  2601.             {
  2602.                 GetCreateEventHandlerList().RemoveHandler(InsertingEventKey, value);
  2603.             }
  2604.         }
  2605.  
  2606.         public event EventHandler<NodeTreeInsertEventArgs<T>> Inserted
  2607.         {
  2608.             add
  2609.             {
  2610.                 GetCreateEventHandlerList().AddHandler(InsertedEventKey, value);
  2611.             }
  2612.  
  2613.             remove
  2614.             {
  2615.                 GetCreateEventHandlerList().RemoveHandler(InsertedEventKey, value);
  2616.             }
  2617.         }
  2618.  
  2619.         public event EventHandler Cutting
  2620.         {
  2621.             add
  2622.             {
  2623.                 GetCreateEventHandlerList().AddHandler(CuttingEventKey, value);
  2624.             }
  2625.  
  2626.             remove
  2627.             {
  2628.                 GetCreateEventHandlerList().RemoveHandler(CuttingEventKey, value);
  2629.             }
  2630.         }
  2631.  
  2632.         public event EventHandler CutDone
  2633.         {
  2634.             add
  2635.             {
  2636.                 GetCreateEventHandlerList().AddHandler(CutDoneEventKey, value);
  2637.             }
  2638.  
  2639.             remove
  2640.             {
  2641.                 GetCreateEventHandlerList().RemoveHandler(CutDoneEventKey, value);
  2642.             }
  2643.         }
  2644.  
  2645.         public event EventHandler<NodeTreeNodeEventArgs<T>> Copying
  2646.         {
  2647.             add
  2648.             {
  2649.                 GetCreateEventHandlerList().AddHandler(CopyingEventKey, value);
  2650.             }
  2651.  
  2652.             remove
  2653.             {
  2654.                 GetCreateEventHandlerList().RemoveHandler(CopyingEventKey, value);
  2655.             }
  2656.         }
  2657.  
  2658.         public event EventHandler<NodeTreeNodeEventArgs<T>> Copied
  2659.         {
  2660.             add
  2661.             {
  2662.                 GetCreateEventHandlerList().AddHandler(CopiedEventKey, value);
  2663.             }
  2664.  
  2665.             remove
  2666.             {
  2667.                 GetCreateEventHandlerList().RemoveHandler(CopiedEventKey, value);
  2668.             }
  2669.         }
  2670.  
  2671.         public event EventHandler<NodeTreeNodeEventArgs<T>> DeepCopying
  2672.         {
  2673.             add
  2674.             {
  2675.                 GetCreateEventHandlerList().AddHandler(DeepCopyingEventKey, value);
  2676.             }
  2677.  
  2678.             remove
  2679.             {
  2680.                 GetCreateEventHandlerList().RemoveHandler(DeepCopyingEventKey, value);
  2681.             }
  2682.         }
  2683.  
  2684.         public event EventHandler<NodeTreeNodeEventArgs<T>> DeepCopied
  2685.         {
  2686.             add
  2687.             {
  2688.                 GetCreateEventHandlerList().AddHandler(DeepCopiedEventKey, value);
  2689.             }
  2690.  
  2691.             remove
  2692.             {
  2693.                 GetCreateEventHandlerList().RemoveHandler(DeepCopiedEventKey, value);
  2694.             }
  2695.         }
  2696.  
  2697.  
  2698.         //-----------------------------------------------------------------------------
  2699.         // Validate
  2700.  
  2701.         protected virtual void OnValidate(INode<T> node, T data)
  2702.         {
  2703.             if (!Root.IsTree) throw new InvalidOperationException("This is not a tree");
  2704.             if (data is INode<T>) throw new ArgumentException("Object is a node");
  2705.  
  2706.             if ((!typeof(T).IsClass) || ((object)data) != null)
  2707.                 if (!DataType.IsInstanceOfType(data))
  2708.                     throw new ArgumentException("Object is not a " + DataType.Name);
  2709.  
  2710.             if (_EventHandlerList != null)
  2711.             {
  2712.                 EventHandler<NodeTreeDataEventArgs<T>> e = (EventHandler<NodeTreeDataEventArgs<T>>)_EventHandlerList[ValidateEventKey];
  2713.                 if (e != null) e(node, new NodeTreeDataEventArgs<T>(data));
  2714.             }
  2715.  
  2716.             if (!IsRoot) GetNodeTree(Root).OnValidate(node, data);
  2717.         }
  2718.  
  2719.         //-----------------------------------------------------------------------------
  2720.         // Clear
  2721.  
  2722.         protected virtual void OnClearing(ITree<T> tree)
  2723.         {
  2724.             if (_EventHandlerList != null)
  2725.             {
  2726.                 EventHandler e = (EventHandler)_EventHandlerList[ClearingEventKey];
  2727.                 if (e != null) e(tree, EventArgs.Empty);
  2728.             }
  2729.         }
  2730.  
  2731.         protected virtual void OnCleared(ITree<T> tree)
  2732.         {
  2733.             if (_EventHandlerList != null)
  2734.             {
  2735.                 EventHandler e = (EventHandler)_EventHandlerList[ClearedEventKey];
  2736.                 if (e != null) e(tree, EventArgs.Empty);
  2737.             }
  2738.         }
  2739.  
  2740.         //-----------------------------------------------------------------------------
  2741.         // Set
  2742.  
  2743.         protected virtual void OnSetting(INode<T> node, T data)
  2744.         {
  2745.             OnSettingCore(node, data, true);
  2746.         }
  2747.  
  2748.         protected virtual void OnSettingCore(INode<T> node, T data, bool raiseValidate)
  2749.         {
  2750.             if (_EventHandlerList != null)
  2751.             {
  2752.                 EventHandler<NodeTreeDataEventArgs<T>> e = (EventHandler<NodeTreeDataEventArgs<T>>)_EventHandlerList[SettingEventKey];
  2753.                 if (e != null) e(node, new NodeTreeDataEventArgs<T>(data));
  2754.             }
  2755.  
  2756.             if (!IsRoot) GetNodeTree(Root).OnSettingCore(node, data, false);
  2757.  
  2758.             if (raiseValidate) OnValidate(node, data);
  2759.         }
  2760.  
  2761.         protected virtual void OnSetDone(INode<T> node, T data)
  2762.         {
  2763.             OnSetDoneCore(node, data, true);
  2764.         }
  2765.  
  2766.         protected virtual void OnSetDoneCore(INode<T> node, T data, bool raiseValidate)
  2767.         {
  2768.             if (_EventHandlerList != null)
  2769.             {
  2770.                 EventHandler<NodeTreeDataEventArgs<T>> e = (EventHandler<NodeTreeDataEventArgs<T>>)_EventHandlerList[SetDoneEventKey];
  2771.                 if (e != null) e(node, new NodeTreeDataEventArgs<T>(data));
  2772.             }
  2773.  
  2774.             if (!IsRoot) GetNodeTree(Root).OnSetDoneCore(node, data, false);
  2775.  
  2776.             //          if ( raiseValidate ) OnValidate( Node, Data );
  2777.         }
  2778.  
  2779.         //-----------------------------------------------------------------------------
  2780.         // Insert
  2781.  
  2782.         protected virtual void OnInserting(INode<T> oldNode, NodeTreeInsertOperation operation, INode<T> newNode)
  2783.         {
  2784.             OnInsertingCore(oldNode, operation, newNode, true);
  2785.         }
  2786.  
  2787.         protected virtual void OnInsertingCore(INode<T> oldNode, NodeTreeInsertOperation operation, INode<T> newNode, bool raiseValidate)
  2788.         {
  2789.             if (_EventHandlerList != null)
  2790.             {
  2791.                 EventHandler<NodeTreeInsertEventArgs<T>> e = (EventHandler<NodeTreeInsertEventArgs<T>>)_EventHandlerList[InsertingEventKey];
  2792.                 if (e != null) e(oldNode, new NodeTreeInsertEventArgs<T>(operation, newNode));
  2793.             }
  2794.  
  2795.             if (!IsRoot) GetNodeTree(Root).OnInsertingCore(oldNode, operation, newNode, false);
  2796.  
  2797.             if (raiseValidate) OnValidate(oldNode, newNode.Data);
  2798.  
  2799.             if (raiseValidate) OnInsertingTree(newNode);
  2800.         }
  2801.  
  2802.         protected virtual void OnInsertingTree(INode<T> newNode)
  2803.         {
  2804.             for (INode<T> child = newNode.Child; child != null; child = child.Next)
  2805.             {
  2806.                 OnInsertingTree(newNode, child);
  2807.  
  2808.                 OnInsertingTree(child);
  2809.             }
  2810.         }
  2811.  
  2812.         protected virtual void OnInsertingTree(INode<T> newNode, INode<T> child)
  2813.         {
  2814.             OnInsertingTreeCore(newNode, child, true);
  2815.         }
  2816.  
  2817.         protected virtual void OnInsertingTreeCore(INode<T> newNode, INode<T> child, bool raiseValidate)
  2818.         {
  2819.             if (_EventHandlerList != null)
  2820.             {
  2821.                 EventHandler<NodeTreeInsertEventArgs<T>> e = (EventHandler<NodeTreeInsertEventArgs<T>>)_EventHandlerList[InsertingEventKey];
  2822.                 if (e != null) e(newNode, new NodeTreeInsertEventArgs<T>(NodeTreeInsertOperation.Tree, child));
  2823.             }
  2824.  
  2825.             if (!IsRoot) GetNodeTree(Root).OnInsertingTreeCore(newNode, child, false);
  2826.  
  2827.             if (raiseValidate) OnValidate(newNode, child.Data);
  2828.         }
  2829.  
  2830.         protected virtual void OnInserted(INode<T> oldNode, NodeTreeInsertOperation operation, INode<T> newNode)
  2831.         {
  2832.             OnInsertedCore(oldNode, operation, newNode, true);
  2833.         }
  2834.  
  2835.         protected virtual void OnInsertedCore(INode<T> oldNode, NodeTreeInsertOperation operation, INode<T> newNode, bool raiseValidate)
  2836.         {
  2837.             if (_EventHandlerList != null)
  2838.             {
  2839.                 EventHandler<NodeTreeInsertEventArgs<T>> e = (EventHandler<NodeTreeInsertEventArgs<T>>)_EventHandlerList[InsertedEventKey];
  2840.                 if (e != null) e(oldNode, new NodeTreeInsertEventArgs<T>(operation, newNode));
  2841.             }
  2842.  
  2843.             if (!IsRoot) GetNodeTree(Root).OnInsertedCore(oldNode, operation, newNode, false);
  2844.  
  2845.             //          if ( raiseValidate ) OnValidate( OldNode, NewNode.Data );
  2846.  
  2847.             if (raiseValidate) OnInsertedTree(newNode);
  2848.         }
  2849.  
  2850.         protected virtual void OnInsertedTree(INode<T> newNode)
  2851.         {
  2852.             for (INode<T> child = newNode.Child; child != null; child = child.Next)
  2853.             {
  2854.                 OnInsertedTree(newNode, child);
  2855.  
  2856.                 OnInsertedTree(child);
  2857.             }
  2858.         }
  2859.  
  2860.         protected virtual void OnInsertedTree(INode<T> newNode, INode<T> child)
  2861.         {
  2862.             OnInsertedTreeCore(newNode, child, true);
  2863.         }
  2864.  
  2865.         protected virtual void OnInsertedTreeCore(INode<T> newNode, INode<T> child, bool raiseValidate)
  2866.         {
  2867.             if (_EventHandlerList != null)
  2868.             {
  2869.                 EventHandler<NodeTreeInsertEventArgs<T>> e = (EventHandler<NodeTreeInsertEventArgs<T>>)_EventHandlerList[InsertedEventKey];
  2870.                 if (e != null) e(newNode, new NodeTreeInsertEventArgs<T>(NodeTreeInsertOperation.Tree, child));
  2871.             }
  2872.  
  2873.             if (!IsRoot) GetNodeTree(Root).OnInsertedTreeCore(newNode, child, false);
  2874.  
  2875.             //          if ( raiseValidate ) OnValidate( newNode, child.Data );
  2876.         }
  2877.  
  2878.         //-----------------------------------------------------------------------------
  2879.         // Cut
  2880.  
  2881.         protected virtual void OnCutting(INode<T> oldNode)
  2882.         {
  2883.             if (_EventHandlerList != null)
  2884.             {
  2885.                 EventHandler e = (EventHandler)_EventHandlerList[CuttingEventKey];
  2886.                 if (e != null) e(oldNode, EventArgs.Empty);
  2887.             }
  2888.  
  2889.             if (!IsRoot) GetNodeTree(Root).OnCutting(oldNode);
  2890.         }
  2891.  
  2892.         protected virtual void OnCutDone(INode<T> oldRoot, INode<T> oldNode)
  2893.         {
  2894.             if (_EventHandlerList != null)
  2895.             {
  2896.                 EventHandler e = (EventHandler)_EventHandlerList[CutDoneEventKey];
  2897.                 if (e != null) e(oldNode, EventArgs.Empty);
  2898.             }
  2899.  
  2900.             if (!IsTree) GetNodeTree(oldRoot).OnCutDone(oldRoot, oldNode);
  2901.         }
  2902.  
  2903.         //-----------------------------------------------------------------------------
  2904.         // Copy
  2905.  
  2906.         protected virtual void OnCopying(INode<T> oldNode, INode<T> newNode)
  2907.         {
  2908.             OnCopyingCore(oldNode, newNode, true);
  2909.         }
  2910.  
  2911.         protected virtual void OnCopyingCore(INode<T> oldNode, INode<T> newNode, bool raiseValidate)
  2912.         {
  2913.             if (_EventHandlerList != null)
  2914.             {
  2915.                 EventHandler<NodeTreeNodeEventArgs<T>> e = (EventHandler<NodeTreeNodeEventArgs<T>>)_EventHandlerList[CopyingEventKey];
  2916.                 if (e != null) e(oldNode, new NodeTreeNodeEventArgs<T>(newNode));
  2917.             }
  2918.  
  2919.             if (!IsRoot) GetNodeTree(Root).OnCopyingCore(oldNode, newNode, false);
  2920.  
  2921.             //          if ( raiseValidate ) OnValidate( oldNode, newNode.Data );
  2922.         }
  2923.  
  2924.         protected virtual void OnCopied(INode<T> oldNode, INode<T> newNode)
  2925.         {
  2926.             OnCopiedCore(oldNode, newNode, true);
  2927.         }
  2928.  
  2929.         protected virtual void OnCopiedCore(INode<T> oldNode, INode<T> newNode, bool raiseValidate)
  2930.         {
  2931.             if (_EventHandlerList != null)
  2932.             {
  2933.                 EventHandler<NodeTreeNodeEventArgs<T>> e = (EventHandler<NodeTreeNodeEventArgs<T>>)_EventHandlerList[CopiedEventKey];
  2934.                 if (e != null) e(oldNode, new NodeTreeNodeEventArgs<T>(newNode));
  2935.             }
  2936.  
  2937.             if (!IsRoot) GetNodeTree(Root).OnCopiedCore(oldNode, newNode, false);
  2938.  
  2939.             //          if ( raiseValidate ) OnValidate( oldNode, newNode.Data );
  2940.         }
  2941.  
  2942.         //-----------------------------------------------------------------------------
  2943.         // DeepCopy
  2944.  
  2945.         protected virtual void OnDeepCopying(INode<T> oldNode, INode<T> newNode)
  2946.         {
  2947.             OnDeepCopyingCore(oldNode, newNode, true);
  2948.         }
  2949.  
  2950.         protected virtual void OnDeepCopyingCore(INode<T> oldNode, INode<T> newNode, bool raiseValidate)
  2951.         {
  2952.             if (_EventHandlerList != null)
  2953.             {
  2954.                 EventHandler<NodeTreeNodeEventArgs<T>> e = (EventHandler<NodeTreeNodeEventArgs<T>>)_EventHandlerList[DeepCopyingEventKey];
  2955.                 if (e != null) e(oldNode, new NodeTreeNodeEventArgs<T>(newNode));
  2956.             }
  2957.  
  2958.             if (!IsRoot) GetNodeTree(Root).OnDeepCopyingCore(oldNode, newNode, false);
  2959.  
  2960.             //          if ( raiseValidate ) OnValidate( oldNode, newNode.Data );
  2961.         }
  2962.  
  2963.         protected virtual void OnDeepCopied(INode<T> oldNode, INode<T> newNode)
  2964.         {
  2965.             OnDeepCopiedCore(oldNode, newNode, true);
  2966.         }
  2967.  
  2968.         protected virtual void OnDeepCopiedCore(INode<T> oldNode, INode<T> newNode, bool raiseValidate)
  2969.         {
  2970.             if (_EventHandlerList != null)
  2971.             {
  2972.                 EventHandler<NodeTreeNodeEventArgs<T>> e = (EventHandler<NodeTreeNodeEventArgs<T>>)_EventHandlerList[DeepCopiedEventKey];
  2973.                 if (e != null) e(oldNode, new NodeTreeNodeEventArgs<T>(newNode));
  2974.             }
  2975.  
  2976.             if (!IsRoot) GetNodeTree(Root).OnDeepCopiedCore(oldNode, newNode, false);
  2977.  
  2978.             //          if ( raiseValidate ) OnValidate( oldNode, newNode.Data );
  2979.         }
  2980.  
  2981.         //-----------------------------------------------------------------------------
  2982.  
  2983.     } // class NodeTree
  2984.  
  2985.     //-----------------------------------------------------------------------------
  2986. }
RAW Paste Data