public Feed getUpdateDetail(string id, DateTime startDate, DateTime endDate)
        {
            SqlConnection conn = new SqlConnection();
            SqlCommand cmd = new SqlCommand();
            SqlDataReader rdr = null;

            Feed feed = new Feed();
            feed.name = "Virus Updates";

            string sql = @"
                SELECT	DATEADD(SECOND, l.EVENT_TIME/1000, '1970-01-01') AS ed,
                        l.EVENT_DESC AS description
                FROM	V_AGENT_SYSTEM_LOG l
                        INNER JOIN SEM_COMPUTER c ON c.COMPUTER_ID = l.COMPUTER_ID
                WHERE	EVENT_SOURCE = 'SYLINK'
                        AND EVENT_DESC LIKE 'Downloaded%'
                        AND c.COMPUTER_ID = @Id
                        AND dateadd(second, l.EVENT_TIME/1000, '1970-01-01') BETWEEN @StartDate AND @EndDate";

            try {
                conn.ConnectionString = this.sqlConnectionString;
                conn.Open();

                cmd = new SqlCommand(sql, conn);
                cmd.CommandType = System.Data.CommandType.Text;

                cmd.Parameters.Add(new SqlParameter("@Id", SqlDbType.VarChar, 32)).Value = id;
                cmd.Parameters.Add(new SqlParameter("@StartDate", SqlDbType.DateTime)).Value = startDate;
                cmd.Parameters.Add(new SqlParameter("@EndDate", SqlDbType.DateTime)).Value = endDate;
                rdr = cmd.ExecuteReader();

                while (rdr.Read()) {
                    Event e = new Event();
                    e.feed = feed.name;
                    e.ed = (DateTime)rdr["ed"];
                    e.description = rdr["description"] == DBNull.Value ? null : (string)rdr["description"];
                    e.et = "Virus Definition Update";

                    feed.events.Add(e);

                    if ((DateTime)rdr["ed"] < mindt) {
                        mindt = (DateTime)rdr["ed"];
                    }

                    if ((DateTime)rdr["ed"] > maxdt) {
                        maxdt = (DateTime)rdr["ed"];
                    }
                }
            } catch (Exception e) {
                feed.error = e.Message;
            } finally {
                rdr.Close();
                rdr.Dispose();
                cmd.Dispose();
                conn.Close();
                conn.Dispose();
            }

            return feed;
        }
        public Feed getHostUserControlDetail(string id, DateTime startDate, DateTime endDate)
        {
            SqlConnection conn = new SqlConnection();
            SqlCommand cmd = new SqlCommand();
            SqlDataReader rdr = null;

            Feed feed = new Feed();
            feed.name = "User Control";

            string sql = @"
                SELECT	dateadd(second,[EVENT_TIME]/1000, '1970-01-01') AS ed,
                        dateadd(second,[BEGIN_TIME]/1000, '1970-01-01') AS begin_time,
                        dateadd(second,[END_TIME]/1000, '1970-01-01') AS end_time,
                        (SELECT
                            CASE [EVENT_ID]
                                WHEN 501 THEN 'Application Control Driver'
                                WHEN 502 THEN 'Application Control Rules'
                                WHEN 999 THEN 'Tamper Protection'
                            END) AS event_type,
                        severity,
                        (SELECT
                            CASE [ACTION]
                                WHEN 0 THEN 'allow'
                                WHEN 1 THEN 'block'
                                WHEN 2 THEN 'ask'
                                WHEN 3 THEN 'continue'
                                WHEN 4 THEN 'terminate'
                            END) AS action,
                        description,
                        rule_name,
                        caller_process_name,
                        parameter,
                        alert,
                        user_name,
                        domain_name
                FROM	v_agent_behavior_log l
                            INNER JOIN identity_map m ON l.[GROUP_ID] = m.[ID]
                WHERE	caller_process_name != 'SysPlant' AND
                        COMPUTER_ID = @Id AND
                        dateadd(second,[BEGIN_TIME]/1000, '1970-01-01')  BETWEEN @StartDate AND @EndDate
                ORDER	BY l.EVENT_TIME";

            try {
                conn.ConnectionString = this.sqlConnectionString;
                conn.Open();

                cmd = new SqlCommand(sql, conn);
                cmd.CommandType = System.Data.CommandType.Text;

                cmd.Parameters.Add(new SqlParameter("@Id", SqlDbType.VarChar, 32)).Value = id;
                cmd.Parameters.Add(new SqlParameter("@StartDate", SqlDbType.DateTime)).Value = startDate;
                cmd.Parameters.Add(new SqlParameter("@EndDate", SqlDbType.DateTime)).Value = endDate;
                rdr = cmd.ExecuteReader();

                while (rdr.Read()) {
                    UserControlEvent e = new UserControlEvent();
                    e.feed = feed.name;
                    e.ed = (DateTime)rdr["begin_time"];
                    e.et = rdr["event_type"] == DBNull.Value ? null : (string)rdr["event_type"];
                    e.severity = (int)rdr["severity"];
                    e.action_taken = rdr["action"] == DBNull.Value ? null : (string)rdr["action"];
                    e.description = rdr["description"] == DBNull.Value ? null : (string)rdr["description"];
                    e.rule_name = rdr["rule_name"] == DBNull.Value ? null : (string)rdr["rule_name"];
                    e.caller_process = rdr["caller_process_name"] == DBNull.Value ? null : (string)rdr["caller_process_name"];
                    e.parameter = rdr["parameter"] == DBNull.Value ? null : (string)rdr["parameter"];
                    if (rdr["alert"] != DBNull.Value && (int)rdr["alert"] == 1) {
                        e.alert = true;
                    }
                    e.user_name = rdr["user_name"] == DBNull.Value ? null : (string)rdr["user_name"];
                    e.domain_name = rdr["domain_name"] == DBNull.Value ? null : (string)rdr["domain_name"];

                    feed.events.Add(e);

                    if ((DateTime)rdr["ed"] < mindt) {
                        mindt = (DateTime)rdr["ed"];
                    }

                    if ((DateTime)rdr["ed"] > maxdt) {
                        maxdt = (DateTime)rdr["ed"];
                    }
                }
            } catch (Exception e) {
                feed.error = e.Message;
            } finally {
                rdr.Close();
                rdr.Dispose();
                cmd.Dispose();
                conn.Close();
                conn.Dispose();
            }

            return feed;
        }
        public Feed getHostIPSDetail(string id, DateTime startDate, DateTime endDate)
        {
            SqlConnection conn = new SqlConnection();
            SqlCommand cmd = new SqlCommand();
            SqlDataReader rdr = null;

            Feed feed = new Feed();
            feed.name = "IPS";

            string sql = @"
                SELECT	DATEADD(second, EVENT_TIME / 1000, '1970-01-01') AS ed,
                        (SELECT CASE [EVENT_ID]
                            WHEN 301 THEN 'TCP Initiated'
                            WHEN 302 THEN 'UDP datagram'
                            WHEN 303 THEN 'Ping request'
                            WHEN 304 THEN 'TCP Completed'
                            WHEN 305 THEN 'Traffic (other)'
                            WHEN 306 THEN 'ICMP packet'
                            WHEN 307 THEN 'Ethernet packet'
                            WHEN 308 THEN 'IP Packet' END) AS traffic_type,
                        SEVERITY,
                        LOCAL_HOST_IP AS local_ip,
                        REMOTE_HOST_IP AS remote_ip,
                        REMOTE_HOST_NAME AS remote_hostname,
                        LOCAL_PORT,
                        REMOTE_PORT,
                        (SELECT CASE TRAFFIC_DIRECTION
                            WHEN 0 THEN 'Unknown'
                            WHEN 1 THEN 'Inbound'
                            WHEN 2 THEN 'Outbound'
                        END) AS direction,
                        REPETITION,
                        (SELECT CASE NETWORK_PROTOCOL
                            WHEN 1 THEN 'Others'
                            WHEN 2 THEN 'TCP'
                            WHEN 3 THEN 'UDP' END) AS protocol,
                        HACK_TYPE,
                        BEGIN_TIME,
                        EVENT_DESC AS description,
                        APP_NAME,
                        ALERT,
                        LOCATION_NAME AS location,
                        INTRUSION_URL AS intrusion_url,
                        INTRUSION_PAYLOAD_URL AS intrusion_payload_url
                FROM	V_AGENT_SECURITY_LOG
                WHERE	COMPUTER_ID = @Id
                        AND DATEADD(second, EVENT_TIME / 1000, '1970-01-01') BETWEEN @StartDate AND @EndDate
            ";

            try {
                conn.ConnectionString = this.sqlConnectionString;
                conn.Open();

                cmd = new SqlCommand(sql, conn);
                cmd.CommandType = System.Data.CommandType.Text;

                cmd.Parameters.Add(new SqlParameter("@Id", SqlDbType.VarChar, 32)).Value = id;
                cmd.Parameters.Add(new SqlParameter("@StartDate", SqlDbType.DateTime)).Value = startDate;
                cmd.Parameters.Add(new SqlParameter("@EndDate", SqlDbType.DateTime)).Value = endDate;
                rdr = cmd.ExecuteReader();

                while (rdr.Read()) {
                    IPSEvent e = new IPSEvent();
                    e.feed = feed.name;
                    e.id = id;
                    e.ed = (DateTime)rdr["ed"];
                    e.traffic_type = rdr["traffic_type"] == DBNull.Value ? null : (string)rdr["traffic_type"];
                    e.severity = (int)rdr["severity"];
                    if (rdr["local_ip"] != DBNull.Value) {
                        if (Type.GetTypeCode(rdr.GetFieldType(rdr.GetOrdinal("local_ip"))) == TypeCode.String) {
                            e.local_ip = Util.IP2Long((string)rdr["local_ip"]);
                        } else {
                            e.local_ip = (long)rdr["local_ip"];
                        }
                    }
                    if (rdr["remote_ip"] != DBNull.Value) {
                        if (Type.GetTypeCode(rdr.GetFieldType(rdr.GetOrdinal("remote_ip"))) == TypeCode.String) {
                            e.remote_ip = Util.IP2Long((string)rdr["remote_ip"]);
                        } else {
                            e.remote_ip = (long)rdr["remote_ip"];
                        }
                    }
                    e.remote_hostname = rdr["remote_hostname"] == DBNull.Value ? null : (string)rdr["remote_hostname"];
                    e.local_port = (int)rdr["local_port"];
                    e.remote_port = (int)rdr["remote_port"];
                    e.direction = rdr["direction"] == DBNull.Value ? null : (string)rdr["direction"];
                    e.repetition = (int)rdr["repetition"];
                    e.protocol = rdr["protocol"] == DBNull.Value ? null : (string)rdr["protocol"];
                    e.app_name = rdr["app_name"] == DBNull.Value ? null : (string)rdr["app_name"];

                    if (rdr["alert"] != DBNull.Value && (byte)rdr["alert"] == 1) {
                        e.alert = true;
                    }
                    e.location = rdr["location"] == DBNull.Value ? null : (string)rdr["location"];
                    e.intrusion_url = rdr["intrusion_url"] == DBNull.Value ? null : (string)rdr["intrusion_url"];
                    e.intrusion_payload_url = rdr["intrusion_payload_url"] == DBNull.Value ? null : (string)rdr["intrusion_payload_url"];
                    e.description = rdr["description"] == DBNull.Value ? null : (string)rdr["description"];

                    feed.events.Add(e);

                    if ((DateTime)rdr["ed"] < mindt) {
                        mindt = (DateTime)rdr["ed"];
                    }

                    if ((DateTime)rdr["ed"] > maxdt) {
                        maxdt = (DateTime)rdr["ed"];
                    }
                }
            } catch (Exception e) {
                feed.error = e.Message;
            } finally {
                rdr.Close();
                rdr.Dispose();
                cmd.Dispose();
                conn.Close();
                conn.Dispose();
            }

            return feed;
        }
        public Feed getHostFirewallDetail(string id, DateTime startDate, DateTime endDate)
        {
            SqlConnection conn = new SqlConnection();
            SqlCommand cmd = new SqlCommand();
            SqlDataReader rdr = null;

            Feed feed = new Feed();
            feed.name = "Firewall";

            string sql = @"
                SELECT	DATEADD(second, [EVENT_TIME] / 1000, '1970-01-01') AS ed,
                        NULL AS protocol,
                        (SELECT CASE [EVENT_ID]
                            WHEN 301 THEN 'TCP Initiated'
                            WHEN 302 THEN 'UDP datagram'
                            WHEN 303 THEN 'Ping request'
                            WHEN 304 THEN 'TCP Completed'
                            WHEN 305 THEN 'Traffic (other)'
                            WHEN 306 THEN 'ICMP packet'
                            WHEN 307 THEN 'Ethernet packet'
                            WHEN 308 THEN 'IP Packet' END) AS traffic_type,
                        LOCAL_HOST_IP AS local_ip,
                        REMOTE_HOST_IP AS remote_ip,
                        REMOTE_HOST_NAME AS remote_hostname,
                        LOCAL_PORT AS local_port,
                        REMOTE_PORT AS remote_port,
                        (SELECT CASE TRAFFIC_DIRECTION
                            WHEN 0 THEN 'Unknown'
                            WHEN 1 THEN 'Inbound'
                            WHEN 2 THEN 'Outbound'
                        END) AS direction,
                        NULL AS severity,
                        NULL AS severity_string,
                        BLOCKED AS blocked,
                        APP_NAME AS app_name,
                        ALERT AS Alert,
                        RULE_NAME AS rule_name,
                        NULL AS location,
                        null AS repetition
                FROM	v_agent_packet_log l
                WHERE	l.COMPUTER_ID = @Id
                        AND l.BLOCKED = 1
                        AND DATEADD(second, l.[EVENT_TIME] / 1000, '1970-01-01') BETWEEN @StartDate AND @EndDate

                UNION

                SELECT	DATEADD(second, [EVENT_TIME] / 1000, '1970-01-01') AS ed,
                        (SELECT CASE [NETWORK_PROTOCOL]
                            WHEN 1 THEN 'Others'
                            WHEN 2 THEN 'TCP'
                            WHEN 3 THEN 'UDP' END) AS protocol,
                        (SELECT CASE [EVENT_ID]
                            WHEN 301 THEN 'TCP Initiated'
                            WHEN 302 THEN 'UDP datagram'
                            WHEN 303 THEN 'Ping request'
                            WHEN 304 THEN 'TCP Completed'
                            WHEN 305 THEN 'Traffic (other)'
                            WHEN 306 THEN 'ICMP packet'
                            WHEN 307 THEN 'Ethernet packet'
                            WHEN 308 THEN 'IP Packet' END) AS traffic_type,
                        LOCAL_HOST_IP AS local_ip,
                        REMOTE_HOST_IP AS remote_ip,
                        [REMOTE_HOST_NAME] AS remote_hostname,
                        [LOCAL_PORT] AS local_port,
                        [REMOTE_PORT] AS remote_port,
                        (SELECT CASE TRAFFIC_DIRECTION
                            WHEN 0 THEN 'Unknown'
                            WHEN 1 THEN 'Inbound'
                            WHEN 2 THEN 'Outbound'
                        END) AS direction,
                        [SEVERITY],	-- 0 to 15, lower is worse
                        (SELECT CASE [SEVERITY]
                            WHEN 0 THEN 'Critical'
                            WHEN 1 THEN 'Critical'
                            WHEN 2 THEN 'Critical'
                            WHEN 3 THEN 'Critical'
                            WHEN 4 THEN 'Major'
                            WHEN 5 THEN 'Major'
                            WHEN 6 THEN 'Major'
                            WHEN 7 THEN 'Major'
                            WHEN 8 THEN 'Minor'
                            WHEN 9 THEN 'Minor'
                            WHEN 10 THEN 'Minor'
                            WHEN 11 THEN 'Minor'
                            WHEN 12 THEN 'Info'
                            WHEN 13 THEN 'Info'
                            WHEN 14 THEN 'Info'
                            WHEN 15 THEN 'Info'
                            END) AS Severity_String,
                        [BLOCKED],
                        [APP_NAME],
                        [ALERT],
                        [RULE_NAME],
                        [LOCATION_NAME],
                        [REPETITION]
                FROM	v_agent_traffic_log l
                WHERE	l.COMPUTER_ID = @Id
                        AND l.BLOCKED = 1
                        AND DATEADD(second, l.[EVENT_TIME] / 1000, '1970-01-01') BETWEEN @StartDate AND @EndDate";

            try {
                conn.ConnectionString = this.sqlConnectionString;
                conn.Open();

                cmd = new SqlCommand(sql, conn);
                cmd.CommandType = System.Data.CommandType.Text;

                cmd.Parameters.Add(new SqlParameter("@Id", SqlDbType.VarChar, 32)).Value = id;
                cmd.Parameters.Add(new SqlParameter("@StartDate", SqlDbType.DateTime)).Value = startDate;
                cmd.Parameters.Add(new SqlParameter("@EndDate", SqlDbType.DateTime)).Value = endDate;
                rdr = cmd.ExecuteReader();

                while (rdr.Read()) {
                    FirewallEvent e = new FirewallEvent();
                    e.feed = feed.name;
                    e.ed = (DateTime)rdr["ed"];
                    if (rdr["local_ip"] != DBNull.Value) {
                        if (Type.GetTypeCode(rdr.GetFieldType(rdr.GetOrdinal("local_ip"))) == TypeCode.String) {
                            e.local_ip = Util.IP2Long((string)rdr["local_ip"]);
                        } else {
                            e.local_ip = (long)rdr["local_ip"];
                        }
                    }
                    if (rdr["remote_ip"] != DBNull.Value) {
                        if (Type.GetTypeCode(rdr.GetFieldType(rdr.GetOrdinal("remote_ip"))) == TypeCode.String) {
                            e.remote_ip = Util.IP2Long((string)rdr["remote_ip"]);
                        } else {
                            e.remote_ip = (long)rdr["remote_ip"];
                        }
                    }
                    e.protocol = rdr["protocol"] == DBNull.Value ? null : (string)rdr["protocol"];
                    e.traffic_type = rdr["traffic_type"] == DBNull.Value ? null : (string)rdr["traffic_type"];
                    e.remote_hostname = rdr["remote_hostname"] == DBNull.Value ? null : (string)rdr["remote_hostname"];
                    e.local_port = (int)rdr["local_port"];
                    e.remote_port = (int)rdr["remote_port"];
                    e.direction = rdr["direction"] == DBNull.Value ? null : (string)rdr["direction"];
                    e.repetition = (int)rdr["repetition"];
                    if (rdr["blocked"] != DBNull.Value && (byte)rdr["blocked"] == 1) {
                        e.action_taken = "Blocked";
                    }
                    e.app_name = rdr["app_name"] == DBNull.Value ? null : (string)rdr["app_name"];
                    if (rdr["alert"] != DBNull.Value && (int)rdr["alert"] == 1) {
                        e.alert = true;
                    }
                    e.rule_name = rdr["rule_name"] == DBNull.Value ? null : (string)rdr["rule_name"];
                    e.location = rdr["location"] == DBNull.Value ? null : (string)rdr["location"];

                    feed.events.Add(e);

                    if ((DateTime)rdr["ed"] < mindt) {
                        mindt = (DateTime)rdr["ed"];
                    }

                    if ((DateTime)rdr["ed"] > maxdt) {
                        maxdt = (DateTime)rdr["ed"];
                    }
                }
            } catch (Exception e) {
                feed.error = e.Message;
            } finally {
                rdr.Close();
                rdr.Dispose();
                cmd.Dispose();
                conn.Close();
                conn.Dispose();
            }

            return feed;
        }
        public Feed getHostDownloadDetail(string id, DateTime startDate, DateTime endDate)
        {
            SqlConnection conn = new SqlConnection();
            SqlCommand cmd = new SqlCommand();
            SqlDataReader rdr = null;

            Feed feed = new Feed();
            feed.name = "Downloads";

            string sql = @"
                SELECT	dateadd(second, c.TIME_STAMP / 1000, '1970-01-01') AS ed,
                        a.[APPLICATION_NAME] AS app_name,
                        a.[COMPANY_NAME] AS app_company,
                        a.[VERSION] AS app_version,
                        a.[FILE_SIZE] AS filesize,
                        a.[APP_DESCRIPTION] AS description,
                        c.[APP_HASH] AS app_md5,
                        c.[CREATOR_SHA2] AS app_sha2,
                        c.[DOWNLOAD_URL] AS url,
                        a.[SIGNER_NAME] AS signer,
                        a.[LAST_MODIFY_TIME] AS last_modify_time
                FROM	COMPUTER_APPLICATION c
                        LEFT JOIN SEM_APPLICATION a on a.APP_HASH = c.APP_HASH
                WHERE	c.COMPUTER_ID = @Id
                        AND dateadd(second, c.TIME_STAMP / 1000, '1970-01-01') BETWEEN @StartDate AND @EndDate
            ";
            try {
                conn.ConnectionString = this.sqlConnectionString;
                conn.Open();

                cmd = new SqlCommand(sql, conn);
                cmd.CommandType = System.Data.CommandType.Text;

                cmd.Parameters.Add(new SqlParameter("@Id", SqlDbType.VarChar, 32)).Value = id;
                cmd.Parameters.Add(new SqlParameter("@StartDate", SqlDbType.DateTime)).Value = startDate;
                cmd.Parameters.Add(new SqlParameter("@EndDate", SqlDbType.DateTime)).Value = endDate;
                rdr = cmd.ExecuteReader();

                while (rdr.Read()) {
                    DownloadEvent e = new DownloadEvent();
                    e.feed = feed.name;
                    e.id = id;
                    e.ed = (DateTime)rdr["ed"];
                    e.app_name = rdr["app_name"] == DBNull.Value ? null : (string)rdr["app_name"];
                    e.app_company = rdr["app_company"] == DBNull.Value ? null : (string)rdr["app_company"];
                    e.app_version = rdr["app_version"] == DBNull.Value ? null : (string)rdr["app_version"];
                    e.filesize = (long)rdr["filesize"];
                    e.description = rdr["description"] == DBNull.Value ? null : (string)rdr["description"];
                    e.app_md5 = rdr["app_md5"] == DBNull.Value ? null : (string)rdr["app_md5"];
                    e.app_sha2 = rdr["app_sha2"] == DBNull.Value ? null : (string)rdr["app_sha2"];
                    e.url = rdr["url"] == DBNull.Value ? null : (string)rdr["url"];
                    e.signer = rdr["signer"] == DBNull.Value ? null : (string)rdr["signer"];
                    e.last_modify_time = (long)rdr["last_modify_time"];

                    feed.events.Add(e);

                    if ((DateTime)rdr["ed"] < mindt) {
                        mindt = (DateTime)rdr["ed"];
                    }

                    if ((DateTime)rdr["ed"] > maxdt) {
                        maxdt = (DateTime)rdr["ed"];
                    }
                }
            } catch (Exception e) {
                feed.error = e.Message;
            } finally {
                rdr.Close();
                rdr.Dispose();
                cmd.Dispose();
                conn.Close();
                conn.Dispose();
            }

            return feed;
        }
        public Feed getHostAntiVirusDetail(string id, DateTime startDate, DateTime endDate)
        {
            SqlConnection conn = new SqlConnection();
            SqlCommand cmd = new SqlCommand();
            SqlDataReader rdr = null;

            Feed feed = new Feed();
            feed.name = "AV Engine";

            string sql = @"
                SELECT
                        a.[ALERTDATETIME] AS ed,
                        a.[SOURCE] AS source,
                        a.filepath,
                        a.[DESCRIPTION] AS description,
                        (replace([ACTUALACTION].[ACTUALACTION],' ', '_')) AS action_taken,
                        app.APP_NAME AS app_name,
                        app.[COMPANY_NAME] AS app_company,
                        app.[APP_VERSION] AS app_version,
                        app.[FILE_SIZE] AS filesize,
                        app.APP_TYPE AS app_type,
                        v.[VIRUSNAME] AS virus_name,
                        a.[USER_NAME],
                        COALESCE(alerts.[SENSITIVITY], 0) AS sensitivity,
                        COALESCE(alerts.[DETECTION_SCORE], 0) AS detection_score,
                        COALESCE(alerts.[COH_ENGINE_VERSION], '') AS 'truscan_engine_version',
                        COALESCE(alerts.[DIS_SUBMIT], 0) AS submission_recommendation,
                        COALESCE(alerts.[WHITELIST_REASON], 0) AS whitelist_reason,
                        COALESCE(alerts.[DISPOSITION], 0) AS disposition,
                        COALESCE(alerts.[Confidence], 0) AS confidence,
                        COALESCE(alerts.[PREVALENCE], 0) AS prevalence,
                        COALESCE(alerts.[URL], '') AS url,
                        COALESCE(alerts.[WEB_DOMAIN], '') AS web_domain,
                        COALESCE(alerts.[DOWNLOADER], '') AS downloader,
                        COALESCE(alerts.[CIDS_ONOFF], 0) AS cids_onoff,
                        COALESCE(alerts.[RISK_LEVEL], 0) AS risk_level
                FROM	V_ALERTS a
                        LEFT JOIN HPP_APPLICATION app ON a.[HPP_APP_IDX] = app.[APP_IDX]
                        LEFT JOIN IDENTITY_MAP g ON a.[CLIENTGROUP_IDX] = g.[ID]
                        LEFT JOIN [V_SEM_COMPUTER] ON a.[COMPUTER_IDX]= [V_SEM_COMPUTER].[COMPUTER_ID]
                        LEFT JOIN V_VIRUS v ON v.[VIRUSNAME_IDX] = a.VIRUSNAME_IDX
                        LEFT JOIN [ACTUALACTION] on a.[ACTUALACTION_IDX] = [ACTUALACTION].[ACTUALACTION_IDX]
                        LEFT JOIN [HPP_ALERTS] alerts on a.[IDX] = alerts.[IDX]
                WHERE	[V_SEM_COMPUTER].COMPUTER_ID = @Id
            --						AND app_type != -1	 -- Seems to return junk data.
                        AND a.[ALERTDATETIME] BETWEEN @StartDate AND @EndDate
                ORDER	BY g.[NAME],
                        a.[ALERTDATETIME],
                        v.[VIRUSNAME]";

            try {
                conn.ConnectionString = this.sqlConnectionString;
                conn.Open();

                cmd = new SqlCommand(sql, conn);
                cmd.CommandType = System.Data.CommandType.Text;

                cmd.Parameters.Add(new SqlParameter("@Id", SqlDbType.VarChar, 32)).Value = id;
                cmd.Parameters.Add(new SqlParameter("@StartDate", SqlDbType.DateTime)).Value = startDate;
                cmd.Parameters.Add(new SqlParameter("@EndDate", SqlDbType.DateTime)).Value = endDate;
                rdr = cmd.ExecuteReader();

                while (rdr.Read()) {
                    VirusEvent e = new VirusEvent();
                    e.feed = feed.name;
                    e.id = id;
                    e.ed = (DateTime)rdr["ed"];
                    e.filepath = rdr["filepath"] == DBNull.Value ? null : (string)rdr["filepath"];
                    e.action_taken = rdr["action_taken"] == DBNull.Value ? null : (string)rdr["action_taken"];
                    e.source = rdr["source"] == DBNull.Value ? null : (string)rdr["source"];
                    e.app_name = rdr["app_name"] == DBNull.Value ? null : (string)rdr["app_name"];
                    e.app_company = rdr["app_company"] == DBNull.Value ? null : (string)rdr["app_company"];
                    e.app_version = rdr["app_version"] == DBNull.Value ? null : (string)rdr["app_version"];
                    e.filesize = (long)rdr["filesize"];
                    e.app_type = (int)rdr["app_type"];
                    e.virus_name = rdr["virus_name"] == DBNull.Value ? null : (string)rdr["virus_name"];
                    e.sensitivity = (int)rdr["sensitivity"];
                    e.detection_score = (int)rdr["detection_score"];
                    e.truscan_engine_version = rdr["truscan_engine_version"] == DBNull.Value ? null : (string)rdr["truscan_engine_version"];
                    e.submission_recommendation = (int)rdr["submission_recommendation"];
                    e.whitelist_reason = (int)rdr["whitelist_reason"];
                    e.disposition = (int)rdr["disposition"];	// 127 if there's no data to compare to
                    e.confidence = (int)rdr["confidence"];
                    e.prevalence = (int)rdr["prevalence"];
                    e.url = rdr["url"] == DBNull.Value ? null : (string)rdr["url"].ToString();
                    e.web_domain = rdr["web_domain"] == DBNull.Value ? null : (string)rdr["web_domain"];
                    e.downloader = rdr["downloader"] == DBNull.Value ? null : (string)rdr["downloader"];
                    e.cids_onoff = (int)rdr["cids_onoff"];
                    e.risk_level = (int)rdr["risk_level"];

                    feed.events.Add(e);

                    if ((DateTime)rdr["ed"] < mindt) {
                        mindt = (DateTime)rdr["ed"];
                    }

                    if ((DateTime)rdr["ed"] > maxdt) {
                        maxdt = (DateTime)rdr["ed"];
                    }
                }
            } catch (Exception e) {
                feed.error = e.Message;
            } finally {
                rdr.Close();
                rdr.Dispose();
                cmd.Dispose();
                conn.Close();
                conn.Dispose();
            }

            return feed;
        }