private RouteInstance IsValid(string[] route, RouteDefinition routeDefinition, string lower)
		{
			if (routeDefinition.IsStatic)
			{
				if (lower.StartsWith(routeDefinition.RouteString))
				{
					return new RouteInstance(true, false);
				}
			}

			if (route.Length > routeDefinition.Url.Count)
			{
				var last = routeDefinition.Url[routeDefinition.Url.Count - 1];
				if (!last.IsParameter && !last.LowerRoute.StartsWith("*", StringComparison.OrdinalIgnoreCase))
				{
					return null;
				}
			}

			var routeInstance = new RouteInstance();
			var index = -1;
			while (index < (route.Length - 1))
			{
				index++;
				
				var routeValue = route[index];
				if (index >= routeDefinition.Url.Count)
				{
					return null;
				}
				var block = routeDefinition.Url[index];
				if (block.IsParameter)
				{
					if (block.LowerRoute.StartsWith("*", StringComparison.OrdinalIgnoreCase))
					{
						var paramName = block.LowerRoute.Substring(1);
						var paramValue = "/" + string.Join("/", route, index, route.Length - index).Trim('/');
						routeInstance.Parameters.Add(paramName, paramValue);
						index = route.Length;
					}
					else
					{
						routeInstance.Parameters.Add(block.Name, routeValue);
					}
				}
				else
				{
					if (string.Compare(routeValue, block.Name, StringComparison.OrdinalIgnoreCase) != 0) return null;
				}
			}
			while (index < (routeDefinition.Url.Count - 1))
			{
				index++;
				var block = routeDefinition.Url[index];
				if (block.IsParameter)
				{
					if (routeDefinition.Parameters.ContainsKey(block.Name))
					{
						var parameter = routeDefinition.Parameters[block.Name];
						if (parameter.Optional)
						{
							if (parameter.Value != null && parameter.Value.GetType() != typeof(RoutingParameter))
							{
								routeInstance.Parameters.Add(block.Name, parameter.Value);
							}
						}
						else if (parameter.Value != null)
						{
							routeInstance.Parameters.Add(block.Name, parameter.Value);
						}
						else
						{
							return null;
						}
					}
					else
					{
						return null;
					}
				}
				else
				{
					return null;
				}

			}
			foreach (var param in routeDefinition.Parameters)
			{
				if (!routeInstance.Parameters.ContainsKey(param.Key))
				{
					var paramReal = param.Value;
					if (paramReal.Value != null && paramReal.Value.GetType() != typeof(RoutingParameter))
					{
						routeInstance.Parameters.Add(param.Key, paramReal.Value);
					}
				}
			}
			return routeInstance;
		}
		public void IgnoreRoute(string route)
		{
			if (!route.StartsWith("~/"))
			{
				throw new Exception(string.Format("Invalid route '{0}' not starting with ~", route));
			}
			route = route.TrimStart('~');
			if (route.StartsWith("/"))
			{
				route = route.TrimStart('/');
			}

			var routeDefinition = new RouteDefinition(route, new Dictionary<string, object>(), false, true);
			CheckForConflicting(routeDefinition);
			_routeDefinitions.Add(routeDefinition);
		}
		public void MapRoute(string name,string url, dynamic defaults = null)
		{
			url = url.TrimStart('~');
			if (url.StartsWith("/"))
			{
				url = url.TrimStart('/');
			}

			var routeDefinition = new RouteDefinition(url, ReflectionUtils.ObjectToDictionary(defaults));
			CheckForConflicting(routeDefinition);
			_routeDefinitions.Add(routeDefinition);
		}
		private int IsMatching(RouteDefinition routeDefinition, Dictionary<string, object> pars, List<string> keys)
		{
			int weight = 0;
			for (int i = 0; i < keys.Count; i++)
			{
				var key = keys[i];
				if (!pars.ContainsKey(key))
				{
					var pardef = routeDefinition.Parameters[key];
					if (!pardef.Optional)
					{
						return 0;
					}
					if (pardef.Value != null)
					{
						weight++;
					}
				}
				else
				{
					weight++;
				}
			}
			return weight;
		}
		private void CheckForConflicting(RouteDefinition routeDefinition)
		{

		}