public TodoItemViewModel (TodoItem todoItem) 
		{
			todo = todoItem;
			saveCommand = new Command (Save);
			deleteCommand = new Command (Delete);
			cancelCommand = new Command (() => Navigation.Pop());
			speakCommand = new Command (Speak);
		}
		public int SaveItem (TodoItem item) 
		{
			lock (locker) {
				if (item.ID != 0) {
					database.Update(item);
					return item.ID;
				} else {
					return database.Insert(item);
				}
			}
		}
		public TodoListViewModel ()
		{
			// HACK: don't need these any more, I packaged a pre-populated SQLite database file
//			App.Database.SaveItem (new TodoItem{ Name = "Buy apples", Notes = "Macintosh" });
//			App.Database.SaveItem (new TodoItem{ Name = "Buy pears", Notes = "" });
//			App.Database.SaveItem (new TodoItem{ Name = "Buy milk", Notes = "Soy" });
//			App.Database.SaveItem (new TodoItem{ Name = "Buy bananas", Notes = "" });
//			App.Database.SaveItem (new TodoItem{ Name = "Buy kiwi", Notes = "" });
//			App.Database.SaveItem (new TodoItem{ Name = "Buy oranges", Notes = "" });

			var all = App.Database.GetItems ().ToList();

			foreach (var t in all) {
				contents.Add (new TodoItemCellViewModel (t));
			}

			MessagingCenter.Subscribe<TodoItemViewModel, TodoItem> (this, "TodoSaved", (sender, model) => {
				App.Database.SaveItem(model);
				Reload();
			});

			MessagingCenter.Subscribe<TodoItemViewModel, TodoItem> (this, "TodoDeleted", (sender, model) => {
				App.Database.DeleteItem(model.ID);
				Reload();
			});

			MessagingCenter.Subscribe<TodoItemViewModel, TodoItem> (this, "TodoSpeak", (sender, model) => {

				Xamarin.Forms.DependencyService.Get<ITextToSpeech>().Speak(model.Name + " " + model.Notes);

			});

			MessagingCenter.Subscribe<TodoListPage, TodoItem> (this, "TodoAdd", (sender, viewModel) => {
				var todo = new TodoItem();
				var todovm = new TodoItemViewModel(todo);
				Navigation.Push (ViewFactory.CreatePage (todovm));
			});

			MessagingCenter.Subscribe<TodoListPage> (this, "TodoListSpeak", (sender) => {
				var todos = App.Database.GetItemsNotDone();
				var tospeak = "";
				foreach (var t in todos)
					tospeak += t.Name + " ";
				if (tospeak == "") tospeak = "there are no tasks to do";

				Xamarin.Forms.DependencyService.Get<ITextToSpeech>().Speak(tospeak);

				//App.Speech.Speak(tospeak);
			});
		}
		public TodoListPage ()
		{
			Title = "TodoMvvm";

			NavigationPage.SetHasNavigationBar (this, true);

			var listView = new ListView ();
			listView.RowHeight = 40;
			listView.SetBinding (ListView.ItemsSourceProperty, "Contents");
			listView.SetBinding (ListView.SelectedItemProperty, new Binding ("SelectedItem", BindingMode.TwoWay));
			listView.ItemTemplate = new DataTemplate (typeof (TodoItemCell));

			Content = new StackLayout {
				VerticalOptions = LayoutOptions.FillAndExpand,
				Children = {listView}
			};

			var tbi = new ToolbarItem ("+", null, () => {
				var t = new TodoItem();
				MessagingCenter.Send (this, "TodoAdd", t);
			}, 0, 0);
			if (Device.OS == TargetPlatform.Android) { // BUG: Android doesn't support the icon being null
				tbi = new ToolbarItem ("+", "plus", () => {
					var t = new TodoItem();
					MessagingCenter.Send (this, "TodoAdd", t);
				}, 0, 0);
			}
			ToolbarItems.Add (tbi);

			if (Device.OS == TargetPlatform.iOS) {
				var tbi2 = new ToolbarItem ("?", null, () => {
					MessagingCenter.Send (this, "TodoListSpeak");
				}, 0, 0);
				ToolbarItems.Add (tbi2);
			}
		}
		public TodoItemCellViewModel (TodoItem todoItem)
		{
			todo = todoItem;
		}