Cleanup

Jonathan Bell [2012-08-10 19:11:27]
Cleanup
Filename
testcase-generation-tester/src/edu/columbia/cs/psl/invivo/example/DummyDriver.java
testcase-generation-tester/src/edu/columbia/cs/psl/invivo/example/ReaderUser.java
testcase-generation/src/edu/columbia/cs/psl/invivo/bench/BeingCloned.java
testcase-generation/src/edu/columbia/cs/psl/invivo/bench/Benchmark.java
testcase-generation/src/edu/columbia/cs/psl/invivo/bench/ComplexObject.java
testcase-generation/src/edu/columbia/cs/psl/invivo/bench/SomeOtherObject.java
testcase-generation/src/edu/columbia/cs/psl/invivo/bench/WallaceLogExplorer.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/CloningUtils.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/Constants.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/ExportedLog.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/ExportedSerializableLog.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/Instrumenter.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/InstrumenterClassWriter.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/Log.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/MethodCall.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/SerializableLog.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/WallaceExportRunner.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/WallaceUncaughtExceptionHandler.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/analysis/MutabilityAnalyzer.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/AnnotatedMethod.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/Expression.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/FieldExpression.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/MethodExpression.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/SimpleExpression.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/CloningAdviceAdapter.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/NonDeterministicLoggingClassVisitor.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/NonDeterministicLoggingMethodVisitor.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/xstream/CatchClassErrorFieldDictionary.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/xstream/StaticReflectionProvider.java
testcase-generation/src/edu/columbia/cs/psl/invivo/replay/NonDeterministicReplayClassVisitor.java
testcase-generation/src/edu/columbia/cs/psl/invivo/replay/NonDeterministicReplayMethodVisitor.java
testcase-generation/src/edu/columbia/cs/psl/invivo/replay/ReplayRunner.java
testcase-generation/src/edu/columbia/cs/psl/invivo/replay/Replayer.java
testcase-generation/src/edu/columbia/cs/psl/invivo/sample/OtherClass.java
testcase-generation/src/edu/columbia/cs/psl/invivo/sample/SimpleClass.java
testcase-generation/src/edu/columbia/cs/psl/wallace/CloningUtils.java
testcase-generation/src/edu/columbia/cs/psl/wallace/Constants.java
testcase-generation/src/edu/columbia/cs/psl/wallace/ExportedLog.java
testcase-generation/src/edu/columbia/cs/psl/wallace/ExportedSerializableLog.java
testcase-generation/src/edu/columbia/cs/psl/wallace/Instrumenter.java
testcase-generation/src/edu/columbia/cs/psl/wallace/InstrumenterClassWriter.java
testcase-generation/src/edu/columbia/cs/psl/wallace/Log.java
testcase-generation/src/edu/columbia/cs/psl/wallace/MethodCall.java
testcase-generation/src/edu/columbia/cs/psl/wallace/SerializableLog.java
testcase-generation/src/edu/columbia/cs/psl/wallace/WallaceExportRunner.java
testcase-generation/src/edu/columbia/cs/psl/wallace/WallaceUncaughtExceptionHandler.java
testcase-generation/src/edu/columbia/cs/psl/wallace/analysis/MutabilityAnalyzer.java
testcase-generation/src/edu/columbia/cs/psl/wallace/bench/WallaceLogExplorer.java
testcase-generation/src/edu/columbia/cs/psl/wallace/replay/NonDeterministicReplayClassVisitor.java
testcase-generation/src/edu/columbia/cs/psl/wallace/replay/NonDeterministicReplayMethodVisitor.java
testcase-generation/src/edu/columbia/cs/psl/wallace/replay/ReplayRunner.java
testcase-generation/src/edu/columbia/cs/psl/wallace/replay/Replayer.java
testcase-generation/src/edu/columbia/cs/psl/wallace/struct/AnnotatedMethod.java
testcase-generation/src/edu/columbia/cs/psl/wallace/struct/Expression.java
testcase-generation/src/edu/columbia/cs/psl/wallace/struct/FieldExpression.java
testcase-generation/src/edu/columbia/cs/psl/wallace/struct/MethodExpression.java
testcase-generation/src/edu/columbia/cs/psl/wallace/struct/SimpleExpression.java
testcase-generation/src/edu/columbia/cs/psl/wallace/visitor/CloningAdviceAdapter.java
testcase-generation/src/edu/columbia/cs/psl/wallace/visitor/NonDeterministicLoggingClassVisitor.java
testcase-generation/src/edu/columbia/cs/psl/wallace/visitor/NonDeterministicLoggingMethodVisitor.java
testcase-generation/src/edu/columbia/cs/psl/wallace/xstream/CatchClassErrorFieldDictionary.java
testcase-generation/src/edu/columbia/cs/psl/wallace/xstream/StaticReflectionProvider.java
diff --git a/testcase-generation-tester/src/edu/columbia/cs/psl/invivo/example/DummyDriver.java b/testcase-generation-tester/src/edu/columbia/cs/psl/invivo/example/DummyDriver.java
index bb5faff..6a91dd8 100644
--- a/testcase-generation-tester/src/edu/columbia/cs/psl/invivo/example/DummyDriver.java
+++ b/testcase-generation-tester/src/edu/columbia/cs/psl/invivo/example/DummyDriver.java
@@ -21,8 +21,8 @@ import javax.swing.JPanel;

 import com.thoughtworks.xstream.XStream;

-import edu.columbia.cs.psl.invivo.record.Constants;
-import edu.columbia.cs.psl.invivo.record.xstream.StaticReflectionProvider;
+import edu.columbia.cs.psl.wallace.Constants;
+import edu.columbia.cs.psl.wallace.xstream.StaticReflectionProvider;


 public class DummyDriver extends SimpleClass {
diff --git a/testcase-generation-tester/src/edu/columbia/cs/psl/invivo/example/ReaderUser.java b/testcase-generation-tester/src/edu/columbia/cs/psl/invivo/example/ReaderUser.java
index 41fb143..444bced 100644
--- a/testcase-generation-tester/src/edu/columbia/cs/psl/invivo/example/ReaderUser.java
+++ b/testcase-generation-tester/src/edu/columbia/cs/psl/invivo/example/ReaderUser.java
@@ -14,8 +14,8 @@ import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.util.Arrays;

-import edu.columbia.cs.psl.invivo.record.ExportedLog;
-import edu.columbia.cs.psl.invivo.record.Log;
+import edu.columbia.cs.psl.wallace.ExportedLog;
+import edu.columbia.cs.psl.wallace.Log;

 public class ReaderUser extends InputStreamReader {
 	protected ReaderUser(InputStream in) {
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/bench/BeingCloned.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/bench/BeingCloned.java
deleted file mode 100644
index c5f9009..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/bench/BeingCloned.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package edu.columbia.cs.psl.invivo.bench;
-
-import java.util.IdentityHashMap;
-
-public class BeingCloned {
-	public static IdentityHashMap<Object, Object> cloneCache;
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/bench/Benchmark.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/bench/Benchmark.java
deleted file mode 100644
index 2a449a7..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/bench/Benchmark.java
+++ /dev/null
@@ -1,105 +0,0 @@
-package edu.columbia.cs.psl.invivo.bench;
-
-import java.io.File;
-
-import com.rits.cloning.Cloner;
-
-public class Benchmark {
-	private static Cloner cloner = new Cloner();
-	public static void main(String[] args) {
-
-//		for(int i = 0; i< 35; i++)
-//		{
-//			System.out.println("if(annoying"+i+" != null) ret.annoying"+i+" = annoying"+i+"._copy();");
-//		}
-//		System.exit(0);
-		for(int i = 0; i < 5; i++)
-		{
-			SomeOtherObject o = generateObjects();
-			long start  = System.currentTimeMillis();
-			SomeOtherObject o2 = o.copy();
-			long end = System.currentTimeMillis();
-			System.out.println("Static: " + (end - start));
-			o = null;
-			try {
-				Thread.sleep(1000);
-			} catch (InterruptedException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-		}
-
-		for(int i = 0; i < 5; i++)
-		{
-			SomeOtherObject o = generateObjects();
-			long start  = System.currentTimeMillis();
-			SomeOtherObject o2 = cloner.deepClone(o);
-			long end = System.currentTimeMillis();
-			System.out.println("Deep: " + (end - start));
-			o = null;
-			try {
-				Thread.sleep(1000);
-			} catch (InterruptedException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-		}
-	}
-
-	private static SomeOtherObject generateObjects() {
-		SomeOtherObject n = new SomeOtherObject(new File("asfd"), new ComplexObject(), new SomeOtherObject(), "asdf", 3);
-//		n.setOtherObject(n);
-//		SomeOtherObject n2 = new SomeOtherObject(n.getF(), n.getO(), null, "aslfdjsaf", 4);
-//		n.getO().setChildren2(new ArrayList<ComplexObject>());
-//		for(int i = 0; i< 1000; i++)
-//		{
-//			ComplexObject oo = new ComplexObject();
-//			oo.setChildren(new ComplexObject[50]);
-//			oo.setChildren2(new ArrayList<ComplexObject>());
-//			n.getO().getChildren2().add(oo);
-//			oo.annoying0 = new ComplexObject();
-//			oo.annoying1 = new ComplexObject();
-//			oo.annoying2 = new ComplexObject();
-//			oo.annoying3 = new ComplexObject();
-//			oo.annoying4 = new ComplexObject();
-//			oo.annoying5 = new ComplexObject();
-//			oo.annoying6 = new ComplexObject();
-//			oo.annoying7 = new ComplexObject();
-//			oo.annoying8 = new ComplexObject();
-//			oo.annoying9 = new ComplexObject();
-//			oo.annoying10 = new ComplexObject();
-//			oo.annoying11 = new ComplexObject();
-//			oo.annoying12 = new ComplexObject();
-//			oo.annoying13 = new ComplexObject();
-//			oo.annoying14 = new ComplexObject();
-//			oo.annoying15 = new ComplexObject();
-//			oo.annoying16 = new ComplexObject();
-//			oo.annoying17 = new ComplexObject();
-//			oo.annoying18 = new ComplexObject();
-//			oo.annoying19 = new ComplexObject();
-//			oo.annoying20 = new ComplexObject();
-//			oo.annoying21 = new ComplexObject();
-//			oo.annoying22 = new ComplexObject();
-//			oo.annoying23 = new ComplexObject();
-//			oo.annoying24 = new ComplexObject();
-//			oo.annoying25 = new ComplexObject();
-//			oo.annoying26 = new ComplexObject();
-//			oo.annoying27 = new ComplexObject();
-//			oo.annoying28 = new ComplexObject();
-//			oo.annoying29 = new ComplexObject();
-//			oo.annoying30 = new ComplexObject();
-//			oo.annoying31 = new ComplexObject();
-//			oo.annoying32 = new ComplexObject();
-//			oo.annoying33 = new ComplexObject();
-//			oo.annoying34 = new ComplexObject();
-//
-//			for(int j = 0;j<50;j++)
-//			{
-//				oo.getChildren()[j] = new ComplexObject(null, new ArrayList<ComplexObject>(), oo, "asdf", n2);
-//				oo.getChildren2().add(oo.getChildren()[j]);
-//			}
-//			oo.setSoo(n);
-//		}
-		return n;
-	}
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/bench/ComplexObject.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/bench/ComplexObject.java
deleted file mode 100644
index 036770a..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/bench/ComplexObject.java
+++ /dev/null
@@ -1,174 +0,0 @@
-package edu.columbia.cs.psl.invivo.bench;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-
-import edu.columbia.cs.psl.invivo.record.CloningUtils;
-import edu.columbia.cs.psl.invivo.record.Instrumenter;
-import edu.columbia.cs.psl.invivo.sample.SimpleClass;
-
-public class ComplexObject extends SimpleClass implements Cloneable {
-	private String[] children;
-	private HashMap<String, Integer> children2;
-	private ComplexObject parent;
-	private String s;
-	private SomeOtherObject soo;
-
-	public ComplexObject annoying0;
-	public ComplexObject annoying1;
-	public ComplexObject annoying2;
-	public ComplexObject annoying3;
-	public ComplexObject annoying4;
-	public ComplexObject annoying5;
-	public ComplexObject annoying6;
-	public ComplexObject annoying7;
-	public ComplexObject annoying8;
-	public ComplexObject annoying9;
-	public ComplexObject annoying10;
-	public ComplexObject annoying11;
-	public ComplexObject annoying12;
-	public ComplexObject annoying13;
-	public ComplexObject annoying14;
-	public ComplexObject annoying15;
-	public ComplexObject annoying16;
-	public ComplexObject annoying17;
-	public ComplexObject annoying18;
-	public ComplexObject annoying19;
-	public ComplexObject annoying20;
-	public ComplexObject annoying21;
-	public ComplexObject annoying22;
-	public ComplexObject annoying23;
-	public ComplexObject annoying24;
-	public ComplexObject annoying25;
-	public ComplexObject annoying26;
-	public ComplexObject annoying27;
-	public ComplexObject annoying28;
-	public ComplexObject annoying29;
-	public ComplexObject annoying30;
-	public ComplexObject annoying31;
-	public ComplexObject annoying32;
-	public ComplexObject annoying33;
-	public ComplexObject annoying34;
-
-
-	public ComplexObject()
-	{
-
-	}
-
-//	public ComplexObject[] getChildren() {
-//		return children;
-//	}
-//
-//	public void setChildren(ComplexObject[] children) {
-//		this.children = children;
-//	}
-//
-//	public ArrayList<String> getChildren2() {
-//		return children2;
-//	}
-//
-//	public void setChildren2(ArrayList<String> children2) {
-//		this.children2 = children2;
-//	}
-
-	public ComplexObject getParent() {
-		return parent;
-	}
-
-	public void setParent(ComplexObject parent) {
-		this.parent = parent;
-	}
-
-	public String getS() {
-		return s;
-	}
-
-	public void setS(String s) {
-		this.s = s;
-	}
-
-	public SomeOtherObject getSoo() {
-		return soo;
-	}
-
-	public void setSoo(SomeOtherObject soo) {
-		this.soo = soo;
-	}
-
-	public ComplexObject copy()
-	{
-		BeingCloned.cloneCache = new IdentityHashMap<Object, Object>();
-		ComplexObject ret = null;
-		try {
-			ret = _copy();
-		} catch (CloneNotSupportedException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-		return ret;
-	}
-
-	static String[][] children1 = null;
-	static int children1_fill;
-
-	public ComplexObject _copy() throws CloneNotSupportedException {
-		if(CloningUtils.cloneCache.containsKey(this))
-			return (ComplexObject) CloningUtils.cloneCache.get(this);
-
-		final ComplexObject ret = (ComplexObject) clone();
-
-		CloningUtils.cloneCache.put(ret, ret);
-
-//		ret.annoying0 = CloningUtils.cloner.deepClone(this.annoying0);
-
-		if (Instrumenter.instrumentedClasses.containsKey(this.getClass().getSuperclass().getName())) {
-//			ret = super.setFieldsOn(ret);
-		}
-
-		//BeingCloned.cloneCache.put(this, ret);
-
-		/*if (children2 != null) {
-			ret.children2 = new HashMap<String, Integer>();
-
-			for (Entry<String, Integer> e : children2.entrySet())
-				ret.children2.put(e.getKey().toString(), e.getValue());
-		}*/
-
-		/*if(parent != null)
-			ret.parent = parent._copy();
-		*/
-
-		if(children != null)
-		{
-			String[] children2 = children1[children1_fill];
-
-			String[] children = new String[children2.length];
-
-			System.arraycopy(children2, 0, children, 0, children2.length);
-		}
-		/*
-		if(soo != null)
-			ret.soo = soo._copy();
-
-		if (s != null)
-			ret.s = s;
-		*/
-
-		return ret;
-	}
-
-	public ComplexObject(ComplexObject[] children, ArrayList<String> children2, ComplexObject parent, String s, SomeOtherObject soo) {
-//		this.children = children;
-//		this.children2 = children2;
-		this.parent = parent;
-		this.s = s;
-		this.soo = soo;
-	}
-	public ComplexObject setFieldsOn(ComplexObject ret) {
-		super.setFieldsOn(ret);
-		return null;
-	}
-
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/bench/SomeOtherObject.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/bench/SomeOtherObject.java
deleted file mode 100644
index 36525ec..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/bench/SomeOtherObject.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package edu.columbia.cs.psl.invivo.bench;
-
-import java.io.File;
-import java.util.IdentityHashMap;
-
-public class SomeOtherObject implements Cloneable {
-	private File f;
-	private ComplexObject o;
-	private SomeOtherObject otherObject;
-	private String s;
-	private int n;
-	public SomeOtherObject(File f, ComplexObject o, SomeOtherObject otherObject, String s, int n) {
-		this.f = f;
-		this.o = o;
-		this.otherObject = otherObject;
-		this.s = s;
-		this.n = n;
-	}
-	public File getF() {
-		return f;
-	}
-	public void setF(File f) {
-		this.f = f;
-	}
-	public ComplexObject getO() {
-		return o;
-	}
-	public void setO(ComplexObject o) {
-		this.o = o;
-	}
-	public SomeOtherObject getOtherObject() {
-		return otherObject;
-	}
-	public void setOtherObject(SomeOtherObject otherObject) {
-		this.otherObject = otherObject;
-	}
-	public String getS() {
-		return s;
-	}
-	public void setS(String s) {
-		this.s = s;
-	}
-	public int getN() {
-		return n;
-	}
-	public void setN(int n) {
-		this.n = n;
-	}
-	public SomeOtherObject()
-	{
-
-	}
-	public SomeOtherObject _copy() throws CloneNotSupportedException
-	{
-		if(BeingCloned.cloneCache.containsKey(this))
-			return (SomeOtherObject) BeingCloned.cloneCache.get(this);
-		final SomeOtherObject ret = (SomeOtherObject) clone();
-		BeingCloned.cloneCache.put(this, ret);
-		if(o !=null)
-			ret.o = o._copy();
-		if(otherObject != null)
-			ret.otherObject = otherObject._copy();
-		if(s != null)
-			ret.s = s;
-		ret.n = n;
-		return ret;
-	}
-	public SomeOtherObject copy() {
-		BeingCloned.cloneCache = new IdentityHashMap<Object, Object>();
-		SomeOtherObject ret = null;
-		try {
-			ret = _copy();
-		} catch (CloneNotSupportedException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-		BeingCloned.cloneCache = new IdentityHashMap<Object, Object>();
-		return ret;
-	}
-
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/bench/WallaceLogExplorer.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/bench/WallaceLogExplorer.java
deleted file mode 100644
index ef6315f..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/bench/WallaceLogExplorer.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package edu.columbia.cs.psl.invivo.bench;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.ObjectInputStream;
-
-import edu.columbia.cs.psl.invivo.record.ExportedSerializableLog;
-
-public class WallaceLogExplorer {
-	public static void main(String[] args) throws Exception {
-		File f = new File("instrumented/wallace_serializable_1344527362195.log");
-		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
-		ExportedSerializableLog log = (ExportedSerializableLog) ois.readObject();
-		Object[] alog = ExportedSerializableLog.aLog;
-
-		char[] clog = ExportedSerializableLog.cLog;
-		byte[] blog = ExportedSerializableLog.bLog;
-		String[] ownersA = ExportedSerializableLog.aLog_owners;
-		System.out.println(ExportedSerializableLog.aLog_fill);
-		System.out.println(ExportedSerializableLog.cLog_fill);
-		System.out.println(ExportedSerializableLog.dLog_fill);
-	}
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/CloningUtils.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/CloningUtils.java
deleted file mode 100644
index 6061eef..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/CloningUtils.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package edu.columbia.cs.psl.invivo.record;
-
-import java.io.BufferedWriter;
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.URI;
-import java.nio.channels.Channel;
-import java.security.Permissions;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.zip.Deflater;
-import java.util.zip.Inflater;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-import com.rits.cloning.Cloner;
-
-public class CloningUtils {
-	public static boolean				CATCH_ALL_ERRORS	= true;
-	private static Cloner				cloner				= new Cloner();
-	public static ReadWriteLock		exportLock			= new ReentrantReadWriteLock();
-	private static HashSet<Class<?>>	moreIgnoredImmutables;
-	private static HashSet<Class<?>>	nullInsteads;
-
-//	private static BufferedWriter		log;
-	static {
-		moreIgnoredImmutables = new HashSet<Class<?>>();
-		moreIgnoredImmutables.add(ClassLoader.class);
-		moreIgnoredImmutables.add(Thread.class);
-		moreIgnoredImmutables.add(URI.class);
-		moreIgnoredImmutables.add(File.class);
-		moreIgnoredImmutables.add(ZipFile.class);
-		moreIgnoredImmutables.add(ZipEntry.class);
-		moreIgnoredImmutables.add(Inflater.class);
-		moreIgnoredImmutables.add(InputStream.class);
-		moreIgnoredImmutables.add(OutputStream.class);
-		moreIgnoredImmutables.add(Deflater.class);
-		moreIgnoredImmutables.add(Socket.class);
-		moreIgnoredImmutables.add(ServerSocket.class);
-		moreIgnoredImmutables.add(Channel.class);
-		moreIgnoredImmutables.add(Closeable.class);
-		moreIgnoredImmutables.add(Class.class);
-		cloner.setExtraNullInsteadOfClone(moreIgnoredImmutables);
-		cloner.setExtraImmutables(moreIgnoredImmutables);
-
-		nullInsteads = new HashSet<Class<?>>();
-		nullInsteads.add(Permissions.class);
-		cloner.setExtraNullInsteadOfClone(nullInsteads);
-//		cloner.setDumpClonedClasses(true);
-		WallaceExportRunner.inst.start();
-		if (CATCH_ALL_ERRORS) {
-			Thread.setDefaultUncaughtExceptionHandler(new WallaceUncaughtExceptionHandler());
-		}
-//		try {
-//			File f = new File("cloneLog");
-//			if (f.exists())
-//				f.delete();
-//			log = new BufferedWriter(new FileWriter("cloneLog"));
-//		} catch (IOException e) {
-//			// TODO Auto-generated catch block
-//			e.printStackTrace();
-//		}
-	}
-
-	public static final <T> T clone(T obj, String debug) {
-// 		System.out.println("source>"+debug);
-			return cloner.deepClone(obj);
-	}
-
-	public static IdentityHashMap<Object, Object>	cloneCache	= new IdentityHashMap<Object, Object>();	;
-
-
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/Constants.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/Constants.java
deleted file mode 100644
index 9eb486a..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/Constants.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package edu.columbia.cs.psl.invivo.record;
-
-public interface Constants {
-	public static String BEEN_CLONED_PREFIX = "__beenCloned_";
-	public static String PREV_VALUE_PREFIX = "__origValue_";
-//	public static String LOGGED_CALL_PREFIX = "__loggedValueAt_";
-
-//	public static String LOG_DUMP_CLASS = "edu/columbia/cs/psl/invivo/record/Log";
-//	public static String LOG_REPLAY_CLASS = "edu/columbia/cs/psl/invivo/record/ExportedLog";
-
-	public static int DEFAULT_LOG_SIZE = 2000;
-	public static int MAX_LOG_SIZE = 40000000;
-	public static int VERY_MAX_LOG_SIZE = 400000000;
-
-	public static double LOG_GROWTH_RATE = 2.5;
-	public static String REPLAY_CLASS_SUFFIX = "InvivoReplay";
-	public static String INNER_COPY_METHOD_NAME = "_Invivo___copy";
-	public static String OUTER_COPY_METHOD_NAME = "_Invivo_copy";
-	public static String SET_FIELDS_METHOD_NAME = "_Invivo_set_fields";
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/ExportedLog.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/ExportedLog.java
deleted file mode 100644
index c16e511..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/ExportedLog.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package edu.columbia.cs.psl.invivo.record;
-
-import java.util.HashMap;
-
-public class ExportedLog {
-	public static Object[] aLog = new Object[Constants.DEFAULT_LOG_SIZE];
-	public static String[] aLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-
-	public static int aLog_fill;
-	public static HashMap<String, Integer> aLog_replayIndex = new HashMap<String, Integer>();
-	public static void clearLog() {
-		aLog = new Object[Constants.DEFAULT_LOG_SIZE];
-		aLog_owners =  new String[Constants.DEFAULT_LOG_SIZE];
-		aLog_fill = 0;
-	}
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/ExportedSerializableLog.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/ExportedSerializableLog.java
deleted file mode 100644
index 468aedb..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/ExportedSerializableLog.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package edu.columbia.cs.psl.invivo.record;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.util.HashMap;
-
-public class ExportedSerializableLog implements Serializable {
-	/**
-	 *
-	 */
-	private static final long serialVersionUID = 1166783255069514273L;
-	public static Object[]	aLog	= new Object[Constants.DEFAULT_LOG_SIZE];
-	public static int[] iLog = new int[Constants.DEFAULT_LOG_SIZE];
-	public static long[] jLog = new long[Constants.DEFAULT_LOG_SIZE];
-	public static float[] fLog = new float[Constants.DEFAULT_LOG_SIZE];
-	public static double[] dLog = new double[Constants.DEFAULT_LOG_SIZE];
-	public static byte[] bLog = new byte[Constants.DEFAULT_LOG_SIZE];
-	public static boolean[] zLog = new boolean[Constants.DEFAULT_LOG_SIZE];
-	public static char[] cLog = new char[Constants.DEFAULT_LOG_SIZE];
-	public static short[] sLog = new short[Constants.DEFAULT_LOG_SIZE];
-	public static Object lock = new Object();
-	public static int aLog_fill, iLog_fill, jLog_fill, fLog_fill, dLog_fill, bLog_fill, zLog_fill, cLog_fill, sLog_fill;
-
-	public static HashMap<String,Integer> aLog_replayIndex = new HashMap<String,Integer>();
-	public static HashMap<String,Integer> iLog_replayIndex = new HashMap<String,Integer>();
-	public static HashMap<String,Integer> jLog_replayIndex = new HashMap<String,Integer>();
-	public static HashMap<String,Integer> fLog_replayIndex = new HashMap<String,Integer>();
-	public static HashMap<String,Integer> dLog_replayIndex = new HashMap<String,Integer>();
-	public static HashMap<String,Integer> bLog_replayIndex = new HashMap<String,Integer>();
-	public static HashMap<String,Integer> zLog_replayIndex = new HashMap<String,Integer>();
-	public static HashMap<String,Integer> cLog_replayIndex = new HashMap<String,Integer>();
-	public static HashMap<String,Integer> sLog_replayIndex = new HashMap<String,Integer>();
-
-	public static String[] aLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-	public static String[] iLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-	public static String[] jLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-	public static String[] fLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-	public static String[] dLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-	public static String[] bLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-	public static String[] zLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-	public static String[] cLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-	public static String[] sLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-
-	public static void clearLog() {
-		aLog = new Serializable[Constants.DEFAULT_LOG_SIZE];
-		aLog_fill = 0;
-	}
-
-	private void writeObject(ObjectOutputStream oos) throws IOException {
-		oos.defaultWriteObject();
-		oos.writeInt(aLog_fill);
-		oos.writeObject(aLog);
-		oos.writeInt(iLog_fill);
-		oos.writeObject(iLog);
-		oos.writeInt(jLog_fill);
-		oos.writeObject(jLog);
-		oos.writeInt(fLog_fill);
-		oos.writeObject(fLog);
-		oos.writeInt(dLog_fill);
-		oos.writeObject(dLog);
-		oos.writeInt(bLog_fill);
-		oos.writeObject(bLog);
-		oos.writeInt(zLog_fill);
-		oos.writeObject(zLog);
-		oos.writeInt(cLog_fill);
-		oos.writeObject(cLog);
-		oos.writeInt(sLog_fill);
-		oos.writeObject(sLog);
-
-		oos.writeObject(aLog_owners);
-		oos.writeObject(iLog_owners);
-		oos.writeObject(jLog_owners);
-		oos.writeObject(fLog_owners);
-		oos.writeObject(dLog_owners);
-		oos.writeObject(bLog_owners);
-		oos.writeObject(zLog_owners);
-		oos.writeObject(cLog_owners);
-		oos.writeObject(sLog_owners);
-
-	}
-
-	private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
-		ois.defaultReadObject();
-		aLog_fill = ois.readInt();
-		aLog = (Object[]) ois.readObject();
-		iLog_fill = ois.readInt();
-		iLog = (int[]) ois.readObject();
-		jLog_fill = ois.readInt();
-		jLog = (long[]) ois.readObject();
-		fLog_fill = ois.readInt();
-		fLog = (float[]) ois.readObject();
-		dLog_fill = ois.readInt();
-		dLog = (double[]) ois.readObject();
-		bLog_fill = ois.readInt();
-		bLog = (byte[]) ois.readObject();
-		zLog_fill = ois.readInt();
-		zLog = (boolean[]) ois.readObject();
-		cLog_fill = ois.readInt();
-		cLog = (char[]) ois.readObject();
-		sLog_fill = ois.readInt();
-		sLog = (short[]) ois.readObject();
-
-		aLog_owners = (String[]) ois.readObject();
-		iLog_owners = (String[]) ois.readObject();
-		jLog_owners = (String[]) ois.readObject();
-		fLog_owners = (String[]) ois.readObject();
-		dLog_owners = (String[]) ois.readObject();
-		bLog_owners = (String[]) ois.readObject();
-		zLog_owners = (String[]) ois.readObject();
-		cLog_owners = (String[]) ois.readObject();
-		sLog_owners = (String[]) ois.readObject();
-
-		ExportedSerializableLog.aLog_replayIndex = new HashMap<String,Integer>();
-		ExportedSerializableLog.iLog_replayIndex = new HashMap<String,Integer>();
-		ExportedSerializableLog.jLog_replayIndex = new HashMap<String,Integer>();
-		ExportedSerializableLog.fLog_replayIndex = new HashMap<String,Integer>();
-		ExportedSerializableLog.dLog_replayIndex = new HashMap<String,Integer>();
-		ExportedSerializableLog.bLog_replayIndex = new HashMap<String,Integer>();
-		ExportedSerializableLog.zLog_replayIndex = new HashMap<String,Integer>();
-		ExportedSerializableLog.cLog_replayIndex = new HashMap<String,Integer>();
-		ExportedSerializableLog.sLog_replayIndex = new HashMap<String,Integer>();
-	}
-}
\ No newline at end of file
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/Instrumenter.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/Instrumenter.java
deleted file mode 100644
index f317a3e..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/Instrumenter.java
+++ /dev/null
@@ -1,342 +0,0 @@
-package edu.columbia.cs.psl.invivo.record;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.nio.channels.FileChannel;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Scanner;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.jar.JarOutputStream;
-
-import org.apache.log4j.Logger;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.commons.GeneratorAdapter;
-import org.objectweb.asm.tree.ClassNode;
-import org.objectweb.asm.tree.FieldNode;
-import org.objectweb.asm.util.CheckClassAdapter;
-
-import edu.columbia.cs.psl.invivo.record.analysis.MutabilityAnalyzer;
-import edu.columbia.cs.psl.invivo.record.struct.AnnotatedMethod;
-import edu.columbia.cs.psl.invivo.record.visitor.CloningAdviceAdapter;
-import edu.columbia.cs.psl.invivo.record.visitor.NonDeterministicLoggingClassVisitor;
-
-public class Instrumenter {
-	public static URLClassLoader						loader;
-	private static Logger								logger				= Logger.getLogger(Instrumenter.class);
-	public static HashMap<String, AnnotatedMethod>		annotatedMethods	= new HashMap<String, AnnotatedMethod>();
-	public static HashMap<String, ClassNode>			instrumentedClasses	= new HashMap<String, ClassNode>();
-
-	private static MutabilityAnalyzer					ma					= new MutabilityAnalyzer(annotatedMethods);
-	private static HashMap<String, HashSet<MethodCall>>	methodCalls			= new HashMap<String, HashSet<MethodCall>>();
-	private static final int							NUM_PASSES			= 2;
-	private static final int							PASS_ANALYZE		= 0;
-	private static final int							PASS_OUTPUT			= 1;
-
-	private static int									pass_number			= 0;
-
-	private static File									rootOutputDir;
-	private static String								lastInstrumentedClass;
-
-	public static AnnotatedMethod getAnnotatedMethod(String owner, String name, String desc) {
-		String lookupKey = owner + "." + name + ":" + desc;
-		return annotatedMethods.get(lookupKey);
-	}
-
-	private static void analyzeClass(InputStream inputStream) {
-		try {
-			ClassNode analysisResult = ma.analyzeClass(new ClassReader(inputStream));
-			instrumentedClasses.put(analysisResult.name, analysisResult);
-		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	}
-
-	private static void finishedPass() {
-		switch (pass_number) {
-		case PASS_ANALYZE:
-			ma.doneSupplyingClasses();
-			break;
-		case PASS_OUTPUT:
-			break;
-		}
-	}
-
-
-	private static byte[] instrumentClass(InputStream is) {
-		try {
-			ClassReader cr = new ClassReader(is);
-			ClassWriter cw = new InstrumenterClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES, loader);
-			NonDeterministicLoggingClassVisitor cv = new NonDeterministicLoggingClassVisitor(Opcodes.ASM4, cw);
-
-			cr.accept(cv, ClassReader.EXPAND_FRAMES);
-			if(methodCalls.containsKey(cv.getClassName()))
-				methodCalls.get(cv.getClassName()).addAll(cv.getLoggedMethodCalls());
-			else
-				methodCalls.put(cv.getClassName(), cv.getLoggedMethodCalls());
-			lastInstrumentedClass = cv.getClassName();
-			byte[] out = cw.toByteArray();
-			try{
-			 ClassReader cr2 = new ClassReader(out);
-			 cr2.accept(new CheckClassAdapter(new ClassWriter(0)), ClassReader.EXPAND_FRAMES);
-			}
-			catch(Exception ex)
-			{
-				System.err.println(lastInstrumentedClass);
-				ex.printStackTrace();
-			}
-			return out;
-		} catch (Exception ex) {
-			logger.error("Exception processing class: " + lastInstrumentedClass, ex);
-			return null;
-		}
-	}
-
-	public static void main(String[] args) {
-		if (args.length <= 1) {
-			System.err
-					.println("Usage: java edu.columbia.cs.psl.invivo.record.Instrumenter [outputFolder] [inputfolder] [classpath]\n Paths can be classes, directories, or jar files");
-			System.exit(-1);
-		}
-		String outputFolder = args[0];
-		rootOutputDir = new File(outputFolder);
-		if (!rootOutputDir.exists())
-			rootOutputDir.mkdir();
-		String inputFolder = args[1];
-		// Setup the class loader
-		URL[] urls = new URL[args.length - 2];
-		for (int i = 2; i < args.length; i++) {
-			File f = new File(args[i]);
-			if (!f.exists()) {
-				System.err.println("Unable to read path " + args[i]);
-				System.exit(-1);
-			}
-			if (f.isDirectory() && !f.getAbsolutePath().endsWith("/"))
-				f = new File(f.getAbsolutePath() + "/");
-			try {
-				urls[i - 2] = f.getCanonicalFile().toURI().toURL();
-			} catch (Exception ex) {
-				ex.printStackTrace();
-			}
-		}
-		loader = new URLClassLoader(urls, Instrumenter.class.getClassLoader());
-
-		for (pass_number = 0; pass_number < NUM_PASSES; pass_number++) // Do
-																		// each
-																		// pass.
-		{
-			File f = new File(inputFolder);
-			if (!f.exists()) {
-				System.err.println("Unable to read path " + inputFolder);
-				System.exit(-1);
-			}
-			if (f.isDirectory())
-				processDirectory(f, rootOutputDir, true);
-			else if (inputFolder.endsWith(".jar"))
-				processJar(f, rootOutputDir);
-			else if (inputFolder.endsWith(".class"))
-				try {
-					processClass(f.getName(), new FileInputStream(f), rootOutputDir);
-				} catch (FileNotFoundException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				}
-			else {
-				System.err.println("Unknown type for path " + inputFolder);
-				System.exit(-1);
-			}
-			finishedPass();
-		}
-		// }
-
-	}
-
-	private static void processClass(String name, InputStream is, File outputDir) {
-		switch (pass_number) {
-		case PASS_ANALYZE:
-			analyzeClass(is);
-			break;
-		case PASS_OUTPUT:
-			try {
-					FileOutputStream fos = new FileOutputStream(outputDir.getPath() + File.separator + name);
-					ByteArrayOutputStream bos = new ByteArrayOutputStream();
-					bos.write(instrumentClass(is));
-					bos.writeTo(fos);
-					fos.close();
-
-
-			} catch (Exception ex) {
-				ex.printStackTrace();
-			}
-		}
-	}
-
-
-
-	private static void processDirectory(File f, File parentOutputDir, boolean isFirstLevel) {
-		File thisOutputDir;
-		if (isFirstLevel) {
-			thisOutputDir = parentOutputDir;
-		} else {
-			thisOutputDir = new File(parentOutputDir.getAbsolutePath() + File.separator + f.getName());
-			if (pass_number == PASS_OUTPUT)
-				thisOutputDir.mkdir();
-		}
-		for (File fi : f.listFiles()) {
-			if (fi.isDirectory())
-				processDirectory(fi, thisOutputDir, false);
-			else if (fi.getName().endsWith(".class"))
-				try {
-					processClass(fi.getName(), new FileInputStream(fi), thisOutputDir);
-				} catch (FileNotFoundException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				}
-			else if (fi.getName().endsWith(".jar"))
-				processJar(fi, thisOutputDir);
-			else if (pass_number == PASS_OUTPUT) {
-				File dest = new File(thisOutputDir.getPath() + File.separator + fi.getName());
-				FileChannel source = null;
-				FileChannel destination = null;
-
-				try {
-					source = new FileInputStream(fi).getChannel();
-					destination = new FileOutputStream(dest).getChannel();
-					destination.transferFrom(source, 0, source.size());
-				} catch (Exception ex) {
-					logger.error("Unable to copy file " + fi, ex);
-					System.exit(-1);
-				} finally {
-					if (source != null) {
-						try {
-							source.close();
-						} catch (IOException e) {
-							// TODO Auto-generated catch block
-							e.printStackTrace();
-						}
-					}
-					if (destination != null) {
-						try {
-							destination.close();
-						} catch (IOException e) {
-							// TODO Auto-generated catch block
-							e.printStackTrace();
-						}
-					}
-				}
-
-			}
-		}
-
-	}
-
-	private static void processJar(File f, File outputDir) {
-		try {
-			JarFile jar = new JarFile(f);
-			JarOutputStream jos = null;
-			if (pass_number == PASS_OUTPUT)
-				jos = new JarOutputStream(new FileOutputStream(outputDir.getPath() + File.separator + f.getName()));
-			Enumeration<JarEntry> entries = jar.entries();
-			while (entries.hasMoreElements()) {
-				JarEntry e = entries.nextElement();
-				switch (pass_number) {
-				case PASS_ANALYZE:
-					if (e.getName().endsWith(".class")) {
-						analyzeClass(jar.getInputStream(e));
-					}
-					break;
-				case PASS_OUTPUT:
-					if (e.getName().endsWith(".class") && !e.getName().startsWith("java") && !e.getName().startsWith("org/objenesis")
-							&& !e.getName().startsWith("com/thoughtworks/xstream/") && !e.getName().startsWith("com/rits/cloning")
-							&& !e.getName().startsWith("com/apple/java/Application")) {
-						{
-							JarEntry outEntry = new JarEntry(e.getName());
-							jos.putNextEntry(outEntry);
-							byte[] clazz = instrumentClass(jar.getInputStream(e));
-							if(clazz == null)
-							{
-								InputStream is = jar.getInputStream(e);
-								byte[] buffer = new byte[1024];
-								while (true) {
-									int count = is.read(buffer);
-									if (count == -1)
-										break;
-									jos.write(buffer, 0, count);
-								}
-							}
-							else
-									jos.write(clazz);
-							jos.closeEntry();
-						}
-
-
-					} else {
-						JarEntry outEntry = new JarEntry(e.getName());
-						if (e.isDirectory()) {
-							jos.putNextEntry(outEntry);
-							jos.closeEntry();
-						} else if (e.getName().startsWith("META-INF") && (e.getName().endsWith(".SF") || e.getName().endsWith(".RSA"))) {
-							// don't copy this
-						} else if (e.getName().equals("META-INF/MANIFEST.MF")) {
-							String newManifest = "";
-							Scanner s = new Scanner(jar.getInputStream(e));
-							jos.putNextEntry(outEntry);
-
-							String curPair = "";
-							while (s.hasNextLine()) {
-								String line = s.nextLine();
-								if (line.equals("")) {
-									curPair += "\n";
-									if (!curPair.contains("SHA1-Digest:"))
-										jos.write(curPair.getBytes());
-									curPair = "";
-								} else {
-									curPair += line + "\n";
-								}
-							}
-							jos.write("\n".getBytes());
-							jos.closeEntry();
-						} else {
-							jos.putNextEntry(outEntry);
-							InputStream is = jar.getInputStream(e);
-							byte[] buffer = new byte[1024];
-							while (true) {
-								int count = is.read(buffer);
-								if (count == -1)
-									break;
-								jos.write(buffer, 0, count);
-							}
-							jos.closeEntry();
-						}
-					}
-				}
-
-			}
-			if (pass_number == PASS_OUTPUT) {
-				jos.close();
-			}
-		} catch (Exception e) {
-			// TODO Auto-generated catch block
-			logger.error("Unable to process jar" + f, e);
-			System.exit(-1);
-		}
-
-	}
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/InstrumenterClassWriter.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/InstrumenterClassWriter.java
deleted file mode 100644
index 2813b6f..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/InstrumenterClassWriter.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package edu.columbia.cs.psl.invivo.record;
-
-import java.net.URLClassLoader;
-
-import org.apache.log4j.Logger;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassWriter;
-
-public class InstrumenterClassWriter extends ClassWriter {
-	private static Logger logger = Logger.getLogger(InstrumenterClassWriter.class);
-	private ClassLoader loader;
-	public InstrumenterClassWriter(ClassReader classReader, int flags, ClassLoader loader) {
-		super(classReader, flags);
-		this.loader = loader;
-	}
-
-	public InstrumenterClassWriter(int flags, URLClassLoader loader) {
-		super(flags);
-		this.loader=loader;
-	}
-
-	@Override
-	protected String getCommonSuperClass(String type1, String type2) {
-		Class<?> c, d;
-        try {
-            c = Class.forName(type1.replace('/', '.'), false, loader);
-            d = Class.forName(type2.replace('/', '.'), false, loader);
-        } catch (ClassNotFoundException e) {
-        	logger.debug("Error while finding common super class for " + type1 +"; " + type2,e);
-        	return "java/lang/Object";
-//        	throw new RuntimeException(e);
-        }
-        if (c.isAssignableFrom(d)) {
-            return type1;
-        }
-        if (d.isAssignableFrom(c)) {
-            return type2;
-        }
-        if (c.isInterface() || d.isInterface()) {
-            return "java/lang/Object";
-        } else {
-            do {
-                c = c.getSuperclass();
-            } while (!c.isAssignableFrom(d));
-            return c.getName().replace('.', '/');
-        }
-	}
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/Log.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/Log.java
deleted file mode 100644
index b7ceeb4..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/Log.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package edu.columbia.cs.psl.invivo.record;
-
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-public class Log {
-	public static Object[] aLog = new Object[Constants.DEFAULT_LOG_SIZE];
-	public static String[] aLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-	public static Lock logLock = new ReentrantLock();
-//	public static Object lock = new Object();
-	public static int logsize = 0;
-	public static int aLog_fill;
-
-
-	public static void clearLog() {
-//		System.err.println("start cl");
-		logsize = 0;
-		aLog = new Object[Constants.DEFAULT_LOG_SIZE];
-		aLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-
-		aLog_fill = 0;
-
-//		System.err.println("starting gc");
-//		System.gc();
-//		System.err.println("Fin gc");
-	}
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/MethodCall.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/MethodCall.java
deleted file mode 100644
index 1d3094b..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/MethodCall.java
+++ /dev/null
@@ -1,163 +0,0 @@
-package edu.columbia.cs.psl.invivo.record;
-
-import java.util.HashSet;
-
-import org.objectweb.asm.Type;
-
-public class MethodCall {
-	private String sourceMethodName;
-	private String sourceMethodDesc;
-	private String sourceClass;
-	private int pc;
-	private int lineNumber;
-	private String methodOwner;
-	private String methodName;
-	private String methodDesc;
-	private boolean isStatic;
-
-	private static HashSet<String> serializableClasses = new HashSet<String>();
-	static{
-		serializableClasses.add(Type.getType(String.class).getInternalName());
-	}
-	public MethodCall(String sourceMethodName, String sourceMethodDesc, String sourceClass, int pc, int lineNumber, String methodOwner, String methodName, String methodDesc, boolean isStatic) {
-		this.sourceMethodName = sourceMethodName;
-		this.sourceMethodDesc = sourceMethodDesc;
-		this.sourceClass = sourceClass;
-		this.pc = pc;
-		this.lineNumber = lineNumber;
-		this.methodOwner = methodOwner;
-		this.methodName = methodName;
-		this.methodDesc = methodDesc;
-		this.isStatic = isStatic;
-	}
-	public boolean isStatic() {
-		return isStatic;
-	}
-	public String getSourceMethodName() {
-		return sourceMethodName;
-	}
-	public String getSourceMethodDesc() {
-		return sourceMethodDesc;
-	}
-	public String getSourceClass() {
-		return sourceClass;
-	}
-	public int getPc() {
-		return pc;
-	}
-	public int getLineNumber() {
-		return lineNumber;
-	}
-	public String getMethodOwner() {
-		return methodOwner;
-	}
-	public String getMethodName() {
-		return methodName;
-	}
-	public String getMethodDesc() {
-		return methodDesc;
-	}
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + lineNumber;
-		result = prime * result + ((methodName == null) ? 0 : methodName.hashCode());
-		result = prime * result + pc;
-		result = prime * result + ((sourceClass == null) ? 0 : sourceClass.hashCode());
-		result = prime * result + ((sourceMethodName == null) ? 0 : sourceMethodName.hashCode());
-		return result;
-	}
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		MethodCall other = (MethodCall) obj;
-		if(other.getLogFieldName().equals(this.getLogFieldName()) && other.sourceClass.equals(this.sourceClass))
-			return true;
-		return false;
-	}
-	public static String getLogClassName(Type t)
-	{
-		if((t.getSort() != Type.OBJECT  && t.getSort() != Type.ARRAY)|| //primitives
-				(t.getSort() == Type.OBJECT && serializableClasses.contains(t.getInternalName())) || //serializble
-				(t.getSort() == Type.ARRAY && ((t.getElementType().getSort() != Type.OBJECT && t.getElementType().getSort() != Type.ARRAY)|| serializableClasses.contains(t.getElementType().getInternalName())))) // array of prims or array of serializable
-			return Type.getInternalName(SerializableLog.class);
-		else
-			return Type.getInternalName(Log.class);
-	}
-	public static String getReplayClassName(Type t)
-	{
-		if(getLogClassName(t).equals(Type.getInternalName(SerializableLog.class)))
-			return Type.getInternalName(ExportedSerializableLog.class);
-		else
-			return Type.getInternalName(ExportedLog.class);
-	}
-	public String getReplayClassName()
-	{
-		return getReplayClassName(Type.getReturnType(methodDesc));
-	}
-	public String getLogClassName()
-	{
-		return getLogClassName(Type.getReturnType(methodDesc));
-	}
-	public String getCapturePrefix()
-	{
-		String r = sourceMethodName.replace("<", "___").replace(">", "___")+"$$$$"+methodName.replace("<", "___").replace(">", "___")+"$$$$";
-		r += lineNumber+ "$"+pc;
-		return r;
-	}
-	public String getLogFieldName()
-	{
-//		Type[] args = Type.getArgumentTypes(methodDesc);
-//		String r = sourceMethodName.replace("<", "___").replace(">", "___")+"$$$$"+methodName+"$$$$";
-//		for(Type t : args)
-//		{
-//			r+=t.getInternalName().replace("/", "$")+"$$";
-//		}
-//		r += lineNumber+ "$"+pc;
-		Type t= Type.getReturnType(methodDesc);
-		if(t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY || methodName.equals("<init>"))
-			return "aLog";
-		else if(t.getSort() == Type.VOID)
-			return "bLog";
-		else
-			return t.getDescriptor().toLowerCase()+"Log";
-	}
-	public Type getReturnType()
-	{
-		return Type.getMethodType(methodDesc).getReturnType();
-	}
-	public Type getLogFieldType() {
-		Type t = Type.getMethodType(methodDesc).getReturnType();
-		if(t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)
-			return Type.getType("[Ljava/lang/Object;");
-		else if(t.getSort() == Type.VOID)
-			return Type.getType("["+Type.BYTE);
-		else
-			return Type.getType("["+t.getDescriptor());
-//		return Type.getType("["+Type.getMethodType(methodDesc).getReturnType().getDescriptor());
-	}
-	public static String getLogFieldName(Type t)
-	{
-		if(t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)
-			return "aLog";
-		else if(t.getSort() == Type.VOID)
-			return "bLog";
-		else
-			return t.getDescriptor().toLowerCase()+"Log";
-	}
-	public static Type getLogFieldType(Type t)
-	{
-		if(t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)
-			return Type.getType("[Ljava/lang/Object;");
-		else if(t.getSort() == Type.VOID)
-			return Type.getType("["+Type.BYTE);
-		else
-			return Type.getType("["+t.getDescriptor());
-	}
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/SerializableLog.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/SerializableLog.java
deleted file mode 100644
index 7b0c2db..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/SerializableLog.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package edu.columbia.cs.psl.invivo.record;
-
-import java.io.Serializable;
-
-public class SerializableLog implements Serializable{
-
-	private static final long	serialVersionUID	= 4627796984904522647L;
-	public static Object[] aLog = new Object[Constants.DEFAULT_LOG_SIZE];
-
-	public static int[] iLog = new int[Constants.DEFAULT_LOG_SIZE];
-	public static long[] jLog = new long[Constants.DEFAULT_LOG_SIZE];
-	public static float[] fLog = new float[Constants.DEFAULT_LOG_SIZE];
-	public static double[] dLog = new double[Constants.DEFAULT_LOG_SIZE];
-	public static byte[] bLog = new byte[Constants.DEFAULT_LOG_SIZE];
-	public static boolean[] zLog = new boolean[Constants.DEFAULT_LOG_SIZE];
-	public static char[] cLog = new char[Constants.DEFAULT_LOG_SIZE];
-	public static short[] sLog = new short[Constants.DEFAULT_LOG_SIZE];
-
-	public static String[] aLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-	public static String[] iLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-	public static String[] jLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-	public static String[] fLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-	public static String[] dLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-	public static String[] bLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-	public static String[] zLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-	public static String[] cLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-	public static String[] sLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-
-	public static int logsize = 0;
-	public static int aLog_fill, iLog_fill, jLog_fill, fLog_fill, dLog_fill, bLog_fill, zLog_fill, cLog_fill, sLog_fill;
-
-
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/WallaceExportRunner.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/WallaceExportRunner.java
deleted file mode 100644
index fec9ada..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/WallaceExportRunner.java
+++ /dev/null
@@ -1,222 +0,0 @@
-package edu.columbia.cs.psl.invivo.record;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.ObjectOutputStream;
-import java.lang.reflect.Field;
-
-import com.thoughtworks.xstream.XStream;
-
-import edu.columbia.cs.psl.invivo.record.xstream.StaticReflectionProvider;
-
-public class WallaceExportRunner extends Thread {
-	// static Class<?> logger;
-	static {
-		// try {
-		// // System.err.println("Loading log class");
-		// logger = Class.forName(Constants.LOG_DUMP_CLASS.replace("/", "."));
-		// // System.err.println("Loaded");
-		// } catch (ClassNotFoundException e) {
-		// // TODO Auto-generated catch block
-		// e.printStackTrace();
-		// }
-	}
-
-	@Override
-	public void run() {
-		// System.err.println("Export runner started");
-		while (1 == 1) {
-			// System.out.println("Exporting");
-			// System.err.println("Exporting");
-			// export(); //TODO uncomment
-			// System.err.println("Exported");
-			try {
-				// Thread.sleep(60000); //1 minute
-				// Thread.sleep(300000); //5 minutes
-				Thread.sleep(10000); // 10 seconds
-				// Thread.sleep(5000); //5 seconds
-				// Thread.sleep(1000); //1 seconds
-				// System.out.println("Waking up checking flag");
-				if (shouldExport == 1)
-					export();
-				if (shouldExportSerializable == 1)
-					exportSerializable();
-				if (shouldExport == 1)
-					export();
-
-			} catch (InterruptedException e) {
-				if (shouldExport == 1)
-					export();
-				if (shouldExportSerializable == 1)
-					exportSerializable();
-				if (shouldExport == 1)
-					export();
-			}
-		}
-	}
-
-	static WallaceExportRunner inst = new WallaceExportRunner();
-
-	public WallaceExportRunner() {
-		setDaemon(true);
-		setPriority(Thread.MAX_PRIORITY);
-	}
-
-	private static ExportedLog log = new ExportedLog();
-
-	public static void export() {
-		shouldExport = 0;
-		try {
-			XStream xstream = new XStream(new StaticReflectionProvider());
-			String xml = "";
-			// System.out.println("Waiting for the lock");
-			Log.logLock.lock();
-			ExportedLog.aLog = Log.aLog;
-			ExportedLog.aLog_owners = Log.aLog_owners;
-			ExportedLog.aLog_fill = Log.aLog_fill;
-			Log.logsize = 0;
-			Log.aLog = new Object[Constants.DEFAULT_LOG_SIZE];
-			Log.aLog_fill = 0;
-			Log.logLock.unlock();
-//			System.err.println("Serializing");
-			try {
-				xml = xstream.toXML(log);
-			} catch (Exception ex) {
-				System.err.println("NPE" + ex.getMessage());
-			}
-			// System.err.println("Clearing");
-			ExportedLog.clearLog();
-			// System.err.println("Cleared");
-
-			// CloningUtils.exportLock.writeLock().unlock();
-			File output = new File("wallace_" + System.currentTimeMillis() + ".log");
-			FileWriter fw = new FileWriter(output);
-			fw.write(xml);
-			fw.close();
-			// synchronized (Log.lock) {
-			// Log.lock.notifyAll();
-			// }
-			// synchronized (Log.lock) {
-			// Log.lock.notifyAll();
-			// }
-
-		} catch (Exception exi) {
-			// System.err.println(exi.getMessage());
-		}
-		shouldExport = -1;
-	}
-
-	private static ExportedSerializableLog logS = new ExportedSerializableLog();
-
-	public static void exportSerializable() {
-		shouldExportSerializable = 0;
-		try {
-
-			Log.logLock.lock();
-			{
-				ExportedSerializableLog.aLog = SerializableLog.aLog;
-				ExportedSerializableLog.aLog_fill = SerializableLog.aLog_fill;
-				ExportedSerializableLog.bLog = SerializableLog.bLog;
-				ExportedSerializableLog.cLog = SerializableLog.cLog;
-				ExportedSerializableLog.dLog = SerializableLog.dLog;
-				ExportedSerializableLog.iLog = SerializableLog.iLog;
-				ExportedSerializableLog.fLog = SerializableLog.fLog;
-				ExportedSerializableLog.jLog = SerializableLog.jLog;
-				ExportedSerializableLog.zLog = SerializableLog.zLog;
-				ExportedSerializableLog.sLog = SerializableLog.sLog;
-
-				ExportedSerializableLog.bLog_fill = SerializableLog.bLog_fill;
-				ExportedSerializableLog.cLog_fill = SerializableLog.cLog_fill;
-				ExportedSerializableLog.dLog_fill = SerializableLog.dLog_fill;
-				ExportedSerializableLog.iLog_fill = SerializableLog.iLog_fill;
-				ExportedSerializableLog.fLog_fill = SerializableLog.fLog_fill;
-				ExportedSerializableLog.jLog_fill = SerializableLog.jLog_fill;
-				ExportedSerializableLog.zLog_fill = SerializableLog.zLog_fill;
-				ExportedSerializableLog.sLog_fill = SerializableLog.sLog_fill;
-
-				ExportedSerializableLog.aLog_owners = SerializableLog.aLog_owners;
-				ExportedSerializableLog.iLog_owners = SerializableLog.iLog_owners;
-				ExportedSerializableLog.jLog_owners = SerializableLog.jLog_owners;
-				ExportedSerializableLog.fLog_owners = SerializableLog.fLog_owners;
-				ExportedSerializableLog.dLog_owners = SerializableLog.dLog_owners;
-				ExportedSerializableLog.bLog_owners = SerializableLog.bLog_owners;
-				ExportedSerializableLog.zLog_owners = SerializableLog.zLog_owners;
-				ExportedSerializableLog.cLog_owners = SerializableLog.cLog_owners;
-				ExportedSerializableLog.sLog_owners = SerializableLog.sLog_owners;
-
-				SerializableLog.aLog = new Object[Constants.DEFAULT_LOG_SIZE];
-				SerializableLog.iLog = new int[Constants.DEFAULT_LOG_SIZE];
-				SerializableLog.jLog = new long[Constants.DEFAULT_LOG_SIZE];
-				SerializableLog.fLog = new float[Constants.DEFAULT_LOG_SIZE];
-				SerializableLog.dLog = new double[Constants.DEFAULT_LOG_SIZE];
-				SerializableLog.bLog = new byte[Constants.DEFAULT_LOG_SIZE];
-				SerializableLog.zLog = new boolean[Constants.DEFAULT_LOG_SIZE];
-				SerializableLog.cLog = new char[Constants.DEFAULT_LOG_SIZE];
-				SerializableLog.sLog = new short[Constants.DEFAULT_LOG_SIZE];
-				SerializableLog.aLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-				SerializableLog.iLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-				SerializableLog.jLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-				SerializableLog.fLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-				SerializableLog.dLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-				SerializableLog.bLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-				SerializableLog.zLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-				SerializableLog.cLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-				SerializableLog.sLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
-				SerializableLog.logsize = 0;
-				SerializableLog.iLog_fill = 0;
-				SerializableLog.jLog_fill = 0;
-				SerializableLog.fLog_fill = 0;
-				SerializableLog.dLog_fill = 0;
-				SerializableLog.bLog_fill = 0;
-				SerializableLog.zLog_fill = 0;
-				SerializableLog.cLog_fill = 0;
-				SerializableLog.sLog_fill = 0;
-				SerializableLog.aLog_fill = 0;
-			}
-			Log.logLock.unlock();
-			// System.err.println("Serializing serializable");
-			File output = new File("wallace_serializable_" + System.currentTimeMillis() + ".log");
-
-			ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(output));
-			oos.writeObject(logS);
-			oos.flush();
-			oos.close();
-			// System.err.println("Clearing serializable");
-			ExportedLog.clearLog();
-			// System.err.println("Cleared serializable");
-			// System.out.println("Notifying; " + Log.logsize
-			// +";"+SerializableLog.logsize);
-			// synchronized (Log.lock) {
-			// Log.lock.notifyAll();
-			// }
-			// synchronized (Log.lock) {
-			// Log.lock.notifyAll();
-			// }
-		} catch (Exception exi) {
-			// System.err.println(exi.getMessage());
-		}
-		shouldExportSerializable = -1;
-	}
-
-	private static int shouldExport = -1;
-	private static int shouldExportSerializable = -1;
-
-	public static void _exportSerializable() {
-		if (shouldExportSerializable == -1) {
-			// System.out.println("Flagged shouldexport serializble");
-			Thread.yield();
-			shouldExportSerializable = 1;
-			inst.interrupt();
-		}
-	}
-
-	public static void _export() {
-		if (shouldExport == -1) {
-			Thread.yield();
-			shouldExport = 1;
-			inst.interrupt();
-		}
-	}
-
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/WallaceUncaughtExceptionHandler.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/WallaceUncaughtExceptionHandler.java
deleted file mode 100644
index 602df4e..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/WallaceUncaughtExceptionHandler.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package edu.columbia.cs.psl.invivo.record;
-
-import java.io.File;
-import java.io.FileWriter;
-
-import com.thoughtworks.xstream.XStream;
-
-import edu.columbia.cs.psl.invivo.record.xstream.StaticReflectionProvider;
-
-public class WallaceUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{
-
-	@Override
-	public void uncaughtException(Thread t, Throwable e) {
-		try{
-			System.err.println("Wallace caught an exception");
-			e.printStackTrace();
-			System.err.println("Writing log");
-			WallaceExportRunner.export();
-			WallaceExportRunner.exportSerializable();
-			}
-		catch(Exception exi)
-		{
-			exi.printStackTrace();
-		}
-	}
-
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/analysis/MutabilityAnalyzer.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/analysis/MutabilityAnalyzer.java
deleted file mode 100644
index 32d43ed..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/analysis/MutabilityAnalyzer.java
+++ /dev/null
@@ -1,721 +0,0 @@
-package edu.columbia.cs.psl.invivo.record.analysis;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ListIterator;
-
-import org.apache.log4j.Logger;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.tree.AbstractInsnNode;
-import org.objectweb.asm.tree.ClassNode;
-import org.objectweb.asm.tree.FieldInsnNode;
-import org.objectweb.asm.tree.MethodInsnNode;
-import org.objectweb.asm.tree.MethodNode;
-
-import edu.columbia.cs.psl.invivo.record.Instrumenter;
-import edu.columbia.cs.psl.invivo.record.struct.AnnotatedMethod;
-import edu.columbia.cs.psl.invivo.record.struct.Expression;
-import edu.columbia.cs.psl.invivo.record.struct.FieldExpression;
-import edu.columbia.cs.psl.invivo.record.struct.MethodExpression;
-import edu.columbia.cs.psl.invivo.record.struct.SimpleExpression;
-import edu.columbia.cs.psl.invivo.record.visitor.NonDeterministicLoggingClassVisitor;
-import edu.columbia.cs.psl.invivo.record.visitor.NonDeterministicLoggingMethodVisitor;
-
-public class MutabilityAnalyzer implements Opcodes {
-
-	private static Logger logger = Logger.getLogger(MutabilityAnalyzer.class);
-	public MutabilityAnalyzer(HashMap<String, AnnotatedMethod> lookupCache) {
-		this.lookupCache = lookupCache;
-	}
-	private HashMap<String, AnnotatedMethod> lookupCache;
-	private static boolean enabled = false;
-	/**
-	 * Call when done calling analyzeClass
-	 */
-	public void doneSupplyingClasses()
-	{
-		if(!enabled)
-			return;
-		for (String s : lookupCache.keySet()) {
-			AnnotatedMethod method = lookupCache.get(s);
-			if (method.isMutatesFieldsDirectly()) {
-				for (AnnotatedMethod caller : method.functionsThatCallMe)
-				{
-					method.setMutatesFields();
-					addAllRecursively(caller);
-				}
-			}
-		}
-//		for(AnnotatedMethod m : lookupCache.values())
-//		{
-//			if(m.getFullName().eq)
-//			System.out.println(m.getFullName() + (m.isFullyDiscovered() ? (m.isMutatesFields() ? "M" : "-") + (m.isMutatesFieldsDirectly() ? "D" : "-") : "??"));
-//			if(m.getClazz().startsWith("edu/columbia1/cs/psl/invivo") && m.isMutatesFields()){
-//				System.out.println(m);
-//				System.out.println("[");
-////				for(FieldExpression f : m.getPutFieldInsnsPossiblyCalled())
-////				{
-////					System.out.println(f.printParents());
-////				}
-//				System.out.println("]");
-//			}
-//
-//		}
-//		AnnotatedMethod m = Instrumenter.annotatedMethods.get("org/apache/batik/dom/ExtensibleDOMImplementation.registerCustomElementFactory:(Ljava/lang/String;Ljava/lang/String;Lorg/apache/batik/dom/ExtensibleDOMImplementation$ElementFactory;)V");
-//		System.out.println(m.getFullName() + (m.isFullyDiscovered() ? (m.isMutatesFields() ? "M" : "-") + (m.isMutatesFieldsDirectly() ? "D" : "-") : "??"));
-////		for(FieldExpression f : m.getPutFieldInsns())
-////		{
-////			System.out.println(f.getName() + ";"+f.getOwner() + ";"+Textifier.OPCODES[f.getOpcode()]);
-//		}
-	}
-
-	private void addAllRecursively(AnnotatedMethod method) {
-		if (method.isMutatesFields())
-			return;
-		method.setMutatesFields();
-		for (AnnotatedMethod caller : method.functionsThatCallMe)
-			addAllRecursively(caller);
-	}
-
-	/**
-	 *
-	 * Approach:
-	 * Find all methods that can change fields
-	 * Recurse that out to find all methods that might call methods that can change fields
-	 *
-	 * At the start of each methods that might change fields, keep track in a field:
-	 * 		The starting count values for each storage array *recursively* this can be in local variables though
-	 * When a field is changed OR a "not safe" local variable (not safe if it might point to a field):
-	 * 		Store a reference to the field/local variable and a copy of the value
-	 * When a method is invoked that might change fields, track:
-	 * 		A reference to the callee
-	 *
-	 *
-	 * When we need to reset the system to a pre-crash state:
-	 * 		Go through the starting count for each field and compare with each current count. If count changed, reset and note
-	 * 		To find each field, may need to (recursively) descend through the holder points-to fields
-	 *
-	 * Take 2:
-	 * At the start of each method, make a reference copy to a local variable of every backup pt that we will subsequently read but might change
-	 *
-	 * If this method directly changes fields, store a local variable with the original value at time of change
-	 * If this method indirectly changes fields, store a local variable with the original value before the method is called
-	 * @param cr
-	 */
-	public ClassNode analyzeClass(ClassReader cr) {
-		ClassNode cn = new ClassNode();
-		cr.accept(cn, ClassReader.SKIP_DEBUG);
-
-		for (Object o : cn.methods) {
-			MethodNode thisMethodNode = (MethodNode) o;
-			AnnotatedMethod thisMethod = findOrAddMethod(cn.name, thisMethodNode);
-			thisMethod.setFullyDiscovered(true);
-			thisMethod.setAccess(thisMethodNode.access);
-
-			if((thisMethodNode.access & ACC_NATIVE) != 0) // is native
-					NonDeterministicLoggingMethodVisitor.registerNDMethod(cn.name, thisMethodNode.name, thisMethodNode.desc);
-
-			ListIterator<?> i = thisMethodNode.instructions.iterator();
-			boolean isFirstInsn = true;
-			while (i.hasNext()) {
-				AbstractInsnNode n = (AbstractInsnNode) i.next();
-				if (n.getType() == AbstractInsnNode.FIELD_INSN) // Field
-																// Instruction
-				{
-					FieldInsnNode fn = (FieldInsnNode) n;
-					if (n.getOpcode() == Opcodes.PUTSTATIC) {
-						// This instruction is changing a static field. Previous
-						// instruction is the value to set to
-						FieldExpression pi = new FieldExpression(fn.name, fn.owner, fn.desc, n.getOpcode());
-						thisMethod.getPutFieldInsns().add(pi);
-						thisMethod.setMutatesFieldsDirectly();
-					} else if (n.getOpcode() == Opcodes.PUTFIELD) {
-
-						// This instruction is changing a field.
-						// Previous instruction will have the value that we are
-						// setting to
-						FieldExpression pi = new FieldExpression(fn.name, fn.owner, fn.desc, n.getOpcode());
-						pi.setParent(parentInstructionOf(thisMethodNode, pi, thisMethodNode.instructions.iterator(i.previousIndex())));
-						thisMethod.getPutFieldInsns().add(pi);
-						thisMethod.setMutatesFieldsDirectly();
-					}
-				} else if (n.getType() == AbstractInsnNode.METHOD_INSN) // Method
-																		// invocation
-				{
-					MethodInsnNode whatWeCall = (MethodInsnNode) n;
-					AnnotatedMethod otherMethod = findOrAddMethod(whatWeCall.owner, whatWeCall.name, whatWeCall.desc,0);
-					otherMethod.functionsThatCallMe.add(thisMethod);
-					MethodExpression otherMethodExp = new MethodExpression(otherMethod, whatWeCall.getOpcode());
-					otherMethodExp.getParams().addAll(paramsOf(thisMethodNode, otherMethodExp, thisMethodNode.instructions.iterator(i.previousIndex())));
-
-					if(whatWeCall.getOpcode() != Opcodes.INVOKESTATIC)
-						otherMethodExp.setParent(parentInstructionOf(thisMethodNode, otherMethodExp, thisMethodNode.instructions.iterator(i.previousIndex())));
-
-					if(NonDeterministicLoggingMethodVisitor.isND(whatWeCall.owner, whatWeCall.name, whatWeCall.desc) &&
-							whatWeCall.name.equals("<init>") && whatWeCall.owner.equals(cn.superName) && thisMethodNode.name.equals("<init>") && isFirstInsn)
-					{
-						NonDeterministicLoggingMethodVisitor.registerNDMethod(cn.name, thisMethodNode.name, thisMethodNode.desc);
-					}
-
-					thisMethod.functionsThatICall.add(otherMethodExp);
-
-					isFirstInsn = false;
-				} else if (n.getType() == AbstractInsnNode.INVOKE_DYNAMIC_INSN) // Invoke
-																				// dynamic
-				{
-
-				}
-			}
-		}
-		ClassNode ret = new ClassNode();
-		ret.name = cn.name;
-		ret.fields = cn.fields;
-		ret.superName = cn.superName;
-		return ret;
-	}
-
-
-
-	private List<Expression> paramsOf(MethodNode sourceMethod, MethodExpression methodInsnToFindParamsOf, ListIterator<?> i) {
-		ArrayList<Expression> ret = new ArrayList<Expression>();
-		int nParams = methodInsnToFindParamsOf.getNumParamsNeeded();
-		int nToSkip = 0;
-		logger.debug("Finding " + nParams + " params for " + methodInsnToFindParamsOf);
-		while (i.hasPrevious() && nParams > 0) {
-			AbstractInsnNode n = (AbstractInsnNode) i.previous();
-			switch (n.getType()) {
-			case AbstractInsnNode.METHOD_INSN:
-				MethodInsnNode min = (MethodInsnNode) n;
-				MethodExpression mi = new MethodExpression(findOrAddMethod(min.owner, min.name, min.desc, min.getOpcode() == Opcodes.INVOKESTATIC ? Opcodes.ACC_STATIC : 0), min.getOpcode());
-				logger.debug("Encountered " + mi + ", skipping " + mi.getStackElementsToSkip());
-
-				if (nToSkip == 0) {
-					mi.setParent(parentInstructionOf(sourceMethod, mi, sourceMethod.instructions.iterator(i.previousIndex() + 1)));
-					mi.getParams().addAll(paramsOf(sourceMethod, mi, sourceMethod.instructions.iterator(i.previousIndex() + 1)));
-
-					ret.add(mi);
-					nParams--;
-				}
-				nToSkip--;
-				nToSkip += mi.getStackElementsToSkip() + (mi.getOpcode() == Opcodes.INVOKESTATIC ? 0 : 1);
-				logger.debug("NTOS" + nToSkip);
-				if (nToSkip < 0)
-					nToSkip = 0;
-				break;
-			case AbstractInsnNode.INVOKE_DYNAMIC_INSN:
-				// TODO
-				break;
-			case AbstractInsnNode.TYPE_INSN:
-				switch (n.getOpcode()) {
-				case NEW:
-					if (nToSkip == 0) {
-						ret.add(new SimpleExpression(n));
-						nParams--;
-					} else
-						nToSkip--;
-					break;
-				case ANEWARRAY:
-				case CHECKCAST:
-				case INSTANCEOF:
-				}
-				break;
-			case AbstractInsnNode.FIELD_INSN:
-				FieldInsnNode fn = (FieldInsnNode) n;
-				if (n.getOpcode() == Opcodes.GETFIELD) {
-					FieldExpression fi = new FieldExpression(fn.name, fn.owner, fn.desc, n.getOpcode());
-					logger.debug("Encoutnered" + fi);
-					if (nToSkip == 0) {
-						fi.setParent(parentInstructionOf(sourceMethod, fi, sourceMethod.instructions.iterator(i.previousIndex() + 1)));
-						ret.add(fi);
-						nParams--;
-					}
-					nToSkip--;
-					nToSkip += 1;
-				} else if (n.getOpcode() == Opcodes.GETSTATIC) {
-					FieldExpression fi = new FieldExpression(fn.name, fn.owner, fn.desc, n.getOpcode());
-					if (nToSkip == 0) {
-						ret.add(fi);
-						nParams--;
-					}
-					nToSkip--;
-				}
-				break;
-			case AbstractInsnNode.INT_INSN:
-			case AbstractInsnNode.LDC_INSN:
-			case AbstractInsnNode.VAR_INSN:
-				switch (n.getOpcode()) {
-				case Opcodes.ILOAD:
-				case Opcodes.LLOAD:
-				case Opcodes.FLOAD:
-				case Opcodes.DLOAD:
-				case Opcodes.ALOAD:
-				case BIPUSH:
-				case SIPUSH:
-				case Opcodes.LDC:
-					if (nToSkip == 0) {
-						ret.add(new SimpleExpression(n));
-						nParams--;
-					} else
-						nToSkip--;
-					break;
-				case ISTORE:
-				case LSTORE:
-				case FSTORE:
-				case DSTORE:
-				case ASTORE:
-					nToSkip--;
-					nToSkip++;
-					break;
-				case LALOAD:
-				case FALOAD:
-				case AALOAD:
-				case BALOAD:
-				case CALOAD:
-				case SALOAD:
-					nToSkip--;
-					nToSkip += 2;
-					break;
-				case AASTORE:
-				case IASTORE:
-				case FASTORE:
-				case DASTORE:
-				case BASTORE:
-				case CASTORE:
-				case SASTORE:
-					nToSkip += 3;
-					break;
-				case NEWARRAY:
-					nToSkip--;
-					nToSkip++;
-				default:
-					logger.debug("Unknown opcode " + n.getOpcode());
-					break;
-				}
-				break;
-			case AbstractInsnNode.INSN:
-				switch (n.getOpcode()) {
-				// case ATHROW: // 1 before n/a after
-				// popValue();
-				// onMethodExit(opcode);
-				// break;
-				//
-				// case LRETURN: // 2 before n/a after
-				// case DRETURN: // 2 before n/a after
-				// popValue();
-				// popValue();
-				// onMethodExit(opcode);
-				// break;
-
-				case NOP:
-				case LNEG:
-				case DNEG:
-				case FNEG:
-				case INEG:
-				case L2D:
-				case D2L:
-				case F2I:
-				case I2B:
-				case I2C:
-				case I2S:
-				case I2F:
-				case F2L: // 1 before 2 after
-				case F2D:
-				case I2L:
-				case I2D:
-
-				case L2I: // 2 before 1 after
-				case L2F: // 2 before 1 after
-				case D2I: // 2 before 1 after
-				case D2F: // 2 before 1 after
-				case ARRAYLENGTH:
-				case SWAP:
-					nToSkip--;
-					nToSkip++;
-					break;
-
-				case IADD:
-				case FADD:
-				case ISUB:
-				case LSHL: // 3 before 2 after
-				case LSHR: // 3 before 2 after
-				case LUSHR: // 3 before 2 after
-				case LSUB:
-				case LMUL:
-				case LDIV:
-				case LREM:
-				case LADD:
-				case LAND:
-				case LOR:
-				case LXOR:
-				case DADD:
-				case DMUL:
-				case DSUB:
-				case DDIV:
-				case DREM:
-
-				case FSUB:
-				case FMUL:
-				case FDIV:
-				case FREM:
-				case FCMPL: // 2 before 1 after
-				case FCMPG: // 2 before 1 after
-				case IMUL:
-				case IDIV:
-				case IREM:
-				case ISHL:
-				case ISHR:
-				case IUSHR:
-				case IAND:
-				case IOR:
-				case IXOR:
-
-				case IALOAD: // remove 2 add 1
-				case FALOAD: // remove 2 add 1
-				case AALOAD: // remove 2 add 1
-				case BALOAD: // remove 2 add 1
-				case CALOAD: // remove 2 add 1
-				case SALOAD: // remove 2 add 1
-				case LALOAD: // remove 2 add 2
-				case DALOAD: // remove 2 add 2
-
-				case LCMP: // 4 before 1 after
-				case DCMPL:
-				case DCMPG:
-					nToSkip--;
-					nToSkip += 2;
-					break;
-
-				case ACONST_NULL:
-				case ICONST_M1:
-				case ICONST_0:
-				case ICONST_1:
-				case ICONST_2:
-				case ICONST_3:
-				case ICONST_4:
-				case ICONST_5:
-				case FCONST_0:
-				case FCONST_1:
-				case FCONST_2:
-				case LCONST_0:
-				case LCONST_1:
-				case DCONST_0:
-				case DCONST_1:
-
-				case DUP:
-				case DUP_X1:
-				case DUP_X2:
-
-				case DUP2: // is this wrong to assume that dup2 is only used on
-							// longs and not 2 shorts?
-				case DUP2_X1:
-				case DUP2_X2:
-					// case POP:
-					// case MONITORENTER:
-					// case MONITOREXIT:
-					// case POP2:
-					if (nToSkip == 0) {
-						ret.add(new SimpleExpression(n));
-						nParams--;
-					} else
-						nToSkip--;
-					break;
-
-				case LASTORE:
-				case DASTORE:
-				case IASTORE:
-				case FASTORE:
-				case AASTORE:
-				case BASTORE:
-				case CASTORE:
-				case SASTORE:
-					nToSkip--;
-					nToSkip += 3;
-					break;
-				}
-				break;
-			}
-		}
-		return ret;
-	}
-
-	private Expression parentInstructionOf(MethodNode mn, Expression insnToFindParentOf, ListIterator<?> i) {
-		if (insnToFindParentOf.getType() == Expression.METHOD_TYPE && ((MethodExpression) insnToFindParentOf).getMethod().getName().equals("<init>"))
-			return null;
-		int nToSkip = insnToFindParentOf.getStackElementsToSkip();
-		logger.debug("Examining " + insnToFindParentOf.toString() + " for parent, skipping " + nToSkip);
-		while (i.hasPrevious()) {
-			AbstractInsnNode n = (AbstractInsnNode) i.previous();
-			switch (n.getType()) {
-			case AbstractInsnNode.METHOD_INSN:
-				MethodInsnNode min = (MethodInsnNode) n;
-				MethodExpression mi = new MethodExpression(findOrAddMethod(min.owner, min.name, min.desc, min.getOpcode() == Opcodes.INVOKESTATIC ? Opcodes.ACC_STATIC : 0), min.getOpcode());
-				logger.debug("Encountered " + mi + ", skipping " + mi.getStackElementsToSkip());
-
-				if (nToSkip == 0) {
-					mi.setParent(parentInstructionOf(mn, mi, mn.instructions.iterator(i.previousIndex() + 1)));
-					mi.getParams().addAll(paramsOf(mn, mi, mn.instructions.iterator(i.previousIndex() + 1)));
-					return mi;
-				}
-				nToSkip--;
-				nToSkip += mi.getStackElementsToSkip() + (mi.getOpcode() == Opcodes.INVOKESTATIC ? 0 : 1);
-				logger.debug("NTos" + nToSkip);
-				break;
-			case AbstractInsnNode.INVOKE_DYNAMIC_INSN:
-				// TODO
-				break;
-			case AbstractInsnNode.TYPE_INSN:
-				switch (n.getOpcode()) {
-				case NEW:
-					if (nToSkip == 0) {
-						return new SimpleExpression(n);
-					} else
-						nToSkip--;
-					break;
-				case ANEWARRAY:
-				case CHECKCAST:
-				case INSTANCEOF:
-				}
-				break;
-			case AbstractInsnNode.FIELD_INSN:
-				FieldInsnNode fn = (FieldInsnNode) n;
-				if (n.getOpcode() == Opcodes.GETFIELD) {
-					FieldExpression fi = new FieldExpression(fn.name, fn.owner, fn.desc, n.getOpcode());
-					logger.debug("Encoutnered field: " + fi);
-					if (nToSkip == 0) {
-						fi.setParent(parentInstructionOf(mn, fi, mn.instructions.iterator(i.previousIndex() + 1)));
-						return fi;
-					}
-					nToSkip--;
-					nToSkip += 1;
-					logger.debug("Ntos" + nToSkip);
-				} else if (n.getOpcode() == Opcodes.GETSTATIC) {
-					FieldExpression fi = new FieldExpression(fn.name, fn.owner, fn.desc, n.getOpcode());
-					if (nToSkip == 0) {
-						fi.setParent(parentInstructionOf(mn, fi, mn.instructions.iterator(i.previousIndex() + 1)));
-						return fi;
-					}
-					nToSkip--;
-					// nToSkip += 1;
-				}
-				break;
-			case AbstractInsnNode.INT_INSN:
-			case AbstractInsnNode.LDC_INSN:
-			case AbstractInsnNode.VAR_INSN:
-				switch (n.getOpcode()) {
-				case Opcodes.ILOAD:
-				case Opcodes.LLOAD:
-				case Opcodes.FLOAD:
-				case Opcodes.DLOAD:
-				case Opcodes.ALOAD:
-				case BIPUSH:
-				case SIPUSH:
-				case Opcodes.LDC:
-					if (nToSkip == 0) {
-						return new SimpleExpression(n);
-					}
-					nToSkip--;
-					break;
-				case ISTORE:
-				case LSTORE:
-				case FSTORE:
-				case DSTORE:
-				case ASTORE:
-					nToSkip--;
-					nToSkip++;
-					break;
-				case LALOAD:
-				case FALOAD:
-				case AALOAD:
-				case BALOAD:
-				case CALOAD:
-				case SALOAD:
-					nToSkip--;
-					nToSkip += 2;
-					break;
-				case AASTORE:
-				case IASTORE:
-				case FASTORE:
-				case DASTORE:
-				case BASTORE:
-				case CASTORE:
-				case SASTORE:
-					nToSkip += 3;
-					break;
-				case NEWARRAY:
-					nToSkip--;
-					nToSkip++;
-				default:
-					logger.debug("Unknown opcode " + n.getOpcode());
-					break;
-				}
-				break;
-			case AbstractInsnNode.INSN:
-				switch (n.getOpcode()) {
-				// case ATHROW: // 1 before n/a after
-				// popValue();
-				// onMethodExit(opcode);
-				// break;
-				//
-				// case LRETURN: // 2 before n/a after
-				// case DRETURN: // 2 before n/a after
-				// popValue();
-				// popValue();
-				// onMethodExit(opcode);
-				// break;
-
-				case NOP:
-				case LNEG:
-				case DNEG:
-				case FNEG:
-				case INEG:
-				case L2D:
-				case D2L:
-				case F2I:
-				case I2B:
-				case I2C:
-				case I2S:
-				case I2F:
-				case F2L: // 1 before 2 after
-				case F2D:
-				case I2L:
-				case I2D:
-
-				case L2I: // 2 before 1 after
-				case L2F: // 2 before 1 after
-				case D2I: // 2 before 1 after
-				case D2F: // 2 before 1 after
-				case ARRAYLENGTH:
-				case SWAP:
-					nToSkip--;
-					nToSkip++;
-					break;
-
-				case IADD:
-				case FADD:
-				case ISUB:
-				case LSHL: // 3 before 2 after
-				case LSHR: // 3 before 2 after
-				case LUSHR: // 3 before 2 after
-				case LSUB:
-				case LMUL:
-				case LDIV:
-				case LREM:
-				case LADD:
-				case LAND:
-				case LOR:
-				case LXOR:
-				case DADD:
-				case DMUL:
-				case DSUB:
-				case DDIV:
-				case DREM:
-
-				case FSUB:
-				case FMUL:
-				case FDIV:
-				case FREM:
-				case FCMPL: // 2 before 1 after
-				case FCMPG: // 2 before 1 after
-				case IMUL:
-				case IDIV:
-				case IREM:
-				case ISHL:
-				case ISHR:
-				case IUSHR:
-				case IAND:
-				case IOR:
-				case IXOR:
-
-				case IALOAD: // remove 2 add 1
-				case FALOAD: // remove 2 add 1
-				case AALOAD: // remove 2 add 1
-				case BALOAD: // remove 2 add 1
-				case CALOAD: // remove 2 add 1
-				case SALOAD: // remove 2 add 1
-				case LALOAD: // remove 2 add 2
-				case DALOAD: // remove 2 add 2
-
-				case LCMP: // 4 before 1 after
-				case DCMPL:
-				case DCMPG:
-					nToSkip--;
-					nToSkip += 2;
-					break;
-
-				case ACONST_NULL:
-				case ICONST_M1:
-				case ICONST_0:
-				case ICONST_1:
-				case ICONST_2:
-				case ICONST_3:
-				case ICONST_4:
-				case ICONST_5:
-				case FCONST_0:
-				case FCONST_1:
-				case FCONST_2:
-				case LCONST_0:
-				case LCONST_1:
-				case DCONST_0:
-				case DCONST_1:
-
-				case DUP:
-				case DUP_X1:
-				case DUP_X2:
-
-				case DUP2: // is this wrong to assume that dup2 is only used on
-							// longs and not 2 shorts?
-				case DUP2_X1:
-				case DUP2_X2:
-					// case POP:
-					// case MONITORENTER:
-					// case MONITOREXIT:
-					// case POP2:
-					if (nToSkip == 0) {
-						return new SimpleExpression(n);
-					}
-					nToSkip--;
-					break;
-
-				case LASTORE:
-				case DASTORE:
-				case IASTORE:
-				case FASTORE:
-				case AASTORE:
-				case BASTORE:
-				case CASTORE:
-				case SASTORE:
-					nToSkip--;
-					nToSkip += 3;
-					break;
-				}
-				break;
-			}
-
-		}
-		return null;
-	}
-
-	private AnnotatedMethod findOrAddMethod(String owner, String name, String desc, int access) {
-		String lookupKey = owner + "." + name + ":" + desc;
-		if (!lookupCache.containsKey(lookupKey))
-			lookupCache.put(lookupKey, new AnnotatedMethod(name, desc, owner, access));
-		return lookupCache.get(lookupKey);
-	}
-
-	private AnnotatedMethod findOrAddMethod(String owner, MethodNode mn) {
-		return findOrAddMethod(owner, mn.name, mn.desc, mn.access);
-	}
-
-	public static void main(String[] args) {
-		try {
-			ClassReader cr = new ClassReader("edu.columbia.cs.psl.invivo.sample.SimpleClass");
-			MutabilityAnalyzer ma = new MutabilityAnalyzer(new HashMap<String, AnnotatedMethod>());
-			ma.analyzeClass(cr);
-			ma.doneSupplyingClasses();
-		} catch (Exception ex) {
-			ex.printStackTrace();
-		}
-	}
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/AnnotatedMethod.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/AnnotatedMethod.java
deleted file mode 100644
index a40208a..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/AnnotatedMethod.java
+++ /dev/null
@@ -1,156 +0,0 @@
-package edu.columbia.cs.psl.invivo.record.struct;
-
-import java.util.LinkedList;
-
-import org.objectweb.asm.commons.Method;
-
-public class AnnotatedMethod {
-
-	/**
-	 * Encoded access flags for this method. private int access
-	 *
-	 * @see Method
-	 */
-	private int access;
-
-	/**
-	 * Fully qualified class name of the class owning this method. private
-	 * String clazz
-	 */
-	private String clazz;
-
-	public LinkedList<AnnotatedMethod> functionsThatCallMe = new LinkedList<AnnotatedMethod>();
-
-	public LinkedList<MethodExpression> functionsThatICall = new LinkedList<MethodExpression>();
-
-	private LinkedList<FieldExpression> putFieldInsns = new LinkedList<FieldExpression>();
-
-	/**
-	 * ASM method at the core of this MethodInstance object. private Method
-	 * method
-	 *
-	 * @see Method
-	 */
-	private Method method;
-
-	private boolean mutatesFieldsDirectly;
-	private boolean mutatesFields;
-	private boolean isFullyDiscovered;
-
-	public String getName()
-	{
-		return this.method.getName();
-	}
-
-	public String getDescriptor()
-	{
-		return this.method.getDescriptor();
-	}
-	public AnnotatedMethod(String fullName) {
-
-		String[] pieces = fullName.split("\\.|:");
-		this.clazz = pieces[0];
-		this.method = new Method(pieces[1], pieces[2]);
-	}
-
-	/**
-	 * Constructor for MethodInstance - accepts method name, method description,
-	 * class name, and access flag.
-	 *
-	 * @param name
-	 *            String name of method
-	 * @param desc
-	 *            String method descriptor
-	 * @param clazz
-	 *            String fully qualified class name
-	 * @param access
-	 *            int access flags in decimal
-	 */
-	public AnnotatedMethod(String name, String desc, String clazz, int access) {
-		this.method = new Method(name, desc);
-		this.clazz = clazz;
-		this.access = access;
-	}
-
-	/**
-	 * (Override) This function declares two MethodInstances A, B "equal" if and
-	 * only if: ((A.getMethod().equals(B.getMethod)) &&
-	 * (A.getClazz().equals(B.getClazz())) == true
-	 *
-	 * @see Object#equals(Object)
-	 * @see AnnotatedMethod#hashCode()
-	 */
-	@Override
-	public boolean equals(Object obj) {
-		if (obj.getClass().equals(this.getClass())) {
-			AnnotatedMethod other = (AnnotatedMethod) obj;
-			if ((other.getClazz().equals(this.getClazz()))
-					&& (other.getMethod().getName().equals(this.getMethod().getName()) && other.getMethod().getDescriptor().equals(this.getMethod().getDescriptor())))
-				return true;
-		}
-		return false;
-	}
-
-	public int getAccess() {
-		return access;
-	}
-
-	/**
-	 * Get the owner class name.
-	 *
-	 * @return String
-	 */
-	public String getClazz() {
-		return clazz;
-	}
-
-	public String getFullName() {
-		return this.clazz + "." + this.method.getName() + ":" + this.method.getDescriptor();
-	}
-
-	/**
-	 * Get the Method underlying this MethodInstance.
-	 *
-	 * @return Method
-	 */
-	public Method getMethod() {
-		return method;
-	}
-
-	@Override
-	public int hashCode() {
-		return this.getClazz().hashCode() * this.getMethod().getName().hashCode() * this.getMethod().getDescriptor().hashCode();
-	}
-
-	@Override
-	public String toString() {
-		return "MethodInstance [method=" + method + ", class=" + clazz + "]";
-	}
-
-	public LinkedList<FieldExpression> getPutFieldInsns() {
-		return putFieldInsns;
-	}
-	public boolean isMutatesFields() {
-		return mutatesFields;
-	}
-	public boolean isMutatesFieldsDirectly() {
-		return mutatesFieldsDirectly;
-	}
-	public void setMutatesFieldsDirectly() {
-		this.mutatesFieldsDirectly = true;
-	}
-	public void setMutatesFields() {
-		this.mutatesFields = true;
-	}
-
-	public void setAccess(int access) {
-		this.access = access;
-	}
-	public boolean isFullyDiscovered() {
-		return isFullyDiscovered;
-	}
-	public void setFullyDiscovered(boolean isFullyDiscovered) {
-		this.isFullyDiscovered = isFullyDiscovered;
-	}
-
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/Expression.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/Expression.java
deleted file mode 100644
index c44b654..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/Expression.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package edu.columbia.cs.psl.invivo.record.struct;
-
-
-public abstract class Expression {
-	public abstract int getType();
-	public static int FIELD_TYPE = 1;
-	public static int METHOD_TYPE = 2;
-	public static int CONSTANT_TYPE = 3;
-	public Expression getParent()
-	{
-		return parent;
-	}
-	public void setParent(Expression ir){
-		this.parent = ir;
-	}
-	public Expression getRootParent()
-	{
-		if(getParent() == null)
-			return this;
-		else
-			return getParent().getRootParent();
-	}
-	private Expression parent;
-	public abstract int getStackElementsToSkip();
-	public abstract int getOpcode();
-
-	public String printParents() {
-		String r = "";
-		if (getParent() != null)
-			r += getParent().printParents() + ".";
-		r += toString();
-		return r;
-	}
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/FieldExpression.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/FieldExpression.java
deleted file mode 100644
index 121cf0e..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/FieldExpression.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package edu.columbia.cs.psl.invivo.record.struct;
-
-import org.objectweb.asm.Opcodes;
-
-public class FieldExpression extends Expression {
-	private String name;
-	private String owner;
-	private String desc;
-	private int opcode;
-
-	public FieldExpression(String name, String owner, String desc, int opcode)
-	{
-		this.name = name;
-		this.owner = owner;
-		this.desc = desc;
-		this.opcode = opcode;
-	}
-	@Override
-	public int getOpcode() {
-		return opcode;
-	}
-	public String getName() {
-		return name;
-	}
-	public String getOwner() {
-		return owner;
-	}
-	public String getDesc() {
-		return desc;
-	}
-
-	@Override
-	public int getType() {
-		return FIELD_TYPE;
-	}
-
-	@Override
-	public int getStackElementsToSkip() {
-		if(opcode == Opcodes.GETFIELD || opcode == Opcodes.GETSTATIC)
-			return 0;
-		return 1;
-	}
-
-	@Override
-	public String toString() {
-//		return "FieldInvocation [name=" + name + ", owner=" + owner + ", desc=" + desc + "]";
-		return name;
-	}
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/MethodExpression.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/MethodExpression.java
deleted file mode 100644
index ccf4168..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/MethodExpression.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package edu.columbia.cs.psl.invivo.record.struct;
-
-import java.util.Stack;
-
-public class MethodExpression extends Expression {
-	@Override
-	public String toString() {
-		String r ="";
-		if(method.getMethod().getName().equals("<init>"))
-			r+="new "+method.getClazz()+"(";
-		else
-			r += method.getMethod().getName()+"(";
-
-		for(int j = 0; j<params.size() - (method.getMethod().getName().equals("<init>") ? 2: 0); j++)
-		{
-			Expression i = params.get(j);
-			Expression parent = i.getParent();
-			String paramParent = "";
-			while(parent != null)
-			{
-				paramParent = parent.toString()+"."+paramParent;
-				parent = parent.getParent();
-			}
-			r+= paramParent;
-			r += i.toString();
-			if(j != params.size() - 1 - (method.getMethod().getName().equals("<init>") ? 2 : 0))
-				r += ",";
-		}
-		r+=")";
-		return r;
-
-	}
-	private Stack<Expression> params = new Stack<Expression>();
-
-	private AnnotatedMethod method;
-	private int opcode;
-	public MethodExpression(AnnotatedMethod method, int opcode)
-	{
-
-		this.method = method;
-		this.opcode = opcode;
-	}
-	@Override
-	public int getOpcode() {
-		return opcode;
-	}
-	@Override
-	public int getType() {
-		return METHOD_TYPE;
-	}
-	public Stack<Expression> getParams() {
-		return params;
-	}
-
-	public AnnotatedMethod getMethod() {
-		return method;
-	}
-	public int getNumParamsNeeded()
-	{
-		return (method.getMethod().getName().equals("<init>") ? 2 : 0) + method.getMethod().getArgumentTypes().length;
-	}
-
-	public boolean hasAllParameters() {
-		// TODO Auto-generated method stub
-		return getNumParamsNeeded() == params.size();
-	}
-	@Override
-	public int getStackElementsToSkip() {
-		return (method.getMethod().getName().equals("<init>") ? 1 : 0) + method.getMethod().getArgumentTypes().length;
-	}
-}
\ No newline at end of file
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/SimpleExpression.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/SimpleExpression.java
deleted file mode 100644
index e31890c..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/struct/SimpleExpression.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package edu.columbia.cs.psl.invivo.record.struct;
-
-import org.objectweb.asm.tree.AbstractInsnNode;
-import org.objectweb.asm.tree.LdcInsnNode;
-import org.objectweb.asm.tree.TypeInsnNode;
-import org.objectweb.asm.tree.VarInsnNode;
-import org.objectweb.asm.util.Printer;
-
-public class SimpleExpression extends Expression {
-	private AbstractInsnNode insn;
-
-	@Override
-	public int getOpcode() {
-		return insn.getOpcode();
-	}
-
-	public SimpleExpression(AbstractInsnNode insn) {
-		this.insn = insn;
-	}
-
-	public AbstractInsnNode getInsn() {
-		return insn;
-	}
-
-	@Override
-	public Expression getParent() {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public void setParent(Expression ir) {
-
-	}
-
-	@Override
-	public int getType() {
-		return CONSTANT_TYPE;
-	}
-
-	@Override
-	public int getStackElementsToSkip() {
-		return 0;
-	}
-
-	public String getDesc() {
-		switch (insn.getType()) {
-		case AbstractInsnNode.TYPE_INSN:
-			return ((TypeInsnNode) insn).desc;
-		case AbstractInsnNode.VAR_INSN:
-			return "" + ((VarInsnNode) insn).var;
-		case AbstractInsnNode.LDC_INSN:
-			return ((LdcInsnNode) insn).cst.toString();
-		default:
-			return "";
-		}
-
-	}
-
-	@Override
-	public String toString() {
-		return "[" + Printer.OPCODES[getOpcode()] + " " + getDesc() + "]";
-	}
-
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/CloningAdviceAdapter.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/CloningAdviceAdapter.java
deleted file mode 100644
index b255389..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/CloningAdviceAdapter.java
+++ /dev/null
@@ -1,377 +0,0 @@
-package edu.columbia.cs.psl.invivo.record.visitor;
-
-import java.util.HashSet;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReadWriteLock;
-
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.commons.AdviceAdapter;
-import org.objectweb.asm.commons.GeneratorAdapter;
-import org.objectweb.asm.commons.LocalVariablesSorter;
-import org.objectweb.asm.commons.Method;
-import org.objectweb.asm.tree.FieldNode;
-
-import edu.columbia.cs.psl.invivo.record.CloningUtils;
-import edu.columbia.cs.psl.invivo.record.Constants;
-import edu.columbia.cs.psl.invivo.record.Instrumenter;
-import edu.columbia.cs.psl.invivo.record.Log;
-import edu.columbia.cs.psl.invivo.record.SerializableLog;
-import edu.columbia.cs.psl.invivo.record.WallaceExportRunner;
-
-public class CloningAdviceAdapter extends GeneratorAdapter implements Opcodes {
-
-	private static final HashSet<String> ignoredClasses = new HashSet<String>();
-	private static boolean flexibleLog = false;
-
-	private static final HashSet<String> immutableClasses = new HashSet<String>();
-	static {
-		immutableClasses.add("Ljava/lang/Integer;");
-		immutableClasses.add("Ljava/lang/Long;");
-		immutableClasses.add("Ljava/lang/Short;");
-		immutableClasses.add("Ljava/lang/Float;");
-		immutableClasses.add("Ljava/lang/String;");
-		immutableClasses.add("Ljava/lang/Char;");
-		immutableClasses.add("Ljava/lang/Byte;");
-		immutableClasses.add("Ljava/lang/Integer;");
-		immutableClasses.add("Ljava/lang/Long;");
-		immutableClasses.add("Ljava/lang/Short;");
-		immutableClasses.add("Ljava/lang/Float;");
-		immutableClasses.add("Ljava/lang/String;");
-		immutableClasses.add("Ljava/lang/Char;");
-		immutableClasses.add("Ljava/lang/Byte;");
-		immutableClasses.add("Ljava/sql/ResultSet;");
-		immutableClasses.add("Ljava/lang/Class;");
-		immutableClasses.add("Z");
-		immutableClasses.add("B");
-		immutableClasses.add("C");
-		immutableClasses.add("S");
-		immutableClasses.add("I");
-		immutableClasses.add("J");
-		immutableClasses.add("F");
-		immutableClasses.add("L");
-
-	}
-	private String className;
-
-	private LocalVariablesSorter lvsorter;
-
-	public CloningAdviceAdapter(int api, MethodVisitor mv, int access, String name, String desc, String classname, LocalVariablesSorter lvsorter) {
-		super(api, mv, access, name, desc);
-		this.className = classname;
-		this.lvsorter = lvsorter;
-	}
-
-	/**
-	 * Precondition: Current element at the top of the stack is the element we
-	 * need cloned Post condition: Current element at the top of the stack is
-	 * the cloned element (and non-cloned is removed)
-	 */
-
-	protected void cloneValAtTopOfStack(String typeOfField) {
-		_generateClone(typeOfField, Constants.OUTER_COPY_METHOD_NAME, null, false);
-	}
-
-	protected void cloneValAtTopOfStack(String typeOfField, String debug, boolean secondElHasArrayLen) {
-		_generateClone(typeOfField, Constants.OUTER_COPY_METHOD_NAME, debug, secondElHasArrayLen);
-	}
-
-	protected void generateCloneInner(String typeOfField) {
-		_generateClone(typeOfField, Constants.INNER_COPY_METHOD_NAME, null, false);
-	}
-
-	public void println(String toPrint) {
-		visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
-		visitLdcInsn(toPrint + " : ");
-		super.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print", "(Ljava/lang/String;)V");
-
-		visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
-		super.visitMethodInsn(INVOKESTATIC, "java/lang/Thread", "currentThread", "()Ljava/lang/Thread;");
-		super.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Thread", "getName", "()Ljava/lang/String;");
-		super.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
-	}
-
-	private void _generateClone(String typeOfField, String copyMethodToCall, String debug, boolean secondElHasArrayLen) {
-		Type fieldType = Type.getType(typeOfField);
-
-		if (
-		// fieldType.getSort() == Type.ARRAY &&
-		// fieldType.getElementType().getSort()
-		// ||
-		fieldType.getSort() == Type.VOID || (fieldType.getSort() != Type.ARRAY && (fieldType.getSort() != Type.OBJECT || immutableClasses.contains(typeOfField)))) {
-			// println("reference> " + debug);
-			// println(debug);
-			// println("Doing nothing");
-			return;
-		}
-		if (fieldType.getSort() == Type.ARRAY) {
-			if (fieldType.getElementType().getSort() != Type.OBJECT || immutableClasses.contains(fieldType.getElementType().getDescriptor())) {
-				// println("array> " + debug);
-
-				// Just need to duplicate the array
-				dup();
-				Label nullContinue = new Label();
-				ifNull(nullContinue);
-				if (secondElHasArrayLen) {
-					swap();
-					// pop();
-					// swap();
-					// dup();
-					// visitFieldInsn(GETSTATIC, "java/lang/System", "out",
-					// "Ljava/io/PrintStream;");
-					// swap();
-					// super.visitMethodInsn(INVOKEVIRTUAL,
-					// "java/io/PrintStream", "println", "(I)V");
-				} else {
-					dup();
-					visitInsn(ARRAYLENGTH);
-				}
-				dup();
-				newArray(Type.getType(fieldType.getDescriptor().substring(1)));
-				dupX2();
-				swap();
-				push(0);
-				dupX2();
-				swap();
-				super.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V");
-				Label noNeedToPop = new Label();
-				if (secondElHasArrayLen) {
-					visitJumpInsn(GOTO, noNeedToPop);
-					visitLabel(nullContinue);
-					swap();
-					pop();
-				} else {
-					visitLabel(nullContinue);
-				}
-
-				visitLabel(noNeedToPop);
-
-			} else {
-				// println("heavy> " + debug);
-				// Just use the reflective cloner
-				visitLdcInsn(debug);
-				invokeStatic(Type.getType(CloningUtils.class), Method.getMethod("Object clone(Object, String)"));
-				checkCast(fieldType);
-			}
-		} else if (fieldType.getClassName().contains("InputStream") || fieldType.getClassName().contains("OutputStream") || fieldType.getClassName().contains("Socket")) {
-			// Do nothing
-		} else {
-			// println("heavy> " + debug);
-			visitLdcInsn(debug);
-			invokeStatic(Type.getType(CloningUtils.class), Method.getMethod("Object clone(Object, String)"));
-			checkCast(fieldType);
-
-		}
-	}
-
-	// private static Object[] ar;
-	// private void magic()
-	// {
-	// new WallaceExportRunner().
-	// }
-	protected void logValueAtTopOfStackToArray(String logFieldOwner, String logFieldName, String logFieldTypeDesc, Type elementType, boolean isStaticLoggingField, String debug,
-			boolean secondElHasArrayLen) {
-		int getOpcode = (isStaticLoggingField ? Opcodes.GETSTATIC : Opcodes.GETFIELD);
-		int putOpcode = (isStaticLoggingField ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD);
-
-		//Lock
-		super.visitFieldInsn(GETSTATIC, Type.getInternalName(Log.class), "logLock", Type.getDescriptor(Lock.class));
-		super.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Lock.class), "lock", "()V");
-
-		// Grow the array if necessary
-
-		super.visitFieldInsn(getOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());
-		super.visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
-		super.arrayLength();
-		Label labelForNoNeedToGrow = new Label();
-		super.ifCmp(Type.INT_TYPE, Opcodes.IFNE, labelForNoNeedToGrow);
-		// In this case, it's necessary to grow it
-		// Create the new array and initialize its size
-
-		int newArray = newLocal(Type.getType(logFieldTypeDesc));
-		visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
-		arrayLength();
-		visitInsn(Opcodes.I2D);
-		visitLdcInsn(Constants.LOG_GROWTH_RATE);
-		visitInsn(Opcodes.DMUL);
-		visitInsn(Opcodes.D2I);
-
-		newArray(Type.getType(logFieldTypeDesc.substring(1))); // Bug in
-																// ASM
-																// prevents
-																// us
-																// from
-																// doing
-																// type.getElementType
-		storeLocal(newArray, Type.getType(logFieldTypeDesc));
-		visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
-		visitInsn(Opcodes.ICONST_0);
-		loadLocal(newArray);
-		visitInsn(Opcodes.ICONST_0);
-		visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
-		arrayLength();
-		visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V");
-
-		// array = newarray
-
-		loadLocal(newArray);
-		visitFieldInsn(putOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
-
-		int newArray2 = newLocal(Type.getType("[Ljava/lang/String;"));
-		visitFieldInsn(getOpcode, logFieldOwner, logFieldName+"_owners", "[Ljava/lang/String;");
-		arrayLength();
-		visitInsn(Opcodes.I2D);
-		visitLdcInsn(Constants.LOG_GROWTH_RATE);
-		visitInsn(Opcodes.DMUL);
-		visitInsn(Opcodes.D2I);
-
-		newArray(Type.getType("Ljava/lang/String;"));
-
-		storeLocal(newArray2, Type.getType("[Ljava/lang/String;"));
-		visitFieldInsn(getOpcode, logFieldOwner, logFieldName+"_owners", "[Ljava/lang/String;");
-		visitInsn(Opcodes.ICONST_0);
-		loadLocal(newArray2);
-		visitInsn(Opcodes.ICONST_0);
-		visitFieldInsn(getOpcode, logFieldOwner, logFieldName+"_owners", "[Ljava/lang/String;");
-		arrayLength();
-		visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V");
-
-		// array = newarray
-
-		loadLocal(newArray2);
-		visitFieldInsn(putOpcode, logFieldOwner, logFieldName+"_owners", "[Ljava/lang/String;");
-
-		visitLabel(labelForNoNeedToGrow);
-		// Load this into the end piece of the array
-		if (elementType.getSize() == 1) {
-			if (secondElHasArrayLen) {
-				/*
-				 * size buf
-				 */
-				dupX1();
-				/*
-				 * buf size buf
-				 */
-				visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
-				dupX2();
-				pop();
-				/*
-				 * buf logfield size buf
-				 */
-				visitFieldInsn(getOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());
-				dupX2();
-				pop();
-				/*
-				 * buf logfield logsize size buf
-				 */
-			} else {
-				dup();
-				visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
-				swap();
-				visitFieldInsn(getOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());
-				swap();
-			}
-		} else if (elementType.getSize() == 2) {
-			dup2();
-			if (!isStaticLoggingField)
-				super.loadThis();
-			super.visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
-			dupX2();
-			pop();
-			if (!isStaticLoggingField)
-				super.loadThis();
-			super.visitFieldInsn(getOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());
-			dupX2();
-			pop();
-		}
-		cloneValAtTopOfStack(elementType.getDescriptor(), debug, secondElHasArrayLen);
-
-		arrayStore(elementType);
-
-		visitFieldInsn(getOpcode, logFieldOwner, logFieldName+"_owners", "[Ljava/lang/String;");
-		visitFieldInsn(getOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());
-
-		visitMethodInsn(INVOKESTATIC, "java/lang/Thread", "currentThread", "()Ljava/lang/Thread;");
-		visitMethodInsn(INVOKEVIRTUAL, "java/lang/Thread", "getName", "()Ljava/lang/String;");
-		arrayStore(Type.getType(String.class));
-		visitFieldInsn(getOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());
-
-		super.visitInsn(Opcodes.ICONST_1);
-		super.visitInsn(Opcodes.IADD);
-		super.visitFieldInsn(putOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());
-		// println("Incremented fill for " + logFieldOwner+"."+logFieldName);
-		// Release the export lock
-		// super.visitFieldInsn(GETSTATIC,
-		// Type.getInternalName(CloningUtils.class), "exportLock",
-		// Type.getDescriptor(ReadWriteLock.class));
-		// super.visitMethodInsn(INVOKEINTERFACE,
-		// Type.getInternalName(ReadWriteLock.class), "readLock",
-		// "()Ljava/util/concurrent/locks/Lock;");
-		// super.visitMethodInsn(INVOKEINTERFACE,
-		// Type.getInternalName(Lock.class), "unlock", "()V");
-
-		// if (threadSafe) {
-		// Unlock
-		// super.visitVarInsn(ALOAD, monitorIndx);
-		// super.monitorExit();
-		// visitLabel(monitorEndLabel);
-		Label endLbl = new Label();
-
-//		if (elementType.getSort() == Type.ARRAY) {
-//			super.visitInsn(DUP);
-//			super.visitInsn(ARRAYLENGTH);
-//		} else
-			super.visitInsn(ICONST_1);
-		// super.visitVarInsn(ALOAD, monitorIndx);
-		// super.monitorEnter();
-		super.visitFieldInsn(getOpcode, logFieldOwner, "logsize", Type.INT_TYPE.getDescriptor());
-		super.visitInsn(IADD);
-		super.visitInsn(DUP);
-		super.visitFieldInsn(PUTSTATIC, logFieldOwner, "logsize", Type.INT_TYPE.getDescriptor());
-
-		super.visitLdcInsn(Constants.MAX_LOG_SIZE);
-		// super.visitInsn(ISUB);
-		super.visitJumpInsn(IF_ICMPLE, endLbl);
-		// super.ifCmp(Type.INT_TYPE, Opcodes.IFGE, endLbl);
-		// super.visitVarInsn(ALOAD, monitorIndx);
-		// super.monitorExit();
-		if (logFieldOwner.equals(Type.getInternalName(SerializableLog.class)))
-			super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(WallaceExportRunner.class), "_exportSerializable", "()V");
-		else
-			super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(WallaceExportRunner.class), "_export", "()V");
-		// super.visitVarInsn(ALOAD, monitorIndx);
-		// super.monitorEnter();
-//		super.visitFieldInsn(getOpcode, logFieldOwner, "logsize", Type.INT_TYPE.getDescriptor());
-//		super.visitLdcInsn(Constants.VERY_MAX_LOG_SIZE);
-//		super.visitJumpInsn(IF_ICMPLE, endLbl);
-
-		// println("GOing to wait for " + logFieldOwner);
-		// super.visitLabel(tryStart);
-
-//		super.visitFieldInsn(Opcodes.GETSTATIC, Type.getInternalName(Log.class), "lock", "Ljava/lang/Object;");
-//		super.visitLdcInsn(500L);
-//		super.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "wait", "(J)V");
-
-		// super.visitLabel(tryEnd);
-
-		// super.visitJumpInsn(GOTO, endLbl);
-		// super.visitLabel(handlerStart);
-		// int n = newLocal(Type.getType(InterruptedException.class));
-		// super.visitVarInsn(ASTORE, n);
-		// super.visitInsn(POP);
-		visitLabel(endLbl);
-//		super.visitVarInsn(ALOAD, monitorIndx);
-//		super.monitorExit();
-		super.visitFieldInsn(GETSTATIC, Type.getInternalName(Log.class), "logLock", Type.getDescriptor(Lock.class));
-		super.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Lock.class), "unlock", "()V");
-		// super.visitLocalVariable(logFieldName + "_monitor",
-		// "Ljava/lang/Object;", null, monitorStart, monitorEndLabel,
-		// monitorIndx);
-		// }
-
-	}
-
-
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/NonDeterministicLoggingClassVisitor.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/NonDeterministicLoggingClassVisitor.java
deleted file mode 100644
index bec7c4e..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/NonDeterministicLoggingClassVisitor.java
+++ /dev/null
@@ -1,163 +0,0 @@
-package edu.columbia.cs.psl.invivo.record.visitor;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-
-import org.apache.log4j.Logger;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.commons.AnalyzerAdapter;
-import org.objectweb.asm.commons.JSRInlinerAdapter;
-import org.objectweb.asm.commons.LocalVariablesSorter;
-import org.objectweb.asm.tree.MethodInsnNode;
-
-import edu.columbia.cs.psl.invivo.record.Constants;
-import edu.columbia.cs.psl.invivo.record.MethodCall;
-
-public class NonDeterministicLoggingClassVisitor extends ClassVisitor implements Opcodes {
-
-	private String className;
-	private boolean isAClass = true;
-
-	public NonDeterministicLoggingClassVisitor(int api, ClassVisitor cv) {
-		super(api, cv);
-
-	}
-
-	private static Logger logger = Logger.getLogger(NonDeterministicLoggingClassVisitor.class);
-
-	@Override
-	public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
-		super.visit(version, access, name, signature, superName, interfaces);
-		this.className = name;
-
-		logger.debug("Visiting " + name + " for instrumentation");
-		if ((access & Opcodes.ACC_INTERFACE) != 0)
-			isAClass = false;
-	}
-
-	private boolean isFirstConstructor = true;
-
-	@Override
-	public MethodVisitor visitMethod(int acc, String name, String desc, String signature, String[] exceptions) {
-		// TODO need an annotation to disable doing this to some apps
-		if (isAClass && !name.equals(Constants.INNER_COPY_METHOD_NAME) && !name.equals(Constants.OUTER_COPY_METHOD_NAME) && !name.equals(Constants.SET_FIELDS_METHOD_NAME)
-				&& !className.startsWith("com/thoughtworks")
-				)
-		{
-			MethodVisitor smv = cv.visitMethod(acc, name, desc, signature, exceptions);
-			JSRInlinerAdapter mv = new JSRInlinerAdapter(smv, acc, name, desc, signature, exceptions);
-
-			AnalyzerAdapter analyzer = new AnalyzerAdapter(className, acc, name, desc, mv);
-//			LocalVariablesSorter sorter  = new LocalVariablesSorter(acc, desc, analyzer);
-
-			// CheckMethodAdapter cmv = new CheckMethodAdapter(mv);
-
-			NonDeterministicLoggingMethodVisitor cloningMV = new NonDeterministicLoggingMethodVisitor(Opcodes.ASM4, analyzer, acc, name, desc, className, isFirstConstructor, analyzer, null);
-			if (name.equals("<init>"))
-				isFirstConstructor = false;
-			cloningMV.setClassVisitor(this);
-			return cloningMV;
-		} else
-			return cv.visitMethod(acc, name, desc, signature, exceptions);
-	}
-
-	public HashSet<MethodCall> getLoggedMethodCalls() {
-		return loggedMethodCalls;
-	}
-
-	private HashSet<MethodCall> loggedMethodCalls = new HashSet<MethodCall>();
-	private HashMap<MethodCall, MethodInsnNode> captureMethodsToGenerate = new HashMap<MethodCall, MethodInsnNode>();
-
-	public void addFieldMarkup(Collection<MethodCall> calls) {
-		logger.debug("Received field markup from method visitor (" + calls.size() + ")");
-		loggedMethodCalls.addAll(calls);
-		// TODO also setup the new method to retrieve the list of replacements
-		// for the method
-	}
-
-	@Override
-	public void visitEnd() {
-		super.visitEnd();
-		for (MethodCall mc : captureMethodsToGenerate.keySet()) {
-			MethodInsnNode mi = captureMethodsToGenerate.get(mc);
-			String methodDesc = mi.desc;
-
-			String captureDesc = mi.desc;
-
-			int opcode = Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL;
-			if(mi.getOpcode() == Opcodes.INVOKESPECIAL && !mi.name.equals("<init>"))
-				opcode = Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL;
-			else if (mi.getOpcode() != Opcodes.INVOKESTATIC) {
-				// Need to put owner of the method on the top of the args list
-				captureDesc = "(L" + mi.owner + ";";
-				for (Type t : Type.getArgumentTypes(mi.desc))
-					captureDesc += t.getDescriptor();
-				captureDesc += ")" + Type.getReturnType(mi.desc).getDescriptor();
-			}
-			MethodVisitor mv = super.visitMethod(opcode, mc.getCapturePrefix() + "_capture", captureDesc, null, null);
-			LocalVariablesSorter lvs = new LocalVariablesSorter(opcode, captureDesc, mv);
-			CloningAdviceAdapter caa = new CloningAdviceAdapter(Opcodes.ASM4, lvs, opcode, mc.getCapturePrefix() + "_capture", captureDesc, className,lvs);
-			Type[] args = Type.getArgumentTypes(captureDesc);
-			if(mi.name.equals("<init>"))
-			{
-				for (int i = 0; i < args.length; i++) {
-					caa.loadArg(i);
-				}
-				caa.visitMethodInsn(Opcodes.INVOKESPECIAL, mi.owner, mi.name, mi.desc);
-				caa.loadArg(0);
-			}
-			else
-			{
-				if(opcode == Opcodes.ACC_PRIVATE)
-					caa.loadThis();
-				for (int i = 0; i < args.length; i++) {
-					caa.loadArg(i);
-				}
-				caa.visitMethodInsn(mi.getOpcode(), mi.owner, mi.name, mi.desc);
-				for (int i = 0; i < args.length; i++) {
-					if (args[i].getSort() == Type.ARRAY) {
-						boolean minimalCopy = (Type.getReturnType(methodDesc).getSort() == Type.INT);
-						if(minimalCopy)
-						{
-							caa.dup();
-							Label isNegative = new Label();
-							Label notNegative = new Label();
-							caa.visitJumpInsn(Opcodes.IFLT, isNegative);
-							caa.dup();
-							caa.visitJumpInsn(Opcodes.GOTO, notNegative);
-							caa.visitLabel(isNegative);
-							caa.visitInsn(ICONST_0);
-							caa.visitLabel(notNegative);
-						}
-						caa.loadArg(i);
-						//- (mi.getOpcode() == Opcodes.INVOKESTATIC ? 0 : 1)
-						caa.logValueAtTopOfStackToArray(MethodCall.getLogClassName(args[i]), "aLog", "[Ljava/lang/Object;",
-								args[i], true, mi.owner+"."+mi.name+"->_"+i+"\t"+args[i].getDescriptor()+"\t\t"+className,minimalCopy);
-						if (args[i].getSize() == 1)
-							caa.pop();
-						else
-							caa.pop2();
-					}
-				}
-			}
-			caa.returnValue();
-			caa.visitMaxs(0, 0);
-			caa.visitEnd();
-		}
-	}
-
-	public String getClassName() {
-		return className;
-	}
-
-	public void addCaptureMethodsToGenerate(HashMap<MethodCall, MethodInsnNode> captureMethodsToGenerate) {
-		this.captureMethodsToGenerate.putAll(captureMethodsToGenerate);
-	}
-
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/NonDeterministicLoggingMethodVisitor.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/NonDeterministicLoggingMethodVisitor.java
deleted file mode 100644
index 5a324f2..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/NonDeterministicLoggingMethodVisitor.java
+++ /dev/null
@@ -1,235 +0,0 @@
-package edu.columbia.cs.psl.invivo.record.visitor;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Scanner;
-
-import org.apache.log4j.Logger;
-import org.objectweb.asm.Handle;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.commons.AnalyzerAdapter;
-import org.objectweb.asm.commons.LocalVariablesSorter;
-import org.objectweb.asm.tree.MethodInsnNode;
-
-import edu.columbia.cs.psl.invivo.record.Constants;
-import edu.columbia.cs.psl.invivo.record.Instrumenter;
-import edu.columbia.cs.psl.invivo.record.MethodCall;
-
-public class NonDeterministicLoggingMethodVisitor extends CloningAdviceAdapter implements Constants {
-	private static Logger			logger					= Logger.getLogger(NonDeterministicLoggingMethodVisitor.class);
-	private String					name;
-	private String					desc;
-	private String					classDesc;
-	private int						pc;
-	public static HashSet<String>	nonDeterministicMethods	= new HashSet<String>();
-	private boolean					isStatic;
-	private boolean					constructor;
-	private boolean					superInitialized;
-	private AnalyzerAdapter analyzer;
-	public static boolean isND(String owner, String name, String desc)
-	{
-		return nonDeterministicMethods.contains(owner + "." + name + ":" + desc);
-	}
-	public static void registerNDMethod(String owner, String name, String desc)
-	{
-		nonDeterministicMethods.add(owner + "." + name + ":" + desc);
-	}
-	static {
-		File f = new File("nondeterministic-methods.txt");
-		Scanner s;
-		try {
-			s = new Scanner(f);
-			while (s.hasNextLine())
-				nonDeterministicMethods.add(s.nextLine());
-		} catch (FileNotFoundException e) {
-			e.printStackTrace();
-		}
-	}
-
-	@Override
-	public void visitCode() {
-		super.visitCode();
-		if (!constructor)
-			superInitialized = true;
-	}
-
-	private boolean	isFirstConstructor;
-
-	protected NonDeterministicLoggingMethodVisitor(int api, MethodVisitor mv, int access, String name, String desc, String classDesc,
-			boolean isFirstConstructor, AnalyzerAdapter analyzer, LocalVariablesSorter lvs) {
-		super(api, mv, access, name, desc,classDesc, lvs);
-		this.name = name;
-		this.desc = desc;
-		this.classDesc = classDesc;
-		this.isStatic = (access & Opcodes.ACC_STATIC) != 0;
-		this.constructor = "<init>".equals(name);
-		this.isFirstConstructor = isFirstConstructor;
-		this.analyzer = analyzer;
-	}
-
-	private NonDeterministicLoggingClassVisitor	parent;
-
-	public void setClassVisitor(NonDeterministicLoggingClassVisitor coaClassVisitor) {
-		this.parent = coaClassVisitor;
-	}
-
-
-	@Override
-	public void visitEnd() {
-//		System.out.println(classDesc + " " + name);
-		super.visitEnd();
-
-		parent.addFieldMarkup(methodCallsToClear);
-		parent.addCaptureMethodsToGenerate(captureMethodsToGenerate);
-	}
-
-	private int	lineNumber	= 0;
-
-	@Override
-	public void visitLineNumber(int line, Label start) {
-		super.visitLineNumber(line, start);
-		lineNumber = line;
-	}
-
-	private HashMap<MethodCall, MethodInsnNode> captureMethodsToGenerate = new HashMap<MethodCall, MethodInsnNode>();
-	@Override
-	public void visitMethodInsn(int opcode, String owner, String name, String desc) {
-		try {
-
-			MethodCall m = new MethodCall(this.name, this.desc, this.classDesc, pc, lineNumber, owner, name, desc, isStatic);
-			Type returnType = Type.getMethodType(desc).getReturnType();
-			if ((!constructor || isFirstConstructor || superInitialized) && !returnType.equals(Type.VOID_TYPE)
-					&& nonDeterministicMethods.contains(owner + "." + name + ":" + desc)) {
-				logger.debug("Adding field in MV to list " + m.getLogFieldName());
-				methodCallsToClear.add(m);
-				Type[] args = Type.getArgumentTypes(desc);
-				boolean hasArray = false;
-				for(Type t : args)
-					if(t.getSort() == Type.ARRAY && !name.contains("write"))
-						hasArray = true;
-
-				if(hasArray)
-				{	//TODO uncomment this block
-					captureMethodsToGenerate.put(m, new MethodInsnNode(opcode, owner, name, desc));
-					String captureDesc = desc;
-
-					int invokeOpcode = Opcodes.INVOKESTATIC;
-					if(opcode == Opcodes.INVOKESPECIAL && !name.equals("<init>"))
-					{
-						invokeOpcode = Opcodes.INVOKESPECIAL;
-					}
-					else if(opcode != Opcodes.INVOKESTATIC)
-					{
-						//Need to put owner of the method on the top of the args list
-						captureDesc = "(L" +  owner +";";
-						for(Type t : args)
-							captureDesc += t.getDescriptor();
-						captureDesc+=")"+Type.getReturnType(desc).getDescriptor();
-					}
-					mv.visitMethodInsn(invokeOpcode, classDesc, m.getCapturePrefix()+"_capture", captureDesc);
-					logValueAtTopOfStackToArray(m.getLogClassName(), m.getLogFieldName(), m.getLogFieldType().getDescriptor(), returnType, true,
-							owner+"."+name + "\t" + desc+"\t\t"+classDesc+"."+this.name,false);
-				}
-				else
-				{
-					mv.visitMethodInsn(opcode, owner, name, desc);
-					logValueAtTopOfStackToArray(m.getLogClassName(), m.getLogFieldName(), m.getLogFieldType().getDescriptor(), returnType, true,
-							owner+"."+name + "\t" + desc+"\t\t"+classDesc+"."+this.name,false);
-				}
-			}
-			else if(opcode == INVOKESPECIAL && name.equals("<init>") && nonDeterministicMethods.contains(owner + "." + name + ":" + desc) && !(owner.equals(Instrumenter.instrumentedClasses.get(classDesc).superName)
-					&& this.name.equals("<init>"))) {
-				super.visitMethodInsn(opcode, owner, name, desc);
-				if(analyzer.stack != null && analyzer.stack.size() > 0 && analyzer.stack.get(analyzer.stack.size()-1).equals(owner))
-					logValueAtTopOfStackToArray(MethodCall.getLogClassName(Type.getType("L"+owner+";")), "aLog", "[Ljava/lang/Object;", Type.getType("L"+owner+";"), true,
-							owner+"."+name + "\t" + desc+"\t\t"+classDesc+"."+this.name,false);
-
-			}
-			else
-				mv.visitMethodInsn(opcode, owner, name, desc);
-			pc++;
-		} catch (Exception ex) {
-			logger.error("Unable to instrument method call", ex);
-		}
-	}
-
-	private HashSet<MethodCall>	methodCallsToClear	= new HashSet<MethodCall>();
-
-	@Override
-	public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-		super.visitFieldInsn(opcode, owner, name, desc);
-		pc++;
-	}
-
-	@Override
-	public void visitIincInsn(int var, int increment) {
-		super.visitIincInsn(var, increment);
-		pc++;
-	}
-
-	@Override
-	public void visitInsn(int opcode) {
-		super.visitInsn(opcode);
-		pc++;
-	}
-
-	@Override
-	public void visitIntInsn(int opcode, int operand) {
-		super.visitIntInsn(opcode, operand);
-		pc++;
-	}
-
-	@Override
-	public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
-		super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
-		pc++;
-	}
-
-	@Override
-	public void visitJumpInsn(int opcode, Label label) {
-		super.visitJumpInsn(opcode, label);
-		pc++;
-	}
-
-	@Override
-	public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-		super.visitLookupSwitchInsn(dflt, keys, labels);
-		pc++;
-	}
-
-	@Override
-	public void visitMultiANewArrayInsn(String desc, int dims) {
-		super.visitMultiANewArrayInsn(desc, dims);
-		pc++;
-	}
-
-	@Override
-	public void visitTypeInsn(int opcode, String type) {
-		super.visitTypeInsn(opcode, type);
-		pc++;
-	}
-
-	@Override
-	public void visitVarInsn(int opcode, int var) {
-		super.visitVarInsn(opcode, var);
-		pc++;
-	}
-
-	@Override
-	public void visitLdcInsn(Object cst) {
-		super.visitLdcInsn(cst);
-		pc++;
-	}
-
-	@Override
-	public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
-		super.visitTableSwitchInsn(min, max, dflt, labels);
-		pc++;
-	}
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/xstream/CatchClassErrorFieldDictionary.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/xstream/CatchClassErrorFieldDictionary.java
deleted file mode 100644
index af74d0e..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/xstream/CatchClassErrorFieldDictionary.java
+++ /dev/null
@@ -1,189 +0,0 @@
-package edu.columbia.cs.psl.invivo.record.xstream;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import com.thoughtworks.xstream.converters.reflection.FieldDictionary;
-import com.thoughtworks.xstream.converters.reflection.FieldKey;
-import com.thoughtworks.xstream.converters.reflection.FieldKeySorter;
-import com.thoughtworks.xstream.converters.reflection.ImmutableFieldKeySorter;
-import com.thoughtworks.xstream.converters.reflection.MissingFieldException;
-import com.thoughtworks.xstream.converters.reflection.ObjectAccessException;
-import com.thoughtworks.xstream.core.Caching;
-import com.thoughtworks.xstream.core.JVM;
-import com.thoughtworks.xstream.core.util.OrderRetainingMap;
-
-public class CatchClassErrorFieldDictionary extends FieldDictionary {
-    private transient Map keyedByFieldNameCache;
-    private transient Map keyedByFieldKeyCache;
-    private final FieldKeySorter sorter;
-
-    public CatchClassErrorFieldDictionary() {
-        this(new ImmutableFieldKeySorter());
-    }
-
-    public CatchClassErrorFieldDictionary(FieldKeySorter sorter) {
-        this.sorter = sorter;
-        init();
-    }
-
-    private void init() {
-        keyedByFieldNameCache = new HashMap();
-        keyedByFieldKeyCache = new HashMap();
-        keyedByFieldNameCache.put(Object.class, Collections.EMPTY_MAP);
-        keyedByFieldKeyCache.put(Object.class, Collections.EMPTY_MAP);
-    }
-
-    /**
-     * Returns an iterator for all fields for some class
-     *
-     * @param cls the class you are interested on
-     * @return an iterator for its fields
-     * @deprecated As of 1.3, use {@link #fieldsFor(Class)} instead
-     */
-    public Iterator serializableFieldsFor(Class cls) {
-        return fieldsFor(cls);
-    }
-
-    /**
-     * Returns an iterator for all fields for some class
-     *
-     * @param cls the class you are interested on
-     * @return an iterator for its fields
-     */
-    public Iterator fieldsFor(final Class cls) {
-        return buildMap(cls, true).values().iterator();
-    }
-
-    /**
-     * Returns an specific field of some class. If definedIn is null, it searches for the field
-     * named 'name' inside the class cls. If definedIn is different than null, tries to find the
-     * specified field name in the specified class cls which should be defined in class
-     * definedIn (either equals cls or a one of it's superclasses)
-     *
-     * @param cls the class where the field is to be searched
-     * @param name the field name
-     * @param definedIn the superclass (or the class itself) of cls where the field was defined
-     * @return the field itself
-     * @throws ObjectAccessException if no field can be found
-     */
-    public Field field(Class cls, String name, Class definedIn) {
-        Field field = fieldOrNull(cls, name, definedIn);
-        if (field == null) {
-            throw new MissingFieldException(cls.getName(), name);
-        } else {
-            return field;
-        }
-    }
-
-    /**
-     * Returns an specific field of some class. If definedIn is null, it searches for the field
-     * named 'name' inside the class cls. If definedIn is different than null, tries to find the
-     * specified field name in the specified class cls which should be defined in class
-     * definedIn (either equals cls or a one of it's superclasses)
-     *
-     * @param cls the class where the field is to be searched
-     * @param name the field name
-     * @param definedIn the superclass (or the class itself) of cls where the field was defined
-     * @return the field itself or <code>null</code>
-     * @since 1.4
-     */
-    public Field fieldOrNull(Class cls, String name, Class definedIn) {
-        Map fields = buildMap(cls, definedIn != null);
-        Field field = (Field)fields.get(definedIn != null
-            ? (Object)new FieldKey(name, definedIn, 0)
-            : (Object)name);
-        return field;
-    }
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-	private Map buildMap(final Class type, boolean tupleKeyed) {
-        final Map result;
-        Class cls = type;
-        synchronized (this) {
-            if (!keyedByFieldNameCache.containsKey(type)) {
-                final List superClasses = new ArrayList();
-                while (!Object.class.equals(cls)) {
-                    superClasses.add(0, cls);
-                    cls = cls.getSuperclass();
-                }
-                Map lastKeyedByFieldName = Collections.EMPTY_MAP;
-                Map lastKeyedByFieldKey = Collections.EMPTY_MAP;
-                for (final Iterator iter = superClasses.iterator(); iter.hasNext();) {
-                    cls = (Class)iter.next();
-                    if (!keyedByFieldNameCache.containsKey(cls)) {
-                        final Map keyedByFieldName = new HashMap(lastKeyedByFieldName);
-                        final Map keyedByFieldKey = new OrderRetainingMap(lastKeyedByFieldKey);
-                        try{
-                        Field[] fields = cls.getDeclaredFields();
-                        if (JVM.reverseFieldDefinition()) {
-                            for (int i = fields.length >> 1; i-- > 0;) {
-                                final int idx = fields.length - i - 1;
-                                final Field field = fields[i];
-                                fields[i] = fields[idx];
-                                fields[idx] = field;
-                            }
-                        }
-                        for (int i = 0; i < fields.length; i++ ) {
-                            Field field = fields[i];
-                            if (!field.isAccessible()) {
-                                field.setAccessible(true);
-                            }
-                            FieldKey fieldKey = new FieldKey(
-                                field.getName(), field.getDeclaringClass(), i);
-                            Field existent = (Field)keyedByFieldName.get(field.getName());
-                            if (existent == null
-                            // do overwrite statics
-                                || ((existent.getModifiers() & Modifier.STATIC) != 0)
-                                // overwrite non-statics with non-statics only
-                                || (existent != null && ((field.getModifiers() & Modifier.STATIC) == 0))) {
-                                keyedByFieldName.put(field.getName(), field);
-                            }
-                            keyedByFieldKey.put(fieldKey, field);
-                        }
-                        }
-                        catch(NoClassDefFoundError ex)
-                        {
-                        	//do nothing!
-                        }
-                        final Map sortedFieldKeys = sorter.sort(type, keyedByFieldKey);
-                        keyedByFieldNameCache.put(cls, keyedByFieldName);
-                        keyedByFieldKeyCache.put(cls, sortedFieldKeys);
-                        lastKeyedByFieldName = keyedByFieldName;
-                        lastKeyedByFieldKey = sortedFieldKeys;
-                    } else {
-                        lastKeyedByFieldName = (Map)keyedByFieldNameCache.get(cls);
-                        lastKeyedByFieldKey = (Map)keyedByFieldKeyCache.get(cls);
-                    }
-                }
-                result = tupleKeyed ? lastKeyedByFieldKey : lastKeyedByFieldName;
-            } else {
-                result = (Map)(tupleKeyed
-                    ? keyedByFieldKeyCache.get(type)
-                    : keyedByFieldNameCache.get(type));
-            }
-        }
-        return result;
-    }
-
-    public synchronized void flushCache() {
-        Set objectTypeSet = Collections.singleton(Object.class);
-        keyedByFieldNameCache.keySet().retainAll(objectTypeSet);
-        keyedByFieldKeyCache.keySet().retainAll(objectTypeSet);
-        if (sorter instanceof Caching) {
-            ((Caching)sorter).flushCache();
-        }
-    }
-
-    protected Object readResolve() {
-        init();
-        return this;
-    }
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/xstream/StaticReflectionProvider.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/xstream/StaticReflectionProvider.java
deleted file mode 100644
index 3852bb0..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/xstream/StaticReflectionProvider.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package edu.columbia.cs.psl.invivo.record.xstream;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Modifier;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-import com.thoughtworks.xstream.converters.reflection.ObjectAccessException;
-import com.thoughtworks.xstream.converters.reflection.Sun14ReflectionProvider;
-
-public class StaticReflectionProvider extends Sun14ReflectionProvider {
-	public void writeField(Object object, String fieldName, Object value, Class definedIn) {
-		if (!Modifier.isStatic(fieldDictionary.field(object.getClass(), fieldName, definedIn).getModifiers())) {
-			super.writeField(object, fieldName, value, definedIn);
-		} else {
-			try {
-				fieldDictionary.field(object.getClass(), fieldName, definedIn).set(null, value);
-			} catch (IllegalArgumentException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			} catch (IllegalAccessException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-		}
-	}
-
-	public StaticReflectionProvider() {
-		super(new CatchClassErrorFieldDictionary());
-	}
-
-	@Override
-	public void visitSerializableFields(Object object, Visitor visitor) {
-		for (Iterator iterator = fieldDictionary.fieldsFor(object.getClass()); iterator.hasNext();) {
-			Field field = (Field) iterator.next();
-			if (!fieldModifiersSupported(field)) {
-				continue;
-			}
-			validateFieldAccess(field);
-			try {
-				Object value = field.get(object);
-				if (value != null)
-					synchronized (value) {
-						visitor.visit(field.getName(), field.getType(), field.getDeclaringClass(), value);
-					}
-				else
-					visitor.visit(field.getName(), field.getType(), field.getDeclaringClass(), value);
-
-			} catch (IllegalArgumentException e) {
-				throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e);
-			} catch (IllegalAccessException e) {
-				throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e);
-			} catch (SecurityException e) {
-				e.printStackTrace();
-			}
-		}
-	}
-
-	@Override
-	protected boolean fieldModifiersSupported(Field field) {
-		int modifiers = field.getModifiers();
-		return !(Modifier.isTransient(modifiers) || (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers) ));
-	}
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/NonDeterministicReplayClassVisitor.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/NonDeterministicReplayClassVisitor.java
deleted file mode 100644
index 085e31d..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/NonDeterministicReplayClassVisitor.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package edu.columbia.cs.psl.invivo.replay;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-
-import org.apache.log4j.Logger;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.commons.AnalyzerAdapter;
-import org.objectweb.asm.commons.JSRInlinerAdapter;
-import org.objectweb.asm.tree.FieldNode;
-import org.objectweb.asm.tree.MethodInsnNode;
-import org.objectweb.asm.util.CheckMethodAdapter;
-
-import edu.columbia.cs.psl.invivo.record.Constants;
-import edu.columbia.cs.psl.invivo.record.MethodCall;
-import edu.columbia.cs.psl.invivo.record.visitor.CloningAdviceAdapter;
-
-public class NonDeterministicReplayClassVisitor extends ClassVisitor implements Opcodes{
-
-	private String className;
-	private boolean isAClass = true;
-
-	public NonDeterministicReplayClassVisitor(int api, ClassVisitor cv) {
-		super(api, cv);
-
-	}
-	private static Logger logger = Logger.getLogger(NonDeterministicReplayClassVisitor.class);
-	@Override
-	public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
-		super.visit(version, access, name, signature, superName, interfaces);
-		this.className = name;
-
-		logger.debug("Visiting " + name+ " for instrumentation");
-		if((access & Opcodes.ACC_INTERFACE) != 0)
-			isAClass = false;
-	}
-	private boolean isFirstConstructor = true;
-	@Override
-	public MethodVisitor visitMethod(int acc, String name, String desc,
-			String signature, String[] exceptions) {
-		//TODO need an annotation to disable doing this to some apps
-		if(isAClass)// && className.startsWith("edu"))
-		{
-
-			MethodVisitor smv = cv.visitMethod(acc, name, desc, signature, exceptions);
-			JSRInlinerAdapter mv = new JSRInlinerAdapter(smv, acc, name, desc, signature, exceptions);
-
-			AnalyzerAdapter analyzer = new AnalyzerAdapter(className, acc, name, desc, mv);
-			CheckMethodAdapter cm = new CheckMethodAdapter(analyzer);
-			NonDeterministicReplayMethodVisitor cloningMV = new NonDeterministicReplayMethodVisitor(Opcodes.ASM4, cm, acc, name, desc,className,isFirstConstructor, analyzer);
-			if(name.equals("<init>"))
-				isFirstConstructor = false;
-			cloningMV.setClassVisitor(this);
-			return cloningMV;
-		}
-		else
-			return 	cv.visitMethod(acc, name, desc, signature,
-					exceptions);
-	}
-
-	public HashSet<MethodCall> getLoggedMethodCalls() {
-		return loggedMethodCalls;
-	}
-	private HashSet<MethodCall> loggedMethodCalls = new HashSet<MethodCall>();
-	private HashMap<String, MethodInsnNode> captureMethodsToGenerate = new HashMap<String, MethodInsnNode>();
-	public void addFieldMarkup(ArrayList<MethodCall> calls) {
-		logger.debug("Received field markup from method visitor (" + calls.size() + ")");
-		loggedMethodCalls.addAll(calls);
-		//TODO also setup the new method to retrieve the list of replacements for the method
-	}
-
-	@Override
-	public void visitEnd() {
-		super.visitEnd();
-
-	}
-	public String getClassName() {
-		return className;
-	}
-
-	public void addCaptureMethodsToGenerate(HashMap<String, MethodInsnNode> captureMethodsToGenerate) {
-		this.captureMethodsToGenerate.putAll(captureMethodsToGenerate);
-	}
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/NonDeterministicReplayMethodVisitor.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/NonDeterministicReplayMethodVisitor.java
deleted file mode 100644
index 7d79d75..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/NonDeterministicReplayMethodVisitor.java
+++ /dev/null
@@ -1,406 +0,0 @@
-package edu.columbia.cs.psl.invivo.replay;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Scanner;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReadWriteLock;
-
-import org.apache.log4j.Logger;
-import org.objectweb.asm.Handle;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.commons.AnalyzerAdapter;
-import org.objectweb.asm.tree.MethodInsnNode;
-
-import edu.columbia.cs.psl.invivo.record.CloningUtils;
-import edu.columbia.cs.psl.invivo.record.Constants;
-import edu.columbia.cs.psl.invivo.record.ExportedLog;
-import edu.columbia.cs.psl.invivo.record.Instrumenter;
-import edu.columbia.cs.psl.invivo.record.Log;
-import edu.columbia.cs.psl.invivo.record.MethodCall;
-import edu.columbia.cs.psl.invivo.record.visitor.CloningAdviceAdapter;
-import edu.columbia.cs.psl.invivo.record.visitor.NonDeterministicLoggingMethodVisitor;
-
-public class NonDeterministicReplayMethodVisitor extends CloningAdviceAdapter implements Constants {
-	private static Logger			logger					= Logger.getLogger(NonDeterministicReplayMethodVisitor.class);
-	private String					name;
-	private String					desc;
-	private String					classDesc;
-	private int						pc;
-	private boolean					isStatic;
-	private boolean					constructor;
-	private boolean					superInitialized;
-
-
-	@Override
-	public void visitCode() {
-		super.visitCode();
-		if (!constructor)
-			superInitialized = true;
-	}
-
-	private boolean	isFirstConstructor;
-	AnalyzerAdapter	analyzer;
-
-	protected NonDeterministicReplayMethodVisitor(int api, MethodVisitor mv, int access, String name, String desc, String classDesc,
-			boolean isFirstConstructor, AnalyzerAdapter analyzer) {
-		super(api, mv, access, name, desc, classDesc, null);
-		this.name = name;
-		this.desc = desc;
-		this.classDesc = classDesc;
-		this.isStatic = (access & Opcodes.ACC_STATIC) != 0;
-		this.constructor = "<init>".equals(name);
-		this.isFirstConstructor = isFirstConstructor;
-		this.analyzer = analyzer;
-	}
-
-	private NonDeterministicReplayClassVisitor	parent;
-
-	public void setClassVisitor(NonDeterministicReplayClassVisitor coaClassVisitor) {
-		this.parent = coaClassVisitor;
-	}
-
-	@Override
-	public void visitEnd() {
-		super.visitEnd();
-		parent.addFieldMarkup(methodCallsToClear);
-		parent.addCaptureMethodsToGenerate(captureMethodsToGenerate);
-	}
-
-	private int	lineNumber	= 0;
-
-	@Override
-	public void visitLineNumber(int line, Label start) {
-		super.visitLineNumber(line, start);
-		lineNumber = line;
-	}
-
-	private void loadReplayIndex(String className, String fieldName) {
-		super.visitFieldInsn(GETSTATIC, className, fieldName + "_replayIndex", "Ljava/util/HashMap;");
-		super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(Thread.class), "currentThread", "()Ljava/lang/Thread;");
-		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(Thread.class), "getName", "()Ljava/lang/String;");
-		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(HashMap.class), "containsKey", "(Ljava/lang/Object;)Z");
-		Label exists = new Label();
-		super.visitJumpInsn(Opcodes.IFNE, exists);
-		super.visitFieldInsn(GETSTATIC, className, fieldName + "_replayIndex", "Ljava/util/HashMap;");
-		super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(Thread.class), "currentThread", "()Ljava/lang/Thread;");
-		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(Thread.class), "getName", "()Ljava/lang/String;");
-		super.visitInsn(ICONST_0);
-		super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(Integer.class), "valueOf", "(I)Ljava/lang/Integer;");
-		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(HashMap.class), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
-		super.visitInsn(POP);
-		super.visitLabel(exists);
-		super.visitFieldInsn(GETSTATIC, className, fieldName + "_replayIndex", "Ljava/util/HashMap;");
-		super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(Thread.class), "currentThread", "()Ljava/lang/Thread;");
-		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(Thread.class), "getName", "()Ljava/lang/String;");
-		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(HashMap.class), "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
-		super.visitTypeInsn(CHECKCAST, "java/lang/Integer");
-		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(Integer.class), "intValue", "()I");
-//				super.visitInsn(ICONST_0);
-	}
-
-	private void incrementReplayIndex(String className, String fieldName) {
-		super.visitFieldInsn(GETSTATIC, className, fieldName + "_replayIndex", "Ljava/util/HashMap;");
-		super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(Thread.class), "currentThread", "()Ljava/lang/Thread;");
-		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(Thread.class), "getName", "()Ljava/lang/String;");
-		loadReplayIndex(className, fieldName);
-		super.visitInsn(ICONST_1);
-		super.visitInsn(IADD);
-		super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(Integer.class), "valueOf", "(I)Ljava/lang/Integer;");
-		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(HashMap.class), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
-		super.visitInsn(POP);
-	}
-
-	private HashMap<String, MethodInsnNode>	captureMethodsToGenerate	= new HashMap<String, MethodInsnNode>();
-
-	@Override
-	public void visitMethodInsn(int opcode, String owner, String name, String desc) {
-
-		try {
-			MethodCall m = new MethodCall(this.name, this.desc, this.classDesc, pc, lineNumber, owner, name, desc, isStatic);
-			Type returnType = Type.getMethodType(desc).getReturnType();
-
-			if (opcode == INVOKESPECIAL && name.equals("<init>") && NonDeterministicLoggingMethodVisitor.nonDeterministicMethods.contains(owner + "." + name + ":" + desc)) {
-				System.out.println(this.classDesc +"."+this.name);
-				System.out.println(Replayer.instrumentedClasses.get(classDesc).superName);
-				System.out.println(owner);
-				System.out.println(analyzer.stack);
-				if (!(owner.equals(Replayer.instrumentedClasses.get(classDesc).superName) && this.name.equals("<init>"))) {
-					Type[] args = Type.getArgumentTypes(desc);
-					for (int i = args.length - 1; i >= 0; i--) {
-						Type t = args[i];
-						if (t.getSize() == 2)
-							mv.visitInsn(POP2);
-						else
-							mv.visitInsn(POP);
-					}
-
-					if (analyzer.stack != null && analyzer.stack.size() > 0
-							&& analyzer.uninitializedTypes.containsKey(analyzer.stack.get(analyzer.stack.size() - 1))
-							&& analyzer.uninitializedTypes.get(analyzer.stack.get(analyzer.stack.size() - 1)).equals(owner)) {
-						mv.visitInsn(POP);
-						if (analyzer.stack.size() > 0 && analyzer.uninitializedTypes.containsKey(analyzer.stack.get(analyzer.stack.size() - 1))
-								&& analyzer.uninitializedTypes.get(analyzer.stack.get(analyzer.stack.size() - 1)).equals(owner))
-							mv.visitInsn(POP);
-
-						String replayClassName = MethodCall.getReplayClassName(Type.getType("L"+m.getMethodOwner()+";"));
-						mv.visitFieldInsn(GETSTATIC, replayClassName, m.getLogFieldName(), "[Ljava/lang/Object;");
-
-						Label fallThrough = new Label();
-						loadReplayIndex(replayClassName, m.getLogFieldName());
-						mv.visitInsn(DUP);
-
-						mv.visitFieldInsn(GETSTATIC, replayClassName, m.getLogFieldName() + "_fill", "I");
-						mv.visitJumpInsn(Opcodes.IF_ICMPNE, fallThrough);
-						mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(ReplayRunner.class), "loadNextLog", "()V");
-						mv.visitInsn(POP);
-						loadReplayIndex(replayClassName, m.getLogFieldName());
-
-						mv.visitLabel(fallThrough);
-						//				arrayLoad(Type.getType("L"+m.getMethodOwner()+";"));
-						mv.visitInsn(AALOAD);
-						mv.visitTypeInsn(CHECKCAST, m.getMethodOwner());
-						incrementReplayIndex(replayClassName, m.getLogFieldName());
-					}
-
-				} else {
-					super.visitMethodInsn(opcode, owner, name, desc);
-				}
-
-			} else if ((!constructor || isFirstConstructor || superInitialized) && returnType.equals(Type.VOID_TYPE) && !name.equals("<init>")
-					&& NonDeterministicLoggingMethodVisitor.nonDeterministicMethods.contains(owner + "." + name + ":" + desc)) {
-				Type[] args = Type.getArgumentTypes(desc);
-				for (int i = args.length - 1; i >= 0; i--) {
-					Type t = args[i];
-					if (t.getSize() == 2)
-						mv.visitInsn(POP2);
-					else
-						mv.visitInsn(POP);
-				}
-				if (opcode != INVOKESTATIC)
-					mv.visitInsn(POP);
-
-				//				else
-				//					super.visitMethodInsn(opcode, owner, name, desc);
-
-			} else if ((!constructor || isFirstConstructor || superInitialized) && !returnType.equals(Type.VOID_TYPE)
-					&& NonDeterministicLoggingMethodVisitor.nonDeterministicMethods.contains(owner + "." + name + ":" + desc)) {
-
-				Label startOfPlayBack = new Label();
-
-				super.visitFieldInsn(GETSTATIC, Type.getInternalName(Log.class), "logLock", Type.getDescriptor(Lock.class));
-				super.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Lock.class), "lock", "()V");
-
-				logger.debug("Adding field in MV to list " + m.getLogFieldName());
-				methodCallsToClear.add(m);
-				Type[] args = Type.getArgumentTypes(desc);
-				boolean hasArray = false;
-				for (Type t : args)
-					if (t.getSort() == Type.ARRAY)
-						hasArray = true;
-
-				if (hasArray) {
-
-					Type[] targs = Type.getArgumentTypes(desc);
-					for (int i = targs.length - 1; i >= 0; i--) {
-						Type t = targs[i];
-						if (t.getSort() == Type.ARRAY) {
-							/*
-							 * stack (grows down): dest (fill not incremented yet)
-							 */
-							String replayClassName = MethodCall.getReplayClassName(t);
-							String replayFieldName = MethodCall.getLogFieldName(t);
-							mv.visitFieldInsn(GETSTATIC, replayClassName, MethodCall.getLogFieldName(t), MethodCall.getLogFieldType(t)
-									.getDescriptor());
-							//							mv.visitFieldInsn(GETSTATIC,replayClassName,
-							//									MethodCall.getLogFieldName(t)+"_replayIndex",
-							//									"I");
-							loadReplayIndex(replayClassName, replayFieldName);
-							mv.visitInsn(DUP);
-							mv.visitFieldInsn(GETSTATIC, replayClassName, MethodCall.getLogFieldName(t) + "_fill", "I");
-							Label fallThrough = new Label();
-
-							mv.visitJumpInsn(Opcodes.IF_ICMPNE, fallThrough);
-							mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(ReplayRunner.class), "loadNextLog", "()V");
-							pop();
-							loadReplayIndex(replayClassName, replayFieldName);
-							visitLabel(fallThrough);
-
-							arrayLoad(t);
-
-							/*
-							 * stack (grows down): dest src
-							 */
-							swap();
-							/*
-							 * stack (grows down): src dest
-							 */
-							push(0);
-							/*
-							 * stack (grows down): src dest 0
-							 */
-							swap();
-							/*
-							 * stack (grows down): src 0 dest
-							 */
-							push(0);
-							/*
-							 * stack (grows down): src 0 dest 0
-							 */
-
-							mv.visitFieldInsn(GETSTATIC, replayClassName, MethodCall.getLogFieldName(t), MethodCall.getLogFieldType(t)
-									.getDescriptor());
-							loadReplayIndex(replayClassName, replayFieldName);
-							arrayLoad(t);
-							mv.visitTypeInsn(Opcodes.CHECKCAST, t.getInternalName());
-							mv.visitInsn(ARRAYLENGTH);
-							incrementReplayIndex(replayClassName, replayFieldName);
-							/*
-							 * stack: src (fill incremented) 0 dest 0 length
-							 */
-							mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V");
-							/*
-							 * stack: dest popped
-							 */
-						} else {
-							switch (t.getSize()) {
-							case 2:
-								mv.visitInsn(POP2);
-								break;
-							case 1:
-							default:
-								mv.visitInsn(POP);
-								break;
-							}
-						}
-					}
-
-				} else {
-					Type[] targs = Type.getArgumentTypes(desc);
-					for (Type t : targs) {
-						switch (t.getSize()) {
-						case 2:
-							visitInsn(POP2);
-							break;
-						case 1:
-						default:
-							visitInsn(POP);
-							break;
-						}
-					}
-				}
-
-				if (opcode != INVOKESTATIC)
-					mv.visitInsn(POP);
-
-				if (returnType.getSort() == Type.VOID)
-					mv.visitInsn(NOP);
-				else {
-					mv.visitFieldInsn(GETSTATIC, m.getReplayClassName(), m.getLogFieldName(), m.getLogFieldType().getDescriptor());
-
-					loadReplayIndex(m.getReplayClassName(), m.getLogFieldName());
-					mv.visitInsn(DUP);
-					Label fallThrough = new Label();
-					mv.visitFieldInsn(GETSTATIC, m.getReplayClassName(), m.getLogFieldName() + "_fill", "I");
-					mv.visitJumpInsn(Opcodes.IF_ICMPNE, fallThrough);
-					mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(ReplayRunner.class), "loadNextLog", "()V");
-					mv.visitInsn(POP);
-					loadReplayIndex(m.getReplayClassName(), m.getLogFieldName());
-
-					mv.visitLabel(fallThrough);
-					arrayLoad(m.getReturnType());
-					incrementReplayIndex(m.getReplayClassName(), m.getLogFieldName());
-				}
-				//Unlock
-				super.visitFieldInsn(GETSTATIC, Type.getInternalName(Log.class), "logLock", Type.getDescriptor(Lock.class));
-				super.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Lock.class), "unlock", "()V");
-
-			} else {
-				super.visitMethodInsn(opcode, owner, name, desc);
-			}
-			pc++;
-		} catch (Exception ex) {
-			logger.error("Unable to instrument method call", ex);
-		}
-	}
-
-	private ArrayList<MethodCall>	methodCallsToClear	= new ArrayList<MethodCall>();
-
-	@Override
-	public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-		super.visitFieldInsn(opcode, owner, name, desc);
-		pc++;
-	}
-
-	@Override
-	public void visitIincInsn(int var, int increment) {
-		super.visitIincInsn(var, increment);
-		pc++;
-	}
-
-	@Override
-	public void visitInsn(int opcode) {
-		super.visitInsn(opcode);
-		pc++;
-	}
-
-	@Override
-	public void visitIntInsn(int opcode, int operand) {
-		super.visitIntInsn(opcode, operand);
-		pc++;
-	}
-
-	@Override
-	public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
-		super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
-		pc++;
-	}
-
-	@Override
-	public void visitJumpInsn(int opcode, Label label) {
-		super.visitJumpInsn(opcode, label);
-		pc++;
-	}
-
-	@Override
-	public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-		super.visitLookupSwitchInsn(dflt, keys, labels);
-		pc++;
-	}
-
-	@Override
-	public void visitMultiANewArrayInsn(String desc, int dims) {
-		super.visitMultiANewArrayInsn(desc, dims);
-		pc++;
-	}
-
-	@Override
-	public void visitTypeInsn(int opcode, String type) {
-		super.visitTypeInsn(opcode, type);
-		pc++;
-	}
-
-	@Override
-	public void visitVarInsn(int opcode, int var) {
-		super.visitVarInsn(opcode, var);
-		pc++;
-	}
-
-	@Override
-	public void visitLdcInsn(Object cst) {
-		super.visitLdcInsn(cst);
-		pc++;
-	}
-
-	@Override
-	public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
-		super.visitTableSwitchInsn(min, max, dflt, labels);
-		pc++;
-	}
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/ReplayRunner.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/ReplayRunner.java
deleted file mode 100644
index ae3b1b2..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/ReplayRunner.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package edu.columbia.cs.psl.invivo.replay;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileWriter;
-import java.io.ObjectInputStream;
-import java.lang.reflect.Array;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-
-import org.objectweb.asm.Type;
-
-import com.thoughtworks.xstream.XStream;
-
-import edu.columbia.cs.psl.invivo.record.CloningUtils;
-import edu.columbia.cs.psl.invivo.record.Constants;
-import edu.columbia.cs.psl.invivo.record.ExportedLog;
-import edu.columbia.cs.psl.invivo.record.ExportedSerializableLog;
-import edu.columbia.cs.psl.invivo.record.Log;
-import edu.columbia.cs.psl.invivo.record.xstream.StaticReflectionProvider;
-
-public class ReplayRunner {
-	public static String[] logFiles;
-	public static String[] serializableLogFiles;
-
-	private static int nextLog = 0;
-	private static int nextSerializableLog = 0;
-
-	public static void loadNextLog(String logClass) {
-		try {
-			Log.logLock.lock();
-			_loadNextLog(logClass);
-			Log.logLock.unlock();
-		} catch (Exception exi) {
-			exi.printStackTrace();
-		}
-	}
-
-	private static void _loadNextLog(String logClass) {
-		try {
-			if (logClass.contains("Serializable")) {
-				ObjectInputStream is = new ObjectInputStream(new FileInputStream(serializableLogFiles[nextSerializableLog]));
-				ExportedSerializableLog el = (ExportedSerializableLog) is.readObject();
-				nextSerializableLog++;
-			} else {
-				XStream xstream = new XStream(new StaticReflectionProvider());
-				Object o = xstream.fromXML(new File(logFiles[nextLog]));
-				nextLog++;
-			}
-		} catch (Exception exi) {
-			exi.printStackTrace();
-		}
-	}
-
-	public static void main(String[] args) {
-		if (args.length < 2) {
-			System.err.println("Usage: ReplayRunner <mainClass> log [log2...logN] class_args [arg1...argM]");
-			System.exit(-1);
-		}
-		String mainClass = args[0];
-		logFiles = new String[args.length - 1];
-		serializableLogFiles = new String[args.length - 1];
-		int class_args = args.length;
-		int nLogs = 0;
-		int nSerializableLogs = 0;
-
-		for (int i = 1; i < args.length; i++) {
-			if (!args[i].equals("class_args"))
-				if (args[i].contains("_serializable_")) {
-					serializableLogFiles[nSerializableLogs] = args[i];
-					nSerializableLogs++;
-				} else {
-					logFiles[nLogs] = args[i];
-					nLogs++;
-				}
-			else {
-				class_args = i + 1;
-				break;
-			}
-		}
-
-		System.out.println("Available logs: " + Arrays.deepToString(logFiles));
-		_loadNextLog(Type.getDescriptor(ExportedLog.class));
-		_loadNextLog(Type.getDescriptor(ExportedSerializableLog.class));
-		Class<?> toRun;
-		try {
-			toRun = Class.forName(mainClass);
-			Method meth = toRun.getMethod("main", String[].class);
-			String[] params = new String[args.length - class_args];
-			if (class_args < args.length)
-				System.arraycopy(args, class_args, params, 0, params.length);
-			meth.invoke(null, new Object[] { params });
-		} catch (ClassNotFoundException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (IllegalArgumentException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (SecurityException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (IllegalAccessException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (InvocationTargetException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (NoSuchMethodException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	}
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/Replayer.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/Replayer.java
deleted file mode 100644
index 043a2a3..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/Replayer.java
+++ /dev/null
@@ -1,426 +0,0 @@
-package edu.columbia.cs.psl.invivo.replay;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.nio.channels.FileChannel;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Scanner;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.jar.JarOutputStream;
-
-import org.apache.log4j.Logger;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.commons.GeneratorAdapter;
-import org.objectweb.asm.tree.ClassNode;
-import org.objectweb.asm.tree.FieldNode;
-import org.objectweb.asm.util.CheckClassAdapter;
-
-import edu.columbia.cs.psl.invivo.record.Constants;
-import edu.columbia.cs.psl.invivo.record.InstrumenterClassWriter;
-import edu.columbia.cs.psl.invivo.record.MethodCall;
-import edu.columbia.cs.psl.invivo.record.analysis.MutabilityAnalyzer;
-import edu.columbia.cs.psl.invivo.record.struct.AnnotatedMethod;
-
-public class Replayer {
-	public static URLClassLoader loader;
-	private static Logger logger = Logger.getLogger(Replayer.class);
-	public static HashMap<String, AnnotatedMethod> annotatedMethods = new HashMap<String, AnnotatedMethod>();
-	public static HashMap<String, ClassNode> instrumentedClasses = new HashMap<String, ClassNode>();
-
-	private static MutabilityAnalyzer ma = new MutabilityAnalyzer(
-			annotatedMethods);
-	private static HashMap<String, HashSet<MethodCall>> methodCalls = new HashMap<String, HashSet<MethodCall>>();
-	private static final int NUM_PASSES = 2;
-	private static final int PASS_ANALYZE = 0;
-	private static final int PASS_OUTPUT = 1;
-
-	private static int pass_number = 0;
-
-	private static File rootOutputDir;
-	private static String lastInstrumentedClass;
-
-	public static AnnotatedMethod getAnnotatedMethod(String owner, String name,
-			String desc) {
-		String lookupKey = owner + "." + name + ":" + desc;
-		return annotatedMethods.get(lookupKey);
-	}
-
-	private static void analyzeClass(InputStream inputStream) {
-		try {
-			ClassNode ret = ma.analyzeClass(new ClassReader(inputStream));
-			instrumentedClasses.put(ret.name, ret);
-		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	}
-
-	private static void finishedPass() {
-		switch (pass_number) {
-		case PASS_ANALYZE:
-			ma.doneSupplyingClasses();
-			break;
-		case PASS_OUTPUT:
-			break;
-		}
-	}
-
-	/*
-	 * private static byte[] generateReplayClass(String className) { ClassWriter
-	 * cw = new InstrumenterClassWriter(ClassWriter.COMPUTE_MAXS |
-	 * ClassWriter.COMPUTE_FRAMES, loader); cw.visit(49, Opcodes.ACC_PUBLIC,
-	 * className+Constants.LOG_CLASS_SUFFIX, null, "java/lang/Object", null);
-	 * cw.visitSource(null, null); MethodVisitor mv =
-	 * cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "<clinit>",
-	 * "()V", null, null); GeneratorAdapter mvz = new GeneratorAdapter(mv,
-	 * Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "<clinit>", "()V");
-	 * mvz.visitCode(); for (MethodCall call : methodCalls.get(className)) {
-	 * mvz.push(Constants.DEFAULT_LOG_SIZE);
-	 * mvz.newArray(Type.getMethodType(call.getMethodDesc()).getReturnType());
-	 * mvz.putStatic(Type.getType("L"+className +
-	 * Constants.LOG_CLASS_SUFFIX+";"), call.getLogFieldName(), Type.getType("["
-	 * +
-	 * Type.getMethodType(call.getMethodDesc()).getReturnType().getDescriptor()
-	 * ));
-	 *
-	 * Type[] argTypes = Type.getArgumentTypes(call.getMethodDesc()); for(int i
-	 * = 0; i < argTypes.length; i++) { if(argTypes[i].getSort() == Type.ARRAY)
-	 * { mvz.push(Constants.DEFAULT_LOG_SIZE); mvz.newArray(argTypes[i]);
-	 * mvz.putStatic(Type.getType("L"+className +
-	 * Constants.LOG_CLASS_SUFFIX+";"), call.getLogFieldName() + "_"+i,
-	 * Type.getType("[" + argTypes[i].getDescriptor())); } } } mvz.visitMaxs(0,
-	 * 0); mvz.returnValue(); mvz.visitEnd();
-	 *
-	 * { mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
-	 * mv.visitVarInsn(Opcodes.ALOAD, 0);
-	 * mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>",
-	 * "()V"); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(1, 1); mv.visitEnd();
-	 * } for (MethodCall call : methodCalls.get(className)) { int opcode =
-	 * Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC; FieldNode fn = new
-	 * FieldNode(Opcodes.ASM4, opcode, call.getLogFieldName(), "[" +
-	 * Type.getMethodType(call.getMethodDesc()).getReturnType().getDescriptor(),
-	 * null, null); fn.accept(cw); FieldNode fn2 = new FieldNode(Opcodes.ASM4,
-	 * opcode, call.getLogFieldName() + "_fill", Type.INT_TYPE.getDescriptor(),
-	 * null, 0); fn2.accept(cw);
-	 *
-	 * Type[] argTypes = Type.getArgumentTypes(call.getMethodDesc()); for(int i
-	 * = 0; i < argTypes.length; i++) { if(argTypes[i].getSort() == Type.ARRAY)
-	 * { fn = new FieldNode(Opcodes.ASM4, opcode, call.getLogFieldName()+"_"+i,
-	 * "[" + argTypes[i].getDescriptor(), null, null); fn.accept(cw); fn2 = new
-	 * FieldNode(Opcodes.ASM4, opcode, call.getLogFieldName()+"_"+i + "_fill",
-	 * Type.INT_TYPE.getDescriptor(), null, 0); fn2.accept(cw);
-	 *
-	 * mvz.push(Constants.DEFAULT_LOG_SIZE); mvz.newArray(argTypes[i]);
-	 * mvz.putStatic(Type.getType("L"+className +
-	 * Constants.LOG_CLASS_SUFFIX+";"), call.getLogFieldName() + i,
-	 * Type.getType("[" + argTypes[i].getDescriptor())); }
-	 *
-	 * } } cw.visitEnd(); System.out.println("We are on: " + className); return
-	 * cw.toByteArray(); }
-	 */
-
-
-	private static byte[] instrumentClass(InputStream is) {
-		try {
-			ClassReader cr = new ClassReader(is);
-			ClassWriter cw = new InstrumenterClassWriter(cr,
-					ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES,
-					loader);
-			NonDeterministicReplayClassVisitor cv = new NonDeterministicReplayClassVisitor(
-					Opcodes.ASM4, cw);
-			cr.accept(cv, ClassReader.EXPAND_FRAMES);
-			methodCalls.put(cv.getClassName(), cv.getLoggedMethodCalls());
-			lastInstrumentedClass = cv.getClassName();
-			byte[] out = cw.toByteArray();
-			try{
-				 ClassReader cr2 = new ClassReader(out);
-				 cr2.accept(new CheckClassAdapter(new ClassWriter(0)), 0);
-				}
-				catch(Exception ex)
-				{
-					System.err.println(lastInstrumentedClass);
-					ex.printStackTrace();
-				}
-
-			return out;
-		} catch (Exception ex) {
-			logger.error("Exception processing class:", ex);
-			return null;
-		}
-	}
-
-	public static void main(String[] args) {
-		if (args.length <= 1) {
-			System.err
-					.println("Usage: java edu.columbia.cs.psl.invivo.record.Instrumenter [outputFolder] [inputfolder] [classpath]\n Paths can be classes, directories, or jar files");
-			System.exit(-1);
-		}
-		String outputFolder = args[0];
-		rootOutputDir = new File(outputFolder);
-		if (!rootOutputDir.exists())
-			rootOutputDir.mkdir();
-		String inputFolder = args[1];
-		// Setup the class loader
-		URL[] urls = new URL[args.length - 2];
-		for (int i = 2; i < args.length; i++) {
-			File f = new File(args[i]);
-			if (!f.exists()) {
-				System.err.println("Unable to read path " + args[i]);
-				System.exit(-1);
-			}
-			if (f.isDirectory() && !f.getAbsolutePath().endsWith("/"))
-				f = new File(f.getAbsolutePath() + "/");
-			try {
-				urls[i - 2] = f.getCanonicalFile().toURI().toURL();
-			} catch (Exception ex) {
-				ex.printStackTrace();
-			}
-		}
-		loader = new URLClassLoader(urls, Replayer.class.getClassLoader());
-
-		for (pass_number = 0; pass_number < NUM_PASSES; pass_number++) // Do
-																		// each
-																		// pass.
-		{
-			File f = new File(inputFolder);
-			if (!f.exists()) {
-				System.err.println("Unable to read path " + inputFolder);
-				System.exit(-1);
-			}
-			if (f.isDirectory())
-				processDirectory(f, rootOutputDir, true);
-			else if (inputFolder.endsWith(".jar"))
-				processJar(f, rootOutputDir);
-			else if (inputFolder.endsWith(".class"))
-				try {
-					processClass(f.getName(), new FileInputStream(f),
-							rootOutputDir);
-				} catch (FileNotFoundException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				}
-			else {
-				System.err.println("Unknown type for path " + inputFolder);
-				System.exit(-1);
-			}
-			finishedPass();
-		}
-		// }
-
-	}
-
-	private static void processClass(String name, InputStream is, File outputDir) {
-		ByteArrayOutputStream bos = null;
-		FileOutputStream fos = null;
-
-		switch (pass_number) {
-		case PASS_ANALYZE:
-			analyzeClass(is);
-			break;
-		case PASS_OUTPUT:
-			try {
-				File f = new File(outputDir.getPath()
-						+ File.separator + name);
-				if(f.exists())
-					f.delete();
-				fos = new FileOutputStream(f);
-				bos = new ByteArrayOutputStream();
-				bos.write(instrumentClass(is));
-
-//				if (name.contains("Reader")) {
-//					ReplayRunner.run(bos.toByteArray(), "ReaderUser");
-//				}
-
-			} catch (Exception ex) {
-				ex.printStackTrace();
-				System.exit(-1);
-			} finally {
-				try {
-					bos.writeTo(fos);
-					fos.close();
-				} catch (IOException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				}
-			}
-		}
-	}
-
-	/*
-	 * private static byte[] generateReplayClass() { return
-	 * generateReplayClass(lastInstrumentedClass); }
-	 */
-
-	private static void processDirectory(File f, File parentOutputDir,
-			boolean isFirstLevel) {
-		File thisOutputDir;
-		if (isFirstLevel) {
-			thisOutputDir = parentOutputDir;
-		} else {
-			thisOutputDir = new File(parentOutputDir.getAbsolutePath()
-					+ File.separator + f.getName());
-			if (pass_number == PASS_OUTPUT)
-				thisOutputDir.mkdir();
-		}
-		for (File fi : f.listFiles()) {
-			if (fi.isDirectory())
-				processDirectory(fi, thisOutputDir, false);
-			else if (fi.getName().endsWith(".class"))
-				try {
-					processClass(fi.getName(), new FileInputStream(fi),
-							thisOutputDir);
-				} catch (FileNotFoundException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				}
-			else if (fi.getName().endsWith(".jar"))
-				processJar(fi, thisOutputDir);
-			else if (pass_number == PASS_OUTPUT) {
-				File dest = new File(thisOutputDir.getPath() + File.separator
-						+ fi.getName());
-				FileChannel source = null;
-				FileChannel destination = null;
-
-				try {
-					source = new FileInputStream(fi).getChannel();
-					destination = new FileOutputStream(dest).getChannel();
-					destination.transferFrom(source, 0, source.size());
-				} catch (Exception ex) {
-					logger.error("Unable to copy file " + fi, ex);
-					System.exit(-1);
-				} finally {
-					if (source != null) {
-						try {
-							source.close();
-						} catch (IOException e) {
-							// TODO Auto-generated catch block
-							e.printStackTrace();
-						}
-					}
-					if (destination != null) {
-						try {
-							destination.close();
-						} catch (IOException e) {
-							// TODO Auto-generated catch block
-							e.printStackTrace();
-						}
-					}
-				}
-
-			}
-		}
-
-	}
-
-	private static void processJar(File f, File outputDir) {
-		try {
-			JarFile jar = new JarFile(f);
-			JarOutputStream jos = null;
-			if (pass_number == PASS_OUTPUT)
-				jos = new JarOutputStream(new FileOutputStream(
-						outputDir.getPath() + File.separator + f.getName()));
-			Enumeration<JarEntry> entries = jar.entries();
-			while (entries.hasMoreElements()) {
-				JarEntry e = entries.nextElement();
-				switch (pass_number) {
-				case PASS_ANALYZE:
-					if (e.getName().endsWith(".class")) {
-						analyzeClass(jar.getInputStream(e));
-					}
-					break;
-				case PASS_OUTPUT:
-					if (e.getName().endsWith(".class")
-							&& !e.getName().startsWith("java")
-							&& !e.getName().startsWith("org/objenesis")
-							&& !e.getName().startsWith(
-									"com/thoughtworks/xstream/")
-							&& !e.getName().startsWith("com/rits/cloning")
-							&& !e.getName().startsWith(
-									"com/apple/java/Application")) {
-						{
-							JarEntry outEntry = new JarEntry(e.getName());
-							jos.putNextEntry(outEntry);
-							byte[] clazz = instrumentClass(jar
-									.getInputStream(e));
-							jos.write(clazz);
-							jos.closeEntry();
-						}
-						{
-							/*
-							 * JarEntry outEntry = new
-							 * JarEntry(e.getName().replace(".class",
-							 * Constants.LOG_CLASS_SUFFIX +".class"));
-							 * jos.putNextEntry(outEntry); byte[] clazz =
-							 * generateReplayClass(); jos.write(clazz);
-							 * jos.closeEntry();
-							 */
-						}
-
-					} else {
-						JarEntry outEntry = new JarEntry(e.getName());
-						if (e.isDirectory()) {
-							jos.putNextEntry(outEntry);
-							jos.closeEntry();
-						} else if (e.getName().startsWith("META-INF")
-								&& (e.getName().endsWith(".SF") || e.getName()
-										.endsWith(".RSA"))) {
-							// don't copy this
-						} else if (e.getName().equals("META-INF/MANIFEST.MF")) {
-							String newManifest = "";
-							Scanner s = new Scanner(jar.getInputStream(e));
-							jos.putNextEntry(outEntry);
-
-							String curPair = "";
-							while (s.hasNextLine()) {
-								String line = s.nextLine();
-								if (line.equals("")) {
-									curPair += "\n";
-									if (!curPair.contains("SHA1-Digest:"))
-										jos.write(curPair.getBytes());
-									curPair = "";
-								} else {
-									curPair += line + "\n";
-								}
-							}
-							jos.write("\n".getBytes());
-							jos.closeEntry();
-						} else {
-							jos.putNextEntry(outEntry);
-							InputStream is = jar.getInputStream(e);
-							byte[] buffer = new byte[1024];
-							while (true) {
-								int count = is.read(buffer);
-								if (count == -1)
-									break;
-								jos.write(buffer, 0, count);
-							}
-							jos.closeEntry();
-						}
-					}
-				}
-
-			}
-			if (pass_number == PASS_OUTPUT) {
-				jos.close();
-			}
-		} catch (Exception e) {
-			// TODO Auto-generated catch block
-			logger.error("Unable to process jar" + f, e);
-			System.exit(-1);
-		}
-
-	}
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/sample/OtherClass.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/sample/OtherClass.java
deleted file mode 100644
index 38db3c2..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/sample/OtherClass.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package edu.columbia.cs.psl.invivo.sample;
-
-import java.io.File;
-
-public class OtherClass {
-	public SimpleClass c;
-
-	public OtherClass()
-	{
-
-	}
-	public OtherClass(SimpleClass c)
-	{
-		this.c = c;
-	}
-	public void setFileAttribute(SimpleClass c)
-	{
-		c.f = new File("log4j.properties");
-	}
-	public void thinkAboutThings()
-	{
-		getSimpleClass().evil(this);
-	}
-	public void setFileAttribute()
-	{
-		c.f = new File("log4j.properties");
-	}
-	public SimpleClass getSimpleClass(SimpleClass c)
-	{
-		return c;
-	}
-	public SimpleClass getSimpleClass() {
-		// TODO Auto-generated method stub
-		return c;
-	}
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/sample/SimpleClass.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/sample/SimpleClass.java
deleted file mode 100644
index a2c36c2..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/sample/SimpleClass.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package edu.columbia.cs.psl.invivo.sample;
-
-import java.io.File;
-
-public class SimpleClass {
-	public File f;
-	public static void main(String[] args) {
-		new SimpleClass().go();
-	}
-	public SimpleClass()
-	{
-
-	}
-	public SimpleClass(String s)
-	{
-
-	}
-	private void go()
-	{
-		o = new OtherClass();
-	}
-	public OtherClass o;
-	public OtherClass o2;
-	public void evil(OtherClass o1)
-	{
-		OtherClass z = getOtherClass();
-		z.c.f = new File("b"); //copy z.c.f onto this object, and a ref to z.c
-
-		o1 = o2; //made copy of o1 NB onto this object
-		o1.c.f = new File("s"); //make copy of o1.c.f onto this object
-		o1.c.f = new File("z"); //make copy
-	}
-	private OtherClass getOtherClass()
-	{
-		if(Math.random() > .5)
-			return o2;
-		else if(Math.random() < .4)
-			return o.getSimpleClass().o;
-		return o;
-	}
-	public void makeCrash()
-	{
-		//record counters for each array of backups that we think we might touch, with the references
-		evil(o);
-		getOtherClass().thinkAboutThings();
-		if(o.c.f.equals("something bad"))
-			System.out.println("Crash");
-	}
-	public void doSomething()
-	{
-		OtherClass o = new OtherClass(this);
-		o.setFileAttribute();
-//		new OtherClass().setFileAttribute(this);
-//		new OtherClass().getSimpleClass(this).f = new File("sdf");
-//		new OtherClass(new SimpleClass("a")).c = this;
-//		getOtherClass().getSimpleClass(getOtherClass().c).f = new File("sdf");
-		getOtherClass().getSimpleClass(new OtherClass().getSimpleClass(new SimpleClass())).f = new File("stuff");
-//		OtherClass o = new OtherClass();
-
-//		new OtherClass().c.f = new File("sdf");
-	}
-	public SimpleClass setFieldsOn(SimpleClass ret) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/CloningUtils.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/CloningUtils.java
new file mode 100644
index 0000000..a611596
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/CloningUtils.java
@@ -0,0 +1,81 @@
+package edu.columbia.cs.psl.wallace;
+
+import java.io.BufferedWriter;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.URI;
+import java.nio.channels.Channel;
+import java.security.Permissions;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import com.rits.cloning.Cloner;
+
+public class CloningUtils {
+	public static boolean				CATCH_ALL_ERRORS	= true;
+	private static Cloner				cloner				= new Cloner();
+	public static ReadWriteLock		exportLock			= new ReentrantReadWriteLock();
+	private static HashSet<Class<?>>	moreIgnoredImmutables;
+	private static HashSet<Class<?>>	nullInsteads;
+
+//	private static BufferedWriter		log;
+	static {
+		moreIgnoredImmutables = new HashSet<Class<?>>();
+		moreIgnoredImmutables.add(ClassLoader.class);
+		moreIgnoredImmutables.add(Thread.class);
+		moreIgnoredImmutables.add(URI.class);
+		moreIgnoredImmutables.add(File.class);
+		moreIgnoredImmutables.add(ZipFile.class);
+		moreIgnoredImmutables.add(ZipEntry.class);
+		moreIgnoredImmutables.add(Inflater.class);
+		moreIgnoredImmutables.add(InputStream.class);
+		moreIgnoredImmutables.add(OutputStream.class);
+		moreIgnoredImmutables.add(Deflater.class);
+		moreIgnoredImmutables.add(Socket.class);
+		moreIgnoredImmutables.add(ServerSocket.class);
+		moreIgnoredImmutables.add(Channel.class);
+		moreIgnoredImmutables.add(Closeable.class);
+		moreIgnoredImmutables.add(Class.class);
+		cloner.setExtraNullInsteadOfClone(moreIgnoredImmutables);
+		cloner.setExtraImmutables(moreIgnoredImmutables);
+
+		nullInsteads = new HashSet<Class<?>>();
+		nullInsteads.add(Permissions.class);
+		cloner.setExtraNullInsteadOfClone(nullInsteads);
+//		cloner.setDumpClonedClasses(true);
+		WallaceExportRunner.inst.start();
+		if (CATCH_ALL_ERRORS) {
+			Thread.setDefaultUncaughtExceptionHandler(new WallaceUncaughtExceptionHandler());
+		}
+//		try {
+//			File f = new File("cloneLog");
+//			if (f.exists())
+//				f.delete();
+//			log = new BufferedWriter(new FileWriter("cloneLog"));
+//		} catch (IOException e) {
+//			// TODO Auto-generated catch block
+//			e.printStackTrace();
+//		}
+	}
+
+	public static final <T> T clone(T obj, String debug) {
+// 		System.out.println("source>"+debug);
+			return cloner.deepClone(obj);
+	}
+
+	public static IdentityHashMap<Object, Object>	cloneCache	= new IdentityHashMap<Object, Object>();	;
+
+
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/Constants.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/Constants.java
new file mode 100644
index 0000000..065fbf4
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/Constants.java
@@ -0,0 +1,14 @@
+package edu.columbia.cs.psl.wallace;
+
+public interface Constants {
+
+	public static int DEFAULT_LOG_SIZE = 2000;
+	public static int MAX_LOG_SIZE = 40000000;
+	public static int VERY_MAX_LOG_SIZE = 400000000;
+
+	public static double LOG_GROWTH_RATE = 2.5;
+	public static String REPLAY_CLASS_SUFFIX = "InvivoReplay";
+	public static String INNER_COPY_METHOD_NAME = "_Invivo___copy";
+	public static String OUTER_COPY_METHOD_NAME = "_Invivo_copy";
+	public static String SET_FIELDS_METHOD_NAME = "_Invivo_set_fields";
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/ExportedLog.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/ExportedLog.java
new file mode 100644
index 0000000..b6945cc
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/ExportedLog.java
@@ -0,0 +1,16 @@
+package edu.columbia.cs.psl.wallace;
+
+import java.util.HashMap;
+
+public class ExportedLog {
+	public static Object[] aLog = new Object[Constants.DEFAULT_LOG_SIZE];
+	public static String[] aLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+
+	public static int aLog_fill;
+	public static HashMap<String, Integer> aLog_replayIndex = new HashMap<String, Integer>();
+	public static void clearLog() {
+		aLog = new Object[Constants.DEFAULT_LOG_SIZE];
+		aLog_owners =  new String[Constants.DEFAULT_LOG_SIZE];
+		aLog_fill = 0;
+	}
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/ExportedSerializableLog.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/ExportedSerializableLog.java
new file mode 100644
index 0000000..5ee9d0a
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/ExportedSerializableLog.java
@@ -0,0 +1,125 @@
+package edu.columbia.cs.psl.wallace;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.HashMap;
+
+public class ExportedSerializableLog implements Serializable {
+	/**
+	 *
+	 */
+	private static final long serialVersionUID = 1166783255069514273L;
+	public static Object[]	aLog	= new Object[Constants.DEFAULT_LOG_SIZE];
+	public static int[] iLog = new int[Constants.DEFAULT_LOG_SIZE];
+	public static long[] jLog = new long[Constants.DEFAULT_LOG_SIZE];
+	public static float[] fLog = new float[Constants.DEFAULT_LOG_SIZE];
+	public static double[] dLog = new double[Constants.DEFAULT_LOG_SIZE];
+	public static byte[] bLog = new byte[Constants.DEFAULT_LOG_SIZE];
+	public static boolean[] zLog = new boolean[Constants.DEFAULT_LOG_SIZE];
+	public static char[] cLog = new char[Constants.DEFAULT_LOG_SIZE];
+	public static short[] sLog = new short[Constants.DEFAULT_LOG_SIZE];
+	public static Object lock = new Object();
+	public static int aLog_fill, iLog_fill, jLog_fill, fLog_fill, dLog_fill, bLog_fill, zLog_fill, cLog_fill, sLog_fill;
+
+	public static HashMap<String,Integer> aLog_replayIndex = new HashMap<String,Integer>();
+	public static HashMap<String,Integer> iLog_replayIndex = new HashMap<String,Integer>();
+	public static HashMap<String,Integer> jLog_replayIndex = new HashMap<String,Integer>();
+	public static HashMap<String,Integer> fLog_replayIndex = new HashMap<String,Integer>();
+	public static HashMap<String,Integer> dLog_replayIndex = new HashMap<String,Integer>();
+	public static HashMap<String,Integer> bLog_replayIndex = new HashMap<String,Integer>();
+	public static HashMap<String,Integer> zLog_replayIndex = new HashMap<String,Integer>();
+	public static HashMap<String,Integer> cLog_replayIndex = new HashMap<String,Integer>();
+	public static HashMap<String,Integer> sLog_replayIndex = new HashMap<String,Integer>();
+
+	public static String[] aLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+	public static String[] iLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+	public static String[] jLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+	public static String[] fLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+	public static String[] dLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+	public static String[] bLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+	public static String[] zLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+	public static String[] cLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+	public static String[] sLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+
+	public static void clearLog() {
+		aLog = new Serializable[Constants.DEFAULT_LOG_SIZE];
+		aLog_fill = 0;
+	}
+
+	private void writeObject(ObjectOutputStream oos) throws IOException {
+		oos.defaultWriteObject();
+		oos.writeInt(aLog_fill);
+		oos.writeObject(aLog);
+		oos.writeInt(iLog_fill);
+		oos.writeObject(iLog);
+		oos.writeInt(jLog_fill);
+		oos.writeObject(jLog);
+		oos.writeInt(fLog_fill);
+		oos.writeObject(fLog);
+		oos.writeInt(dLog_fill);
+		oos.writeObject(dLog);
+		oos.writeInt(bLog_fill);
+		oos.writeObject(bLog);
+		oos.writeInt(zLog_fill);
+		oos.writeObject(zLog);
+		oos.writeInt(cLog_fill);
+		oos.writeObject(cLog);
+		oos.writeInt(sLog_fill);
+		oos.writeObject(sLog);
+
+		oos.writeObject(aLog_owners);
+		oos.writeObject(iLog_owners);
+		oos.writeObject(jLog_owners);
+		oos.writeObject(fLog_owners);
+		oos.writeObject(dLog_owners);
+		oos.writeObject(bLog_owners);
+		oos.writeObject(zLog_owners);
+		oos.writeObject(cLog_owners);
+		oos.writeObject(sLog_owners);
+
+	}
+
+	private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+		ois.defaultReadObject();
+		aLog_fill = ois.readInt();
+		aLog = (Object[]) ois.readObject();
+		iLog_fill = ois.readInt();
+		iLog = (int[]) ois.readObject();
+		jLog_fill = ois.readInt();
+		jLog = (long[]) ois.readObject();
+		fLog_fill = ois.readInt();
+		fLog = (float[]) ois.readObject();
+		dLog_fill = ois.readInt();
+		dLog = (double[]) ois.readObject();
+		bLog_fill = ois.readInt();
+		bLog = (byte[]) ois.readObject();
+		zLog_fill = ois.readInt();
+		zLog = (boolean[]) ois.readObject();
+		cLog_fill = ois.readInt();
+		cLog = (char[]) ois.readObject();
+		sLog_fill = ois.readInt();
+		sLog = (short[]) ois.readObject();
+
+		aLog_owners = (String[]) ois.readObject();
+		iLog_owners = (String[]) ois.readObject();
+		jLog_owners = (String[]) ois.readObject();
+		fLog_owners = (String[]) ois.readObject();
+		dLog_owners = (String[]) ois.readObject();
+		bLog_owners = (String[]) ois.readObject();
+		zLog_owners = (String[]) ois.readObject();
+		cLog_owners = (String[]) ois.readObject();
+		sLog_owners = (String[]) ois.readObject();
+
+		ExportedSerializableLog.aLog_replayIndex = new HashMap<String,Integer>();
+		ExportedSerializableLog.iLog_replayIndex = new HashMap<String,Integer>();
+		ExportedSerializableLog.jLog_replayIndex = new HashMap<String,Integer>();
+		ExportedSerializableLog.fLog_replayIndex = new HashMap<String,Integer>();
+		ExportedSerializableLog.dLog_replayIndex = new HashMap<String,Integer>();
+		ExportedSerializableLog.bLog_replayIndex = new HashMap<String,Integer>();
+		ExportedSerializableLog.zLog_replayIndex = new HashMap<String,Integer>();
+		ExportedSerializableLog.cLog_replayIndex = new HashMap<String,Integer>();
+		ExportedSerializableLog.sLog_replayIndex = new HashMap<String,Integer>();
+	}
+}
\ No newline at end of file
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/Instrumenter.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/Instrumenter.java
new file mode 100644
index 0000000..61c8c72
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/Instrumenter.java
@@ -0,0 +1,342 @@
+package edu.columbia.cs.psl.wallace;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.channels.FileChannel;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Scanner;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+
+import org.apache.log4j.Logger;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.GeneratorAdapter;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.FieldNode;
+import org.objectweb.asm.util.CheckClassAdapter;
+
+import edu.columbia.cs.psl.wallace.analysis.MutabilityAnalyzer;
+import edu.columbia.cs.psl.wallace.struct.AnnotatedMethod;
+import edu.columbia.cs.psl.wallace.visitor.CloningAdviceAdapter;
+import edu.columbia.cs.psl.wallace.visitor.NonDeterministicLoggingClassVisitor;
+
+public class Instrumenter {
+	public static URLClassLoader						loader;
+	private static Logger								logger				= Logger.getLogger(Instrumenter.class);
+	public static HashMap<String, AnnotatedMethod>		annotatedMethods	= new HashMap<String, AnnotatedMethod>();
+	public static HashMap<String, ClassNode>			instrumentedClasses	= new HashMap<String, ClassNode>();
+
+	private static MutabilityAnalyzer					ma					= new MutabilityAnalyzer(annotatedMethods);
+	private static HashMap<String, HashSet<MethodCall>>	methodCalls			= new HashMap<String, HashSet<MethodCall>>();
+	private static final int							NUM_PASSES			= 2;
+	private static final int							PASS_ANALYZE		= 0;
+	private static final int							PASS_OUTPUT			= 1;
+
+	private static int									pass_number			= 0;
+
+	private static File									rootOutputDir;
+	private static String								lastInstrumentedClass;
+
+	public static AnnotatedMethod getAnnotatedMethod(String owner, String name, String desc) {
+		String lookupKey = owner + "." + name + ":" + desc;
+		return annotatedMethods.get(lookupKey);
+	}
+
+	private static void analyzeClass(InputStream inputStream) {
+		try {
+			ClassNode analysisResult = ma.analyzeClass(new ClassReader(inputStream));
+			instrumentedClasses.put(analysisResult.name, analysisResult);
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	private static void finishedPass() {
+		switch (pass_number) {
+		case PASS_ANALYZE:
+			ma.doneSupplyingClasses();
+			break;
+		case PASS_OUTPUT:
+			break;
+		}
+	}
+
+
+	private static byte[] instrumentClass(InputStream is) {
+		try {
+			ClassReader cr = new ClassReader(is);
+			ClassWriter cw = new InstrumenterClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES, loader);
+			NonDeterministicLoggingClassVisitor cv = new NonDeterministicLoggingClassVisitor(Opcodes.ASM4, cw);
+
+			cr.accept(cv, ClassReader.EXPAND_FRAMES);
+			if(methodCalls.containsKey(cv.getClassName()))
+				methodCalls.get(cv.getClassName()).addAll(cv.getLoggedMethodCalls());
+			else
+				methodCalls.put(cv.getClassName(), cv.getLoggedMethodCalls());
+			lastInstrumentedClass = cv.getClassName();
+			byte[] out = cw.toByteArray();
+			try{
+			 ClassReader cr2 = new ClassReader(out);
+			 cr2.accept(new CheckClassAdapter(new ClassWriter(0)), ClassReader.EXPAND_FRAMES);
+			}
+			catch(Exception ex)
+			{
+				System.err.println(lastInstrumentedClass);
+				ex.printStackTrace();
+			}
+			return out;
+		} catch (Exception ex) {
+			logger.error("Exception processing class: " + lastInstrumentedClass, ex);
+			return null;
+		}
+	}
+
+	public static void main(String[] args) {
+		if (args.length <= 1) {
+			System.err
+					.println("Usage: java edu.columbia.cs.psl.invivo.record.Instrumenter [outputFolder] [inputfolder] [classpath]\n Paths can be classes, directories, or jar files");
+			System.exit(-1);
+		}
+		String outputFolder = args[0];
+		rootOutputDir = new File(outputFolder);
+		if (!rootOutputDir.exists())
+			rootOutputDir.mkdir();
+		String inputFolder = args[1];
+		// Setup the class loader
+		URL[] urls = new URL[args.length - 2];
+		for (int i = 2; i < args.length; i++) {
+			File f = new File(args[i]);
+			if (!f.exists()) {
+				System.err.println("Unable to read path " + args[i]);
+				System.exit(-1);
+			}
+			if (f.isDirectory() && !f.getAbsolutePath().endsWith("/"))
+				f = new File(f.getAbsolutePath() + "/");
+			try {
+				urls[i - 2] = f.getCanonicalFile().toURI().toURL();
+			} catch (Exception ex) {
+				ex.printStackTrace();
+			}
+		}
+		loader = new URLClassLoader(urls, Instrumenter.class.getClassLoader());
+
+		for (pass_number = 0; pass_number < NUM_PASSES; pass_number++) // Do
+																		// each
+																		// pass.
+		{
+			File f = new File(inputFolder);
+			if (!f.exists()) {
+				System.err.println("Unable to read path " + inputFolder);
+				System.exit(-1);
+			}
+			if (f.isDirectory())
+				processDirectory(f, rootOutputDir, true);
+			else if (inputFolder.endsWith(".jar"))
+				processJar(f, rootOutputDir);
+			else if (inputFolder.endsWith(".class"))
+				try {
+					processClass(f.getName(), new FileInputStream(f), rootOutputDir);
+				} catch (FileNotFoundException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			else {
+				System.err.println("Unknown type for path " + inputFolder);
+				System.exit(-1);
+			}
+			finishedPass();
+		}
+		// }
+
+	}
+
+	private static void processClass(String name, InputStream is, File outputDir) {
+		switch (pass_number) {
+		case PASS_ANALYZE:
+			analyzeClass(is);
+			break;
+		case PASS_OUTPUT:
+			try {
+					FileOutputStream fos = new FileOutputStream(outputDir.getPath() + File.separator + name);
+					ByteArrayOutputStream bos = new ByteArrayOutputStream();
+					bos.write(instrumentClass(is));
+					bos.writeTo(fos);
+					fos.close();
+
+
+			} catch (Exception ex) {
+				ex.printStackTrace();
+			}
+		}
+	}
+
+
+
+	private static void processDirectory(File f, File parentOutputDir, boolean isFirstLevel) {
+		File thisOutputDir;
+		if (isFirstLevel) {
+			thisOutputDir = parentOutputDir;
+		} else {
+			thisOutputDir = new File(parentOutputDir.getAbsolutePath() + File.separator + f.getName());
+			if (pass_number == PASS_OUTPUT)
+				thisOutputDir.mkdir();
+		}
+		for (File fi : f.listFiles()) {
+			if (fi.isDirectory())
+				processDirectory(fi, thisOutputDir, false);
+			else if (fi.getName().endsWith(".class"))
+				try {
+					processClass(fi.getName(), new FileInputStream(fi), thisOutputDir);
+				} catch (FileNotFoundException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			else if (fi.getName().endsWith(".jar"))
+				processJar(fi, thisOutputDir);
+			else if (pass_number == PASS_OUTPUT) {
+				File dest = new File(thisOutputDir.getPath() + File.separator + fi.getName());
+				FileChannel source = null;
+				FileChannel destination = null;
+
+				try {
+					source = new FileInputStream(fi).getChannel();
+					destination = new FileOutputStream(dest).getChannel();
+					destination.transferFrom(source, 0, source.size());
+				} catch (Exception ex) {
+					logger.error("Unable to copy file " + fi, ex);
+					System.exit(-1);
+				} finally {
+					if (source != null) {
+						try {
+							source.close();
+						} catch (IOException e) {
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						}
+					}
+					if (destination != null) {
+						try {
+							destination.close();
+						} catch (IOException e) {
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						}
+					}
+				}
+
+			}
+		}
+
+	}
+
+	private static void processJar(File f, File outputDir) {
+		try {
+			JarFile jar = new JarFile(f);
+			JarOutputStream jos = null;
+			if (pass_number == PASS_OUTPUT)
+				jos = new JarOutputStream(new FileOutputStream(outputDir.getPath() + File.separator + f.getName()));
+			Enumeration<JarEntry> entries = jar.entries();
+			while (entries.hasMoreElements()) {
+				JarEntry e = entries.nextElement();
+				switch (pass_number) {
+				case PASS_ANALYZE:
+					if (e.getName().endsWith(".class")) {
+						analyzeClass(jar.getInputStream(e));
+					}
+					break;
+				case PASS_OUTPUT:
+					if (e.getName().endsWith(".class") && !e.getName().startsWith("java") && !e.getName().startsWith("org/objenesis")
+							&& !e.getName().startsWith("com/thoughtworks/xstream/") && !e.getName().startsWith("com/rits/cloning")
+							&& !e.getName().startsWith("com/apple/java/Application")) {
+						{
+							JarEntry outEntry = new JarEntry(e.getName());
+							jos.putNextEntry(outEntry);
+							byte[] clazz = instrumentClass(jar.getInputStream(e));
+							if(clazz == null)
+							{
+								InputStream is = jar.getInputStream(e);
+								byte[] buffer = new byte[1024];
+								while (true) {
+									int count = is.read(buffer);
+									if (count == -1)
+										break;
+									jos.write(buffer, 0, count);
+								}
+							}
+							else
+									jos.write(clazz);
+							jos.closeEntry();
+						}
+
+
+					} else {
+						JarEntry outEntry = new JarEntry(e.getName());
+						if (e.isDirectory()) {
+							jos.putNextEntry(outEntry);
+							jos.closeEntry();
+						} else if (e.getName().startsWith("META-INF") && (e.getName().endsWith(".SF") || e.getName().endsWith(".RSA"))) {
+							// don't copy this
+						} else if (e.getName().equals("META-INF/MANIFEST.MF")) {
+							String newManifest = "";
+							Scanner s = new Scanner(jar.getInputStream(e));
+							jos.putNextEntry(outEntry);
+
+							String curPair = "";
+							while (s.hasNextLine()) {
+								String line = s.nextLine();
+								if (line.equals("")) {
+									curPair += "\n";
+									if (!curPair.contains("SHA1-Digest:"))
+										jos.write(curPair.getBytes());
+									curPair = "";
+								} else {
+									curPair += line + "\n";
+								}
+							}
+							jos.write("\n".getBytes());
+							jos.closeEntry();
+						} else {
+							jos.putNextEntry(outEntry);
+							InputStream is = jar.getInputStream(e);
+							byte[] buffer = new byte[1024];
+							while (true) {
+								int count = is.read(buffer);
+								if (count == -1)
+									break;
+								jos.write(buffer, 0, count);
+							}
+							jos.closeEntry();
+						}
+					}
+				}
+
+			}
+			if (pass_number == PASS_OUTPUT) {
+				jos.close();
+			}
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			logger.error("Unable to process jar" + f, e);
+			System.exit(-1);
+		}
+
+	}
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/InstrumenterClassWriter.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/InstrumenterClassWriter.java
new file mode 100644
index 0000000..05ec18a
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/InstrumenterClassWriter.java
@@ -0,0 +1,48 @@
+package edu.columbia.cs.psl.wallace;
+
+import java.net.URLClassLoader;
+
+import org.apache.log4j.Logger;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+
+public class InstrumenterClassWriter extends ClassWriter {
+	private static Logger logger = Logger.getLogger(InstrumenterClassWriter.class);
+	private ClassLoader loader;
+	public InstrumenterClassWriter(ClassReader classReader, int flags, ClassLoader loader) {
+		super(classReader, flags);
+		this.loader = loader;
+	}
+
+	public InstrumenterClassWriter(int flags, URLClassLoader loader) {
+		super(flags);
+		this.loader=loader;
+	}
+
+	@Override
+	protected String getCommonSuperClass(String type1, String type2) {
+		Class<?> c, d;
+        try {
+            c = Class.forName(type1.replace('/', '.'), false, loader);
+            d = Class.forName(type2.replace('/', '.'), false, loader);
+        } catch (ClassNotFoundException e) {
+        	logger.debug("Error while finding common super class for " + type1 +"; " + type2,e);
+        	return "java/lang/Object";
+//        	throw new RuntimeException(e);
+        }
+        if (c.isAssignableFrom(d)) {
+            return type1;
+        }
+        if (d.isAssignableFrom(c)) {
+            return type2;
+        }
+        if (c.isInterface() || d.isInterface()) {
+            return "java/lang/Object";
+        } else {
+            do {
+                c = c.getSuperclass();
+            } while (!c.isAssignableFrom(d));
+            return c.getName().replace('.', '/');
+        }
+	}
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/Log.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/Log.java
new file mode 100644
index 0000000..dd86ac7
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/Log.java
@@ -0,0 +1,22 @@
+package edu.columbia.cs.psl.wallace;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class Log {
+	public static Object[] aLog = new Object[Constants.DEFAULT_LOG_SIZE];
+	public static String[] aLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+	public static Lock logLock = new ReentrantLock();
+	public static int logsize = 0;
+	public static int aLog_fill;
+
+
+	public static void clearLog() {
+		logsize = 0;
+		aLog = new Object[Constants.DEFAULT_LOG_SIZE];
+		aLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+
+		aLog_fill = 0;
+
+	}
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/MethodCall.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/MethodCall.java
new file mode 100644
index 0000000..469fdba
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/MethodCall.java
@@ -0,0 +1,163 @@
+package edu.columbia.cs.psl.wallace;
+
+import java.util.HashSet;
+
+import org.objectweb.asm.Type;
+
+public class MethodCall {
+	private String sourceMethodName;
+	private String sourceMethodDesc;
+	private String sourceClass;
+	private int pc;
+	private int lineNumber;
+	private String methodOwner;
+	private String methodName;
+	private String methodDesc;
+	private boolean isStatic;
+
+	private static HashSet<String> serializableClasses = new HashSet<String>();
+	static{
+		serializableClasses.add(Type.getType(String.class).getInternalName());
+	}
+	public MethodCall(String sourceMethodName, String sourceMethodDesc, String sourceClass, int pc, int lineNumber, String methodOwner, String methodName, String methodDesc, boolean isStatic) {
+		this.sourceMethodName = sourceMethodName;
+		this.sourceMethodDesc = sourceMethodDesc;
+		this.sourceClass = sourceClass;
+		this.pc = pc;
+		this.lineNumber = lineNumber;
+		this.methodOwner = methodOwner;
+		this.methodName = methodName;
+		this.methodDesc = methodDesc;
+		this.isStatic = isStatic;
+	}
+	public boolean isStatic() {
+		return isStatic;
+	}
+	public String getSourceMethodName() {
+		return sourceMethodName;
+	}
+	public String getSourceMethodDesc() {
+		return sourceMethodDesc;
+	}
+	public String getSourceClass() {
+		return sourceClass;
+	}
+	public int getPc() {
+		return pc;
+	}
+	public int getLineNumber() {
+		return lineNumber;
+	}
+	public String getMethodOwner() {
+		return methodOwner;
+	}
+	public String getMethodName() {
+		return methodName;
+	}
+	public String getMethodDesc() {
+		return methodDesc;
+	}
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + lineNumber;
+		result = prime * result + ((methodName == null) ? 0 : methodName.hashCode());
+		result = prime * result + pc;
+		result = prime * result + ((sourceClass == null) ? 0 : sourceClass.hashCode());
+		result = prime * result + ((sourceMethodName == null) ? 0 : sourceMethodName.hashCode());
+		return result;
+	}
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MethodCall other = (MethodCall) obj;
+		if(other.getLogFieldName().equals(this.getLogFieldName()) && other.sourceClass.equals(this.sourceClass))
+			return true;
+		return false;
+	}
+	public static String getLogClassName(Type t)
+	{
+		if((t.getSort() != Type.OBJECT  && t.getSort() != Type.ARRAY)|| //primitives
+				(t.getSort() == Type.OBJECT && serializableClasses.contains(t.getInternalName())) || //serializble
+				(t.getSort() == Type.ARRAY && ((t.getElementType().getSort() != Type.OBJECT && t.getElementType().getSort() != Type.ARRAY)|| serializableClasses.contains(t.getElementType().getInternalName())))) // array of prims or array of serializable
+			return Type.getInternalName(SerializableLog.class);
+		else
+			return Type.getInternalName(Log.class);
+	}
+	public static String getReplayClassName(Type t)
+	{
+		if(getLogClassName(t).equals(Type.getInternalName(SerializableLog.class)))
+			return Type.getInternalName(ExportedSerializableLog.class);
+		else
+			return Type.getInternalName(ExportedLog.class);
+	}
+	public String getReplayClassName()
+	{
+		return getReplayClassName(Type.getReturnType(methodDesc));
+	}
+	public String getLogClassName()
+	{
+		return getLogClassName(Type.getReturnType(methodDesc));
+	}
+	public String getCapturePrefix()
+	{
+		String r = sourceMethodName.replace("<", "___").replace(">", "___")+"$$$$"+methodName.replace("<", "___").replace(">", "___")+"$$$$";
+		r += lineNumber+ "$"+pc;
+		return r;
+	}
+	public String getLogFieldName()
+	{
+//		Type[] args = Type.getArgumentTypes(methodDesc);
+//		String r = sourceMethodName.replace("<", "___").replace(">", "___")+"$$$$"+methodName+"$$$$";
+//		for(Type t : args)
+//		{
+//			r+=t.getInternalName().replace("/", "$")+"$$";
+//		}
+//		r += lineNumber+ "$"+pc;
+		Type t= Type.getReturnType(methodDesc);
+		if(t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY || methodName.equals("<init>"))
+			return "aLog";
+		else if(t.getSort() == Type.VOID)
+			return "bLog";
+		else
+			return t.getDescriptor().toLowerCase()+"Log";
+	}
+	public Type getReturnType()
+	{
+		return Type.getMethodType(methodDesc).getReturnType();
+	}
+	public Type getLogFieldType() {
+		Type t = Type.getMethodType(methodDesc).getReturnType();
+		if(t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)
+			return Type.getType("[Ljava/lang/Object;");
+		else if(t.getSort() == Type.VOID)
+			return Type.getType("["+Type.BYTE);
+		else
+			return Type.getType("["+t.getDescriptor());
+//		return Type.getType("["+Type.getMethodType(methodDesc).getReturnType().getDescriptor());
+	}
+	public static String getLogFieldName(Type t)
+	{
+		if(t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)
+			return "aLog";
+		else if(t.getSort() == Type.VOID)
+			return "bLog";
+		else
+			return t.getDescriptor().toLowerCase()+"Log";
+	}
+	public static Type getLogFieldType(Type t)
+	{
+		if(t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)
+			return Type.getType("[Ljava/lang/Object;");
+		else if(t.getSort() == Type.VOID)
+			return Type.getType("["+Type.BYTE);
+		else
+			return Type.getType("["+t.getDescriptor());
+	}
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/SerializableLog.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/SerializableLog.java
new file mode 100644
index 0000000..9c6838c
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/SerializableLog.java
@@ -0,0 +1,33 @@
+package edu.columbia.cs.psl.wallace;
+
+import java.io.Serializable;
+
+public class SerializableLog implements Serializable{
+
+	private static final long	serialVersionUID	= 4627796984904522647L;
+	public static Object[] aLog = new Object[Constants.DEFAULT_LOG_SIZE];
+
+	public static int[] iLog = new int[Constants.DEFAULT_LOG_SIZE];
+	public static long[] jLog = new long[Constants.DEFAULT_LOG_SIZE];
+	public static float[] fLog = new float[Constants.DEFAULT_LOG_SIZE];
+	public static double[] dLog = new double[Constants.DEFAULT_LOG_SIZE];
+	public static byte[] bLog = new byte[Constants.DEFAULT_LOG_SIZE];
+	public static boolean[] zLog = new boolean[Constants.DEFAULT_LOG_SIZE];
+	public static char[] cLog = new char[Constants.DEFAULT_LOG_SIZE];
+	public static short[] sLog = new short[Constants.DEFAULT_LOG_SIZE];
+
+	public static String[] aLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+	public static String[] iLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+	public static String[] jLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+	public static String[] fLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+	public static String[] dLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+	public static String[] bLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+	public static String[] zLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+	public static String[] cLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+	public static String[] sLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+
+	public static int logsize = 0;
+	public static int aLog_fill, iLog_fill, jLog_fill, fLog_fill, dLog_fill, bLog_fill, zLog_fill, cLog_fill, sLog_fill;
+
+
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/WallaceExportRunner.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/WallaceExportRunner.java
new file mode 100644
index 0000000..5c29146
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/WallaceExportRunner.java
@@ -0,0 +1,222 @@
+package edu.columbia.cs.psl.wallace;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Field;
+
+import com.thoughtworks.xstream.XStream;
+
+import edu.columbia.cs.psl.wallace.xstream.StaticReflectionProvider;
+
+public class WallaceExportRunner extends Thread {
+	// static Class<?> logger;
+	static {
+		// try {
+		// // System.err.println("Loading log class");
+		// logger = Class.forName(Constants.LOG_DUMP_CLASS.replace("/", "."));
+		// // System.err.println("Loaded");
+		// } catch (ClassNotFoundException e) {
+		// // TODO Auto-generated catch block
+		// e.printStackTrace();
+		// }
+	}
+
+	@Override
+	public void run() {
+		// System.err.println("Export runner started");
+		while (1 == 1) {
+			// System.out.println("Exporting");
+			// System.err.println("Exporting");
+			// export(); //TODO uncomment
+			// System.err.println("Exported");
+			try {
+				// Thread.sleep(60000); //1 minute
+				// Thread.sleep(300000); //5 minutes
+				Thread.sleep(10000); // 10 seconds
+				// Thread.sleep(5000); //5 seconds
+				// Thread.sleep(1000); //1 seconds
+				// System.out.println("Waking up checking flag");
+				if (shouldExport == 1)
+					export();
+				if (shouldExportSerializable == 1)
+					exportSerializable();
+				if (shouldExport == 1)
+					export();
+
+			} catch (InterruptedException e) {
+				if (shouldExport == 1)
+					export();
+				if (shouldExportSerializable == 1)
+					exportSerializable();
+				if (shouldExport == 1)
+					export();
+			}
+		}
+	}
+
+	static WallaceExportRunner inst = new WallaceExportRunner();
+
+	public WallaceExportRunner() {
+		setDaemon(true);
+		setPriority(Thread.MAX_PRIORITY);
+	}
+
+	private static ExportedLog log = new ExportedLog();
+
+	public static void export() {
+		shouldExport = 0;
+		try {
+			XStream xstream = new XStream(new StaticReflectionProvider());
+			String xml = "";
+			// System.out.println("Waiting for the lock");
+			Log.logLock.lock();
+			ExportedLog.aLog = Log.aLog;
+			ExportedLog.aLog_owners = Log.aLog_owners;
+			ExportedLog.aLog_fill = Log.aLog_fill;
+			Log.logsize = 0;
+			Log.aLog = new Object[Constants.DEFAULT_LOG_SIZE];
+			Log.aLog_fill = 0;
+			Log.logLock.unlock();
+//			System.err.println("Serializing");
+			try {
+				xml = xstream.toXML(log);
+			} catch (Exception ex) {
+				System.err.println("NPE" + ex.getMessage());
+			}
+			// System.err.println("Clearing");
+			ExportedLog.clearLog();
+			// System.err.println("Cleared");
+
+			// CloningUtils.exportLock.writeLock().unlock();
+			File output = new File("wallace_" + System.currentTimeMillis() + ".log");
+			FileWriter fw = new FileWriter(output);
+			fw.write(xml);
+			fw.close();
+			// synchronized (Log.lock) {
+			// Log.lock.notifyAll();
+			// }
+			// synchronized (Log.lock) {
+			// Log.lock.notifyAll();
+			// }
+
+		} catch (Exception exi) {
+			// System.err.println(exi.getMessage());
+		}
+		shouldExport = -1;
+	}
+
+	private static ExportedSerializableLog logS = new ExportedSerializableLog();
+
+	public static void exportSerializable() {
+		shouldExportSerializable = 0;
+		try {
+
+			Log.logLock.lock();
+			{
+				ExportedSerializableLog.aLog = SerializableLog.aLog;
+				ExportedSerializableLog.aLog_fill = SerializableLog.aLog_fill;
+				ExportedSerializableLog.bLog = SerializableLog.bLog;
+				ExportedSerializableLog.cLog = SerializableLog.cLog;
+				ExportedSerializableLog.dLog = SerializableLog.dLog;
+				ExportedSerializableLog.iLog = SerializableLog.iLog;
+				ExportedSerializableLog.fLog = SerializableLog.fLog;
+				ExportedSerializableLog.jLog = SerializableLog.jLog;
+				ExportedSerializableLog.zLog = SerializableLog.zLog;
+				ExportedSerializableLog.sLog = SerializableLog.sLog;
+
+				ExportedSerializableLog.bLog_fill = SerializableLog.bLog_fill;
+				ExportedSerializableLog.cLog_fill = SerializableLog.cLog_fill;
+				ExportedSerializableLog.dLog_fill = SerializableLog.dLog_fill;
+				ExportedSerializableLog.iLog_fill = SerializableLog.iLog_fill;
+				ExportedSerializableLog.fLog_fill = SerializableLog.fLog_fill;
+				ExportedSerializableLog.jLog_fill = SerializableLog.jLog_fill;
+				ExportedSerializableLog.zLog_fill = SerializableLog.zLog_fill;
+				ExportedSerializableLog.sLog_fill = SerializableLog.sLog_fill;
+
+				ExportedSerializableLog.aLog_owners = SerializableLog.aLog_owners;
+				ExportedSerializableLog.iLog_owners = SerializableLog.iLog_owners;
+				ExportedSerializableLog.jLog_owners = SerializableLog.jLog_owners;
+				ExportedSerializableLog.fLog_owners = SerializableLog.fLog_owners;
+				ExportedSerializableLog.dLog_owners = SerializableLog.dLog_owners;
+				ExportedSerializableLog.bLog_owners = SerializableLog.bLog_owners;
+				ExportedSerializableLog.zLog_owners = SerializableLog.zLog_owners;
+				ExportedSerializableLog.cLog_owners = SerializableLog.cLog_owners;
+				ExportedSerializableLog.sLog_owners = SerializableLog.sLog_owners;
+
+				SerializableLog.aLog = new Object[Constants.DEFAULT_LOG_SIZE];
+				SerializableLog.iLog = new int[Constants.DEFAULT_LOG_SIZE];
+				SerializableLog.jLog = new long[Constants.DEFAULT_LOG_SIZE];
+				SerializableLog.fLog = new float[Constants.DEFAULT_LOG_SIZE];
+				SerializableLog.dLog = new double[Constants.DEFAULT_LOG_SIZE];
+				SerializableLog.bLog = new byte[Constants.DEFAULT_LOG_SIZE];
+				SerializableLog.zLog = new boolean[Constants.DEFAULT_LOG_SIZE];
+				SerializableLog.cLog = new char[Constants.DEFAULT_LOG_SIZE];
+				SerializableLog.sLog = new short[Constants.DEFAULT_LOG_SIZE];
+				SerializableLog.aLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+				SerializableLog.iLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+				SerializableLog.jLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+				SerializableLog.fLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+				SerializableLog.dLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+				SerializableLog.bLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+				SerializableLog.zLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+				SerializableLog.cLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+				SerializableLog.sLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
+				SerializableLog.logsize = 0;
+				SerializableLog.iLog_fill = 0;
+				SerializableLog.jLog_fill = 0;
+				SerializableLog.fLog_fill = 0;
+				SerializableLog.dLog_fill = 0;
+				SerializableLog.bLog_fill = 0;
+				SerializableLog.zLog_fill = 0;
+				SerializableLog.cLog_fill = 0;
+				SerializableLog.sLog_fill = 0;
+				SerializableLog.aLog_fill = 0;
+			}
+			Log.logLock.unlock();
+			// System.err.println("Serializing serializable");
+			File output = new File("wallace_serializable_" + System.currentTimeMillis() + ".log");
+
+			ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(output));
+			oos.writeObject(logS);
+			oos.flush();
+			oos.close();
+			// System.err.println("Clearing serializable");
+			ExportedLog.clearLog();
+			// System.err.println("Cleared serializable");
+			// System.out.println("Notifying; " + Log.logsize
+			// +";"+SerializableLog.logsize);
+			// synchronized (Log.lock) {
+			// Log.lock.notifyAll();
+			// }
+			// synchronized (Log.lock) {
+			// Log.lock.notifyAll();
+			// }
+		} catch (Exception exi) {
+			// System.err.println(exi.getMessage());
+		}
+		shouldExportSerializable = -1;
+	}
+
+	private static int shouldExport = -1;
+	private static int shouldExportSerializable = -1;
+
+	public static void _exportSerializable() {
+		if (shouldExportSerializable == -1) {
+			// System.out.println("Flagged shouldexport serializble");
+			Thread.yield();
+			shouldExportSerializable = 1;
+			inst.interrupt();
+		}
+	}
+
+	public static void _export() {
+		if (shouldExport == -1) {
+			Thread.yield();
+			shouldExport = 1;
+			inst.interrupt();
+		}
+	}
+
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/WallaceUncaughtExceptionHandler.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/WallaceUncaughtExceptionHandler.java
new file mode 100644
index 0000000..5657757
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/WallaceUncaughtExceptionHandler.java
@@ -0,0 +1,27 @@
+package edu.columbia.cs.psl.wallace;
+
+import java.io.File;
+import java.io.FileWriter;
+
+import com.thoughtworks.xstream.XStream;
+
+import edu.columbia.cs.psl.wallace.xstream.StaticReflectionProvider;
+
+public class WallaceUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{
+
+	@Override
+	public void uncaughtException(Thread t, Throwable e) {
+		try{
+			System.err.println("Wallace caught an exception");
+			e.printStackTrace();
+			System.err.println("Writing log");
+			WallaceExportRunner.export();
+			WallaceExportRunner.exportSerializable();
+			}
+		catch(Exception exi)
+		{
+			exi.printStackTrace();
+		}
+	}
+
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/analysis/MutabilityAnalyzer.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/analysis/MutabilityAnalyzer.java
new file mode 100644
index 0000000..a2097af
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/analysis/MutabilityAnalyzer.java
@@ -0,0 +1,700 @@
+package edu.columbia.cs.psl.wallace.analysis;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.apache.log4j.Logger;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.FieldInsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+import org.objectweb.asm.tree.MethodNode;
+
+import edu.columbia.cs.psl.wallace.Instrumenter;
+import edu.columbia.cs.psl.wallace.struct.AnnotatedMethod;
+import edu.columbia.cs.psl.wallace.struct.Expression;
+import edu.columbia.cs.psl.wallace.struct.FieldExpression;
+import edu.columbia.cs.psl.wallace.struct.MethodExpression;
+import edu.columbia.cs.psl.wallace.struct.SimpleExpression;
+import edu.columbia.cs.psl.wallace.visitor.NonDeterministicLoggingClassVisitor;
+import edu.columbia.cs.psl.wallace.visitor.NonDeterministicLoggingMethodVisitor;
+
+public class MutabilityAnalyzer implements Opcodes {
+
+	private static Logger logger = Logger.getLogger(MutabilityAnalyzer.class);
+	public MutabilityAnalyzer(HashMap<String, AnnotatedMethod> lookupCache) {
+		this.lookupCache = lookupCache;
+	}
+	private HashMap<String, AnnotatedMethod> lookupCache;
+	private static boolean enabled = false;
+	/**
+	 * Call when done calling analyzeClass
+	 */
+	public void doneSupplyingClasses()
+	{
+		if(!enabled)
+			return;
+		for (String s : lookupCache.keySet()) {
+			AnnotatedMethod method = lookupCache.get(s);
+			if (method.isMutatesFieldsDirectly()) {
+				for (AnnotatedMethod caller : method.functionsThatCallMe)
+				{
+					method.setMutatesFields();
+					addAllRecursively(caller);
+				}
+			}
+		}
+	}
+
+	private void addAllRecursively(AnnotatedMethod method) {
+		if (method.isMutatesFields())
+			return;
+		method.setMutatesFields();
+		for (AnnotatedMethod caller : method.functionsThatCallMe)
+			addAllRecursively(caller);
+	}
+
+	/**
+	 *
+	 * Approach:
+	 * Find all methods that can change fields
+	 * Recurse that out to find all methods that might call methods that can change fields
+	 *
+	 * At the start of each methods that might change fields, keep track in a field:
+	 * 		The starting count values for each storage array *recursively* this can be in local variables though
+	 * When a field is changed OR a "not safe" local variable (not safe if it might point to a field):
+	 * 		Store a reference to the field/local variable and a copy of the value
+	 * When a method is invoked that might change fields, track:
+	 * 		A reference to the callee
+	 *
+	 *
+	 * When we need to reset the system to a pre-crash state:
+	 * 		Go through the starting count for each field and compare with each current count. If count changed, reset and note
+	 * 		To find each field, may need to (recursively) descend through the holder points-to fields
+	 *
+	 * Take 2:
+	 * At the start of each method, make a reference copy to a local variable of every backup pt that we will subsequently read but might change
+	 *
+	 * If this method directly changes fields, store a local variable with the original value at time of change
+	 * If this method indirectly changes fields, store a local variable with the original value before the method is called
+	 * @param cr
+	 */
+	public ClassNode analyzeClass(ClassReader cr) {
+		ClassNode cn = new ClassNode();
+		cr.accept(cn, ClassReader.SKIP_DEBUG);
+
+		for (Object o : cn.methods) {
+			MethodNode thisMethodNode = (MethodNode) o;
+			AnnotatedMethod thisMethod = findOrAddMethod(cn.name, thisMethodNode);
+			thisMethod.setFullyDiscovered(true);
+			thisMethod.setAccess(thisMethodNode.access);
+
+			if((thisMethodNode.access & ACC_NATIVE) != 0) // is native
+					NonDeterministicLoggingMethodVisitor.registerNDMethod(cn.name, thisMethodNode.name, thisMethodNode.desc);
+
+			ListIterator<?> i = thisMethodNode.instructions.iterator();
+			boolean isFirstInsn = true;
+			while (i.hasNext()) {
+				AbstractInsnNode n = (AbstractInsnNode) i.next();
+				if (n.getType() == AbstractInsnNode.FIELD_INSN) // Field
+																// Instruction
+				{
+					FieldInsnNode fn = (FieldInsnNode) n;
+					if (n.getOpcode() == Opcodes.PUTSTATIC) {
+						// This instruction is changing a static field. Previous
+						// instruction is the value to set to
+						FieldExpression pi = new FieldExpression(fn.name, fn.owner, fn.desc, n.getOpcode());
+						thisMethod.getPutFieldInsns().add(pi);
+						thisMethod.setMutatesFieldsDirectly();
+					} else if (n.getOpcode() == Opcodes.PUTFIELD) {
+
+						// This instruction is changing a field.
+						// Previous instruction will have the value that we are
+						// setting to
+						FieldExpression pi = new FieldExpression(fn.name, fn.owner, fn.desc, n.getOpcode());
+						pi.setParent(parentInstructionOf(thisMethodNode, pi, thisMethodNode.instructions.iterator(i.previousIndex())));
+						thisMethod.getPutFieldInsns().add(pi);
+						thisMethod.setMutatesFieldsDirectly();
+					}
+				} else if (n.getType() == AbstractInsnNode.METHOD_INSN) // Method
+																		// invocation
+				{
+					MethodInsnNode whatWeCall = (MethodInsnNode) n;
+					AnnotatedMethod otherMethod = findOrAddMethod(whatWeCall.owner, whatWeCall.name, whatWeCall.desc,0);
+					otherMethod.functionsThatCallMe.add(thisMethod);
+					MethodExpression otherMethodExp = new MethodExpression(otherMethod, whatWeCall.getOpcode());
+					otherMethodExp.getParams().addAll(paramsOf(thisMethodNode, otherMethodExp, thisMethodNode.instructions.iterator(i.previousIndex())));
+
+					if(whatWeCall.getOpcode() != Opcodes.INVOKESTATIC)
+						otherMethodExp.setParent(parentInstructionOf(thisMethodNode, otherMethodExp, thisMethodNode.instructions.iterator(i.previousIndex())));
+
+					if(NonDeterministicLoggingMethodVisitor.isND(whatWeCall.owner, whatWeCall.name, whatWeCall.desc) &&
+							whatWeCall.name.equals("<init>") && whatWeCall.owner.equals(cn.superName) && thisMethodNode.name.equals("<init>") && isFirstInsn)
+					{
+						NonDeterministicLoggingMethodVisitor.registerNDMethod(cn.name, thisMethodNode.name, thisMethodNode.desc);
+					}
+
+					thisMethod.functionsThatICall.add(otherMethodExp);
+
+					isFirstInsn = false;
+				} else if (n.getType() == AbstractInsnNode.INVOKE_DYNAMIC_INSN) // Invoke
+																				// dynamic
+				{
+
+				}
+			}
+		}
+		ClassNode ret = new ClassNode();
+		ret.name = cn.name;
+		ret.fields = cn.fields;
+		ret.superName = cn.superName;
+		return ret;
+	}
+
+
+
+	private List<Expression> paramsOf(MethodNode sourceMethod, MethodExpression methodInsnToFindParamsOf, ListIterator<?> i) {
+		ArrayList<Expression> ret = new ArrayList<Expression>();
+		int nParams = methodInsnToFindParamsOf.getNumParamsNeeded();
+		int nToSkip = 0;
+		logger.debug("Finding " + nParams + " params for " + methodInsnToFindParamsOf);
+		while (i.hasPrevious() && nParams > 0) {
+			AbstractInsnNode n = (AbstractInsnNode) i.previous();
+			switch (n.getType()) {
+			case AbstractInsnNode.METHOD_INSN:
+				MethodInsnNode min = (MethodInsnNode) n;
+				MethodExpression mi = new MethodExpression(findOrAddMethod(min.owner, min.name, min.desc, min.getOpcode() == Opcodes.INVOKESTATIC ? Opcodes.ACC_STATIC : 0), min.getOpcode());
+				logger.debug("Encountered " + mi + ", skipping " + mi.getStackElementsToSkip());
+
+				if (nToSkip == 0) {
+					mi.setParent(parentInstructionOf(sourceMethod, mi, sourceMethod.instructions.iterator(i.previousIndex() + 1)));
+					mi.getParams().addAll(paramsOf(sourceMethod, mi, sourceMethod.instructions.iterator(i.previousIndex() + 1)));
+
+					ret.add(mi);
+					nParams--;
+				}
+				nToSkip--;
+				nToSkip += mi.getStackElementsToSkip() + (mi.getOpcode() == Opcodes.INVOKESTATIC ? 0 : 1);
+				logger.debug("NTOS" + nToSkip);
+				if (nToSkip < 0)
+					nToSkip = 0;
+				break;
+			case AbstractInsnNode.INVOKE_DYNAMIC_INSN:
+				// TODO
+				break;
+			case AbstractInsnNode.TYPE_INSN:
+				switch (n.getOpcode()) {
+				case NEW:
+					if (nToSkip == 0) {
+						ret.add(new SimpleExpression(n));
+						nParams--;
+					} else
+						nToSkip--;
+					break;
+				case ANEWARRAY:
+				case CHECKCAST:
+				case INSTANCEOF:
+				}
+				break;
+			case AbstractInsnNode.FIELD_INSN:
+				FieldInsnNode fn = (FieldInsnNode) n;
+				if (n.getOpcode() == Opcodes.GETFIELD) {
+					FieldExpression fi = new FieldExpression(fn.name, fn.owner, fn.desc, n.getOpcode());
+					logger.debug("Encoutnered" + fi);
+					if (nToSkip == 0) {
+						fi.setParent(parentInstructionOf(sourceMethod, fi, sourceMethod.instructions.iterator(i.previousIndex() + 1)));
+						ret.add(fi);
+						nParams--;
+					}
+					nToSkip--;
+					nToSkip += 1;
+				} else if (n.getOpcode() == Opcodes.GETSTATIC) {
+					FieldExpression fi = new FieldExpression(fn.name, fn.owner, fn.desc, n.getOpcode());
+					if (nToSkip == 0) {
+						ret.add(fi);
+						nParams--;
+					}
+					nToSkip--;
+				}
+				break;
+			case AbstractInsnNode.INT_INSN:
+			case AbstractInsnNode.LDC_INSN:
+			case AbstractInsnNode.VAR_INSN:
+				switch (n.getOpcode()) {
+				case Opcodes.ILOAD:
+				case Opcodes.LLOAD:
+				case Opcodes.FLOAD:
+				case Opcodes.DLOAD:
+				case Opcodes.ALOAD:
+				case BIPUSH:
+				case SIPUSH:
+				case Opcodes.LDC:
+					if (nToSkip == 0) {
+						ret.add(new SimpleExpression(n));
+						nParams--;
+					} else
+						nToSkip--;
+					break;
+				case ISTORE:
+				case LSTORE:
+				case FSTORE:
+				case DSTORE:
+				case ASTORE:
+					nToSkip--;
+					nToSkip++;
+					break;
+				case LALOAD:
+				case FALOAD:
+				case AALOAD:
+				case BALOAD:
+				case CALOAD:
+				case SALOAD:
+					nToSkip--;
+					nToSkip += 2;
+					break;
+				case AASTORE:
+				case IASTORE:
+				case FASTORE:
+				case DASTORE:
+				case BASTORE:
+				case CASTORE:
+				case SASTORE:
+					nToSkip += 3;
+					break;
+				case NEWARRAY:
+					nToSkip--;
+					nToSkip++;
+				default:
+					logger.debug("Unknown opcode " + n.getOpcode());
+					break;
+				}
+				break;
+			case AbstractInsnNode.INSN:
+				switch (n.getOpcode()) {
+				// case ATHROW: // 1 before n/a after
+				// popValue();
+				// onMethodExit(opcode);
+				// break;
+				//
+				// case LRETURN: // 2 before n/a after
+				// case DRETURN: // 2 before n/a after
+				// popValue();
+				// popValue();
+				// onMethodExit(opcode);
+				// break;
+
+				case NOP:
+				case LNEG:
+				case DNEG:
+				case FNEG:
+				case INEG:
+				case L2D:
+				case D2L:
+				case F2I:
+				case I2B:
+				case I2C:
+				case I2S:
+				case I2F:
+				case F2L: // 1 before 2 after
+				case F2D:
+				case I2L:
+				case I2D:
+
+				case L2I: // 2 before 1 after
+				case L2F: // 2 before 1 after
+				case D2I: // 2 before 1 after
+				case D2F: // 2 before 1 after
+				case ARRAYLENGTH:
+				case SWAP:
+					nToSkip--;
+					nToSkip++;
+					break;
+
+				case IADD:
+				case FADD:
+				case ISUB:
+				case LSHL: // 3 before 2 after
+				case LSHR: // 3 before 2 after
+				case LUSHR: // 3 before 2 after
+				case LSUB:
+				case LMUL:
+				case LDIV:
+				case LREM:
+				case LADD:
+				case LAND:
+				case LOR:
+				case LXOR:
+				case DADD:
+				case DMUL:
+				case DSUB:
+				case DDIV:
+				case DREM:
+
+				case FSUB:
+				case FMUL:
+				case FDIV:
+				case FREM:
+				case FCMPL: // 2 before 1 after
+				case FCMPG: // 2 before 1 after
+				case IMUL:
+				case IDIV:
+				case IREM:
+				case ISHL:
+				case ISHR:
+				case IUSHR:
+				case IAND:
+				case IOR:
+				case IXOR:
+
+				case IALOAD: // remove 2 add 1
+				case FALOAD: // remove 2 add 1
+				case AALOAD: // remove 2 add 1
+				case BALOAD: // remove 2 add 1
+				case CALOAD: // remove 2 add 1
+				case SALOAD: // remove 2 add 1
+				case LALOAD: // remove 2 add 2
+				case DALOAD: // remove 2 add 2
+
+				case LCMP: // 4 before 1 after
+				case DCMPL:
+				case DCMPG:
+					nToSkip--;
+					nToSkip += 2;
+					break;
+
+				case ACONST_NULL:
+				case ICONST_M1:
+				case ICONST_0:
+				case ICONST_1:
+				case ICONST_2:
+				case ICONST_3:
+				case ICONST_4:
+				case ICONST_5:
+				case FCONST_0:
+				case FCONST_1:
+				case FCONST_2:
+				case LCONST_0:
+				case LCONST_1:
+				case DCONST_0:
+				case DCONST_1:
+
+				case DUP:
+				case DUP_X1:
+				case DUP_X2:
+
+				case DUP2: // is this wrong to assume that dup2 is only used on
+							// longs and not 2 shorts?
+				case DUP2_X1:
+				case DUP2_X2:
+					// case POP:
+					// case MONITORENTER:
+					// case MONITOREXIT:
+					// case POP2:
+					if (nToSkip == 0) {
+						ret.add(new SimpleExpression(n));
+						nParams--;
+					} else
+						nToSkip--;
+					break;
+
+				case LASTORE:
+				case DASTORE:
+				case IASTORE:
+				case FASTORE:
+				case AASTORE:
+				case BASTORE:
+				case CASTORE:
+				case SASTORE:
+					nToSkip--;
+					nToSkip += 3;
+					break;
+				}
+				break;
+			}
+		}
+		return ret;
+	}
+
+	private Expression parentInstructionOf(MethodNode mn, Expression insnToFindParentOf, ListIterator<?> i) {
+		if (insnToFindParentOf.getType() == Expression.METHOD_TYPE && ((MethodExpression) insnToFindParentOf).getMethod().getName().equals("<init>"))
+			return null;
+		int nToSkip = insnToFindParentOf.getStackElementsToSkip();
+		logger.debug("Examining " + insnToFindParentOf.toString() + " for parent, skipping " + nToSkip);
+		while (i.hasPrevious()) {
+			AbstractInsnNode n = (AbstractInsnNode) i.previous();
+			switch (n.getType()) {
+			case AbstractInsnNode.METHOD_INSN:
+				MethodInsnNode min = (MethodInsnNode) n;
+				MethodExpression mi = new MethodExpression(findOrAddMethod(min.owner, min.name, min.desc, min.getOpcode() == Opcodes.INVOKESTATIC ? Opcodes.ACC_STATIC : 0), min.getOpcode());
+				logger.debug("Encountered " + mi + ", skipping " + mi.getStackElementsToSkip());
+
+				if (nToSkip == 0) {
+					mi.setParent(parentInstructionOf(mn, mi, mn.instructions.iterator(i.previousIndex() + 1)));
+					mi.getParams().addAll(paramsOf(mn, mi, mn.instructions.iterator(i.previousIndex() + 1)));
+					return mi;
+				}
+				nToSkip--;
+				nToSkip += mi.getStackElementsToSkip() + (mi.getOpcode() == Opcodes.INVOKESTATIC ? 0 : 1);
+				logger.debug("NTos" + nToSkip);
+				break;
+			case AbstractInsnNode.INVOKE_DYNAMIC_INSN:
+				// TODO
+				break;
+			case AbstractInsnNode.TYPE_INSN:
+				switch (n.getOpcode()) {
+				case NEW:
+					if (nToSkip == 0) {
+						return new SimpleExpression(n);
+					} else
+						nToSkip--;
+					break;
+				case ANEWARRAY:
+				case CHECKCAST:
+				case INSTANCEOF:
+				}
+				break;
+			case AbstractInsnNode.FIELD_INSN:
+				FieldInsnNode fn = (FieldInsnNode) n;
+				if (n.getOpcode() == Opcodes.GETFIELD) {
+					FieldExpression fi = new FieldExpression(fn.name, fn.owner, fn.desc, n.getOpcode());
+					logger.debug("Encoutnered field: " + fi);
+					if (nToSkip == 0) {
+						fi.setParent(parentInstructionOf(mn, fi, mn.instructions.iterator(i.previousIndex() + 1)));
+						return fi;
+					}
+					nToSkip--;
+					nToSkip += 1;
+					logger.debug("Ntos" + nToSkip);
+				} else if (n.getOpcode() == Opcodes.GETSTATIC) {
+					FieldExpression fi = new FieldExpression(fn.name, fn.owner, fn.desc, n.getOpcode());
+					if (nToSkip == 0) {
+						fi.setParent(parentInstructionOf(mn, fi, mn.instructions.iterator(i.previousIndex() + 1)));
+						return fi;
+					}
+					nToSkip--;
+					// nToSkip += 1;
+				}
+				break;
+			case AbstractInsnNode.INT_INSN:
+			case AbstractInsnNode.LDC_INSN:
+			case AbstractInsnNode.VAR_INSN:
+				switch (n.getOpcode()) {
+				case Opcodes.ILOAD:
+				case Opcodes.LLOAD:
+				case Opcodes.FLOAD:
+				case Opcodes.DLOAD:
+				case Opcodes.ALOAD:
+				case BIPUSH:
+				case SIPUSH:
+				case Opcodes.LDC:
+					if (nToSkip == 0) {
+						return new SimpleExpression(n);
+					}
+					nToSkip--;
+					break;
+				case ISTORE:
+				case LSTORE:
+				case FSTORE:
+				case DSTORE:
+				case ASTORE:
+					nToSkip--;
+					nToSkip++;
+					break;
+				case LALOAD:
+				case FALOAD:
+				case AALOAD:
+				case BALOAD:
+				case CALOAD:
+				case SALOAD:
+					nToSkip--;
+					nToSkip += 2;
+					break;
+				case AASTORE:
+				case IASTORE:
+				case FASTORE:
+				case DASTORE:
+				case BASTORE:
+				case CASTORE:
+				case SASTORE:
+					nToSkip += 3;
+					break;
+				case NEWARRAY:
+					nToSkip--;
+					nToSkip++;
+				default:
+					logger.debug("Unknown opcode " + n.getOpcode());
+					break;
+				}
+				break;
+			case AbstractInsnNode.INSN:
+				switch (n.getOpcode()) {
+				// case ATHROW: // 1 before n/a after
+				// popValue();
+				// onMethodExit(opcode);
+				// break;
+				//
+				// case LRETURN: // 2 before n/a after
+				// case DRETURN: // 2 before n/a after
+				// popValue();
+				// popValue();
+				// onMethodExit(opcode);
+				// break;
+
+				case NOP:
+				case LNEG:
+				case DNEG:
+				case FNEG:
+				case INEG:
+				case L2D:
+				case D2L:
+				case F2I:
+				case I2B:
+				case I2C:
+				case I2S:
+				case I2F:
+				case F2L: // 1 before 2 after
+				case F2D:
+				case I2L:
+				case I2D:
+
+				case L2I: // 2 before 1 after
+				case L2F: // 2 before 1 after
+				case D2I: // 2 before 1 after
+				case D2F: // 2 before 1 after
+				case ARRAYLENGTH:
+				case SWAP:
+					nToSkip--;
+					nToSkip++;
+					break;
+
+				case IADD:
+				case FADD:
+				case ISUB:
+				case LSHL: // 3 before 2 after
+				case LSHR: // 3 before 2 after
+				case LUSHR: // 3 before 2 after
+				case LSUB:
+				case LMUL:
+				case LDIV:
+				case LREM:
+				case LADD:
+				case LAND:
+				case LOR:
+				case LXOR:
+				case DADD:
+				case DMUL:
+				case DSUB:
+				case DDIV:
+				case DREM:
+
+				case FSUB:
+				case FMUL:
+				case FDIV:
+				case FREM:
+				case FCMPL: // 2 before 1 after
+				case FCMPG: // 2 before 1 after
+				case IMUL:
+				case IDIV:
+				case IREM:
+				case ISHL:
+				case ISHR:
+				case IUSHR:
+				case IAND:
+				case IOR:
+				case IXOR:
+
+				case IALOAD: // remove 2 add 1
+				case FALOAD: // remove 2 add 1
+				case AALOAD: // remove 2 add 1
+				case BALOAD: // remove 2 add 1
+				case CALOAD: // remove 2 add 1
+				case SALOAD: // remove 2 add 1
+				case LALOAD: // remove 2 add 2
+				case DALOAD: // remove 2 add 2
+
+				case LCMP: // 4 before 1 after
+				case DCMPL:
+				case DCMPG:
+					nToSkip--;
+					nToSkip += 2;
+					break;
+
+				case ACONST_NULL:
+				case ICONST_M1:
+				case ICONST_0:
+				case ICONST_1:
+				case ICONST_2:
+				case ICONST_3:
+				case ICONST_4:
+				case ICONST_5:
+				case FCONST_0:
+				case FCONST_1:
+				case FCONST_2:
+				case LCONST_0:
+				case LCONST_1:
+				case DCONST_0:
+				case DCONST_1:
+
+				case DUP:
+				case DUP_X1:
+				case DUP_X2:
+
+				case DUP2: // is this wrong to assume that dup2 is only used on
+							// longs and not 2 shorts?
+				case DUP2_X1:
+				case DUP2_X2:
+					// case POP:
+					// case MONITORENTER:
+					// case MONITOREXIT:
+					// case POP2:
+					if (nToSkip == 0) {
+						return new SimpleExpression(n);
+					}
+					nToSkip--;
+					break;
+
+				case LASTORE:
+				case DASTORE:
+				case IASTORE:
+				case FASTORE:
+				case AASTORE:
+				case BASTORE:
+				case CASTORE:
+				case SASTORE:
+					nToSkip--;
+					nToSkip += 3;
+					break;
+				}
+				break;
+			}
+
+		}
+		return null;
+	}
+
+	private AnnotatedMethod findOrAddMethod(String owner, String name, String desc, int access) {
+		String lookupKey = owner + "." + name + ":" + desc;
+		if (!lookupCache.containsKey(lookupKey))
+			lookupCache.put(lookupKey, new AnnotatedMethod(name, desc, owner, access));
+		return lookupCache.get(lookupKey);
+	}
+
+	private AnnotatedMethod findOrAddMethod(String owner, MethodNode mn) {
+		return findOrAddMethod(owner, mn.name, mn.desc, mn.access);
+	}
+
+	public static void main(String[] args) {
+		try {
+			ClassReader cr = new ClassReader("edu.columbia.cs.psl.invivo.sample.SimpleClass");
+			MutabilityAnalyzer ma = new MutabilityAnalyzer(new HashMap<String, AnnotatedMethod>());
+			ma.analyzeClass(cr);
+			ma.doneSupplyingClasses();
+		} catch (Exception ex) {
+			ex.printStackTrace();
+		}
+	}
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/bench/WallaceLogExplorer.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/bench/WallaceLogExplorer.java
new file mode 100644
index 0000000..6e9b156
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/bench/WallaceLogExplorer.java
@@ -0,0 +1,23 @@
+package edu.columbia.cs.psl.wallace.bench;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.ObjectInputStream;
+
+import edu.columbia.cs.psl.wallace.ExportedSerializableLog;
+
+public class WallaceLogExplorer {
+	public static void main(String[] args) throws Exception {
+		File f = new File("instrumented/wallace_serializable_1344527362195.log");
+		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
+		ExportedSerializableLog log = (ExportedSerializableLog) ois.readObject();
+		Object[] alog = ExportedSerializableLog.aLog;
+
+		char[] clog = ExportedSerializableLog.cLog;
+		byte[] blog = ExportedSerializableLog.bLog;
+		String[] ownersA = ExportedSerializableLog.aLog_owners;
+		System.out.println(ExportedSerializableLog.aLog_fill);
+		System.out.println(ExportedSerializableLog.cLog_fill);
+		System.out.println(ExportedSerializableLog.dLog_fill);
+	}
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/replay/NonDeterministicReplayClassVisitor.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/replay/NonDeterministicReplayClassVisitor.java
new file mode 100644
index 0000000..6140496
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/replay/NonDeterministicReplayClassVisitor.java
@@ -0,0 +1,88 @@
+package edu.columbia.cs.psl.wallace.replay;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+
+import org.apache.log4j.Logger;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.AnalyzerAdapter;
+import org.objectweb.asm.commons.JSRInlinerAdapter;
+import org.objectweb.asm.tree.FieldNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+import org.objectweb.asm.util.CheckMethodAdapter;
+
+import edu.columbia.cs.psl.wallace.Constants;
+import edu.columbia.cs.psl.wallace.MethodCall;
+import edu.columbia.cs.psl.wallace.visitor.CloningAdviceAdapter;
+
+public class NonDeterministicReplayClassVisitor extends ClassVisitor implements Opcodes{
+
+	private String className;
+	private boolean isAClass = true;
+
+	public NonDeterministicReplayClassVisitor(int api, ClassVisitor cv) {
+		super(api, cv);
+
+	}
+	private static Logger logger = Logger.getLogger(NonDeterministicReplayClassVisitor.class);
+	@Override
+	public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
+		super.visit(version, access, name, signature, superName, interfaces);
+		this.className = name;
+
+		logger.debug("Visiting " + name+ " for instrumentation");
+		if((access & Opcodes.ACC_INTERFACE) != 0)
+			isAClass = false;
+	}
+	private boolean isFirstConstructor = true;
+	@Override
+	public MethodVisitor visitMethod(int acc, String name, String desc,
+			String signature, String[] exceptions) {
+		//TODO need an annotation to disable doing this to some apps
+		if(isAClass)// && className.startsWith("edu"))
+		{
+
+			MethodVisitor smv = cv.visitMethod(acc, name, desc, signature, exceptions);
+			JSRInlinerAdapter mv = new JSRInlinerAdapter(smv, acc, name, desc, signature, exceptions);
+
+			AnalyzerAdapter analyzer = new AnalyzerAdapter(className, acc, name, desc, mv);
+			CheckMethodAdapter cm = new CheckMethodAdapter(analyzer);
+			NonDeterministicReplayMethodVisitor cloningMV = new NonDeterministicReplayMethodVisitor(Opcodes.ASM4, cm, acc, name, desc,className,isFirstConstructor, analyzer);
+			if(name.equals("<init>"))
+				isFirstConstructor = false;
+			cloningMV.setClassVisitor(this);
+			return cloningMV;
+		}
+		else
+			return 	cv.visitMethod(acc, name, desc, signature,
+					exceptions);
+	}
+
+	public HashSet<MethodCall> getLoggedMethodCalls() {
+		return loggedMethodCalls;
+	}
+	private HashSet<MethodCall> loggedMethodCalls = new HashSet<MethodCall>();
+	private HashMap<String, MethodInsnNode> captureMethodsToGenerate = new HashMap<String, MethodInsnNode>();
+	public void addFieldMarkup(ArrayList<MethodCall> calls) {
+		logger.debug("Received field markup from method visitor (" + calls.size() + ")");
+		loggedMethodCalls.addAll(calls);
+		//TODO also setup the new method to retrieve the list of replacements for the method
+	}
+
+	@Override
+	public void visitEnd() {
+		super.visitEnd();
+
+	}
+	public String getClassName() {
+		return className;
+	}
+
+	public void addCaptureMethodsToGenerate(HashMap<String, MethodInsnNode> captureMethodsToGenerate) {
+		this.captureMethodsToGenerate.putAll(captureMethodsToGenerate);
+	}
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/replay/NonDeterministicReplayMethodVisitor.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/replay/NonDeterministicReplayMethodVisitor.java
new file mode 100644
index 0000000..dcbcc0b
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/replay/NonDeterministicReplayMethodVisitor.java
@@ -0,0 +1,403 @@
+package edu.columbia.cs.psl.wallace.replay;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Scanner;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+
+import org.apache.log4j.Logger;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.AnalyzerAdapter;
+import org.objectweb.asm.tree.MethodInsnNode;
+
+import edu.columbia.cs.psl.wallace.CloningUtils;
+import edu.columbia.cs.psl.wallace.Constants;
+import edu.columbia.cs.psl.wallace.ExportedLog;
+import edu.columbia.cs.psl.wallace.Instrumenter;
+import edu.columbia.cs.psl.wallace.Log;
+import edu.columbia.cs.psl.wallace.MethodCall;
+import edu.columbia.cs.psl.wallace.visitor.CloningAdviceAdapter;
+import edu.columbia.cs.psl.wallace.visitor.NonDeterministicLoggingMethodVisitor;
+
+public class NonDeterministicReplayMethodVisitor extends CloningAdviceAdapter implements Constants {
+	private static Logger			logger					= Logger.getLogger(NonDeterministicReplayMethodVisitor.class);
+	private String					name;
+	private String					desc;
+	private String					classDesc;
+	private int						pc;
+	private boolean					isStatic;
+	private boolean					constructor;
+	private boolean					superInitialized;
+
+
+	@Override
+	public void visitCode() {
+		super.visitCode();
+		if (!constructor)
+			superInitialized = true;
+	}
+
+	private boolean	isFirstConstructor;
+	AnalyzerAdapter	analyzer;
+
+	protected NonDeterministicReplayMethodVisitor(int api, MethodVisitor mv, int access, String name, String desc, String classDesc,
+			boolean isFirstConstructor, AnalyzerAdapter analyzer) {
+		super(api, mv, access, name, desc, classDesc, null);
+		this.name = name;
+		this.desc = desc;
+		this.classDesc = classDesc;
+		this.isStatic = (access & Opcodes.ACC_STATIC) != 0;
+		this.constructor = "<init>".equals(name);
+		this.isFirstConstructor = isFirstConstructor;
+		this.analyzer = analyzer;
+	}
+
+	private NonDeterministicReplayClassVisitor	parent;
+
+	public void setClassVisitor(NonDeterministicReplayClassVisitor coaClassVisitor) {
+		this.parent = coaClassVisitor;
+	}
+
+	@Override
+	public void visitEnd() {
+		super.visitEnd();
+		parent.addFieldMarkup(methodCallsToClear);
+		parent.addCaptureMethodsToGenerate(captureMethodsToGenerate);
+	}
+
+	private int	lineNumber	= 0;
+
+	@Override
+	public void visitLineNumber(int line, Label start) {
+		super.visitLineNumber(line, start);
+		lineNumber = line;
+	}
+
+	private void loadReplayIndex(String className, String fieldName) {
+		super.visitFieldInsn(GETSTATIC, className, fieldName + "_replayIndex", "Ljava/util/HashMap;");
+		super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(Thread.class), "currentThread", "()Ljava/lang/Thread;");
+		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(Thread.class), "getName", "()Ljava/lang/String;");
+		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(HashMap.class), "containsKey", "(Ljava/lang/Object;)Z");
+		Label exists = new Label();
+		super.visitJumpInsn(Opcodes.IFNE, exists);
+		super.visitFieldInsn(GETSTATIC, className, fieldName + "_replayIndex", "Ljava/util/HashMap;");
+		super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(Thread.class), "currentThread", "()Ljava/lang/Thread;");
+		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(Thread.class), "getName", "()Ljava/lang/String;");
+		super.visitInsn(ICONST_0);
+		super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(Integer.class), "valueOf", "(I)Ljava/lang/Integer;");
+		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(HashMap.class), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+		super.visitInsn(POP);
+		super.visitLabel(exists);
+		super.visitFieldInsn(GETSTATIC, className, fieldName + "_replayIndex", "Ljava/util/HashMap;");
+		super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(Thread.class), "currentThread", "()Ljava/lang/Thread;");
+		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(Thread.class), "getName", "()Ljava/lang/String;");
+		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(HashMap.class), "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
+		super.visitTypeInsn(CHECKCAST, "java/lang/Integer");
+		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(Integer.class), "intValue", "()I");
+//				super.visitInsn(ICONST_0);
+	}
+
+	private void incrementReplayIndex(String className, String fieldName) {
+		super.visitFieldInsn(GETSTATIC, className, fieldName + "_replayIndex", "Ljava/util/HashMap;");
+		super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(Thread.class), "currentThread", "()Ljava/lang/Thread;");
+		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(Thread.class), "getName", "()Ljava/lang/String;");
+		loadReplayIndex(className, fieldName);
+		super.visitInsn(ICONST_1);
+		super.visitInsn(IADD);
+		super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(Integer.class), "valueOf", "(I)Ljava/lang/Integer;");
+		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(HashMap.class), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+		super.visitInsn(POP);
+	}
+
+	private HashMap<String, MethodInsnNode>	captureMethodsToGenerate	= new HashMap<String, MethodInsnNode>();
+
+	@Override
+	public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+
+		try {
+			MethodCall m = new MethodCall(this.name, this.desc, this.classDesc, pc, lineNumber, owner, name, desc, isStatic);
+			Type returnType = Type.getMethodType(desc).getReturnType();
+
+			if (opcode == INVOKESPECIAL && name.equals("<init>") && NonDeterministicLoggingMethodVisitor.nonDeterministicMethods.contains(owner + "." + name + ":" + desc)) {
+
+				if (!(owner.equals(Replayer.instrumentedClasses.get(classDesc).superName) && this.name.equals("<init>"))) {
+					Type[] args = Type.getArgumentTypes(desc);
+					for (int i = args.length - 1; i >= 0; i--) {
+						Type t = args[i];
+						if (t.getSize() == 2)
+							mv.visitInsn(POP2);
+						else
+							mv.visitInsn(POP);
+					}
+
+					if (analyzer.stack != null && analyzer.stack.size() > 0
+							&& analyzer.uninitializedTypes.containsKey(analyzer.stack.get(analyzer.stack.size() - 1))
+							&& analyzer.uninitializedTypes.get(analyzer.stack.get(analyzer.stack.size() - 1)).equals(owner)) {
+						mv.visitInsn(POP);
+						if (analyzer.stack.size() > 0 && analyzer.uninitializedTypes.containsKey(analyzer.stack.get(analyzer.stack.size() - 1))
+								&& analyzer.uninitializedTypes.get(analyzer.stack.get(analyzer.stack.size() - 1)).equals(owner))
+							mv.visitInsn(POP);
+
+						String replayClassName = MethodCall.getReplayClassName(Type.getType("L"+m.getMethodOwner()+";"));
+						mv.visitFieldInsn(GETSTATIC, replayClassName, m.getLogFieldName(), "[Ljava/lang/Object;");
+
+						Label fallThrough = new Label();
+						loadReplayIndex(replayClassName, m.getLogFieldName());
+						mv.visitInsn(DUP);
+
+						mv.visitFieldInsn(GETSTATIC, replayClassName, m.getLogFieldName() + "_fill", "I");
+						mv.visitJumpInsn(Opcodes.IF_ICMPNE, fallThrough);
+						mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(ReplayRunner.class), "loadNextLog", "()V");
+						mv.visitInsn(POP);
+						loadReplayIndex(replayClassName, m.getLogFieldName());
+
+						mv.visitLabel(fallThrough);
+						//				arrayLoad(Type.getType("L"+m.getMethodOwner()+";"));
+						mv.visitInsn(AALOAD);
+						mv.visitTypeInsn(CHECKCAST, m.getMethodOwner());
+						incrementReplayIndex(replayClassName, m.getLogFieldName());
+					}
+
+				} else {
+					super.visitMethodInsn(opcode, owner, name, desc);
+				}
+
+			} else if ((!constructor || isFirstConstructor || superInitialized) && returnType.equals(Type.VOID_TYPE) && !name.equals("<init>")
+					&& NonDeterministicLoggingMethodVisitor.nonDeterministicMethods.contains(owner + "." + name + ":" + desc)) {
+				Type[] args = Type.getArgumentTypes(desc);
+				for (int i = args.length - 1; i >= 0; i--) {
+					Type t = args[i];
+					if (t.getSize() == 2)
+						mv.visitInsn(POP2);
+					else
+						mv.visitInsn(POP);
+				}
+				if (opcode != INVOKESTATIC)
+					mv.visitInsn(POP);
+
+				//				else
+				//					super.visitMethodInsn(opcode, owner, name, desc);
+
+			} else if ((!constructor || isFirstConstructor || superInitialized) && !returnType.equals(Type.VOID_TYPE)
+					&& NonDeterministicLoggingMethodVisitor.nonDeterministicMethods.contains(owner + "." + name + ":" + desc)) {
+
+				Label startOfPlayBack = new Label();
+
+				super.visitFieldInsn(GETSTATIC, Type.getInternalName(Log.class), "logLock", Type.getDescriptor(Lock.class));
+				super.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Lock.class), "lock", "()V");
+
+				logger.debug("Adding field in MV to list " + m.getLogFieldName());
+				methodCallsToClear.add(m);
+				Type[] args = Type.getArgumentTypes(desc);
+				boolean hasArray = false;
+				for (Type t : args)
+					if (t.getSort() == Type.ARRAY)
+						hasArray = true;
+
+				if (hasArray) {
+
+					Type[] targs = Type.getArgumentTypes(desc);
+					for (int i = targs.length - 1; i >= 0; i--) {
+						Type t = targs[i];
+						if (t.getSort() == Type.ARRAY) {
+							/*
+							 * stack (grows down): dest (fill not incremented yet)
+							 */
+							String replayClassName = MethodCall.getReplayClassName(t);
+							String replayFieldName = MethodCall.getLogFieldName(t);
+							mv.visitFieldInsn(GETSTATIC, replayClassName, MethodCall.getLogFieldName(t), MethodCall.getLogFieldType(t)
+									.getDescriptor());
+							//							mv.visitFieldInsn(GETSTATIC,replayClassName,
+							//									MethodCall.getLogFieldName(t)+"_replayIndex",
+							//									"I");
+							loadReplayIndex(replayClassName, replayFieldName);
+							mv.visitInsn(DUP);
+							mv.visitFieldInsn(GETSTATIC, replayClassName, MethodCall.getLogFieldName(t) + "_fill", "I");
+							Label fallThrough = new Label();
+
+							mv.visitJumpInsn(Opcodes.IF_ICMPNE, fallThrough);
+							mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(ReplayRunner.class), "loadNextLog", "()V");
+							pop();
+							loadReplayIndex(replayClassName, replayFieldName);
+							visitLabel(fallThrough);
+
+							arrayLoad(t);
+
+							/*
+							 * stack (grows down): dest src
+							 */
+							swap();
+							/*
+							 * stack (grows down): src dest
+							 */
+							push(0);
+							/*
+							 * stack (grows down): src dest 0
+							 */
+							swap();
+							/*
+							 * stack (grows down): src 0 dest
+							 */
+							push(0);
+							/*
+							 * stack (grows down): src 0 dest 0
+							 */
+
+							mv.visitFieldInsn(GETSTATIC, replayClassName, MethodCall.getLogFieldName(t), MethodCall.getLogFieldType(t)
+									.getDescriptor());
+							loadReplayIndex(replayClassName, replayFieldName);
+							arrayLoad(t);
+							mv.visitTypeInsn(Opcodes.CHECKCAST, t.getInternalName());
+							mv.visitInsn(ARRAYLENGTH);
+							incrementReplayIndex(replayClassName, replayFieldName);
+							/*
+							 * stack: src (fill incremented) 0 dest 0 length
+							 */
+							mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V");
+							/*
+							 * stack: dest popped
+							 */
+						} else {
+							switch (t.getSize()) {
+							case 2:
+								mv.visitInsn(POP2);
+								break;
+							case 1:
+							default:
+								mv.visitInsn(POP);
+								break;
+							}
+						}
+					}
+
+				} else {
+					Type[] targs = Type.getArgumentTypes(desc);
+					for (Type t : targs) {
+						switch (t.getSize()) {
+						case 2:
+							visitInsn(POP2);
+							break;
+						case 1:
+						default:
+							visitInsn(POP);
+							break;
+						}
+					}
+				}
+
+				if (opcode != INVOKESTATIC)
+					mv.visitInsn(POP);
+
+				if (returnType.getSort() == Type.VOID)
+					mv.visitInsn(NOP);
+				else {
+					mv.visitFieldInsn(GETSTATIC, m.getReplayClassName(), m.getLogFieldName(), m.getLogFieldType().getDescriptor());
+
+					loadReplayIndex(m.getReplayClassName(), m.getLogFieldName());
+					mv.visitInsn(DUP);
+					Label fallThrough = new Label();
+					mv.visitFieldInsn(GETSTATIC, m.getReplayClassName(), m.getLogFieldName() + "_fill", "I");
+					mv.visitJumpInsn(Opcodes.IF_ICMPNE, fallThrough);
+					mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(ReplayRunner.class), "loadNextLog", "()V");
+					mv.visitInsn(POP);
+					loadReplayIndex(m.getReplayClassName(), m.getLogFieldName());
+
+					mv.visitLabel(fallThrough);
+					arrayLoad(m.getReturnType());
+					incrementReplayIndex(m.getReplayClassName(), m.getLogFieldName());
+				}
+				//Unlock
+				super.visitFieldInsn(GETSTATIC, Type.getInternalName(Log.class), "logLock", Type.getDescriptor(Lock.class));
+				super.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Lock.class), "unlock", "()V");
+
+			} else {
+				super.visitMethodInsn(opcode, owner, name, desc);
+			}
+			pc++;
+		} catch (Exception ex) {
+			logger.error("Unable to instrument method call", ex);
+		}
+	}
+
+	private ArrayList<MethodCall>	methodCallsToClear	= new ArrayList<MethodCall>();
+
+	@Override
+	public void visitFieldInsn(int opcode, String owner, String name, String desc) {
+		super.visitFieldInsn(opcode, owner, name, desc);
+		pc++;
+	}
+
+	@Override
+	public void visitIincInsn(int var, int increment) {
+		super.visitIincInsn(var, increment);
+		pc++;
+	}
+
+	@Override
+	public void visitInsn(int opcode) {
+		super.visitInsn(opcode);
+		pc++;
+	}
+
+	@Override
+	public void visitIntInsn(int opcode, int operand) {
+		super.visitIntInsn(opcode, operand);
+		pc++;
+	}
+
+	@Override
+	public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
+		super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
+		pc++;
+	}
+
+	@Override
+	public void visitJumpInsn(int opcode, Label label) {
+		super.visitJumpInsn(opcode, label);
+		pc++;
+	}
+
+	@Override
+	public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
+		super.visitLookupSwitchInsn(dflt, keys, labels);
+		pc++;
+	}
+
+	@Override
+	public void visitMultiANewArrayInsn(String desc, int dims) {
+		super.visitMultiANewArrayInsn(desc, dims);
+		pc++;
+	}
+
+	@Override
+	public void visitTypeInsn(int opcode, String type) {
+		super.visitTypeInsn(opcode, type);
+		pc++;
+	}
+
+	@Override
+	public void visitVarInsn(int opcode, int var) {
+		super.visitVarInsn(opcode, var);
+		pc++;
+	}
+
+	@Override
+	public void visitLdcInsn(Object cst) {
+		super.visitLdcInsn(cst);
+		pc++;
+	}
+
+	@Override
+	public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
+		super.visitTableSwitchInsn(min, max, dflt, labels);
+		pc++;
+	}
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/replay/ReplayRunner.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/replay/ReplayRunner.java
new file mode 100644
index 0000000..e874348
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/replay/ReplayRunner.java
@@ -0,0 +1,116 @@
+package edu.columbia.cs.psl.wallace.replay;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.ObjectInputStream;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+
+import org.objectweb.asm.Type;
+
+import com.thoughtworks.xstream.XStream;
+
+import edu.columbia.cs.psl.wallace.CloningUtils;
+import edu.columbia.cs.psl.wallace.Constants;
+import edu.columbia.cs.psl.wallace.ExportedLog;
+import edu.columbia.cs.psl.wallace.ExportedSerializableLog;
+import edu.columbia.cs.psl.wallace.Log;
+import edu.columbia.cs.psl.wallace.xstream.StaticReflectionProvider;
+
+public class ReplayRunner {
+	public static String[] logFiles;
+	public static String[] serializableLogFiles;
+
+	private static int nextLog = 0;
+	private static int nextSerializableLog = 0;
+
+	public static void loadNextLog(String logClass) {
+		try {
+			Log.logLock.lock();
+			_loadNextLog(logClass);
+			Log.logLock.unlock();
+		} catch (Exception exi) {
+			exi.printStackTrace();
+		}
+	}
+
+	private static void _loadNextLog(String logClass) {
+		try {
+			if (logClass.contains("Serializable")) {
+				ObjectInputStream is = new ObjectInputStream(new FileInputStream(serializableLogFiles[nextSerializableLog]));
+				ExportedSerializableLog el = (ExportedSerializableLog) is.readObject();
+				nextSerializableLog++;
+			} else {
+				XStream xstream = new XStream(new StaticReflectionProvider());
+				Object o = xstream.fromXML(new File(logFiles[nextLog]));
+				nextLog++;
+			}
+		} catch (Exception exi) {
+			exi.printStackTrace();
+		}
+	}
+
+	public static void main(String[] args) {
+		if (args.length < 2) {
+			System.err.println("Usage: ReplayRunner <mainClass> log [log2...logN] class_args [arg1...argM]");
+			System.exit(-1);
+		}
+		String mainClass = args[0];
+		logFiles = new String[args.length - 1];
+		serializableLogFiles = new String[args.length - 1];
+		int class_args = args.length;
+		int nLogs = 0;
+		int nSerializableLogs = 0;
+
+		for (int i = 1; i < args.length; i++) {
+			if (!args[i].equals("class_args"))
+				if (args[i].contains("_serializable_")) {
+					serializableLogFiles[nSerializableLogs] = args[i];
+					nSerializableLogs++;
+				} else {
+					logFiles[nLogs] = args[i];
+					nLogs++;
+				}
+			else {
+				class_args = i + 1;
+				break;
+			}
+		}
+
+		System.out.println("Available logs: " + Arrays.deepToString(logFiles));
+		_loadNextLog(Type.getDescriptor(ExportedLog.class));
+		_loadNextLog(Type.getDescriptor(ExportedSerializableLog.class));
+		Class<?> toRun;
+		try {
+			toRun = Class.forName(mainClass);
+			Method meth = toRun.getMethod("main", String[].class);
+			String[] params = new String[args.length - class_args];
+			if (class_args < args.length)
+				System.arraycopy(args, class_args, params, 0, params.length);
+			meth.invoke(null, new Object[] { params });
+		} catch (ClassNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IllegalArgumentException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (SecurityException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IllegalAccessException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (InvocationTargetException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (NoSuchMethodException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/replay/Replayer.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/replay/Replayer.java
new file mode 100644
index 0000000..a2a209a
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/replay/Replayer.java
@@ -0,0 +1,426 @@
+package edu.columbia.cs.psl.wallace.replay;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.channels.FileChannel;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Scanner;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+
+import org.apache.log4j.Logger;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.commons.GeneratorAdapter;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.FieldNode;
+import org.objectweb.asm.util.CheckClassAdapter;
+
+import edu.columbia.cs.psl.wallace.Constants;
+import edu.columbia.cs.psl.wallace.InstrumenterClassWriter;
+import edu.columbia.cs.psl.wallace.MethodCall;
+import edu.columbia.cs.psl.wallace.analysis.MutabilityAnalyzer;
+import edu.columbia.cs.psl.wallace.struct.AnnotatedMethod;
+
+public class Replayer {
+	public static URLClassLoader loader;
+	private static Logger logger = Logger.getLogger(Replayer.class);
+	public static HashMap<String, AnnotatedMethod> annotatedMethods = new HashMap<String, AnnotatedMethod>();
+	public static HashMap<String, ClassNode> instrumentedClasses = new HashMap<String, ClassNode>();
+
+	private static MutabilityAnalyzer ma = new MutabilityAnalyzer(
+			annotatedMethods);
+	private static HashMap<String, HashSet<MethodCall>> methodCalls = new HashMap<String, HashSet<MethodCall>>();
+	private static final int NUM_PASSES = 2;
+	private static final int PASS_ANALYZE = 0;
+	private static final int PASS_OUTPUT = 1;
+
+	private static int pass_number = 0;
+
+	private static File rootOutputDir;
+	private static String lastInstrumentedClass;
+
+	public static AnnotatedMethod getAnnotatedMethod(String owner, String name,
+			String desc) {
+		String lookupKey = owner + "." + name + ":" + desc;
+		return annotatedMethods.get(lookupKey);
+	}
+
+	private static void analyzeClass(InputStream inputStream) {
+		try {
+			ClassNode ret = ma.analyzeClass(new ClassReader(inputStream));
+			instrumentedClasses.put(ret.name, ret);
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	private static void finishedPass() {
+		switch (pass_number) {
+		case PASS_ANALYZE:
+			ma.doneSupplyingClasses();
+			break;
+		case PASS_OUTPUT:
+			break;
+		}
+	}
+
+	/*
+	 * private static byte[] generateReplayClass(String className) { ClassWriter
+	 * cw = new InstrumenterClassWriter(ClassWriter.COMPUTE_MAXS |
+	 * ClassWriter.COMPUTE_FRAMES, loader); cw.visit(49, Opcodes.ACC_PUBLIC,
+	 * className+Constants.LOG_CLASS_SUFFIX, null, "java/lang/Object", null);
+	 * cw.visitSource(null, null); MethodVisitor mv =
+	 * cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "<clinit>",
+	 * "()V", null, null); GeneratorAdapter mvz = new GeneratorAdapter(mv,
+	 * Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "<clinit>", "()V");
+	 * mvz.visitCode(); for (MethodCall call : methodCalls.get(className)) {
+	 * mvz.push(Constants.DEFAULT_LOG_SIZE);
+	 * mvz.newArray(Type.getMethodType(call.getMethodDesc()).getReturnType());
+	 * mvz.putStatic(Type.getType("L"+className +
+	 * Constants.LOG_CLASS_SUFFIX+";"), call.getLogFieldName(), Type.getType("["
+	 * +
+	 * Type.getMethodType(call.getMethodDesc()).getReturnType().getDescriptor()
+	 * ));
+	 *
+	 * Type[] argTypes = Type.getArgumentTypes(call.getMethodDesc()); for(int i
+	 * = 0; i < argTypes.length; i++) { if(argTypes[i].getSort() == Type.ARRAY)
+	 * { mvz.push(Constants.DEFAULT_LOG_SIZE); mvz.newArray(argTypes[i]);
+	 * mvz.putStatic(Type.getType("L"+className +
+	 * Constants.LOG_CLASS_SUFFIX+";"), call.getLogFieldName() + "_"+i,
+	 * Type.getType("[" + argTypes[i].getDescriptor())); } } } mvz.visitMaxs(0,
+	 * 0); mvz.returnValue(); mvz.visitEnd();
+	 *
+	 * { mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
+	 * mv.visitVarInsn(Opcodes.ALOAD, 0);
+	 * mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>",
+	 * "()V"); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(1, 1); mv.visitEnd();
+	 * } for (MethodCall call : methodCalls.get(className)) { int opcode =
+	 * Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC; FieldNode fn = new
+	 * FieldNode(Opcodes.ASM4, opcode, call.getLogFieldName(), "[" +
+	 * Type.getMethodType(call.getMethodDesc()).getReturnType().getDescriptor(),
+	 * null, null); fn.accept(cw); FieldNode fn2 = new FieldNode(Opcodes.ASM4,
+	 * opcode, call.getLogFieldName() + "_fill", Type.INT_TYPE.getDescriptor(),
+	 * null, 0); fn2.accept(cw);
+	 *
+	 * Type[] argTypes = Type.getArgumentTypes(call.getMethodDesc()); for(int i
+	 * = 0; i < argTypes.length; i++) { if(argTypes[i].getSort() == Type.ARRAY)
+	 * { fn = new FieldNode(Opcodes.ASM4, opcode, call.getLogFieldName()+"_"+i,
+	 * "[" + argTypes[i].getDescriptor(), null, null); fn.accept(cw); fn2 = new
+	 * FieldNode(Opcodes.ASM4, opcode, call.getLogFieldName()+"_"+i + "_fill",
+	 * Type.INT_TYPE.getDescriptor(), null, 0); fn2.accept(cw);
+	 *
+	 * mvz.push(Constants.DEFAULT_LOG_SIZE); mvz.newArray(argTypes[i]);
+	 * mvz.putStatic(Type.getType("L"+className +
+	 * Constants.LOG_CLASS_SUFFIX+";"), call.getLogFieldName() + i,
+	 * Type.getType("[" + argTypes[i].getDescriptor())); }
+	 *
+	 * } } cw.visitEnd(); System.out.println("We are on: " + className); return
+	 * cw.toByteArray(); }
+	 */
+
+
+	private static byte[] instrumentClass(InputStream is) {
+		try {
+			ClassReader cr = new ClassReader(is);
+			ClassWriter cw = new InstrumenterClassWriter(cr,
+					ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES,
+					loader);
+			NonDeterministicReplayClassVisitor cv = new NonDeterministicReplayClassVisitor(
+					Opcodes.ASM4, cw);
+			cr.accept(cv, ClassReader.EXPAND_FRAMES);
+			methodCalls.put(cv.getClassName(), cv.getLoggedMethodCalls());
+			lastInstrumentedClass = cv.getClassName();
+			byte[] out = cw.toByteArray();
+			try{
+				 ClassReader cr2 = new ClassReader(out);
+				 cr2.accept(new CheckClassAdapter(new ClassWriter(0)), 0);
+				}
+				catch(Exception ex)
+				{
+					System.err.println(lastInstrumentedClass);
+					ex.printStackTrace();
+				}
+
+			return out;
+		} catch (Exception ex) {
+			logger.error("Exception processing class:", ex);
+			return null;
+		}
+	}
+
+	public static void main(String[] args) {
+		if (args.length <= 1) {
+			System.err
+					.println("Usage: java edu.columbia.cs.psl.wallace.replay.Replayer [outputFolder] [inputfolder] [classpath]\n Paths can be classes, directories, or jar files");
+			System.exit(-1);
+		}
+		String outputFolder = args[0];
+		rootOutputDir = new File(outputFolder);
+		if (!rootOutputDir.exists())
+			rootOutputDir.mkdir();
+		String inputFolder = args[1];
+		// Setup the class loader
+		URL[] urls = new URL[args.length - 2];
+		for (int i = 2; i < args.length; i++) {
+			File f = new File(args[i]);
+			if (!f.exists()) {
+				System.err.println("Unable to read path " + args[i]);
+				System.exit(-1);
+			}
+			if (f.isDirectory() && !f.getAbsolutePath().endsWith("/"))
+				f = new File(f.getAbsolutePath() + "/");
+			try {
+				urls[i - 2] = f.getCanonicalFile().toURI().toURL();
+			} catch (Exception ex) {
+				ex.printStackTrace();
+			}
+		}
+		loader = new URLClassLoader(urls, Replayer.class.getClassLoader());
+
+		for (pass_number = 0; pass_number < NUM_PASSES; pass_number++) // Do
+																		// each
+																		// pass.
+		{
+			File f = new File(inputFolder);
+			if (!f.exists()) {
+				System.err.println("Unable to read path " + inputFolder);
+				System.exit(-1);
+			}
+			if (f.isDirectory())
+				processDirectory(f, rootOutputDir, true);
+			else if (inputFolder.endsWith(".jar"))
+				processJar(f, rootOutputDir);
+			else if (inputFolder.endsWith(".class"))
+				try {
+					processClass(f.getName(), new FileInputStream(f),
+							rootOutputDir);
+				} catch (FileNotFoundException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			else {
+				System.err.println("Unknown type for path " + inputFolder);
+				System.exit(-1);
+			}
+			finishedPass();
+		}
+		// }
+
+	}
+
+	private static void processClass(String name, InputStream is, File outputDir) {
+		ByteArrayOutputStream bos = null;
+		FileOutputStream fos = null;
+
+		switch (pass_number) {
+		case PASS_ANALYZE:
+			analyzeClass(is);
+			break;
+		case PASS_OUTPUT:
+			try {
+				File f = new File(outputDir.getPath()
+						+ File.separator + name);
+				if(f.exists())
+					f.delete();
+				fos = new FileOutputStream(f);
+				bos = new ByteArrayOutputStream();
+				bos.write(instrumentClass(is));
+
+//				if (name.contains("Reader")) {
+//					ReplayRunner.run(bos.toByteArray(), "ReaderUser");
+//				}
+
+			} catch (Exception ex) {
+				ex.printStackTrace();
+				System.exit(-1);
+			} finally {
+				try {
+					bos.writeTo(fos);
+					fos.close();
+				} catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+		}
+	}
+
+	/*
+	 * private static byte[] generateReplayClass() { return
+	 * generateReplayClass(lastInstrumentedClass); }
+	 */
+
+	private static void processDirectory(File f, File parentOutputDir,
+			boolean isFirstLevel) {
+		File thisOutputDir;
+		if (isFirstLevel) {
+			thisOutputDir = parentOutputDir;
+		} else {
+			thisOutputDir = new File(parentOutputDir.getAbsolutePath()
+					+ File.separator + f.getName());
+			if (pass_number == PASS_OUTPUT)
+				thisOutputDir.mkdir();
+		}
+		for (File fi : f.listFiles()) {
+			if (fi.isDirectory())
+				processDirectory(fi, thisOutputDir, false);
+			else if (fi.getName().endsWith(".class"))
+				try {
+					processClass(fi.getName(), new FileInputStream(fi),
+							thisOutputDir);
+				} catch (FileNotFoundException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			else if (fi.getName().endsWith(".jar"))
+				processJar(fi, thisOutputDir);
+			else if (pass_number == PASS_OUTPUT) {
+				File dest = new File(thisOutputDir.getPath() + File.separator
+						+ fi.getName());
+				FileChannel source = null;
+				FileChannel destination = null;
+
+				try {
+					source = new FileInputStream(fi).getChannel();
+					destination = new FileOutputStream(dest).getChannel();
+					destination.transferFrom(source, 0, source.size());
+				} catch (Exception ex) {
+					logger.error("Unable to copy file " + fi, ex);
+					System.exit(-1);
+				} finally {
+					if (source != null) {
+						try {
+							source.close();
+						} catch (IOException e) {
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						}
+					}
+					if (destination != null) {
+						try {
+							destination.close();
+						} catch (IOException e) {
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						}
+					}
+				}
+
+			}
+		}
+
+	}
+
+	private static void processJar(File f, File outputDir) {
+		try {
+			JarFile jar = new JarFile(f);
+			JarOutputStream jos = null;
+			if (pass_number == PASS_OUTPUT)
+				jos = new JarOutputStream(new FileOutputStream(
+						outputDir.getPath() + File.separator + f.getName()));
+			Enumeration<JarEntry> entries = jar.entries();
+			while (entries.hasMoreElements()) {
+				JarEntry e = entries.nextElement();
+				switch (pass_number) {
+				case PASS_ANALYZE:
+					if (e.getName().endsWith(".class")) {
+						analyzeClass(jar.getInputStream(e));
+					}
+					break;
+				case PASS_OUTPUT:
+					if (e.getName().endsWith(".class")
+							&& !e.getName().startsWith("java")
+							&& !e.getName().startsWith("org/objenesis")
+							&& !e.getName().startsWith(
+									"com/thoughtworks/xstream/")
+							&& !e.getName().startsWith("com/rits/cloning")
+							&& !e.getName().startsWith(
+									"com/apple/java/Application")) {
+						{
+							JarEntry outEntry = new JarEntry(e.getName());
+							jos.putNextEntry(outEntry);
+							byte[] clazz = instrumentClass(jar
+									.getInputStream(e));
+							jos.write(clazz);
+							jos.closeEntry();
+						}
+						{
+							/*
+							 * JarEntry outEntry = new
+							 * JarEntry(e.getName().replace(".class",
+							 * Constants.LOG_CLASS_SUFFIX +".class"));
+							 * jos.putNextEntry(outEntry); byte[] clazz =
+							 * generateReplayClass(); jos.write(clazz);
+							 * jos.closeEntry();
+							 */
+						}
+
+					} else {
+						JarEntry outEntry = new JarEntry(e.getName());
+						if (e.isDirectory()) {
+							jos.putNextEntry(outEntry);
+							jos.closeEntry();
+						} else if (e.getName().startsWith("META-INF")
+								&& (e.getName().endsWith(".SF") || e.getName()
+										.endsWith(".RSA"))) {
+							// don't copy this
+						} else if (e.getName().equals("META-INF/MANIFEST.MF")) {
+							String newManifest = "";
+							Scanner s = new Scanner(jar.getInputStream(e));
+							jos.putNextEntry(outEntry);
+
+							String curPair = "";
+							while (s.hasNextLine()) {
+								String line = s.nextLine();
+								if (line.equals("")) {
+									curPair += "\n";
+									if (!curPair.contains("SHA1-Digest:"))
+										jos.write(curPair.getBytes());
+									curPair = "";
+								} else {
+									curPair += line + "\n";
+								}
+							}
+							jos.write("\n".getBytes());
+							jos.closeEntry();
+						} else {
+							jos.putNextEntry(outEntry);
+							InputStream is = jar.getInputStream(e);
+							byte[] buffer = new byte[1024];
+							while (true) {
+								int count = is.read(buffer);
+								if (count == -1)
+									break;
+								jos.write(buffer, 0, count);
+							}
+							jos.closeEntry();
+						}
+					}
+				}
+
+			}
+			if (pass_number == PASS_OUTPUT) {
+				jos.close();
+			}
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			logger.error("Unable to process jar" + f, e);
+			System.exit(-1);
+		}
+
+	}
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/struct/AnnotatedMethod.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/struct/AnnotatedMethod.java
new file mode 100644
index 0000000..f99b292
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/struct/AnnotatedMethod.java
@@ -0,0 +1,156 @@
+package edu.columbia.cs.psl.wallace.struct;
+
+import java.util.LinkedList;
+
+import org.objectweb.asm.commons.Method;
+
+public class AnnotatedMethod {
+
+	/**
+	 * Encoded access flags for this method. private int access
+	 *
+	 * @see Method
+	 */
+	private int access;
+
+	/**
+	 * Fully qualified class name of the class owning this method. private
+	 * String clazz
+	 */
+	private String clazz;
+
+	public LinkedList<AnnotatedMethod> functionsThatCallMe = new LinkedList<AnnotatedMethod>();
+
+	public LinkedList<MethodExpression> functionsThatICall = new LinkedList<MethodExpression>();
+
+	private LinkedList<FieldExpression> putFieldInsns = new LinkedList<FieldExpression>();
+
+	/**
+	 * ASM method at the core of this MethodInstance object. private Method
+	 * method
+	 *
+	 * @see Method
+	 */
+	private Method method;
+
+	private boolean mutatesFieldsDirectly;
+	private boolean mutatesFields;
+	private boolean isFullyDiscovered;
+
+	public String getName()
+	{
+		return this.method.getName();
+	}
+
+	public String getDescriptor()
+	{
+		return this.method.getDescriptor();
+	}
+	public AnnotatedMethod(String fullName) {
+
+		String[] pieces = fullName.split("\\.|:");
+		this.clazz = pieces[0];
+		this.method = new Method(pieces[1], pieces[2]);
+	}
+
+	/**
+	 * Constructor for MethodInstance - accepts method name, method description,
+	 * class name, and access flag.
+	 *
+	 * @param name
+	 *            String name of method
+	 * @param desc
+	 *            String method descriptor
+	 * @param clazz
+	 *            String fully qualified class name
+	 * @param access
+	 *            int access flags in decimal
+	 */
+	public AnnotatedMethod(String name, String desc, String clazz, int access) {
+		this.method = new Method(name, desc);
+		this.clazz = clazz;
+		this.access = access;
+	}
+
+	/**
+	 * (Override) This function declares two MethodInstances A, B "equal" if and
+	 * only if: ((A.getMethod().equals(B.getMethod)) &&
+	 * (A.getClazz().equals(B.getClazz())) == true
+	 *
+	 * @see Object#equals(Object)
+	 * @see AnnotatedMethod#hashCode()
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		if (obj.getClass().equals(this.getClass())) {
+			AnnotatedMethod other = (AnnotatedMethod) obj;
+			if ((other.getClazz().equals(this.getClazz()))
+					&& (other.getMethod().getName().equals(this.getMethod().getName()) && other.getMethod().getDescriptor().equals(this.getMethod().getDescriptor())))
+				return true;
+		}
+		return false;
+	}
+
+	public int getAccess() {
+		return access;
+	}
+
+	/**
+	 * Get the owner class name.
+	 *
+	 * @return String
+	 */
+	public String getClazz() {
+		return clazz;
+	}
+
+	public String getFullName() {
+		return this.clazz + "." + this.method.getName() + ":" + this.method.getDescriptor();
+	}
+
+	/**
+	 * Get the Method underlying this MethodInstance.
+	 *
+	 * @return Method
+	 */
+	public Method getMethod() {
+		return method;
+	}
+
+	@Override
+	public int hashCode() {
+		return this.getClazz().hashCode() * this.getMethod().getName().hashCode() * this.getMethod().getDescriptor().hashCode();
+	}
+
+	@Override
+	public String toString() {
+		return "MethodInstance [method=" + method + ", class=" + clazz + "]";
+	}
+
+	public LinkedList<FieldExpression> getPutFieldInsns() {
+		return putFieldInsns;
+	}
+	public boolean isMutatesFields() {
+		return mutatesFields;
+	}
+	public boolean isMutatesFieldsDirectly() {
+		return mutatesFieldsDirectly;
+	}
+	public void setMutatesFieldsDirectly() {
+		this.mutatesFieldsDirectly = true;
+	}
+	public void setMutatesFields() {
+		this.mutatesFields = true;
+	}
+
+	public void setAccess(int access) {
+		this.access = access;
+	}
+	public boolean isFullyDiscovered() {
+		return isFullyDiscovered;
+	}
+	public void setFullyDiscovered(boolean isFullyDiscovered) {
+		this.isFullyDiscovered = isFullyDiscovered;
+	}
+
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/struct/Expression.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/struct/Expression.java
new file mode 100644
index 0000000..321a3b0
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/struct/Expression.java
@@ -0,0 +1,34 @@
+package edu.columbia.cs.psl.wallace.struct;
+
+
+public abstract class Expression {
+	public abstract int getType();
+	public static int FIELD_TYPE = 1;
+	public static int METHOD_TYPE = 2;
+	public static int CONSTANT_TYPE = 3;
+	public Expression getParent()
+	{
+		return parent;
+	}
+	public void setParent(Expression ir){
+		this.parent = ir;
+	}
+	public Expression getRootParent()
+	{
+		if(getParent() == null)
+			return this;
+		else
+			return getParent().getRootParent();
+	}
+	private Expression parent;
+	public abstract int getStackElementsToSkip();
+	public abstract int getOpcode();
+
+	public String printParents() {
+		String r = "";
+		if (getParent() != null)
+			r += getParent().printParents() + ".";
+		r += toString();
+		return r;
+	}
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/struct/FieldExpression.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/struct/FieldExpression.java
new file mode 100644
index 0000000..ae49ee9
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/struct/FieldExpression.java
@@ -0,0 +1,49 @@
+package edu.columbia.cs.psl.wallace.struct;
+
+import org.objectweb.asm.Opcodes;
+
+public class FieldExpression extends Expression {
+	private String name;
+	private String owner;
+	private String desc;
+	private int opcode;
+
+	public FieldExpression(String name, String owner, String desc, int opcode)
+	{
+		this.name = name;
+		this.owner = owner;
+		this.desc = desc;
+		this.opcode = opcode;
+	}
+	@Override
+	public int getOpcode() {
+		return opcode;
+	}
+	public String getName() {
+		return name;
+	}
+	public String getOwner() {
+		return owner;
+	}
+	public String getDesc() {
+		return desc;
+	}
+
+	@Override
+	public int getType() {
+		return FIELD_TYPE;
+	}
+
+	@Override
+	public int getStackElementsToSkip() {
+		if(opcode == Opcodes.GETFIELD || opcode == Opcodes.GETSTATIC)
+			return 0;
+		return 1;
+	}
+
+	@Override
+	public String toString() {
+//		return "FieldInvocation [name=" + name + ", owner=" + owner + ", desc=" + desc + "]";
+		return name;
+	}
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/struct/MethodExpression.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/struct/MethodExpression.java
new file mode 100644
index 0000000..8c04f14
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/struct/MethodExpression.java
@@ -0,0 +1,71 @@
+package edu.columbia.cs.psl.wallace.struct;
+
+import java.util.Stack;
+
+public class MethodExpression extends Expression {
+	@Override
+	public String toString() {
+		String r ="";
+		if(method.getMethod().getName().equals("<init>"))
+			r+="new "+method.getClazz()+"(";
+		else
+			r += method.getMethod().getName()+"(";
+
+		for(int j = 0; j<params.size() - (method.getMethod().getName().equals("<init>") ? 2: 0); j++)
+		{
+			Expression i = params.get(j);
+			Expression parent = i.getParent();
+			String paramParent = "";
+			while(parent != null)
+			{
+				paramParent = parent.toString()+"."+paramParent;
+				parent = parent.getParent();
+			}
+			r+= paramParent;
+			r += i.toString();
+			if(j != params.size() - 1 - (method.getMethod().getName().equals("<init>") ? 2 : 0))
+				r += ",";
+		}
+		r+=")";
+		return r;
+
+	}
+	private Stack<Expression> params = new Stack<Expression>();
+
+	private AnnotatedMethod method;
+	private int opcode;
+	public MethodExpression(AnnotatedMethod method, int opcode)
+	{
+
+		this.method = method;
+		this.opcode = opcode;
+	}
+	@Override
+	public int getOpcode() {
+		return opcode;
+	}
+	@Override
+	public int getType() {
+		return METHOD_TYPE;
+	}
+	public Stack<Expression> getParams() {
+		return params;
+	}
+
+	public AnnotatedMethod getMethod() {
+		return method;
+	}
+	public int getNumParamsNeeded()
+	{
+		return (method.getMethod().getName().equals("<init>") ? 2 : 0) + method.getMethod().getArgumentTypes().length;
+	}
+
+	public boolean hasAllParameters() {
+		// TODO Auto-generated method stub
+		return getNumParamsNeeded() == params.size();
+	}
+	@Override
+	public int getStackElementsToSkip() {
+		return (method.getMethod().getName().equals("<init>") ? 1 : 0) + method.getMethod().getArgumentTypes().length;
+	}
+}
\ No newline at end of file
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/struct/SimpleExpression.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/struct/SimpleExpression.java
new file mode 100644
index 0000000..3f96800
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/struct/SimpleExpression.java
@@ -0,0 +1,65 @@
+package edu.columbia.cs.psl.wallace.struct;
+
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.LdcInsnNode;
+import org.objectweb.asm.tree.TypeInsnNode;
+import org.objectweb.asm.tree.VarInsnNode;
+import org.objectweb.asm.util.Printer;
+
+public class SimpleExpression extends Expression {
+	private AbstractInsnNode insn;
+
+	@Override
+	public int getOpcode() {
+		return insn.getOpcode();
+	}
+
+	public SimpleExpression(AbstractInsnNode insn) {
+		this.insn = insn;
+	}
+
+	public AbstractInsnNode getInsn() {
+		return insn;
+	}
+
+	@Override
+	public Expression getParent() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public void setParent(Expression ir) {
+
+	}
+
+	@Override
+	public int getType() {
+		return CONSTANT_TYPE;
+	}
+
+	@Override
+	public int getStackElementsToSkip() {
+		return 0;
+	}
+
+	public String getDesc() {
+		switch (insn.getType()) {
+		case AbstractInsnNode.TYPE_INSN:
+			return ((TypeInsnNode) insn).desc;
+		case AbstractInsnNode.VAR_INSN:
+			return "" + ((VarInsnNode) insn).var;
+		case AbstractInsnNode.LDC_INSN:
+			return ((LdcInsnNode) insn).cst.toString();
+		default:
+			return "";
+		}
+
+	}
+
+	@Override
+	public String toString() {
+		return "[" + Printer.OPCODES[getOpcode()] + " " + getDesc() + "]";
+	}
+
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/visitor/CloningAdviceAdapter.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/visitor/CloningAdviceAdapter.java
new file mode 100644
index 0000000..4be9f24
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/visitor/CloningAdviceAdapter.java
@@ -0,0 +1,377 @@
+package edu.columbia.cs.psl.wallace.visitor;
+
+import java.util.HashSet;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.AdviceAdapter;
+import org.objectweb.asm.commons.GeneratorAdapter;
+import org.objectweb.asm.commons.LocalVariablesSorter;
+import org.objectweb.asm.commons.Method;
+import org.objectweb.asm.tree.FieldNode;
+
+import edu.columbia.cs.psl.wallace.CloningUtils;
+import edu.columbia.cs.psl.wallace.Constants;
+import edu.columbia.cs.psl.wallace.Instrumenter;
+import edu.columbia.cs.psl.wallace.Log;
+import edu.columbia.cs.psl.wallace.SerializableLog;
+import edu.columbia.cs.psl.wallace.WallaceExportRunner;
+
+public class CloningAdviceAdapter extends GeneratorAdapter implements Opcodes {
+
+	private static final HashSet<String> ignoredClasses = new HashSet<String>();
+	private static boolean flexibleLog = false;
+
+	private static final HashSet<String> immutableClasses = new HashSet<String>();
+	static {
+		immutableClasses.add("Ljava/lang/Integer;");
+		immutableClasses.add("Ljava/lang/Long;");
+		immutableClasses.add("Ljava/lang/Short;");
+		immutableClasses.add("Ljava/lang/Float;");
+		immutableClasses.add("Ljava/lang/String;");
+		immutableClasses.add("Ljava/lang/Char;");
+		immutableClasses.add("Ljava/lang/Byte;");
+		immutableClasses.add("Ljava/lang/Integer;");
+		immutableClasses.add("Ljava/lang/Long;");
+		immutableClasses.add("Ljava/lang/Short;");
+		immutableClasses.add("Ljava/lang/Float;");
+		immutableClasses.add("Ljava/lang/String;");
+		immutableClasses.add("Ljava/lang/Char;");
+		immutableClasses.add("Ljava/lang/Byte;");
+		immutableClasses.add("Ljava/sql/ResultSet;");
+		immutableClasses.add("Ljava/lang/Class;");
+		immutableClasses.add("Z");
+		immutableClasses.add("B");
+		immutableClasses.add("C");
+		immutableClasses.add("S");
+		immutableClasses.add("I");
+		immutableClasses.add("J");
+		immutableClasses.add("F");
+		immutableClasses.add("L");
+
+	}
+	private String className;
+
+	private LocalVariablesSorter lvsorter;
+
+	public CloningAdviceAdapter(int api, MethodVisitor mv, int access, String name, String desc, String classname, LocalVariablesSorter lvsorter) {
+		super(api, mv, access, name, desc);
+		this.className = classname;
+		this.lvsorter = lvsorter;
+	}
+
+	/**
+	 * Precondition: Current element at the top of the stack is the element we
+	 * need cloned Post condition: Current element at the top of the stack is
+	 * the cloned element (and non-cloned is removed)
+	 */
+
+	protected void cloneValAtTopOfStack(String typeOfField) {
+		_generateClone(typeOfField, Constants.OUTER_COPY_METHOD_NAME, null, false);
+	}
+
+	protected void cloneValAtTopOfStack(String typeOfField, String debug, boolean secondElHasArrayLen) {
+		_generateClone(typeOfField, Constants.OUTER_COPY_METHOD_NAME, debug, secondElHasArrayLen);
+	}
+
+	protected void generateCloneInner(String typeOfField) {
+		_generateClone(typeOfField, Constants.INNER_COPY_METHOD_NAME, null, false);
+	}
+
+	public void println(String toPrint) {
+		visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+		visitLdcInsn(toPrint + " : ");
+		super.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print", "(Ljava/lang/String;)V");
+
+		visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+		super.visitMethodInsn(INVOKESTATIC, "java/lang/Thread", "currentThread", "()Ljava/lang/Thread;");
+		super.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Thread", "getName", "()Ljava/lang/String;");
+		super.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
+	}
+
+	private void _generateClone(String typeOfField, String copyMethodToCall, String debug, boolean secondElHasArrayLen) {
+		Type fieldType = Type.getType(typeOfField);
+
+		if (
+		// fieldType.getSort() == Type.ARRAY &&
+		// fieldType.getElementType().getSort()
+		// ||
+		fieldType.getSort() == Type.VOID || (fieldType.getSort() != Type.ARRAY && (fieldType.getSort() != Type.OBJECT || immutableClasses.contains(typeOfField)))) {
+			// println("reference> " + debug);
+			// println(debug);
+			// println("Doing nothing");
+			return;
+		}
+		if (fieldType.getSort() == Type.ARRAY) {
+			if (fieldType.getElementType().getSort() != Type.OBJECT || immutableClasses.contains(fieldType.getElementType().getDescriptor())) {
+				// println("array> " + debug);
+
+				// Just need to duplicate the array
+				dup();
+				Label nullContinue = new Label();
+				ifNull(nullContinue);
+				if (secondElHasArrayLen) {
+					swap();
+					// pop();
+					// swap();
+					// dup();
+					// visitFieldInsn(GETSTATIC, "java/lang/System", "out",
+					// "Ljava/io/PrintStream;");
+					// swap();
+					// super.visitMethodInsn(INVOKEVIRTUAL,
+					// "java/io/PrintStream", "println", "(I)V");
+				} else {
+					dup();
+					visitInsn(ARRAYLENGTH);
+				}
+				dup();
+				newArray(Type.getType(fieldType.getDescriptor().substring(1)));
+				dupX2();
+				swap();
+				push(0);
+				dupX2();
+				swap();
+				super.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V");
+				Label noNeedToPop = new Label();
+				if (secondElHasArrayLen) {
+					visitJumpInsn(GOTO, noNeedToPop);
+					visitLabel(nullContinue);
+					swap();
+					pop();
+				} else {
+					visitLabel(nullContinue);
+				}
+
+				visitLabel(noNeedToPop);
+
+			} else {
+				// println("heavy> " + debug);
+				// Just use the reflective cloner
+				visitLdcInsn(debug);
+				invokeStatic(Type.getType(CloningUtils.class), Method.getMethod("Object clone(Object, String)"));
+				checkCast(fieldType);
+			}
+		} else if (fieldType.getClassName().contains("InputStream") || fieldType.getClassName().contains("OutputStream") || fieldType.getClassName().contains("Socket")) {
+			// Do nothing
+		} else {
+			// println("heavy> " + debug);
+			visitLdcInsn(debug);
+			invokeStatic(Type.getType(CloningUtils.class), Method.getMethod("Object clone(Object, String)"));
+			checkCast(fieldType);
+
+		}
+	}
+
+	// private static Object[] ar;
+	// private void magic()
+	// {
+	// new WallaceExportRunner().
+	// }
+	protected void logValueAtTopOfStackToArray(String logFieldOwner, String logFieldName, String logFieldTypeDesc, Type elementType, boolean isStaticLoggingField, String debug,
+			boolean secondElHasArrayLen) {
+		int getOpcode = (isStaticLoggingField ? Opcodes.GETSTATIC : Opcodes.GETFIELD);
+		int putOpcode = (isStaticLoggingField ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD);
+
+		//Lock
+		super.visitFieldInsn(GETSTATIC, Type.getInternalName(Log.class), "logLock", Type.getDescriptor(Lock.class));
+		super.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Lock.class), "lock", "()V");
+
+		// Grow the array if necessary
+
+		super.visitFieldInsn(getOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());
+		super.visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
+		super.arrayLength();
+		Label labelForNoNeedToGrow = new Label();
+		super.ifCmp(Type.INT_TYPE, Opcodes.IFNE, labelForNoNeedToGrow);
+		// In this case, it's necessary to grow it
+		// Create the new array and initialize its size
+
+		int newArray = newLocal(Type.getType(logFieldTypeDesc));
+		visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
+		arrayLength();
+		visitInsn(Opcodes.I2D);
+		visitLdcInsn(Constants.LOG_GROWTH_RATE);
+		visitInsn(Opcodes.DMUL);
+		visitInsn(Opcodes.D2I);
+
+		newArray(Type.getType(logFieldTypeDesc.substring(1))); // Bug in
+																// ASM
+																// prevents
+																// us
+																// from
+																// doing
+																// type.getElementType
+		storeLocal(newArray, Type.getType(logFieldTypeDesc));
+		visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
+		visitInsn(Opcodes.ICONST_0);
+		loadLocal(newArray);
+		visitInsn(Opcodes.ICONST_0);
+		visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
+		arrayLength();
+		visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V");
+
+		// array = newarray
+
+		loadLocal(newArray);
+		visitFieldInsn(putOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
+
+		int newArray2 = newLocal(Type.getType("[Ljava/lang/String;"));
+		visitFieldInsn(getOpcode, logFieldOwner, logFieldName+"_owners", "[Ljava/lang/String;");
+		arrayLength();
+		visitInsn(Opcodes.I2D);
+		visitLdcInsn(Constants.LOG_GROWTH_RATE);
+		visitInsn(Opcodes.DMUL);
+		visitInsn(Opcodes.D2I);
+
+		newArray(Type.getType("Ljava/lang/String;"));
+
+		storeLocal(newArray2, Type.getType("[Ljava/lang/String;"));
+		visitFieldInsn(getOpcode, logFieldOwner, logFieldName+"_owners", "[Ljava/lang/String;");
+		visitInsn(Opcodes.ICONST_0);
+		loadLocal(newArray2);
+		visitInsn(Opcodes.ICONST_0);
+		visitFieldInsn(getOpcode, logFieldOwner, logFieldName+"_owners", "[Ljava/lang/String;");
+		arrayLength();
+		visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V");
+
+		// array = newarray
+
+		loadLocal(newArray2);
+		visitFieldInsn(putOpcode, logFieldOwner, logFieldName+"_owners", "[Ljava/lang/String;");
+
+		visitLabel(labelForNoNeedToGrow);
+		// Load this into the end piece of the array
+		if (elementType.getSize() == 1) {
+			if (secondElHasArrayLen) {
+				/*
+				 * size buf
+				 */
+				dupX1();
+				/*
+				 * buf size buf
+				 */
+				visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
+				dupX2();
+				pop();
+				/*
+				 * buf logfield size buf
+				 */
+				visitFieldInsn(getOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());
+				dupX2();
+				pop();
+				/*
+				 * buf logfield logsize size buf
+				 */
+			} else {
+				dup();
+				visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
+				swap();
+				visitFieldInsn(getOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());
+				swap();
+			}
+		} else if (elementType.getSize() == 2) {
+			dup2();
+			if (!isStaticLoggingField)
+				super.loadThis();
+			super.visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
+			dupX2();
+			pop();
+			if (!isStaticLoggingField)
+				super.loadThis();
+			super.visitFieldInsn(getOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());
+			dupX2();
+			pop();
+		}
+		cloneValAtTopOfStack(elementType.getDescriptor(), debug, secondElHasArrayLen);
+
+		arrayStore(elementType);
+
+		visitFieldInsn(getOpcode, logFieldOwner, logFieldName+"_owners", "[Ljava/lang/String;");
+		visitFieldInsn(getOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());
+
+		visitMethodInsn(INVOKESTATIC, "java/lang/Thread", "currentThread", "()Ljava/lang/Thread;");
+		visitMethodInsn(INVOKEVIRTUAL, "java/lang/Thread", "getName", "()Ljava/lang/String;");
+		arrayStore(Type.getType(String.class));
+		visitFieldInsn(getOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());
+
+		super.visitInsn(Opcodes.ICONST_1);
+		super.visitInsn(Opcodes.IADD);
+		super.visitFieldInsn(putOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());
+		// println("Incremented fill for " + logFieldOwner+"."+logFieldName);
+		// Release the export lock
+		// super.visitFieldInsn(GETSTATIC,
+		// Type.getInternalName(CloningUtils.class), "exportLock",
+		// Type.getDescriptor(ReadWriteLock.class));
+		// super.visitMethodInsn(INVOKEINTERFACE,
+		// Type.getInternalName(ReadWriteLock.class), "readLock",
+		// "()Ljava/util/concurrent/locks/Lock;");
+		// super.visitMethodInsn(INVOKEINTERFACE,
+		// Type.getInternalName(Lock.class), "unlock", "()V");
+
+		// if (threadSafe) {
+		// Unlock
+		// super.visitVarInsn(ALOAD, monitorIndx);
+		// super.monitorExit();
+		// visitLabel(monitorEndLabel);
+		Label endLbl = new Label();
+
+//		if (elementType.getSort() == Type.ARRAY) {
+//			super.visitInsn(DUP);
+//			super.visitInsn(ARRAYLENGTH);
+//		} else
+			super.visitInsn(ICONST_1);
+		// super.visitVarInsn(ALOAD, monitorIndx);
+		// super.monitorEnter();
+		super.visitFieldInsn(getOpcode, logFieldOwner, "logsize", Type.INT_TYPE.getDescriptor());
+		super.visitInsn(IADD);
+		super.visitInsn(DUP);
+		super.visitFieldInsn(PUTSTATIC, logFieldOwner, "logsize", Type.INT_TYPE.getDescriptor());
+
+		super.visitLdcInsn(Constants.MAX_LOG_SIZE);
+		// super.visitInsn(ISUB);
+		super.visitJumpInsn(IF_ICMPLE, endLbl);
+		// super.ifCmp(Type.INT_TYPE, Opcodes.IFGE, endLbl);
+		// super.visitVarInsn(ALOAD, monitorIndx);
+		// super.monitorExit();
+		if (logFieldOwner.equals(Type.getInternalName(SerializableLog.class)))
+			super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(WallaceExportRunner.class), "_exportSerializable", "()V");
+		else
+			super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(WallaceExportRunner.class), "_export", "()V");
+		// super.visitVarInsn(ALOAD, monitorIndx);
+		// super.monitorEnter();
+//		super.visitFieldInsn(getOpcode, logFieldOwner, "logsize", Type.INT_TYPE.getDescriptor());
+//		super.visitLdcInsn(Constants.VERY_MAX_LOG_SIZE);
+//		super.visitJumpInsn(IF_ICMPLE, endLbl);
+
+		// println("GOing to wait for " + logFieldOwner);
+		// super.visitLabel(tryStart);
+
+//		super.visitFieldInsn(Opcodes.GETSTATIC, Type.getInternalName(Log.class), "lock", "Ljava/lang/Object;");
+//		super.visitLdcInsn(500L);
+//		super.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "wait", "(J)V");
+
+		// super.visitLabel(tryEnd);
+
+		// super.visitJumpInsn(GOTO, endLbl);
+		// super.visitLabel(handlerStart);
+		// int n = newLocal(Type.getType(InterruptedException.class));
+		// super.visitVarInsn(ASTORE, n);
+		// super.visitInsn(POP);
+		visitLabel(endLbl);
+//		super.visitVarInsn(ALOAD, monitorIndx);
+//		super.monitorExit();
+		super.visitFieldInsn(GETSTATIC, Type.getInternalName(Log.class), "logLock", Type.getDescriptor(Lock.class));
+		super.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Lock.class), "unlock", "()V");
+		// super.visitLocalVariable(logFieldName + "_monitor",
+		// "Ljava/lang/Object;", null, monitorStart, monitorEndLabel,
+		// monitorIndx);
+		// }
+
+	}
+
+
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/visitor/NonDeterministicLoggingClassVisitor.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/visitor/NonDeterministicLoggingClassVisitor.java
new file mode 100644
index 0000000..9ff65fb
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/visitor/NonDeterministicLoggingClassVisitor.java
@@ -0,0 +1,163 @@
+package edu.columbia.cs.psl.wallace.visitor;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+
+import org.apache.log4j.Logger;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.AnalyzerAdapter;
+import org.objectweb.asm.commons.JSRInlinerAdapter;
+import org.objectweb.asm.commons.LocalVariablesSorter;
+import org.objectweb.asm.tree.MethodInsnNode;
+
+import edu.columbia.cs.psl.wallace.Constants;
+import edu.columbia.cs.psl.wallace.MethodCall;
+
+public class NonDeterministicLoggingClassVisitor extends ClassVisitor implements Opcodes {
+
+	private String className;
+	private boolean isAClass = true;
+
+	public NonDeterministicLoggingClassVisitor(int api, ClassVisitor cv) {
+		super(api, cv);
+
+	}
+
+	private static Logger logger = Logger.getLogger(NonDeterministicLoggingClassVisitor.class);
+
+	@Override
+	public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
+		super.visit(version, access, name, signature, superName, interfaces);
+		this.className = name;
+
+		logger.debug("Visiting " + name + " for instrumentation");
+		if ((access & Opcodes.ACC_INTERFACE) != 0)
+			isAClass = false;
+	}
+
+	private boolean isFirstConstructor = true;
+
+	@Override
+	public MethodVisitor visitMethod(int acc, String name, String desc, String signature, String[] exceptions) {
+		// TODO need an annotation to disable doing this to some apps
+		if (isAClass && !name.equals(Constants.INNER_COPY_METHOD_NAME) && !name.equals(Constants.OUTER_COPY_METHOD_NAME) && !name.equals(Constants.SET_FIELDS_METHOD_NAME)
+				&& !className.startsWith("com/thoughtworks")
+				)
+		{
+			MethodVisitor smv = cv.visitMethod(acc, name, desc, signature, exceptions);
+			JSRInlinerAdapter mv = new JSRInlinerAdapter(smv, acc, name, desc, signature, exceptions);
+
+			AnalyzerAdapter analyzer = new AnalyzerAdapter(className, acc, name, desc, mv);
+//			LocalVariablesSorter sorter  = new LocalVariablesSorter(acc, desc, analyzer);
+
+			// CheckMethodAdapter cmv = new CheckMethodAdapter(mv);
+
+			NonDeterministicLoggingMethodVisitor cloningMV = new NonDeterministicLoggingMethodVisitor(Opcodes.ASM4, analyzer, acc, name, desc, className, isFirstConstructor, analyzer, null);
+			if (name.equals("<init>"))
+				isFirstConstructor = false;
+			cloningMV.setClassVisitor(this);
+			return cloningMV;
+		} else
+			return cv.visitMethod(acc, name, desc, signature, exceptions);
+	}
+
+	public HashSet<MethodCall> getLoggedMethodCalls() {
+		return loggedMethodCalls;
+	}
+
+	private HashSet<MethodCall> loggedMethodCalls = new HashSet<MethodCall>();
+	private HashMap<MethodCall, MethodInsnNode> captureMethodsToGenerate = new HashMap<MethodCall, MethodInsnNode>();
+
+	public void addFieldMarkup(Collection<MethodCall> calls) {
+		logger.debug("Received field markup from method visitor (" + calls.size() + ")");
+		loggedMethodCalls.addAll(calls);
+		// TODO also setup the new method to retrieve the list of replacements
+		// for the method
+	}
+
+	@Override
+	public void visitEnd() {
+		super.visitEnd();
+		for (MethodCall mc : captureMethodsToGenerate.keySet()) {
+			MethodInsnNode mi = captureMethodsToGenerate.get(mc);
+			String methodDesc = mi.desc;
+
+			String captureDesc = mi.desc;
+
+			int opcode = Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL;
+			if(mi.getOpcode() == Opcodes.INVOKESPECIAL && !mi.name.equals("<init>"))
+				opcode = Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL;
+			else if (mi.getOpcode() != Opcodes.INVOKESTATIC) {
+				// Need to put owner of the method on the top of the args list
+				captureDesc = "(L" + mi.owner + ";";
+				for (Type t : Type.getArgumentTypes(mi.desc))
+					captureDesc += t.getDescriptor();
+				captureDesc += ")" + Type.getReturnType(mi.desc).getDescriptor();
+			}
+			MethodVisitor mv = super.visitMethod(opcode, mc.getCapturePrefix() + "_capture", captureDesc, null, null);
+			LocalVariablesSorter lvs = new LocalVariablesSorter(opcode, captureDesc, mv);
+			CloningAdviceAdapter caa = new CloningAdviceAdapter(Opcodes.ASM4, lvs, opcode, mc.getCapturePrefix() + "_capture", captureDesc, className,lvs);
+			Type[] args = Type.getArgumentTypes(captureDesc);
+			if(mi.name.equals("<init>"))
+			{
+				for (int i = 0; i < args.length; i++) {
+					caa.loadArg(i);
+				}
+				caa.visitMethodInsn(Opcodes.INVOKESPECIAL, mi.owner, mi.name, mi.desc);
+				caa.loadArg(0);
+			}
+			else
+			{
+				if(opcode == Opcodes.ACC_PRIVATE)
+					caa.loadThis();
+				for (int i = 0; i < args.length; i++) {
+					caa.loadArg(i);
+				}
+				caa.visitMethodInsn(mi.getOpcode(), mi.owner, mi.name, mi.desc);
+				for (int i = 0; i < args.length; i++) {
+					if (args[i].getSort() == Type.ARRAY) {
+						boolean minimalCopy = (Type.getReturnType(methodDesc).getSort() == Type.INT);
+						if(minimalCopy)
+						{
+							caa.dup();
+							Label isNegative = new Label();
+							Label notNegative = new Label();
+							caa.visitJumpInsn(Opcodes.IFLT, isNegative);
+							caa.dup();
+							caa.visitJumpInsn(Opcodes.GOTO, notNegative);
+							caa.visitLabel(isNegative);
+							caa.visitInsn(ICONST_0);
+							caa.visitLabel(notNegative);
+						}
+						caa.loadArg(i);
+						//- (mi.getOpcode() == Opcodes.INVOKESTATIC ? 0 : 1)
+						caa.logValueAtTopOfStackToArray(MethodCall.getLogClassName(args[i]), "aLog", "[Ljava/lang/Object;",
+								args[i], true, mi.owner+"."+mi.name+"->_"+i+"\t"+args[i].getDescriptor()+"\t\t"+className,minimalCopy);
+						if (args[i].getSize() == 1)
+							caa.pop();
+						else
+							caa.pop2();
+					}
+				}
+			}
+			caa.returnValue();
+			caa.visitMaxs(0, 0);
+			caa.visitEnd();
+		}
+	}
+
+	public String getClassName() {
+		return className;
+	}
+
+	public void addCaptureMethodsToGenerate(HashMap<MethodCall, MethodInsnNode> captureMethodsToGenerate) {
+		this.captureMethodsToGenerate.putAll(captureMethodsToGenerate);
+	}
+
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/visitor/NonDeterministicLoggingMethodVisitor.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/visitor/NonDeterministicLoggingMethodVisitor.java
new file mode 100644
index 0000000..98eca00
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/visitor/NonDeterministicLoggingMethodVisitor.java
@@ -0,0 +1,235 @@
+package edu.columbia.cs.psl.wallace.visitor;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Scanner;
+
+import org.apache.log4j.Logger;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.AnalyzerAdapter;
+import org.objectweb.asm.commons.LocalVariablesSorter;
+import org.objectweb.asm.tree.MethodInsnNode;
+
+import edu.columbia.cs.psl.wallace.Constants;
+import edu.columbia.cs.psl.wallace.Instrumenter;
+import edu.columbia.cs.psl.wallace.MethodCall;
+
+public class NonDeterministicLoggingMethodVisitor extends CloningAdviceAdapter implements Constants {
+	private static Logger			logger					= Logger.getLogger(NonDeterministicLoggingMethodVisitor.class);
+	private String					name;
+	private String					desc;
+	private String					classDesc;
+	private int						pc;
+	public static HashSet<String>	nonDeterministicMethods	= new HashSet<String>();
+	private boolean					isStatic;
+	private boolean					constructor;
+	private boolean					superInitialized;
+	private AnalyzerAdapter analyzer;
+	public static boolean isND(String owner, String name, String desc)
+	{
+		return nonDeterministicMethods.contains(owner + "." + name + ":" + desc);
+	}
+	public static void registerNDMethod(String owner, String name, String desc)
+	{
+		nonDeterministicMethods.add(owner + "." + name + ":" + desc);
+	}
+	static {
+		File f = new File("nondeterministic-methods.txt");
+		Scanner s;
+		try {
+			s = new Scanner(f);
+			while (s.hasNextLine())
+				nonDeterministicMethods.add(s.nextLine());
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+	public void visitCode() {
+		super.visitCode();
+		if (!constructor)
+			superInitialized = true;
+	}
+
+	private boolean	isFirstConstructor;
+
+	protected NonDeterministicLoggingMethodVisitor(int api, MethodVisitor mv, int access, String name, String desc, String classDesc,
+			boolean isFirstConstructor, AnalyzerAdapter analyzer, LocalVariablesSorter lvs) {
+		super(api, mv, access, name, desc,classDesc, lvs);
+		this.name = name;
+		this.desc = desc;
+		this.classDesc = classDesc;
+		this.isStatic = (access & Opcodes.ACC_STATIC) != 0;
+		this.constructor = "<init>".equals(name);
+		this.isFirstConstructor = isFirstConstructor;
+		this.analyzer = analyzer;
+	}
+
+	private NonDeterministicLoggingClassVisitor	parent;
+
+	public void setClassVisitor(NonDeterministicLoggingClassVisitor coaClassVisitor) {
+		this.parent = coaClassVisitor;
+	}
+
+
+	@Override
+	public void visitEnd() {
+//		System.out.println(classDesc + " " + name);
+		super.visitEnd();
+
+		parent.addFieldMarkup(methodCallsToClear);
+		parent.addCaptureMethodsToGenerate(captureMethodsToGenerate);
+	}
+
+	private int	lineNumber	= 0;
+
+	@Override
+	public void visitLineNumber(int line, Label start) {
+		super.visitLineNumber(line, start);
+		lineNumber = line;
+	}
+
+	private HashMap<MethodCall, MethodInsnNode> captureMethodsToGenerate = new HashMap<MethodCall, MethodInsnNode>();
+	@Override
+	public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+		try {
+
+			MethodCall m = new MethodCall(this.name, this.desc, this.classDesc, pc, lineNumber, owner, name, desc, isStatic);
+			Type returnType = Type.getMethodType(desc).getReturnType();
+			if ((!constructor || isFirstConstructor || superInitialized) && !returnType.equals(Type.VOID_TYPE)
+					&& nonDeterministicMethods.contains(owner + "." + name + ":" + desc)) {
+				logger.debug("Adding field in MV to list " + m.getLogFieldName());
+				methodCallsToClear.add(m);
+				Type[] args = Type.getArgumentTypes(desc);
+				boolean hasArray = false;
+				for(Type t : args)
+					if(t.getSort() == Type.ARRAY && !name.contains("write"))
+						hasArray = true;
+
+				if(hasArray)
+				{	//TODO uncomment this block
+					captureMethodsToGenerate.put(m, new MethodInsnNode(opcode, owner, name, desc));
+					String captureDesc = desc;
+
+					int invokeOpcode = Opcodes.INVOKESTATIC;
+					if(opcode == Opcodes.INVOKESPECIAL && !name.equals("<init>"))
+					{
+						invokeOpcode = Opcodes.INVOKESPECIAL;
+					}
+					else if(opcode != Opcodes.INVOKESTATIC)
+					{
+						//Need to put owner of the method on the top of the args list
+						captureDesc = "(L" +  owner +";";
+						for(Type t : args)
+							captureDesc += t.getDescriptor();
+						captureDesc+=")"+Type.getReturnType(desc).getDescriptor();
+					}
+					mv.visitMethodInsn(invokeOpcode, classDesc, m.getCapturePrefix()+"_capture", captureDesc);
+					logValueAtTopOfStackToArray(m.getLogClassName(), m.getLogFieldName(), m.getLogFieldType().getDescriptor(), returnType, true,
+							owner+"."+name + "\t" + desc+"\t\t"+classDesc+"."+this.name,false);
+				}
+				else
+				{
+					mv.visitMethodInsn(opcode, owner, name, desc);
+					logValueAtTopOfStackToArray(m.getLogClassName(), m.getLogFieldName(), m.getLogFieldType().getDescriptor(), returnType, true,
+							owner+"."+name + "\t" + desc+"\t\t"+classDesc+"."+this.name,false);
+				}
+			}
+			else if(opcode == INVOKESPECIAL && name.equals("<init>") && nonDeterministicMethods.contains(owner + "." + name + ":" + desc) && !(owner.equals(Instrumenter.instrumentedClasses.get(classDesc).superName)
+					&& this.name.equals("<init>"))) {
+				super.visitMethodInsn(opcode, owner, name, desc);
+				if(analyzer.stack != null && analyzer.stack.size() > 0 && analyzer.stack.get(analyzer.stack.size()-1).equals(owner))
+					logValueAtTopOfStackToArray(MethodCall.getLogClassName(Type.getType("L"+owner+";")), "aLog", "[Ljava/lang/Object;", Type.getType("L"+owner+";"), true,
+							owner+"."+name + "\t" + desc+"\t\t"+classDesc+"."+this.name,false);
+
+			}
+			else
+				mv.visitMethodInsn(opcode, owner, name, desc);
+			pc++;
+		} catch (Exception ex) {
+			logger.error("Unable to instrument method call", ex);
+		}
+	}
+
+	private HashSet<MethodCall>	methodCallsToClear	= new HashSet<MethodCall>();
+
+	@Override
+	public void visitFieldInsn(int opcode, String owner, String name, String desc) {
+		super.visitFieldInsn(opcode, owner, name, desc);
+		pc++;
+	}
+
+	@Override
+	public void visitIincInsn(int var, int increment) {
+		super.visitIincInsn(var, increment);
+		pc++;
+	}
+
+	@Override
+	public void visitInsn(int opcode) {
+		super.visitInsn(opcode);
+		pc++;
+	}
+
+	@Override
+	public void visitIntInsn(int opcode, int operand) {
+		super.visitIntInsn(opcode, operand);
+		pc++;
+	}
+
+	@Override
+	public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
+		super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
+		pc++;
+	}
+
+	@Override
+	public void visitJumpInsn(int opcode, Label label) {
+		super.visitJumpInsn(opcode, label);
+		pc++;
+	}
+
+	@Override
+	public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
+		super.visitLookupSwitchInsn(dflt, keys, labels);
+		pc++;
+	}
+
+	@Override
+	public void visitMultiANewArrayInsn(String desc, int dims) {
+		super.visitMultiANewArrayInsn(desc, dims);
+		pc++;
+	}
+
+	@Override
+	public void visitTypeInsn(int opcode, String type) {
+		super.visitTypeInsn(opcode, type);
+		pc++;
+	}
+
+	@Override
+	public void visitVarInsn(int opcode, int var) {
+		super.visitVarInsn(opcode, var);
+		pc++;
+	}
+
+	@Override
+	public void visitLdcInsn(Object cst) {
+		super.visitLdcInsn(cst);
+		pc++;
+	}
+
+	@Override
+	public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
+		super.visitTableSwitchInsn(min, max, dflt, labels);
+		pc++;
+	}
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/xstream/CatchClassErrorFieldDictionary.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/xstream/CatchClassErrorFieldDictionary.java
new file mode 100644
index 0000000..199c8a8
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/xstream/CatchClassErrorFieldDictionary.java
@@ -0,0 +1,189 @@
+package edu.columbia.cs.psl.wallace.xstream;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.thoughtworks.xstream.converters.reflection.FieldDictionary;
+import com.thoughtworks.xstream.converters.reflection.FieldKey;
+import com.thoughtworks.xstream.converters.reflection.FieldKeySorter;
+import com.thoughtworks.xstream.converters.reflection.ImmutableFieldKeySorter;
+import com.thoughtworks.xstream.converters.reflection.MissingFieldException;
+import com.thoughtworks.xstream.converters.reflection.ObjectAccessException;
+import com.thoughtworks.xstream.core.Caching;
+import com.thoughtworks.xstream.core.JVM;
+import com.thoughtworks.xstream.core.util.OrderRetainingMap;
+
+public class CatchClassErrorFieldDictionary extends FieldDictionary {
+    private transient Map keyedByFieldNameCache;
+    private transient Map keyedByFieldKeyCache;
+    private final FieldKeySorter sorter;
+
+    public CatchClassErrorFieldDictionary() {
+        this(new ImmutableFieldKeySorter());
+    }
+
+    public CatchClassErrorFieldDictionary(FieldKeySorter sorter) {
+        this.sorter = sorter;
+        init();
+    }
+
+    private void init() {
+        keyedByFieldNameCache = new HashMap();
+        keyedByFieldKeyCache = new HashMap();
+        keyedByFieldNameCache.put(Object.class, Collections.EMPTY_MAP);
+        keyedByFieldKeyCache.put(Object.class, Collections.EMPTY_MAP);
+    }
+
+    /**
+     * Returns an iterator for all fields for some class
+     *
+     * @param cls the class you are interested on
+     * @return an iterator for its fields
+     * @deprecated As of 1.3, use {@link #fieldsFor(Class)} instead
+     */
+    public Iterator serializableFieldsFor(Class cls) {
+        return fieldsFor(cls);
+    }
+
+    /**
+     * Returns an iterator for all fields for some class
+     *
+     * @param cls the class you are interested on
+     * @return an iterator for its fields
+     */
+    public Iterator fieldsFor(final Class cls) {
+        return buildMap(cls, true).values().iterator();
+    }
+
+    /**
+     * Returns an specific field of some class. If definedIn is null, it searches for the field
+     * named 'name' inside the class cls. If definedIn is different than null, tries to find the
+     * specified field name in the specified class cls which should be defined in class
+     * definedIn (either equals cls or a one of it's superclasses)
+     *
+     * @param cls the class where the field is to be searched
+     * @param name the field name
+     * @param definedIn the superclass (or the class itself) of cls where the field was defined
+     * @return the field itself
+     * @throws ObjectAccessException if no field can be found
+     */
+    public Field field(Class cls, String name, Class definedIn) {
+        Field field = fieldOrNull(cls, name, definedIn);
+        if (field == null) {
+            throw new MissingFieldException(cls.getName(), name);
+        } else {
+            return field;
+        }
+    }
+
+    /**
+     * Returns an specific field of some class. If definedIn is null, it searches for the field
+     * named 'name' inside the class cls. If definedIn is different than null, tries to find the
+     * specified field name in the specified class cls which should be defined in class
+     * definedIn (either equals cls or a one of it's superclasses)
+     *
+     * @param cls the class where the field is to be searched
+     * @param name the field name
+     * @param definedIn the superclass (or the class itself) of cls where the field was defined
+     * @return the field itself or <code>null</code>
+     * @since 1.4
+     */
+    public Field fieldOrNull(Class cls, String name, Class definedIn) {
+        Map fields = buildMap(cls, definedIn != null);
+        Field field = (Field)fields.get(definedIn != null
+            ? (Object)new FieldKey(name, definedIn, 0)
+            : (Object)name);
+        return field;
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+	private Map buildMap(final Class type, boolean tupleKeyed) {
+        final Map result;
+        Class cls = type;
+        synchronized (this) {
+            if (!keyedByFieldNameCache.containsKey(type)) {
+                final List superClasses = new ArrayList();
+                while (!Object.class.equals(cls)) {
+                    superClasses.add(0, cls);
+                    cls = cls.getSuperclass();
+                }
+                Map lastKeyedByFieldName = Collections.EMPTY_MAP;
+                Map lastKeyedByFieldKey = Collections.EMPTY_MAP;
+                for (final Iterator iter = superClasses.iterator(); iter.hasNext();) {
+                    cls = (Class)iter.next();
+                    if (!keyedByFieldNameCache.containsKey(cls)) {
+                        final Map keyedByFieldName = new HashMap(lastKeyedByFieldName);
+                        final Map keyedByFieldKey = new OrderRetainingMap(lastKeyedByFieldKey);
+                        try{
+                        Field[] fields = cls.getDeclaredFields();
+                        if (JVM.reverseFieldDefinition()) {
+                            for (int i = fields.length >> 1; i-- > 0;) {
+                                final int idx = fields.length - i - 1;
+                                final Field field = fields[i];
+                                fields[i] = fields[idx];
+                                fields[idx] = field;
+                            }
+                        }
+                        for (int i = 0; i < fields.length; i++ ) {
+                            Field field = fields[i];
+                            if (!field.isAccessible()) {
+                                field.setAccessible(true);
+                            }
+                            FieldKey fieldKey = new FieldKey(
+                                field.getName(), field.getDeclaringClass(), i);
+                            Field existent = (Field)keyedByFieldName.get(field.getName());
+                            if (existent == null
+                            // do overwrite statics
+                                || ((existent.getModifiers() & Modifier.STATIC) != 0)
+                                // overwrite non-statics with non-statics only
+                                || (existent != null && ((field.getModifiers() & Modifier.STATIC) == 0))) {
+                                keyedByFieldName.put(field.getName(), field);
+                            }
+                            keyedByFieldKey.put(fieldKey, field);
+                        }
+                        }
+                        catch(NoClassDefFoundError ex)
+                        {
+                        	//do nothing!
+                        }
+                        final Map sortedFieldKeys = sorter.sort(type, keyedByFieldKey);
+                        keyedByFieldNameCache.put(cls, keyedByFieldName);
+                        keyedByFieldKeyCache.put(cls, sortedFieldKeys);
+                        lastKeyedByFieldName = keyedByFieldName;
+                        lastKeyedByFieldKey = sortedFieldKeys;
+                    } else {
+                        lastKeyedByFieldName = (Map)keyedByFieldNameCache.get(cls);
+                        lastKeyedByFieldKey = (Map)keyedByFieldKeyCache.get(cls);
+                    }
+                }
+                result = tupleKeyed ? lastKeyedByFieldKey : lastKeyedByFieldName;
+            } else {
+                result = (Map)(tupleKeyed
+                    ? keyedByFieldKeyCache.get(type)
+                    : keyedByFieldNameCache.get(type));
+            }
+        }
+        return result;
+    }
+
+    public synchronized void flushCache() {
+        Set objectTypeSet = Collections.singleton(Object.class);
+        keyedByFieldNameCache.keySet().retainAll(objectTypeSet);
+        keyedByFieldKeyCache.keySet().retainAll(objectTypeSet);
+        if (sorter instanceof Caching) {
+            ((Caching)sorter).flushCache();
+        }
+    }
+
+    protected Object readResolve() {
+        init();
+        return this;
+    }
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/wallace/xstream/StaticReflectionProvider.java b/testcase-generation/src/edu/columbia/cs/psl/wallace/xstream/StaticReflectionProvider.java
new file mode 100644
index 0000000..278b1fb
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/wallace/xstream/StaticReflectionProvider.java
@@ -0,0 +1,67 @@
+package edu.columbia.cs.psl.wallace.xstream;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import com.thoughtworks.xstream.converters.reflection.ObjectAccessException;
+import com.thoughtworks.xstream.converters.reflection.Sun14ReflectionProvider;
+
+public class StaticReflectionProvider extends Sun14ReflectionProvider {
+	public void writeField(Object object, String fieldName, Object value, Class definedIn) {
+		if (!Modifier.isStatic(fieldDictionary.field(object.getClass(), fieldName, definedIn).getModifiers())) {
+			super.writeField(object, fieldName, value, definedIn);
+		} else {
+			try {
+				fieldDictionary.field(object.getClass(), fieldName, definedIn).set(null, value);
+			} catch (IllegalArgumentException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (IllegalAccessException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+	}
+
+	public StaticReflectionProvider() {
+		super(new CatchClassErrorFieldDictionary());
+	}
+
+	@Override
+	public void visitSerializableFields(Object object, Visitor visitor) {
+		for (Iterator iterator = fieldDictionary.fieldsFor(object.getClass()); iterator.hasNext();) {
+			Field field = (Field) iterator.next();
+			if (!fieldModifiersSupported(field)) {
+				continue;
+			}
+			validateFieldAccess(field);
+			try {
+				Object value = field.get(object);
+				if (value != null)
+					synchronized (value) {
+						visitor.visit(field.getName(), field.getType(), field.getDeclaringClass(), value);
+					}
+				else
+					visitor.visit(field.getName(), field.getType(), field.getDeclaringClass(), value);
+
+			} catch (IllegalArgumentException e) {
+				throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e);
+			} catch (IllegalAccessException e) {
+				throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e);
+			} catch (SecurityException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	@Override
+	protected boolean fieldModifiersSupported(Field field) {
+		int modifiers = field.getModifiers();
+		return !(Modifier.isTransient(modifiers) || (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers) ));
+	}
+}