public async Task<ServerCredentials> GetServerCredentials()
        {
            if (_servers == null)
            {
                await _asyncLock.WaitAsync().ConfigureAwait(false);

                try
                {
                    if (_servers == null)
                    {
                        try
                        {
                            _servers = _json.DeserializeFromFile<ServerCredentials>(Path);
                        }
                        catch (IOException)
                        {
                            _servers = new ServerCredentials();
                        }
                        catch (Exception ex)
                        {
                            _logger.ErrorException("Error reading saved credentials", ex);
                            _servers = new ServerCredentials();
                        }
                    }
                }
                finally
                {
                    _asyncLock.Release();
                }
            }
            return _servers;
        }
        private async Task<bool> SaveServerCreds(ServerCredentials configuration)
        {
            var tsc = new TaskCompletionSource<bool>();
            Deployment.Current.Dispatcher.BeginInvoke(async () =>
            {
                await Lock.WaitAsync();

                try
                {
                    var json = JsonConvert.SerializeObject(configuration);

                    await _storageService.WriteAllTextAsync(Constants.Settings.ServerCredentialSettings, json).ConfigureAwait(false);
                }
                finally
                {
                    Lock.Release();
                }

                Debug.WriteLine("SaveCreds, Server count: " + (configuration != null && configuration.Servers != null ? configuration.Servers.Count : 0));

                tsc.SetResult(true);
            });

            return await tsc.Task;
        }
        public async Task SaveServerCredentials(ServerCredentials configuration)
        {
            var path = Path;
            Directory.CreateDirectory(System.IO.Path.GetDirectoryName(path));

            await _asyncLock.WaitAsync().ConfigureAwait(false);

            try
            {
                _json.SerializeToFile(configuration, path);
            }
            finally
            {
                _asyncLock.Release();
            }
        }
 public async Task SaveServerCredentials(ServerCredentials configuration)
 {
     await SaveServerCreds(configuration);
 }
        private async Task EnsureConnectUser(ServerCredentials credentials, CancellationToken cancellationToken)
        {
            if (ConnectUser != null && string.Equals(ConnectUser.Id, credentials.ConnectUserId, StringComparison.Ordinal))
            {
                return;
            }

            ConnectUser = null;

            if (!string.IsNullOrWhiteSpace(credentials.ConnectUserId) && !string.IsNullOrWhiteSpace(credentials.ConnectAccessToken))
            {
                try
                {
                    ConnectUser = await _connectService.GetConnectUser(new ConnectUserQuery
                    {
                        Id = credentials.ConnectUserId

                    }, credentials.ConnectAccessToken, cancellationToken).ConfigureAwait(false);

                    OnConnectUserSignIn(ConnectUser);
                }
                catch
                {
                    // Already logged at lower levels
                }
            }
        }
        private async Task AddAuthenticationInfoFromConnect(ServerInfo server,
            ConnectionMode connectionMode,
            ServerCredentials credentials,
            CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(credentials.ConnectUserId))
            {
                throw new ArgumentException("server");
            }

            if (string.IsNullOrWhiteSpace(server.ExchangeToken))
            {
                throw new ArgumentException("server");
            }

            _logger.Debug("Adding authentication info from Connect");

            var url = server.GetAddress(connectionMode);

            url += "/emby/Connect/Exchange?format=json&ConnectUserId=" + credentials.ConnectUserId;

            var headers = new HttpHeaders();
            headers.SetAccessToken(server.ExchangeToken);

            try
            {
                using (var stream = await _httpClient.SendAsync(new HttpRequest
                {
                    CancellationToken = cancellationToken,
                    Method = "GET",
                    RequestHeaders = headers,
                    Url = url

                }).ConfigureAwait(false))
                {
                    var auth = JsonSerializer.DeserializeFromStream<ConnectAuthenticationExchangeResult>(stream);

                    server.UserId = auth.LocalUserId;
                    server.AccessToken = auth.AccessToken;
                }
            }
            catch (OperationCanceledException)
            {
                throw;
            }
            catch (Exception ex)
            {
                // Already logged at a lower level

                server.UserId = null;
                server.AccessToken = null;
            }
        }
        private async Task<List<Tuple<ServerInfo, ServerUserInfo, UserDto>>> GetOfflineUsers(ServerCredentials credentials, bool? isSignedIn)
        {
            var list = new List<Tuple<ServerInfo, ServerUserInfo, UserDto>>();

            foreach (var server in credentials.Servers)
            {
                foreach (var user in server.Users)
                {
                    if (isSignedIn.HasValue)
                    {
                        if (user.IsSignedInOffline != isSignedIn.Value)
                        {
                            continue;
                        }
                    }

                    var userRecord = await _localAssetManager.GetUser(user.Id).ConfigureAwait(false);

                    if (userRecord != null)
                    {
                        list.Add(new Tuple<ServerInfo, ServerUserInfo, UserDto>(server, user, userRecord));
                    }
                }
            }
            return list;
        }