/// <summary>
        /// Adds the address book to the list
        /// </summary>
        /// <param name="addressBook"></param>
        public void Add(AddressBook addressBook)
        {
            if (addressBook == null)
            {
                throw new ArgumentNullException("AddressBook", "A null reference to an AddressBook cannot be added to the list.");
            }

            if (this.Contains(addressBook))
            {
                throw new NameNotUniqueException(addressBook.Name);
            }

            addressBook.Changed           += new AddressingEventHandler(this.OnChanged);
            addressBook.BeforeNameChanged += new NameChangeEventHandler(this.OnBeforeAddressBookNameChanged);

            base.InnerList.Add(addressBook);

            addressBook.Parent = _parent;

            /*
             * raise the event
             *
             * starting it at the object level, which will trickle all the way up through the object heirarchies
             * normally, the "this" pointer would be the context of the call, but because we want the object
             * to get the add and remove events as well, we start the call with it
             * */
            AddressBookEventArgs e = new AddressBookEventArgs(addressBook, AddressingActions.Added);

            addressBook.OnChanged(this, e);
//			this.OnChanged(this, e);
        }
        public void Add(AddressBook addressBook, bool overwrite)
        {
            if (!overwrite)
            {
                this.Add(addressBook);
                return;
            }

            if (addressBook == null)
            {
                throw new ArgumentNullException("AddressBook", "A null reference to an AddressBook cannot be added to the list.");
            }

            // find by name...
            if (this.Contains(addressBook))
            {
                AddressBook existingBook = this[addressBook.Name];
                addressBook.WriteProperties(existingBook);
                return;
            }
            else
            {
                // try and find it by id
                AddressBook existingBook = this.FindById(addressBook.Id);

                // if we have a hit, that means this is the same object, just renamed
                if (existingBook != null)
                {
                    // so give it a new id
                    addressBook.GetNewId();
                }
            }

            addressBook.Changed           += new AddressingEventHandler(this.OnChanged);
            addressBook.BeforeNameChanged += new NameChangeEventHandler(this.OnBeforeAddressBookNameChanged);

            base.InnerList.Add(addressBook);

            addressBook.Parent = _parent;

            /*
             * raise the event
             *
             * starting it at the object level, which will trickle all the way up through the object heirarchies
             * normally, the "this" pointer would be the context of the call, but because we want the object
             * to get the add and remove events as well, we start the call with it
             * */
            AddressBookEventArgs e = new AddressBookEventArgs(addressBook, AddressingActions.Added);

            addressBook.OnChanged(this, e);
//			this.OnChanged(this, e);
        }
 /// <summary>
 /// Raises the AddressBookChanged event
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 protected virtual void OnAddressBookChanged(object sender, AddressBookEventArgs e)
 {
     try
     {
         if (this.AddressBookChanged != null)
         {
             this.AddressBookChanged(sender, e);
         }
     }
     catch (Exception ex)
     {
         Trace.WriteLine(ex);
     }
 }
        /// <summary>
        /// Removes the address book from the list
        /// </summary>
        /// <param name="addressBook"></param>
        public void Remove(AddressBook addressBook)
        {
            if (this.Contains(addressBook))
            {
                /*
                 * raise the event
                 *
                 * starting it at the object level, which will trickle all the way up through the object heirarchies
                 * normally, the "this" pointer would be the context of the call, but because we want the object
                 * to get the add and remove events as well, we start the call with it
                 * */
                AddressBookEventArgs e = new AddressBookEventArgs(addressBook, AddressingActions.Removed);
                addressBook.OnChanged(this, e);
//				this.OnChanged(this, e);

                addressBook.Changed           -= new AddressingEventHandler(this.OnChanged);
                addressBook.BeforeNameChanged -= new NameChangeEventHandler(this.OnBeforeAddressBookNameChanged);

                base.InnerList.Remove(addressBook);

                addressBook.Parent = null;
            }
        }
		/// <summary>
		/// Raises the AddressBookChanged event
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected virtual void OnAddressBookChanged(object sender, AddressBookEventArgs e)
		{
			try
			{
				if (this.AddressBookChanged != null)
					this.AddressBookChanged(sender, e);
			}
			catch(Exception ex)
			{
				Trace.WriteLine(ex);
			}
		}
		public void Add(AddressBook addressBook, bool overwrite)
		{
			if (!overwrite)
			{
				this.Add(addressBook);
				return;
			}

			if (addressBook == null)
				throw new ArgumentNullException("AddressBook", "A null reference to an AddressBook cannot be added to the list.");

			// find by name...
			if (this.Contains(addressBook))
			{
				AddressBook existingBook = this[addressBook.Name];
				addressBook.WriteProperties(existingBook);				
				return;
			}
			else 
			{
				// try and find it by id
				AddressBook existingBook = this.FindById(addressBook.Id);

				// if we have a hit, that means this is the same object, just renamed
				if (existingBook != null)
					// so give it a new id
					addressBook.GetNewId();									
			}
			
			addressBook.Changed += new AddressingEventHandler(this.OnChanged);
			addressBook.BeforeNameChanged += new NameChangeEventHandler(this.OnBeforeAddressBookNameChanged);
			
			base.InnerList.Add(addressBook);

			addressBook.Parent = _parent;

			/*
			 * raise the event
			 * 
			 * starting it at the object level, which will trickle all the way up through the object heirarchies
			 * normally, the "this" pointer would be the context of the call, but because we want the object
			 * to get the add and remove events as well, we start the call with it
			 * */
			AddressBookEventArgs e = new AddressBookEventArgs(addressBook, AddressingActions.Added);
			addressBook.OnChanged(this, e);
//			this.OnChanged(this, e);
		}
		/// <summary>
		/// Adds the address book to the list
		/// </summary>
		/// <param name="addressBook"></param>
		public void Add(AddressBook addressBook)
		{
			if (addressBook == null)
				throw new ArgumentNullException("AddressBook", "A null reference to an AddressBook cannot be added to the list.");

			if (this.Contains(addressBook))
				throw new NameNotUniqueException(addressBook.Name);

			addressBook.Changed += new AddressingEventHandler(this.OnChanged);
			addressBook.BeforeNameChanged += new NameChangeEventHandler(this.OnBeforeAddressBookNameChanged);
			
			base.InnerList.Add(addressBook);

			addressBook.Parent = _parent;

			/*
			 * raise the event
			 * 
			 * starting it at the object level, which will trickle all the way up through the object heirarchies
			 * normally, the "this" pointer would be the context of the call, but because we want the object
			 * to get the add and remove events as well, we start the call with it
			 * */
			AddressBookEventArgs e = new AddressBookEventArgs(addressBook, AddressingActions.Added);
			addressBook.OnChanged(this, e);
//			this.OnChanged(this, e);
		}
		/// <summary>
		/// Removes the address book from the list
		/// </summary>
		/// <param name="addressBook"></param>
		public void Remove(AddressBook addressBook)
		{
			if (this.Contains(addressBook))
			{
				/*
				* raise the event
				* 
				* starting it at the object level, which will trickle all the way up through the object heirarchies
				* normally, the "this" pointer would be the context of the call, but because we want the object
				* to get the add and remove events as well, we start the call with it
				* */
				AddressBookEventArgs e = new AddressBookEventArgs(addressBook, AddressingActions.Removed);
				addressBook.OnChanged(this, e);
//				this.OnChanged(this, e);						

				addressBook.Changed -= new AddressingEventHandler(this.OnChanged);
				addressBook.BeforeNameChanged -= new NameChangeEventHandler(this.OnBeforeAddressBookNameChanged);

				base.InnerList.Remove(addressBook);

				addressBook.Parent = null;
			}	
		}