public bool Matches(ResolvedRouteValues values)
 {
     for (var i = 0; i < _parts.Length; i++)
     {
         if (!values.ContainsKey(_parts[i]))
         {
             return(false);
         }
     }
     return(true);
 }
        public string ToUrl(ResolvedRouteValues values)
        {
            if (values.Count == 0 && _tokenized.Length == 1 && _tokenized[0][0] != '@')
            {
                return(_tokenized[0]);
            }

            var sb = new StringBuilder(_length);
            var i  = 0;

            for (var index = 0; index < _tokenized.Length; index++)
            {
                var t = _tokenized[index];
                if (t[0] == '@')
                {
                    if (values.TryGetValue(_parts[i], out var v))
                    {
                        if (string.IsNullOrEmpty(v))
                        {
                            throw new Exception($"'{_parts[i]}' defined but is empty on url: {_route}");
                        }

                        sb.Append(Uri.EscapeDataString(v));
                    }
                    else
                    {
                        throw new Exception($"No value provided for '{_parts[i]}' on url: {_route}");
                    }

                    i++;
                }
                else
                {
                    sb.Append(t);
                }
            }
            return(sb.ToString());
        }