/// <summary>
        /// Checks if the background filters are up-to-date or not. To update the filters,
        /// unregister and register background task again
        /// (call BackgroundTaskManager.UpdateBackgroundTaskAsync()).
        /// </summary>
        /// <returns>True, if an update is required. False otherwise.</returns>
        public static bool CheckIfBackgroundFilterUpdateIsRequired()
        {
            bool isRequired = SdkData.BackgroundFilterUpdateRequired;

            if (!isRequired && !string.IsNullOrEmpty(SdkData.LayoutBeaconId1Hash))
            {
                string upToDateHash = LayoutManager.CreateHashOfBeaconId1SInLayout(ServiceManager.LayoutManager.Layout);

                if (!string.IsNullOrEmpty(upToDateHash) &&
                    !SdkData.LayoutBeaconId1Hash.Equals(upToDateHash))
                {
                    SdkData.LayoutBeaconId1Hash            = upToDateHash;
                    SdkData.BackgroundFilterUpdateRequired = true;
                    isRequired = true;
                }
            }

            return(isRequired);
        }
        /// <summary>
        /// Registers the BLE advertisement watcher background task.
        /// </summary>
        /// <param name="configuration">Configuration for the new registration.</param>
        /// <returns>The registration result.</returns>
        private async Task <BackgroundTaskRegistrationResult> RegisterAdvertisementWatcherBackgroundTaskAsync(SdkConfiguration configuration)
        {
            BackgroundTaskRegistrationResult result = new BackgroundTaskRegistrationResult()
            {
                Success   = false,
                Exception = null
            };

            if (BackgroundTaskRegistered(AdvertisementClass))
            {
                // Already registered
                Logger.Debug("BackgroundTaskManager.RegisterAdvertisementWatcherBackgroundTask(): Already registered");
                result.Success = true;
            }
            else
            {
                BackgroundTaskBuilder backgroundTaskBuilder = new BackgroundTaskBuilder();

                backgroundTaskBuilder.Name           = AdvertisementClass + Guid.NewGuid();
                backgroundTaskBuilder.TaskEntryPoint = configuration.BackgroundAdvertisementClassName;

                BluetoothLEAdvertisementWatcherTrigger advertisementWatcherTrigger = new BluetoothLEAdvertisementWatcherTrigger();

                // This filter includes all Sensorberg beacons
                var pattern = BeaconFactory.UuidToAdvertisementBytePattern(configuration.BackgroundBeaconUuidSpace, configuration.ManufacturerId, configuration.BeaconCode);
                advertisementWatcherTrigger.AdvertisementFilter.BytePatterns.Add(pattern);

                ILayoutManager layoutManager = ServiceManager.LayoutManager;

                AppSettings = await ServiceManager.SettingsManager.GetSettings();

                // Using MaxSamplingInterval as SamplingInterval ensures that we get an event only
                // when entering or exiting from the range of the beacon
                advertisementWatcherTrigger.SignalStrengthFilter.SamplingInterval = advertisementWatcherTrigger.MaxSamplingInterval;
                if (AppSettings.RssiEnterThreshold != null && AppSettings.RssiEnterThreshold.Value >= -128 &&
                    AppSettings.RssiEnterThreshold.Value <= 127)
                {
                    advertisementWatcherTrigger.SignalStrengthFilter.InRangeThresholdInDBm = AppSettings.RssiEnterThreshold;
                }
                else
                {
                    advertisementWatcherTrigger.SignalStrengthFilter.InRangeThresholdInDBm = Constants.DefaultBackgroundScannerEnterThreshold;
                }

                advertisementWatcherTrigger.SignalStrengthFilter.OutOfRangeThresholdInDBm = SignalStrengthFilterOutOfRangeThresholdInDBm;
                advertisementWatcherTrigger.SignalStrengthFilter.OutOfRangeTimeout        = TimeSpan.FromMilliseconds(AppSettings.BeaconExitTimeout);

                IBackgroundTrigger trigger = advertisementWatcherTrigger;

                backgroundTaskBuilder.SetTrigger(trigger);

                try
                {
                    BackgroundTaskRegistration backgroundTaskRegistration = backgroundTaskBuilder.Register();
                    backgroundTaskRegistration.Completed += OnAdvertisementWatcherBackgroundTaskCompleted;
                    backgroundTaskRegistration.Progress  += OnAdvertisementWatcherBackgroundTaskProgress;

                    result.Success = true;
                }
                catch (Exception ex)
                {
                    result.Exception = ex;
                    Logger.Error("BackgroundTaskManager.RegisterAdvertisementWatcherBackgroundTask(): Failed to register: ", ex);
                    if (ex.Message.Contains("0x800710DF)"))
                    {
                        await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() => await new MessageDialog("Activate Bluetooth for the app").ShowAsync());
                    }
                }

                if (result.Success)
                {
                    // Check if there was a pending filter update
                    if (SdkData.BackgroundFilterUpdateRequired)
                    {
                        string upToDateHash = LayoutManager.CreateHashOfBeaconId1SInLayout(layoutManager.Layout);

                        if (!string.IsNullOrEmpty(upToDateHash) && SdkData.LayoutBeaconId1Hash.Equals(upToDateHash))
                        {
                            // Background filter updated successfully
                            SdkData.BackgroundFilterUpdateRequired = false;

                            BackgroundFiltersUpdated?.Invoke(this, null);
                        }
                    }
                    else if (string.IsNullOrEmpty(SdkData.LayoutBeaconId1Hash))
                    {
                        // This is the first time the background task is registered with valid layout =>
                        // set the hash
                        string upToDateHash = LayoutManager.CreateHashOfBeaconId1SInLayout(layoutManager.Layout);

                        if (!string.IsNullOrEmpty(upToDateHash))
                        {
                            SdkData.LayoutBeaconId1Hash = upToDateHash;
                        }
                    }
                }
            }

            //Load last events from background
            await LoadBackgroundActions();

            return(result);
        }