public override void ParseResults(XDocument xmlDoc, Exception error)
            {
                List <Stop> stops         = new List <Stop>();;
                bool        limitExceeded = false;

                if (xmlDoc == null || error != null)
                {
                    callback(stops, limitExceeded, error);
                }
                else
                {
                    try
                    {
                        IDictionary <string, Route> routesMap = ParseAllRoutes(xmlDoc);

                        stops.AddRange(from stop in xmlDoc.Descendants("stop")
                                       select ParseStop(
                                           stop,
                                           (from routeId in stop.Element("routeIds").Descendants("string")
                                            select routesMap[SafeGetValue(routeId)]).ToList <Route>()));

                        IEnumerable <XElement> descendants = xmlDoc.Descendants("data");
                        if (descendants.Count() != 0)
                        {
                            limitExceeded = bool.Parse(SafeGetValue(descendants.First().Element("limitExceeded")));
                        }

                        Debug.Assert(limitExceeded == false);
                    }
                    catch (WebserviceResponseException ex)
                    {
                        error = ex;
                    }
                    catch (Exception ex)
                    {
                        error = new WebserviceParsingException(requestUrl, xmlDoc.ToString(), ex);
                    }
                }

                Debug.Assert(error == null);

                // Remove a page from the cache if we hit a parsing error.  This way we won't keep
                // invalid server data in the cache
                if (error != null)
                {
                    stopsCache.Invalidate(new Uri(requestUrl));
                }

                callback(stops, limitExceeded, error);
            }
        public void StopsForLocation(GeoCoordinate location, string query, int radiusInMeters, int maxCount, bool invalidateCache, StopsForLocation_Callback callback)
        {
            GeoCoordinate roundedLocation = GetRoundedLocation(location);

            // ditto for the search radius -- nearest 50 meters for caching
            int roundedRadius = (int)(Math.Round(radiusInMeters / 50.0) * 50);

            string requestString = string.Format(
                "{0}/{1}.xml?key={2}&lat={3}&lon={4}&radius={5}&Version={6}",
                WebServiceUrlForLocation(location),
                "stops-for-location",
                KEY,
                roundedLocation.Latitude.ToString(NumberFormatInfo.InvariantInfo),
                roundedLocation.Longitude.ToString(NumberFormatInfo.InvariantInfo),
                roundedRadius,
                APIVERSION
                );

            if (string.IsNullOrEmpty(query) == false)
            {
                requestString += string.Format("&query={0}", query);
            }

            if (maxCount > 0)
            {
                requestString += string.Format("&maxCount={0}", maxCount);
            }

            Uri requestUri = new Uri(requestString);

            if (invalidateCache)
            {
                stopsCache.Invalidate(requestUri);
            }

            stopsCache.DownloadStringAsync(requestUri, new GetStopsForLocationCompleted(requestString, stopsCache, callback).HttpCache_Completed);
        }
            public override void ParseResults(XDocument xmlDoc, Exception error)
            {
                List <RouteStops> routeStops = new List <RouteStops>();

                if (xmlDoc == null || error != null)
                {
                    callback(routeStops, error);
                }
                else
                {
                    try
                    {
                        IDictionary <string, Route> routesMap = ParseAllRoutes(xmlDoc);

                        // parse all the stops, using previously parsed Route objects
                        IList <Stop> stops =
                            (from stop in xmlDoc.Descendants("stop")
                             select ParseStop(stop,
                                              (from routeId in stop.Element("routeIds").Descendants("string")
                                               select routesMap[SafeGetValue(routeId)]
                                              ).ToList <Route>()
                                              )).ToList <Stop>();

                        IDictionary <string, Stop> stopsMap = new Dictionary <string, Stop>();
                        foreach (Stop s in stops)
                        {
                            stopsMap.Add(s.id, s);
                        }

                        // and put it all together
                        routeStops.AddRange
                            (from stopGroup in xmlDoc.Descendants("stopGroup")
                            where SafeGetValue(stopGroup.Element("name").Element("type")) == "destination"
                            select new RouteStops
                        {
                            name             = SafeGetValue(stopGroup.Descendants("names").First().Element("string")),
                            encodedPolylines = (from poly in stopGroup.Descendants("encodedPolyline")
                                                select new PolyLine
                            {
                                pointsString = SafeGetValue(poly.Element("points")),
                                length = SafeGetValue(poly.Element("length"))
                            }).ToList <PolyLine>(),
                            stops =
                                (from stopId in stopGroup.Descendants("stopIds").First().Descendants("string")
                                 select stopsMap[SafeGetValue(stopId)]).ToList <Stop>(),

                            route = routesMap[routeId]
                        });
                    }
                    catch (WebserviceResponseException ex)
                    {
                        error = ex;
                    }
                    catch (Exception ex)
                    {
                        error = new WebserviceParsingException(requestUrl, xmlDoc.ToString(), ex);
                    }
                }

                Debug.Assert(error == null);

                // Remove a page from the cache if we hit a parsing error.  This way we won't keep
                // invalid server data in the cache
                if (error != null)
                {
                    directionCache.Invalidate(new Uri(requestUrl));
                }

                callback(routeStops, error);
            }