private void ProcessQueue(LinkedList <ScheduledRequestItem> queue, long intervals, int maxBurst)
        {
            LinkedListNode <ScheduledRequestItem> lastAddedNode   = null;
            LinkedListNode <ScheduledRequestItem> lastAddedHpNode = GeneralQueue.Count == 0 ? null : GeneralQueue.First;
            var node = queue.First;

            do
            {
                ChatRequestCount requestCount = RequestCounts[node.Value.ChatId];
                if (requestCount.GetRequestCount(intervals) <= maxBurst)
                {
                    requestCount.Increment();
                    if (node.Value.IsHighPriority)
                    {
                        lastAddedHpNode = InsertToGeneralQueueHp(node.Value, lastAddedHpNode);
                    }
                    else
                    {
                        lastAddedNode = InsertToGeneralQueue(node.Value, lastAddedNode);
                    }
                    var nextNode = node.Next;
                    queue.Remove(node);
                    node = nextNode;
                }
                else
                {
                    node = node.Next;
                }
            }while (node != null);
        }
        // Used for private chats, groups, supergroups and channels when they are referenced by ID
        private void WaitOneInternalLocked(long chatId, SchedulingMethod schedulingMethod)
        {
            if (schedulingMethod == SchedulingMethod.NoScheduling)
            {
                lock (QueueLock)
                {
                    GeneralRequestCount++;
                    if (RequestCounts.TryGetValue(chatId, out ChatRequestCount chatRequestCount))
                    {
                        chatRequestCount.GetRequestCount(chatId > 0 ? PrivateChatIntervals : GroupChatIntervals);
                        chatRequestCount.Increment();
                    }
                    else
                    {
                        RequestCounts.Add(chatId, new ChatRequestCount(1, chatId > 0 ? PrivateChatIntervals : GroupChatIntervals));
                    }
                }
                return;
            }
            bool isHighPriority = schedulingMethod == SchedulingMethod.HighPriority;

            ManualResetEvent mre = null;

            if (chatId > 0)
            {
                lock (QueueLock)
                {
                    if (RequestCounts.TryGetValue(chatId, out ChatRequestCount ChatRequestCount))
                    {
                        if (ChatRequestCount.GetRequestCount(PrivateChatIntervals) <= PrivateChatMaxBurst)
                        {
                            ChatRequestCount.Increment();
                            mre = WaitOneInternalUnlocked(schedulingMethod);
                        }
                        else
                        {
                            var requestItem = new ScheduledRequestItem(TimerIntervals, isHighPriority, chatId);
                            if (isHighPriority)
                            {
                                PrivateChatQueue.AddFirst(requestItem);
                            }
                            else
                            {
                                PrivateChatQueue.AddLast(requestItem);
                            }
                            mre = requestItem.MRE;
                        }
                    }
                    else
                    {
                        RequestCounts.Add(chatId, new ChatRequestCount(1, PrivateChatIntervals));
                        mre = WaitOneInternalUnlocked(schedulingMethod);
                    }
                }
            }
            else
            {
                lock (QueueLock)
                {
                    if (RequestCounts.TryGetValue(chatId, out ChatRequestCount ChatRequestCount))
                    {
                        if (ChatRequestCount.GetRequestCount(GroupChatIntervals) <= GroupChatMaxBurst)
                        {
                            ChatRequestCount.Increment();
                            mre = WaitOneInternalUnlocked(schedulingMethod);
                        }
                        else
                        {
                            var requestItem = new ScheduledRequestItem(TimerIntervals, isHighPriority, chatId);
                            if (isHighPriority)
                            {
                                GroupChatQueue.AddFirst(requestItem);
                            }
                            else
                            {
                                GroupChatQueue.AddLast(requestItem);
                            }
                            mre = requestItem.MRE;
                        }
                    }
                    else
                    {
                        RequestCounts.Add(chatId, new ChatRequestCount(1, GroupChatIntervals));
                        mre = WaitOneInternalUnlocked(schedulingMethod);
                    }
                }
            }

            mre?.WaitOne();
            return;
        }