/// <summary>
        /// This class extends the class ImageInfo to pertain to image information for local images
        /// </summary>
        // Downloads cached response stored locally.
        // Program does not currently save Knowledge API responses locally
        // If you want to add this functionality, save the Knowledge API response in the same folder as your image as "filepath.json"
        public override async Task GenerateSearchResponse()
        {
            // Try to look for a json response file in the same location with same filename but .json extension
            // if exits attempt to read it as a KAPI JSON response file. If not, fallback.
            var name            = this.Url;
            var nameForJsonFile = name.Replace(".jpg", ".json");                               //only support JPG at the moment

            if (string.Equals(name, nameForJsonFile) == false && File.Exists(nameForJsonFile)) //If there exists a JSON file with the same name as a jpeg, then continue
            {
                try
                {
                    KapiResponse sr = new KapiResponse();
                    sr.Status = "Cached Response";
                    sr.Source = SearchResponseSource.Cache;

                    string jsonResponse = File.ReadAllText(nameForJsonFile);
                    this.JsonString = jsonResponse;

                    bool parsed = sr.TryParse(jsonResponse);
                    if (parsed == false)
                    {
                        this.SearchResponse = sr;
                        return;
                    }

                    sr.Status = "Cached Response";
                    sr.Source = SearchResponseSource.Cache;

                    // we may get a KAPI response of type error. So only process the success (ImageKnowledge) type responses
                    if (sr.ResponseType == KapiResponseType.ImageKnowledge)
                    {
                        sr.ExtractSearchResults();

                        var tagNames = from tag in sr.Tags
                                       let t                 = tag.DisplayName
                                                       let s = tag.Score.HasValue ? $"({tag.Score.Value.ToString("F1")})" : String.Empty
                                                               where string.IsNullOrEmpty(tag.DisplayName) == false
                                                               select $"{t}{s}";

                        this.Tags = tagNames.ToArray();
                    }

                    this.SearchResponse = sr;
                    return;
                }
                catch (Exception) { }
            }

            // In the case that cached response is found, we still populate the SearchResponse
            await Task.Run(() =>
            {
                this.SearchResponse = new SearchResponse();
                this.SearchResponse.SearchEndpointUrl = KapiSearch.KapiEndpointUrl;
                this.SearchResponse.Status            = "No Cached Response Available";
                this.SearchResponse.Source            = SearchResponseSource.None;
            });

            return;
        }
        // Downloads cached response from blob.
        // Program does not currently save Knowledge API responses to the blob
        // If you want to add this functionality, save the Knowledge API response to your blob as "uri.json"
        private async Task DownloadAndGenerateSearchResponse()
        {
            if (this.SearchResponse != null) // we have already generated this response no need to try again
            {
                return;
            }
            try
            {
                var sr = new KapiResponse();
                sr.SearchEndpointUrl = KapiSearch.KapiEndpointUrl; // queryUrl for Kapi is constant.
                sr.Status            = "No Cached Response Available";
                sr.Source            = SearchResponseSource.None;

                var blobUrl      = new Uri(this.Url);
                var jsonBlobName = blobUrl.Segments[blobUrl.Segments.Length - 1].Replace(".jpg", ".json");

                var blob =
                    await this.Container.GetBlobReferenceFromServerAsync(jsonBlobName);

                // if no blob exists
                if (blob == null || await blob.ExistsAsync() == false)
                {
                    this.SearchResponse = sr;
                    return;
                }

                MemoryStream memStream = new MemoryStream();
                await blob.DownloadRangeToStreamAsync(memStream, null, null);

                byte[] bytes = memStream.ToArray();
                if (bytes.Length == 0)
                {
                    this.SearchResponse = sr;
                    return;
                }

                string jsonResponse = Encoding.UTF8.GetString(bytes);
                this.JsonString = jsonResponse;
                bool parsed = sr.TryParse(jsonResponse);
                if (parsed == false)
                {
                    this.SearchResponse = sr;
                    return;
                }

                sr.Status = "Cached Response";
                sr.Source = SearchResponseSource.Cache;

                // we may get a KAPI response of type error. So only process the success (ImageKnowledge) type responses
                if (sr.ResponseType == KapiResponseType.ImageKnowledge)
                {
                    sr.ExtractSearchResults();

                    var tagNames = from tag in sr.Tags
                                   let t                 = tag.DisplayName
                                                   let s = tag.Score.HasValue ? $"({tag.Score.Value.ToString("F1")})" : String.Empty
                                                           where string.IsNullOrEmpty(tag.DisplayName) == false
                                                           select $"{t}{s}";

                    this.Tags = tagNames.ToArray();

                    sr.MiscInfo = new Dictionary <string, Newtonsoft.Json.Linq.JToken>();
                    sr.MiscInfo.Add("Response", sr.KapiResponseJson);
                }

                this.SearchResponse = sr;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.ToString());
            }
        }