Default implementation of IControllerTree. Represents an binary tree of registered controllers.

It is used by the controller factory to resolve a controller instance based on the specified area (which is optional) and controller name

IControllerTree Castle.MonoRail.Framework.Services.AbstractControllerFactory
Inheritance: IControllerTree
		public void AddingController_RaisesNotifcationEvent() 
		{
			DefaultControllerTree tree = new DefaultControllerTree();
			bool eventRaised = false;
			tree.ControllerAdded += delegate { eventRaised = true; };
			tree.AddController("clients","home",typeof(ClientHomeController));
			Assert.IsTrue(eventRaised);
		}
		public void EmptyArea()
		{
			DefaultControllerTree tree = new DefaultControllerTree();
			tree.AddController("", "home", typeof(HomeController));
			tree.AddController("", "contact", typeof(ContactController));
			tree.AddController("", "cart", typeof(CartController));

			Assert.AreEqual( typeof(HomeController), tree.GetController("", "home") );
			Assert.AreEqual( typeof(ContactController), tree.GetController("", "contact") );
			Assert.AreEqual( typeof(CartController), tree.GetController("", "cart") );
		}
        /// <summary>
        /// Register a controller on the tree. If the specified
        /// area name matches the current node, the controller is
        /// register on the node itself, otherwise on the right or
        /// on the left node.
        /// </summary>
        /// <remarks>
        /// Note that the controller is an <c>object</c>. That allows
        /// different implementation of a controller factory to register
        /// different representation of what a controller is (a name, a descriptor etc)
        /// </remarks>
        /// <param name="areaName">The area name, or <c>String.Empty</c></param>
        /// <param name="controllerName">The controller name</param>
        /// <param name="controller">The controller representation</param>
        public void AddController(String areaName, String controllerName, Type controller)
        {
            if (areaName == null)
            {
                throw new ArgumentNullException("areaName");
            }
            if (controllerName == null)
            {
                throw new ArgumentNullException("controllerName");
            }
            if (controller == null)
            {
                throw new ArgumentNullException("controller");
            }

            var cmp = String.Compare(areaName, area, true);

            if (cmp == 0)
            {
                // If it's the same area, register the controller
                controllers[controllerName] = controller;
            }
            else
            {
                // Otherwise, check if the controller should be registered
                // on the left or on the right

                DefaultControllerTree node;

                if (cmp < 0)
                {
                    if (left == null)
                    {
                        left = new DefaultControllerTree(areaName);
                    }
                    node = left;
                }
                else
                {
                    if (right == null)
                    {
                        right = new DefaultControllerTree(areaName);
                    }
                    node = right;
                }

                node.AddController(areaName, controllerName, controller);
                OnControllerAdded(areaName, controllerName, controller);
            }
        }
		public void FewAreas()
		{
			DefaultControllerTree tree = new DefaultControllerTree();

			tree.AddController("", "home", typeof(HomeController));
			tree.AddController("", "contact", typeof(ContactController));
			tree.AddController("", "cart", typeof(CartController));
			tree.AddController("clients", "home", typeof(ClientHomeController));
			tree.AddController("clients", "contact", typeof(ClientContactController));
			tree.AddController("clients", "cart", typeof(ClientCartController));
			tree.AddController("lists", "home", typeof(ListController));

			Assert.AreEqual( typeof(HomeController), tree.GetController("", "home") );
			Assert.AreEqual( typeof(ContactController), tree.GetController("", "contact") );
			Assert.AreEqual( typeof(CartController), tree.GetController("", "cart") );

			Assert.AreEqual( typeof(ClientHomeController), tree.GetController("clients", "home") );
			Assert.AreEqual( typeof(ClientContactController), tree.GetController("clients", "contact") );
			Assert.AreEqual( typeof(ClientCartController), tree.GetController("clients", "cart") );

			Assert.AreEqual( typeof(ListController), tree.GetController("lists", "home") );
		}
        public void Should_AddTwoUrls_WhenControllerAddedToTree()
        {
            MockRepository mocks = new MockRepository();

            IUrlTokenizer tokenizer = mocks.DynamicMock<IUrlTokenizer>();
            IControllerTree controllerTree = new DefaultControllerTree();

            StubServiceProvider serviceProvider = new StubServiceProvider(tokenizer, controllerTree);

            DefaultUrlProvider provider = new DefaultUrlProvider();
            provider.Service(serviceProvider);

            using (mocks.Record())
            {
                tokenizer.AddDefaultRule("area/controller.rails", "area", "controller", "collection");
                tokenizer.AddDefaultRule("/area/controller.rails", "area","controller", "collection");
            }

            using (mocks.Playback())
            {
                controllerTree.AddController("area", "controller", typeof(SampleRestController));
            }
        }
		/// <summary>
		/// Register a controller on the tree. If the specified
		/// area name matches the current node, the controller is
		/// register on the node itself, otherwise on the right or 
		/// on the left node.
		/// </summary>
		/// <remarks>
		/// Note that the controller is an <c>object</c>. That allows
		/// different implementation of a controller factory to register
		/// different representation of what a controller is (a name, a descriptor etc)
		/// </remarks>
		/// <param name="areaName">The area name, or <c>String.Empty</c></param>
		/// <param name="controllerName">The controller name</param>
		/// <param name="controller">The controller representation</param>
		public void AddController(String areaName, String controllerName, Type controller)
		{
			if (areaName == null) throw new ArgumentNullException("areaName");
			if (controllerName == null) throw new ArgumentNullException("controllerName");
			if (controller == null) throw new ArgumentNullException("controller");

			var cmp = String.Compare(areaName, area, true);

			if (cmp == 0)
			{
				// If it's the same area, register the controller
				controllers[controllerName] = controller;
			}
			else
			{
				// Otherwise, check if the controller should be registered
				// on the left or on the right

				DefaultControllerTree node;

				if (cmp < 0)
				{
					if (left == null)
					{
						left = new DefaultControllerTree(areaName);
					}
					node = left;
				}
				else
				{
					if (right == null)
					{
						right = new DefaultControllerTree(areaName);
					}
					node = right;
				}

				node.AddController(areaName, controllerName, controller);
				OnControllerAdded(areaName, controllerName, controller);
			}
		}