/// <summary>
		/// Processes one attribute route
		/// </summary>
		/// <param name="action">Action to process</param>
		/// <returns>Route information</returns>
		private AttributeRouteInfo ProcessAttributeRoute(ControllerActionDescriptor action)
		{
			var constraint = action.RouteConstraints
				.FirstOrDefault(c => c.RouteKey == AttributeRouting.RouteGroupKey);
			if (constraint == null ||
				constraint.KeyHandling != RouteKeyHandling.RequireKey ||
				constraint.RouteValue == null)
			{
				// This can happen if an ActionDescriptor has a route template, but doesn't have one of our
				// special route group constraints. This is a good indication that the user is using a 3rd party
				// routing system, or has customized their ADs in a way that we can no longer understand them.
				//
				// We just treat this case as an 'opt-out' of our attribute routing system.
				return null;
			}

			var template = TemplateParser.Parse(action.AttributeRouteInfo.Template);

			var info = new AttributeRouteInfo
			{
				Constraints = GetConstraints(action.AttributeRouteInfo.Template, template),
                Defaults = GetDefaults(action, template),
                Optional = new List<string>(),
				Order = action.AttributeRouteInfo.Order,
				Precedence = AttributeRoutePrecedence.Compute(template),
			};
			_parser.Parse(template, info);

			return info;
		}
 public AttributeRouteInfoValues(AttributeRouteInfo inner)
 {
     Template = inner?.Template;
     Order = inner?.Order;
     Name = inner?.Name;
 }