/// <summary>
        /// Pick image folder and detect all faces in these images
        /// </summary>
        /// <param name="sender">Event sender</param>
        /// <param name="e">Event arguments</param>
        private async void FolderPicker_Click(object sender, RoutedEventArgs e)
        {
            bool groupExists = false;

            MainWindow mainWindow        = Window.GetWindow(this) as MainWindow;
            string     subscriptionKey   = mainWindow._scenariosControl.SubscriptionKey;
            string     endpoint          = mainWindow._scenariosControl.SubscriptionEndpoint;
            var        faceServiceClient = new FaceServiceClient(subscriptionKey, endpoint);

            try
            {
                MainWindow.Log("Request: Large Face List {0} will be used to build a person database. Checking whether the large face list exists.", this._largeFaceListId);

                await faceServiceClient.GetLargeFaceListAsync(this._largeFaceListId);

                groupExists = true;
                MainWindow.Log("Response: Face List {0} exists.", this._largeFaceListId);
            }
            catch (FaceAPIException ex)
            {
                if (ex.ErrorCode != "LargeFaceListNotFound")
                {
                    MainWindow.Log("Response: {0}. {1}", ex.ErrorCode, ex.ErrorMessage);
                    return;
                }
                else
                {
                    MainWindow.Log("Response: Large Face List {0} did not exist previously.", this._largeFaceListId);
                }
            }

            if (groupExists)
            {
                var cleanLargeFaceList = System.Windows.MessageBox.Show(string.Format("Requires a clean up for large face list \"{0}\" before setting up a new large face list. Click OK to proceed, large face list \"{0}\" will be cleared.", this._largeFaceListId), "Warning", MessageBoxButton.OKCancel);
                if (cleanLargeFaceList == MessageBoxResult.OK)
                {
                    await faceServiceClient.DeleteLargeFaceListAsync(this._largeFaceListId);

                    this._largeFaceListId = Guid.NewGuid().ToString();
                }
                else
                {
                    return;
                }
            }

            OpenFaceButton.IsEnabled = false;
            // Show folder picker
            System.Windows.Forms.FolderBrowserDialog dlg = new System.Windows.Forms.FolderBrowserDialog();
            var result = dlg.ShowDialog();

            bool forceContinue = false;


            if (result == System.Windows.Forms.DialogResult.OK)
            {
                // Enumerate all ".jpg" files in the folder, call detect
                List <Task> tasks = new List <Task>();

                FacesCollection.Clear();
                TargetFaces.Clear();
                FindSimilarMatchPersonCollection.Clear();
                FindSimilarMatchFaceCollection.Clear();
                SelectedFile = null;

                // Set the suggestion count is intent to minimum the data preparation step only,
                // it's not corresponding to service side constraint
                const int SuggestionCount = 10;
                int       processCount    = 0;

                MainWindow.Log("Request: Preparing, detecting faces in chosen folder.");

                await faceServiceClient.CreateLargeFaceListAsync(this._largeFaceListId, this._largeFaceListId, "large face list for sample");

                var imageList =
                    new ConcurrentBag <string>(
                        Directory.EnumerateFiles(dlg.SelectedPath, "*.*", SearchOption.AllDirectories)
                        .Where(s => s.ToLower().EndsWith(".jpg") || s.ToLower().EndsWith(".png") || s.ToLower().EndsWith(".bmp") || s.ToLower().EndsWith(".gif")));

                string img;
                int    invalidImageCount = 0;
                while (imageList.TryTake(out img))
                {
                    tasks.Add(Task.Factory.StartNew(
                                  async(obj) =>
                    {
                        var imgPath = obj as string;
                        // Call detection
                        using (var fStream = File.OpenRead(imgPath))
                        {
                            try
                            {
                                var faces =
                                    await faceServiceClient.AddFaceToLargeFaceListAsync(this._largeFaceListId, fStream);
                                return(new Tuple <string, ClientContract.AddPersistedFaceResult>(imgPath, faces));
                            }
                            catch (FaceAPIException ex)
                            {
                                // if operation conflict, retry.
                                if (ex.ErrorCode.Equals("ConcurrentOperationConflict"))
                                {
                                    imageList.Add(imgPath);
                                    return(null);
                                }
                                // if operation cause rate limit exceed, retry.
                                else if (ex.ErrorCode.Equals("RateLimitExceeded"))
                                {
                                    imageList.Add(imgPath);
                                    return(null);
                                }
                                else if (ex.ErrorMessage.Contains("more than 1 face in the image."))
                                {
                                    Interlocked.Increment(ref invalidImageCount);
                                }
                                // Here we simply ignore all detection failure in this sample
                                // You may handle these exceptions by check the Error.Error.Code and Error.Message property for ClientException object
                                return(new Tuple <string, ClientContract.AddPersistedFaceResult>(imgPath, null));
                            }
                        }
                    },
                                  img).Unwrap().ContinueWith((detectTask) =>
                    {
                        var res = detectTask?.Result;
                        if (res?.Item2 == null)
                        {
                            return;
                        }

                        // Update detected faces on UI
                        this.Dispatcher.Invoke(
                            new Action
                            <ObservableCollection <Face>, string, ClientContract.AddPersistedFaceResult>(
                                UIHelper.UpdateFace),
                            FacesCollection,
                            res.Item1,
                            res.Item2);
                    }));

                    processCount++;

                    if (processCount >= SuggestionCount && !forceContinue)
                    {
                        var continueProcess =
                            System.Windows.Forms.MessageBox.Show(
                                "The images loaded have reached the recommended count, may take long time if proceed. Would you like to continue to load images?",
                                "Warning", System.Windows.Forms.MessageBoxButtons.YesNo);
                        if (continueProcess == System.Windows.Forms.DialogResult.Yes)
                        {
                            forceContinue = true;
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (tasks.Count >= _maxConcurrentProcesses || imageList.IsEmpty)
                    {
                        await Task.WhenAll(tasks);

                        tasks.Clear();
                    }
                }
                if (invalidImageCount > 0)
                {
                    MainWindow.Log("Warning: more or less than one face is detected in {0} images, can not add to large face list.", invalidImageCount);
                }
                MainWindow.Log("Response: Success. Total {0} faces are detected.", FacesCollection.Count);

                try
                {
                    // Start train large face list.
                    MainWindow.Log("Request: Training Large Face List \"{0}\"", this._largeFaceListId);
                    await faceServiceClient.TrainLargeFaceListAsync(this._largeFaceListId);

                    // Wait until train completed
                    while (true)
                    {
                        await Task.Delay(1000);

                        var status = await faceServiceClient.GetLargeFaceListTrainingStatusAsync(this._largeFaceListId);

                        MainWindow.Log("Response: {0}. Large Face List \"{1}\" training process is {2}", "Success", this._largeFaceListId, status.Status);
                        if (status.Status != Contract.Status.Running)
                        {
                            break;
                        }
                    }
                    OpenFaceButton.IsEnabled = true;
                }
                catch (FaceAPIException ex)
                {
                    MainWindow.Log("Response: {0}. {1}", ex.ErrorCode, ex.ErrorMessage);
                }
            }

            GC.Collect();
        }