public RoomViewModel(Room room)
        {
            if (room == null)
                throw new ArgumentNullException("room");

            this.Room = room;
        }
            public async Task SmokeTest()
            {
                await BlobCache.Secure.SaveLogin("Gitter", "TheAccessToken", "Gitter");
                var room = new Room { name = "TheRoom", id = "TheRoomId" };
                var api = Substitute.For<IGitterApi>();
                api.GetMessages(Arg.Any<string>(), Arg.Any<string>()).Returns(Observable.Return((IReadOnlyList<Message>)new List<Message>()));
                var fixture = new MessagesViewModel(room, api, Substitute.For<IScreen>());
                await fixture.LoadMessages.ExecuteAsync();

                fixture.MessageText = "TheMessage";

                await fixture.SendMessage.ExecuteAsync();

                api.Received(1).SendMessage(room.id, Arg.Is<SendMessage>(x => x.Text == "TheMessage"), "Bearer TheAccessToken");
            }
            public async Task ClearsMessageTextAfterSending()
            {
                await BlobCache.Secure.SaveLogin("Gitter", "TheAccessToken", "Gitter");
                var room = new Room { name = "TheRoom", id = "TheRoomId" };
                var api = Substitute.For<IGitterApi>();
                api.GetMessages(Arg.Any<string>(), Arg.Any<string>()).Returns(Observable.Return((IReadOnlyList<Message>)new List<Message>()));
                var fixture = new MessagesViewModel(room, api, Substitute.For<IScreen>());
                await fixture.LoadMessages.ExecuteAsync();

                fixture.MessageText = "TheMessage";

                await fixture.SendMessage.ExecuteAsync();

                Assert.IsEmpty(fixture.MessageText);
            }
            public async Task CanExecuteWhenMessageIsNotNullOrEmpty()
            {
                await BlobCache.Secure.SaveLogin("Gitter", "TheAccessToken", "Gitter");
                var room = new Room { name = "TheRoom", id = "TheRoomId" };
                var api = Substitute.For<IGitterApi>();
                api.GetMessages(Arg.Any<string>(), Arg.Any<string>()).Returns(Observable.Return((IReadOnlyList<Message>)new List<Message>()));
                var fixture = new MessagesViewModel(room, api, Substitute.For<IScreen>());
                await fixture.LoadMessages.ExecuteAsync();

                fixture.MessageText = "TheMessage";
                Assert.True(fixture.SendMessage.CanExecute(null));

                fixture.MessageText = null;
                Assert.False(fixture.SendMessage.CanExecute(null));

                fixture.MessageText = String.Empty;
                Assert.False(fixture.SendMessage.CanExecute(null));

                fixture.MessageText = " ";
                Assert.False(fixture.SendMessage.CanExecute(null));
            }
        public MessagesViewModel(Room room, IGitterApi api = null, IScreen hostScreen = null)
        {
            this.HostScreen = hostScreen ?? Locator.Current.GetService<IScreen>();

            this.Messages = new ReactiveList<MessageViewModel>();
            this.UrlPathSegment = room.name;

            IObservable<string> accessToken = GitterApi.GetAccessToken().PublishLast().RefCount();

            this.LoadMessages = ReactiveCommand.CreateAsyncObservable(_ => accessToken.SelectMany(token => (api ?? GitterApi.UserInitiated).GetMessages(room.id, token)));

            this.Users = new ReactiveList<UserViewModel>();
            this.LoadUsers = ReactiveCommand.CreateAsyncObservable(_ => accessToken
                .SelectMany(token => (api ?? GitterApi.UserInitiated).GetRoomUsers(room.id, token))
                .Select(users => users.OrderBy(user => user.displayName, StringComparer.CurrentCulture).Select(user => new UserViewModel(user))));
            this.LoadUsers.Subscribe(x =>
            {
                using (this.Users.SuppressChangeNotifications())
                {
                    this.Users.Clear();
                    this.Users.AddRange(x);
                }
            });

            this.SendMessage = ReactiveCommand.CreateAsyncTask(this.WhenAnyValue(x => x.MessageText, x => !String.IsNullOrWhiteSpace(x)), async _ =>
            {
                await (api ?? GitterApi.UserInitiated).SendMessage(room.id, new SendMessage(this.MessageText), await accessToken);
                this.MessageText = String.Empty;
            });

            this.LoadMessages.FirstAsync().SelectMany(x => x.ToObservable())
                .Concat(this.StreamMessages(room.id))
                .Select(x => new MessageViewModel(x))
                .Subscribe(x =>
                {
                    this.Messages.Insert(0, x);
                });
        }