public void when_subscribing_to_initialized_shell_then_receives_event_and_completes()
		{
			object zombie = false;
			var observable = new ShellInitializedObservable(Mock.Of<IVsShell>(shell => shell.GetProperty(ZombieProperty, out zombie) == VSConstants.S_OK));

			var completed = false;
			ShellInitialized data = null;

			using (observable.Subscribe(e => data = e, () => completed = true)) { }

			Assert.True(completed);
			Assert.NotNull(data);
		}
		public async Task when_subscribing_to_noninitialized_shell_then_can_wait_event_and_completion()
		{
			object zombie = true;
			uint cookie = 1;
			IVsShellPropertyEvents callback = null;

			var shell = new Mock<IVsShell>();
			shell.Setup(x => x.GetProperty(ZombieProperty, out zombie)).Returns(VSConstants.S_OK);

			var capture = new CaptureMatch<IVsShellPropertyEvents>(s => callback = s);
			shell.Setup(x => x.AdviseShellPropertyChanges(Capture.With(capture), out cookie))
				.Returns(VSConstants.S_OK);

			var observable = new ShellInitializedObservable(shell.Object);

			// Callback should have been provided at this point.
			Assert.NotNull(callback);

			var completed = false;
			ShellInitialized data = null;

			observable.Subscribe(e => data = e, () => completed = true);

			Assert.False(completed, "Observable shouldn't have completed yet.");
			Assert.Null(data);

			callback.OnShellPropertyChange(ZombieProperty, false);

			SpinWait.SpinUntil(() => completed, 5000);

			Assert.True(completed, "Observable should have completed already.");
			Assert.NotNull(data);

			shell.Verify(x => x.UnadviseShellPropertyChanges(cookie));

			// Subsequent subscription should get one and complete right away.

			var ev = await observable;

			Assert.Same(data, ev);
		}