/// <summary>
 /// Starts a background operation to check for new Remote Settings and apply them.
 /// </summary>
 /// <returns>Remote settings from file</returns>
 public override Task <GroupedRemoteSettings> Start()
 {
     RequiresNotDisposed();
     startTask = Task.Run(async delegate
     {
         string settingsFileEventName = "VS/Core/RemoteSettings/GetSettingsFileContent";
         Dictionary <string, object> settingsFileEventProperties = new Dictionary <string, object>();
         using (Stream stream = await remoteFileReader.Value.ReadFileAsync())
         {
             if (stream != null)
             {
                 settingsFileEventProperties["VS.Core.RemoteSettings.GetContentsSucceeded"] = true;
                 remoteSettingsTelemetry.PostEvent(settingsFileEventName, settingsFileEventProperties);
                 string name = "VS/Core/RemoteSettings/ParseSettings";
                 Dictionary <string, object> dictionary = new Dictionary <string, object>();
                 VersionedDeserializedRemoteSettings versionedDeserializedRemoteSettings = remoteSettingsParser.TryParseVersionedStream(stream);
                 if (!versionedDeserializedRemoteSettings.Successful)
                 {
                     logger.LogError("Error deserializing RemoteControl file: " + versionedDeserializedRemoteSettings.Error);
                     dictionary["VS.Core.RemoteSettings.ErrorMessage"] = versionedDeserializedRemoteSettings.Error;
                     remoteSettingsTelemetry.PostEvent(name, dictionary);
                     ValidateStoredRemoteSettings();
                     return(null);
                 }
                 logger.LogVerbose("Got " + Name + " settings of version " + versionedDeserializedRemoteSettings.FileVersion + " with ChangesetId " + versionedDeserializedRemoteSettings.ChangesetId);
                 dictionary["VS.Core.RemoteSettings.SettingsFileVersion"]   = versionedDeserializedRemoteSettings.FileVersion;
                 dictionary["VS.Core.RemoteSettings.SettingsFileChangeSet"] = versionedDeserializedRemoteSettings.ChangesetId;
                 remoteSettingsTelemetry.PostEvent(name, dictionary);
                 ProcessRemoteSettingsFile(versionedDeserializedRemoteSettings);
                 return(new GroupedRemoteSettings(versionedDeserializedRemoteSettings, Name));
             }
             if (startedDisposing == 0)
             {
                 settingsFileEventProperties["VS.Core.RemoteSettings.GetContentsSucceeded"] = false;
                 remoteSettingsTelemetry.PostEvent(settingsFileEventName, settingsFileEventProperties);
                 ValidateStoredRemoteSettings();
             }
         }
         return(null);
     });
     return(startTask);
 }
        private async Task <GroupedRemoteSettings> ProcessRemoteSettingsFromTargetedNotificationsAsync()
        {
            IEnumerable <LoggingContext <ActionWrapper <JObject> > > source = await GetActionsInternalAsync <JObject>("VS\\Core\\RemoteSettings", false).ConfigureAwait(false);

            if (source.Any())
            {
                List <GroupedRemoteSettings> list = new List <GroupedRemoteSettings>();
                List <Tuple <ActionWrapper <JObject>, DeserializedRemoteSettings> > list2 = new List <Tuple <ActionWrapper <JObject>, DeserializedRemoteSettings> >();
                foreach (LoggingContext <ActionWrapper <JObject> > item in source.OrderBy((LoggingContext <ActionWrapper <JObject> > x) => x.Value.Precedence))
                {
                    DeserializedRemoteSettings deserializedRemoteSettings = remoteSettingsParser.TryParseFromJObject(item.Value.Action, string.IsNullOrEmpty(item.Value.FlightName) ? null : ("Flight." + item.Value.FlightName));
                    if (deserializedRemoteSettings.Successful)
                    {
                        list.Add(new GroupedRemoteSettings(deserializedRemoteSettings, Name + "-" + item.Context));
                    }
                    else
                    {
                        logger.LogError("Error deserializing TN rule " + item.Context + ": " + deserializedRemoteSettings.Error);
                        list2.Add(Tuple.Create(item.Value, deserializedRemoteSettings));
                    }
                }
                if (list2.Any())
                {
                    string name = "VS/Core/RemoteSettings/TargetedParseSettings";
                    Dictionary <string, object> dictionary = new Dictionary <string, object>();
                    dictionary["VS.Core.RemoteSettings.TargetedRuleIds"] = string.Join(",", list2.Select((Tuple <ActionWrapper <JObject>, DeserializedRemoteSettings> x) => x.Item1.RuleId));
                    dictionary["VS.Core.RemoteSettings.TargetedErrors"]  = string.Join(",", list2.Select((Tuple <ActionWrapper <JObject>, DeserializedRemoteSettings> x) => x.Item2.Error));
                    remoteSettingsTelemetry.PostEvent(name, dictionary);
                }
                if (list.Any())
                {
                    GroupedRemoteSettings groupedRemoteSettings = list.Aggregate(delegate(GroupedRemoteSettings a, GroupedRemoteSettings b)
                    {
                        a.Merge(b, logger);
                        return(a);
                    });
                    liveStorageHandler.SaveSettings(groupedRemoteSettings);
                    Interlocked.Exchange(ref currentStorageHandler, liveStorageHandler);
                    cacheableStorageHandler.DeleteAllSettings();
                    cacheableStorageHandler.SaveSettings(groupedRemoteSettings);
                    return(groupedRemoteSettings);
                }
            }
            else
            {
                Interlocked.Exchange(ref currentStorageHandler, liveStorageHandler);
                cacheableStorageHandler.DeleteAllSettings();
            }
            return(null);
        }