Inheritance: ISerializable
		public void Add(ComponentName name, IHandler handler)
		{
			if (root == null)
			{
				root = new TreeNode(name, handler);
				count++;
				return;
			}

			TreeNode current = root;

			while (true)
			{
				int cmp = String.Compare(current.CompName.Service, name.Service);

				if (cmp < 0)
				{
					if (current.Left != null)
					{
						current = current.Left;
					}
					else
					{
						current.Left = new TreeNode(name, handler);
						count++;
						break;
					}
				}
				else if (cmp > 0)
				{
					if (current.Right != null)
					{
						current = current.Right;
					}
					else
					{
						current.Right = new TreeNode(name, handler);
						count++;
						break;
					}
				}
				else
				{
					current.AddSibling(new TreeNode(name, handler));
					count++;
					break;
				}
			}
		}
		public bool Contains(ComponentName name)
		{
			return FindNode(name) != null;
		}
		public void Remove(ComponentName name)
		{
			Remove(FindNode(name));
		}
		public TreeNode FindBestMatch(ComponentName name)
		{
			if ("*".Equals(name.LiteralProperties))
			{
				return this;
			}
			else if (name.LiteralProperties == null || name.LiteralProperties == string.Empty)
			{
				return FindWithEmptyProperties();
			}
			else
			{
				return FindBestMatchByProperties(name);
			}
		}
		private TreeNode FindBestMatchByProperties(ComponentName name)
		{
			TreeNode current = this;

			while (current != null)
			{
				bool selected = true;

				foreach (DictionaryEntry entry in name.Properties)
				{
					String value = current.CompName.Properties[entry.Key] as String;

					if (value == null || !value.Equals(entry.Value))
					{
						selected = false;
						break;
					}
				}

				if (selected) break;

				current = current.NextSibling;
			}

			return current;
		}
		internal TreeNode FindNode(ComponentName name)
		{
			if (root == null) return null;

			TreeNode current = root;

			while (true)
			{
				int cmp = String.Compare(current.CompName.Service, name.Service);

				if (cmp < 0)
				{
					if (current.Left != null)
					{
						current = current.Left;
					}
					else
					{
						return null;
					}
				}
				else if (cmp > 0)
				{
					if (current.Right != null)
					{
						current = current.Right;
					}
					else
					{
						return null;
					}
				}
				else
				{
					return current.FindBestMatch(name);
				}
			}
		}
		public TreeNode(ComponentName compName, IHandler handler)
		{
			if (compName == null) throw new ArgumentNullException("compName");
			if (handler == null) throw new ArgumentNullException("handler");

			this.compName = compName;
			this.handler = handler;
		}
		public IHandler[] GetHandlers(ComponentName name)
		{
			TreeNode node = FindNode(name);

			if (node != null)
			{
				ArrayList list = new ArrayList();

				list.Add(node.Handler);

				while (node.NextSibling != null)
				{
					node = node.NextSibling.FindBestMatch(name);

					list.Add(node.Handler);
				}

				return (IHandler[])list.ToArray(typeof(IHandler));
			}

			return null;
		}
		public IHandler GetHandler(ComponentName name)
		{
			TreeNode node = FindNode(name);

			return node != null ? node.Handler : null;
		}
		private TreeNode FindBestMatchByProperties(ComponentName name)
		{
			TreeNode current = this;

			while (current != null)
			{
				bool selected = true;

				foreach (KeyValuePair<string, string> entry in name.Properties)
				{
					string value;
					current.CompName.Properties.TryGetValue(entry.Key, out value);
					if (value == null || !value.Equals(entry.Value))
					{
						selected = false;
						break;
					}
				}

				if (selected) break;

				current = current.NextSibling;
			}

			return current;
		}
		public TreeNode FindBestMatch(ComponentName name)
		{
			if ("*".Equals(name.LiteralProperties))
			{
				return this;
			}
			if (string.IsNullOrEmpty(name.LiteralProperties))
			{
				return FindWithEmptyProperties();
			}
			return FindBestMatchByProperties(name);
		}
		public IHandler[] GetHandlers(ComponentName name)
		{
			TreeNode node = FindNode(name);

			if (node != null)
			{
				var list = new List<IHandler>();

				list.Add(node.Handler);

				while (node.NextSibling != null)
				{
					node = node.NextSibling.FindBestMatch(name);

					list.Add(node.Handler);
				}

				return list.ToArray();
			}

			return null;
		}