diff --git a/iTrust/sql/data/hcp_additional_diagnosis_data.sql b/iTrust/sql/data/hcp_additional_diagnosis_data.sql
new file mode 100644
index 0000000000000000000000000000000000000000..29163d99144e43aa8e334f49d9e05ab5a39c5419
--- /dev/null
+++ b/iTrust/sql/data/hcp_additional_diagnosis_data.sql
@@ -0,0 +1,29 @@
+INSERT INTO officevisits(ID, visitDate, HCPID, notes, PatientID, HospitalID)
+VALUES
+(125, '2020-11-18', 9000000000, 'Diagnose Cataracts', 1, '1'),   
+(126, '2020-11-18', 9000000000, 'Diagnose Cataracts', 2, '1'),   
+(127, '2020-11-18', 9000000000, 'Diagnose Cataracts', 3, '1'),   
+(128, '2020-11-18', 9000000000, 'Diagnose Cataracts', 4, '1'),   
+(129, '2020-11-18', 9000000000, 'Diagnose Cataracts', 21, '1'),  
+(130, '2020-11-18', 9000000000, 'Diagnose Cataracts', 22, '1'),  
+(131, '2020-11-18', 9000000000, 'Diagnose Cataracts', 23, '1'),  
+(132, '2020-11-18', 9000000000, 'Diagnose Cataracts', 24, '1'),  
+(133, '2020-11-18', 9000000000, 'Diagnose Cataracts', 105, '1'), 
+(134, '2020-11-18', 9000000000, 'Diagnose Cataracts', 107, '1')  
+
+ON DUPLICATE KEY UPDATE id = id;
+
+INSERT INTO ovdiagnosis(ID, VisitID, ICDCode)
+VALUES
+(125, 125, 26.8),
+(126, 126, 26.8),
+(127, 127, 26.8),
+(128, 128, 26.8),
+(129, 129, 26.8),
+(130, 130, 26.8),
+(131, 131, 26.8),
+(132, 132, 26.8),
+(133, 133, 26.8),
+(134, 134, 26.8)
+
+ON DUPLICATE KEY UPDATE VisitID = VALUES(VisitID), ICDCode = VALUES(ICDCode);
diff --git a/iTrust/sql/data/hcp_diagnosis_data.sql b/iTrust/sql/data/hcp_diagnosis_data.sql
index 37684d9fb85a272d1c71c97e243d6beced141a43..f0def171bbbe09e7242ce842d96afc93790ee2d9 100644
--- a/iTrust/sql/data/hcp_diagnosis_data.sql
+++ b/iTrust/sql/data/hcp_diagnosis_data.sql
@@ -1,5 +1,3 @@
-
-
 INSERT INTO officevisits(ID, visitDate, HCPID, notes, PatientID, HospitalID)
 VALUES
 (107, '2007-03-09', 9000000004, 'Diagnose Echovirus', 2, '1'),
@@ -47,6 +45,7 @@ VALUES
 (122, 122, 72.00),
 (123, 123, 72.00),
 (124, 124, 72.00)
+
 ON DUPLICATE KEY UPDATE VisitID = VALUES(VisitID), ICDCode = VALUES(ICDCode);
 
 INSERT INTO labprocedure (PatientMID, LaboratoryProcedureCode, Rights, Status, Commentary, Results, OfficeVisitID, UpdatedDate,
diff --git a/iTrust/sql/data/malariaEpidemic.sql b/iTrust/sql/data/malariaEpidemic1.sql
similarity index 100%
rename from iTrust/sql/data/malariaEpidemic.sql
rename to iTrust/sql/data/malariaEpidemic1.sql
diff --git a/iTrust/sql/data/malariaEpidemic2.sql b/iTrust/sql/data/malariaEpidemic2.sql
new file mode 100644
index 0000000000000000000000000000000000000000..cee03251dcb6466825acd2dee32f5baa56125648
--- /dev/null
+++ b/iTrust/sql/data/malariaEpidemic2.sql
@@ -0,0 +1,63 @@
+INSERT INTO officevisits(ID, visitDate, HCPID, notes, PatientID, HospitalID)
+VALUES
+(218, CONCAT(YEAR(NOW())-20, '-11-01'), 9000000000, 'Diagnose Malaria', 1, '1'),
+(219, CONCAT(YEAR(NOW())-20, '-11-02'), 9000000000, 'Diagnose Malaria', 2, '1'),
+(220, CONCAT(YEAR(NOW())-20, '-11-03'), 9000000000, 'Diagnose Malaria', 3, '1'),
+(221, CONCAT(YEAR(NOW())-20, '-11-04'), 9000000000, 'Diagnose Malaria', 4, '1'),
+(222, CONCAT(YEAR(NOW())-20, '-11-05'), 9000000000, 'Diagnose Malaria', 5, '1'),
+(223, CONCAT(YEAR(NOW())-20, '-11-06'), 9000000000, 'Diagnose Malaria', 6, '1'),
+(224, CONCAT(YEAR(NOW())-20, '-11-07'), 9000000000, 'Diagnose Malaria', 7, '1'),
+(225, CONCAT(YEAR(NOW())-20, '-11-08'), 9000000000, 'Diagnose Malaria', 8, '1'),
+(226, CONCAT(YEAR(NOW())-20, '-11-09'), 9000000000, 'Diagnose Malaria', 25, '1'),
+(227, CONCAT(YEAR(NOW())-20, '-11-10'), 9000000000, 'Diagnose Malaria', 20, '1'),
+(228, CONCAT(YEAR(NOW())-20, '-11-11'), 9000000000, 'Diagnose Malaria', 21, '1'),
+(229, CONCAT(YEAR(NOW())-20, '-11-12'), 9000000000, 'Diagnose Malaria', 101, '1'),
+(230, CONCAT(YEAR(NOW())-20, '-11-13'), 9000000000, 'Diagnose Malaria', 106, '1'),
+(231, CONCAT(YEAR(NOW())-20, '-11-14'), 9000000000, 'Diagnose Malaria', 300, '1'),
+
+(233, CONCAT(YEAR(NOW())-20-1, '-11-02'), 9000000000, 'Diagnose Malaria', 2, '1'),
+(234, CONCAT(YEAR(NOW())-20-1, '-11-03'), 9000000000, 'Diagnose Malaria', 3, '1'),
+(235, CONCAT(YEAR(NOW())-20-1, '-11-04'), 9000000000, 'Diagnose Malaria', 4, '1'),
+(236, CONCAT(YEAR(NOW())-20-1, '-11-05'), 9000000000, 'Diagnose Malaria', 5, '1'),
+(237, CONCAT(YEAR(NOW())-20-1, '-11-06'), 9000000000, 'Diagnose Malaria', 6, '1'),
+(238, CONCAT(YEAR(NOW())-20-1, '-11-07'), 9000000000, 'Diagnose Malaria', 7, '1'),
+(239, CONCAT(YEAR(NOW())-20-1, '-11-08'), 9000000000, 'Diagnose Malaria', 8, '1'),
+(240, CONCAT(YEAR(NOW())-20-1, '-11-09'), 9000000000, 'Diagnose Malaria', 25, '1'),
+(241, CONCAT(YEAR(NOW())-20-1, '-11-10'), 9000000000, 'Diagnose Malaria', 20, '1'),
+(242, CONCAT(YEAR(NOW())-20-1, '-11-11'), 9000000000, 'Diagnose Malaria', 21, '1'),
+(243, CONCAT(YEAR(NOW())-20-1, '-11-12'), 9000000000, 'Diagnose Malaria', 101, '1')
+
+
+ON DUPLICATE KEY UPDATE id = id;
+
+INSERT INTO ovdiagnosis(ID, VisitID, ICDCode)
+VALUES
+
+(218, 218, 84.50), 
+(219, 219, 84.50), 
+(220, 220, 84.50), 
+(221, 221, 84.50), 
+(222, 222, 84.50), 
+(223, 223, 84.50), 
+(224, 224, 84.50), 
+(225, 225, 84.50), 
+(226, 226, 84.50), 
+(227, 227, 84.50), 
+(228, 228, 84.50), 
+(229, 229, 84.50), 
+(230, 230, 84.50), 
+(231, 231, 84.50), 
+(232, 232, 84.50), 
+(233, 233, 84.50), 
+(234, 234, 84.50), 
+(235, 235, 84.50), 
+(236, 236, 84.50), 
+(237, 237, 84.50), 
+(238, 238, 84.50), 
+(239, 239, 84.50), 
+(240, 240, 84.50), 
+(241, 241, 84.50), 
+(242, 242, 84.50),
+(243, 243, 84.50)
+
+ON DUPLICATE KEY UPDATE VisitID = VALUES(VisitID), ICDCode = VALUES(ICDCode);
diff --git a/iTrust/sql/data/malariaEpidemic3.sql b/iTrust/sql/data/malariaEpidemic3.sql
new file mode 100644
index 0000000000000000000000000000000000000000..78485fd32b6e3c3ae7b4ad5799f567e3a36cf682
--- /dev/null
+++ b/iTrust/sql/data/malariaEpidemic3.sql
@@ -0,0 +1,44 @@
+INSERT INTO officevisits(ID, visitDate, HCPID, notes, PatientID, HospitalID)
+VALUES
+(218, CONCAT(YEAR(NOW()), '-11-02'), 9000000000, 'Diagnose Malaria', 1, '1'),
+(219, CONCAT(YEAR(NOW()), '-11-02'), 9000000000, 'Diagnose Malaria', 2, '1'),
+
+(221, CONCAT(YEAR(NOW()), '-11-09'), 9000000000, 'Diagnose Malaria', 6, '1'),
+(222, CONCAT(YEAR(NOW()), '-11-09'), 9000000000, 'Diagnose Malaria', 7, '1'),
+
+
+(223, CONCAT(YEAR(NOW())-1, '-11-02'), 9000000000, 'Diagnose Malaria', 1, '1'),
+(224, CONCAT(YEAR(NOW())-1, '-11-02'), 9000000000, 'Diagnose Malaria', 2, '1'),
+(225, CONCAT(YEAR(NOW())-2, '-11-02'), 9000000000, 'Diagnose Malaria', 3, '1'),
+(226, CONCAT(YEAR(NOW())-2, '-11-02'), 9000000000, 'Diagnose Malaria', 4, '1'),
+(227, CONCAT(YEAR(NOW())-1, '-11-09'), 9000000000, 'Diagnose Malaria', 6, '1'),
+(228, CONCAT(YEAR(NOW())-1, '-11-09'), 9000000000, 'Diagnose Malaria', 7, '1'),
+(229, CONCAT(YEAR(NOW())-2, '-11-09'), 9000000000, 'Diagnose Malaria', 8, '1'),
+(230, CONCAT(YEAR(NOW())-2, '-11-09'), 9000000000, 'Diagnose Malaria', 20, '1'),
+
+
+(231, CONCAT(YEAR(NOW())-20, '-10-02'), 9000000000, 'Diagnose Malaria', 3, '1'),
+(232, CONCAT(YEAR(NOW())-20, '-10-09'), 9000000000, 'Diagnose Malaria', 6, '1')
+
+
+ON DUPLICATE KEY UPDATE id = id;
+
+INSERT INTO ovdiagnosis(ID, VisitID, ICDCode)
+VALUES
+(218, 218, 84.50),
+(219, 219, 84.50),
+(220, 220, 84.50),
+(221, 221, 84.50),
+(222, 222, 84.50),
+(223, 223, 84.50),
+(224, 224, 84.50),
+(225, 225, 84.50),
+(226, 226, 84.50),
+(227, 227, 84.50),
+(228, 228, 84.50),
+(229, 229, 84.50),
+(230, 230, 84.50),
+(231, 231, 84.50),
+(232, 232, 84.50)
+
+ON DUPLICATE KEY UPDATE VisitID = VALUES(VisitID), ICDCode = VALUES(ICDCode);
diff --git a/iTrust/src/edu/ncsu/csc/itrust/action/ViewDiagnosisStatisticsAction.java b/iTrust/src/edu/ncsu/csc/itrust/action/ViewDiagnosisStatisticsAction.java
index 509296bce95820bcad84abeab94e0ceb30d64907..a6f01b269e3e19cbf648a58e302193fedb13b238 100644
--- a/iTrust/src/edu/ncsu/csc/itrust/action/ViewDiagnosisStatisticsAction.java
+++ b/iTrust/src/edu/ncsu/csc/itrust/action/ViewDiagnosisStatisticsAction.java
@@ -20,291 +20,283 @@ import edu.ncsu.csc.itrust.exception.ITrustException;
  * and get diagnosis statistics for a specified Zip code, Diagnosis code, and date range.
  */
 public class ViewDiagnosisStatisticsAction {
-	/** Database access methods for ICD codes (diagnoses) */
-	private ICDCodesDAO icdDAO;
-	/** Database access methods for diagnosis information */
-	private DiagnosesDAO diagnosesDAO;
-	/** ICD Code for malaria */
-	private static final String ICD_MALARIA = "84.50";
-	/** ICD Code for Influenza */
-	private static final String ICD_INFLUENZA = "487.00";
-	
-	/**
-	 * Constructor for the action. Initializes DAO fields
-	 * @param factory The session's factory for DAOs
-	 */
-	public ViewDiagnosisStatisticsAction(DAOFactory factory) {
-		this.icdDAO = factory.getICDCodesDAO();
-		this.diagnosesDAO = factory.getDiagnosesDAO();
-	}
-	
-	/**
-	 * Gets all the diagnosis codes in iTrust and returns them in a list of beans.
-	 * 
-	 * @return List of DiagnosisBeans correlating to all ICDCodes
-	 * @throws ITrustException
-	 */
-	public List<DiagnosisBean> getDiagnosisCodes() throws ITrustException  {
-		return icdDAO.getAllICDCodes();
-	}
-	
-	/**
-	 * Gets the counts of local and regional diagnoses for the specified input
-	 * 
-	 * @param lowerDate The beginning date for the time range
-	 * @param upperDate The ending date for the time range
-	 * @param icdCode The diagnosis code to examine
-	 * @param zip The zip code to examine
-	 * @return A bean containing the local and regional counts
-	 * @throws FormValidationException
-	 * @throws ITrustException
-	 */
-	public DiagnosisStatisticsBean getDiagnosisStatistics(String lowerDate, String upperDate, String icdCode, String zip) throws FormValidationException, ITrustException {
-		DiagnosisStatisticsBean dsBean;
-		try {
-			
-			if (lowerDate == null || upperDate == null || icdCode == null)
-				return null;
-			
-			Date lower = new SimpleDateFormat("MM/dd/yyyy").parse(lowerDate);
-			Date upper = new SimpleDateFormat("MM/dd/yyyy").parse(upperDate);
+    /** Database access methods for ICD codes (diagnoses) */
+    private ICDCodesDAO icdDAO;
+    /** Database access methods for diagnosis information */
+    private DiagnosesDAO diagnosesDAO;
+    /** ICD Code for malaria */
+    private static final String ICD_MALARIA = "84.50";
+    /** ICD Code for Influenza */
+    private static final String ICD_INFLUENZA = "487.00";
+    
+    /**
+     * Constructor for the action. Initializes DAO fields
+     * @param factory The session's factory for DAOs
+     */
+    public ViewDiagnosisStatisticsAction(DAOFactory factory) {
+        this.icdDAO = factory.getICDCodesDAO();
+        this.diagnosesDAO = factory.getDiagnosesDAO();
+    }
+    
+    /**
+     * Gets all the diagnosis codes in iTrust and returns them in a list of beans.
+     * 
+     * @return List of DiagnosisBeans correlating to all ICDCodes
+     * @throws ITrustException
+     */
+    public List<DiagnosisBean> getDiagnosisCodes() throws ITrustException  {
+        return icdDAO.getAllICDCodes();
+    }
+    
+    /**
+     * Gets the counts of local and regional diagnoses for the specified input
+     * 
+     * @param lowerDate The beginning date for the time range
+     * @param upperDate The ending date for the time range
+     * @param icdCode The diagnosis code to examine
+     * @param zip The zip code to examine
+     * @return A bean containing the local and regional counts
+     * @throws FormValidationException
+     * @throws ITrustException
+     */
+    public DiagnosisStatisticsBean getDiagnosisStatistics(String lowerDate, String upperDate, String icdCode, String zip) throws FormValidationException, ITrustException {
+        DiagnosisStatisticsBean dsBean;
+        try {
+            
+            if (lowerDate == null || upperDate == null || icdCode == null)
+                return null;
+            
+            Date lower = new SimpleDateFormat("MM/dd/yyyy").parse(lowerDate);
+            Date upper = new SimpleDateFormat("MM/dd/yyyy").parse(upperDate);
 
-			if (lower.after(upper))
-				throw new FormValidationException("Start date must be before end date!");
-			
-			if (!zip.matches("([0-9]{5})|([0-9]{5}-[0-9]{4})"))
-				throw new FormValidationException("Zip Code must be 5 digits!");
+            if (lower.after(upper))
+                throw new FormValidationException("Start date must be before end date!");
+            
+            if (!zip.matches("([0-9]{5})|([0-9]{5}-[0-9]{4})"))
+                throw new FormValidationException("Zip Code must be 5 digits!");
 
-			boolean validCode = false;
-			for(DiagnosisBean diag : getDiagnosisCodes()) {
-					if (diag.getICDCode().equals(icdCode))
-						validCode = true;
-			}
-			if (validCode == false) {
-				throw new FormValidationException("ICDCode must be valid diagnosis!");
-			}
+            boolean validCode = false;
+            for(DiagnosisBean diag : getDiagnosisCodes()) {
+                    if (diag.getICDCode().equals(icdCode))
+                        validCode = true;
+            }
+            if (validCode == false) {
+                throw new FormValidationException("ICDCode must be valid diagnosis!");
+            }
 
-			dsBean = diagnosesDAO.getDiagnosisCounts(icdCode, zip, lower, upper);
-			
-		} catch (ParseException e) {
-			throw new FormValidationException("Enter dates in MM/dd/yyyy");
-		} 
-		
-		
-		return dsBean;
-	}
-	
-	/**
-	 * Gets the local and regional counts for the specified week and calculates the prior average.
-	 * 
-	 * @param startDate a date in the week to analyze
-	 * @param icdCode the diagnosis to analyze
-	 * @param zip the area to analyze
-	 * @param threshold threshold
-	 * @return statistics for the week and previous averages
-	 * @throws FormValidationException
-	 * @throws DBException
-	 */
-	public ArrayList<DiagnosisStatisticsBean> getEpidemicStatistics(String startDate, String icdCode, String zip, String threshold) throws FormValidationException, DBException {
-		
-		if (startDate == null || icdCode == null)
-			return null;
-		
-		if (!(icdCode.equals("84.50") || icdCode.equals("487.00")) ) {
-			throw new FormValidationException("Exception");
-		}
-		if(ICD_MALARIA.equals(icdCode)){
-			try{
-				Integer.parseInt(threshold);
-			}catch(NumberFormatException e){
-				throw new FormValidationException("Threshold must be an integer.");
-			}
-		}
-		Date lower;  //lower, which is parsed to startDate
-		try {
-			lower = new SimpleDateFormat("MM/dd/yyyy").parse(startDate);
-		} catch (ParseException e) {
-			throw new FormValidationException("Enter dates in MM/dd/yyyy");
-		}
-		if (!zip.matches("([0-9]{5})|([0-9]{5}-[0-9]{4})"))
-			throw new FormValidationException("Zip Code must be 5 digits!");
-		
-		DiagnosisStatisticsBean dbWeek = diagnosesDAO.getCountForWeekOf(icdCode, zip, lower);
-		DiagnosisStatisticsBean dbAvg = new DiagnosisStatisticsBean(zip, 0, 0, lower, lower);
-		
-		Calendar cal = Calendar.getInstance();
-		
-		Date start = diagnosesDAO.findEarliestIncident(icdCode); //start, which is set to earliest incident
-		Calendar startCal = Calendar.getInstance();
-		if(start != null)
-			startCal.setTime(start);
-		
-		ArrayList<DiagnosisStatisticsBean> ret = new ArrayList<DiagnosisStatisticsBean>();
-		if (start == null) {
-			ret.add(dbWeek);
-			ret.add(dbAvg);
-			return ret;
-		}
-		cal.setTime(lower); //cal, which is set to lower
-		Calendar lowerCal = Calendar.getInstance();
-		lowerCal.setTime(lower);
-		int weekOfYr = cal.get(Calendar.WEEK_OF_YEAR);
-		
-		cal.set(Calendar.YEAR, startCal.get(Calendar.YEAR));  //cal's year then gets set to start's year
-		ArrayList<DiagnosisStatisticsBean> dbList = new ArrayList<DiagnosisStatisticsBean>();
-		
-		while( cal.getTime().before(lower) && cal.get(Calendar.YEAR) != lowerCal.get(Calendar.YEAR)) {
-			dbList.add( diagnosesDAO.getCountForWeekOf(icdCode, zip, cal.getTime()) );
-			cal.add(Calendar.YEAR, 1);
-			cal.set(Calendar.WEEK_OF_YEAR, weekOfYr);
-			cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
-		}
-		
-		long avg = 0;
-		long avgRegion = 0;
-		if (dbList.size() > 0) {
-			for (DiagnosisStatisticsBean d : dbList) {
-				avg += d.getZipStats();
-				avgRegion += d.getRegionStats();
-			}
-			avg /= dbList.size();
-			avgRegion /= dbList.size();
-		}
-		
-		dbAvg.setRegionStats(avgRegion);
-		dbAvg.setZipStats(avg);
-		
-		ret.add(dbWeek);
-		ret.add(dbAvg);
-		return ret;
-	}
-	
-	/**
-	 * Determines if an Influenza Epidemic is happening
-	 * 
-	 * @param curDateStr a date in the currently evaluated week
-	 * @param zip the zip code to analyze
-	 * @return whether or not there is an epidemic
-	 * @throws ParseException
-	 * @throws DBException
-	 */
-	public boolean isFluEpidemic(String curDateStr, String zip) throws ParseException, DBException {
-		new SimpleDateFormat("MM/dd/yyyy").parse("01/04/1998");
-		Date curDate = new SimpleDateFormat("MM/dd/yyyy").parse(curDateStr);
-		
-		Calendar cal = Calendar.getInstance();
-		cal.setTime(curDate);
-		
-		int weekOfYr = cal.get(Calendar.WEEK_OF_YEAR);
-		double threshold = calcThreshold(weekOfYr);
-		double thresholdL = calcThreshold(weekOfYr-1);
-		double thresholdN = calcThreshold(weekOfYr+1); 
-		
-		DiagnosisStatisticsBean dbNow = diagnosesDAO.getCountForWeekOf(ICD_INFLUENZA, zip, cal.getTime());
-		cal.add(Calendar.HOUR, -12*7);
-		DiagnosisStatisticsBean dbLast = diagnosesDAO.getCountForWeekOf(ICD_INFLUENZA, zip, cal.getTime());
-		cal.add(Calendar.HOUR, 2*12*7);
-		DiagnosisStatisticsBean dbNext =  diagnosesDAO.getCountForWeekOf(ICD_INFLUENZA, zip, cal.getTime());
-		
-		double weekNow = (double) dbNow.getRegionStats();
-		double weekL = (double) dbLast.getRegionStats();
-		double weekN = (double) dbNext.getRegionStats();
-		
-		return weekNow > threshold && (weekL > thresholdL || weekN > thresholdN);
-		
-	}
-	
-	/**
-	 * Calculates the threshold of an influenza epidemic
-	 * 
-	 * @param weekNumber the week of the year
-	 * @return the epidemic threshold for flu cases
-	 */
-	private double calcThreshold(double weekNumber) {
-		return 5.34 + 0.271 * weekNumber + 3.45 * Math.sin(2 * Math.PI * weekNumber / 52.0) + 8.41 * Math.cos(2 * Math.PI * weekNumber / 52.0);
-	}
-	
-	/**
-	 * Determines whether a Malaria epidemic is happening
-	 * 
-	 * @param weekDate a date in the currently evaluated week
-	 * @param zip the zip code to analyze
-	 * @param thresholdStr the threshold for an epidemic
-	 * @return whether or not there is an epidemic
-	 * @throws DBException
-	 * @throws ParseException
-	 */
-	public boolean isMalariaEpidemic(String weekDate, String zip, String thresholdStr) throws DBException, ParseException {
-		
-		Date wkDate = new SimpleDateFormat("MM/dd/yyyy").parse(weekDate);
-		
-		ArrayList<DiagnosisStatisticsBean> dbList = new ArrayList<DiagnosisStatisticsBean>();
-		ArrayList<DiagnosisStatisticsBean> dbListL = new ArrayList<DiagnosisStatisticsBean>();
-		ArrayList<DiagnosisStatisticsBean> dbListN = new ArrayList<DiagnosisStatisticsBean>();
-		int threshold = Integer.parseInt(thresholdStr);
-		DiagnosisStatisticsBean current = diagnosesDAO.getCountForWeekOf(ICD_MALARIA, zip, wkDate);
-		long weekTotal = current.getRegionStats();
-		
-		Calendar cal = Calendar.getInstance();
-		cal.setTime(wkDate);
-		cal.add(Calendar.HOUR, -7*24);
-		DiagnosisStatisticsBean last = diagnosesDAO.getCountForWeekOf(ICD_MALARIA, zip, cal.getTime());
-		long weekTotalL = last.getRegionStats();
-		cal.add(Calendar.HOUR, 2*7*24);
-		DiagnosisStatisticsBean next = diagnosesDAO.getCountForWeekOf(ICD_MALARIA, zip, cal.getTime());
-		long weekTotalN = next.getRegionStats();
-		
-		cal.setTime(wkDate);
-		int weekOfYr = cal.get(Calendar.WEEK_OF_YEAR);
-		
-		//Find earliest Malaria Case. Set calendar's year to that year
-		Date startData = diagnosesDAO.findEarliestIncident(ICD_MALARIA);
-		if (startData == null) {
-			if (current.getRegionStats() > 0) {
-				return true;
-			}
-			return false;
-		}
-		Calendar startDateCal = Calendar.getInstance();
-		startDateCal.setTime(startData);
-		Calendar wkDateCal = Calendar.getInstance();
-		wkDateCal.setTime(wkDate);
-		cal.set(Calendar.YEAR, startDateCal.get(Calendar.YEAR));
+            dsBean = diagnosesDAO.getDiagnosisCounts(icdCode, zip, lower, upper);
+            
+        } catch (ParseException e) {
+            throw new FormValidationException("Enter dates in MM/dd/yyyy");
+        } 
+        
+        
+        return dsBean;
+    }
+    
+    /**
+     * Gets the local and regional counts for the specified week and calculates the prior average.
+     * 
+     * @param startDate a date in the week to analyze
+     * @param icdCode the diagnosis to analyze
+     * @param zip the area to analyze
+     * @param threshold threshold
+     * @return statistics for the week and previous averages
+     * @throws FormValidationException
+     * @throws DBException
+     */
+    public ArrayList<DiagnosisStatisticsBean> getEpidemicStatistics(String startDate, String icdCode, String zip, String threshold) throws FormValidationException, DBException {
+        
+        if (startDate == null || icdCode == null)
+            return null;
+        
+        if (!(icdCode.equals("84.50") || icdCode.equals("487.00")) ) {
+            throw new FormValidationException("Invalid ICD code.");
+        }
+        if(ICD_MALARIA.equals(icdCode)){
+            try{
+                Integer.parseInt(threshold);
+            }catch(NumberFormatException e){
+                throw new FormValidationException("Threshold must be an integer.");
+            }
+        }
+        Date lower;  //lower, which is parsed to startDate
+        try {
+            lower = new SimpleDateFormat("MM/dd/yyyy").parse(startDate);
+        } catch (ParseException e) {
+            throw new FormValidationException("Enter dates in MM/dd/yyyy");
+        }
+        if (!zip.matches("([0-9]{5})|([0-9]{5}-[0-9]{4})"))
+            throw new FormValidationException("Zip Code must be 5 digits!");
+        
+        DiagnosisStatisticsBean dbWeek = diagnosesDAO.getCountForWeekOf(icdCode, zip, lower);
+        DiagnosisStatisticsBean dbAvg = new DiagnosisStatisticsBean(zip, 0, 0, lower, lower);
+        
+        Calendar cal = Calendar.getInstance();
+        
+        Date start = diagnosesDAO.findEarliestIncident(icdCode); //start, which is set to earliest incident
+        Calendar startCal = Calendar.getInstance();
+        if(start != null)
+            startCal.setTime(start);
+        
+        ArrayList<DiagnosisStatisticsBean> ret = new ArrayList<DiagnosisStatisticsBean>();
+        if (start == null) {
+            ret.add(dbWeek);
+            ret.add(dbAvg);
+            return ret;
+        }
+        cal.setTime(lower); //cal, which is set to lower
+        Calendar lowerCal = Calendar.getInstance();
+        lowerCal.setTime(lower);
+        int weekOfYr = cal.get(Calendar.WEEK_OF_YEAR);
+        
+        cal.set(Calendar.YEAR, startCal.get(Calendar.YEAR));  //cal's year then gets set to start's year
+        ArrayList<DiagnosisStatisticsBean> dbList = new ArrayList<DiagnosisStatisticsBean>();
+        
+        while( cal.getTime().before(lower) && cal.get(Calendar.YEAR) != lowerCal.get(Calendar.YEAR)) {
+            dbList.add( diagnosesDAO.getCountForWeekOf(icdCode, zip, cal.getTime()) );
+            cal.add(Calendar.YEAR, 1);
+            cal.set(Calendar.WEEK_OF_YEAR, weekOfYr);
+            cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+        }
+        
+        long avg = 0;
+        long avgRegion = 0;
+        if (dbList.size() > 0) {
+            for (DiagnosisStatisticsBean d : dbList) {
+                avg += d.getZipStats();
+                avgRegion += d.getRegionStats();
+            }
+            avg /= dbList.size();
+            avgRegion /= dbList.size();
+        }
+        
+        dbAvg.setRegionStats(avgRegion);
+        dbAvg.setZipStats(avg);
+        
+        ret.add(dbWeek);
+        ret.add(dbAvg);
+        return ret;
+    }
+    
+    /**
+     * Determines if an Influenza Epidemic is happening
+     * 
+     * @param curDateStr a date in the currently evaluated week
+     * @param zip the zip code to analyze
+     * @return whether or not there is an epidemic
+     * @throws ParseException
+     * @throws DBException
+     */
+    public boolean isFluEpidemic(String curDateStr, String zip) throws ParseException, DBException {
+        new SimpleDateFormat("MM/dd/yyyy").parse("01/04/1998");
+        Date curDate = new SimpleDateFormat("MM/dd/yyyy").parse(curDateStr);
+        
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(curDate);
+        
+        int weekOfYr = cal.get(Calendar.WEEK_OF_YEAR);
+        double threshold = calcThreshold(weekOfYr);
+        double thresholdL = calcThreshold(weekOfYr-1);
+        double thresholdN = calcThreshold(weekOfYr+1); 
+        
+        DiagnosisStatisticsBean dbNow = diagnosesDAO.getCountForWeekOf(ICD_INFLUENZA, zip, cal.getTime());
+        cal.add(Calendar.HOUR, -12*7);
+        DiagnosisStatisticsBean dbLast = diagnosesDAO.getCountForWeekOf(ICD_INFLUENZA, zip, cal.getTime());
+        cal.add(Calendar.HOUR, 2*12*7);
+        DiagnosisStatisticsBean dbNext =  diagnosesDAO.getCountForWeekOf(ICD_INFLUENZA, zip, cal.getTime());
+        
+        double weekNow = (double) dbNow.getRegionStats();
+        double weekL = (double) dbLast.getRegionStats();
+        double weekN = (double) dbNext.getRegionStats();
+        
+        return weekNow > threshold && (weekL > thresholdL || weekN > thresholdN);
+        
+    }
+    
+    /**
+     * Calculates the threshold of an influenza epidemic
+     * 
+     * @param weekNumber the week of the year
+     * @return the epidemic threshold for flu cases
+     */
+    private double calcThreshold(double weekNumber) {
+        return 5.34 + 0.271 * weekNumber + 3.45 * Math.sin(2 * Math.PI * weekNumber / 52.0) + 8.41 * Math.cos(2 * Math.PI * weekNumber / 52.0);
+    }
+    
+    /**
+     * Determines whether a Malaria epidemic is happening for two consecutive weeks
+     * prior to the current date.
+     * 
+     * @param weekDate a date in the currently evaluated week
+     * @param zip the zip code to analyze
+     * @param thresholdStr the threshold for an epidemic
+     * @return whether or not there is an epidemic
+     * @throws DBException
+     * @throws ParseException
+     */
+    public boolean isMalariaEpidemic(String weekDate, String zip, String thresholdStr) throws DBException, ParseException {
+        
+        Date wkDate = new SimpleDateFormat("MM/dd/yyyy").parse(weekDate);
+        
+        ArrayList<DiagnosisStatisticsBean> historyWkL1 = new ArrayList<DiagnosisStatisticsBean>();
+        ArrayList<DiagnosisStatisticsBean> historyWkL2 = new ArrayList<DiagnosisStatisticsBean>();
+        
+        double threshold = Double.parseDouble(thresholdStr);
+        
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(wkDate);
 
-		while( cal.getTime().before(wkDate) && cal.get(Calendar.YEAR) != wkDateCal.get(Calendar.YEAR)) {
-			
-			dbList.add( diagnosesDAO.getCountForWeekOf(ICD_MALARIA, zip, cal.getTime()) );
-			cal.add(Calendar.HOUR, -7*24);
-			dbListL.add( diagnosesDAO.getCountForWeekOf(ICD_MALARIA, zip, cal.getTime()) );
-			cal.add(Calendar.HOUR, 2*7*24);
-			dbListN.add( diagnosesDAO.getCountForWeekOf(ICD_MALARIA, zip, cal.getTime()) );
-			cal.add(Calendar.YEAR, 1);
-			cal.set(Calendar.WEEK_OF_YEAR, weekOfYr);
-			cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
-		}
-		
-		long total = 0;
-		for (DiagnosisStatisticsBean d : dbList) {
-			total += d.getRegionStats();
-		}
-		for (DiagnosisStatisticsBean d : dbListL) {
-			d.getRegionStats();
-		}
-		for (DiagnosisStatisticsBean d : dbListN) {
-			d.getRegionStats();
-		}
-		
-		long avg = 0;
-		long avgL = 0;
-		long avgN = 0;
-		if (dbList.size() != 0) {
-			avg = total / dbList.size();
-			avgL = total/ dbListL.size();
-			avgN = total/ dbListN.size();
-		} 
-			
-		return weekTotal != 0 && (weekTotal*100/threshold) > avg && 
-				(	( weekTotalL != 0 && (weekTotalL*100/threshold) > avgL ) || 
-					( weekTotalN != 0 && (weekTotalN*100/threshold) > avgN ) );
-	}
+        DiagnosisStatisticsBean current = diagnosesDAO.getCountForWeekOf(ICD_MALARIA, zip, cal.getTime());
+        
+        DiagnosisStatisticsBean prev1 = diagnosesDAO.getCountForWeekBefore(ICD_MALARIA, zip, cal.getTime());
+        long weekTotalL1 = prev1.getRegionStats();
+        
+        cal.add(Calendar.HOUR, -7*24);
+        DiagnosisStatisticsBean prev2 = diagnosesDAO.getCountForWeekBefore(ICD_MALARIA, zip, cal.getTime());
+        long weekTotalL2 = prev2.getRegionStats();
+        
+        cal.setTime(wkDate);
+        
+        //Find earliest Malaria Case. Set calendar's year to that year
+        Date startData = diagnosesDAO.findEarliestIncident(ICD_MALARIA);
+        if (startData == null) {
+            if (current.getRegionStats() > 0) {
+                return true;
+            }
+            return false;
+        }
+        Calendar startDateCal = Calendar.getInstance();
+        startDateCal.setTime(startData);
+        Calendar wkDateCal = Calendar.getInstance();
+        wkDateCal.setTime(wkDate);
+        cal.set(Calendar.YEAR, startDateCal.get(Calendar.YEAR));
+        
+        while( cal.getTime().before(wkDate) && cal.get(Calendar.YEAR) != wkDateCal.get(Calendar.YEAR)) {
+            historyWkL1.add( diagnosesDAO.getCountForWeekBefore(ICD_MALARIA, zip, cal.getTime()) );
+            cal.add(Calendar.HOUR, -7*24);
+            historyWkL2.add( diagnosesDAO.getCountForWeekBefore(ICD_MALARIA, zip, cal.getTime()) );
+            cal.add(Calendar.HOUR, 7*24);
+
+            cal.add(Calendar.YEAR, 1);
+        }
+        
+        long totalHistL1 = 0;
+        long totalHistL2 = 0;
+        long countHistL1 = historyWkL1.size();
+        long countHistL2 = historyWkL1.size();
+        for (DiagnosisStatisticsBean d : historyWkL1) {
+            totalHistL1 += d.getRegionStats();
+        }
+        for (DiagnosisStatisticsBean d : historyWkL2) {
+            totalHistL2 += d.getRegionStats();
+        }
+                
+        double avgL1 = ((double)totalHistL1) / ((double)countHistL1);
+        double avgL2 = ((double)totalHistL2) / ((double)countHistL2);
+
+        boolean epidemicL1 = (weekTotalL1*100.0) / threshold > avgL1 || (countHistL1 == 0 && weekTotalL1 != 0);
+        boolean epidemicL2 = (weekTotalL2*100.0) / threshold > avgL2 || (countHistL2 == 0 && weekTotalL2 != 0);
+        return epidemicL1 && epidemicL2;
+    }
 }
diff --git a/iTrust/src/edu/ncsu/csc/itrust/dao/mysql/DiagnosesDAO.java b/iTrust/src/edu/ncsu/csc/itrust/dao/mysql/DiagnosesDAO.java
index 3fef79301c04e0a116490cd2f849015dbf1e7054..d58b52c286db99d535c5bfa47a36ad3e606b9d68 100644
--- a/iTrust/src/edu/ncsu/csc/itrust/dao/mysql/DiagnosesDAO.java
+++ b/iTrust/src/edu/ncsu/csc/itrust/dao/mysql/DiagnosesDAO.java
@@ -9,6 +9,7 @@ import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
+import java.lang.IllegalArgumentException;
 import edu.ncsu.csc.itrust.DBUtil;
 import edu.ncsu.csc.itrust.beans.DiagnosisBean;
 import edu.ncsu.csc.itrust.beans.DiagnosisStatisticsBean;
@@ -33,8 +34,8 @@ import edu.ncsu.csc.itrust.exception.DBException;
  */
 
 public class DiagnosesDAO {
-	private DAOFactory factory;
-	private DiagnosisBeanLoader loader = new DiagnosisBeanLoader(true);
+    private DAOFactory factory;
+    private DiagnosisBeanLoader loader = new DiagnosisBeanLoader(true);
 	
 	/**
 	 * @param factory
@@ -68,7 +69,12 @@ public class DiagnosesDAO {
 		} finally {
 			DBUtil.closeConnection(conn, ps);
 		}
-	}
+    }
+
+    // Use default value of 3 for zipSFs
+    public DiagnosisStatisticsBean getDiagnosisCounts(String icdCode, String zipCode, java.util.Date lower, java.util.Date upper) throws DBException{
+        return getDiagnosisCounts(icdCode, zipCode, lower, upper, 3);
+    }
 	
 	/**
 	 * Gets a local zip code count and regional count of a specified diagnosis code
@@ -77,11 +83,17 @@ public class DiagnosesDAO {
 	 * @param zipCode The zip code to evaluate
 	 * @param lower The starting date
 	 * @param upper The ending date
+     * @param zipSFs The number of significant figures (maximum 5)
 	 * @return A bean containing the local and regional counts
 	 * @throws DBException
 	 */
-	public DiagnosisStatisticsBean getDiagnosisCounts(String icdCode, String zipCode, java.util.Date lower, java.util.Date upper) throws DBException {
-		Connection conn = null;
+	public DiagnosisStatisticsBean getDiagnosisCounts(String icdCode, String zipCode, java.util.Date lower, java.util.Date upper, int zipSFs) throws DBException {
+        // Make sure user is not asking for more than 5 sig figs in zip
+        if (zipSFs < 0 || zipSFs > 5) {
+            throw new IllegalArgumentException("Invalid zip code significant figures.");
+        }
+        
+        Connection conn = null;
 		PreparedStatement ps = null;
 		DiagnosisStatisticsBean dsBean = null;
 		try {
@@ -91,19 +103,19 @@ public class DiagnosesDAO {
 			ps.setString(2, zipCode);
 			ps.setTimestamp(3, new Timestamp(lower.getTime()));
 			// add 1 day's worth to include the upper
-			ps.setTimestamp(4, new Timestamp(upper.getTime() + 1000L * 60L * 60 * 24L));
-			
+            ps.setTimestamp(4, new Timestamp(upper.getTime() + 1000L * 60L * 60 * 24L - 1000));
+            			
 			ResultSet rs = ps.executeQuery();
 			rs.last();
 			int local = rs.getRow();
 			ps.close();
 			ps = conn.prepareStatement("SELECT * FROM ovdiagnosis INNER JOIN officevisits ON ovdiagnosis.VisitID=officevisits.ID INNER JOIN patients ON officevisits.PatientID=patients.MID WHERE ICDCode=? AND zip LIKE ? AND visitDate >= ? AND visitDate <= ? ");
 			ps.setString(1, icdCode);
-			ps.setString(2, zipCode.substring(0, 3) + "%");
+			ps.setString(2, zipCode.substring(0, zipSFs) + "%");
 			ps.setTimestamp(3, new Timestamp(lower.getTime()));
 			// add 1 day's worth to include the upper
-			ps.setTimestamp(4, new Timestamp(upper.getTime() + 1000L * 60L * 60 * 24L));
-			
+            ps.setTimestamp(4, new Timestamp(upper.getTime() + 1000L * 60L * 60 * 24L - 1000));
+            			
 			rs = ps.executeQuery();
 			rs.last();
 			int region = rs.getRow();
@@ -119,43 +131,29 @@ public class DiagnosesDAO {
 			DBUtil.closeConnection(conn, ps);
 		}
 		
-	}
-	
-	/**
-	 * Gets a weekly local zip code count and regional count of a specified diagnosis code over a time period
-	 * 
-	 * @param icdCode The diagnosis code
-	 * @param zipCode The zip code to evaluate
-	 * @param lower The starting date
-	 * @param upper The ending date
-	 * @return A list of beans containing the local and regional count for each week in the time period
-	 * @throws DBException
-	 */
-	public ArrayList<DiagnosisStatisticsBean> getWeeklyCounts(String icdCode, String zipCode, java.util.Date lower, java.util.Date upper) throws DBException {
-		Calendar cal = Calendar.getInstance();
-		cal.setTime(lower);
-		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
-		Date lowerDate = cal.getTime();
-		cal.add(Calendar.HOUR, 24*6);
-		Date upperDate = cal.getTime();
-		
-		ArrayList<DiagnosisStatisticsBean> weekStats = new ArrayList<DiagnosisStatisticsBean>();
-		
-		do {
-			DiagnosisStatisticsBean db = getDiagnosisCounts(icdCode, zipCode, lowerDate, upperDate);
-			weekStats.add(db);
-			
-			cal.setTime(upperDate);
-			cal.add(Calendar.HOUR, 24);
-			lowerDate = cal.getTime();
-			cal.add(Calendar.HOUR, 24*6);
-			upperDate = cal.getTime();
-		} while (lowerDate.before(upper));
-		
-		return weekStats;
-	}
-	
-	public DiagnosisStatisticsBean getCountForWeekOf(String icdCode, String zipCode, java.util.Date lower) throws DBException {
+    }
+    
+    public DiagnosisStatisticsBean getCountForWeekBefore(String icdCode, String zipCode, java.util.Date next) throws DBException {
+        return getCountForWeekBefore(icdCode, zipCode, next, 3);
+    }
+
+
+	public DiagnosisStatisticsBean getCountForWeekBefore(String icdCode, String zipCode, java.util.Date next, int zipSFs) throws DBException {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(next);
+        cal.add(Calendar.HOUR, -7*24);
+        Date start = cal.getTime();
+        cal.add(Calendar.HOUR, 6*24);
+        Date end = cal.getTime();
+
+        return getDiagnosisCounts(icdCode, zipCode, start, end);
+    }
+    
+    public DiagnosisStatisticsBean getCountForWeekOf(String icdCode, String zipCode, java.util.Date lower) throws DBException {
+        return getCountForWeekOf(icdCode, zipCode, lower, 3);
+    }
+
+	public DiagnosisStatisticsBean getCountForWeekOf(String icdCode, String zipCode, java.util.Date lower, int zipSFs) throws DBException {
 		Calendar cal = Calendar.getInstance();
 		cal.setTime(lower);
 		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
diff --git a/iTrust/test/edu/ncsu/csc/itrust/selenium/ViewDiagnosisStatisticsTest.java b/iTrust/test/edu/ncsu/csc/itrust/selenium/ViewDiagnosisStatisticsTest.java
index 2c8b648f74aba24d8b4e82e96d13fcfaaba945e7..1dd3d14fdb8b11d7a1b72b34a8811c95583e7094 100644
--- a/iTrust/test/edu/ncsu/csc/itrust/selenium/ViewDiagnosisStatisticsTest.java
+++ b/iTrust/test/edu/ncsu/csc/itrust/selenium/ViewDiagnosisStatisticsTest.java
@@ -558,5 +558,51 @@ public class ViewDiagnosisStatisticsTest extends iTrustSeleniumTest {
 		assertTrue(driver.getCurrentUrl().equals(ADDRESS + "auth/hcp-pha/viewDiagnosisStatistics.jsp"));
 		assertLogged(TransactionType.DIAGNOSIS_EPIDEMICS_VIEW, 9000000007L, 0L, "");
 		assertTrue(driver.getPageSource().contains("There is no epidemic occurring in the region."));
+    }
+    
+    public void testViewDiagnosisEpidemics_ErrorFlows() throws Exception {
+		driver = (HtmlUnitDriver)login("9000000007", "pw");
+
+		// Click Diagnosis Trends
+		driver.findElement(By.cssSelector("h2.panel-title")).click();
+		driver.findElement(By.xpath("//div[@class='panel-body']/ul/li[11]")).click();
+		driver.findElement(By.linkText("Diagnosis Trends")).click();
+
+		// Epidemics
+		assertTrue(driver.getCurrentUrl().equals(ADDRESS + "auth/hcp-pha/viewDiagnosisStatistics.jsp"));
+		new Select(driver.findElement(By.name("viewSelect"))).selectByValue("epidemics");
+        driver.findElement(By.id("select_View")).click();
+        
+        // No ICD code
+		driver.findElement(By.name("zipCode")).clear();
+		driver.findElement(By.name("zipCode")).sendKeys("27607");
+		driver.findElement(By.name("startDate")).clear();
+        driver.findElement(By.name("startDate")).sendKeys("02/15/2010");
+        driver.findElement(By.name("threshold")).sendKeys("110");
+        driver.findElement(By.id("select_diagnosis")).click();
+        assertTrue(driver.getPageSource().contains("Invalid ICD code."));
+        
+        // Invalid zip
+        new Select(driver.findElement(By.name("icdCode"))).selectByVisibleText("84.50 - Malaria");
+        driver.findElement(By.name("zipCode")).clear();
+        driver.findElement(By.name("zipCode")).sendKeys("asdf");
+        driver.findElement(By.id("select_diagnosis")).click();
+        assertTrue(driver.getPageSource().contains("Zip Code must be 5 digits!"));
+
+        // Invalid date
+        driver.findElement(By.name("startDate")).clear();
+        driver.findElement(By.name("startDate")).sendKeys("asdf");
+        driver.findElement(By.name("zipCode")).clear();
+        driver.findElement(By.name("zipCode")).sendKeys("27607");
+        driver.findElement(By.id("select_diagnosis")).click();
+        assertTrue(driver.getPageSource().contains("Enter dates in MM/dd/yyyy"));
+
+        // Invalid threshold
+        driver.findElement(By.name("threshold")).clear();
+        driver.findElement(By.name("threshold")).sendKeys("asdf");
+        driver.findElement(By.name("startDate")).clear();
+        driver.findElement(By.name("startDate")).sendKeys("02/15/2010");
+        driver.findElement(By.id("select_diagnosis")).click();
+        assertTrue(driver.getPageSource().contains("Threshold must be an integer."));
 	}
 }
\ No newline at end of file
diff --git a/iTrust/test/edu/ncsu/csc/itrust/unit/action/ViewDiagnosisStatisticsActionTest.java b/iTrust/test/edu/ncsu/csc/itrust/unit/action/ViewDiagnosisStatisticsActionTest.java
index 000bc468bcd8bfb0cb9d990ca291bcc6fc82f8a5..30600b38c3d14103ef71830275c354c1cbb5f97c 100644
--- a/iTrust/test/edu/ncsu/csc/itrust/unit/action/ViewDiagnosisStatisticsActionTest.java
+++ b/iTrust/test/edu/ncsu/csc/itrust/unit/action/ViewDiagnosisStatisticsActionTest.java
@@ -88,11 +88,50 @@ public class ViewDiagnosisStatisticsActionTest extends TestCase {
 		}
 	}
 	
-	public void testIsMalariaEpidemic() throws Exception {
-		gen.malaria_epidemic();
-		assertTrue(action.isMalariaEpidemic("11/02/" + thisYear, "27606", "110"));
-		assertFalse(action.isMalariaEpidemic("11/16/" + thisYear, "27606", "110"));
-	}
+	public void testIsMalariaEpidemicBasic() throws Exception {
+		gen.malaria_epidemic1();
+		assertFalse(action.isMalariaEpidemic("11/02/" + thisYear, "27606", "110"));
+		assertTrue(action.isMalariaEpidemic("11/16/" + thisYear, "27606", "110"));
+    }
+    
+    public void testIsMalariaEpidemicRolling() throws Exception {
+        int year = thisYear-20;
+        gen.malaria_epidemic2();
+        assertFalse(action.isMalariaEpidemic("11/01/" + year, "27606", "110"));
+        assertFalse(action.isMalariaEpidemic("11/02/" + year, "27606", "110"));
+        assertFalse(action.isMalariaEpidemic("11/03/" + year, "27606", "110"));
+        assertFalse(action.isMalariaEpidemic("11/04/" + year, "27606", "110"));
+        assertFalse(action.isMalariaEpidemic("11/05/" + year, "27606", "110"));
+        assertFalse(action.isMalariaEpidemic("11/06/" + year, "27606", "110"));
+        assertFalse(action.isMalariaEpidemic("11/07/" + year, "27606", "110"));
+        assertFalse(action.isMalariaEpidemic("11/08/" + year, "27606", "110"));
+        assertFalse(action.isMalariaEpidemic("11/09/" + year, "27606", "110"));
+        assertFalse(action.isMalariaEpidemic("11/10/" + year, "27606", "110"));
+        assertFalse(action.isMalariaEpidemic("11/11/" + year, "27606", "110"));
+        assertFalse(action.isMalariaEpidemic("11/12/" + year, "27606", "110"));
+        assertFalse(action.isMalariaEpidemic("11/13/" + year, "27606", "110"));
+        assertTrue(action.isMalariaEpidemic("11/14/" + year, "27606", "110"));
+        assertTrue(action.isMalariaEpidemic("11/15/" + year, "27606", "110"));
+    }
+
+    public void testIsMalariaEpidemicEdge() throws Exception {
+        int year = thisYear - 20;
+        gen.malaria_epidemic3();
+        // Exactly 100 percentile
+        assertFalse(action.isMalariaEpidemic("11/02/" + thisYear, "27606", "110"));
+
+        // Threshold shouldn't matter if there is no history
+        assertTrue(action.isMalariaEpidemic("10/10/" + year, "27606", "110"));
+        assertTrue(action.isMalariaEpidemic("10/10/" + year, "27606", "100000000"));
+
+        // Date/zip with 0 cases should be false
+        assertFalse(action.isMalariaEpidemic("02/02/" + thisYear, "27606", "110"));
+        assertFalse(action.isMalariaEpidemic("10/10/" + thisYear, "99999", "110"));
+    }
+
+    public void testIsMalariaEpidemicNone() throws Exception {
+        assertFalse(action.isMalariaEpidemic("06/02/2010", "38201", "110"));
+    }
 	
 	public void testIsFluEpidemic() throws Exception {
 		gen.influenza_epidemic();
diff --git a/iTrust/test/edu/ncsu/csc/itrust/unit/charts/DiagnosisTrendDataTest.java b/iTrust/test/edu/ncsu/csc/itrust/unit/charts/DiagnosisTrendDataTest.java
index 5761a9ec059a905144e37ec997175f563782e4a0..32252af96822ab7d062e2e76428f18f6911ceca3 100644
--- a/iTrust/test/edu/ncsu/csc/itrust/unit/charts/DiagnosisTrendDataTest.java
+++ b/iTrust/test/edu/ncsu/csc/itrust/unit/charts/DiagnosisTrendDataTest.java
@@ -22,7 +22,7 @@ public class DiagnosisTrendDataTest extends TestCase {
 		gen.clearAllTables();
 		gen.standardData();
 		gen.influenza_epidemic();
-		gen.malaria_epidemic();
+		gen.malaria_epidemic1();
 	}
 	
 	public void testProduceDataset() {
diff --git a/iTrust/test/edu/ncsu/csc/itrust/unit/dao/officevisit/OVDiagnosesTest.java b/iTrust/test/edu/ncsu/csc/itrust/unit/dao/officevisit/OVDiagnosesTest.java
index ea119beb4997fa04627d8b4d9303fbf1fe70c72d..94d05e3dd12077f686f783acf77847237ca8f7ac 100644
--- a/iTrust/test/edu/ncsu/csc/itrust/unit/dao/officevisit/OVDiagnosesTest.java
+++ b/iTrust/test/edu/ncsu/csc/itrust/unit/dao/officevisit/OVDiagnosesTest.java
@@ -4,6 +4,7 @@ import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
+import java.lang.IllegalArgumentException;
 
 import junit.framework.TestCase;
 import edu.ncsu.csc.itrust.action.ViewDiagnosisStatisticsAction;
@@ -91,28 +92,106 @@ public class OVDiagnosesTest extends TestCase {
 		assertEquals(3, dsBean.getZipStats());
 		assertEquals(5, dsBean.getRegionStats());
 	}
-	
-	/**
-	 * testGetWeeklyStatisticsValid
-	 * @throws Exception
-	 */
-	public void testGetWeeklyStatisticsValid() throws Exception {
-		Date lower = new SimpleDateFormat("MM/dd/yyyy").parse("06/28/2011");
-		Date upper = new SimpleDateFormat("MM/dd/yyyy").parse("09/28/2011");
-		List<DiagnosisStatisticsBean> db = diagDAO.getWeeklyCounts("487.00", "27607", lower, upper);
-		
-		assertEquals(new SimpleDateFormat("MM/dd/yyyy").parse("06/27/2011"), db.get(0).getStartDate());
-		assertEquals(new SimpleDateFormat("MM/dd/yyyy").parse("07/03/2011"), db.get(0).getEndDate());
-		assertEquals(new SimpleDateFormat("MM/dd/yyyy").parse("09/26/2011"), db.get(db.size()-1).getStartDate());
-		
-		long totalRegion = 0;
-		for (DiagnosisStatisticsBean d : db) {
-			totalRegion += d.getRegionStats();
-		}
-		//If previous test fails, this test may fail
-		long totalRegionNonsplit = diagDAO.getDiagnosisCounts("487.00", "27607", lower, upper).getRegionStats();
-		assertEquals(totalRegionNonsplit, totalRegion);
-	}
+    
+    public void testZipSFs() throws Exception {
+        TestDataGenerator gen = new TestDataGenerator();
+        gen.hcp_additional_diagnosis_data();
+        Date lower = new SimpleDateFormat("MM/dd/yyyy").parse("11/18/2020");
+		Date upper = new SimpleDateFormat("MM/dd/yyyy").parse("11/18/2020");
+        DiagnosisStatisticsBean bean = diagDAO.getDiagnosisCounts("26.8", "27606-1234", lower, upper, 5);
+        assertEquals(bean.getZipStats(), bean.getRegionStats());
+        assertEquals(3, bean.getZipStats());
+        
+        lower = new SimpleDateFormat("MM/dd/yyyy").parse("11/18/2020");
+		upper = new SimpleDateFormat("MM/dd/yyyy").parse("11/18/2020");
+        bean = diagDAO.getDiagnosisCounts("26.8", "27607", lower, upper, 4);
+        assertEquals(1, bean.getZipStats());
+        assertEquals(5, bean.getRegionStats());
+
+        lower = new SimpleDateFormat("MM/dd/yyyy").parse("11/18/2020");
+		upper = new SimpleDateFormat("MM/dd/yyyy").parse("11/18/2020");
+        bean = diagDAO.getDiagnosisCounts("26.8", "27603", lower, upper, 3);
+        assertEquals(1, bean.getZipStats());
+        assertEquals(5, bean.getRegionStats());
+
+        lower = new SimpleDateFormat("MM/dd/yyyy").parse("11/18/2020");
+		upper = new SimpleDateFormat("MM/dd/yyyy").parse("11/18/2020");
+        bean = diagDAO.getDiagnosisCounts("26.8", "27606", lower, upper, 2);
+        assertEquals(0, bean.getZipStats());
+        assertEquals(5, bean.getRegionStats());
+
+        lower = new SimpleDateFormat("MM/dd/yyyy").parse("11/18/2020");
+		upper = new SimpleDateFormat("MM/dd/yyyy").parse("11/18/2020");
+        bean = diagDAO.getDiagnosisCounts("26.8", "20000", lower, upper, 1);
+        assertEquals(0, bean.getZipStats());
+        assertEquals(6, bean.getRegionStats());
+
+        lower = new SimpleDateFormat("MM/dd/yyyy").parse("11/18/2020");
+		upper = new SimpleDateFormat("MM/dd/yyyy").parse("11/18/2020");
+        bean = diagDAO.getDiagnosisCounts("26.8", "10001", lower, upper, 0);
+        assertEquals(3, bean.getZipStats());
+        assertEquals(10, bean.getRegionStats());
+    }
+
+    public void testInvalidZipSigFigs() throws Exception {
+        try {
+            Date lower = new SimpleDateFormat("MM/dd/yyyy").parse("11/18/2020");
+		    Date upper = new SimpleDateFormat("MM/dd/yyyy").parse("11/18/2020");
+            DiagnosisStatisticsBean bean = diagDAO.getDiagnosisCounts("26.8", "27606-1234", lower, upper, -1);
+            fail("Expected exception.");
+        } catch (IllegalArgumentException e) { }
+
+        try {
+            Date lower = new SimpleDateFormat("MM/dd/yyyy").parse("11/18/2020");
+		    Date upper = new SimpleDateFormat("MM/dd/yyyy").parse("11/18/2020");
+            DiagnosisStatisticsBean bean = diagDAO.getDiagnosisCounts("26.8", "27606-1234", lower, upper, 6);
+            fail("Expected exception.");
+        } catch (IllegalArgumentException e) { }
+    }
+
+    public void testGetCountForWeekBeforeRolling() throws Exception {
+        TestDataGenerator gen = new TestDataGenerator();
+        gen.malaria_epidemic2();
+
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(new SimpleDateFormat("MM/dd/yyyy").parse("11/01/2000"));
+
+        gen.malaria_epidemic2();
+        System.out.println(cal.getTime());
+        assertEquals(0, diagDAO.getCountForWeekBefore("84.5", "27606", cal.getTime()).getRegionStats());
+        cal.add(Calendar.DATE, 1);
+        System.out.println(cal.getTime());
+        assertEquals(1, diagDAO.getCountForWeekBefore("84.5", "27606", cal.getTime()).getRegionStats());
+        cal.add(Calendar.HOUR, 24);
+        assertEquals(2, diagDAO.getCountForWeekBefore("84.5", "27606", cal.getTime()).getRegionStats());
+        cal.add(Calendar.HOUR, 24);
+        assertEquals(3, diagDAO.getCountForWeekBefore("84.5", "27606", cal.getTime()).getRegionStats());
+        cal.add(Calendar.HOUR, 24);
+        assertEquals(4, diagDAO.getCountForWeekBefore("84.5", "27606", cal.getTime()).getRegionStats());
+        cal.add(Calendar.HOUR, 24);
+        assertEquals(5, diagDAO.getCountForWeekBefore("84.5", "27606", cal.getTime()).getRegionStats());
+        cal.add(Calendar.HOUR, 24);
+        assertEquals(6, diagDAO.getCountForWeekBefore("84.5", "27606", cal.getTime()).getRegionStats());
+        cal.add(Calendar.HOUR, 24);
+        assertEquals(7, diagDAO.getCountForWeekBefore("84.5", "27606", cal.getTime()).getRegionStats());
+        cal.add(Calendar.HOUR, 24);
+        assertEquals(7, diagDAO.getCountForWeekBefore("84.5", "27606", cal.getTime()).getRegionStats());
+        cal.add(Calendar.HOUR, 24);
+        assertEquals(7, diagDAO.getCountForWeekBefore("84.5", "27606", cal.getTime()).getRegionStats());
+        cal.add(Calendar.HOUR, 24);
+        assertEquals(7, diagDAO.getCountForWeekBefore("84.5", "27606", cal.getTime()).getRegionStats());
+        cal.add(Calendar.HOUR, 24);
+        assertEquals(7, diagDAO.getCountForWeekBefore("84.5", "27606", cal.getTime()).getRegionStats());
+        cal.add(Calendar.HOUR, 24);
+        assertEquals(7, diagDAO.getCountForWeekBefore("84.5", "27606", cal.getTime()).getRegionStats());
+        cal.add(Calendar.HOUR, 24);
+        assertEquals(7, diagDAO.getCountForWeekBefore("84.5", "27606", cal.getTime()).getRegionStats());
+        cal.add(Calendar.HOUR, 24);
+        assertEquals(7, diagDAO.getCountForWeekBefore("84.5", "27606", cal.getTime()).getRegionStats());
+        cal.add(Calendar.HOUR, 24);
+        assertEquals(6, diagDAO.getCountForWeekBefore("84.5", "27606", cal.getTime()).getRegionStats());
+        cal.add(Calendar.HOUR, 24);
+    }
 	
 	/**
 	 * testMalaria
@@ -121,11 +200,11 @@ public class OVDiagnosesTest extends TestCase {
 	public void testMalaria() throws Exception {
 		DAOFactory factory = TestDAOFactory.getTestInstance();
 		TestDataGenerator gen = new TestDataGenerator();
-		gen.malaria_epidemic();
+		gen.malaria_epidemic1();
 		
 		ViewDiagnosisStatisticsAction a = new ViewDiagnosisStatisticsAction(factory);
 		
-		assertTrue(a.isMalariaEpidemic("11/02/" + thisYear, "27607", "110"));
+		assertTrue(a.isMalariaEpidemic("11/16/" + thisYear, "27607", "110"));
 		
 	}
 	
diff --git a/iTrust/test/edu/ncsu/csc/itrust/unit/datagenerators/TestDataGenerator.java b/iTrust/test/edu/ncsu/csc/itrust/unit/datagenerators/TestDataGenerator.java
index 03037124a70bf63dceb07e8c4125466287497fdf..33922fb4d0541e45356e3b06bd55e61891d49ce7 100644
--- a/iTrust/test/edu/ncsu/csc/itrust/unit/datagenerators/TestDataGenerator.java
+++ b/iTrust/test/edu/ncsu/csc/itrust/unit/datagenerators/TestDataGenerator.java
@@ -741,7 +741,12 @@ public class TestDataGenerator {
 	public void hcp_diagnosis_data() throws FileNotFoundException, IOException,
 			SQLException {
 		new DBBuilder(factory).executeSQLFile(DIR + "/hcp_diagnosis_data.sql");
-	}
+    }
+    
+    public void hcp_additional_diagnosis_data() throws FileNotFoundException, 
+        IOException, SQLException {
+            new DBBuilder(factory).executeSQLFile(DIR + "/hcp_additional_diagnosis_data.sql");
+        }
 
 	public void immunization_data() throws FileNotFoundException, IOException,
 			SQLException {
@@ -905,9 +910,19 @@ public class TestDataGenerator {
 				+ "/referral_sort_testdata.sql");
 	}
 
-	public void malaria_epidemic() throws SQLException, FileNotFoundException,
+	public void malaria_epidemic1() throws SQLException, FileNotFoundException,
+			IOException {
+		new DBBuilder(factory).executeSQLFile(DIR + "/malariaEpidemic1.sql");
+    }
+    
+    public void malaria_epidemic2() throws SQLException, FileNotFoundException,
+			IOException {
+		new DBBuilder(factory).executeSQLFile(DIR + "/malariaEpidemic2.sql");
+    }
+    
+    public void malaria_epidemic3() throws SQLException, FileNotFoundException,
 			IOException {
-		new DBBuilder(factory).executeSQLFile(DIR + "/malariaEpidemic.sql");
+		new DBBuilder(factory).executeSQLFile(DIR + "/malariaEpidemic3.sql");
 	}
 
 	public void influenza_epidemic() throws SQLException,