/// <summary>Gets the game list as <see cref="HtmlAgilityPack.HtmlNode"/>.</summary>
		public IEnumerable<AIGameResult> GetGames(AIGamesCompetition competition, string playerName)
		{
			if (competition == null) { throw new ArgumentNullException("competition"); }
			if (string.IsNullOrEmpty(playerName)) { throw new ArgumentNullException("playerName"); }

			var page = 0;
			var count = 0;
			var last = 0;

			while (true)
			{
				Driver.Url = competition.GetGameListUrl(playerName, ++page).ToString();

				var html = new HtmlDocument();
				html.LoadHtml(Driver.PageSource);

				var rows =html.DocumentNode.SelectNodes("//table[@class='table table-gameLog']/tbody/tr");
				if (rows == null) { yield break; }
				foreach(var row in rows)
				{
					var game = AIGameResult.FromRow(row);
					if (game != null)
					{
						count++;
						yield return game;
					}
				}
				// No new games for the last page, So break.
				if (last == count) { yield break; }
				last = count;
			}
		}
		public IEnumerable<AIGamesBot> GetHtmlLeaderboard(AIGamesCompetition competition)
		{
			if (competition == null) { throw new ArgumentNullException("competition"); }
			Driver.Url = competition.GetLeaderboard().ToString();
			
			var document = new HtmlDocument();
			document.LoadHtml(Driver.PageSource);

			var rows= document.DocumentNode.SelectNodes("//table[@id='leaderboard-table']/tbody/tr");
			if (rows == null) { yield break; }
			foreach (var row in rows)
			{
				var bot = AIGamesBot.FromRow(row);
				if (bot != null)
				{
					yield return bot;
				}
			}
		}
		/// <summary>Saves the game dump for a specified game.</summary>
		public bool SaveGameDump(AIGamesCompetition competition, AIGameResult game)
		{
			if (competition == null) { throw new ArgumentNullException("competition"); }
			if (game == null) { throw new ArgumentNullException("game"); }

			var dir = competition.GetGameDumpDirectory();
			if (!dir.Exists) { dir.Create(); }

			var dump = AIGameDump.GetLocation(competition, game);
			if (dump.Exists) { return false; }

			Driver.Url = competition.GetGameDumpUrl(game.Id).ToString();

			var html = new HtmlDocument();
			html.LoadHtml(Driver.PageSource);

			var code = html.DocumentNode.SelectNodes("//code").ElementAt(1).InnerHtml;

			if (String.IsNullOrEmpty(code)) { return false; }

			using (var stream = dump.OpenWrite())
			{
				AIGameDump.Save(stream, code);
			}
			return true;
		}
		/// <summary>Gets the game list as <see cref="HtmlAgilityPack.HtmlNode"/>.</summary>
		public IEnumerable<AIGameResult> GetGames(AIGamesCompetition competition)
		{
			return GetGames(competition, "a");
		}
		/// <summary>Challenges an opponent.</summary>
		public void ChallengeOpponent(AIGamesCompetition competition, string playerName)
		{
			if (competition == null) { throw new ArgumentNullException("competition"); }
			Driver.Url = competition.GetChallengeUrl(playerName).ToString();
		}