/// <summary>
        /// Creates localized routes
        /// You can override this method to change the source of localized routes - DB, File,...
        /// </summary>
        /// <returns>Localized routes</returns>
        protected virtual async Task <IEnumerable <LocalizedRoute> > GetRoutesAsync()
        {
            /*
             *
             *  LocalizedRouteController -  LocalizedRouteAction
             *  LocalizedRouteController -  RouteAction
             *  LocalizedRouteController -  OriginalAction
             *  RouteController - LocalizedRouteAction
             *  OriginalController - LocalizedRouteAction
             *
             */

            var localizedRoutes = new List <LocalizedRoute>();

            foreach (var routeDescriptor in _controllerActionDescriptorProvider.Get())
            {
                routeDescriptor.RouteValues.TryGetValue("controller", out var controller);
                routeDescriptor.RouteValues.TryGetValue("action", out var action);

                var controllerLocalizedRouteAttributes = GetControllersAttribute <LocalizedRouteAttribute>(routeDescriptor);
                var controllerRouteAttributes          = GetControllersAttribute <RouteAttribute>(routeDescriptor);
                var actionLocalizedRouteAttributes     = GetMethodsAttribute <LocalizedRouteAttribute>(routeDescriptor);
                var actionRouteAttributes = GetMethodsAttribute <RouteAttribute>(routeDescriptor);

                foreach (var controllerLocalizedRouteAttribute in controllerLocalizedRouteAttributes)
                {
                    var actionLocalizedRouteAttribute = actionLocalizedRouteAttributes
                                                        .FirstOrDefault(s => s.Culture == controllerLocalizedRouteAttribute.Culture);

                    if (actionLocalizedRouteAttribute != null)
                    {
                        AddLocalizedRoute(controllerLocalizedRouteAttribute.Culture, controllerLocalizedRouteAttribute.Template, actionLocalizedRouteAttribute.Template);
                    }
                    else if (actionRouteAttributes.Any())
                    {
                        foreach (var actionRouteAttribute in actionRouteAttributes)
                        {
                            AddLocalizedRoute(controllerLocalizedRouteAttribute.Culture, controllerLocalizedRouteAttribute.Template, actionRouteAttribute.Template);
                        }
                    }
                    else
                    {
                        AddLocalizedRoute(controllerLocalizedRouteAttribute.Culture, controllerLocalizedRouteAttribute.Template, action);
                    }
                }

                foreach (var controllerRouteAttribute in controllerRouteAttributes)
                {
                    foreach (var actionLocalizedRouteAttribute in actionLocalizedRouteAttributes)
                    {
                        AddLocalizedRoute(actionLocalizedRouteAttribute.Culture, controllerRouteAttribute.Template, actionLocalizedRouteAttribute.Template);
                    }

                    foreach (var actionRouteAttribute in actionRouteAttributes)
                    {
                        foreach (var culture in _supportedCultures)
                        {
                            AddLocalizedRoute(culture.Name, controllerRouteAttribute.Template, actionRouteAttribute.Template);
                        }
                    }

                    if (!actionRouteAttributes.Any() && !actionLocalizedRouteAttributes.Any())
                    {
                        foreach (var culture in _supportedCultures)
                        {
                            AddLocalizedRoute(culture.Name, controllerRouteAttribute.Template, action);
                        }
                    }
                }

                if (!controllerLocalizedRouteAttributes.Any() && !controllerRouteAttributes.Any())
                {
                    foreach (var actionLocalizedRouteAttribute in actionLocalizedRouteAttributes)
                    {
                        AddLocalizedRoute(actionLocalizedRouteAttribute.Culture, controller, actionLocalizedRouteAttribute.Template);
                    }

                    foreach (var actionRouteAttribute in actionRouteAttributes)
                    {
                        foreach (var culture in _supportedCultures)
                        {
                            AddLocalizedRoute(culture.Name, controller, actionRouteAttribute.Template);
                        }
                    }

                    if (!actionLocalizedRouteAttributes.Any() && !actionRouteAttributes.Any())
                    {
                        foreach (var culture in _supportedCultures)
                        {
                            AddLocalizedRoute(culture.Name, controller, action);
                        }
                    }
                }

                void AddLocalizedRoute(string cultureName, string controllerName, string actionName)
                {
                    localizedRoutes.Add(LocalizedRoute.Create(cultureName,
                                                              RouteInformation.Create(controller, action),
                                                              RouteInformation.Create(controllerName, actionName)));
                }
            }

            return(localizedRoutes);
        }