/// <summary>
        /// Initializes a new instance of the <see cref="LocationCardBuilder"/> class.
        /// </summary>
        /// <param name="apiKey">The geo spatial API key.</param>
        public LocationCardBuilder(string apiKey, LocationResourceManager resourceManager)
        {
            //SetField.NotNull(out this.apiKey, nameof(apiKey), apiKey);
            //SetField.NotNull(out this.resourceManager, nameof(resourceManager), resourceManager);
            if (string.IsNullOrEmpty(apiKey))
            {
                throw new ArgumentNullException(nameof(apiKey));
            }

            if (resourceManager == null)
            {
                throw new ArgumentNullException(nameof(resourceManager));
            }

            this.apiKey          = apiKey;
            this.resourceManager = resourceManager;

            if (!string.IsNullOrEmpty(this.apiKey) && this.apiKey.Length > 60)
            {
                useAzureMaps = false;
            }
        }
        public LocationDialog(
            string apiKey,
            string prompt,
            BotState state,
            string dialogId         = DefaultLocationDialogId,
            bool skipPrompt         = false,
            bool useAzureMaps       = true,
            LocationOptions options = LocationOptions.None,
            LocationRequiredFields requiredFields   = LocationRequiredFields.None,
            LocationResourceManager resourceManager = null) : base(dialogId)
        {
            resourceManager = resourceManager ?? new LocationResourceManager();

            if (!options.HasFlag(LocationOptions.SkipFavorites) && state == null)
            {
                throw new ArgumentNullException(nameof(state),
                                                "If LocationOptions.SkipFavorites is not used then BotState object must be " +
                                                "provided to allow for storing / retrieval of favorites");
            }

            var favoriteLocations = state.CreateProperty <List <FavoriteLocation> >($"{nameof(LocationDialog)}.Favorites");
            var favoritesManager  = new FavoritesManager(favoriteLocations);

            IGeoSpatialService geoSpatialService;

            if (useAzureMaps)
            {
                geoSpatialService = new AzureMapsSpatialService(apiKey);
            }
            else
            {
                geoSpatialService = new BingGeoSpatialService(apiKey);
            }

            InitialDialogId = dialogId;

            AddDialog(new ChoicePrompt(PromptDialogIds.Choice));
            AddDialog(new TextPrompt(PromptDialogIds.Text));
            AddDialog(new ConfirmPrompt(PromptDialogIds.Confirm));

            AddDialog(new WaterfallDialog(InitialDialogId, new WaterfallStep[]
            {
                async(dc, cancellationToken) =>
                {
                    if (options.HasFlag(LocationOptions.SkipFavorites) ||
                        !favoritesManager.GetFavorites(dc.Context).Result.Any())
                    {
                        var isFacebookChannel = StringComparer.OrdinalIgnoreCase.Equals(
                            dc.Context.Activity.ChannelId, "facebook");

                        if (options.HasFlag(LocationOptions.UseNativeControl) && isFacebookChannel)
                        {
                            return(await dc.BeginDialogAsync(DialogIds.LocationRetrieverFacebookDialog));
                        }

                        return(await dc.BeginDialogAsync(DialogIds.LocationRetrieverRichDialog));
                    }

                    return(await dc.BeginDialogAsync(DialogIds.HeroStartCardDialog));
                },
                async(dc, cancellationToken) =>
                {
                    var selectedLocation = (Bing.Location)dc.Result;
                    dc.Values[StepContextKeys.SelectedLocation] = selectedLocation;

                    if (options.HasFlag(LocationOptions.SkipFinalConfirmation))
                    {
                        return(await dc.NextAsync());
                    }

                    await dc.PromptAsync(PromptDialogIds.Confirm,
                                         new PromptOptions()
                    {
                        Prompt = new Activity
                        {
                            Type = ActivityTypes.Message,
                            Text = string.Format(resourceManager.ConfirmationAsk,
                                                 selectedLocation.GetFormattedAddress(resourceManager.AddressSeparator))
                        },
                        RetryPrompt = new Activity
                        {
                            Type = ActivityTypes.Message,
                            Text = resourceManager.ConfirmationInvalidResponse
                        }
                    });

                    return(EndOfTurn);
                },
                async(dc, cancellationToken) =>
                {
                    if (dc.Result is bool result && !result)
                    {
                        await dc.Context.SendActivityAsync(resourceManager.ResetPrompt);
                        return(await dc.ReplaceDialogAsync(InitialDialogId));
                    }

                    if (!options.HasFlag(LocationOptions.SkipFavorites))
                    {
                        return(await dc.BeginDialogAsync(DialogIds.AddToFavoritesDialog,
                                                         new AddToFavoritesDialogOptions()
                        {
                            Location = (Bing.Location)dc.Values[StepContextKeys.SelectedLocation]
                        }
                                                         ));
                    }
                    else
                    {
                        await dc.NextAsync();
                    }

                    return(EndOfTurn);
                },
                async(dc, cancellationToken) =>
                {
                    var selectedLocation = (Bing.Location)dc.Values[StepContextKeys.SelectedLocation];
                    return(await dc.EndDialogAsync(CreatePlace(selectedLocation)));
                }
            }));