private static void CalculateInitialX(TreeNodeModel <T> node)
        {
            foreach (var child in node.Children)
            {
                CalculateInitialX(child);
            }

            // if no children
            if (node.IsLeaf())
            {
                // if there is a previous sibling in this set, set X to previous sibling + designated distance
                if (!node.IsLeftMost())
                {
                    node.X = node.GetPreviousSibling().X + NodeSize + SiblingDistance;
                }
                else
                {
                    // if this is the first node in a set, set X to 0
                    node.X = 0;
                }
            }
            // if there is only one child
            else if (node.Children.Count == 1)
            {
                // if this is the first node in a set, set it's X value equal to it's child's X value
                if (node.IsLeftMost())
                {
                    node.X = node.Children[0].X;
                }
                else
                {
                    node.X   = node.GetPreviousSibling().X + NodeSize + SiblingDistance;
                    node.Mod = node.X - node.Children[0].X;
                }
            }
            else
            {
                var leftChild  = node.GetLeftMostChild();
                var rightChild = node.GetRightMostChild();
                var mid        = (leftChild.X + rightChild.X) / 2;

                if (node.IsLeftMost())
                {
                    node.X = mid;
                }
                else
                {
                    node.X   = node.GetPreviousSibling().X + NodeSize + SiblingDistance;
                    node.Mod = node.X - mid;
                }
            }

            if (node.Children.Count > 0 && !node.IsLeftMost())
            {
                // Since subtrees can overlap, check for conflicts and shift tree right if needed
                CheckForConflicts(node);
            }
        }
        private static void DrawNode(TreeNodeModel <NodeModel> node, Graphics graphic)
        {
            // Set the pen
            var nodePen = node.Item.Colour;

            // rectangle where node will be positioned
            var nodeRect = new Rectangle(Convert.ToInt32(NodeMarginX + node.X * (NodeWidth + NodeMarginX)),
                                         NodeMarginY + node.Y * (NodeHeight + NodeMarginY), NodeWidth, NodeHeight);

            // draw box
            if (!node.Item.IsCompressed)
            {
                graphic.DrawRectangle(nodePen, nodeRect);
            }

            // draw content
            var font       = new Font(FontFamily.GenericMonospace, 8);
            var stringSize = graphic.MeasureString(node.ToString(), font);

            graphic.DrawString(node.ToString(), font, nodePen.Brush, nodeRect.X + NodeWidth / 2 - stringSize.Width / 2,
                               nodeRect.Y + NodeHeight / 2 - stringSize.Height / 2);

            // draw line to parent
            if (node.Parent != null)
            {
                var nodeTopMiddle    = new Point(nodeRect.X + nodeRect.Width / 2, nodeRect.Y);
                var nodeBottomMiddle = new Point(nodeTopMiddle.X, nodeTopMiddle.Y - NodeMarginY / 2);
                graphic.DrawLine(nodePen, nodeTopMiddle, nodeBottomMiddle);
            }

            // draw line to children
            if (node.Children.Count > 0)
            {
                var nodeBottomMiddle = new Point(nodeRect.X + nodeRect.Width / 2, nodeRect.Y + nodeRect.Height);
                var nodeTopMiddle    = new Point(nodeBottomMiddle.X, nodeBottomMiddle.Y + NodeMarginY / 2);
                graphic.DrawLine(nodePen, nodeBottomMiddle, nodeTopMiddle);

                // draw line over children
                if (node.Children.Count > 1)
                {
                    var childrenLineStartX = Convert.ToInt32(NodeMarginX + node.GetRightMostChild().X *
                                                             // ReSharper disable once PossibleLossOfFraction
                                                             (NodeWidth + NodeMarginX) + NodeWidth / 2);
                    var childrenLineStartY = nodeBottomMiddle.Y + NodeMarginY / 2;
                    var childrenLineStart  = new Point(childrenLineStartX, childrenLineStartY);

                    var childrenLineEndX = Convert.ToInt32(NodeMarginX +
                                                           node.GetLeftMostChild().X *(NodeWidth + NodeMarginX) +
                                                           // ReSharper disable once PossibleLossOfFraction
                                                           NodeWidth / 2);
                    var childrenLineEndY = nodeBottomMiddle.Y + NodeMarginY / 2;
                    var childrenLineEnd  = new Point(childrenLineEndX, childrenLineEndY);

                    graphic.DrawLine(Pens.Black, childrenLineStart, childrenLineEnd);
                }
            }

            foreach (var item in node.Children)
            {
                DrawNode(item, graphic);
            }
        }