private void CreateOutOfBoundsFreePoint(FreePoint freePoint) {
            // For an out of bounds (OOB) point, we'll link one edge from it to the inbounds edge if it's
            // out of bounds in only one direction; if in two, we'll add a bend. Currently we don't need
            // to do any more because multiple waypoints are processed as multiple subpaths.
            var oobLocation = freePoint.Point;
            Point inboundsLocation = graphGenerator.MakeInBoundsLocation(oobLocation);
            Directions dirFromGraph = PointComparer.GetDirections(inboundsLocation, oobLocation);
            freePoint.OutOfBoundsDirectionFromGraph = dirFromGraph;
            if (!PointComparer.IsPureDirection(dirFromGraph)) {
                // It's OOB in two directions so will need a bend, but we know inboundsLocation
                // is a graph corner so it has a vertex already and we don't need to look up sides.
                StaticGraphUtility.Assert(null != VisGraph.FindVertex(inboundsLocation), "graph corner vertex not found", ObstacleTree, VisGraph);
                freePoint.AddOobEdgesFromGraphCorner(TransUtil, inboundsLocation);
                return;
            }

            // We know inboundsLocation is on the nearest graphBox border ScanSegment, so this won't return a
            // null edge, and we'll just do normal join-to-one-edge handling, extending in the direction to the graph.
            var inboundsVertex = this.VisGraph.FindVertex(inboundsLocation);
            var dirToGraph = CompassVector.OppositeDir(dirFromGraph);
            if (null != inboundsVertex) {
                freePoint.AddToAdjacentVertex(this.TransUtil, inboundsVertex, dirToGraph, this.portSpliceLimitRectangle);
            }
            else {
                var edge = this.FindorCreateNearestPerpEdge(oobLocation, inboundsLocation, dirFromGraph, ScanSegment.NormalWeight);
                if (null != edge) {
                    inboundsVertex = freePoint.AddEdgeToAdjacentEdge(this.TransUtil, edge, dirToGraph, this.portSpliceLimitRectangle);
                }
            }

            // This may be an oob waypoint, in which case we want to add additional edges so we can
            // go outside graph, cross the waypoint, and come back in.  Shortest-paths will do the
            // work of determining the optimal path, to avoid backtracking.
            var inboundsLeftVertex = StaticGraphUtility.FindNextVertex(inboundsVertex, CompassVector.RotateLeft(dirToGraph));
            if (inboundsLeftVertex != null) {
                this.TransUtil.ConnectVertexToTargetVertex(freePoint.Vertex, inboundsLeftVertex, dirToGraph, ScanSegment.NormalWeight);
            }
            var inboundsRightVertex = StaticGraphUtility.FindNextVertex(inboundsVertex, CompassVector.RotateRight(dirToGraph));
            if (inboundsRightVertex != null) {
                this.TransUtil.ConnectVertexToTargetVertex(freePoint.Vertex, inboundsRightVertex, dirToGraph, ScanSegment.NormalWeight);
            }
        }
        private void ConnectFreePointToLateralEdge(FreePoint freePoint, Directions lateralDir) {
            // Turn on pivot vertex to either side to find the next edge to connect to.  If the freepoint is
            // overlapped (inside an obstacle), just find the closest ScanSegment outside the obstacle and 
            // start extending from there; otherwise, we can have the FreePoint calculate its max visibility.
            var end = freePoint.IsOverlapped ? this.InBoundsGraphBoxIntersect(freePoint.Point, lateralDir)
                                             : freePoint.MaxVisibilityInDirectionForNonOverlappedFreePoint(lateralDir, this.TransUtil);
            var lateralEdge = this.FindorCreateNearestPerpEdge(end, freePoint.Point, lateralDir, freePoint.InitialWeight);

            // There may be no VisibilityEdge between the current point and any adjoining obstacle in that direction.
            if (null != lateralEdge) {
                freePoint.AddEdgeToAdjacentEdge(TransUtil, lateralEdge, lateralDir, this.portSpliceLimitRectangle);
            }
        }