private static async Task <Response> ProcessAsyncResponse <T>(Response response, Action <int> remainingTimeCallback) where T : Resource
        {
            if (response != null)
            {
                if (response.ErrorDetails != null && response.ErrorDetails.Length > 0)
                {
                    throw new Exception(String.Join("", response.ErrorDetails));
                }

                if (response.ResourceSets != null && response.ResourceSets.Length > 0 && response.ResourceSets[0].Resources != null && response.ResourceSets[0].Resources.Length > 0)
                {
                    if (response.ResourceSets[0].Resources[0] is AsyncStatus && !string.IsNullOrEmpty((response.ResourceSets[0].Resources[0] as AsyncStatus).RequestId))
                    {
                        var status = response.ResourceSets[0].Resources[0] as AsyncStatus;

                        status = await ServiceHelper.ProcessAsyncStatus(status, remainingTimeCallback);

                        if (status != null && status.IsCompleted && !string.IsNullOrEmpty(status.ResultUrl))
                        {
                            try
                            {
                                using (var resultStream = await ServiceHelper.GetStreamAsync(new Uri(status.ResultUrl)))
                                {
                                    var resource = ServiceHelper.DeserializeStream <T>(resultStream);
                                    response.ResourceSets[0].Resources[0] = resource;
                                }
                            }
                            catch (Exception ex)
                            {
                                throw new Exception("There was an issue downloading and serializing the results. Results Download URL: " + status.ResultUrl + "\r\n" + ex.Message);
                            }
                        }

                        return(response);
                    }
                    else if (response.ResourceSets[0].Resources[0] is AsyncStatus && !string.IsNullOrEmpty((response.ResourceSets[0].Resources[0] as AsyncStatus).ErrorMessage))
                    {
                        throw new Exception((response.ResourceSets[0].Resources[0] as AsyncStatus).ErrorMessage);
                    }
                    else if (response.ResourceSets[0].Resources[0] is Resource && !(response.ResourceSets[0].Resources[0] is AsyncStatus))
                    {
                        return(response);
                    }
                }
            }

            throw new Exception("No response returned by service.");
        }
        //TODO: this is temporary until distance matrix Async response updated.
        private static async Task <Response> ProcessAsyncResponse <T>(Response response, Action <int> remainingTimeCallback) where T : Resource
        {
            if (response != null)
            {
                if (response.ErrorDetails != null && response.ErrorDetails.Length > 0)
                {
                    throw new Exception(String.Join("", response.ErrorDetails));
                }

                if (Response.HasResource(response))
                {
                    var res = Response.GetFirstResource(response);
                    if (res is AsyncStatus && !string.IsNullOrEmpty((res as AsyncStatus).RequestId))
                    {
                        var status = res as AsyncStatus;

                        status = await ServiceHelper.ProcessAsyncStatus(status, remainingTimeCallback).ConfigureAwait(false);

                        if (status != null && status.IsCompleted && !string.IsNullOrEmpty(status.ResultUrl))
                        {
                            try
                            {
                                using (var resultStream = await ServiceHelper.GetStreamAsync(new Uri(status.ResultUrl)).ConfigureAwait(false))
                                {
                                    if (typeof(T) == typeof(DistanceMatrix))
                                    {
                                        //There is a bug in the distance matrix service that when some options are set, the response isn't wrapped with a resourceSet->resources like all other services.
                                        using (var sr = new StreamReader(resultStream))
                                        {
                                            var r = sr.ReadToEnd();

                                            //Remove first character from string.
                                            r = r.Remove(0, 1);

                                            //Add namespace type to JSON object.
                                            r = "{\"__type\":\"DistanceMatrix:http://schemas.microsoft.com/search/local/ws/rest/v1\"," + r;

                                            var bytes = Encoding.UTF8.GetBytes(r);
                                            using (var stream = new MemoryStream(bytes))
                                            {
                                                var resource = ServiceHelper.DeserializeStream <T>(stream);
                                                response.ResourceSets[0].Resources[0] = resource;
                                            }
                                        }
                                    }
                                    else if (typeof(T) == typeof(SnapToRoadResponse))
                                    {
                                        //Snap to road for some reason includes a full resource set response while other async services don't.
                                        response = ServiceHelper.DeserializeStream <Response>(resultStream);
                                    }
                                    else
                                    {
                                        var resource = ServiceHelper.DeserializeStream <T>(resultStream);
                                        response.ResourceSets[0].Resources[0] = resource;
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                throw new Exception("There was an issue downloading and serializing the results. Results Download URL: " + status.ResultUrl + "\r\n" + ex.Message);
                            }
                        }

                        return(response);
                    }
                    else if (res is AsyncStatus && !string.IsNullOrEmpty((res as AsyncStatus).ErrorMessage))
                    {
                        throw new Exception((res as AsyncStatus).ErrorMessage);
                    }
                    else if (res is Resource && !(res is AsyncStatus))
                    {
                        return(response);
                    }
                }
            }

            throw new Exception("No response returned by service.");
        }