public RouteValueDictionary Match(string virtualPath, RouteValueDictionary defaultValues)
        {
            IList <string> source = RouteParser.SplitUrlToPathSegmentStrings(virtualPath);

            if (defaultValues == null)
            {
                defaultValues = new RouteValueDictionary();
            }
            RouteValueDictionary matchedValues = new RouteValueDictionary();
            bool flag  = false;
            bool flag2 = false;

            for (int i = 0; i < this.PathSegments.Count; i++)
            {
                PathSegment segment = this.PathSegments[i];
                if (source.Count <= i)
                {
                    flag = true;
                }
                string a = flag ? null : source[i];
                if (segment is SeparatorPathSegment)
                {
                    if (!flag && !string.Equals(a, "/", StringComparison.Ordinal))
                    {
                        return(null);
                    }
                }
                else
                {
                    ContentPathSegment contentPathSegment = segment as ContentPathSegment;
                    if (contentPathSegment != null)
                    {
                        if (contentPathSegment.IsCatchAll)
                        {
                            this.MatchCatchAll(contentPathSegment, source.Skip <string>(i), defaultValues, matchedValues);
                            flag2 = true;
                        }
                        else if (!this.MatchContentPathSegment(contentPathSegment, a, defaultValues, matchedValues))
                        {
                            return(null);
                        }
                    }
                }
            }
            if (!flag2 && (this.PathSegments.Count < source.Count))
            {
                for (int j = this.PathSegments.Count; j < source.Count; j++)
                {
                    if (!RouteParser.IsSeparator(source[j]))
                    {
                        return(null);
                    }
                }
            }
            if (defaultValues != null)
            {
                foreach (KeyValuePair <string, object> pair in defaultValues)
                {
                    if (!matchedValues.ContainsKey(pair.Key))
                    {
                        matchedValues.Add(pair.Key, pair.Value);
                    }
                }
            }
            return(matchedValues);
        }
        public RouteValueDictionary Match(string virtualPath, RouteValueDictionary defaultValues)
        {
            IList <string> requestPathSegments = RouteParser.SplitUrlToPathSegmentStrings(virtualPath);

            if (defaultValues == null)
            {
                defaultValues = new RouteValueDictionary();
            }

            RouteValueDictionary matchedValues = new RouteValueDictionary();

            // This flag gets set once all the data in the URL has been parsed through, but
            // the route we're trying to match against still has more parts. At this point
            // we'll only continue matching separator characters and parameters that have
            // default values.
            bool ranOutOfStuffToParse = false;

            // This value gets set once we start processing a catchall parameter (if there is one
            // at all). Once we set this value we consume all remaining parts of the URL into its
            // parameter value.
            bool usedCatchAllParameter = false;

            for (int i = 0; i < PathSegments.Count; i++)
            {
                PathSegment pathSegment = PathSegments[i];

                if (requestPathSegments.Count <= i)
                {
                    ranOutOfStuffToParse = true;
                }

                string requestPathSegment = ranOutOfStuffToParse ? null : requestPathSegments[i];

                if (pathSegment is SeparatorPathSegment)
                {
                    if (ranOutOfStuffToParse)
                    {
                        // If we're trying to match a separator in the route but there's no more content, that's OK
                    }
                    else
                    {
                        if (!String.Equals(requestPathSegment, "/", StringComparison.Ordinal))
                        {
                            return(null);
                        }
                    }
                }
                else
                {
                    ContentPathSegment contentPathSegment = pathSegment as ContentPathSegment;
                    if (contentPathSegment != null)
                    {
                        if (contentPathSegment.IsCatchAll)
                        {
                            Debug.Assert(i == (PathSegments.Count - 1), "If we're processing a catch-all, we should be on the last route segment.");
                            MatchCatchAll(contentPathSegment, requestPathSegments.Skip(i), defaultValues, matchedValues);
                            usedCatchAllParameter = true;
                        }
                        else
                        {
                            if (!MatchContentPathSegment(contentPathSegment, requestPathSegment, defaultValues, matchedValues))
                            {
                                return(null);
                            }
                        }
                    }
                    else
                    {
                        Debug.Fail("Invalid path segment type");
                    }
                }
            }

            if (!usedCatchAllParameter)
            {
                if (PathSegments.Count < requestPathSegments.Count)
                {
                    // If we've already gone through all the parts defined in the route but the URL
                    // still contains more content, check that the remaining content is all separators.
                    for (int i = PathSegments.Count; i < requestPathSegments.Count; i++)
                    {
                        if (!RouteParser.IsSeparator(requestPathSegments[i]))
                        {
                            return(null);
                        }
                    }
                }
            }

            // Copy all remaining default values to the route data
            if (defaultValues != null)
            {
                foreach (var defaultValue in defaultValues)
                {
                    if (!matchedValues.ContainsKey(defaultValue.Key))
                    {
                        matchedValues.Add(defaultValue.Key, defaultValue.Value);
                    }
                }
            }

            return(matchedValues);
        }