public void ValidateTermination(BadTerminationHandler badTerminationHandler)
        {
            // Don't worry if the last object in the flow is a "TODO",
            // even if there are other loose ends in other places
            if (lastParsedSignificantObject is AuthorWarning)
            {
                return;
            }

            // By now, any sub-weaves will have passed loose ends up to the root weave (this).
            // So there are 2 possible situations:
            //  - There are loose ends from somewhere in the flow.
            //    These aren't necessarily "real" loose ends - they're weave points
            //    that don't connect to any lower weave points, so we just
            //    have to check that they terminate properly.
            //  - This weave is just a list of content with no actual weave points,
            //    so we just need to check that the list of content terminates.

            bool hasLooseEnds = looseEnds != null && looseEnds.Count > 0;

            if (hasLooseEnds)
            {
                foreach (var looseEnd in looseEnds)
                {
                    var looseEndFlow = ContentThatFollowsWeavePoint(looseEnd);
                    ValidateFlowOfObjectsTerminates(looseEndFlow, (Parsed.Object)looseEnd, badTerminationHandler);
                }
            }

            // No loose ends... is there any inner weaving at all?
            // If not, make sure the single content stream is terminated correctly
            else
            {
                // If there's any actual weaving, assume that content is
                // terminated correctly since we would've had a loose end otherwise
                foreach (var obj in content)
                {
                    if (obj is IWeavePoint)
                    {
                        return;
                    }
                }

                // Straight linear flow? Check it terminates
                ValidateFlowOfObjectsTerminates(content, this, badTerminationHandler);
            }
        }
        void ValidateFlowOfObjectsTerminates(IEnumerable <Parsed.Object> objFlow, Parsed.Object defaultObj, BadTerminationHandler badTerminationHandler)
        {
            bool terminated = false;

            Parsed.Object terminatingObj = defaultObj;
            foreach (var flowObj in objFlow)
            {
                var divert = flowObj.Find <Divert> (d => !d.isThread && !d.isTunnel && !d.isFunctionCall && !(d.parent is DivertTarget));
                if (divert != null)
                {
                    terminated = true;
                }

                if (flowObj.Find <TunnelOnwards> () != null)
                {
                    terminated = true;
                    break;
                }

                terminatingObj = flowObj;
            }


            if (!terminated)
            {
                // Author has left a note to self here - clearly we don't need
                // to leave them with another warning since they know what they're doing.
                if (terminatingObj is AuthorWarning)
                {
                    return;
                }

                badTerminationHandler(terminatingObj);
            }
        }