public void eval(HashMap<String, TreeSet<String>> functionMap, int thresholdSupport, double thresholdConfidence) {
		/*
		 * Please see PairConfidence.java for details. It contains function,
		 * function pair, support, and confidence. PairCofidence is a key used
		 * in TreeMap, and the value is a TreeSet which has the functions with
		 * bugs The complexity of my current algorithm is still n square. May
		 * need some optimization. THe current run time of test3 is only 2 to 3
		 * sec. The order of our output is not important. It will be sorted
		 * before comparing with gold file.
		 */
		TreeMap<PairConfidence, TreeSet<String>> pairs = new TreeMap<PairConfidence, TreeSet<String>>();
		ArrayList<String> functions = new ArrayList<String>();
		functions.addAll(functionMap.keySet());
		for (int i = 0; i < functions.size(); i++) {
			String function1 = functions.get(i);
			TreeSet<String> callerList = functionMap.get(functions.get(i));
			int support = functionMap.get(functions.get(i)).size();
			if (support == 0) {
				continue;
			}
			
			/*
			 * for each individual function rather than if self
			 * compare the caller sets of both functions
			 * the support of pair is the number of common elements in both sets
			 * the support of function is the number of elements in the function's caller sets
			 */
			for (int j = 0; j < functions.size(); j++) {
				if (i == j) {
					continue;
				}
				
				// compare two caller sets and get the number of common elements as the support
				String function2 = functions.get(j);
				TreeSet<String> tmp = new TreeSet<String>();
				tmp.addAll(callerList);
				TreeSet<String> remain = new TreeSet<String>();
				
				// the remain elements in the caller set are the bug locations
				remain.addAll(tmp);
				tmp.retainAll(functionMap.get(functions.get(j)));
				remain.removeAll(tmp);
				
				// filter the result by the support level and confidence level
				int supportPair = tmp.size();
				if (supportPair < thresholdSupport) {
					continue;
				}
				double confidence = ((double) supportPair) / ((double) support);

				if (confidence < thresholdConfidence) {
					continue;
				}

				// create the PairConfidence and bug location list
				// create result maps
				String pair = "";
				if (function1.compareTo(function2) < 0) {
					pair = "(" + function1 + " " + function2 + ") ";
				} else {
					pair = "(" + function2 + " " + function1 + ") ";
				}
				PairConfidence pc = new PairConfidence(function1, pair,
						supportPair, confidence);
				pairs.put(pc, remain);
			}
		}

		// System.out.println("RESULTS:");
		// System.out.println("--------");
		NumberFormat numf = NumberFormat.getNumberInstance();
		numf.setMaximumFractionDigits(2);
		numf.setRoundingMode(RoundingMode.HALF_EVEN);

		// only for local test. The actual output on ECE machine will be
		// sorted automatically.
		TreeMap<String, String> display = new TreeMap<String, String>();

		for (Map.Entry entry : pairs.entrySet()) {
			String function = ((PairConfidence) entry.getKey()).getFunction();
			String header = "bug: " + function + " in ";
			for (String s : pairs.get(entry.getKey())) {
				String message = header + s
						+ ((PairConfidence) entry.getKey()).toString();
				System.out.println(message); // will be used on ECE machine.

				// only for local test. The actual output on ECE machine
				// will be sorted automatically.
//				display.put(message.replaceAll("_", "").replaceAll(" ", ""),
//						message);
			}
		}

		// only for local test. The actual output on ECE machine will be
		// sorted automatically.
//		for (Map.Entry entry : display.entrySet()) {
//			System.out.println((String) entry.getValue());
//		}

		System.exit(0);

	}