private static Type GetControllerTypeFromDirectRoute(RouteData routeData)
        {
            Contract.Assert(routeData != null);

            var matchingRouteDatas = routeData.GetDirectRouteMatches();

            List<Type> controllerTypes = new List<Type>();
            foreach (var directRouteData in matchingRouteDatas)
            {
                if (directRouteData != null)
                {
                    Type controllerType = directRouteData.GetTargetControllerType();
                    if (controllerType == null)
                    {
                        // We don't expect this to happen, but it could happen if some code messes with the 
                        // route data tokens and removes the key we're looking for. 
                        throw new InvalidOperationException(MvcResources.DirectRoute_MissingControllerType);
                    }

                    if (!controllerTypes.Contains(controllerType))
                    {
                        controllerTypes.Add(controllerType);
                    }
                }
            }

            // We only want to handle the case where all matched direct routes refer to the same controller.
            // Handling the multiple-controllers case would put attribute routing down a totally different
            // path than traditional routing.
            if (controllerTypes.Count == 0)
            {
                return null;
            }
            else if (controllerTypes.Count == 1)
            {
                return controllerTypes[0];
            }
            else
            {
                throw CreateDirectRouteAmbiguousControllerException(controllerTypes);
            }
        }