diff --git a/PNTransformDriver.cpp b/PNTransformDriver.cpp
index 7078adfe15019d309fe81d88398df71fb023681e..11783621d0dca72e1bd0567a0802e1ab8bb77e51 100644
--- a/PNTransformDriver.cpp
+++ b/PNTransformDriver.cpp
@@ -25,6 +25,7 @@
 #include <fstream>
 #include <sstream>
 #include <iomanip>
+#include <memory>
 // #include "beaengine/BeaEngine.h"
 #include "General_Utility.hpp"
 #include "PNIrdbManager.hpp"
@@ -58,15 +59,15 @@ using namespace IRDB_SDK;
 
 char* get_current_dir_name(void) 
 {
-  char* pwd = getenv("PWD");
-  char tmp[PATH_MAX];
-  struct stat a,b;
-  if (pwd && !stat(".",&a) && !stat(pwd,&b) &&
-	  a.st_dev==b.st_dev && a.st_ino==b.st_ino)
-	return strdup(pwd);
-  if (getcwd(tmp,sizeof(tmp)))
-	return strdup(tmp);
-  return 0;
+	char* pwd = getenv("PWD");
+	char tmp[PATH_MAX];
+	struct stat a,b;
+	if (pwd && !stat(".",&a) && !stat(pwd,&b) &&
+			a.st_dev==b.st_dev && a.st_ino==b.st_ino)
+		return strdup(pwd);
+	if (getcwd(tmp,sizeof(tmp)))
+		return strdup(tmp);
+	return 0;
 }
 
 //TODO: this var is a hack for TNE
@@ -105,7 +106,7 @@ static bool CompareValidationRecordAscending(validation_record a, validation_rec
 
 
 PNTransformDriver::PNTransformDriver(VariantID_t *pidp,string BED_script, pqxxDB_t *pqxx_if) : 
-	pn_regex(NULL), pqxx_interface(pqxx_if)
+	pqxx_interface(pqxx_if)
 {
 	//TODO: throw exception?
 	assert(pidp != NULL);
@@ -129,18 +130,12 @@ PNTransformDriver::PNTransformDriver(VariantID_t *pidp,string BED_script, pqxxDB
 
 PNTransformDriver::~PNTransformDriver()
 {
-	//NOTE: because I now handle shared objects, I clean up orig_virp
-	//as I create use it, deleting here caused errors, I had to 
-	//ensure orig_virp is NULL, which I could do, but it is just as
-	//easy to destroy it myself when I am finished with it. 
-//	if(orig_virp != NULL)
-//		delete orig_virp;
 }
 
 //TODO: redesign the way inferences are added
 void PNTransformDriver::AddInference(PNStackLayoutInference *inference, int level)
 {
-//TODO: throw exceptions
+	//TODO: throw exceptions
 	if(level < 0)
 		assert(false);
 	if(inference == NULL)
@@ -198,14 +193,6 @@ void PNTransformDriver::SetDoAlignStack(bool align_stack)
 void PNTransformDriver::AddBlacklist(set<string> &blacklist)
 {
 	this->blacklist.insert(blacklist.begin(),blacklist.end());
-
-/*
-	set<string>::iterator it;
-	for(it = blacklist.begin();it != blacklist.end();it++)
-	{
-		this->blacklist.insert(*it);
-	}
-*/
 }
 
 void PNTransformDriver::AddBlacklistFunction(string func_name)
@@ -262,7 +249,7 @@ bool PNTransformDriver::PaddingTransformHandler(PNStackLayout *layout, Function_
 
 	layout->Shuffle();//one final shuffle
 	layout->AddRandomPadding(do_align);
-			
+
 	if(!Sans_Canary_Rewrite(layout,func))
 	{
 		undo(func);
@@ -276,20 +263,9 @@ bool PNTransformDriver::PaddingTransformHandler(PNStackLayout *layout, Function_
 	else
 	{
 		cerr<<"PNTransformDriver: Final Transformation Success: "<<layout->ToString()<<endl;
-//		transformed_history[layout->GetLayoutName()].push_back(layout);
-		// finalize_record fr;
-		// fr.layout = layout;
-		// fr.func = func;
-		// fr.firp = orig_virp;
-		// finalization_registry.push_back(fr);
-		// undo(func);
 		success = true;
-		//undo_list.clear();
-		//reset_undo(func->getName());
 	}
 
-	//orig_virp->writeToDB();
-
 	return success;
 }
 
@@ -311,30 +287,20 @@ bool PNTransformDriver::LayoutRandTransformHandler(PNStackLayout *layout, Functi
 		//TODO: do I need to check for success at this point?
 		Sans_Canary_Rewrite(layout,func);
 		cerr<<"PNTransformDriver: Final Transformation Success: "<<layout->ToString()<<endl;
-//		transformed_history[layout->GetLayoutName()].push_back(layout);
-		// finalize_record fr;
-		// fr.layout = layout;
-		// fr.func = func;
-		// fr.firp = orig_virp;
-		// finalization_registry.push_back(fr);
-		// undo(func);
 		success = true;
-		//undo_list.clear();
-		//reset_undo(func->getName());
 	}
 
-	//orig_virp->writeToDB();
 	return success;
 }
 
 bool PNTransformDriver::IsBlacklisted(Function_t *func)
 {
-  if(sanitized.find(func) != sanitized.end())
-  {
-	  cerr<<"PNTransformDriver:: Sanitized Function "<<func->getName()<<endl;
-	  sanitized_funcs++;
-	  return true;
-  }
+	if(sanitized.find(func) != sanitized.end())
+	{
+		cerr<<"PNTransformDriver:: Sanitized Function "<<func->getName()<<endl;
+		sanitized_funcs++;
+		return true;
+	}
 
 	// @todo: specify regex patterns in black list file instead
 	//		  of special-casing here
@@ -342,21 +308,22 @@ bool PNTransformDriver::IsBlacklisted(Function_t *func)
 	// filter out _L_lock_*
 	// filter out _L_unlock_*
 
-  if (func->getName().find("_L_lock_") == 0 ||
-  func->getName().find("_L_unlock_") == 0 ||
-  func->getName().find("__gnu_")	!= string::npos ||
-  func->getName().find("cxx_") != string::npos||
-  func->getName().find("_cxx")  != string::npos ||
-  func->getName().find("_GLOBAL_")  != string::npos ||
-  func->getName().find("_Unwind")	 != string::npos ||
-  func->getName().find("__timepunct")	 != string::npos ||
-  func->getName().find("__timepunct")	 != string::npos ||
-  func->getName().find("__numpunct") != string::npos||
-  func->getName().find("__moneypunct")  != string::npos ||
-  func->getName().find("__PRETTY_FUNCTION__")	 != string::npos ||
-  func->getName().find("__cxa")  != string::npos ||
-  blacklist.find(func->getName()) != blacklist.end())
-//	if(blacklist.find(func->getName()) != blacklist.end())
+	if (
+			func->getName().find("_L_lock_") == 0 ||
+			func->getName().find("_L_unlock_") == 0 ||
+			func->getName().find("__gnu_")	!= string::npos ||
+			func->getName().find("cxx_") != string::npos||
+			func->getName().find("_cxx")  != string::npos ||
+			func->getName().find("_GLOBAL_")  != string::npos ||
+			func->getName().find("_Unwind")	 != string::npos ||
+			func->getName().find("__timepunct")	 != string::npos ||
+			func->getName().find("__timepunct")	 != string::npos ||
+			func->getName().find("__numpunct") != string::npos||
+			func->getName().find("__moneypunct")  != string::npos ||
+			func->getName().find("__PRETTY_FUNCTION__")	 != string::npos ||
+			func->getName().find("__cxa")  != string::npos ||
+			blacklist.find(func->getName()) != blacklist.end()
+	   )
 	{
 		cerr<<"PNTransformDriver: Blacklisted Function "<<func->getName()<<endl;
 		blacklist_funcs++;
@@ -395,19 +362,15 @@ void PNTransformDriver::InitNewFileIR(File_t* this_file, IRDBObjects_t *const ir
 	{
 		this_file=pidp->getMainFile();
 	}
+
 	//Always modify a.ncexe first. This is assumed to be what the constructor of FileIR_t will return if
 	//the variant ID is used alone as the parameter to the constructor. 
 	orig_virp = irdb_objects->addFileIR(pidp->getBaseID(), this_file->getBaseID());// new FileIR_t(*pidp, this_file);
 	assert(orig_virp && pidp);
 
-#if 0
-	int elfoid=orig_virp->getFile()->getELFOID();
-	pqxx::largeobject lo(elfoid);
-	lo.to_file(pqxx_interface->getTransaction(),"readeh_tmp_file.exe");
-#endif
 	elfiop=new EXEIO::exeio;
 	elfiop->load((char*)"a.ncexe");
-	
+
 	EXEIO::dump::header(cout,*elfiop);
 	EXEIO::dump::section_headers(cout,*elfiop);
 
@@ -418,7 +381,7 @@ void PNTransformDriver::InitNewFileIR(File_t* this_file, IRDBObjects_t *const ir
 
 
 template <class T> struct file_less : binary_function <T,T,bool> {
-  bool operator() (const T& x, const T& y) const {return  x->getURL()  <   y->getURL()  ;}
+	bool operator() (const T& x, const T& y) const {return  x->getURL()  <   y->getURL()  ;}
 };
 
 void PNTransformDriver::GenerateTransforms(IRDBObjects_t *const irdb_objects)
@@ -436,7 +399,7 @@ void PNTransformDriver::GenerateTransforms(IRDBObjects_t *const irdb_objects)
 		cerr<<"PNTransformDriver ERROR: no_validation_level greater than highest level in the hierarchy, exiting."<<endl;
 		exit(1);
 	}
-	
+
 
 	//TODO: I refactored PN, but to keep the refactoring simple, I did not change the use of the class field "orig_virp"
 	//now that I am protecting shared objects, it might be better to pass this variable around, or at least change the
@@ -447,7 +410,7 @@ void PNTransformDriver::GenerateTransforms(IRDBObjects_t *const irdb_objects)
 
 
 	// now that we've loaded the FileIR, we can init the reg expressions needed for this object.
-	pn_regex=new PNRegularExpressions;
+	pn_regex=make_unique<PNRegularExpressions>();
 
 
 	//Sanity check: make sure that this file is actually a.ncexe, if not assert false for now
@@ -474,9 +437,9 @@ void PNTransformDriver::GenerateTransforms(IRDBObjects_t *const irdb_objects)
 		set<File_t*,file_less<File_t*> > sorted_files;
 
 		for(set<File_t*>::iterator it=pidp->getFiles().begin();
-			it!=pidp->getFiles().end();
-			++it
-			)
+				it!=pidp->getFiles().end();
+				++it
+		   )
 		{
 			File_t* this_file=*it;
 			sorted_files.insert(this_file);
@@ -484,9 +447,9 @@ void PNTransformDriver::GenerateTransforms(IRDBObjects_t *const irdb_objects)
 
 
 		for(set<File_t*,file_less<File_t*> >::iterator it=sorted_files.begin();
-			it!=sorted_files.end()&&!timeExpired;
-			++it
-			)
+				it!=sorted_files.end()&&!timeExpired;
+				++it
+		   )
 		{
 			File_t* this_file=*it;
 			assert(this_file);
@@ -507,7 +470,7 @@ void PNTransformDriver::GenerateTransforms(IRDBObjects_t *const irdb_objects)
 			//the complete path is not currently in the DB for a shared object
 			//I have to loop through the map for now. 
 			for(map<string, map<string, double> >::iterator it=coverage_map.begin();
-				it!=coverage_map.end()&&!timeExpired; ++it)
+					it!=coverage_map.end()&&!timeExpired; ++it)
 			{
 				key = it->first;
 
@@ -528,7 +491,6 @@ void PNTransformDriver::GenerateTransforms(IRDBObjects_t *const irdb_objects)
 
 
 			cerr<<"######PreFile Report: Accumulated results prior to processing file: "<<url<<"######"<<endl;
-			//Print_Report();
 
 			cout<<"PNTransformDriver: Protecting File: "<<url<<endl;
 			GenerateTransformsHidden(file_coverage_map);
@@ -600,11 +562,11 @@ static bool is_exit_insn(Instruction_t* prev)
 
 	// check for fixed_call
 	const auto reloc_it=find_if(ALLOF(prev->getRelocations()), [&](const Relocation_t* r)
-		{ return r->getType()=="fix_call_fallthrough"; } ); 
+			{ return r->getType()=="fix_call_fallthrough"; } ); 
 	if(reloc_it!=end(prev->getRelocations()))
 		return false;
-	
-	
+
+
 	if(prev->getFallthrough()==NULL && prev->getTarget()==NULL)
 	{
 		const auto dp=DecodedInstruction_t::factory(prev);
@@ -616,9 +578,9 @@ static bool is_exit_insn(Instruction_t* prev)
 		if(ib_targets)
 		{
 			const auto out_of_function_it=find_if(ALLOF(*ib_targets), [&](const Instruction_t* i)
-				{ 
+					{ 
 					return i->getFunction() != prev->getFunction(); 
-				} ) ;
+					} ) ;
 
 			if(out_of_function_it!=end(*ib_targets))
 				return true; // detected this as an exit node.
@@ -658,9 +620,9 @@ static bool	check_for_cond_frame(Function_t *func, ControlFlowGraph_t* cfg)
 	const auto is_rsp_sub= [](const DecodedInstruction_t &d) -> bool
 	{
 		return 
-		  (d.getMnemonic() == /*string(d.Instruction.Mnemonic)==*/"sub" &&  		/* is sub */
-		  d.getOperand(0)->isRegister() /* ((d.Argument1.ArgType&0xFFFF0000)==REGISTER_TYPE+GENERAL_REG )*/ &&  /* and arg1 is a register */
-		  d.getOperand(0)->getRegNumber()==4 /*(d.Argument1.ArgType&0x0000FFFF)==REG4*/);		/* and is the stack pointer. */
+			(d.getMnemonic() == /*string(d.Instruction.Mnemonic)==*/"sub" &&  		/* is sub */
+			 d.getOperand(0)->isRegister() /* ((d.Argument1.ArgType&0xFFFF0000)==REGISTER_TYPE+GENERAL_REG )*/ &&  /* and arg1 is a register */
+			 d.getOperand(0)->getRegNumber()==4 /*(d.Argument1.ArgType&0x0000FFFF)==REG4*/);		/* and is the stack pointer. */
 	};
 
 	const auto is_rsp_sub_insn= [&](const Instruction_t* i) -> bool
@@ -688,7 +650,7 @@ static bool	check_for_cond_frame(Function_t *func, ControlFlowGraph_t* cfg)
 			cout<<"Found cond-frame in "<<func->getName()<<" because "<<i->getDisassembly()<<endl;
 			return false; 
 		}
-			
+
 	} 
 	return true;
 }
@@ -710,7 +672,7 @@ static bool	check_for_push_pop_coherence(Function_t *func)
 
 
 
-//cerr<<"Found "<<prologue_pushes<<" pushes in "<<func->getName()<<endl;
+	//cerr<<"Found "<<prologue_pushes<<" pushes in "<<func->getName()<<endl;
 
 	// keep a map that keeps the count of pops for each function exit.
 	map<Instruction_t*, int> pop_count_per_exit;
@@ -719,9 +681,9 @@ static bool	check_for_push_pop_coherence(Function_t *func)
 
 	// now, look for pops, and fill in that map.
 	for(
-		set<Instruction_t*>::const_iterator it=func->getInstructions().begin();
-		it!=func->getInstructions().end();
-		++it
+			set<Instruction_t*>::const_iterator it=func->getInstructions().begin();
+			it!=func->getInstructions().end();
+			++it
 	   )
 	{
 		Instruction_t* insn=*it;
@@ -747,7 +709,7 @@ static bool	check_for_push_pop_coherence(Function_t *func)
 
 			if(exit_insn)
 			{
-//cerr<<"Found exit insn ("<< d2.CompleteInstr << ") for pop ("<< d.CompleteInstr << ")"<<endl;
+				//cerr<<"Found exit insn ("<< d2.CompleteInstr << ") for pop ("<< d.CompleteInstr << ")"<<endl;
 				map<Instruction_t*, int>::iterator mit;
 				mit=pop_count_per_exit.find(exit_insn);
 				if(mit == pop_count_per_exit.end())		// not found
@@ -757,12 +719,12 @@ static bool	check_for_push_pop_coherence(Function_t *func)
 			}
 			else
 			{
-//
-//  some pops dont match exit points because they follow a call instruction where arguments were pushed.
-//  so, we don't immediately error if the pop doesn't match to an exit point.
-//
-//				cerr<<"Could not find exit insn for pop ("<< hex << insn->getBaseID() <<":"<< d.CompleteInstr << " at " << insn->getAddress()->getVirtualOffset() << ")"<<endl;
-//				return false;
+				//
+				//  some pops dont match exit points because they follow a call instruction where arguments were pushed.
+				//  so, we don't immediately error if the pop doesn't match to an exit point.
+				//
+				//				cerr<<"Could not find exit insn for pop ("<< hex << insn->getBaseID() <<":"<< d.CompleteInstr << " at " << insn->getAddress()->getVirtualOffset() << ")"<<endl;
+				//				return false;
 			}
 		}
 	}
@@ -773,9 +735,9 @@ static bool	check_for_push_pop_coherence(Function_t *func)
 	// stack first.  Also handy as this allows "fixed" calls to be ignored.
 	// but, since exits with 0 pops aren't in the map, we don't need an explicit check for them.
 	for(
-		map<Instruction_t* ,int>::iterator it=pop_count_per_exit.begin();
-		it!=pop_count_per_exit.end();
-		++it
+			map<Instruction_t* ,int>::iterator it=pop_count_per_exit.begin();
+			it!=pop_count_per_exit.end();
+			++it
 	   )
 	{
 		pair<Instruction_t*const,int> map_pair=*it;
@@ -822,14 +784,14 @@ static bool	check_for_push_pop_coherence(Function_t *func)
 					<<hex<<"0x"<<insn->getAddress()->getVirtualOffset()<<endl;
 				return false;
 			}
-			
+
 		}
 		else
 		{
 			cerr<<"Sanitizing function "<<func->getName()<<" because prologue has more than 1 subrsp? "<<endl;
 			return false;
 		}
-		
+
 	}
 
 	return true;
@@ -837,30 +799,30 @@ static bool	check_for_push_pop_coherence(Function_t *func)
 
 /*
  * check_for_bad_variadic_funcs  -- Look for functions of this form:
-   0x0000000000418108 <+0>:	push   rbp
-   0x0000000000418109 <+1>:	mov    rbp,rsp
-   0x000000000041810c <+4>:	sub    rsp,0x100
-   0x0000000000418113 <+11>:	mov    DWORD PTR [rbp-0xd4],edi
-   0x0000000000418119 <+17>:	mov    QWORD PTR [rbp-0xe0],rsi
-   0x0000000000418120 <+24>:	mov    QWORD PTR [rbp-0x98],rcx
-   0x0000000000418127 <+31>:	mov    QWORD PTR [rbp-0x90],r8
-   0x000000000041812e <+38>:	mov    QWORD PTR [rbp-0x88],r9
-   0x0000000000418135 <+45>:	movzx  eax,al
-   0x0000000000418138 <+48>:	mov    QWORD PTR [rbp-0xf8],rax
-   0x000000000041813f <+55>:	mov    rcx,QWORD PTR [rbp-0xf8]
-   0x0000000000418146 <+62>:	lea    rax,[rcx*4+0x0]
-   0x000000000041814e <+70>:	mov    QWORD PTR [rbp-0xf8],0x41818d
-   0x0000000000418159 <+81>:	sub    QWORD PTR [rbp-0xf8],rax
-   0x0000000000418160 <+88>:	lea    rax,[rbp-0x1]
-   0x0000000000418164 <+92>:	mov    rcx,QWORD PTR [rbp-0xf8]
-   0x000000000041816b <+99>:	jmp    rcx
-	<leaves function>
-
-This is a common IDApro failure, as the computed jump is strange for IDA.
-
-We check for this case by looking for the movzx before EAX is/used otherwise .
-
-Return value:  true if function is OK to transform, false if we find the pattern.
+ 0x0000000000418108 <+0>:	push   rbp
+ 0x0000000000418109 <+1>:	mov    rbp,rsp
+ 0x000000000041810c <+4>:	sub    rsp,0x100
+ 0x0000000000418113 <+11>:	mov    DWORD PTR [rbp-0xd4],edi
+ 0x0000000000418119 <+17>:	mov    QWORD PTR [rbp-0xe0],rsi
+ 0x0000000000418120 <+24>:	mov    QWORD PTR [rbp-0x98],rcx
+ 0x0000000000418127 <+31>:	mov    QWORD PTR [rbp-0x90],r8
+ 0x000000000041812e <+38>:	mov    QWORD PTR [rbp-0x88],r9
+ 0x0000000000418135 <+45>:	movzx  eax,al
+ 0x0000000000418138 <+48>:	mov    QWORD PTR [rbp-0xf8],rax
+ 0x000000000041813f <+55>:	mov    rcx,QWORD PTR [rbp-0xf8]
+ 0x0000000000418146 <+62>:	lea    rax,[rcx*4+0x0]
+ 0x000000000041814e <+70>:	mov    QWORD PTR [rbp-0xf8],0x41818d
+ 0x0000000000418159 <+81>:	sub    QWORD PTR [rbp-0xf8],rax
+ 0x0000000000418160 <+88>:	lea    rax,[rbp-0x1]
+ 0x0000000000418164 <+92>:	mov    rcx,QWORD PTR [rbp-0xf8]
+ 0x000000000041816b <+99>:	jmp    rcx
+ <leaves function>
+
+ This is a common IDApro failure, as the computed jump is strange for IDA.
+
+ We check for this case by looking for the movzx before EAX is/used otherwise .
+
+ Return value:  true if function is OK to transform, false if we find the pattern.
 
 */
 bool	check_for_bad_variadic_funcs(Function_t *func, const ControlFlowGraph_t* cfg)
@@ -910,17 +872,17 @@ bool	check_for_bad_variadic_funcs(Function_t *func, const ControlFlowGraph_t* cf
 
 static EXEIO::section*  find_section(VirtualOffset_t addr, EXEIO::exeio *elfiop)
 {
-	 for ( int i = 0; i < elfiop->sections.size(); ++i )
-	 {
-		 EXEIO::section* pSec = elfiop->sections[i];
-		 assert(pSec);
-		 if(pSec->get_address() > addr)
-				 continue;
-		 if(addr >= pSec->get_address()+pSec->get_size())
-				 continue;
-
-		 return pSec;
-}
+	for ( int i = 0; i < elfiop->sections.size(); ++i )
+	{
+		EXEIO::section* pSec = elfiop->sections[i];
+		assert(pSec);
+		if(pSec->get_address() > addr)
+			continue;
+		if(addr >= pSec->get_address()+pSec->get_size())
+			continue;
+
+		return pSec;
+	}
 	return NULL;
 }
 
@@ -975,33 +937,33 @@ bool PNTransformDriver::check_jump_tables(Instruction_t* insn)
 
 		if(table_entry!=0)
 		{
-//			cout << "found possible table entry "<<hex<<table_entry<<" from func "<<insn->getFunction()->getName()<<endl;
+			//			cout << "found possible table entry "<<hex<<table_entry<<" from func "<<insn->getFunction()->getName()<<endl;
 			jump_tab_entries.insert(table_entry);
 		}
 
 	}
-	
+
 	return check_jump_table_entries(jump_tab_entries,insn->getFunction());
-	
+
 }
 
 bool PNTransformDriver::check_jump_table_entries(set<int> jump_tab_entries,Function_t* func)
 {
 	for(
-		set<Instruction_t*>::const_iterator it=orig_virp->getInstructions().begin();
-		it!=orig_virp->getInstructions().end();
-		++it
+			set<Instruction_t*>::const_iterator it=orig_virp->getInstructions().begin();
+			it!=orig_virp->getInstructions().end();
+			++it
 	   )
 	{
 		Instruction_t* ftinsn=*it;;
 		AddressID_t* addr=ftinsn->getAddress();
 		int voff=addr->getVirtualOffset();
-	
+
 		// check to see if this instruction is in my table 
 		if(jump_tab_entries.find(voff)!=jump_tab_entries.end())
 		{
 			// it is!
-	
+
 			// now, check to see if the instruction is in my function 
 			if(func !=ftinsn->getFunction())
 			{
@@ -1021,58 +983,58 @@ bool PNTransformDriver::check_jump_table_entries(set<int> jump_tab_entries,Funct
 bool PNTransformDriver::backup_until(const char* insn_type_regex, Instruction_t *& prev, Instruction_t* orig, bool recursive)
 {
 	prev=orig;
-        regex_t preg;
+	regex_t preg;
 
-        assert(0 == regcomp(&preg, insn_type_regex, REG_EXTENDED));
+	assert(0 == regcomp(&preg, insn_type_regex, REG_EXTENDED));
 
-        int max=10000;
-        while(preds[prev].size()==1 && max-- > 0)
-        {
-                // get the only item in the list.
-                prev=*(preds[prev].begin());
+	int max=10000;
+	while(preds[prev].size()==1 && max-- > 0)
+	{
+		// get the only item in the list.
+		prev=*(preds[prev].begin());
 
 
-                // get I7's disassembly
-                auto disasm_p=DecodedInstruction_t::factory(prev);
+		// get I7's disassembly
+		auto disasm_p=DecodedInstruction_t::factory(prev);
 		auto &disasm=*disasm_p;
 
-                // check it's the requested type
-                if(regexec(&preg, disasm.getDisassembly().c_str() /*CompleteInstr*/, 0, NULL, 0) == 0)
-                {
-                        regfree(&preg);
-                        return true;
-                }
-
-                // otherwise, try backing up again.
-        }
-
-        if(recursive)
-        {
-                Instruction_t* myprev=prev;
-                // can't just use prev because recursive call will update it.
-                for(InstructionSet_t::iterator it=preds[myprev].begin();
-                        it!=preds[myprev].end(); ++it)
-                {
-                        Instruction_t* pred=*it;
-                        //Disassemble(pred,disasm);
-                        auto disasmp=DecodedInstruction_t::factory(pred);
-                        auto &disasm=*disasmp;
-                        // check it's the requested type
-                        if(regexec(&preg, disasm.getDisassembly().c_str()/*CompleteInstr*/, 0, NULL, 0) == 0)
-                        {
-                                regfree(&preg);
-                                return true;
-                        }
-                        if(backup_until(insn_type_regex, prev, pred))
-                        {
-                                regfree(&preg);
-                                return true;
-                        }
-                        // reset for next call
-                        prev=myprev;
-                }
-        }
-        regfree(&preg);
+		// check it's the requested type
+		if(regexec(&preg, disasm.getDisassembly().c_str() /*CompleteInstr*/, 0, NULL, 0) == 0)
+		{
+			regfree(&preg);
+			return true;
+		}
+
+		// otherwise, try backing up again.
+	}
+
+	if(recursive)
+	{
+		Instruction_t* myprev=prev;
+		// can't just use prev because recursive call will update it.
+		for(InstructionSet_t::iterator it=preds[myprev].begin();
+				it!=preds[myprev].end(); ++it)
+		{
+			Instruction_t* pred=*it;
+			//Disassemble(pred,disasm);
+			auto disasmp=DecodedInstruction_t::factory(pred);
+			auto &disasm=*disasmp;
+			// check it's the requested type
+			if(regexec(&preg, disasm.getDisassembly().c_str()/*CompleteInstr*/, 0, NULL, 0) == 0)
+			{
+				regfree(&preg);
+				return true;
+			}
+			if(backup_until(insn_type_regex, prev, pred))
+			{
+				regfree(&preg);
+				return true;
+			}
+			// reset for next call
+			prev=myprev;
+		}
+	}
+	regfree(&preg);
 	return false;
 }
 
@@ -1081,10 +1043,10 @@ void  PNTransformDriver::calc_preds()
 	preds.clear();
 	for(const auto &insn : orig_virp->getInstructions())
 	{
-			if(insn->getTarget())
-					preds[insn->getTarget()].insert(insn);
-			if(insn->getFallthrough())
-					preds[insn->getFallthrough()].insert(insn);
+		if(insn->getTarget())
+			preds[insn->getTarget()].insert(insn);
+		if(insn->getFallthrough())
+			preds[insn->getFallthrough()].insert(insn);
 	}
 }
 
@@ -1097,108 +1059,108 @@ void  PNTransformDriver::calc_preds()
 bool PNTransformDriver::check_for_PIC_switch_table64(Instruction_t* insn, const DecodedInstruction_t& disasm)
 {
 
-		/* here's the pattern we're looking for */
+	/* here's the pattern we're looking for */
 #if 0
 I1:   0x000000000044425a <+218>:        cmp    DWORD PTR [rax+0x8],0xd   // bounds checking code, 0xd cases.
-I2:   0x000000000044425e <+222>:        jbe    0x444320 <_gedit_tab_get_icon+416>
-
-<snip>
-I3:   0x0000000000444264 <+228>:        mov    rdi,rbp // default case, also jumped to via indirect branch below
-<snip>
-I4:   0x0000000000444320 <+416>:        mov    edx,DWORD PTR [rax+0x8]
-I5:   0x0000000000444323 <+419>:        lea    rax,[rip+0x3e1b6]        # 0x4824e0
-I6:   0x000000000044432a <+426>:        movsxd rdx,DWORD PTR [rax+rdx*4]
-I7:   0x000000000044432e <+430>:        add    rax,rdx
-I8:   0x0000000000444331 <+433>:        jmp    rax      // relatively standard switch dispatch code
-
-
-D1:   0x4824e0: .long 0x4824e0-L1       // L1-LN are labels in the code where case statements start.
-D2:   0x4824e0: .long 0x4824e0-L2
-..
-DN:   0x4824e0: .long 0x4824e0-LN
+	      I2:   0x000000000044425e <+222>:        jbe    0x444320 <_gedit_tab_get_icon+416>
+
+	      <snip>
+	      I3:   0x0000000000444264 <+228>:        mov    rdi,rbp // default case, also jumped to via indirect branch below
+	      <snip>
+	      I4:   0x0000000000444320 <+416>:        mov    edx,DWORD PTR [rax+0x8]
+	      I5:   0x0000000000444323 <+419>:        lea    rax,[rip+0x3e1b6]        # 0x4824e0
+	      I6:   0x000000000044432a <+426>:        movsxd rdx,DWORD PTR [rax+rdx*4]
+	      I7:   0x000000000044432e <+430>:        add    rax,rdx
+	      I8:   0x0000000000444331 <+433>:        jmp    rax      // relatively standard switch dispatch code
+
+
+	      D1:   0x4824e0: .long 0x4824e0-L1       // L1-LN are labels in the code where case statements start.
+	      D2:   0x4824e0: .long 0x4824e0-L2
+	      ..
+	      DN:   0x4824e0: .long 0x4824e0-LN
 #endif
 
 
-		// for now, only trying to find I4-I8.  ideally finding I1 would let us know the size of the
-		// jump table.  We'll figure out N by trying targets until they fail to produce something valid.
+	      // for now, only trying to find I4-I8.  ideally finding I1 would let us know the size of the
+	      // jump table.  We'll figure out N by trying targets until they fail to produce something valid.
 
-		Instruction_t* I8=insn;
-		Instruction_t* I7=NULL;
-		Instruction_t* I6=NULL;
-		Instruction_t* I5=NULL;
-		// check if I8 is a jump
-		if(disasm.getMnemonic() !=  "jmp")
-				return true;
+	      Instruction_t* I8=insn;
+      Instruction_t* I7=NULL;
+      Instruction_t* I6=NULL;
+      Instruction_t* I5=NULL;
+      // check if I8 is a jump
+      if(disasm.getMnemonic() !=  "jmp")
+	      return true;
 
-	// return if it's a jump to a constant address, these are common
-	if(disasm.getOperand(0)->isConstant())
-		return true;
-	// return if it's a jump to a memory address
-	if(disasm.getOperand(0)->isMemory())
-		return true;
+      // return if it's a jump to a constant address, these are common
+      if(disasm.getOperand(0)->isConstant())
+	      return true;
+      // return if it's a jump to a memory address
+      if(disasm.getOperand(0)->isMemory())
+	      return true;
 
-	// has to be a jump to a register now
+      // has to be a jump to a register now
 
-	// backup and find the instruction that's an add before I8 
-	if(!backup_until("add", I7, I8))
-		return true;
+      // backup and find the instruction that's an add before I8 
+      if(!backup_until("add", I7, I8))
+	      return true;
 
-	// backup and find the instruction that's an movsxd before I7
-	if(!backup_until("movsxd", I6, I7))
-		return true;
+      // backup and find the instruction that's an movsxd before I7
+      if(!backup_until("movsxd", I6, I7))
+	      return true;
 
-	// backup and find the instruction that's an lea before I6
-	if(!backup_until("lea", I5, I6))
-		return true;
+      // backup and find the instruction that's an lea before I6
+      if(!backup_until("lea", I5, I6))
+	      return true;
 
-	auto i5_disasmp=DecodedInstruction_t::factory(I5); // Disassemble(I5,disasm);
-	auto &i5_disasm=*i5_disasmp;
+      auto i5_disasmp=DecodedInstruction_t::factory(I5); // Disassemble(I5,disasm);
+      auto &i5_disasm=*i5_disasmp;
 
-	if(!i5_disasm.getOperand(1)->isMemory())
-			return true;
-	if(!i5_disasm.getOperand(1)->isPcrel())
-			return true;
+      if(!i5_disasm.getOperand(1)->isMemory())
+	      return true;
+      if(!i5_disasm.getOperand(1)->isPcrel())
+	      return true;
 
-	// note that we'd normally have to add the displacement to the
-	// instruction address (and include the instruction's size, etc.
-	// but, fix_calls has already removed this oddity so we can relocate
-	// the instruction.
-	int D1=strtol(i5_disasm.getOperand(1)->getString().c_str(), NULL, 16);
+      // note that we'd normally have to add the displacement to the
+      // instruction address (and include the instruction's size, etc.
+      // but, fix_calls has already removed this oddity so we can relocate
+      // the instruction.
+      int D1=strtol(i5_disasm.getOperand(1)->getString().c_str(), NULL, 16);
 
-	// find the section with the data table
-	EXEIO::section *pSec=find_section(D1,elfiop);
+      // find the section with the data table
+      EXEIO::section *pSec=find_section(D1,elfiop);
 
-	// sanity check there's a section
-	if(!pSec)
-			return true;
+      // sanity check there's a section
+      if(!pSec)
+	      return true;
 
-	const char* secdata=pSec->get_data();
+      const char* secdata=pSec->get_data();
 
-	// if the section has no data, abort 
-	if(!secdata)
-		return true;
+      // if the section has no data, abort 
+      if(!secdata)
+	      return true;
 
-	set<int> table_entries;
-		int offset=D1-pSec->get_address();
-		int entry=0;
-		for(int i=0;table_entries.size()<5;i++)
-		{
-				// check that we can still grab a word from this section
-				if((int)(offset+sizeof(int)) > (int)pSec->get_size())
-						break;
+      set<int> table_entries;
+      int offset=D1-pSec->get_address();
+      int entry=0;
+      for(int i=0;table_entries.size()<5;i++)
+      {
+	      // check that we can still grab a word from this section
+	      if((int)(offset+sizeof(int)) > (int)pSec->get_size())
+		      break;
 
-				const int *table_entry_ptr=(const int*)&(secdata[offset]);
-				int table_entry=*table_entry_ptr;
+	      const int *table_entry_ptr=(const int*)&(secdata[offset]);
+	      int table_entry=*table_entry_ptr;
 
-		//put in set -> d1+table_entry
-		table_entries.insert(D1+table_entry);
+	      //put in set -> d1+table_entry
+	      table_entries.insert(D1+table_entry);
 
-				offset+=sizeof(int);
-				entry++;
+	      offset+=sizeof(int);
+	      entry++;
 
-		} 
+      } 
 
-	return check_jump_table_entries(table_entries,insn->getFunction());
+      return check_jump_table_entries(table_entries,insn->getFunction());
 }
 
 void PNTransformDriver::SanitizeFunctions()
@@ -1208,19 +1170,19 @@ void PNTransformDriver::SanitizeFunctions()
 	sanitized.clear();
 
 	for(
-		set<Function_t*>::const_iterator func_it=orig_virp->getFunctions().begin();
-		func_it!=orig_virp->getFunctions().end();
-		++func_it
-		)
+			set<Function_t*>::const_iterator func_it=orig_virp->getFunctions().begin();
+			func_it!=orig_virp->getFunctions().end();
+			++func_it
+	   )
 	{
 		Function_t *func = *func_it;
 		assert(func);
 
 		for(
-			set<Instruction_t*>::const_iterator it=func->getInstructions().begin();
-			it!=func->getInstructions().end();
-			++it
-			)
+				set<Instruction_t*>::const_iterator it=func->getInstructions().begin();
+				it!=func->getInstructions().end();
+				++it
+		   )
 		{
 			Instruction_t* instr = *it;
 
@@ -1245,7 +1207,7 @@ void PNTransformDriver::SanitizeFunctions()
 					// exits the function.  If so, sanitize both funcs.
 					TargetFunctionCheck(instr,instr->getTarget());
 
-			
+
 			}
 
 			// if it's not already sanitized
@@ -1263,7 +1225,7 @@ void PNTransformDriver::SanitizeFunctions()
 			// if it's not already sanitized
 			if(sanitized.find(func)==sanitized.end())
 			{
-			  	if(!check_for_PIC_switch_table64(instr,disasm))
+				if(!check_for_PIC_switch_table64(instr,disasm))
 				{
 					pic_jump_table_sanitized++;
 					sanitized.insert(func);
@@ -1274,8 +1236,8 @@ void PNTransformDriver::SanitizeFunctions()
 			if(sanitized.find(func)==sanitized.end())
 			{
 				if(instr->getEhCallSite() && 
-				   instr->getEhCallSite()->getLandingPad() && 
-				   instr->getEhCallSite()->getLandingPad()->getFunction()!=func) 
+						instr->getEhCallSite()->getLandingPad() && 
+						instr->getEhCallSite()->getLandingPad()->getFunction()!=func) 
 				{
 					eh_sanitized++;
 					sanitized.insert(func);
@@ -1325,10 +1287,10 @@ void PNTransformDriver::SanitizeFunctions()
 	cerr<<"Sanitization Report:"<<"\nThe following "<<sanitized.size()<<
 		" functions were sanitized from this file:"<<endl;
 	for(
-		set<Function_t*>::const_iterator it=sanitized.begin();
-		it!=sanitized.end();
-		++it
-		)
+			set<Function_t*>::const_iterator it=sanitized.begin();
+			it!=sanitized.end();
+			++it
+	   )
 	{
 		Function_t *func=*it;
 		if(func != NULL)
@@ -1386,7 +1348,7 @@ inline bool PNTransformDriver::TargetFunctionCheck(Instruction_t* a, Instruction
 
 
 template <class T> struct func_less : binary_function <T,T,bool> {
-  bool operator() (const T& x, const T& y) const {return  x->getName()  <   y->getName()  ;}
+	bool operator() (const T& x, const T& y) const {return  x->getName()  <   y->getName()  ;}
 };
 //Speculation note:
 
@@ -1417,14 +1379,14 @@ void PNTransformDriver::GenerateTransformsHidden(map<string,double> &file_covera
 				func->getName()<<endl;
 			break;
 		}
-		
+
 		if(getenv("PN_ONLYTRANSFORM") && funcs_attempted!=atoi(getenv("PN_ONLYTRANSFORM")))
 		{
 			cout<<"Skipping function "<<dec<<funcs_attempted<<", named: "<<func->getName()<<endl;
 			funcs_attempted++;
 			continue;
 		}
-		
+
 
 		//TODO: remove this at some point when I understand if this can happen or not
 		assert(func != NULL);
@@ -1490,10 +1452,10 @@ void PNTransformDriver::GenerateTransformsHidden(map<string,double> &file_covera
 		//If the number of null inferences encountered equals the number of inferences
 		//that are possible (based on the starting level which may not be 0), then
 		//the function is not transformable. 
-//		if((int)transform_hierarchy.size()-starting_level == null_inf_count)
-//			not_transformable.push_back(func->getName());
+		//		if((int)transform_hierarchy.size()-starting_level == null_inf_count)
+		//			not_transformable.push_back(func->getName());
 		//TODO: is there a better way of checking this?
-//		else
+		//		else
 
 		if(layouts.size() == 0)
 		{
@@ -1605,11 +1567,10 @@ void PNTransformDriver::GenerateTransformsHidden(map<string,double> &file_covera
 //returns true if all validate vrs validate without any failures. 
 void PNTransformDriver::ShuffleValidation(vector<validation_record> &vrs)
 {
-//	bool success = true;
 	for(unsigned int i=0;i<vrs.size()&&!timeExpired;i++)
 	{
 		PNStackLayout *layout = vrs[i].layouts[vrs[i].layout_index];
-		
+
 		while(layout != NULL&&!timeExpired)
 		{
 			//using padding transform handler since I now 
@@ -1620,7 +1581,6 @@ void PNTransformDriver::ShuffleValidation(vector<validation_record> &vrs)
 			//does not even attempt it. 
 			if(!PaddingTransformHandler(layout,vrs[i].func,true))
 			{
-//				success = false;
 				//we will assume all subsequent layouts require shuffle validation. 
 				//if it doesn't, the padding transform handler will add
 				//padding and shuffle without shuffle validation.
@@ -1645,7 +1605,7 @@ void PNTransformDriver::ShuffleValidation(vector<validation_record> &vrs)
 		}
 	}
 
-//	return success;
+	//	return success;
 }
 
 //Alters the passed in validation record to record the layout information, and
@@ -1708,9 +1668,6 @@ void PNTransformDriver::Register_Finalized(vector<validation_record> &vrs,unsign
 		//could change when the modification is finalized. 
 		transformed_history[fr.layout->GetLayoutName()].push_back(fr.layout);
 
-//DEBUG: turning off undo to accumulate for now. A bug in modifying zsh
-//seems to indicate this functionality (registration) is broken. 
-//		undo(vrs[index].func); //make sure this function is registered only (undo any prior mods)
 		cout<<"registering "<<fr.func->getName()<<" layout "<<fr.layout->GetLayoutName()<<endl;
 	}
 
@@ -1800,49 +1757,10 @@ bool PNTransformDriver::Validate_Recursive(vector<validation_record> &vrs, unsig
 
 			return false;
 		}
-		
+
 	}
 }
 
-
-
-
-
-// 			//NOTE: this only_validate_list functionality may not be needed any more, consider removing
-// 			//TODO: for now, only validate if the only_validate_list doesn't have any contents and
-// 			//the level does not equal the never_validate level. I may want to allow the only validate
-// 			//list to be empty, in which case a pointer is better, to check for NULL.
-// 			bool do_validate = true;
-// 			if(only_validate_list.size() != 0)
-// 			{
-// 				if(only_validate_list.find(func->getName()) == only_validate_list.end())
-// 					do_validate = false;
-// 			}
-
-// 			do_validate = do_validate && (level != no_validation_level);
-		
-
-// 			//Go through each layout in the level of the hierarchy in order. 
-// 			for(unsigned int i=0;i<layouts.size()&&!timeExpired;i++)
-// 			{
-// 				//TODO: I need to have the ability to make transformations optional
-// 				if(layouts[i]->IsCanarySafe())
-// 					success = CanaryTransformHandler(layouts[i],func,do_validate);
-// 				else if(layouts[i]->IsPaddingSafe())
-// 					success = PaddingTransformHandler(layouts[i],func,do_validate);
-// 				//if not canary or padding safe, the layout can only be randomized
-// 				else
-// 					success = LayoutRandTransformHandler(layouts[i],func,do_validate);
-
-// 				if(!success && (int)transform_hierarchy.size()-1 == level && i == layouts.size()-1)
-// 						failed.push_back(func);
-// 					else if(success)
-// 						break;
-// 			}
-// 		}	
-// 	}
-// }
-
 void PNTransformDriver::Finalize_Transformation()
 {
 	cout<<"Finalizing Transformation: Committing all previously validated transformations ("<<finalization_registry.size()<<" functions)"<<endl;
@@ -1862,9 +1780,9 @@ void PNTransformDriver::Finalize_Transformation()
 	//Commit changes for each file. 
 	//TODO: is this necessary, can I do one write?
 	for(set<FileIR_t*>::iterator it=registered_firps.begin();
-		it!=registered_firps.end();
-		++it
-		)
+			it!=registered_firps.end();
+			++it
+	   )
 	{
 		FileIR_t *firp = *it;
 		cout<<"Writing to DB: "<<firp->getFile()->getURL()<<endl;
@@ -1908,7 +1826,7 @@ void PNTransformDriver::Print_Report()
 	for(it = transformed_history.begin(); it != transformed_history.end(); it++)
 	{
 		total_transformed += it->second.size();
-	
+
 		//TODO: sort by layout type then print
 		for(unsigned int i=0;i<it->second.size();i++)
 		{
@@ -2051,7 +1969,7 @@ vector<PNStackLayout*> PNTransformDriver::GenerateInferences(Function_t *func,in
 	{
 		cerr << "PNTransformDriver: Generating Layout Inference for " << transform_hierarchy[level][inf]->GetInferenceName() << endl;
 		PNStackLayout *tmp = (transform_hierarchy[level][inf])->GetPNStackLayout(func);
-		
+
 		if (tmp == NULL)
 		{  
 			cerr << "PNTransformDriver: NULL Inference Generated" << endl;
@@ -2121,75 +2039,6 @@ bool PNTransformDriver::Validate(FileIR_t *virp, string name)
 		return true;
 
 	assert(0); // functionality deprecated.
-#if 0
-	cerr<<"PNTransformDriver: Validate(): "<<name<<endl;
-
-	string dirname = "p1.xform/" + name;
-	string cmd = "mkdir -p " + dirname;
-	int res=system(cmd.c_str());
-	assert(res!=-1);
-	
-	string aspri_filename = string(get_current_dir_name()) + "/" + dirname + "/a.irdb.aspri";
-	string bspri_filename = string(get_current_dir_name()) + "/" + dirname + "/a.irdb.bspri";
-	ofstream aspriFile;
-	aspriFile.open(aspri_filename.c_str());
-	
-	if(!aspriFile.is_open())
-	{
-		assert(false);
-	}
-	
-	cerr<<"Pre genreate SPRI"<<endl;
-
-	if(virp == NULL)
-	{
-		//Generate spri for previous files
-		for(set<FileIR_t*>::iterator it=registered_firps.begin();
-			it!=registered_firps.end();
-			++it
-			)
-		{
-			FileIR_t *firp = *it;
-			firp->GenerateSPRI(aspriFile,false);
-		}
-	}
-	//generate spri for the current file
-	else
-		virp->GenerateSPRI(aspriFile,false); // p1.xform/<function_name>/a.irdb.aspri
-	cerr<<"Post genreate SPRI"<<endl;
-	aspriFile.close();
-
-	char new_instr[1024];
-	//This script generates the aspri and bspri files; it also runs BED
-	sprintf(new_instr, "%s %d %s %s", BED_script.c_str(), orig_progid, aspri_filename.c_str(), bspri_filename.c_str());
-	
-	//If OK=BED(func), then commit	
-	int rt=system(new_instr);
-	int actual_exit = -1;
-//	int actual_signal = -1;
-	if (WIFEXITED(rt)) actual_exit = WEXITSTATUS(rt);
-//	else actual_signal = WTERMSIG(rt);
-	int retval = actual_exit;
-
-	//TODO: I have set exit code status 3 to indicate spasm failure
-	//if spasm fails, there is no point in continuing. 
-	assert(retval != 3);
-
-	//TODO: was I supposed to do something with actual_signal?
-
-	string asm_filename = string(get_current_dir_name()) + "/" + dirname + "/a.irdb.?spri.asm";
-	string bin_filename = string(get_current_dir_name()) + "/" + dirname + "/a.irdb.?spri.asm.bin";
-	string map_filename = string(get_current_dir_name()) + "/" + dirname + "/a.irdb.?spri.asm.map";
-	string rm_command="rm -f ";
-	rm_command+=bspri_filename + " ";
-	rm_command+=asm_filename   + " ";
-	rm_command+=bin_filename   + " ";
-	rm_command+=map_filename   + " ";
-
-	ignore_result(system(rm_command.c_str())); // don't bother with an error check.
-	
-	return (retval == 0);
-#endif
 }
 
 unsigned int PNTransformDriver::GetRandomCanary()
@@ -2200,30 +2049,13 @@ unsigned int PNTransformDriver::GetRandomCanary()
 	 */
 	return pn_options->getCanaryValue();
 
-#if 0
-/* note:  this code  is being careful to get a full 32-bits of entropy, and rand() is only promising 16-bits of entropy.
- */
-	//TODO: check for bias.
-	stringstream canary;
-	canary.str("");
-
-	//canary<<hex<<pn_options->GetCanaryValue(); 
-	for(int i=0;i<8;i++)
-	{
-		canary<<hex<< (rand()%16);
-	}
-	unsigned int ret_val;
-	sscanf(canary.str().c_str(),"%x",&ret_val);
-
-	return ret_val;
-#endif
 }
 
 bool PNTransformDriver::Canary_Rewrite(PNStackLayout *orig_layout, Function_t *func)
 {
 	auto cfgp=ControlFlowGraph_t::factory(func);
 	auto &cfg=*cfgp;
-	
+
 	string esp_reg;
 	string word_dec;
 	if (FileIR_t::getArchitectureBitWidth() == 32)
@@ -2312,13 +2144,13 @@ bool PNTransformDriver::Canary_Rewrite(PNStackLayout *orig_layout, Function_t *f
 		//The number should be positive, but we want negative so 
 		//convert to negative
 		c.ret_offset = c.ret_offset * -1;
-	
+
 		if (verbose_log)
 			cerr << "c.canary_val = " << hex << c.canary_val << "	c.ret_offset = " << dec << c.ret_offset << "  c.esp_offset = " << c.esp_offset << "  floating canary offset = " << floating_canary_offset << " (max: " << layout->GetAlteredAllocSize()-layout->GetOriginalAllocSize()<< ")" << endl;
 
 		canaries.push_back(c);
 	}
-	
+
 	//bool stack_alloc = false;
 	int max = PNRegularExpressions::MAX_MATCHES;
 	regmatch_t *pmatch = new regmatch_t[max]; 
@@ -2373,24 +2205,20 @@ bool PNTransformDriver::Canary_Rewrite(PNStackLayout *orig_layout, Function_t *f
 
 			stringstream ss;
 			ss << hex << layout->GetAlteredAllocSize();
-		
+
 			disasm_str = "sub " + esp_reg +", 0x"+ss.str();
 
 			if (verbose_log)
 				cerr << "PNTransformDriver: New Instruction = " << disasm_str << endl;		
 
 			virp->registerAssembly(instr, disasm_str);
-/*
-  if(!instr->assemble(disasm_str))
-  return false;
-*/
 			//stack_alloc = true;
 
 			for (unsigned int i = 0; i < canaries.size(); ++i)
 			{
 				ss.str("");
 				ss<<"mov "<<word_dec<<" ["<<esp_reg<<"+0x"<<hex<<canaries[i].esp_offset
-				  <<"], 0x"<<hex<<canaries[i].canary_val;
+					<<"], 0x"<<hex<<canaries[i].canary_val;
 				instr = P1_insertAssemblyAfter(virp,instr,ss.str());
 				if(i==0)
 					instr->setComment("Canary Setup Entry: "+ss.str());
@@ -2426,7 +2254,7 @@ bool PNTransformDriver::Canary_Rewrite(PNStackLayout *orig_layout, Function_t *f
 		//for now don't do a canary check on calls in these situations. 
 		else if(layout->IsStaticStack() && regexec(&(pn_regex->regex_call), disasm_str.c_str(),5,pmatch,0)==0)
 		{
-		
+
 			if(verbose_log)
 				cerr<<"PNTransformDriver: Canary Rewrite: inserting call canary check"<<endl;
 
@@ -2457,8 +2285,6 @@ bool PNTransformDriver::Canary_Rewrite(PNStackLayout *orig_layout, Function_t *f
 
 
 	orig_layout->SetCanaries(canaries);
-//	orig_layout->SetBaseID(func->getBaseID());
-//	orig_layout->SetEntryID(func->getEntryPoint()->getBaseID());
 
 	EhUpdater_t eh_update(orig_virp, func, layout);
 	if(!eh_update.execute())
@@ -2503,7 +2329,7 @@ static Instruction_t* GetNextInstruction(Instruction_t *prev, Instruction_t* ins
 {
 	Instruction_t* ft=insn->getFallthrough();
 	Instruction_t* targ=insn->getTarget();
-	
+
 	/* if there's a fallthrough, but no targ, and the fallthrough is in the function */
 	if(ft &&  !targ && func->getInstructions().find(ft)!=func->getInstructions().end())
 		return ft;
@@ -2523,56 +2349,55 @@ static Instruction_t* GetNextInstruction(Instruction_t *prev, Instruction_t* ins
 //
 int PNTransformDriver::prologue_offset_to_actual_offset(ControlFlowGraph_t* cfg, Instruction_t *instr,int offset)
 {
-	Function_t* func=cfg->getFunction();
+	const auto func = cfg->getFunction();
 	assert(func);
-	BasicBlock_t* entry_block=cfg->getEntry();
+	const auto entry_block = cfg->getEntry();
 	if(!entry_block)
 		return offset;
 
 	/* find the instruction in the vector */
-	set<Instruction_t*>::iterator it= func->getInstructions().find(instr);
+	const auto it = find(ALLOF(entry_block->getInstructions()),instr);
 
 	/* if the instruction isn't in the entry block, give up now */
-	if( it == func->getInstructions().end())
+	if( it == entry_block->getInstructions().end())
 		return offset;
 
-	
+
 	Instruction_t* insn=*it, *prev=NULL;
-	for(int i=0;insn!=NULL && i<MAX_JUMPS_TO_FOLLOW; ++i, insn=GetNextInstruction(prev,insn, func))
+	for(int i=0; insn!=NULL && i<MAX_JUMPS_TO_FOLLOW; ++i, insn=GetNextInstruction(prev,insn, func))
 	{
 		assert(insn);
 		const auto dp=DecodedInstruction_t::factory(insn);
 		const auto &d=*dp;
-		string disasm_str=d.getDisassembly() /*CompleteInstr*/;
-		
-		//if(strstr(d.CompleteInstr, "push")!=NULL)
+		string disasm_str=d.getDisassembly();
+
 		if(d.getMnemonic()=="push")
 			return offset;
-	
+
 		int max = PNRegularExpressions::MAX_MATCHES;
-		//regmatch_t pmatch[max];
-		regmatch_t *pmatch=new regmatch_t[max]; // (max*sizeof(regmatch_t));
+		auto pmatch=make_unique<regmatch_t[]>(max); 
+
 
 		/* check for a stack alloc */
-				if(regexec(&(pn_regex->regex_stack_alloc), d.getDisassembly().c_str() /*CompleteInstr*/, 5, pmatch, 0)==0)
+		if(regexec(&(pn_regex->regex_stack_alloc), d.getDisassembly().c_str(), 5, pmatch.get(), 0)==0)
 		{
 
-						if (pmatch[1].rm_so >= 0 && pmatch[1].rm_eo >= 0)
-						{
+			if (pmatch[1].rm_so >= 0 && pmatch[1].rm_eo >= 0)
+			{
 				string matched="";
-								int mlen = pmatch[1].rm_eo - pmatch[1].rm_so;
-								matched = disasm_str.substr(pmatch[1].rm_so,mlen);
-								//extract K
-								unsigned int ssize;
-								if(str2uint(ssize, matched.c_str()) != STR2_SUCCESS)
-								{
+				int mlen = pmatch[1].rm_eo - pmatch[1].rm_so;
+				matched = disasm_str.substr(pmatch[1].rm_so,mlen);
+				//extract K
+				unsigned int ssize;
+				if(str2uint(ssize, matched.c_str()) != STR2_SUCCESS)
+				{
 					return offset;
-								}
+				}
 				// found! 
 				// mov ... [rsp+offset] ...
 				// sub rsp, ssize
 				// note: offset is negative
-			
+
 				// sanity check that the allocation iss bigger than the neg offset
 				assert((unsigned)ssize==(unsigned)ssize);
 				if(-offset>(int)ssize)
@@ -2581,13 +2406,13 @@ int PNTransformDriver::prologue_offset_to_actual_offset(ControlFlowGraph_t* cfg,
 				// success
 				return offset+ssize;
 
-						}
+			}
 			return offset;
 
 		}
 		// else, check next instruction 
 
-		
+
 	}
 
 	return offset;
@@ -2614,7 +2439,7 @@ inline bool PNTransformDriver::Instruction_Rewrite(PNStackLayout *layout, Instru
 	const auto disasmp = DecodedInstruction_t::factory(instr);
 	const auto &disasm =*disasmp;
 	disasm_str = disasm.getDisassembly() /*CompleteInstr*/;
-	
+
 	//the disassmebly of lea has extra tokens not accepted by nasm, remove those tokens
 	if(regexec(&(pn_regex->regex_lea_hack), disasm_str.c_str(), max, pmatch, 0) == 0)
 	{
@@ -2636,7 +2461,7 @@ inline bool PNTransformDriver::Instruction_Rewrite(PNStackLayout *layout, Instru
 
 		matched = "";
 	}
-		
+
 
 	if(instr->getFunction() && instr->getFunction()->getUseFramePointer() && regexec(&(pn_regex->regex_add_rbp), disasm_str.c_str(), 5, pmatch, 0) == 0)
 	{
@@ -2658,7 +2483,7 @@ inline bool PNTransformDriver::Instruction_Rewrite(PNStackLayout *layout, Instru
 			cerr << "PNTransformDriver: Convrting to "<<lea_string.str()<<endl;
 
 		virp->registerAssembly(instr,lea_string.str());
-		
+
 	}
 	else if(regexec(&(pn_regex->regex_stack_alloc), disasm_str.c_str(), 5, pmatch, 0)==0)
 	{
@@ -2713,35 +2538,18 @@ inline bool PNTransformDriver::Instruction_Rewrite(PNStackLayout *layout, Instru
 
 		stringstream ss;
 		ss << hex << layout->GetAlteredAllocSize();
-		
+
 		disasm_str = "sub "+esp_reg+", 0x"+ss.str();
 
 		if(verbose_log)
 			cerr<<"PNTransformDriver: New Instruction = "<<disasm_str<<endl;		
 
 		virp->registerAssembly(instr,disasm_str);
-
-/*
-  if(!instr->assemble(disasm_str))
-  return false;
-*/
-
-		//stack_alloc = true;
 	} 
 	else if(regexec(&(pn_regex->regex_and_esp), disasm_str.c_str(), max, pmatch, 0)==0)
 	{
 		if(verbose_log)
 			cerr << "PNTransformDriver: and_esp pattern matched, ignoring"<<endl;
-/*
-  cerr<<"PNTransformDriver: Transforming AND ESP instruction"<<endl;
-
-  disasm_str = "nop";
-
-  cerr<<"PNTransformDriver: New Instruction = "<<disasm_str<<endl;
-
-  if(!instr->assemble(disasm_str))
-  return false;
-*/
 	}
 	else if(regexec(&(pn_regex->regex_esp_scaled_nodisp), disasm_str.c_str(), max, pmatch, 0)==0) 
 	{
@@ -2764,7 +2572,7 @@ inline bool PNTransformDriver::Instruction_Rewrite(PNStackLayout *layout, Instru
 		{
 			if(verbose_log)
 				cerr<<"PNTransformDriver: Displacement of [esp+reg*scale] is Zero, Ignoring Transformation"<<endl;
-			
+
 			return true;
 		}
 
@@ -2777,17 +2585,11 @@ inline bool PNTransformDriver::Instruction_Rewrite(PNStackLayout *layout, Instru
 		assert(mlen==1);
 
 		disasm_str.replace(pmatch[1].rm_so,mlen,matched);
-		
+
 		if(verbose_log)
 			cerr<<"PNTransformDriver: New Instruction = "<<disasm_str<<endl;
 
 		virp->registerAssembly(instr,disasm_str);
-
-/*
-  if(!instr->assemble(disasm_str.c_str()))
-  return false;		
-*/
-		
 	}
 	else if(regexec(&(pn_regex->regex_esp_only), disasm_str.c_str(), max, pmatch, 0)==0) 
 	{
@@ -2810,7 +2612,7 @@ inline bool PNTransformDriver::Instruction_Rewrite(PNStackLayout *layout, Instru
 		{
 			if(verbose_log)
 				cerr<<"PNTransformDriver: Displacement of [esp] is Zero, Ignoring Transformation"<<endl;
-			
+
 			return true;
 		}
 
@@ -2820,17 +2622,12 @@ inline bool PNTransformDriver::Instruction_Rewrite(PNStackLayout *layout, Instru
 		matched = esp_reg+"+0x"+ss.str();
 		int mlen = pmatch[1].rm_eo - pmatch[1].rm_so;	
 		disasm_str.replace(pmatch[1].rm_so,mlen,matched);
-		
+
 		if(verbose_log)
 			cerr<<"PNTransformDriver: New Instruction = "<<disasm_str<<endl;
 
 		virp->registerAssembly(instr,disasm_str);
 
-/*
-  if(!instr->assemble(disasm_str.c_str()))
-  return false;		
-*/
-		
 	}
 #if 1
 	else if(regexec(&(pn_regex->regex_esp_direct_negoffset), disasm_str.c_str(), 5, pmatch, 0)==0)
@@ -2856,7 +2653,7 @@ inline bool PNTransformDriver::Instruction_Rewrite(PNStackLayout *layout, Instru
 		{	
 			if(verbose_log)
 				cerr<<"PNTransformDriver: ignoring, not in prologue "<<endl;
-			
+
 		}
 		else
 		{
@@ -2871,22 +2668,22 @@ inline bool PNTransformDriver::Instruction_Rewrite(PNStackLayout *layout, Instru
 
 			// sanity 
 			assert(new_offset<0);
-			
+
 			stringstream ss;
 			ss<<hex<<(- new_offset); 	// neg sign already in string
-	
+
 			matched = "0x"+ss.str();
-			
+
 			disasm_str.replace(pmatch[1].rm_so,mlen,matched);
-			
+
 			if(verbose_log)
 				cerr<<"PNTransformDriver: New Instruction = "<<disasm_str<<endl;
-	
+
 			virp->registerAssembly(instr,disasm_str);
 		}
 	}
 #endif
-//TODO: the regular expression order does matter, scaled must come first, change the regex so this doesn't matter  
+	//TODO: the regular expression order does matter, scaled must come first, change the regex so this doesn't matter  
 	else if(regexec(&(pn_regex->regex_esp_scaled), disasm_str.c_str(), 5, pmatch, 0)==0 ||
 			regexec(&(pn_regex->regex_esp_direct), disasm_str.c_str(), 5, pmatch, 0)==0)
 	{
@@ -2901,14 +2698,14 @@ inline bool PNTransformDriver::Instruction_Rewrite(PNStackLayout *layout, Instru
 
 		//TODO: I don't think this can happen but just in case
 		assert(offset >= 0);
-	
-		
+
+
 		// an ESP+<scale>+<const> that points at 
 		// the saved reg area isn't likely realy indexing the saved regs. assume it's in the 
 		// local var area instead.
 		int new_offset = 0; 
 		if((int)offset==(int)layout->GetOriginalAllocSize() && 
-			regexec(&(pn_regex->regex_esp_scaled), disasm_str.c_str(), 5, pmatch2, 0)==0)
+				regexec(&(pn_regex->regex_esp_scaled), disasm_str.c_str(), 5, pmatch2, 0)==0)
 		{
 			if(verbose_log)
 				cerr<<"JDH: PNTransformDriver: found esp+scale+const pointing at saved regs."<<endl;	
@@ -2916,23 +2713,19 @@ inline bool PNTransformDriver::Instruction_Rewrite(PNStackLayout *layout, Instru
 		}
 		else
 			new_offset=layout->GetNewOffsetESP(offset);
-		
+
 		stringstream ss;
 		ss<<hex<<new_offset;
 
 		matched = "0x"+ss.str();
-		
+
 		disasm_str.replace(pmatch[1].rm_so,mlen,matched);
-		
+
 		if(verbose_log)
 			cerr<<"PNTransformDriver: New Instruction = "<<disasm_str<<endl;
 
 		virp->registerAssembly(instr,disasm_str);
 
-/*
-  if(!instr->assemble(disasm_str.c_str()))
-  return false;
-*/
 	}
 	//TODO: the regular expression order does matter, scaled must come first, change the regex so this doesn't matter
 	//for lea esp, [ebp-<const>] it is assumed the <const> will not be in the stack frame, so it should be ignored.
@@ -2966,7 +2759,7 @@ inline bool PNTransformDriver::Instruction_Rewrite(PNStackLayout *layout, Instru
 		ss<<hex<<new_offset;
 
 		matched = "0x"+ss.str();
-		
+
 		disasm_str.replace(pmatch[1].rm_so,mlen,matched);
 
 		if(verbose_log)
@@ -2975,11 +2768,7 @@ inline bool PNTransformDriver::Instruction_Rewrite(PNStackLayout *layout, Instru
 
 		virp->registerAssembly(instr,disasm_str);
 
-/*
-  if(!instr->assemble(disasm_str.c_str()))
-  return false;
-*/
-		
+
 	}
 	//if we get an instruction where ebp is the index, transform it using the
 	//offset as the lookup (the second pattern matched), however, it is assumed
@@ -3016,18 +2805,13 @@ inline bool PNTransformDriver::Instruction_Rewrite(PNStackLayout *layout, Instru
 		ss<<hex<<new_offset;
 
 		matched = "0x"+ss.str();
-		
+
 		disasm_str.replace(pmatch[2].rm_so,mlen,matched);
 
 		if(verbose_log)
 			cerr<<"PNTransformDriver: New Instruction = "<<disasm_str<<endl;
 
 		virp->registerAssembly(instr,disasm_str);
-
-/*
-  if(!instr->assemble(disasm_str.c_str()))
-  return false;
-*/
 	}
 	else if(regexec(&(pn_regex->regex_stack_dealloc), disasm_str.c_str(), 5, pmatch, 0)==0)
 	{
@@ -3059,16 +2843,12 @@ inline bool PNTransformDriver::Instruction_Rewrite(PNStackLayout *layout, Instru
 		ss << hex <<layout->GetAlteredAllocSize();
 
 		disasm_str = "add "+esp_reg+", 0x"+ss.str();
-		
+
 
 		if(verbose_log)
 			cerr<<"PNTransformDriver: New Instruction = "<<disasm_str<<endl;
 
 		virp->registerAssembly(instr,disasm_str);
-/*
-  if (!instr->assemble(disasm_str)) 
-  return false;
-*/
 	}
 	else
 	{
@@ -3076,7 +2856,7 @@ inline bool PNTransformDriver::Instruction_Rewrite(PNStackLayout *layout, Instru
 		{
 			cerr<<"PNTransformDriver: No Pattern Match";
 			if(strstr(disasm_str.c_str(), "rsp")!=NULL || 
-			   strstr(disasm_str.c_str(), "esp")!=NULL)
+					strstr(disasm_str.c_str(), "esp")!=NULL)
 				cerr<<"BUT CAUTION *******************  esp/rsp found in instruction.";
 			cerr<<endl;
 		}
@@ -3090,78 +2870,9 @@ inline bool PNTransformDriver::Instruction_Rewrite(PNStackLayout *layout, Instru
 //void PNTransformDriver::undo(map<Instruction_t*, Instruction_t*> undo_list, Function_t *func)
 void PNTransformDriver::undo(Function_t *func)
 {
-	string func_name = func->getName();
-
-	//rollback any changes
-	cerr<<"PNTransformDriver: Undo Transform: "<<undo_list[func].size()<<" instructions to rollback for function "<<func_name<<endl;
-	for(
-		map<Instruction_t*, Instruction_t*>::const_iterator mit=undo_list[func].begin();
-		mit != undo_list[func].end();
-		++mit)
-	{
-#if 1
-		assert(0); // functionality removed.
-#else
-		Instruction_t* alt = mit->first;
-		Instruction_t* orig = mit->second;
-  
-		P1_copyInstruction(orig,alt);
-		
-		orig_virp->unregisterAssembly(alt);
-	
-		//TODO: apparently there is a issue with this delete.
-		//When using the padding/shuffle transformation PN terminates
-		//for some reason with no segfault. Removing this delete
-		//solves the issue. Using the canary transformation, I haven't
-		//observed the same issue however there are fewer undos when
-		//using the canary transform. 
-//	delete orig;
-#endif
-	}
-
-	for(set<Instruction_t*>::const_iterator it=inserted_instr[func].begin();
-		it != inserted_instr[func].end();
-		++it
-		)
-	{
-#if 1
-		assert(0); // functionality removed.
-#else
-		orig_virp->unregisterAssembly(*it);
-		orig_virp->getInstructions().erase(*it);
-		func->getInstructions().erase(*it);
-		delete *it;
-#endif
-	}
-
-	for(set<AddressID_t*>::const_iterator it=inserted_addr[func].begin();
-		it != inserted_addr[func].end();
-		++it
-		)
-	{
-#if 1
-		assert(0); // functionality removed.
-#else
-		orig_virp->getAddresses().erase(*it);
-		delete *it;
-#endif
-	}
-	//reset_undo(func->getName());
-
-	undo_list.erase(func);
-	inserted_instr.erase(func);
-	inserted_addr.erase(func);
-	//undo_list.clear();
+	assert(undo_list.size() == 0); // functionality removed.
 }
 
-/*
-  void PNTransformDriver::reset_undo(string func)
-  {
-  undo_list.erase(func);
-  inserted_instr.erase(func);
-  inserted_addr.erase(func);
-  }
-*/
 
 
 bool PNTransformDriver::WriteStackIRToDB()
@@ -3193,10 +2904,10 @@ bool PNTransformDriver::WriteStackIRToDB()
 			for(unsigned int j = 0; j < mem_objects.size(); j++)
 			{
 				IRDB_SDK::DatabaseID_t new_id = irdb_manager.InsertStackObject(
-					layouts[laynum]->getFunctionName(),
-					mem_objects[j]->getOffset(),
-					mem_objects[j]->getSize(),
-					PNIrdbManager::IRS_PEASOUP);
+						layouts[laynum]->getFunctionName(),
+						mem_objects[j]->getOffset(),
+						mem_objects[j]->getSize(),
+						PNIrdbManager::IRS_PEASOUP);
 
 				// DEBUG
 				cerr<< "\tOffset = " << mem_objects[j]->getOffset() << " Size = "<<mem_objects[j]->getSize() << endl;
diff --git a/PNTransformDriver.hpp b/PNTransformDriver.hpp
index c14019824e9305a3501ce9ca50bd420949e86303..2eeaf44937e1fbf8b10589fa57fd3043eac57314 100644
--- a/PNTransformDriver.hpp
+++ b/PNTransformDriver.hpp
@@ -77,7 +77,7 @@ class PNTransformDriver
 	bool do_shared_object_protection;
   
     	std::vector< std::vector<PNStackLayoutInference*> > transform_hierarchy;
-    	PNRegularExpressions *pn_regex;
+    	unique_ptr<PNRegularExpressions> pn_regex;
     	std::set<std::string> blacklist;
 	std::set<IRDB_SDK::Function_t*> sanitized;
     	std::set<std::string> only_validate_list;
diff --git a/SConstruct b/SConstruct
index 74143aaa4455ca885111b55d02300922b437a0e8..2bc901f4162d009c74d7a3e5963a9684ee76650e 100644
--- a/SConstruct
+++ b/SConstruct
@@ -43,7 +43,7 @@ env.Replace(debug=ARGUMENTS.get("debug",0))   # build in debug mode?
 #
 # Required:  need these flag to appropriately include/link IRDB files.
 #
-env.Append(CXXFLAGS=" -std=c++11 ")	# enable c++11
+env.Append(CXXFLAGS=" -std=c++17 ")	# enable c++17
 env.Append(LINKFLAGS=" -Wl,-unresolved-symbols=ignore-in-shared-libs ") # irdb libs may have symbols that resolve OK at runtime, but not linktime.