/// <summary>
        /// Downloads the achievements for a the specified gamer tag and game ID.
        /// </summary>
        /// <param name="sGamerTag">The gamer tag of the player of the game.</param>
        /// <param name="iGameID">The ID of the game to download achievements for.</param>
        /// <returns>Returns a <seealso cref="XboxLeadersNETWrapper.GameAchievements">GameAchievements</seealso> object.</returns>
        /// <example>XboxLeadersNETWrapper.GameAchievements gaAchievements = XboxLeadersNETWrapper.DownloadGameAchievements("Major Nelson", 1297287449);</example>
        public static GameAchievements DownloadGameAchievements(String sGamerTag, Int32 iGameID)
        {
            WebClient wcDownloader = new WebClient();
            GameAchievements gaAchievements = new GameAchievements();
            XmlDocument xGame = new XmlDocument();
            XmlReader xReader;
            XElement xJSONRoot;
            Byte[] bJSONData;

            bJSONData = System.Text.Encoding.ASCII.GetBytes(wcDownloader.DownloadString(String.Format("https://www.xboxleaders.com/api/achievements.json?gamertag={0}&gameid={1}", sGamerTag, iGameID)));

            xReader = JsonReaderWriterFactory.CreateJsonReader(bJSONData, new XmlDictionaryReaderQuotas());

            if (xReader == null)
            {
                throw new Exception("Unable to convert data.");
            }

            xJSONRoot = XElement.Load(xReader);

            xGame.LoadXml(xJSONRoot.ToString());

            if (xGame.SelectSingleNode("root/status").InnerText.ToLower() != "success")
            {
                //TODO: Catch errors in JSON feed (Problem: If JSON returns a 501 the WebClient throws an exception.)
                throw new Exception("");
            }

            gaAchievements.GamerTag = xGame.SelectSingleNode("root/data/gamertag").InnerText;
            gaAchievements.GameName = xGame.SelectSingleNode("root/data/game").InnerText;
            gaAchievements.ID = Int32.Parse(xGame.SelectSingleNode("root/data/id").InnerText);
            gaAchievements.HID = xGame.SelectSingleNode("root/data/hid").InnerText;
            gaAchievements.GamerScore = new GamerScore(Int32.Parse(xGame.SelectSingleNode("root/data/gamerscore/current").InnerText), Int32.Parse(xGame.SelectSingleNode("root/data/gamerscore/total").InnerText));
            gaAchievements.Achievements = new Achievements(Int32.Parse(xGame.SelectSingleNode("root/data/achievement/current").InnerText), Int32.Parse(xGame.SelectSingleNode("root/data/achievement/total").InnerText));
            gaAchievements.Progress = Double.Parse(xGame.SelectSingleNode("root/data/progress").InnerText);
            gaAchievements.LastPlayed = DateTimeFromEpoc(Int64.Parse(xGame.SelectSingleNode("root/data/lastplayed").InnerText));

            gaAchievements.AchievementList = new List<Achievement>();

            foreach (XmlNode xAchievement in xGame.SelectNodes("root/data/achievements/item"))
            {
                Achievement aAchievement = new Achievement();

                aAchievement.ID = Int32.Parse(xAchievement.SelectSingleNode("id").InnerText);
                aAchievement.Title = HttpUtility.HtmlDecode(xAchievement.SelectSingleNode("title").InnerText);
                aAchievement.LockedArtwork = DownloadImage(xAchievement.SelectSingleNode("artwork/locked").InnerText);
                aAchievement.UnlockedArtwork = DownloadImage(xAchievement.SelectSingleNode("artwork/unlocked").InnerText);
                aAchievement.Description = xAchievement.SelectSingleNode("description").InnerText;
                aAchievement.GamerScore = Int32.Parse(xAchievement.SelectSingleNode("gamerscore").InnerText);
                aAchievement.Secret = Boolean.Parse(xAchievement.SelectSingleNode("secret").InnerText);
                aAchievement.Unlocked = Boolean.Parse(xAchievement.SelectSingleNode("unlocked").InnerText);

                if (aAchievement.Unlocked)
                {
                    aAchievement.UnlockedDate = DateTimeFromEpoc(Int64.Parse(xAchievement.SelectSingleNode("unlockdate").InnerText));
                    aAchievement.UnlockedOffline = Boolean.Parse(xAchievement.SelectSingleNode("unlockedoffline").InnerText);
                }
                else
                {
                    aAchievement.UnlockedOffline = false;
                }

                gaAchievements.AchievementList.Add(aAchievement);
            }

            return gaAchievements;
        }
        /// <summary>
        /// Downloads XBox Live search results based on the specified search query.
        /// </summary>
        /// <param name="sSearchQuery">The search query for the search.</param>
        /// <returns>Returns a <seealso cref="XboxLeadersNETWrapper.Search">Search</seealso> object</returns>
        /// <example>XboxLeadersNETWrapper.Search sSearch = XboxLeadersNETWrapper.DownloadSearchResults("GTA V");</example>
        public static Search DownloadSearchResults(String sSearchQuery)
        {
            WebClient wcDownloader = new WebClient();
            String sFormattedQuery = HttpUtility.UrlPathEncode(sSearchQuery);
            GameAchievements gaAchievements = new GameAchievements();
            XmlDocument xSearchResults = new XmlDocument();
            Search sSearch = new Search();
            XmlReader xReader;
            XElement xJSONRoot;
            Byte[] bJSONData;

            bJSONData = System.Text.Encoding.ASCII.GetBytes(wcDownloader.DownloadString("https://www.xboxleaders.com/api/search.json?query=" + sFormattedQuery));

            xReader = JsonReaderWriterFactory.CreateJsonReader(bJSONData, new XmlDictionaryReaderQuotas());

            if (xReader == null)
            {
                throw new Exception("Unable to convert data.");
            }

            xJSONRoot = XElement.Load(xReader);

            xSearchResults.LoadXml(xJSONRoot.ToString());

            if (xSearchResults.SelectSingleNode("root/status").InnerText.ToLower() != "success")
            {
                //TODO: Catch errors in JSON feed (Problem: If JSON returns a 501 the WebClient throws an exception.)
                throw new Exception("");
            }

            sSearch.TotalResults = Int32.Parse(xSearchResults.SelectSingleNode("root/data/totalresults").InnerText);
            sSearch.ResultsLink = new Uri(xSearchResults.SelectSingleNode("root/data/resultslink").InnerText);

            sSearch.Results = new List<SearchResult>();

            foreach (XmlNode xNode in xSearchResults.SelectNodes("root/data/results/item"))
            {
                SearchResult srResult = new SearchResult();

                srResult.Title = xNode.SelectSingleNode("title").InnerText;
                srResult.Parent = xNode.SelectSingleNode("parent").InnerText;
                srResult.Link = new Uri(xNode.SelectSingleNode("link").InnerText);
                srResult.Image = DownloadImage(xNode.SelectSingleNode("image").InnerText);
                srResult.DownloadType = new DownloadType(xNode.SelectSingleNode("downloadtype/class").InnerText, xNode.SelectSingleNode("downloadtype/title").InnerText);
                srResult.Prices = new Prices(xNode.SelectSingleNode("prices/silver").InnerText, xNode.SelectSingleNode("prices/gold").InnerText);

                sSearch.Results.Add(srResult);
            }

            return sSearch;
        }