private void InsertLocalMinima(LocalMinima newLm)
        {
            Contract.Requires(newLm != null);

            if (MinimaList == null)
            {
                MinimaList = newLm;
            }
            else if (newLm.Y >= MinimaList.Y)
            {
                newLm.Next = MinimaList;
                MinimaList = newLm;
            }
            else
            {
                var tmpLm = MinimaList;
                while (tmpLm.Next != null && (newLm.Y < tmpLm.Next.Y))
                    tmpLm = tmpLm.Next;
                newLm.Next = tmpLm.Next;
                tmpLm.Next = newLm;
            }
        }
        private TEdge AddBoundsToLML(TEdge e)
        {
            Contract.Requires(e != null);
            Contract.Requires(e.Next != null);

            //Starting at the top of one bound we progress to the bottom where there's
            //a local minima. We then go to the top of the next bound. These two bounds
            //form the left and right (or right and left) bounds of the local minima.
            e.NextInLML = null;
            e = e.Next;
            for (; ; )
            {
                if (e.Dx == HORIZONTAL)
                {
                    //nb: proceed through horizontals when approaching from their right,
                    //    but break on horizontal minima if approaching from their left.
                    //    This ensures 'local minima' are always on the left of horizontals.
                    if (e.Next.YTop < e.YTop && e.Next.XBot > e.Prev.XBot)
                        break;
                    if (e.XTop != e.Prev.XBot)
                        SwapX(e);
                    e.NextInLML = e.Prev;
                }
                else if (e.YCurr == e.Prev.YCurr)
                    break;
                else
                    e.NextInLML = e.Prev;
                e = e.Next;
            }

            //e and e.prev are now at a local minima ...
            var newLm = new LocalMinima { Next = null, Y = e.Prev.YBot };

            if (e.Dx == HORIZONTAL) //horizontal edges never start a left bound
            {
                if (e.XBot != e.Prev.XBot)
                    SwapX(e);
                newLm.LeftBound = e.Prev;
                newLm.RightBound = e;
            }
            else if (e.Dx < e.Prev.Dx)
            {
                newLm.LeftBound = e.Prev;
                newLm.RightBound = e;
            }
            else
            {
                newLm.LeftBound = e;
                newLm.RightBound = e.Prev;
            }
            newLm.LeftBound.Side = EdgeSide.Left;
            newLm.RightBound.Side = EdgeSide.Right;
            InsertLocalMinima(newLm);

            for (; ; )
            {
                if (e.Next.YTop == e.YTop && e.Next.Dx != HORIZONTAL)
                    break;
                e.NextInLML = e.Next;
                e = e.Next;
                if (e.Dx == HORIZONTAL && e.XBot != e.Prev.XTop)
                    SwapX(e);
            }
            return e.Next;
        }
 protected void PopLocalMinima()
 {
     if (CurrentLM == null)
         return;
     CurrentLM = CurrentLM.Next;
 }
        protected virtual void Reset()
        {
            CurrentLM = MinimaList;

            //reset all edges ...
            var lm = MinimaList;
            while (lm != null)
            {
                var e = lm.LeftBound;
                while (e != null)
                {
                    e.XCurr = e.XBot;
                    e.YCurr = e.YBot;
                    e.Side = EdgeSide.Left;
                    e.OutIdx = -1;
                    e = e.NextInLML;
                }
                e = lm.RightBound;
                while (e != null)
                {
                    e.XCurr = e.XBot;
                    e.YCurr = e.YBot;
                    e.Side = EdgeSide.Right;
                    e.OutIdx = -1;
                    e = e.NextInLML;
                }
                lm = lm.Next;
            }
        }
 // ReSharper disable once UnusedMemberHiearchy.Global
 // ReSharper disable once MemberCanBeProtected.Global
 public virtual void Clear()
 {
     MinimaList = null;
     MinimaList = null;
     Edges.Clear();
 }