protected Result CheckService(IHService service)
        {
            if (service == null)
            {
                return(Result.SingleFatal(Fatals.KeepAliveServicePassedNullService, ServiceName));
            }

            var serviceId = service.ServiceName;
            ServiceStatusInformation serviceInfo;

            if (!(ServiceStatuses.ContainsKey(serviceId)) || (serviceInfo = ServiceStatuses[serviceId]) == null)
            {
                return(Result.SingleFatal(Fatals.KeepAliveServiceMissingService, service, ServiceName));
            }

            StatusTypes currentStatus;

            // Nothing to do, if the service isn't failed.
            if ((currentStatus = serviceInfo.CurrentStatus) != StatusTypes.Failed)
            {
                return(Result.Success);
            }

            // Status is failed.
            Result   revive;
            bool     shouldRevive;
            TimeSpan?secondsToWait;

            if (!(revive = CheckIfShouldRevive(serviceInfo, out shouldRevive, out secondsToWait)) || !shouldRevive)
            {
                return(revive);
            }

            // Status is failed and should be revived.
            if (!(revive += TriggerRevivingService(service)))
            {
                return(revive);
            }

            // Setting reason information about start.
            var reason = Result.SingleInfo(ServiceReasons.KeepAliveStartup, Debugs.StartedByKeepAliveMonitor, serviceInfo.FailedAttempts + 1);

            if (!(Result)(serviceInfo.LastResult = service.Start(reason)))
            {
                // Failed to revive.
                ++serviceInfo.FailedAttempts;
                serviceInfo.LastAttempt      = DateTime.Now;
                serviceInfo.CurrentWaitTicks = secondsToWait == null ? (long?)null : secondsToWait.Value.Ticks;
                return(revive + TriggerReviveFailed(service));
            }

            // Service revived.
            serviceInfo.CurrentStatus  = service.Status;
            serviceInfo.PriorStatus    = currentStatus;
            serviceInfo.FailedAttempts = 0;
            serviceInfo.LastAttempt    = null;

            ++serviceInfo.Revivals;
            return(TriggerServiceRevived(service));
        }
        protected Result UpdateServiceStatus(IHService service)
        {
            if (service == null)
            {
                return(Result.SingleFatal(Fatals.KeepAliveServicePassedNullService, ServiceName));
            }

            // Add any services that are missing.
            var serviceId = service.ServiceName;

            if (!(ServiceStatuses.ContainsKey(serviceId)))
            {
                ServiceStatuses.Add(serviceId, new ServiceStatusInformation(serviceId));
            }

            // Get reference to monitored service state.
            var statusInfo = ServiceStatuses[serviceId];

            StatusTypes currentStatus;
            var         priorStatus = statusInfo.CurrentStatus;

            // If the service is not currently failed, clear failed attempts.
            if ((currentStatus = service.Status) != StatusTypes.Failed)
            {
                statusInfo.FailedAttempts = 0;
            }

            // If the current status is not the prior status, then it was updated externally.
            if (currentStatus != priorStatus)
            {
                statusInfo.LastResult = service.LastTransitionReason;
            }

            statusInfo.CurrentStatus = currentStatus;
            statusInfo.PriorStatus   = priorStatus;
            return(Result.Success);
        }