/// <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>
		/// Initializes a new instance of the AddressBookConnectionManager class
		/// </summary>
		/// <param name="addressBook"></param>
		public AddressBookConnectionManager(AddressBook addressBook) : this()
		{								
			// we require a valid address book
			if (addressBook == null)
				throw new ArgumentNullException("addressBook");

			/*
			 * wire up to the events of the address book and monitor it for changes
			 * */
			_addressBook = addressBook;

			// determines whether the manager intercepts the events from the address book to control the connection managers
			this.InterceptAddressBookEvents = false;
		}
		/// <summary>
		/// Writes this instances properties to the item using it's public properties (Only data related fields are assigned)
		/// </summary>
		/// <param name="item">The item to write properties to</param>
		public void WriteProperties(AddressBook book)
		{
			book.Name = _name;			
			book.Description = _description;			
		}
		/// <summary>
		/// Initializes a new instance of the AddressBook class
		/// </summary>
		/// <param name="addressBook">The address book to copy</param>
		public AddressBook(AddressBook addressBook) : this(addressBook.Name, addressBook.Description, addressBook.Items)
		{			
			_id = addressBook.Id;
		}
		/// <summary>
		/// Initializes a new instance of the AddressBookEventArgs class
		/// </summary>
		/// <param name="addressBook">The context of the event</param>
		/// <param name="action">The action taken on the context</param>
		public AddressBookEventArgs(AddressBook addressBook, AddressingActions action) : base(addressBook, action)
		{
			
		}		
		/// <summary>
		/// Orphans the item, killing it's parent and wiping out any attached event handlers
		/// </summary>
		public virtual void Orphan()
		{
			this.Changed = null;
			this.BeforeNameChanged = null;
			_parent = null;
		}
			public AddressBookTreeNode(AddressBook addressBook) : base(addressBook.Name, 1 /* image index */, 1 /* selected image index */)
			{
				_addressBook = addressBook;
			}
		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>
		/// Determines if the list contains the address book
		/// </summary>
		/// <param name="addressBook"></param>
		/// <returns></returns>
		public bool Contains(AddressBook addressBook)
		{
			if (addressBook == null)
				throw new ArgumentNullException("AddressBook", "A null reference to an AddressBook cannot be compared to items in the list.");

			return this.Contains(addressBook.Name);
		}
		/// <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;
			}	
		}