private void WatchThread(CancellationToken token)
        {
            for (; ;)
            {
                var chatThreadViewModels = new List <ChatThreadViewModel>();

                try
                {
                    App.Current.Dispatcher.Invoke(() =>
                    {
                        if (token.IsCancellationRequested)
                        {
                            return;
                        }

                        var chatCategoryViewModels = new List <ChatCategoryViewModel>();
                        chatCategoryViewModels.Add(this.TabViewModel.Value);

                        for (int i = 0; i < chatCategoryViewModels.Count; i++)
                        {
                            chatCategoryViewModels.AddRange(chatCategoryViewModels[i].Categories);
                            chatThreadViewModels.AddRange(chatCategoryViewModels[i].Threads);
                        }
                    }, DispatcherPriority.Background, token);
                }
                catch (OperationCanceledException)
                {
                    return;
                }

                var trustSignatures = new HashSet <Signature>(_messageManager.TrustSignatures);

                foreach (var chatThreadViewModel in chatThreadViewModels)
                {
                    if (token.IsCancellationRequested)
                    {
                        return;
                    }

                    var newMessages = new HashSet <MulticastCommentMessage>(_amoebaInterfaceManager.GetMulticastCommentMessages(chatThreadViewModel.Model.Tag, CancellationToken.None).Result);

                    lock (chatThreadViewModel.Model.Messages.LockObject)
                    {
                        newMessages.ExceptWith(chatThreadViewModel.Model.Messages.Select(n => n.Message));

                        var messageInfos = new List <ChatMessageInfo>();
                        messageInfos.AddRange(chatThreadViewModel.Model.Messages);

                        foreach (var message in newMessages)
                        {
                            messageInfos.Add(new ChatMessageInfo()
                            {
                                Message = message, State = ChatMessageState.New
                            });
                        }

                        messageInfos.Sort((x, y) => y.Message.CreationTime.CompareTo(x.Message.CreationTime));

                        chatThreadViewModel.Model.Messages.Clear();

                        foreach (var info in messageInfos.ToArray())
                        {
                            if (chatThreadViewModel.Model.IsTrustMessageOnly && !trustSignatures.Contains(info.Message.AuthorSignature))
                            {
                                continue;
                            }

                            if (!trustSignatures.Contains(info.Message.AuthorSignature))
                            {
                                if (info.Message.Cost.CashAlgorithm != CashAlgorithm.Version1)
                                {
                                    continue;
                                }
                                if (info.Message.Cost.Value < this.SelectedMiningLimit.Value)
                                {
                                    continue;
                                }
                            }

                            chatThreadViewModel.Model.Messages.Add(info);
                            if (chatThreadViewModel.Model.Messages.Count >= 1024)
                            {
                                break;
                            }
                        }
                    }

                    try
                    {
                        App.Current.Dispatcher.Invoke(() =>
                        {
                            if (token.IsCancellationRequested)
                            {
                                return;
                            }

                            int newCount = chatThreadViewModel.Model.Messages.Count(n => n.State.HasFlag(ChatMessageState.New));

                            chatThreadViewModel.Model.IsUpdated = (newCount > 0);
                            chatThreadViewModel.Count.Value     = newCount;
                        }, DispatcherPriority.Background, token);
                    }
                    catch (OperationCanceledException)
                    {
                        return;
                    }
                }

                if (token.WaitHandle.WaitOne(1000 * 30))
                {
                    return;
                }
            }
        }