private async Task AnalyzeTextAsync()
        {
            try
            {
                this.progressControl.IsActive = true;
                DisplayProcessingUI();

                string input = this.inputText.Text;
                var    detectedLanguageTask       = TextAnalyticsHelper.DetectLanguageAsync(input);
                var    detectedKeyPhrasesTask     = TextAnalyticsHelper.ExtractKeyPhrasesAsync(input);
                var    documentSentimentTask      = TextAnalyticsHelper.AnalyzeSentimentAsync(input, sentimentAnalyses: AdditionalSentimentAnalyses.OpinionMining);
                var    namedEntitiesResponseTask  = TextAnalyticsHelper.RecognizeEntitiesAsync(input);
                var    linkedEntitiesResponseTask = TextAnalyticsHelper.RecognizeLinkedEntitiesAsync(input);

                await Task.WhenAll(detectedLanguageTask, detectedKeyPhrasesTask, documentSentimentTask, namedEntitiesResponseTask, linkedEntitiesResponseTask);

                var detectedLanguage       = detectedLanguageTask.Result;
                var detectedKeyPhrases     = detectedKeyPhrasesTask.Result;
                var documentSentiment      = documentSentimentTask.Result;
                var namedEntitiesResponse  = namedEntitiesResponseTask.Result;
                var linkedEntitiesResponse = linkedEntitiesResponseTask.Result;

                // detected language and key phrases
                this.detectedLangTextBlock.Text       = !string.IsNullOrEmpty(detectedLanguage.Name) ? $"{detectedLanguage.Name} (confidence: {(int)(detectedLanguage.ConfidenceScore * 100)}%)" : "Not found";
                this.detectedKeyPhrasesTextBlock.Text = detectedKeyPhrases.Any() ? string.Join(", ", detectedKeyPhrases) : "Not found";

                // document sentiment
                CreateSentimentChart(documentSentiment);

                // mined opinions
                OpinionMiningCollection.Clear();
                var minedOpinions = documentSentiment?.Sentences.SelectMany(s => s.MinedOpinions);
                if (minedOpinions != null && minedOpinions.Any())
                {
                    var minedOpinionList = minedOpinions.Select(om => new MinedOpinion()
                    {
                        Aspect   = om.Aspect.Text,
                        Opinions = string.Join(", ", om.Opinions.Select(o => $"{o.Text} ({o.Sentiment.ToString("G")})"))
                    });
                    OpinionMiningCollection.AddRange(minedOpinionList);
                }

                // entities
                if (namedEntitiesResponse.Any())
                {
                    this.namesEntitiesGridView.ItemsSource = namedEntitiesResponse.Select(x => new { x.Text, Category = $"[{x.Category}]" });
                }
                else
                {
                    this.namesEntitiesGridView.ItemsSource = new[] { new { Text = "No entities" } };
                }

                // linked entities
                if (linkedEntitiesResponse.Any())
                {
                    this.linkedEntitiesGridView.ItemsSource = linkedEntitiesResponse.Select(x => new { Name = $"{x.Name} ({x.DataSource})", x.Url });
                }
                else
                {
                    this.linkedEntitiesGridView.ItemsSource = new[] { new { Name = "No linked entities" } };
                }

                // prepare json result
                var jsonResult = new
                {
                    LanguageDetection = detectedLanguage,
                    KeyPhrases        = detectedKeyPhrases,
                    Sentiment         = documentSentiment,
                    Entities          = namedEntitiesResponse,
                    EntityLinking     = linkedEntitiesResponse
                };
                this.jsonResultTextBlock.Text = JsonConvert.SerializeObject(jsonResult, Formatting.Indented);
            }
            catch (Exception ex)
            {
                await Util.GenericApiCallExceptionHandler(ex, "Failure analyzing text");
            }
            finally
            {
                this.progressControl.IsActive = false;
            }
        }
        private async Task AnalyzeTextAsync()
        {
            try
            {
                this.progressControl.IsActive = true;
                DisplayProcessingUI();

                // detect language
                string           input            = this.inputText.Text;
                DetectedLanguage detectedLanguage = await TextAnalyticsHelper.DetectLanguageAsync(input);

                string languageCode = TextAnalyticsHelper.GetLanguageCode(detectedLanguage);

                // check supported languages
                bool isOpinionMiningSupported = TextAnalyticsHelper.OpinionMiningSupportedLanguages.Any(l => string.Equals(l, languageCode, StringComparison.OrdinalIgnoreCase));
                bool isSentimentSupported     = TextAnalyticsHelper.SentimentAnalysisSupportedLanguages.Any(l => string.Equals(l, languageCode, StringComparison.OrdinalIgnoreCase));
                bool isKeyPhraseSupported     = TextAnalyticsHelper.KeyPhraseExtractionSupportedLanguages.Any(l => string.Equals(l, languageCode, StringComparison.OrdinalIgnoreCase));
                bool isNamedEntitySupported   = TextAnalyticsHelper.NamedEntitySupportedLanguages.Any(l => string.Equals(l, languageCode, StringComparison.OrdinalIgnoreCase));
                bool isEntityLinkingSupported = TextAnalyticsHelper.EntityLinkingSupportedLanguages.Any(l => string.Equals(l, languageCode, StringComparison.OrdinalIgnoreCase));

                // sentiment analysis, key phrase extraction, named entity recognition and entity linking
                Task <DocumentSentiment>           documentSentimentTask      = isSentimentSupported ? TextAnalyticsHelper.AnalyzeSentimentAsync(input, languageCode, isOpinionMiningSupported) : Task.FromResult <DocumentSentiment>(null);
                Task <KeyPhraseCollection>         detectedKeyPhrasesTask     = isKeyPhraseSupported ? TextAnalyticsHelper.ExtractKeyPhrasesAsync(input, languageCode) : Task.FromResult <KeyPhraseCollection>(null);
                Task <CategorizedEntityCollection> namedEntitiesResponseTask  = isNamedEntitySupported ? TextAnalyticsHelper.RecognizeEntitiesAsync(input, languageCode) : Task.FromResult <CategorizedEntityCollection>(null);
                Task <LinkedEntityCollection>      linkedEntitiesResponseTask = isEntityLinkingSupported ? TextAnalyticsHelper.RecognizeLinkedEntitiesAsync(input, languageCode) : Task.FromResult <LinkedEntityCollection>(null);

                await Task.WhenAll(documentSentimentTask, detectedKeyPhrasesTask, namedEntitiesResponseTask, linkedEntitiesResponseTask);

                DocumentSentiment           documentSentiment      = documentSentimentTask.Result;
                KeyPhraseCollection         detectedKeyPhrases     = detectedKeyPhrasesTask.Result;
                CategorizedEntityCollection namedEntitiesResponse  = namedEntitiesResponseTask.Result;
                LinkedEntityCollection      linkedEntitiesResponse = linkedEntitiesResponseTask.Result;

                // display results
                this.detectedLangTextBlock.Text = !string.IsNullOrEmpty(detectedLanguage.Name) ? $"{detectedLanguage.Name} (confidence: {(int)(detectedLanguage.ConfidenceScore * 100)}%)" : NotFound;

                this.detectedKeyPhrasesTextBlock.Text = detectedKeyPhrases != null && detectedKeyPhrases.Any()
                    ? string.Join(", ", detectedKeyPhrases)
                    : isKeyPhraseSupported?NotFound : LanguageNotSupported;

                this.namesEntitiesGridView.ItemsSource = namedEntitiesResponse != null && namedEntitiesResponse.Any()
                    ? namedEntitiesResponse.Select(x => new { x.Text, Category = $"[{x.Category}]" })
                    : new[] { new { Text = isNamedEntitySupported ? "No entities" : LanguageNotSupported, Category = "" } };

                this.linkedEntitiesGridView.ItemsSource = linkedEntitiesResponse != null && linkedEntitiesResponse.Any()
                    ? linkedEntitiesResponse.Select(x => new { Name = $"{x.Name} ({x.DataSource})", x.Url })
                    : new[] {
                    isEntityLinkingSupported
                        ? new { Name = "No linked entities", Url = new Uri("about:blank") }
                        : new { Name = LanguageNotSupported, Url = TextAnalyticsHelper.LanguageSupportUri }
                };

                if (isSentimentSupported)
                {
                    CreateSentimentChart(documentSentiment);

                    // mined opinions
                    OpinionMiningCollection.Clear();
                    var minedOpinions = documentSentiment?.Sentences.SelectMany(s => s.MinedOpinions);
                    if (minedOpinions != null && minedOpinions.Any())
                    {
                        var minedOpinionList = minedOpinions.Select(om => new MinedOpinion()
                        {
                            Aspect   = om.Aspect.Text,
                            Opinions = string.Join(", ", om.Opinions.Select(o => $"{o.Text} ({o.Sentiment.ToString("G")})"))
                        });
                        OpinionMiningCollection.AddRange(minedOpinionList);
                    }
                }
                else
                {
                    this.sentimentTextBlock.Text   = LanguageNotSupported;
                    this.sentimentChart.Visibility = Visibility.Collapsed;
                }

                // prepare json result
                var jsonResult = new
                {
                    LanguageDetection = detectedLanguage,
                    KeyPhrases        = detectedKeyPhrases,
                    Sentiment         = documentSentiment,
                    Entities          = namedEntitiesResponse,
                    EntityLinking     = linkedEntitiesResponse
                };
                this.jsonResultTextBlock.Text = JsonConvert.SerializeObject(jsonResult, Formatting.Indented);
            }
            catch (Exception ex)
            {
                await Util.GenericApiCallExceptionHandler(ex, "Failure analyzing text");
            }
            finally
            {
                this.progressControl.IsActive = false;
            }
        }