public override async Task <IActionResult> SelectShippingMethod(string shippingoption, IFormCollection form)
        {
            //validation
            if (_orderSettings.CheckoutDisabled)
            {
                return(RedirectToRoute("ShoppingCart"));
            }

            var cart = await _shoppingCartService.GetShoppingCartAsync(await _workContext.GetCurrentCustomerAsync(), ShoppingCartType.ShoppingCart, (await _storeContext.GetCurrentStoreAsync()).Id);

            if (!cart.Any())
            {
                return(RedirectToRoute("ShoppingCart"));
            }

            if (_orderSettings.OnePageCheckoutEnabled)
            {
                return(RedirectToRoute("CheckoutOnePage"));
            }

            if (await _customerService.IsGuestAsync(await _workContext.GetCurrentCustomerAsync()) && !_orderSettings.AnonymousCheckoutAllowed)
            {
                return(Challenge());
            }

            if (!(await _shoppingCartService.ShoppingCartRequiresShippingAsync(cart)))
            {
                await _genericAttributeService.SaveAttributeAsync <ShippingOption>(await _workContext.GetCurrentCustomerAsync(),
                                                                                   NopCustomerDefaults.SelectedShippingOptionAttribute, null, (await _storeContext.GetCurrentStoreAsync()).Id);

                return(RedirectToRoute("CheckoutPaymentMethod"));
            }

            //pickup point
            if (_shippingSettings.AllowPickupInStore && _orderSettings.DisplayPickupInStoreOnShippingMethodPage)
            {
                var pickupInStore = ParsePickupInStore(form);
                if (pickupInStore)
                {
                    var pickupOption = await ParsePickupOptionAsync(form);
                    await SavePickupOptionAsync(pickupOption);

                    return(RedirectToRoute("CheckoutPaymentMethod"));
                }

                //set value indicating that "pick up in store" option has not been chosen
                await _genericAttributeService.SaveAttributeAsync <PickupPoint>(await _workContext.GetCurrentCustomerAsync(), NopCustomerDefaults.SelectedPickupPointAttribute, null, (await _storeContext.GetCurrentStoreAsync()).Id);
            }

            //parse selected method
            if (string.IsNullOrEmpty(shippingoption))
            {
                return(RedirectToAction("ShippingMethod"));
            }
            var splittedOption = shippingoption.Split(new[] { "___" }, StringSplitOptions.RemoveEmptyEntries);

            if (splittedOption.Length != 2)
            {
                return(RedirectToAction("ShippingMethod"));
            }
            var selectedName = splittedOption[0];
            var shippingRateComputationMethodSystemName = splittedOption[1];

            //find it
            //performance optimization. try cache first
            var shippingOptions = await _genericAttributeService.GetAttributeAsync <List <ShippingOption> >(await _workContext.GetCurrentCustomerAsync(),
                                                                                                            NopCustomerDefaults.OfferedShippingOptionsAttribute, (await _storeContext.GetCurrentStoreAsync()).Id);

            if (shippingOptions == null || !shippingOptions.Any())
            {
                //not found? let's load them using shipping service
                shippingOptions = (await _shippingService.GetShippingOptionsAsync(cart, await _customerService.GetCustomerShippingAddressAsync(await _workContext.GetCurrentCustomerAsync()),
                                                                                  await _workContext.GetCurrentCustomerAsync(), shippingRateComputationMethodSystemName, (await _storeContext.GetCurrentStoreAsync()).Id)).ShippingOptions.ToList();
            }
            else
            {
                //loaded cached results. let's filter result by a chosen shipping rate computation method
                shippingOptions = shippingOptions.Where(so => so.ShippingRateComputationMethodSystemName.Equals(shippingRateComputationMethodSystemName, StringComparison.InvariantCultureIgnoreCase))
                                  .ToList();
            }

            var shippingOption = shippingOptions
                                 .Find(so => !string.IsNullOrEmpty(so.Name) && so.Name.Equals(selectedName, StringComparison.InvariantCultureIgnoreCase));

            if (shippingOption == null)
            {
                return(RedirectToAction("ShippingMethod"));
            }

            //save
            await _genericAttributeService.SaveAttributeAsync(await _workContext.GetCurrentCustomerAsync(), NopCustomerDefaults.SelectedShippingOptionAttribute, shippingOption, (await _storeContext.GetCurrentStoreAsync()).Id);

            await SendExternalShippingMethodRequestAsync();

            if (await _warrantyService.CartContainsWarrantiesAsync(cart))
            {
                return(RedirectToRoute("WarrantySelection"));
            }

            return(RedirectToRoute("CheckoutPaymentMethod"));
        }