private ZoneInfoPathNode(
            IZoneInfo zoneInfo,
            Func <IZoneInfoPathNode, QueryResult <IZoneInfo, RelativeZoneInfoQuery>, bool> canBeJoinedFunc,
            Func <IZoneInfo, int?> getDestinationHashCode,
            IZoneInfoPathNode previousPathNode,
            IZoneInfoPathNode originParentPathNode,
            int distance,
            ZoneInfoDistanceTracker distanceTracker)
        {
            ZoneInfo         = zoneInfo;
            PreviousPathNode = previousPathNode;

            _originParentPathNode = originParentPathNode ?? this;

            DestinationHashCode = getDestinationHashCode(zoneInfo);

            Distance = distance;

            _childPathsLazy = new Lazy <List <IZoneInfoPathNode> >(() =>
                                                                   !distanceTracker.IsPreviouslyNotSeenOrSeenAtLargerDistance(ZoneInfo, distance, previousPathNode)
                ? Enumerable.Empty <IZoneInfoPathNode>().ToList()
                : ZoneInfo
                                                                   .GetNorthEastSouthWest()
                                                                   .Where(x => x.HasMatch)
                                                                   .Where(x => x.MatchingObject != PreviousPathNode?.ZoneInfo)
                                                                   .Where(x => distanceTracker.DoesNotExceedMaximumDistanceForAllCriteria(ZoneInfo, distance))
                                                                   .Where(x => canBeJoinedFunc(this, x))
                                                                   .Select(x => new ZoneInfoPathNode(
                                                                               zoneInfo: x.MatchingObject,
                                                                               canBeJoinedFunc: canBeJoinedFunc,
                                                                               getDestinationHashCode: getDestinationHashCode,
                                                                               previousPathNode: this,
                                                                               originParentPathNode: _originParentPathNode,
                                                                               distance: Distance + x.MatchingObject.GetDistanceScoreBasedOnConsumption(),
                                                                               distanceTracker: distanceTracker
                                                                               ))
                                                                   .ToList <IZoneInfoPathNode>());
        }
 public ZoneInfoPathNode(IZoneInfo zoneInfo, Func <IZoneInfoPathNode, QueryResult <IZoneInfo, RelativeZoneInfoQuery>, bool> canBeJoinedFunc, Func <IZoneInfo, int?> getDestinationHashCode, ZoneInfoDistanceTracker distanceTracker)
     : this(
         zoneInfo : zoneInfo,
         canBeJoinedFunc : canBeJoinedFunc,
         getDestinationHashCode : getDestinationHashCode,
         previousPathNode : null,
         originParentPathNode : null,
         distance : 0,
         distanceTracker : distanceTracker)
 {
 }