internal List<RouteEntry> MapMvcAttributeRoutes(IEnumerable<Type> controllerTypes)
        {
            ControllerDescriptorCache descriptorsCache = new AsyncControllerActionInvoker().DescriptorCache;
            IEnumerable<ReflectedAsyncControllerDescriptor> descriptors = controllerTypes
                .Select(
                    type =>
                    descriptorsCache.GetDescriptor(type, innerType => new ReflectedAsyncControllerDescriptor(innerType), type))
                .Cast<ReflectedAsyncControllerDescriptor>();

            List<RouteEntry> routeEntries = new List<RouteEntry>();

            foreach (ReflectedAsyncControllerDescriptor controllerDescriptor in descriptors)
            {
                routeEntries.AddRange(MapMvcAttributeRoutes(controllerDescriptor));
            }

            routeEntries.Sort();

            return routeEntries;
        }
        internal static void AddRouteEntries(SubRouteCollection collector, IEnumerable<Type> controllerTypes,
            IInlineConstraintResolver constraintResolver)
        {
            ControllerDescriptorCache descriptorsCache = new AsyncControllerActionInvoker().DescriptorCache;
            IEnumerable<ReflectedAsyncControllerDescriptor> descriptors = controllerTypes
                .Select(
                    type =>
                    descriptorsCache.GetDescriptor(type, innerType => new ReflectedAsyncControllerDescriptor(innerType), type))
                .Cast<ReflectedAsyncControllerDescriptor>();

            foreach (ReflectedAsyncControllerDescriptor controllerDescriptor in descriptors)
            {
                AddRouteEntries(collector, controllerDescriptor, constraintResolver);
            }
        }
        private static IEnumerable<ReflectedAsyncControllerDescriptor> GetControllerDescriptors(IEnumerable<Type> controllerTypes)
        {
            Contract.Assert(controllerTypes != null);

            Func<Type, ControllerDescriptor> descriptorFactory = ReflectedAsyncControllerDescriptor.DefaultDescriptorFactory;
            ControllerDescriptorCache descriptorsCache = new AsyncControllerActionInvoker().DescriptorCache;

            return 
                controllerTypes
                .Select(type => descriptorsCache.GetDescriptor(type, descriptorFactory, type))
                .Cast<ReflectedAsyncControllerDescriptor>();
        }