private static void FirstWalk(LeafNode currentNode, int currentLevel)
        {
            currentNode.LeftSibling = GetPrevNodeAtLevel( currentLevel );
            SetPrevNodeAtLevel( currentLevel, currentNode );
            currentNode.Modifier = 0;

            if( currentNode.IsLeaf() || (currentLevel == MaxLevelDepth) )
            {
                if( currentNode.HasLeftSibling() )
                {
                    currentNode.PreliminaryLocation = currentNode.GetLeftSibling().PreliminaryLocation 
                        + HorizontalSiblingSeparationFine 
                        + CalcAverageNodeSize( currentNode.GetLeftSibling(), currentNode );
                }
                else
                {
                    currentNode.PreliminaryLocation = 0;
                }
            }
            else
            {
                var rightMostNode = currentNode.GetFirstChild();
                var leftMostNode = rightMostNode;
                FirstWalk( leftMostNode, currentLevel + 1 );

                while ( rightMostNode.HasRightSibling() )
                {
                    rightMostNode = rightMostNode.GetRightSibling();
                    FirstWalk( rightMostNode, currentLevel + 1 );
                }

                var midpoint = (leftMostNode.PreliminaryLocation + rightMostNode.PreliminaryLocation) / 2;

                if( currentNode.HasLeftSibling() )
                {
                    currentNode.PreliminaryLocation = currentNode.GetLeftSibling().PreliminaryLocation 
                        + HorizontalSiblingSeparationFine 
                        + CalcAverageNodeSize( currentNode.GetLeftSibling(), currentNode );

                    currentNode.Modifier = currentNode.PreliminaryLocation - midpoint;
                    Apportion( currentNode, currentLevel );
                }
                else
                {
                    currentNode.PreliminaryLocation = midpoint;
                }
            }
        }
        private static void Apportion(LeafNode currentNode, int currentLevel)
        {
            var leftMostNode = currentNode.GetFirstChild();
            var neighbor = leftMostNode.LeftNeighbor();
            uint compareDepth = 1;
            var depthToStop = (uint) (MaxLevelDepth - currentLevel);

            while ( leftMostNode != null && neighbor != null && compareDepth <= depthToStop )
            {
                float leftModsum = 0;
                float rightModsum = 0;

                var ancestorLeftMost = leftMostNode;
                var ancestorNeighbor = neighbor;

                for ( var i = 0; i < compareDepth; i++ )
                {
                    ancestorLeftMost = ancestorLeftMost.GetParent();
                    ancestorNeighbor = ancestorNeighbor.GetParent();
                    rightModsum += ancestorLeftMost.Modifier;
                    leftModsum += ancestorNeighbor.Modifier;
                }

                var distance = neighbor.PreliminaryLocation 
                    + leftModsum 
                    + HorizontalSubtreeSeparationCoarse 
                    + CalcAverageNodeSize( leftMostNode, neighbor ) 
                    - (leftMostNode.PreliminaryLocation + rightModsum);

                if( distance > 0 )
                {
                    uint numLeftSiblings = 0;

                    var tmp = currentNode;
                    while ( tmp != null && tmp != ancestorNeighbor ) 
                    {
                        numLeftSiblings++;
                        tmp = tmp.GetLeftSibling();
                    }

                    if( tmp == null ) return;

                    var portion = distance / numLeftSiblings;
                    for (tmp = currentNode; tmp != ancestorNeighbor; tmp = tmp.GetLeftSibling())
                    {
                        tmp.PreliminaryLocation = tmp.PreliminaryLocation + distance;
                        tmp.Modifier = tmp.Modifier + distance;
                        distance -= portion;
                    }
                }

                compareDepth++;
                leftMostNode = leftMostNode.IsLeaf()
                    ? GetLeftMost( currentNode, 0, (int) compareDepth )
                    : leftMostNode.GetFirstChild();

                neighbor = leftMostNode == null
                    ? null
                    : leftMostNode.LeftNeighbor();
            }
        }
        private static LeafNode GetLeftMost(LeafNode currentNode, int currentLevel, int searchDepth)
        {
            if( currentLevel == searchDepth ) return currentNode; 
            if( currentNode.IsLeaf() ) return null;
            
            var rightMostNode = currentNode.GetFirstChild();
            var leftMost = GetLeftMost( rightMostNode, currentLevel + 1, searchDepth );

            while ( leftMost == null && rightMostNode.HasRightSibling() ) 
            {
                leftMost = GetLeftMost( rightMostNode, currentLevel + 1, searchDepth );
                rightMostNode = rightMostNode.GetRightSibling();
            } 

            return leftMost;
        }
        private static bool SecondWalk(LeafNode currentNode, int currentLevel, int modsum)
        {
            var result = true;
            long xTemp = 0;
            long yTemp = 0;

            if( currentLevel <= MaxLevelDepth )
            {
                xTemp = _xTopAdjustment + (long) (currentNode.PreliminaryLocation + modsum);
                yTemp = _yTopAdjustment + (long) (currentLevel*(VerticalLevelSeparation + currentNode.Height));
            }

            currentNode.HorizontalCoordinate = (int)xTemp;
            currentNode.VerticalCoordinate = (int)yTemp;

            if( currentNode.HasChild() )
            {
                result = SecondWalk(currentNode.GetFirstChild(), currentLevel + 1, (int)(modsum + currentNode.Modifier));
            }

            if( result && currentNode.HasRightSibling() )
            {
                result = SecondWalk(currentNode.GetRightSibling(), currentLevel, modsum);
            }

            return result;
        }