private IStreamHandler InitializeHandler()
        {
            var handler = StreamHandler.Create(StatusInbox.Enqueue,
                                               ex =>
            {
                BehaviorLogger.Log("U/S", _account.UnreliableScreenName + ":" + ex.ToString());
                BackstageModel.RegisterEvent(new StreamDecodeFailedEvent(_account.UnreliableScreenName, ex));
            });

            handler.AddHandler <StreamDelete>(d => StatusInbox.EnqueueRemoval(d.Id));
            handler.AddHandler <StreamDisconnect>(
                d => BackstageModel.RegisterEvent(new UserStreamsDisconnectedEvent(_account, d.Reason)));
            handler.AddHandler <StreamLimit>(
                limit => NotificationService.NotifyLimitationInfoGot(_account, (int)limit.UndeliveredCount));
            handler.AddHandler <StreamStatusEvent>(s =>
            {
                switch (s.Event)
                {
                case StatusEvents.Unknown:
                    BackstageModel.RegisterEvent(new UnknownEvent(s.Source, s.RawEvent));
                    break;

                case StatusEvents.Favorite:
                    NotificationService.NotifyFavorited(s.Source, s.TargetObject);
                    break;

                case StatusEvents.Unfavorite:
                    NotificationService.NotifyUnfavorited(s.Source, s.TargetObject);
                    break;

                case StatusEvents.FavoriteRetweet:
                    NotificationService.NotifyFavorited(s.Source, s.TargetObject);
                    break;

                case StatusEvents.RetweetRetweet:
                    NotificationService.NotifyRetweeted(s.Source, s.TargetObject.RetweetedOriginal, s.TargetObject);
                    break;

                case StatusEvents.Quote:
                    // do nothing
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                if (s.TargetObject != null)
                {
                    StatusInbox.Enqueue(s.TargetObject);
                }
            });
            handler.AddHandler <StreamUserEvent>(async item =>
            {
                var active  = item.Source.Id == _account.Id;
                var passive = item.Target.Id == _account.Id;
                var reldata = _account.RelationData;
                switch (item.Event)
                {
                case UserEvents.Unknown:
                    BackstageModel.RegisterEvent(new UnknownEvent(item.Source, item.RawEvent));
                    break;

                case UserEvents.Follow:
                    if (active)
                    {
                        await reldata.Followings.SetAsync(item.Target.Id, true).ConfigureAwait(false);
                    }
                    if (passive)
                    {
                        await reldata.Followers.SetAsync(item.Source.Id, true).ConfigureAwait(false);
                    }
                    NotificationService.NotifyFollowed(item.Source, item.Target);
                    break;

                case UserEvents.Unfollow:
                    if (active)
                    {
                        await reldata.Followings.SetAsync(item.Target.Id, false).ConfigureAwait(false);
                    }
                    if (passive)
                    {
                        await reldata.Followers.SetAsync(item.Source.Id, false).ConfigureAwait(false);
                    }
                    NotificationService.NotifyUnfollowed(item.Source, item.Target);
                    break;

                case UserEvents.Block:
                    if (active)
                    {
                        await reldata.Followings.SetAsync(item.Target.Id, false).ConfigureAwait(false);
                        await reldata.Followers.SetAsync(item.Target.Id, false).ConfigureAwait(false);
                        await reldata.Blockings.SetAsync(item.Target.Id, true).ConfigureAwait(false);
                    }
                    if (passive)
                    {
                        await reldata.Followers.SetAsync(item.Target.Id, false).ConfigureAwait(false);
                    }
                    NotificationService.NotifyBlocked(item.Source, item.Target);
                    break;

                case UserEvents.Unblock:
                    if (active)
                    {
                        await reldata.Blockings.SetAsync(item.Target.Id, false).ConfigureAwait(false);
                    }
                    NotificationService.NotifyUnblocked(item.Source, item.Target);
                    break;

                case UserEvents.UserUpdate:
                    NotificationService.NotifyUserUpdated(item.Source);
                    break;

                case UserEvents.Mute:
                    if (active)
                    {
                        await reldata.Mutes.SetAsync(item.Target.Id, true).ConfigureAwait(false);
                    }
                    NotificationService.NotifyBlocked(item.Source, item.Target);
                    break;

                case UserEvents.UnMute:
                    if (active)
                    {
                        await reldata.Mutes.SetAsync(item.Target.Id, false).ConfigureAwait(false);
                    }
                    NotificationService.NotifyUnblocked(item.Source, item.Target);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            });
            return(handler);
        }