main
 1using System.Collections.Generic;
 2using System.Linq;
 3using gorilla.utility;
 4
 5namespace solidware.financials.service.domain.hierarchy
 6{
 7    public class Hierarchy : Visitable<Hierarchy>
 8    {
 9        static readonly Hierarchy Null = new NullHierarchy();
10
11        public void accept(Visitor<Hierarchy> visitor)
12        {
13            visitor.visit(this);
14            children.each(x => x.accept(visitor));
15        }
16
17        public void add(Hierarchy child)
18        {
19            child.parent = this;
20            children.Add(child);
21        }
22
23        public void move_to(Hierarchy new_tree)
24        {
25            parent.remove(this);
26            new_tree.add(this);
27        }
28
29        public virtual void remove(Hierarchy descendant)
30        {
31            if (children.Contains(descendant))
32                children.Remove(descendant);
33            else
34            {
35                var hierarchy = children.SingleOrDefault(x => x.contains(descendant));
36                if(null != hierarchy) hierarchy.remove(descendant);
37            }
38        }
39
40        public bool contains(Hierarchy child)
41        {
42            return everyone().Any(x => x.Equals(child));
43        }
44
45        IEnumerable<Hierarchy> everyone()
46        {
47            var all = new List<Hierarchy> {this};
48            foreach (var child in children) all.AddRange(child.everyone());
49            return all;
50        }
51
52        public bool belongs_to(Hierarchy tree)
53        {
54            return tree.contains(this);
55        }
56
57        IList<Hierarchy> children = new List<Hierarchy>();
58        Hierarchy parent = Null;
59
60        class NullHierarchy : Hierarchy
61        {
62            public override void remove(Hierarchy descendant) {}
63        }
64    }
65}