protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);

            //
            // Get the person object from the intent
            //
            Person person;
            if (Intent.HasExtra ("Person")) {
                var serializer = new System.Xml.Serialization.XmlSerializer (typeof (Person));
                var personBytes = Intent.GetByteArrayExtra ("Person");
                person = (Person)serializer.Deserialize (new MemoryStream (personBytes));
            } else {
                person = new Person ();
            }

            //
            // Load the View Model
            //
            viewModel = new PersonViewModel (person, Android.Application.SharedFavoritesRepository);
            viewModel.PropertyChanged += HandleViewModelPropertyChanged;

            //
            // Setup the UI
            //
            ListView.Divider = null;
            ListAdapter = new PersonAdapter (viewModel);

            Title = person.SafeDisplayName;
        }
 /// <summary>
 /// Creates the intent that can be used to present this activity given
 /// a specific Person object.
 /// </summary>
 /// <returns>
 /// The intent.
 /// </returns>
 /// <param name='person'>
 /// The Person to show in this activity.
 /// </param>
 public static Intent CreateIntent (Context context, Person person)
 {
     var intent = new Intent (context, typeof (PersonActivity));
     var serializer = new System.Xml.Serialization.XmlSerializer (typeof (Person));
     var personStream = new MemoryStream ();
     serializer.Serialize (personStream, person);
     intent.PutExtra ("Person", personStream.ToArray ());
     return intent;
 }
        public PersonViewController(Person person, IFavoritesRepository favoritesRepository)
            : base(UITableViewStyle.Grouped)
        {
            personViewModel = new PersonViewModel (person, favoritesRepository);

            Title = person.SafeFirstName;

            TableView.DataSource = new PersonDataSource (this);
            TableView.Delegate = new PersonDelegate (this);
        }
        void StartImageDownload(UITableView tableView, NSIndexPath indexPath, Person person)
        {
            if (imageDownloadsInProgress.Contains (person.Id))
                return;

            imageDownloadsInProgress.Add (person.Id);

            imageDownloader.GetImageAsync (Gravatar.GetImageUrl (person.Email, 88)).ContinueWith (t => {
                if (!t.IsFaulted)
                    FinishImageDownload (tableView, indexPath, person, (UIImage)t.Result);
            }, TaskScheduler.FromCurrentSynchronizationContext ());
        }
        void FinishImageDownload(UITableView tableView, NSIndexPath indexPath, Person person, UIImage image)
        {
            images [person.Id] = image;
            imageDownloadsInProgress.Remove (person.Id);

            if (indexPath.Section < Groups.Count &&
                indexPath.Row < Groups [indexPath.Section].People.Count) {

                var cell = tableView.CellAt (indexPath);
                if (cell != null)
                    cell.ImageView.Image = image;
            }
        }
		public void Delete (Person person)
		{
			var newPeopleQ = from p in People
			                 where p.Id != person.Id
			                 select p;
			var newPeople = newPeopleQ.ToList ();
			var n = People.Count - newPeople.Count;
			People = newPeople;
			if (n != 0) {
				var task = Task.Run (async () => {
					await Commit ();
				});
				task.Wait ();
			}
		}
		public void InsertOrUpdate (Person person)
		{
			var existing = People.FirstOrDefault (x => x.Id == person.Id);
			if (existing != null)
				People.Remove (existing);

			People.Add (person);
			var task = Task.Run (async () => {
				await Commit ();
			});
			task.Wait ();
		}
		public bool IsFavorite (Person person)
		{
			return People.Any (x => x.Id == person.Id);
		}
		public void Delete (Person person)
		{
			var newPeopleQ = from p in People where p.Id != person.Id select p;
			var newPeople = newPeopleQ.ToList ();
			var n = People.Count - newPeople.Count;
			People = newPeople;
			if (n != 0) {
				Commit ().Wait();
			}
		}
		public void InsertOrUpdate (Person person)
		{
			var existing = People.FirstOrDefault (x => x.Id == person.Id);
			if (existing != null) {
				People.Remove (existing);
			}
			People.Add (person);
			Commit ().Wait();
		}
 public PersonItem (Person person, bool isLastPersonInGroup)
 {
     Person = person;
     IsLastPersonInGroup = isLastPersonInGroup;
 }
        void FinishImageDownload (ListView listView, int position, Person person, Bitmap image)
        {
            images [person.Id] = image;
            imageDownloadsInProgress.Remove (person.Id);

            var personItem = (position < items.Count) ?
                            items [position] as PersonItem :
                            null;

            if (personItem != null && personItem.Person == person) {

                var firstPostion = listView.FirstVisiblePosition - listView.HeaderViewsCount;
                var childIndex = position - firstPostion;

                if (0 <= childIndex && childIndex < listView.ChildCount) {
                    var view = listView.GetChildAt (childIndex);
                    var imageButton = view.FindViewById<ImageButton> (Resource.Id.ImageButton);
                    imageButton.SetImageBitmap (image);
                }
            }
        }
        void StartImageDownload (ListView listView, int position, Person person)
        {
            if (imageDownloadsInProgress.Contains (person.Id))
                return;

            var url = Gravatar.GetImageUrl (person.Email, 100);

            if (imageDownloader.HasLocallyCachedCopy (url)) {

                var image = imageDownloader.GetImage (url);
                FinishImageDownload (listView, position, person, (Bitmap)image);

            } else {
                imageDownloadsInProgress.Add (person.Id);

                imageDownloader.GetImageAsync (url).ContinueWith (t => {
                    if (!t.IsFaulted) {
                        FinishImageDownload (listView, position, person, (Bitmap)t.Result);
                    }
                }, TaskScheduler.FromCurrentSynchronizationContext ());
            }
        }
		// For handling properties with multiple entries

		IList<Person> Search (string searchFilter, int sizeLimit)
		{
			var results = new List<Person> ();

			try {
				//
				// Query the server
				//
				var lsc = conn.Search (
					          SearchBase,
					          LdapConnection.SCOPE_SUB,
					          searchFilter,
					          null,
					          false,
					          new LdapSearchConstraints (0, 0, LdapSearchConstraints.DEREF_NEVER, sizeLimit, false, 1, null, 10));

				while (lsc.hasMore ()) {
					var nextEntry = lsc.next ();

					//
					// Create the person and load all their properties
					//
					// This code uses Reflection to create a mapping between LDAP
					// attribute types and .NET properties. See PropertyAttribute and
					// the static constructor of this class for details.
					//
					var person = new Person {
						Id = nextEntry.DN
					};

					foreach (LdapAttribute attribute in nextEntry.getAttributeSet ()) {
						var attributeName = attribute.Name;
						var val = attribute.StringValue;

						PropertyInfo p;
						if (propertyFromLdap.TryGetValue (attributeName, out p)) {
							if (ListType.IsAssignableFrom (p.PropertyType)) {
								var list = (List<string>)p.GetValue (person, null);
								list.Add (val);
							} else {
								p.SetValue (person, val, null);
							}
						}
					}

					//
					// Make sure we only load people by looking for a last name
					//
					if (!string.IsNullOrEmpty (person.LastName))
						results.Add (person);
				}
			} catch (LdapException e) {
				if (e.ResultCode != 4)
					throw;
			}

			return results;
		}
		void CreateTile (Person person, Uri imageUri)
		{
			var uri = "/PersonPage.xaml?id=" + Uri.EscapeDataString (person.Id);

			// Make sure they are in our favorites list
			if (!ViewModel.IsFavorite) {
				ViewModel.ToggleFavorite ();
			}

			// Delete any old tile
			var foundTile = ShellTile.ActiveTiles.FirstOrDefault (x => x.NavigationUri.ToString ().Contains (uri));

			if (foundTile != null) {
				foundTile.Delete ();
			}

			// Create the new tile
			var tile = new StandardTileData {
				Title = person.SafeDisplayName,
				BackContent = person.TitleAndDepartment,
				BackTitle = person.SafeDisplayName,
				BackgroundImage = (imageUri != null) ? imageUri : new Uri ("/Background.png", UriKind.RelativeOrAbsolute),
			};

			ShellTile.Create (new Uri (uri, UriKind.Relative), tile);
		}