diff --git a/include/zipr_dollop_man.h b/include/zipr_dollop_man.h
index 42c4cfdb0b2a084ac6a6d90081b5341325f7ea2f..25115ad4e0e87ec8b2508888bd5bc17637edd562 100644
--- a/include/zipr_dollop_man.h
+++ b/include/zipr_dollop_man.h
@@ -37,21 +37,29 @@ class ZiprDollopManager_t {
 	public:
 		ZiprDollopManager_t() {}
 		void AddDollop(Dollop_t *dollop);
-		Zipr_SDK::Dollop_t *GetContainingDollop(libIRDB::Instruction_t *insn) {
-			try {
-				return m_insn_to_dollop.at(insn);
-			} catch (const std::out_of_range &oor) {
-				return NULL;
-			}
+		Zipr_SDK::Dollop_t *AddNewDollop(libIRDB::Instruction_t *start);
+		Zipr_SDK::Dollop_t *GetContainingDollop(libIRDB::Instruction_t *insn);
+		size_t Size() {
+			return m_dollops.size();
 		}
-
-		static Zipr_SDK::Dollop_t *CreateDollop(libIRDB::Instruction_t *start) {
-			return new Zipr_SDK::Dollop_t(start);
+		void AddDollopPatch(Zipr_SDK::DollopPatch_t *new_patch) {
+			m_patches_to_dollops[new_patch->Target()].push_back(new_patch);
+		}
+		std::list<DollopPatch_t*> PatchesToDollop(Dollop_t *target) {
+			/*
+			 * FIXME: This will throw an exception if target is
+			 * not already in the list. [] fixes that but allocates.
+			 * Decide what to do.
+			 */
+			return m_patches_to_dollops.at(target);
 		}
+		void PrintDollopPatches(const std::ostream &);
 
 	private:
 		std::map<libIRDB::Instruction_t*,Dollop_t*> m_insn_to_dollop;
 		std::list<Dollop_t*> m_dollops;
+		std::list<DollopPatch_t*> m_patches;
+		std::map<Dollop_t*, std::list<DollopPatch_t*>> m_patches_to_dollops;
 };
 
 #endif
diff --git a/src/dollop.cpp b/src/dollop.cpp
index f89235cae5eb82f5f78f15d81a9eff4a6e7d7dfa..bc24820cc2e060fec89ff869066fa6bce5bcba63 100644
--- a/src/dollop.cpp
+++ b/src/dollop.cpp
@@ -1,12 +1,22 @@
 #include <zipr_all.h>
+#include <iostream>
 
 namespace Zipr_SDK {
 	using namespace libIRDB;
 	using namespace zipr;
 	Dollop_t::Dollop_t(Instruction_t *start)
 	{
+		Instruction_t *loop = NULL;
 		m_start = start;
 		m_size = CalculateWorstCaseSize();
+
+		if (start == NULL)
+			return;
+
+		loop = start;
+		do {
+			push_back(new DollopEntry_t(loop));
+		} while (NULL != (loop = loop->GetFallthrough()));
 	}
 
 	size_t Dollop_t::CalculateWorstCaseSize()
@@ -38,6 +48,89 @@ namespace Zipr_SDK {
 	}
 
 	Dollop_t *Dollop_t::Split(libIRDB::Instruction_t *split_point) {
-		return new Dollop_t(NULL);
+		/*
+		 * 1. Find the matching dollop entry.
+		 */
+		DollopEntry_t query(split_point);
+		std::list<DollopEntry_t *>::iterator de_split_point, de_it;
+		Dollop_t *new_dollop = NULL;
+
+		de_split_point = find_if(begin(),end(),
+			[&query](const DollopEntry_t *p) {
+				std::cout << "Checking "
+				          << std::hex << query.Instruction() << " ?= "
+									<< std::hex << p->Instruction() << "." << std::endl;
+				return query == *p;
+			});
+		/*
+		 * No matching split point. Just return NULL.
+		 */
+		if (de_split_point == end())
+			return NULL;
+
+		new_dollop = new Dollop_t();
+		/*
+		 * 2. Remove them from this one
+		 */
+		de_it = de_split_point;
+		while (de_it != end()) {
+		/*
+		 * 3. Move them to a new one
+		 */
+			DollopEntry_t *to_remove = *de_it, *to_add = NULL;
+			std::list<DollopEntry_t*>::iterator to_remove_it = de_it;
+
+			de_it++;
+
+			new_dollop->push_back(to_add=new DollopEntry_t(to_remove->Instruction()));
+			erase(to_remove_it);
+			delete to_remove;
+		}
+		/*
+		 * 4. Return the new one
+		 */
+		return new_dollop;
+	}
+
+	DollopEntry_t::DollopEntry_t(libIRDB::Instruction_t *insn) {
+		/*
+		 * NB: This does not link if the insn has a target.
+		 */
+		m_instruction = insn;
+		m_target_dollop = NULL;
+	}
+
+	bool DollopEntry_t::operator==(const DollopEntry_t &comp) {
+		std::cout << "operator==s being invoked "
+		          << "(" << std::hex << m_instruction
+		          << ", " << std::hex << comp.m_instruction
+							<< ") "
+		          << "(" << std::hex << m_target_dollop
+		          << ", " << std::hex << comp.m_target_dollop
+							<< ") "
+							<< std::endl;
+		return comp.m_instruction == m_instruction &&
+		       comp.m_target_dollop == m_target_dollop;
+	}
+	bool DollopEntry_t::operator!=(const DollopEntry_t &comp) {
+		return !operator==(comp);
+	}
+	Dollop_t *Dollop_t::CreateNewDollop(libIRDB::Instruction_t *start) {
+		return new Zipr_SDK::Dollop_t(start);
+	}
+	std::ostream &operator<<(std::ostream &out, const Dollop_t &d) {
+		std::list<DollopEntry_t*>::const_iterator it, it_end;
+
+		for (it = d.begin(), it_end = d.end();
+		     it != it_end;
+				 it++) {
+			out << std::hex << (*it)->Instruction() << ",";
+		}
+		return out;
+	}
+
+	std::ostream &operator<<(std::ostream &out, const DollopPatch_t &p) {
+		out << std::hex << &p << ":" << std::hex << p.Target();
+		return out;
 	}
 }
diff --git a/src/zipr_dollop_man.cpp b/src/zipr_dollop_man.cpp
index c08c9ec1e7ff5ecafaa981773a360c2d6495deca..68de6a1ea33f4b3ba60e3b1af80f1e384625626a 100644
--- a/src/zipr_dollop_man.cpp
+++ b/src/zipr_dollop_man.cpp
@@ -1,9 +1,48 @@
 #include <zipr_all.h>
+#include <iostream>
 
 using namespace zipr;
 using namespace std;
 using namespace Zipr_SDK;
+using namespace libIRDB;
+
+Dollop_t *ZiprDollopManager_t::AddNewDollop(Instruction_t *start) {
+	Dollop_t *new_dollop = Dollop_t::CreateNewDollop(start);
+	AddDollop(new_dollop);
+	return new_dollop;
+}
+
+void ZiprDollopManager_t::PrintDollopPatches(const ostream &out) {
+	std::list<DollopPatch_t*>::const_iterator patch_it, patch_it_end;
+
+	for (patch_it = m_patches.begin(), patch_it_end = m_patches.end();
+	     patch_it != patch_it_end;
+			 patch_it++) {
+		cout << *(*patch_it) << endl;
+	}
+}
+
+Dollop_t *ZiprDollopManager_t::GetContainingDollop(libIRDB::Instruction_t *insn) {
+	try {
+		return m_insn_to_dollop.at(insn);
+	} catch (const std::out_of_range &oor) {
+		return NULL;
+	}
+	return NULL;
+}
 
 void ZiprDollopManager_t::AddDollop(Dollop_t *dollop) {
-	return;
+	/*
+	 * Populate the instruction-to-dollop map.
+	 */
+	list<DollopEntry_t*>::const_iterator it, it_end;
+	for (it = dollop->begin(), it_end = dollop->end();
+	     it != it_end;
+			 it++) {
+		m_insn_to_dollop[(*it)->Instruction()] = dollop;
+	}
+	/*
+	 * Push the actual dollop onto the list of dollops.
+	 */
+	m_dollops.push_back(dollop);
 }
diff --git a/test/SConscript b/test/SConscript
index df5eaf4769e2a9a82443c2b13347235782cd64ad..78548f0c176ba50a8bbebfa1b2d4df1bc4cda442 100644
--- a/test/SConscript
+++ b/test/SConscript
@@ -56,7 +56,7 @@ libpath='''
 	'''
 
 myenv.Append(CCFLAGS=" -Wall ")
-myenv.Append(CXXFLAGS=" -g -O0 ")
+myenv.Append(CXXFLAGS=" -std=c++11 -g -O0 ")
 myenv.Append(LINKFLAGS=" -Wl,-E ")	# export all symbols
 
 
diff --git a/test/ZiprDollop.cpp b/test/ZiprDollop.cpp
index 85692e9f7a37b08cacbd39a05a5fdb840f0af8e7..8605e7c03e88751a21500fb1cd355d0b69c4e8f8 100644
--- a/test/ZiprDollop.cpp
+++ b/test/ZiprDollop.cpp
@@ -23,6 +23,7 @@
 
 using namespace zipr;
 using namespace std;
+using namespace Zipr_SDK;
 
 #define INVOKE(a) \
 bool __ ## a ## _result = false; \
@@ -37,10 +38,189 @@ else \
 printf(" fail\n"); \
 }
 
-int main(int argc, char *argv[])
-{
+bool TestGetContainingDollopNoFallthrough() {
+	ZiprDollopManager_t dollop_man;
+	libIRDB::Instruction_t *insn_a = new libIRDB::Instruction_t();
+	libIRDB::Instruction_t *insn_b = new libIRDB::Instruction_t();
+	Dollop_t *dollop_a = NULL;
+
+	dollop_a = Dollop_t::CreateNewDollop(insn_a);
+	dollop_man.AddDollop(dollop_a);
+
+	return dollop_man.GetContainingDollop(insn_b) == NULL &&
+	       dollop_man.GetContainingDollop(insn_a) == dollop_a;
+}
+
+bool TestGetContainingDollopFallthrough(void) {
+	ZiprDollopManager_t dollop_man;
+	libIRDB::Instruction_t *insn_a = new libIRDB::Instruction_t();
+	libIRDB::Instruction_t *insn_b = new libIRDB::Instruction_t();
+	Dollop_t *dollop_a = NULL;
+
+	insn_a->SetFallthrough(insn_b);
+
+	dollop_a = Dollop_t::CreateNewDollop(insn_a);
+	dollop_man.AddDollop(dollop_a);
+
+	return dollop_man.GetContainingDollop(insn_b) == dollop_a &&
+	       dollop_man.GetContainingDollop(insn_a) == dollop_a;
+}
+
+bool TestGetContainingDollop(void) {
+	ZiprDollopManager_t dollop_man;
+	libIRDB::Instruction_t *insn_a = new libIRDB::Instruction_t();
+	libIRDB::Instruction_t *insn_b = new libIRDB::Instruction_t();
+	Dollop_t *dollop_a = Dollop_t::CreateNewDollop(insn_a);
+	Dollop_t *dollop_b = Dollop_t::CreateNewDollop(insn_b);
+	dollop_man.AddDollop(dollop_a);
+	dollop_man.AddDollop(dollop_b);
+	return dollop_man.GetContainingDollop(insn_a) == dollop_a &&
+	       dollop_man.GetContainingDollop(insn_b) == dollop_b;
+}
+
+bool TestAddDollopEntry(void) {
 	ZiprDollopManager_t dollop_man;
 	libIRDB::Instruction_t *insn = new libIRDB::Instruction_t();
-	dollop_man.AddDollop(ZiprDollopManager_t::CreateDollop(insn));
+	dollop_man.AddDollop(Dollop_t::CreateNewDollop(insn));
+	return 1 == dollop_man.Size();
+}
+
+bool TestDollopPatch(void) {
+	Dollop_t *a = NULL;
+	DollopPatch_t patch;
+
+	libIRDB::Instruction_t *insn_a = new libIRDB::Instruction_t();
+	a = Dollop_t::CreateNewDollop(insn_a);
+
+	patch.Target(a);
+
+	return patch.Target() == a;
+}
+
+bool TestDollopPatchDollopManager(void) {
+	ZiprDollopManager_t dollop_man;
+	DollopPatch_t patch_a, patch_b;
+	Dollop_t *dollop_a, *dollop_b;
+
+	libIRDB::Instruction_t *insn_a = new libIRDB::Instruction_t();
+	libIRDB::Instruction_t *insn_b = new libIRDB::Instruction_t();
+
+	dollop_a = Dollop_t::CreateNewDollop(insn_a);
+	dollop_b = Dollop_t::CreateNewDollop(insn_b);
+
+	patch_a.Target(dollop_b);
+	patch_b.Target(dollop_a);
+
+	dollop_man.AddDollopPatch(&patch_a);
+	dollop_man.AddDollopPatch(&patch_b);
+
+	dollop_man.PrintDollopPatches(cout);
+	return true;
+}
+
+bool TestDollopPatchMapDollopManager(void) {
+	bool success = true;
+	ZiprDollopManager_t dollop_man;
+	DollopPatch_t patch_a, patch_aa, patch_c;
+	Dollop_t *dollop_a, *dollop_c;
+	std::list<DollopPatch_t *>::const_iterator patches_it, patches_it_end;
+
+	libIRDB::Instruction_t *insn_a = new libIRDB::Instruction_t();
+	libIRDB::Instruction_t *insn_c = new libIRDB::Instruction_t();
+
+	dollop_a = Dollop_t::CreateNewDollop(insn_a);
+	dollop_c = Dollop_t::CreateNewDollop(insn_c);
+
+	patch_a.Target(dollop_a);
+	patch_aa.Target(dollop_a);
+	patch_c.Target(dollop_c);
+
+	dollop_man.AddDollop(dollop_a);
+	dollop_man.AddDollop(dollop_c);
+
+	dollop_man.AddDollopPatch(&patch_a);
+	dollop_man.AddDollopPatch(&patch_aa);
+	dollop_man.AddDollopPatch(&patch_c);
+
+	cout << "&dollop_a: " << std::hex << dollop_a << endl;
+	cout << "&dollop_c: " << std::hex << dollop_c << endl;
+
+	std::list<DollopPatch_t *> patches = dollop_man.PatchesToDollop(dollop_a);
+	for (patches_it = patches.begin(), patches_it_end = patches.end();
+	     patches_it != patches.end();
+			 patches_it++) {
+		success &= ((*patches_it)->Target()) == dollop_a;
+		cout << *(*patches_it) << endl;
+	}
+	patches = dollop_man.PatchesToDollop(dollop_c);
+	for (patches_it = patches.begin(), patches_it_end = patches.end();
+	     patches_it != patches.end();
+			 patches_it++) {
+		success &= ((*patches_it)->Target()) == dollop_c;
+		cout << *(*patches_it) << endl;
+	}
+	return success;
+}
+
+bool TestDollopSplit(void) {
+	Dollop_t *a, *b;
+
+	libIRDB::Instruction_t *insn_a = new libIRDB::Instruction_t();
+	libIRDB::Instruction_t *insn_b = new libIRDB::Instruction_t();
+	libIRDB::Instruction_t *insn_c = new libIRDB::Instruction_t();
+	libIRDB::Instruction_t *insn_d = new libIRDB::Instruction_t();
+	libIRDB::Instruction_t *insn_e = new libIRDB::Instruction_t();
+
+	insn_a->SetFallthrough(insn_b);
+	insn_b->SetFallthrough(insn_c);
+	insn_c->SetFallthrough(insn_d);
+	insn_d->SetFallthrough(insn_e);
+
+	a = Dollop_t::CreateNewDollop(insn_a);
+
+	cout << "Dollop A: " << endl;
+	cout << *a << endl;
+
+	b = a->Split(insn_b);
+
+	cout << "Dollop A: " << endl;
+	cout << *a << endl;
+	cout << "Dollop B: " << endl;
+	cout << *b << endl;
+
+	return a->GetDollopEntryCount() == 1 && b->GetDollopEntryCount() == 4;
+}
+
+bool TestDollopEntryEquals(void) {
+	DollopEntry_t *a, *b, *c, *d;
+
+	libIRDB::Instruction_t *insn_a = new libIRDB::Instruction_t();
+	libIRDB::Instruction_t *insn_b = new libIRDB::Instruction_t();
+
+	a = new DollopEntry_t(insn_a);
+	b = new DollopEntry_t(insn_b);
+	c = new DollopEntry_t(insn_a);
+	d = new DollopEntry_t(insn_a);
+	d->SetTargetDollop((Dollop_t*)0x5000);
+
+	return *a != *b &&
+	       *b != *c &&
+	       *a == *a &&
+				 *b == *b &&
+				 *a == *c &&
+				 *a != *d;
+}
+
+int main(int argc, char *argv[])
+{
+	INVOKE(TestAddDollopEntry);
+	INVOKE(TestDollopEntryEquals);
+	INVOKE(TestDollopSplit);
+	INVOKE(TestGetContainingDollop);
+	INVOKE(TestGetContainingDollopFallthrough);
+	INVOKE(TestGetContainingDollopNoFallthrough);
+	INVOKE(TestDollopPatch);
+	INVOKE(TestDollopPatchDollopManager);
+	INVOKE(TestDollopPatchMapDollopManager);
 	return 0;
 }