/// <summary>
        /// Method to pull data from an A3 server
        /// </summary>
        /// <param name="host">Host name/IP of the A3 server</param>
        /// <param name="port">Port of the A3 server steam query point (+1 game port)</param>
        /// <returns>Filled in <see cref="ServerInfo"/> object</returns>
        public ServerInfo GetServerInfo(string host, int port) {
            Stopwatch retry = new Stopwatch();
            retry.Start();
            while (retry.ElapsedMilliseconds < Properties.Settings.Default.retryTimeLimit) {
                try {
                    using (UdpClient client = new UdpClient(56800)) {
                        IPAddress[] hostEntry = Dns.GetHostAddresses(host);

                        IPEndPoint remoteIpEndpoint = null;
                        if (hostEntry.Length > 0) {
                            remoteIpEndpoint = new IPEndPoint(hostEntry[0], port);
                        }
                        else {
                            remoteIpEndpoint = new IPEndPoint(IPAddress.Parse(host), port);
                        }
                        
                        client.Client.ReceiveTimeout = 20000;
                        client.Connect(remoteIpEndpoint);

                        //Server Info
                        //request general info
                        client.Send(REQUEST_INFO, REQUEST_INFO.Length);
                        Stopwatch ping = new Stopwatch();
                        ping.Start();
                        byte[] response = client.Receive(ref remoteIpEndpoint);
                        ping.Stop();
                        ServerInfo serverInfo = new ServerInfo(response);
                        serverInfo.Ping = ping.ElapsedMilliseconds;

                        //get player info
                        serverInfo.AddPlayers(GetChallengeResponse(PLAYER_BYTE, client, remoteIpEndpoint));

                        return serverInfo;
                    }
                } catch (Exception e) {
                    _logger.Warn("Trouble connecting to the server: ", e);
                    if (retry.ElapsedMilliseconds > Properties.Settings.Default.retryTimeLimit) {
                        throw new NoServerInfoException("Trouble connecting to the server");
                    } else {
                        System.Threading.Thread.Sleep(Properties.Settings.Default.pollRate);
                    }

                }
            }
            return null;
        }
        /// <summary>
        /// Helper method to update <see cref="Player"/> data in the database
        /// </summary>
        /// <param name="playerDAO">DAO for <see cref="Player"/>s</param>
        /// <param name="session">The current game <see cref="Session"/></param>
        /// <param name="serverInfo">The current <see cref="ServerInfo"/></param>
        /// <param name="missionSession">The current <see cref="MissionSession"/></param>
        /// <returns>The current set of <see cref="PlayerSession"/>s</returns>
        private ISet<PlayerSession> UpdatePlayerData(PlayerDAO playerDAO, Session session, ServerInfo serverInfo, MissionSession missionSession) {
            ISet<PlayerSession> playerSessions = playerDAO.GetOrCreatePlayerSessions(serverInfo.Players, session);

            foreach (PlayerSession playerSession in playerSessions) {
                playerSession.Updated = true;
                playerSession.Length += (Settings.Default.pollRate / 1000);
                if (playerSession.Played == false && CheckPlayedThreshold(playerSession.Length)) {
                    playerSession.Played = true;
                }
            }

            playerDAO.UpdatePlayerSessions(playerSessions);
            return playerSessions;
        }
        /// <summary>
        /// Helper method to update <see cref="Mission"/> data in the database
        /// </summary>
        /// <param name="missionDAO">DAO for <see cref="Mission"/>s</param>
        /// <param name="session">The current game <see cref="Session"/></param>
        /// <param name="serverInfo">The current <see cref="ServerInfo"/></param>
        /// <param name="missionCount">The number of missions played</param>
        /// <returns>The current <see cref="MissionSession"/></returns>
        private MissionSession UpdateMissionData(MissionDAO missionDAO, Session session, ServerInfo serverInfo, ref int missionCount) {
            MissionSession missionSession = missionDAO.GetOrCreateMissionSession(serverInfo.MapName, serverInfo.Mission, session);

            missionSession.Updated = true;
            missionSession.Length += (Settings.Default.pollRate / 1000);
            if (missionSession.Played == false && CheckPlayedThreshold(missionSession.Length)) {
                missionSession.Played = true;
                missionCount++;
            }

            missionDAO.UpdateMissionSession(missionSession);

            return missionSession;
        }
        /// <summary>
        /// Helper method to update <see cref="Session"/> data in the database
        /// </summary>
        /// <param name="sessionDAO">DAO for <see cref="Session"/>s</param>
        /// <param name="session">The current game <see cref="Session"/></param>
        /// <param name="serverInfo">The current <see cref="ServerInfo"/></param>
        private void UpdateSessionData(SessionDAO sessionDAO, Session session, ServerInfo serverInfo) {
            bool updateSession = false;

            if (session.MaxPing < serverInfo.Ping) {
                session.MaxPing = serverInfo.Ping;
                updateSession = true;
            } else if (session.MinPing > serverInfo.Ping) {
                session.MinPing = serverInfo.Ping;
                updateSession = true;
            }

            if (session.MaxPlayers < serverInfo.Players.Count) {
                session.MaxPlayers = serverInfo.Players.Count;
                updateSession = true;
            }

            if (updateSession) {
                sessionDAO.UpdateSession(session);
            }
        }