/// <summary>
        /// Check that the designated route is ready and if so, start the loc.
        /// </summary>
        /// <returns>The timespan before this method wants to be called again.</returns>
        private TimeSpan OnWaitingForRouteReady(ILocState loc)
        {
            // Check state
            if (loc.AutomaticState.Actual != AutoLocState.WaitingForAssignedRouteReady)
            {
                log.Warn("Cannot start running loc {0} in {1} state.", loc, loc.AutomaticState);
                return(TimeSpan.MaxValue);
            }

            // Log state
            log.Trace("OnWaitingForRouteReady{0}", loc);

            // If the route ready?
            var route = loc.CurrentRoute.Actual;

            if (!route.Route.IsPrepared)
            {
                // Make sure we stop
                loc.Speed.Requested = 0;
                // We're not ready yet
                return(TimeSpan.FromMinutes(1));
            }

            // Set to max speed
            loc.Speed.Requested = loc.GetMaximumSpeed(route.Route);

            // Update state
            loc.AutomaticState.Actual = AutoLocState.Running;

            // Already look for a next route
            ChooseNextRoute(loc);

            return(TimeSpan.MaxValue);
        }
        /// <summary>
        /// Loc is entering its destination.
        /// </summary>
        /// <returns>The timespan before this method wants to be called again.</returns>
        private TimeSpan OnEnteringDestination(ILocState loc)
        {
            // Check state
            var state = loc.AutomaticState.Actual;

            if (state != AutoLocState.EnteringDestination)
            {
                // Wrong state, no need to do anything
                return(TimeSpan.MaxValue);
            }

            // Log state
            log.Trace("OnEnteringDestination {0}", loc);

            // The loc can continue (if a free route is found)
            ChooseNextRoute(loc);
            if (loc.HasNextRoute() && loc.NextRoute.Actual.IsPrepared)
            {
                // We have a next route, so we can continue our speed
                loc.Speed.Requested = loc.GetMaximumSpeed(loc.NextRoute.Actual);
            }

            return(TimeSpan.MaxValue);
        }
        /// <summary>
        /// Loc has triggered an enter sensor.
        /// </summary>
        /// <returns>The timespan before this method wants to be called again.</returns>
        private TimeSpan OnEnterSensorActivated(ILocState loc)
        {
            // Check state
            var state = loc.AutomaticState.Actual;

            if (state != AutoLocState.EnterSensorActivated)
            {
                // Wrong state, no need to do anything
                return(TimeSpan.MaxValue);
            }

            // Log state
            log.Trace("OnEnterSensorActivated {0}", loc);

            // Notify route selector
            loc.RouteSelector.BlockEntered(loc, loc.CurrentRoute.Actual.Route.To);

            // Should we wait in the destination block?
            if (loc.WaitAfterCurrentRoute.Actual)
            {
                // The loc should wait in the target block,
                // so slow down the loc.
                if (loc.IsLastEventBehaviorSpeedDefault)
                {
                    loc.Speed.Requested = loc.GetMediumSpeed(loc.CurrentRoute.Actual.Route);
                }
            }
            else
            {
                // The loc can continue (if a free route is found)
                ChooseNextRoute(loc);
                var nextRoute = loc.NextRoute.Actual;
                if ((nextRoute != null) && nextRoute.IsPrepared)
                {
                    // We have a next route, so we can continue our speed
                    if (loc.IsLastEventBehaviorSpeedDefault)
                    {
                        loc.Speed.Requested = loc.GetMaximumSpeed(nextRoute);
                    }
                }
                else if (nextRoute != null)
                {
                    // No next route not yet ready, slow down
                    if (loc.IsLastEventBehaviorSpeedDefault)
                    {
                        loc.Speed.Requested = loc.GetMediumSpeed(nextRoute);
                    }
                }
                else
                {
                    // No route available at this time, or next route not yet ready, slow down
                    if (loc.IsLastEventBehaviorSpeedDefault)
                    {
                        loc.Speed.Requested = loc.GetMediumSpeed(loc.CurrentRoute.Actual.Route);
                    }
                }
            }

            // Update state
            loc.AutomaticState.Actual = AutoLocState.EnteringDestination;

            return(TimeSpan.FromMinutes(1));
        }