/// <summary>
        /// Draws a branch in a tree. This function is recursive.
        /// </summary>
        /// <param name="branch">the branch to draw</param>
        /// <param name="graphics">allows graphics to be drawn</param>
        /// <param name="pen">for drawing lines</param>
        /// <param name="nodeFill">for drawing nodes</param>
        /// <param name="direction">the side of the tree the node is drawn on</param>
        /// <param name="slotsUsed">the number of slots on this side of the tree that have already been used</param>
        /// <param name="pixelsPerSlot">the number of pixels in a slot</param>
        /// <param name="childPositionX">the x-position of this branch's child</param>
        private void drawBranch(TreeNode branch, Graphics graphics, Pen pen, Brush nodeFill, int direction, int slotsUsed, float pixelsPerSlot, float childPositionX)
        {
            // calculate some useful numbers
            int slotsInThisBranch = branch.GetNumParentlessAncestors();
            float nodeCenterX = (this.Width / 2) + (direction * (slotsUsed + ((slotsInThisBranch + 1) / 2)) * pixelsPerSlot);

            // draw this node
            graphics.FillEllipse(nodeFill, nodeCenterX - (NODE_DIAMETER / 2), ValueToYCoordinate(branch.value) - (NODE_DIAMETER / 2), NODE_DIAMETER, NODE_DIAMETER);

            // draw lines from the branch node back to its child
            graphics.DrawLine(pen, childPositionX, ValueToYCoordinate(branch.GetChildren()[0].value), nodeCenterX, ValueToYCoordinate(branch.GetChildren()[0].value));
            graphics.DrawLine(pen, nodeCenterX, ValueToYCoordinate(branch.GetChildren()[0].value), nodeCenterX, ValueToYCoordinate(branch.value));

            int slotsUsedAfterParent = slotsUsed;
            foreach (TreeNode parent in branch.GetParents()) {
                drawBranch(parent, graphics, pen, nodeFill, direction, slotsUsedAfterParent, pixelsPerSlot, nodeCenterX);
                slotsUsedAfterParent += parent.GetNumParentlessAncestors(); }
        }