diff --git a/.monadid b/.monadid
index f10a407930ddecc817846bb1735502d9f850d563..dd982b4e68174f4b7f05621dd3d03234660fbcfd 100644
--- a/.monadid
+++ b/.monadid
@@ -1,4 +1,4 @@
 monad identification file
 This file is used for monad directory identification
 Built by toole1 on linux4.ews.illinois.edu
-Build Date: Wed Oct 26 16:33:52 CDT 2011
+Build Date: Sat Oct 29 04:30:53 CDT 2011
diff --git a/monad b/monad
index 9d1ca1f8b1c4c91babed89d8bd64d628d923b52b..018e061bc485b1180462fc3140e6197328632ef6 100755
Binary files a/monad and b/monad differ
diff --git a/proxy.cpp b/proxy.cpp
index bc8454f1dbc67336e6b18bae197032b5bf0af140..275ec25baa68d0de4cb106712dae252241b3d572 100644
--- a/proxy.cpp
+++ b/proxy.cpp
@@ -543,7 +543,7 @@ void test_execution::child_valgrind()
 	nums_pipe.close_write();
 	
 	start_timeout();
-	exec("valgrind", "--trace-children=yes", /*"--log-fd=-1",*/ "-q", "./proxy", test.name, NULL);
+	exec("valgrind", "--dsymutil=yes", "--trace-children=yes", /*"--log-fd=-1",*/ "-q", "./proxy", test.name, NULL);
 }
 
 
diff --git a/proxy.h b/proxy.h
index ea3f656840778d8e6e14b698488a88e623deba24..12b44899b8104c57822bbbc5e6b93ec1e6506166 100644
--- a/proxy.h
+++ b/proxy.h
@@ -219,7 +219,7 @@ using std::endl;
 
 namespace proxy {
 template <typename T>
-inline std::string assert_equals_help(T expected, T actual, const char * expstr, const char * actstr)
+inline std::string assert_equals_help(const T & expected, const T & actual, const char * expstr, const char * actstr)
 {
 	std::stringstream ss;
 	if (actual != expected)
@@ -267,24 +267,42 @@ namespace proxy
 		uint64_t totalTime;
 	};
 
-	template <typename Generator, typename Timer>                  TimeIterationsData timeIterationsImpl(Generator gen,            Timer timeFunctor, size_t input_size);
-	template <typename Generator, typename Timer>                  TimeIterationsData timeIterations    (Generator gen,            Timer timeFunctor, size_t input_size);
-	template <typename GenResult, typename GenArg, typename Timer> TimeIterationsData timeIterations    (GenResult (*gen)(GenArg), Timer timeFunctor, size_t input_size);
+	template <typename Generator, typename Timer, typename Cleaner>                  TimeIterationsData timeIterationsImpl(Generator gen,            Timer timeFunctor, Cleaner cleanupFunc, size_t input_size);
+	template <typename Generator, typename Timer, typename Cleaner>                  TimeIterationsData timeIterations    (Generator gen,            Timer timeFunctor, Cleaner cleanupFunc, size_t input_size);
+	template <typename GenResult, typename GenArg, typename Timer, typename Cleaner> TimeIterationsData timeIterations    (GenResult (*gen)(GenArg), Timer timeFunctor, Cleaner cleanupFunc, size_t input_size);
 	
-	template <typename Generator, typename Timer>
-	bool assert_time_impl(Generator gen, Timer functor, proxy_runtime_t expectedTime, size_t size1 = 100, size_t size2 = 400);
+	template <typename Generator, typename Timer, typename Cleaner>
+	bool assert_time_impl(Generator gen, Timer functor, Cleaner cleanupFunc, proxy_runtime_t expectedTime, size_t size1 = 100, size_t size2 = 400);
+	
+	struct nop
+	{
+		template <typename T>
+		void operator()(const T & t) { }
+	};
 }
 
-#define ASSERT_TIME3(gen, functor, expectedTime)                                          \
-	do {                                                                                  \
-		if (proxy::assert_time_impl(gen, functor, expectedTime))                          \
-			FAIL(string("Runtime was larger than ") + proxy::runtime_str[expectedTime]);  \
+#define ASSERT_TIME3(gen, functor, expectedTime)                                             \
+	do {                                                                                     \
+		if (proxy::assert_time_impl(gen, functor, proxy::nop(), expectedTime))                 \
+			FAIL(string("Runtime was larger than ") + proxy::runtime_str[expectedTime]);     \
+	} while(0)
+
+#define ASSERT_TIME4(gen, functor, cleanupFunc, expectedTime)                                \
+	do {                                                                                     \
+		if (proxy::assert_time_impl(gen, functor, cleanupFunc, expectedTime))                \
+			FAIL(string("Runtime was larger than ") + proxy::runtime_str[expectedTime]);     \
 	} while(0)
 
-#define ASSERT_TIME5(gen, functor, expectedTime, size1, size2)                            \
-	do {                                                                                  \
-		if (proxy::assert_time_impl(gen, functor, expectedTime, size1, size2))            \
-			FAIL(string("Runtime was larger than ") + proxy::runtime_str[expectedTime]);  \
+#define ASSERT_TIME5(gen, functor, expectedTime, size1, size2)                               \
+	do {                                                                                     \
+		if (proxy::assert_time_impl(gen, functor, proxy::nop(), expectedTime, size1, size2))   \
+			FAIL(string("Runtime was larger than ") + proxy::runtime_str[expectedTime]);     \
+	} while(0)
+
+#define ASSERT_TIME6(gen, functor, cleanupFunc, expectedTime, size1, size2)                  \
+	do {                                                                                     \
+		if (proxy::assert_time_impl(gen, functor, cleanupFunc, expectedTime, size1, size2))  \
+			FAIL(string("Runtime was larger than ") + proxy::runtime_str[expectedTime]);     \
 	} while(0)
 
 // Crazy hack for overloading!
@@ -292,30 +310,31 @@ namespace proxy
 // http://cplusplus.co.il/2010/07/17/variadic-macro-to-count-number-of-arguments/
 // Overloading tips:
 // http://stackoverflow.com/questions/3046889/optional-parameters-with-c-macros
-#define ASSERT_TIME_SIXTH_ARG(a, b, c, d, e, f, ...) f
+#define ASSERT_TIME_SEVENTH_ARG(a, b, c, d, e, f, g, ...) g
 
 #define ASSERT_TIME(...)  \
-	ASSERT_TIME_SIXTH_ARG(__VA_ARGS__, ASSERT_TIME5, 0, ASSERT_TIME3, 0, 0) (__VA_ARGS__)
+	ASSERT_TIME_SEVENTH_ARG(__VA_ARGS__, ASSERT_TIME6, ASSERT_TIME5, ASSERT_TIME4, ASSERT_TIME3, 0, 0) (__VA_ARGS__)
 
 namespace proxy {
 
-template <typename Generator, typename Timer>
-TimeIterationsData timeIterations(Generator gen, Timer timeFunctor, size_t input_size)
+template <typename Generator, typename Timer, typename Cleaner>
+TimeIterationsData timeIterations(Generator gen, Timer timeFunctor, Cleaner cleanupFunc, size_t input_size)
 {
 	return timeIterationsImpl(
 			bind1st(mem_fun(&Generator::operator()), &gen),
 			timeFunctor,
+			cleanupFunc,
 			input_size);
 }
 
-template <typename GenResult, typename GenArg, typename Timer>
-TimeIterationsData timeIterations(GenResult (*gen)(GenArg), Timer timeFunctor, size_t input_size)
+template <typename GenResult, typename GenArg, typename Timer, typename Cleaner>
+TimeIterationsData timeIterations(GenResult (*gen)(GenArg), Timer timeFunctor, Cleaner cleanupFunc, size_t input_size)
 {
-	return timeIterationsImpl(ptr_fun(gen), timeFunctor, input_size);
+	return timeIterationsImpl(ptr_fun(gen), timeFunctor, cleanupFunc, input_size);
 }
 
-template <typename Generator, typename Timer>
-TimeIterationsData timeIterationsImpl(Generator gen, Timer timeFunctor, size_t input_size)
+template <typename Generator, typename Timer, typename Cleaner>
+TimeIterationsData timeIterationsImpl(Generator gen, Timer timeFunctor, Cleaner cleanupFunc, size_t input_size)
 {
 	const uint64_t min_time = 1000000; // in microseconds
 	const size_t max_gen_iterations = 1000000;
@@ -341,7 +360,11 @@ TimeIterationsData timeIterationsImpl(Generator gen, Timer timeFunctor, size_t i
 	uint64_t endtime = util::process_clock();
 
 	for (size_t i = 0; i < max_iterations; i++)
+	{
+		cleanupFunc(*inputs[i]);
 		delete inputs[i];
+	}
+	cleanupFunc(warmup_temp);
 
 	TimeIterationsData result;
 	result.timePerCall = static_cast<double>(endtime - starttime) / succeeded_iterations;
@@ -357,12 +380,12 @@ inline void timeIterationsOutput(size_t size, const TimeIterationsData & data)
 			  << "for an average of " << data.timePerCall << " us per call" << endl;
 }
 
-template <typename Generator, typename Timer>
-bool assert_time_impl(Generator gen, Timer functor, proxy_runtime_t expectedTime, size_t size1, size_t size2)
+template <typename Generator, typename Timer, typename Cleaner>
+bool assert_time_impl(Generator gen, Timer functor, Cleaner cleanupMem, proxy_runtime_t expectedTime, size_t size1, size_t size2)
 {
-	TimeIterationsData diff0 = timeIterations(gen, functor, 1);
-	TimeIterationsData diff1 = timeIterations(gen, functor, size1);
-	TimeIterationsData diff2 = timeIterations(gen, functor, size2);
+	TimeIterationsData diff0 = timeIterations(gen, functor, cleanupMem, 1);
+	TimeIterationsData diff1 = timeIterations(gen, functor, cleanupMem, size1);
+	TimeIterationsData diff2 = timeIterations(gen, functor, cleanupMem, size2);
 	timeIterationsOutput(    1, diff0);
 	timeIterationsOutput(size1, diff1);
 	timeIterationsOutput(size2, diff2);
diff --git a/util.cpp b/util.cpp
index e32ac36d4b2b33a5ef3e36e0e930f3237f49e805..f624c92dc791a55dc6da7c64d0b5abc5e39ce823 100644
--- a/util.cpp
+++ b/util.cpp
@@ -322,7 +322,7 @@ void protectDir(const string & dir)
 
 // Originally from Simon Biber
 // http://bytes.com/topic/c/answers/545614-list-files-current-directory
-vector<string> get_files_in_dir(const string & dir)
+vector<string> get_files_in_dir(const string & dir, bool concatdir /* = true */)
 {
 	EXIT_IF_ERROR(dir == "" || dir[dir.length()-1] != '/', "Directory name must end in a '/'");
 	
@@ -335,7 +335,7 @@ vector<string> get_files_in_dir(const string & dir)
 	{
 		string file = ent->d_name;
 		if (file != "." && file != "..")
-			files.push_back(dir + file);
+			files.push_back(concatdir ? dir + file : file);
 		ent = readdir(dirp);
 	}
 
@@ -592,6 +592,85 @@ void readFileGeneric(const string & filename, FileMap * map, vector<string> * li
 }
 
 
+OptionsParser::OptionsParser()
+{
+	valueMap[""]      = true;
+
+	valueMap["yes"]   = true;
+	valueMap["no"]    = false;
+
+	valueMap["on"]    = true;
+	valueMap["off"]   = false;
+
+	valueMap["true"]  = true;
+	valueMap["false"] = false;
+
+	valueMap["1"]     = true;
+	valueMap["0"]     = false;
+}
+
+vector<string> OptionsParser::parse(int argc, const char ** argv)
+{
+	vector<string> unprocessedArgs;
+	size_t out_arg_i = 0;
+
+	for (int arg_i = 1; arg_i < argc; arg_i++)
+	{
+		string currarg = toLower(argv[arg_i]);
+
+		if (currarg.compare(0, 2, "--") == 0) //long option
+		{
+			bool invert = (currarg.compare(2, 2, "no") == 0);
+			size_t name_i = (invert ? 4 : 2);
+			size_t equalspos = currarg.find_first_of("=-", name_i);
+			
+			string name = currarg.substr(name_i, equalspos - name_i);
+			string value = (equalspos >= currarg.length()) ? "" : currarg.substr(equalspos);
+
+			optsMap_t::iterator option = optsMap.find(name);
+			if (option == optsMap.end())
+			{
+				cerr << "Unknown option: " << currarg << endl;
+				exit(-1);
+			}
+
+			valueMap_t::iterator valueIt = valueMap.find(value);
+			if (valueIt == valueMap.end())
+			{
+				cerr << "Unknown value: " << currarg << endl;
+				exit(-1);
+			}
+
+			*option->second = valueIt->second ^ invert;
+		} // "--"
+
+		else if (currarg[0] == '-') //string of single char options
+		{
+			for (size_t c = 1; currarg[c] != '\0'; c++)
+			{
+				optsMap_t::iterator option = optsMap.find(string(1,currarg[c]));
+				if (option == optsMap.end())
+				{
+					cerr << "Unknown option: -" << currarg[c] << endl;
+					exit(-1);
+				}
+				*option->second = true;
+			}
+		}
+
+		else //positional argument
+		{
+			if (out_arg_i < args.size())
+				*args[out_arg_i] = currarg;
+			else
+				unprocessedArgs.push_back(currarg);
+			out_arg_i++;
+		}
+	}
+	
+	return unprocessedArgs;
+}
+
 char * processOptions(int argc, char ** argv, OptionsMap & opts, vector<string> & args)
 {
 	for (int arg_i = 1; arg_i < argc; arg_i++)
diff --git a/util.h b/util.h
index 93448dfe98538960d562fbbe145d1ff016862234..fd88ac05e25598a448123d05c77b3cf4f43f486a 100644
--- a/util.h
+++ b/util.h
@@ -1,3 +1,8 @@
+/* CS 225 Util Library
+ * 
+ * @author Jack Toole
+ */
+
 #ifndef UTIL_H
 #define UTIL_H
 
@@ -61,7 +66,22 @@ struct ci_less : std::binary_function<std::string, std::string, bool>
 typedef map<string, vector<string>, ci_less> FileMap;
 typedef map<string, bool, ci_less> OptionsMap;
 
-
+class OptionsParser
+{
+	private:
+	typedef map<string, bool*> optsMap_t;
+	typedef map<string, bool>  valueMap_t;
+	valueMap_t valueMap; // not static to prevent still reachable memory
+	
+	optsMap_t  optsMap;
+	vector<string *> args;
+
+	public:
+	OptionsParser();
+	void addOption(const string & name, bool & setValue) { optsMap[name] = &setValue; }
+	void addArg(string & setValue) { args.push_back(&setValue); }
+	vector<string> parse(int argc, const char ** argv);
+};
 
 // EXEC()
 int8_t exec(int redirect_fd, const char * command,
@@ -110,7 +130,7 @@ void copyFiles(const string & sourceFolder, const string & destFolder, const vec
 void protectFiles(const string & folder, const vector<string> & files);
 void protectDir(const string & dir);
 void linkDirs(const string & sourceFolder, const string & destFolder, const vector<string> & dirs);
-vector<string> get_files_in_dir(const string & dir);
+vector<string> get_files_in_dir(const string & dir, bool concatdir = true);
 bool is_symlink(const string & file);
 string get_symlink_target(const string & symlink);
 
@@ -143,6 +163,10 @@ string toLower(const string & str);
 // String concatenation
 template <typename T>
 string to_string(const T & value);
+template <typename T>
+T from_string(const string & s);
+template <typename T, typename F>
+T lexical_cast(const F & from);
 string operator+(const string & lhs, const string & rhs); // These 5 functions are to disambiguate
 string operator+(const string & lhs, const char * rhs);        // operator+ so that the following
 string operator+(const string & lhs, char rhs);                // templates may exist
@@ -233,6 +257,34 @@ inline string to_string(const T & value)
 	return ss.str();
 }
 
+// http://stackoverflow.com/questions/5017001/like-atoi-but-to-float
+template <typename T>
+inline T from_string(const string & s)
+{
+	stringstream ss(s);
+	T value;
+	ss >> value;
+	return value;
+}
+
+template <typename T, typename F>
+inline T lexical_cast(const F & from)
+{
+	T to;
+	stringstream ss;
+	if (!(ss << from))
+	{
+		cerr << "ERROR: Could not convert types" << endl;
+		return to;
+	}
+	if (!(ss >> to))
+	{
+		cerr << "ERROR: Could not convert types" << endl;
+		return to;
+	}
+	return to;
+}
+
 inline int intlen(unsigned int a)
 {
 	int len = 1;