public Result <RouteNetworkInterest> UpdateRouteNetworkElements(CommandContext cmdContext, RouteNetworkInterest walkOfInterest, InterestsProjection interestProjection, WalkValidator walkValidator)
        {
            if (walkOfInterest.Kind != RouteNetworkInterestKindEnum.WalkOfInterest)
            {
                return(Result.Fail(new RegisterWalkOfInterestError(RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_KIND_MUST_BE_WALK_OF_INTEREST, "Interest kind must be WalkOfInterest")));
            }

            if (walkOfInterest.Id == Guid.Empty)
            {
                return(Result.Fail(new RegisterWalkOfInterestError(RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_ID_CANNOT_BE_EMPTY, $"{RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_ID_CANNOT_BE_EMPTY}: Interest id cannot be empty")));
            }

            if (interestProjection.GetInterest(walkOfInterest.Id).IsFailed)
            {
                return(Result.Fail(new RegisterWalkOfInterestError(RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_DONT_EXISTS, $"{RegisterWalkOfInterestErrorCodes.INVALID_INTEREST_DONT_EXISTS}: An interest with id: {walkOfInterest.Id} could not be found")));
            }

            var walkValidationResult = walkValidator.ValidateWalk(walkOfInterest.RouteNetworkElementRefs);

            if (walkValidationResult.IsFailed)
            {
                return(Result.Fail(walkValidationResult.Errors.First()));
            }

            if (_interest == null)
            {
                throw new ApplicationException("Unexpected aggreagate state. Interest state must be non-null when this event is processed.");
            }

            // Reverse walk if one of its ends are opposite of existing walk ends
            var existingWalk = new ValidatedRouteNetworkWalk(_interest.RouteNetworkElementRefs);
            var newWalk      = new ValidatedRouteNetworkWalk(walkValidationResult.Value);

            if (newWalk.FromNodeId == existingWalk.ToNodeId || newWalk.ToNodeId == existingWalk.FromNodeId)
            {
                newWalk = newWalk.Reverse();
            }

            RaiseEvent(
                new WalkOfInterestRouteNetworkElementsModified(this.Id, newWalk.RouteNetworkElementRefs)
            {
                CorrelationId = cmdContext.CorrelationId,
                IncitingCmdId = cmdContext.CmdId,
                UserName      = cmdContext.UserContext?.UserName,
                WorkTaskId    = cmdContext.UserContext?.WorkTaskId
            }
                );

            if (_interest == null)
            {
                throw new ApplicationException("Unexpected aggreagate state. Interest must be non-null after WalkOfInterestRegistered has been raised.");
            }

            return(Result.Ok <RouteNetworkInterest>(_interest));
        }
        private RouteNetworkElementIdList MergeWalks(ValidatedRouteNetworkWalk firstSpanEquipmentWalk, ValidatedRouteNetworkWalk secondSpanEquipmentWalk)
        {
            var result = new RouteNetworkElementIdList();

            // first span equipment -> second span equipment
            if (firstSpanEquipmentWalk.ToNodeId == secondSpanEquipmentWalk.FromNodeId)
            {
                result.AddRange(firstSpanEquipmentWalk.SegmentIds);
                result.AddRange(secondSpanEquipmentWalk.SegmentIds);
            }
            // first span equipment -> second span equipment (reversed)
            else if (firstSpanEquipmentWalk.ToNodeId == secondSpanEquipmentWalk.ToNodeId)
            {
                secondSpanEquipmentWalk = secondSpanEquipmentWalk.Reverse();

                result.AddRange(firstSpanEquipmentWalk.SegmentIds);
                result.AddRange(secondSpanEquipmentWalk.SegmentIds);
            }
            // second span equipment -> first span equipment
            else if (firstSpanEquipmentWalk.FromNodeId == secondSpanEquipmentWalk.ToNodeId)
            {
                result.AddRange(secondSpanEquipmentWalk.SegmentIds);
                result.AddRange(firstSpanEquipmentWalk.SegmentIds);
            }
            // second span equipment (reversed) -> first span equipment
            else if (firstSpanEquipmentWalk.FromNodeId == secondSpanEquipmentWalk.FromNodeId)
            {
                secondSpanEquipmentWalk = secondSpanEquipmentWalk.Reverse();

                result.AddRange(secondSpanEquipmentWalk.SegmentIds);
                result.AddRange(firstSpanEquipmentWalk.SegmentIds);
            }
            else
            {
                throw new ApplicationException("Merge Walk logic is broken");
            }

            return(result);
        }