/// <summary>
        /// An event handler which rebuilds <see cref="parsedPattern"/> after regex constraint changed.
        /// </summary>
        /// <param name="sender">The constraint which fired the event.</param>
        /// <param name="e">An <see cref="System.EventArgs"/> that contains no event data.</param>
        protected void OnRegexChanged(object sender, EventArgs e)
        {
            var fullPathSegment = ParseSegments(Url);
            var urlMatch        = BuildRegex(fullPathSegment);

            this.parsedPattern = new ParsedRoutePattern(urlMatch, fullPathSegment);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ElasticRoute"/> class.
        /// </summary>
        /// <param name="url">The URL pattern.</param>
        /// <param name="routeHandler">The route handler.</param>
        /// <param name="constraints">The route constraints.</param>
        /// <param name="incomingDefaults">The incoming request default route values.</param>
        /// <param name="outgoingDefaults">The URL generation default route values.</param>
        /// <param name="projections">The route values projections.</param>
        /// <param name="dataTokens">The data tokens.</param>
        public ElasticRoute(string url, IRouteHandler routeHandler,
                            RouteValueDictionary constraints      = null,
                            RouteValueDictionary incomingDefaults = null,
                            RouteValueDictionary outgoingDefaults = null,
                            IDictionary <string, IRouteValueProjection> projections = null,
                            RouteValueDictionary dataTokens = null)
        {
            this.Url              = url;
            this.RouteHandler     = routeHandler;
            this.IncomingDefaults = incomingDefaults ?? EmptyValues();
            this.OutgoingDefaults = outgoingDefaults ?? EmptyValues();
            this.Constraints      = constraints ?? EmptyValues();
            this.Projections      = projections ?? new Dictionary <string, IRouteValueProjection>();
            this.DataTokens       = dataTokens ?? EmptyValues();

            this.routeWrapper = new RouteWrapper(this);

            foreach (var constraint in Constraints.Values.OfType <IDynamicRegexRouteConstraint>())
            {
                constraint.RegexChanged += OnRegexChanged;
            }

            var fullPathSegment = ParseSegments(url);
            var urlMatch        = BuildRegex(fullPathSegment);

            this.parsedPattern = new ParsedRoutePattern(urlMatch, fullPathSegment);

            this.RequiredParameters = new HashSet <string>(fullPathSegment.RequiredParameters.Select(p => p.Name), StringComparer.InvariantCultureIgnoreCase);
            this.AllParameters      = new HashSet <string>(fullPathSegment.Parameters, StringComparer.InvariantCultureIgnoreCase);
        }