code: package resources.auxiliary;
  
  import java.awt.image.BufferedImageFilter;
  import java.io.BufferedReader;
  import java.io.BufferedWriter;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.FileReader;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.io.OutputStreamWriter;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Hashtable;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  
  public class Dumper {
  
  	public static boolean SUCC_TEST = false;
  	public static int TEST_ID = -1;
  	private static List trace = new ArrayList(1100);
  	private static List statements = new ArrayList();
  	private static List coverage = new ArrayList();
  	private static Set alreadyRun = new HashSet();
  	private static Set alreadyObserved = new HashSet();
  	private static List coverages = new ArrayList();
  	private static String operators[] = { "<=", ">=", "==", "!=", "<", ">" };
  
  	private static final long MAX_OUTPUT_FILE_SIZE = 5; // max file size in GB
  	// private static final String OUT_AND_LIB_PATH =
  	// "/home//code/space/StateCoverLocator";
  	private static final String OUT_AND_LIB_PATH = "/home/lillian/git/StateCoverLocator";
  	private static final String OUT_FILE_NAME = OUT_AND_LIB_PATH + "/out/path.out";
  	private static final String TRACE_FILE_NAME = OUT_AND_LIB_PATH + "/out/trace.out";
  
  	public static void reset() {
  		alreadyRun = new HashSet();
  		alreadyObserved = new HashSet();
  		statements = new ArrayList();
  		coverage = new ArrayList();
  		read();
  	}
  
  	public static void resetTrueOrFalse() {
  		statements = new ArrayList();
  		coverages = new ArrayList();
  		readTrueOrFalse();
  	}
  
  	public static boolean observe(String stmt) {
  		if (!alreadyObserved.contains(stmt)) {
  			alreadyObserved.add(stmt);
  
  			int index = statements.indexOf(stmt);
  			if (index >= 0) {
  				Record record = (Record) coverage.get(index);
  				record.incObserved(SUCC_TEST);
  			} else {
  				statements.add(stmt);
  				Record record = new Record(0, 0, 0, 0);
  				record.incObserved(SUCC_TEST);
  				coverage.add(record);
  			}
  		}
  		return true;
  	}
  
  	public static boolean traceInit() {
  		trace.add("---------" + TEST_ID + "---------");
  		return true;
  	}
  
  	public static boolean write(String stmt) {
  		if (TEST_ID >= 0) {
  			trace.add(stmt);
  			if (trace.size() > 1000) {
  				dumpTrace();
  			}
  		}
  		if (!alreadyRun.contains(stmt)) {
  			alreadyRun.add(stmt);
  
  			int index = statements.indexOf(stmt);
  			if (index >= 0) {
  				Record record = (Record) coverage.get(index);
  				record.inc(SUCC_TEST);
  			} else {
  				statements.add(stmt);
  				Record record = new Record(0, 0, 0, 0);
  				record.inc(SUCC_TEST);
  				coverage.add(record);
  			}
  		}
  		return true;
  	}
  
  	public static boolean slowWrite(String stmt) {
  		if (!alreadyRun.contains(stmt)) {
  			alreadyRun.add(stmt);
  
  			statements = new ArrayList();
  			coverage = new ArrayList();
  			read();
  
  			int index = statements.indexOf(stmt);
  			if (index >= 0) {
  				Record record = (Record) coverage.get(index);
  				record.inc(SUCC_TEST);
  			} else {
  				statements.add(stmt);
  				Record record = new Record(0, 0, 0, 0);
  				record.inc(SUCC_TEST);
  				coverage.add(record);
  			}
  			dump();
  		}
  		return true;
  	}
  
  	public static boolean writeTrue(String stmt) {
  		return writeTrueOrFalse(stmt, true);
  	}
  
  	public static boolean writeFalse(String stmt) {
  		return writeTrueOrFalse(stmt, false);
  	}
  
  	private static boolean writeTrueOrFalse(String stmt, boolean isTrue) {
  		if (!alreadyRun.contains(stmt)) { // Does not run in this execution
  			alreadyRun.add(stmt);
  			int index = statements.indexOf(stmt);
  			ArrayList records = null;
  			if (index >= 0) {
  				records = (ArrayList) coverages.get(index);
  			} else {
  				statements.add(stmt);
  				records = new ArrayList();
  				coverages.add(records);
  			}
  			if (isTrue) {
  				records.add(new PredicateRecord(1, 0, SUCC_TEST));
  			} else {
  				records.add(new PredicateRecord(0, 1, SUCC_TEST));
  			}
  		} else {
  			int index = statements.indexOf(stmt);
  			ArrayList records = (ArrayList) coverages.get(index);
  			PredicateRecord record = (PredicateRecord) records.get(records.size() - 1);
  			record.inc(isTrue);
  		}
  		return true;
  	}
  
  	public static boolean dumpTrueOrFalse() {
  		File file = new File(OUT_FILE_NAME);
  		if (!file.exists()) {
  			try {
  				file.getParentFile().mkdirs();
  				file.createNewFile();
  			} catch (IOException e) {
  				return false;
  			}
  		}
  		BufferedWriter bufferedWriter = null;
  		try {
  			bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, false), "UTF-8"));
  		} catch (IOException e) {
  			return false;
  		}
  		try {
  
  			for (int i = 0; i < statements.size(); i++) {
  				bufferedWriter.write((String) statements.get(i));
  				bufferedWriter.write("\n");
  				List others = (List) coverages.get(i);
  				for (int j = 0; j < others.size(); j++) {
  					PredicateRecord r = (PredicateRecord) others.get(j);
  					bufferedWriter.write(r.getValue());
  					bufferedWriter.write("\n");
  				}
  			}
  			bufferedWriter.close();
  		} catch (IOException e) {
  			e.printStackTrace();
  			return false;
  		} finally {
  			if (bufferedWriter != null) {
  				try {
  					bufferedWriter.close();
  				} catch (IOException e) {
  					e.printStackTrace();
  				}
  			}
  		}
  		return true;
  	}
  
  	public static boolean dumpTrace() {
  		if (trace.isEmpty()) {
  			return true;
  		}
  		File file = new File(TRACE_FILE_NAME);
  		if (!file.exists()) {
  			try {
  				file.getParentFile().mkdirs();
  				file.createNewFile();
  			} catch (IOException e) {
  				return false;
  			}
  		}
  		BufferedWriter bufferedWriter = null;
  		try {
  			bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true), "UTF-8"));
  		} catch (IOException e) {
  			return false;
  		}
  		try {
  
  			for (int i = 0; i < trace.size(); i++) {
  				bufferedWriter.write("" + trace.get(i) + "\n");
  			}
  			bufferedWriter.close();
  		} catch (IOException e) {
  			e.printStackTrace();
  			return false;
  		} finally {
  			if (bufferedWriter != null) {
  				try {
  					bufferedWriter.close();
  				} catch (IOException e) {
  					e.printStackTrace();
  				}
  			}
  		}
  		trace.clear();
  		return true;
  	}
  
  	public static boolean dump() {
  		File file = new File(OUT_FILE_NAME);
  		if (!file.exists()) {
  			try {
  				file.getParentFile().mkdirs();
  				file.createNewFile();
  			} catch (IOException e) {
  				return false;
  			}
  		}
  		BufferedWriter bufferedWriter = null;
  		try {
  			bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, false), "UTF-8"));
  		} catch (IOException e) {
  			return false;
  		}
  		try {
  
  			for (int i = 0; i < statements.size(); i++) {
  				Record record = (Record) coverage.get(i);
  				String content = (String) statements.get(i) + "\t" + record.getValue();
  				bufferedWriter.write(content);
  				bufferedWriter.write("\n");
  			}
  			bufferedWriter.close();
  		} catch (IOException e) {
  			e.printStackTrace();
  			return false;
  		} finally {
  			if (bufferedWriter != null) {
  				try {
  					bufferedWriter.close();
  				} catch (IOException e) {
  					e.printStackTrace();
  				}
  			}
  		}
  		return true;
  	}
  
  	// logConditionCoverage, lcc for short
  	public static boolean lcc(boolean condition, String trueLogInfo, String falseLogInfo) {
  		observe(trueLogInfo);
  		observe(falseLogInfo);
  		if (condition) {
  			write(trueLogInfo);
  		} else {
  			write(falseLogInfo);
  		}
  		return condition;
  	}
  
  	public static boolean logConditionCoverageWithEvaluationBias(boolean condition, String message) {
  		if (condition) {
  			writeTrue(message);
  		} else {
  			writeFalse(message);
  		}
  		return condition;
  	}
  
  	private static void logCoverage(boolean condition, String message, boolean useSober) {
  		if (useSober) {
  			if (condition) {
  				writeTrue(message);
  			} else {
  				writeFalse(message);
  			}
  		} else {
  			observe(message);
  			if (condition) {
  				write(message);
  			}
  		}
  	}
  
  	public static Double lpc(final double a, double b, String message, String var1, String var2, boolean useSober) {
  		return (Double) lpccommon(Double.valueOf(a), Double.valueOf(b), message, var1, var2, useSober);
  	}
  
  	public static Integer lpc(final int a, int b, String message, String var1, String var2, boolean useSober) {
  		return (Integer) lpccommon(Integer.valueOf(a), Integer.valueOf(b), message, var1, var2, useSober);
  	}
  
  	public static Float lpc(final float a, float b, String message, String var1, String var2, boolean useSober) {
  		return (Float) lpccommon(Float.valueOf(a), Float.valueOf(b), message, var1, var2, useSober);
  	}
  
  	public static Byte lpc(final byte a, byte b, String message, String var1, String var2, boolean useSober) {
  		return (Byte) lpccommon(Byte.valueOf(a), Byte.valueOf(b), message, var1, var2, useSober);
  	}
  
  	public static Character lpc(final char a, char b, String message, String var1, String var2, boolean useSober) {
  		return (Character) lpccommon(Character.valueOf(a), Character.valueOf(b), message, var1, var2, useSober);
  	}
  
  	public static Long lpc(final long a, long b, String message, String var1, String var2, boolean useSober) {
  		return (Long) lpccommon(Long.valueOf(a), Long.valueOf(b), message, var1, var2, useSober);
  	}
  
  	public static Short lpc(final short a, short b, String message, String var1, String var2, boolean useSober) {
  		return (Short) lpccommon(Short.valueOf(a), Short.valueOf(b), message, var1, var2, useSober);
  	}
  
  	public static Object lpcNull(final Object a, String message, String var, boolean useSober) {
  		logCoverage(a == null, message + "#" + var + "==null#1", useSober);
  		return a;
  	}
  
  	// logPairCoverage, lpc for short to shorten function
  	public static Object lpccommon(final Object a, Object b, String message, String var1, String var2,
  			boolean useSober) {
  		Comparable ac = (Comparable) a;
  		Comparable bc = (Comparable) b;
  		int cmp = ac.compareTo(bc);
  		for (int i = 0; i < operators.length; i++) {
  			String op = operators[i];
  			String finalMessage = message + "#" + var1 + op + var2 + "#1";
  			boolean condition = false;
  			if (op.equals("<")) {
  				condition = cmp < 0;
  			} else if (op.equals("<=")) {
  				condition = cmp <= 0;
  			} else if (op.equals(">")) {
  				condition = cmp > 0;
  			} else if (op.equals(">=")) {
  				condition = cmp >= 0;
  			} else if (op.equals("==")) {
  				condition = cmp == 0;
  			} else if (op.equals("!=")) {
  				condition = cmp != 0;
  			}
  			logCoverage(condition, finalMessage, useSober);
  		}
  		return a;
  	}
  
  	public static Integer lpcs(final int a, int[] vars, String message, String name, String[] names, boolean useSober) {
  		for (int i = 0; i < vars.length; i++) {
  			Dumper.lpc(a, vars[i], message, name, names[i], useSober);
  		}
  		return Integer.valueOf(a);
  	}
  
  	public static Float lpcs(final float a, float[] vars, String message, String name, String[] names,
  			boolean useSober) {
  		for (int i = 0; i < vars.length; i++) {
  			Dumper.lpc(a, vars[i], message, name, names[i], useSober);
  		}
  		return Float.valueOf(a);
  	}
  
  	public static Double lpcs(final double a, double[] vars, String message, String name, String[] names,
  			boolean useSober) {
  		for (int i = 0; i < vars.length; i++) {
  			Dumper.lpc(a, vars[i], message, name, names[i], useSober);
  		}
  		return Double.valueOf(a);
  	}
  
  	public static Long lpcs(final long a, long[] vars, String message, String name, String[] names, boolean useSober) {
  		for (int i = 0; i < vars.length; i++) {
  			Dumper.lpc(a, vars[i], message, name, names[i], useSober);
  		}
  		return Long.valueOf(a);
  	}
  
  	public static Character lpcs(final char a, char[] vars, String message, String name, String[] names,
  			boolean useSober) {
  		for (int i = 0; i < vars.length; i++) {
  			Dumper.lpc(a, vars[i], message, name, names[i], useSober);
  		}
  		return Character.valueOf(a);
  	}
  
  	public static Short lpcs(final short a, short[] vars, String message, String name, String[] names,
  			boolean useSober) {
  		for (int i = 0; i < vars.length; i++) {
  			Dumper.lpc(a, vars[i], message, name, names[i], useSober);
  		}
  		return Short.valueOf(a);
  	}
  
  	public static Byte lpcs(final byte a, byte[] vars, String message, String name, String[] names, boolean useSober) {
  		for (int i = 0; i < vars.length; i++) {
  			Dumper.lpc(a, vars[i], message, name, names[i], useSober);
  		}
  		return Byte.valueOf(a);
  	}
  
  	private static boolean readTrueOrFalse() {
  		File file = new File(OUT_FILE_NAME);
  		if (!file.exists()) {
  			try {
  				file.getParentFile().mkdirs();
  				file.createNewFile();
  			} catch (IOException e) {
  				return false;
  			}
  		}
  		BufferedReader bufferedReader = null;
  		try {
  			bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
  		} catch (IOException e) {
  			return false;
  		}
  		try {
  			String line = null;
  			ArrayList others = null;
  			while ((line = bufferedReader.readLine()) != null) {
  				if (line.isEmpty()) {
  					continue;
  				}
  				String[] strings = line.split("\t");
  				if (strings.length == 3) {
  					others.add(new PredicateRecord(Integer.parseInt(strings[0]), Integer.parseInt(strings[1]),
  							strings[2].equals("0") ? false : true));
  					continue;
  				}
  				statements.add(line);
  				others = new ArrayList();
  				coverages.add(others);
  			}
  			bufferedReader.close();
  		} catch (IOException e) {
  			e.printStackTrace();
  		} finally {
  			if (bufferedReader != null) {
  				try {
  					bufferedReader.close();
  				} catch (IOException e) {
  					e.printStackTrace();
  				}
  			}
  		}
  		return true;
  	}
  
  	private static boolean read() {
  		File file = new File(OUT_FILE_NAME);
  		if (!file.exists()) {
  			try {
  				file.getParentFile().mkdirs();
  				file.createNewFile();
  			} catch (IOException e) {
  				return false;
  			}
  		}
  		BufferedReader bufferedReader = null;
  		try {
  			bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
  		} catch (IOException e) {
  			return false;
  		}
  		try {
  			String line = null;
  			while ((line = bufferedReader.readLine()) != null) {
  				String[] strings = line.split("\t");
  				if (strings.length < 5) {
  					continue;
  				}
  				statements.add(strings[0]);
  				coverage.add(new Record(Integer.parseInt(strings[1]), Integer.parseInt(strings[2]),
  						Integer.parseInt(strings[3]), Integer.parseInt(strings[4])));
  			}
  
  			bufferedReader.close();
  		} catch (IOException e) {
  			e.printStackTrace();
  			return false;
  		} finally {
  			if (bufferedReader != null) {
  				try {
  					bufferedReader.close();
  				} catch (IOException e) {
  					e.printStackTrace();
  				}
  			}
  		}
  		return true;
  	}
  }
  
  class Record {
  	private int pass = 0;
  	private int fail = 0;
  	private int passObserved = 0;
  	private int failObserved = 0;
  
  	public Record(int f, int p, int fo, int po) {
  		fail = f;
  		pass = p;
  		failObserved = fo;
  		passObserved = po;
  	}
  
  	public void inc(boolean passTest) {
  		if (passTest) {
  			pass++;
  		} else {
  			fail++;
  		}
  	}
  
  	public void incObserved(boolean passTest) {
  		if (passTest) {
  			passObserved++;
  		} else {
  			failObserved++;
  		}
  	}
  
  	public int getSuc() {
  		return pass;
  	}
  
  	public int getFail() {
  		return fail;
  	}
  
  	public String getValue() {
  		return fail + "\t" + pass + "\t" + failObserved + "\t" + passObserved;
  	}
  }
  
  class PredicateRecord {
  	private int trueCnt = 0;
  	private int falseCnt = 0;
  	private boolean pass = false;
  
  	public PredicateRecord(int t, int f, boolean pass) {
  		trueCnt = t;
  		falseCnt = f;
  		this.pass = pass;
  	}
  
  	public void inc(boolean isTrue) {
  		if (isTrue) {
  			trueCnt++;
  		} else {
  			falseCnt++;
  		}
  	}
  
  	public String getValue() {
  		String passStr = pass ? "1" : "0";
  		return trueCnt + "\t" + falseCnt + "\t" + passStr;
  	}
  }
  
  class PredicateSignature {
  	private boolean condition = false;
  	private String signature = "";
  
  	public boolean getCondition() {
  		return condition;
  	}
  
  	public void setCondition(boolean cond) {
  		condition = cond;
  	}
  
  	public String getSignature() {
  		return signature;
  	}
  
  	public void setSignature(String sig) {
  		signature = sig;
  	}
  }
  