protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            if (!_autoDeployConfiguration.Enabled)
            {
                return;
            }

            await Task.Delay(TimeSpan.FromSeconds(_autoDeployConfiguration.StartupDelayInSeconds), stoppingToken);

            while (!stoppingToken.IsCancellationRequested)
            {
                ImmutableArray <DeploymentTarget> deploymentTargets;
                using (var targetsTokenSource =
                           new CancellationTokenSource(TimeSpan.FromSeconds(_autoDeployConfiguration.DefaultTimeoutInSeconds)))
                {
                    using (CancellationTokenSource linked =
                               CancellationTokenSource.CreateLinkedTokenSource(stoppingToken,
                                                                               targetsTokenSource.Token))
                    {
                        deploymentTargets = (await _deploymentTargetReadService.GetDeploymentTargetsAsync(linked.Token))
                                            .Where(target => target.Enabled && target.AutoDeployEnabled)
                                            .ToImmutableArray();
                    }
                }

                if (deploymentTargets.IsDefaultOrEmpty)
                {
                    _logger.Verbose("Found no deployment targets with auto deployment enabled, waiting {DelayInSeconds} seconds", _autoDeployConfiguration.EmptyTargetsDelayInSeconds);
                    await Task.Delay(TimeSpan.FromSeconds(_autoDeployConfiguration.EmptyTargetsDelayInSeconds), stoppingToken);

                    continue;
                }

                ImmutableArray <DeploymentTarget> targetsWithUrl = deploymentTargets.Where(target => target.Url.HasValue()).ToImmutableArray();

                if (targetsWithUrl.IsDefaultOrEmpty)
                {
                    _logger.Verbose("Found no deployment targets with auto deployment enabled and URL defined, waiting {DelayInSeconds} seconds", _autoDeployConfiguration.EmptyTargetsDelayInSeconds);
                    await Task.Delay(TimeSpan.FromSeconds(_autoDeployConfiguration.EmptyTargetsDelayInSeconds), stoppingToken);

                    continue;
                }

                AppVersion[] appVersions;
                using (var cancellationTokenSource =
                           new CancellationTokenSource(
                               TimeSpan.FromSeconds(_autoDeployConfiguration.MetadataTimeoutInSeconds)))
                {
                    using (CancellationTokenSource linkedCancellationTokenSource =
                               CancellationTokenSource.CreateLinkedTokenSource(cancellationTokenSource.Token, stoppingToken))
                    {
                        CancellationToken cancellationToken = linkedCancellationTokenSource.Token;

                        IEnumerable <Task <AppVersion> > tasks = targetsWithUrl.Select(target =>
                                                                                       _monitoringService.GetAppMetadataAsync(target, cancellationToken));

                        appVersions = await Task.WhenAll(tasks);
                    }
                }

                foreach (DeploymentTarget deploymentTarget in targetsWithUrl)
                {
                    AppVersion appVersion = appVersions.SingleOrDefault(v =>
                                                                        v.Target.Id.Equals(deploymentTarget.Id, StringComparison.OrdinalIgnoreCase));

                    if (appVersion?.SemanticVersion is null || appVersion.PackageId.IsNullOrWhiteSpace())
                    {
                        continue;
                    }

                    ImmutableHashSet <PackageVersion> packageVersions;
                    using (var packageVersionCancellationTokenSource =
                               new CancellationTokenSource(TimeSpan.FromSeconds(_autoDeployConfiguration.DefaultTimeoutInSeconds)))
                    {
                        using (CancellationTokenSource linked =
                                   CancellationTokenSource.CreateLinkedTokenSource(stoppingToken,
                                                                                   packageVersionCancellationTokenSource.Token))
                        {
                            packageVersions =
                                (await _packageService.GetPackageVersionsAsync(deploymentTarget.PackageId, cancellationToken: linked.Token, logger: _logger)).ToImmutableHashSet();
                        }
                    }

                    if (packageVersions.IsEmpty)
                    {
                        continue;
                    }

                    ImmutableHashSet <PackageVersion> filteredPackages = !deploymentTarget.AllowPreRelease ? packageVersions.Where(p => !p.Version.IsPrerelease).ToImmutableHashSet() : packageVersions;

                    if (filteredPackages.IsEmpty)
                    {
                        continue;
                    }

                    ImmutableHashSet <PackageVersion> newerPackages = filteredPackages
                                                                      .Where(package =>
                                                                             package.PackageId.Equals(appVersion.PackageId, StringComparison.OrdinalIgnoreCase) &&
                                                                             package.Version > appVersion.SemanticVersion)
                                                                      .ToImmutableHashSet();

                    PackageVersion packageToDeploy = newerPackages
                                                     .OrderByDescending(package => package.Version)
                                                     .FirstOrDefault();

                    if (packageToDeploy != null)
                    {
                        var task = new DeploymentTask(packageToDeploy, deploymentTarget.Id, Guid.NewGuid());

                        _logger.Information("Auto-deploying package {Package} to target {TargetId}",
                                            packageToDeploy,
                                            deploymentTarget.Id);

                        _deploymentWorker.Enqueue(task);
                    }
                }

                await Task.Delay(TimeSpan.FromSeconds(_autoDeployConfiguration.AfterDeployDelayInSeconds), stoppingToken);
            }
        }