/// <summary>
        /// Get a forecast for the given latitude and longitude
        /// </summary>
        public void GetForecast(string latitude, string longitude)
        {
            // form the URI
            UriBuilder fullUri = new UriBuilder("http://forecast.weather.gov/MapClick.php");

            fullUri.Query = "lat=" + latitude + "&lon=" + longitude + "&FcstType=dwml";

            // initialize a new WebRequest
            HttpWebRequest forecastRequest = (HttpWebRequest)WebRequest.Create(fullUri.Uri);

            // set up the state object for the async request
            ForecastUpdateState forecastState = new ForecastUpdateState();

            forecastState.AsyncRequest = forecastRequest;

            // start the asynchronous request
            forecastRequest.BeginGetResponse(new AsyncCallback(HandleForecastResponse),
                                             forecastState);
        }
        /// <summary>
        /// Handle the information returned from the async request
        /// </summary>
        /// <param name="asyncResult"></param>
        private void HandleForecastResponse(IAsyncResult asyncResult)
        {
            // get the state information
            ForecastUpdateState forecastState   = (ForecastUpdateState)asyncResult.AsyncState;
            HttpWebRequest      forecastRequest = (HttpWebRequest)forecastState.AsyncRequest;

            // end the async request
            forecastState.AsyncResponse = (HttpWebResponse)forecastRequest.EndGetResponse(asyncResult);

            Stream streamResult;

            string newCredit   = "";
            string newCityName = "";
            int    newHeight   = 0;

            // create a temp collection for the new forecast information for each
            // time period
            ObservableCollection <ForecastPeriod> newForecastList =
                new ObservableCollection <ForecastPeriod>();

            try
            {
                // get the stream containing the response from the async call
                streamResult = forecastState.AsyncResponse.GetResponseStream();

                // load the XML
                XElement xmlWeather = XElement.Load(streamResult);

                // start parsing the XML.  You can see what the XML looks like by
                // browsing to:
                // http://forecast.weather.gov/MapClick.php?lat=44.52160&lon=-87.98980&FcstType=dwml

                // find the source element and retrieve the credit information
                XElement xmlCurrent = xmlWeather.Descendants("source").First();
                newCredit = (string)(xmlCurrent.Element("credit"));

                // find the source element and retrieve the city and elevation information
                xmlCurrent  = xmlWeather.Descendants("location").First();
                newCityName = (string)(xmlCurrent.Element("city"));
                newHeight   = (int)(xmlCurrent.Element("height"));

                // find the first time layout element
                xmlCurrent = xmlWeather.Descendants("time-layout").First();

                int timeIndex = 1;

                // search through the time layout elements until you find a node
                // contains at least 12 time periods of information. Other nodes can be ignored
                while (xmlCurrent.Elements("start-valid-time").Count() < 12)
                {
                    xmlCurrent = xmlWeather.Descendants("time-layout").ElementAt(timeIndex);
                    timeIndex++;
                }

                ForecastPeriod newPeriod;

                // For each time period element, create a new forecast object and store
                // the time period name.
                // Time periods vary depending on the time of day the data is fetched.
                // You may get "Today", "Tonight", "Monday", "Monday Night", etc
                // or you may get "Tonight", "Monday", "Monday Night", etc
                // or you may get "This Afternoon", "Tonight", "Monday", "Monday Night", etc
                foreach (XElement curElement in xmlCurrent.Elements("start-valid-time"))
                {
                    try
                    {
                        newPeriod          = new ForecastPeriod();
                        newPeriod.TimeName = (string)(curElement.Attribute("period-name"));
                        newForecastList.Add(newPeriod);
                    }
                    catch (FormatException)
                    {
                    }
                }

                // now read in the weather data for each time period
                GetMinMaxTemperatures(xmlWeather, newForecastList);
                GetChancePrecipitation(xmlWeather, newForecastList);
                GetCurrentConditions(xmlWeather, newForecastList);
                GetWeatherIcon(xmlWeather, newForecastList);
                GetTextForecast(xmlWeather, newForecastList);


                // copy the data over
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    // copy forecast object over
                    Credit   = newCredit;
                    Height   = newHeight;
                    CityName = newCityName;

                    ForecastList.Clear();

                    // copy the list of forecast time periods over
                    foreach (ForecastPeriod forecastPeriod in newForecastList)
                    {
                        ForecastList.Add(forecastPeriod);
                    }
                });
            }
            catch (FormatException)
            {
                // there was some kind of error processing the response from the web
                // additional error handling would normally be added here
                return;
            }
        }