public async Task SaveTodoItemAsync(TodoItem todoItem)
		{
			if (String.IsNullOrEmpty(todoItem.ID))
				await todoTable.InsertAsync(todoItem);
			else
				await todoTable.UpdateAsync(todoItem);
		}
		public async Task DeleteTodoItemAsync (TodoItem t)
		{
			DBError error;

			var table = store.GetTable (tableName);
			var r = table.GetRecord (t.ID, out error);
			r.DeleteRecord();

			await store.SyncAsync ();
		}
		ParseObject ToParseObject (TodoItem todo)
		{
			var po = new ParseObject("Task");
			if (todo.ID != string.Empty)
				po.ObjectId = todo.ID;
			po["Title"] = todo.Name;
			po["Description"] = todo.Notes;
			po["IsDone"] = todo.Done;

			return po;
		}
		public void CreateTask () {
			// first, add the task to the underlying data
			var newTodo = new TodoItem();

			// then open the detail view to edit it
			var detail = Storyboard.InstantiateViewController("detail") as TaskDetailViewController;
			detail.SetTask (newTodo);
			NavigationController.PushViewController (detail, true);

			// Could to this instead of the above, but need to create 'new Task()' in PrepareForSegue()
			//this.PerformSegue ("TaskSegue", this);
		}
		public async Task SaveTodoItemAsync (TodoItem t)
		{
			DBError error;

			var table = store.GetTable (tableName);
			var r = table.GetRecord (t.ID, out error);
			if (r == null)
				table.Insert (t.ToDictionary ());
			else 
				r.Update (t); 

			await store.SyncAsync ();
		}
		static TodoItem FromParseObject (ParseObject po)
		{
			var t = new TodoItem();
			t.ID = po.ObjectId;

			try {
				t.Done = Convert.ToBoolean (po["IsDone"]);
				t.Name = Convert.ToString(po["Title"]); // can never be null
				t.Notes = Convert.ToString (po["Description"]); // could be null
			} catch (KeyNotFoundException){

			}
			return t;
		}
		protected async override void OnCreate (Bundle bundle)
		{
			base.OnCreate (bundle);
			
			View titleView = Window.FindViewById(Android.Resource.Id.Title);
			if (titleView != null) {
			  IViewParent parent = titleView.Parent;
			  if (parent != null && (parent is View)) {
			    View parentView = (View)parent;
			    parentView.SetBackgroundColor(Color.Rgb(0x26, 0x75 ,0xFF)); //38, 117 ,255
			  }
			}

			// set our layout to be the home screen
			SetContentView(Resource.Layout.TaskDetails);
			nameTextEdit = FindViewById<EditText>(Resource.Id.txtName);
			notesTextEdit = FindViewById<EditText>(Resource.Id.txtNotes);
			saveButton = FindViewById<Button>(Resource.Id.btnSave);
			doneCheckbox = FindViewById<CheckBox>(Resource.Id.chkDone);
			cancelDeleteButton = FindViewById<Button>(Resource.Id.btnCancelDelete);

			// button clicks 
			cancelDeleteButton.Click += (sender, e) => { CancelDelete(); };
			saveButton.Click += (sender, e) => { Save(); };

			string taskID = Intent.GetStringExtra("TaskID");
			if(!String.IsNullOrEmpty(taskID)) {
				//HACK: task = AppDelegate.Current.TaskMgr.GetTask(taskID);
				task = await AppDelegate.Current.TaskMgr.GetTaskAsync(taskID);
			}

			// set the cancel delete based on whether or not it's an existing task
			cancelDeleteButton.Text = (String.IsNullOrEmpty(task.ID) ? "Cancel" : "Delete");

			nameTextEdit.Text = task.Name;
			notesTextEdit.Text = task.Notes;
			doneCheckbox.Checked = task.Done;
		}
		public RootTableSource (TodoItem[] items)
		{
			tableItems = items; 
		}
		public async Task DeleteTodoItemAsync(TodoItem item)
		{
			try 
			{
				await ToParseObject(item).DeleteAsync();
			} 
			catch (Exception e) 
			{
				Console.Error.WriteLine(@"				ERROR {0}", e.Message);
			}
		}
		public async Task SaveTodoItemAsync(TodoItem todoItem)
		{
			await ToParseObject(todoItem).SaveAsync();
		}
		public Task DeleteTaskAsync (TodoItem item)
		{
			return storage.DeleteTodoItemAsync(item);
		}
		public static DBRecord Update (this DBRecord record, TodoItem t)
		{
			record.SetObject (new NSString(t.Name), "Title");
			record.SetObject (new NSString(t.Notes), "Description");
			record.SetObject (new NSString(t.Done.ToString()), "IsDone");
			return record;
		}
		public static DBRecord Update (this DBRecord record, TodoItem t)
		{
			record.Set ("Title", t.Name);
			record.Set ("Description", t.Notes);
			record.Set ("IsDone", t.Done);
			return record;
		}
		public async Task DeleteTodoItemAsync (TodoItem t)
		{
			await Task.Run (() => {
				var table = store.GetTable (tableName);
				var r = table.Get (t.ID);
				r.DeleteRecord ();

				store.Sync ();
			});
		}
		public async Task SaveTodoItemAsync (TodoItem t)
		{
			await Task.Run(() => {
			var table = store.GetTable (tableName);
			var r = table.Get (t.ID);
			if (r == null)
				table.Insert (t.ToDictionary ());
			else 
				r.Update (t); 

			store.Sync ();
			return;
			});
		}
		// this will be called before the view is displayed (from the list screen)
		public void SetTask (TodoItem todo) {
			currentTodoItem = todo;
		}
		public async Task DeleteTodoItemAsync(TodoItem item)
		{
			try 
			{
				await todoTable.DeleteAsync(item);
			} 
			catch (MobileServiceInvalidOperationException msioe)
			{
				Console.Error.WriteLine(@"INVALID {0}", msioe.Message);
			}
			catch (Exception e) 
			{
				Console.Error.WriteLine(@"ERROR {0}", e.Message);
			}
		}
		public Task SaveTaskAsync (TodoItem item)
		{
			return storage.SaveTodoItemAsync(item);
		}