/// <summary>
        /// For a client sync request, gathers applicable software updates that the client does not have yet
        /// </summary>
        /// <param name="installedNonLeaf">List of non leaf updates installed on the client</param>
        /// <param name="otherCached">List of other updates known to the client</param>
        /// <param name="response">The response  to append new updates to</param>
        /// <param name="updatesAdded">On return: true of updates were added to the response, false otherwise</param>
        private void AddMissingSoftwareUpdatesToSyncUpdatesResponse(List <Guid> installedNonLeaf, List <Guid> otherCached, SyncInfo response, out bool updatesAdded)
        {
            var allMissingApplicableUpdates = SoftwareLeafUpdateGuids
                                              .Except(installedNonLeaf)                                                        // Do not resend installed updates
                                              .Except(otherCached)                                                             // Do not resend other client known updates
                                              .Select(guid => IdToFullIdentityMap[guid])                                       // Map the GUID to a fully qualified identity
                                              .Select(id => MetadataSource.UpdatesIndex[id])                                   // Select the software update by identity
                                              .OfType <SoftwareUpdate>()
                                              .Where(u => !u.IsSuperseded && u.IsApplicable(installedNonLeaf) && !u.IsBundle); // Remove superseded, not applicable and bundles

            var unapprovedMissingUpdates = allMissingApplicableUpdates
                                           .Where(u => !ApprovedSoftwareUpdates.Contains(u.Identity) && (!u.IsBundled || !u.BundleParent.Any(i => ApprovedSoftwareUpdates.Contains(i))));

            if (unapprovedMissingUpdates.Count() > 0)
            {
                OnUnApprovedSoftwareUpdatesRequested?.Invoke(unapprovedMissingUpdates);
            }

            var missingApplicableUpdates = allMissingApplicableUpdates
                                           .Where(u => ApprovedSoftwareUpdates.Contains(u.Identity) || (u.IsBundled && u.BundleParent.Any(i => ApprovedSoftwareUpdates.Contains(i)))) // The update is approved or it's part of a bundle that is approved
                                           .Take(MaxUpdatesInResponse + 1)                                                                                                            // Only take the maximum number of updates allowed + 1 (to see if we truncated)
                                           .ToList();

            response.Truncated = missingApplicableUpdates.Count > MaxUpdatesInResponse;

            if (missingApplicableUpdates.Count > 0)
            {
                response.NewUpdates = CreateUpdateInfoListFromSoftwareUpdate(missingApplicableUpdates).ToArray();
                updatesAdded        = true;
            }
            else
            {
                updatesAdded = false;
            }
        }
        /// <summary>
        /// Handle driver sync requests
        /// </summary>
        /// <param name="parameters"></param>
        /// <returns></returns>
        private Task <SyncInfo> DoDriversSync(SyncUpdateParameters parameters)
        {
            // Get list of driver updates known to the client
            var cachedDrivers = GetUpdateIdentitiesFromClientIndexes(parameters.CachedDriverIDs);

            // Get list of installed non-leaf updates. Used to match pre-requisites for driver updates
            var installedNonLeafUpdatesGuids = GetInstalledNotLeafGuidsFromSyncParameters(parameters);

            // Initialize the response
            var syncResult = new SyncInfo()
            {
                NewCookie = new Cookie()
                {
                    Expiration = DateTime.Now.AddDays(5), EncryptedData = new byte[12]
                },
                DriverSyncNotNeeded = "false",
                Truncated           = false
            };

            List <Guid> computerHardwareIds = parameters.ComputerSpec.HardwareIDs != null?parameters.ComputerSpec.HardwareIDs.ToList() : new List <Guid>();

            List <UpdateInfo> driverUpdates = new List <UpdateInfo>();

            List <Update> unapprovedDriversMatched = new List <Update>();

            // Go through all client reported devices
            foreach (var device in parameters.SystemSpec)
            {
                // Combine the list hardware ids and compatible hwids; we will
                // match them in this order, from specific to less specific
                var hardwareIdsToMatch = new List <string>(device.HardwareIDs);
                if (device.CompatibleIDs != null)
                {
                    hardwareIdsToMatch.AddRange(device.CompatibleIDs);
                }

                // Get best match driver
                var driverMatchResult = MetadataSource.MatchDriver(hardwareIdsToMatch, computerHardwareIds, installedNonLeafUpdatesGuids);

                // If we have a match and the client does not have it, add it to the list
                if (driverMatchResult != null &&
                    !cachedDrivers.Contains(driverMatchResult.Driver.Identity) &&
                    !IsInstalledDriverBetterMatch(device.installedDriver, driverMatchResult, hardwareIdsToMatch, computerHardwareIds))
                {
                    if (ApprovedSoftwareUpdates.Contains(driverMatchResult.Driver.Identity))
                    {
                        // Get core XML fragment for driver update
                        var coreXml = GetCoreFragment(driverMatchResult.Driver.Identity);

                        driverUpdates.Add(new UpdateInfo()
                        {
                            Deployment = new Deployment()
                            {
                                Action               = DeploymentAction.Install,
                                ID                   = 25000,
                                AutoDownload         = "0",
                                AutoSelect           = "0",
                                SupersedenceBehavior = "0",
                                IsAssigned           = true,
                                LastChangeTime       = "2019-08-06"
                            },
                            ID           = IdToRevisionMap[driverMatchResult.Driver.Identity.ID],
                            IsLeaf       = true,
                            Xml          = coreXml,
                            IsShared     = false,
                            Verification = null
                        });
                    }
                    else
                    {
                        unapprovedDriversMatched.Add(driverMatchResult.Driver);
                    }
                }

                // Stop matching if we have max updates already
                if (driverUpdates.Count == MaxUpdatesInResponse)
                {
                    syncResult.Truncated = true;
                    break;
                }
            }

            if (unapprovedDriversMatched.Count > 0)
            {
                OnUnApprovedDriverUpdatesRequested?.Invoke(unapprovedDriversMatched);
            }

            syncResult.NewUpdates = driverUpdates.ToArray();

            return(Task.FromResult(syncResult));
        }