///<summary>Finds the next adjacent edge to [edge], ie the adjacent edge that creates the smallest angle</summary>
        private static LinedefSide NextEdge(LinedefSide edge, Dictionary <Linedef, int> visited_lines)
        {
            // Get relevant vertices
            Vertex vertex;                      // Vertex to be tested
            Vertex vertex_prev;                 // 'Previous' vertex

            if (edge.Front)
            {
                vertex      = edge.Line.End;
                vertex_prev = edge.Line.Start;
            }
            else
            {
                vertex      = edge.Line.Start;
                vertex_prev = edge.Line.End;
            }

            // Find next connected line with the lowest angle
            float       min_angle = Angle2D.PI2;
            LinedefSide next      = null;

            foreach (Linedef line in vertex.Linedefs)
            {
                // Ignore original line
                if (line == edge.Line)
                {
                    continue;
                }

                // Ignore if zero-length
                if (line.Start.Position == line.End.Position)
                {
                    continue;
                }

                // Get next vertex
                Vertex vertex_next;
                bool   front = true;
                if (line.Start == vertex)
                {
                    vertex_next = line.End;
                }
                else
                {
                    vertex_next = line.Start;
                    front       = false;
                }

                // Ignore already-traversed lines
                int side = (front ? 1 : 2);
                if (visited_lines.ContainsKey(line) && (visited_lines[line] & side) == side)
                {
                    continue;
                }


                // Determine angle between lines
                float angle = Angle2D.GetAngle(new Vector2D(vertex_prev.Position.x, vertex_prev.Position.y),
                                               new Vector2D(vertex.Position.x, vertex.Position.y),
                                               new Vector2D(vertex_next.Position.x, vertex_next.Position.y));

                // Check if minimum angle
                if (angle < min_angle)
                {
                    min_angle = angle;

                    if (next == null)
                    {
                        next = new LinedefSide(line, front);
                    }
                    else
                    {
                        next.Line  = line;
                        next.Front = front;
                    }
                }
            }

            // Return the next edge found
            if (next == null)
            {
                return(null);
            }
            if (!visited_lines.ContainsKey(next.Line))
            {
                visited_lines.Add(next.Line, 0);
            }
            visited_lines[next.Line] |= (next.Front ? 1 : 2);
            return(next);
        }
        /// <summary>Find the closest edge within the current outline (that isn't part of the current outline)</summary>
        private LinedefSide FindInnerEdge()
        {
            //DebugConsole.WriteLine("FindInnerEdge: processing " + vertex_valid.Count + " verts");

            // Find rightmost non-discarded vertex
            vertex_right = null;
            foreach (Vertex v in vertex_valid)
            {
                // Set rightmost if no current rightmost vertex
                if (vertex_right == null)
                {
                    vertex_right = v;
                    continue;
                }

                // Check if the vertex is rightmost
                if (v.Position.x > vertex_right.Position.x)
                {
                    vertex_right = v;
                }
            }

            // If no vertex was found, we're done
            if (vertex_right == null)
            {
                //DebugConsole.WriteLine("FindInnerEdge: no vertex_right");
                return(null);
            }

            // Go through vertex's connected lines, to find
            // the line with the smallest angle parallel with
            // the right side of the bbox
            Linedef eline     = null;
            float   min_angle = float.MaxValue;

            foreach (Linedef line in vertex_right.Linedefs)
            {
                // Ignore if zero-length
                if (line.Start == line.End)
                {
                    continue;
                }

                // Get opposite vertex
                Vertex opposite = (line.Start == vertex_right ? line.End : line.Start);

                // Determine angle
                float angle = Angle2D.GetAngle(new Vector2D(vertex_right.Position.x + 32, vertex_right.Position.y),
                                               new Vector2D(vertex_right.Position.x, vertex_right.Position.y),
                                               new Vector2D(opposite.Position.x, opposite.Position.y));

                // Check if minimum
                if (angle < min_angle)
                {
                    min_angle = angle;
                    eline     = line;
                }
            }

            // If no line was found, something is wrong (the vertex may have no attached lines)
            if (eline == null)
            {
                // Discard vertex and try again
                vertex_valid.Remove(vertex_right);
                //DebugConsole.WriteLine("vertex_valid: " + vertex_valid.Count + " verts after Remove (in FindInnerEdge)");

                return(FindInnerEdge());
            }

            // Determine appropriate side
            return(new LinedefSide(eline, (vertex_right == eline.Start)));
        }