private void ProcessNewChatUserInfos(int chatId, Dictionary <int, ChatUserInfo> chatUserInfos)
        {
            if (chatUserInfos == null || !chatUserInfos.Any())
            {
                return;
            }

            lock (ChatUserInfosCache)
            {
                lock (_newChatUserInfosHandlers)
                {
                    foreach (var userInfo in chatUserInfos)
                    {
                        var id = new ChatUserId(userInfo.Key, chatId);
                        if (ChatUserInfosCache.ContainsKey(id))
                        {
                            ChatUserInfosCache[id] = userInfo.Value;
                        }
                        if (_newChatUserInfosHandlers.ContainsKey(id))
                        {
                            _newChatUserInfosHandlers[id]?.Invoke(this, userInfo.Value);
                        }
                    }
                }
            }
        }
        public async Task <ChatUserInfo> GetChatSpecificUserInfoAsync(int chatId, int userId)
        {
            var chatUserId = new ChatUserId(userId, chatId);

            lock (_lock)
                if (_poller != null)
                {
                    lock (_poller.ChatUserInfosCache)
                        if (_poller.ChatUserInfosCache.ContainsKey(chatUserId))
                        {
                            return(_poller.ChatUserInfosCache[chatUserId]);
                        }
                }

            var response = await _client.GetAsync($"chats/{chatId}/users/{userId}/info").ConfigureAwait(false);

            if (!response.IsSuccessStatusCode)
            {
                return(null);
            }

            var ret = await response.Content.ReadAsAsync <ChatUserInfo>();

            lock (_lock)
                if (_poller != null)
                {
                    lock (_poller.ChatUserInfosCache)
                        if (!_poller.ChatUserInfosCache.ContainsKey(chatUserId))
                        {
                            _poller.ChatUserInfosCache.Add(chatUserId, ret);
                        }
                }
            return(ret);
        }
        public void UnsubscribeFromNewChatUserInfo(int chatId, int userId, EventHandler <ChatUserInfo> handler)
        {
            var key = new ChatUserId(userId, chatId);

            lock (_newChatUserInfosHandlers)
            {
                if (!_newChatUserInfosHandlers.ContainsKey(key))
                {
                    throw new ArgumentException("No such subscription exists");
                }
                _newChatUserInfosHandlers[key] -= handler;
            }
        }
        public void SubscribeToNewChatUserInfo(int chatId, int userId, EventHandler <ChatUserInfo> handler)
        {
            var key = new ChatUserId(userId, chatId);

            lock (_newChatUserInfosHandlers)
            {
                if (_newChatUserInfosHandlers.ContainsKey(key))
                {
                    _newChatUserInfosHandlers[key] += handler;
                }
                else
                {
                    _newChatUserInfosHandlers.Add(key, handler);
                }
            }
        }
 public void SetChatUserInfo(int userId, int chatId, ChatUserInfo chatUserInfo)
 {
     lock (ChatUserInfosCache)
     {
         var key = new ChatUserId(userId, chatId);
         if (ChatUserInfosCache.ContainsKey(key))
         {
             ChatUserInfosCache[key] = chatUserInfo;
         }
         else
         {
             ChatUserInfosCache.Add(key, chatUserInfo);
         }
         if (_newChatUserInfosHandlers.ContainsKey(key))
         {
             _newChatUserInfosHandlers[key]?.Invoke(this, chatUserInfo);
         }
     }
 }
        private void ProcessNewChatMembers(int chatId, IEnumerable <int> members)
        {
            if (members == null)
            {
                return;
            }

            var membersArray = members as int[] ?? members.ToArray();

            if (!membersArray.Any())
            {
                return;
            }

            lock (ChatsStorage)
            {
                lock (ChatUserInfosCache)
                {
                    var prevMembers = ChatsStorage[chatId].Users;
                    foreach (var excludedMember in prevMembers.Where(x => !membersArray.Contains(x)))
                    {
                        var key = new ChatUserId(excludedMember, chatId);
                        if (ChatUserInfosCache.ContainsKey(key))
                        {
                            ChatUserInfosCache.Remove(key);
                        }
                    }
                }
                ChatsStorage[chatId].Users = membersArray;
            }

            lock (_newChatMembersHandlers)
            {
                if (_newChatMembersHandlers.ContainsKey(chatId))
                {
                    _newChatMembersHandlers[chatId]?.Invoke(this, membersArray);
                }
            }
        }