diff --git a/.gitattributes b/.gitattributes
index 12270cdf7bf66ae01b9f0115ff01894f9965707f..edb8e96f833259d6a3c636f6e0413047cb20d551 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -14,13 +14,16 @@ include/zipr_impl.h -text
 include/zipr_mem_space.h -text
 include/zipr_optimizations.h -text
 include/zipr_stats.h -text
+include/zipr_utils.h -text
 /install-sh -text
 src/Makefile.in -text
 src/SConscript -text
 src/SConstruct -text
+src/dollop.cpp -text
 src/main.cpp -text
 src/memory_space.cpp -text
 src/plugin_man.cpp -text
+src/utils.cpp -text
 src/zipr.cpp -text
 src/zipr_options.cpp -text
 src/zipr_stats.cpp -text
diff --git a/include/plugin_man.h b/include/plugin_man.h
index 658a4257dd364a9216cc2406af7b0fb08bb6f3fd..c98faf428c3b2762c28402d1f6b8b5c8284cbe22 100644
--- a/include/plugin_man.h
+++ b/include/plugin_man.h
@@ -42,6 +42,7 @@ class ZiprPluginManager_t : public ZiprPluginInterface_t
 
 		virtual bool DoesPluginPlop(libIRDB::Instruction_t*,DLFunctionHandle_t&);
 
+		virtual bool DoesPluginPlace(const RangeAddress_t &, const Dollop_t &, Range_t &, DLFunctionHandle_t &);
 	private:
 
 		void open_plugins
diff --git a/include/unresolved.h b/include/unresolved.h
index a7e89d381867e1f6fd302e2e487a225cdf7130b7..312ff29dd7ef064bf83ad458ad69f1433e9c0032 100644
--- a/include/unresolved.h
+++ b/include/unresolved.h
@@ -125,7 +125,7 @@ class Patch_t
 	public:
 		Patch_t(RangeAddress_t p_from_addr, UnresolvedType_t p_t) : from_addr(p_from_addr), type(p_t) {}
 
-		RangeAddress_t GetAddress() { return from_addr; }
+		RangeAddress_t GetAddress() const { return from_addr; }
 		UnresolvedType_t GetType() { return type; }
 
 	private:
diff --git a/include/zipr_all.h b/include/zipr_all.h
index d705355f4d03c94a02b38cf8198e0dbc3fea3ab3..34cec6c0a0381104c5526713ac6c85c7cbce0f4d 100644
--- a/include/zipr_all.h
+++ b/include/zipr_all.h
@@ -52,6 +52,7 @@ using namespace Zipr_SDK;
 #include <unresolved.h>
 #include <zipr_mem_space.h>
 #include <plugin_man.h>
+#include <zipr_utils.h>
 #include <zipr_impl.h>
 #include <zipr_optimizations.h>
 #include <zipr_stats.h>
diff --git a/include/zipr_mem_space.h b/include/zipr_mem_space.h
index a99c128ee927eb96951e7cc65151d6bd9491c63e..18a782761f55e513535f21e7bcbfc034aeba857c 100644
--- a/include/zipr_mem_space.h
+++ b/include/zipr_mem_space.h
@@ -46,6 +46,7 @@ class ZiprMemorySpace_t : public MemorySpace_t
 		void MergeFreeRange(RangeAddress_t addr);
 		RangeSet_t::iterator FindFreeRange(RangeAddress_t addr);
 		Range_t GetFreeRange(int size);
+		Range_t GetNearbyFreeRange(const RangeAddress_t hint);
 		void AddFreeRange(Range_t newRange);
 		void RemoveFreeRange(Range_t newRange);
 
diff --git a/include/zipr_utils.h b/include/zipr_utils.h
new file mode 100644
index 0000000000000000000000000000000000000000..4209ad69b91a8e2d8a14d565beafae18b4fd3e71
--- /dev/null
+++ b/include/zipr_utils.h
@@ -0,0 +1,9 @@
+
+#ifndef zipr_utils_h
+#define zipr_utils_h
+
+namespace Utils {
+	extern size_t CALLBACK_TRAMPOLINE_SIZE;
+	int DetermineWorstCaseInsnSize(libIRDB::Instruction_t*);
+}
+#endif
diff --git a/src/SConscript b/src/SConscript
index 535db7909fbbe187ecf79128a5356c40f91434b5..6404294c1dc6daf69af1738692a42e7f167e7b68 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -18,6 +18,8 @@ files=  '''
 	zipr.cpp
 	zipr_options.cpp
 	zipr_stats.cpp
+	utils.cpp
+	dollop.cpp
 	'''
 
 # ELFIO needs to be first so we get the zipr version instead of the sectrans version.  the zipr version is modified to include get_offset.
diff --git a/src/dollop.cpp b/src/dollop.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..64cb89ae4e2deeed7b7e636d8c90f47c425d71c3
--- /dev/null
+++ b/src/dollop.cpp
@@ -0,0 +1,39 @@
+#include <zipr_all.h>
+
+namespace Zipr_SDK {
+	using namespace libIRDB;
+	using namespace zipr;
+	Dollop_t::Dollop_t(Instruction_t *start)
+	{
+		m_start = start;
+		m_size = CalculateWorstCaseSize();
+	}
+
+	size_t Dollop_t::CalculateWorstCaseSize()
+	{
+		size_t dollop_size = 0;
+		Instruction_t *cur_insn = m_start;
+		while (cur_insn != NULL)
+		{
+			/*
+			 * TODO: Take into consideration the dollop might
+			 * be MUCH shorter if it is going to jump to a 
+			 * previously placed dollop at this insn.
+			 */
+	#if 0
+			if ((to_addr=final_insn_locations[cur_insn]) != 0)
+			{
+				if (!m_replop)
+				{
+					if (m_verbose)
+						printf("Fallthrough loop detected. ");
+					break;
+				}
+			}
+	#endif
+			dollop_size += Utils::DetermineWorstCaseInsnSize(cur_insn);
+			cur_insn=cur_insn->GetFallthrough();
+		}
+		return dollop_size;
+	}
+}
diff --git a/src/memory_space.cpp b/src/memory_space.cpp
index b409e298c7a7a89d8e6e6991868ec8186a3e360b..3932ff6ba8e4b0b4eaaff329999a1c44bedb9c55 100644
--- a/src/memory_space.cpp
+++ b/src/memory_space.cpp
@@ -161,6 +161,20 @@ bool ZiprMemorySpace_t::IsValidRange(RangeSet_t::iterator it)
 	return it!=free_ranges.end();
 }
 
+Range_t ZiprMemorySpace_t::GetNearbyFreeRange(const RangeAddress_t hint)
+{
+	RangeSet_t::iterator result;
+	Range_t search(hint, hint+1);
+	/*
+	 * TODO: Not quite sure what to make of this.
+	 */
+	if (free_ranges.end() == (result = free_ranges.upper_bound(search))) {
+		cout << "Oops: GetNearbyFreeRange() is BAD" << endl;
+		return Range_t(0,0);
+	}
+	return *result;
+}
+
 Range_t ZiprMemorySpace_t::GetFreeRange(int size)
 {
 	vector<Range_t> v;
diff --git a/src/plugin_man.cpp b/src/plugin_man.cpp
index bdde51fa3d20df5dfb05412c733bca75bc4b8046..2e3885e54fba30ff05bde8f5c0afddee28b0d29e 100644
--- a/src/plugin_man.cpp
+++ b/src/plugin_man.cpp
@@ -81,6 +81,21 @@ void ZiprPluginManager_t::CallbackLinkingEnd()
 	dispatch_to(CallbackLinkingEnd);
 }
 
+bool ZiprPluginManager_t::DoesPluginPlace(const RangeAddress_t &jump, const Dollop_t &dollop, Range_t &place, DLFunctionHandle_t &placer)
+{
+	DLFunctionHandleSet_t::iterator it=m_handleList.begin();
+	for(m_handleList.begin();it!=m_handleList.end();++it)
+	{
+		ZiprPluginInterface_t* zpi=(ZiprPluginInterface_t*)*it;
+		if (Zipr_SDK::ZiprPreference::Must == zpi->PlopAddress(jump, dollop, place))
+		{
+			placer = zpi;
+			return true;
+		}
+	}
+	return false;
+}
+
 bool ZiprPluginManager_t::DoesPluginPlop(Instruction_t *insn, DLFunctionHandle_t &callback) 
 {
 	DLFunctionHandleSet_t::iterator it=m_handleList.begin();
diff --git a/src/utils.cpp b/src/utils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..735f91101be562380140a06521fdb740269fb824
--- /dev/null
+++ b/src/utils.cpp
@@ -0,0 +1,70 @@
+#include <zipr_all.h>
+
+namespace zipr {
+namespace Utils {
+size_t CALLBACK_TRAMPOLINE_SIZE=9;
+using namespace libIRDB;
+int DetermineWorstCaseInsnSize(Instruction_t* insn)
+{
+
+	int required_size=0;
+
+	switch(insn->GetDataBits()[0])
+	{
+		case (char)0x71:
+		case (char)0x72:
+		case (char)0x73:
+		case (char)0x74:
+		case (char)0x75:
+		case (char)0x76:
+		case (char)0x77:
+		case (char)0x78:
+		case (char)0x79:
+		case (char)0x7a:
+		case (char)0x7b:
+		case (char)0x7c:
+		case (char)0x7d:
+		case (char)0x7e:
+		case (char)0x7f:
+		{
+			// two byte JCC -> 6byte JCC
+			required_size=6;
+			break;
+		}
+
+		case (char)0xeb:
+		{
+			// two byte JMP -> 5byte JMP
+			required_size=5;
+			break;
+		}
+
+		case (char)0xe0:
+		case (char)0xe1:
+		case (char)0xe2:
+		case (char)0xe3:
+		{
+			// loop, loopne, loopeq, jecxz
+			// convert to:
+			// <op> +5:
+			// jmp fallthrough
+			// +5: jmp target
+			// 2+5+5;
+			required_size=10;
+			break;
+		}
+		
+
+		default:
+		{
+			required_size=insn->GetDataBits().size();
+			if (insn->GetCallback()!="") required_size+=CALLBACK_TRAMPOLINE_SIZE;
+			break;
+		}
+	}
+	
+	// add an extra 5 for a "trampoline" in case we have to end this fragment early
+	return required_size+5;
+}
+}
+}
diff --git a/src/zipr.cpp b/src/zipr.cpp
index 722eb452490f5ec3fff00c613d37e88f79fdfebc..28bd031c582ab49d83dd786185be631f5c3ebf3e 100644
--- a/src/zipr.cpp
+++ b/src/zipr.cpp
@@ -1224,77 +1224,44 @@ int ZiprImpl_t::_DetermineWorstCaseInsnSize(Instruction_t* insn)
 	return worst_case_size;
 }
 
-#define CALLBACK_TRAMPOLINE_SIZE 9
 //static int DetermineWorstCaseInsnSize(Instruction_t* insn)
 int ZiprImpl_t::DetermineWorstCaseInsnSize(Instruction_t* insn)
 {
-
-	int required_size=0;
-
-	switch(insn->GetDataBits()[0])
-	{
-		case (char)0x71:
-		case (char)0x72:
-		case (char)0x73:
-		case (char)0x74:
-		case (char)0x75:
-		case (char)0x76:
-		case (char)0x77:
-		case (char)0x78:
-		case (char)0x79:
-		case (char)0x7a:
-		case (char)0x7b:
-		case (char)0x7c:
-		case (char)0x7d:
-		case (char)0x7e:
-		case (char)0x7f:
-		{
-			// two byte JCC -> 6byte JCC
-			required_size=6;
-			break;
-		}
-
-		case (char)0xeb:
-		{
-			// two byte JMP -> 5byte JMP
-			required_size=5;
-			break;
-		}
-
-		case (char)0xe0:
-		case (char)0xe1:
-		case (char)0xe2:
-		case (char)0xe3:
-		{
-			// loop, loopne, loopeq, jecxz
-			// convert to:
-			// <op> +5:
-			// jmp fallthrough
-			// +5: jmp target
-			// 2+5+5;
-			required_size=10;
-			break;
-		}
-		
-
-		default:
-		{
-			required_size=insn->GetDataBits().size();
-			if (insn->GetCallback()!="") required_size+=CALLBACK_TRAMPOLINE_SIZE;
-			break;
-		}
-	}
-	
-	// add an extra 5 for a "trampoline" in case we have to end this fragment early
-	return required_size+5;
+	return Utils::DetermineWorstCaseInsnSize(insn);
 }
 
 void ZiprImpl_t::ProcessUnpinnedInstruction(const UnresolvedUnpinned_t &uu, const Patch_t &p)
 {
 	int req_size=_DetermineWorstCaseInsnSize(uu.GetInstruction());
-	Range_t r=memory_space.GetFreeRange(req_size);
+	Range_t r;
+	//Range_t r=memory_space.GetFreeRange(req_size);
+	//Range_t r=memory_space.GetNearbyFreeRange(p.GetAddress());
 	int insn_count=0;
 	const char* truncated="not truncated.";
+	bool placed = false;
+	DLFunctionHandle_t placer = NULL;
+
+	/*
+	 *
+	 */
+	if (plugman.DoesPluginPlace(p.GetAddress(), Dollop_t(uu.GetInstruction()), r, placer))
+	{
+		if (m_verbose)
+			cout << placer->ToString() << " placed this dollop." << endl;
+		placed = true;
+		if ((r.GetEnd()-r.GetStart()) < req_size) {
+			if (m_verbose)
+				printf("Bad GetNearbyFreeRange() result.\n");
+			placed = false;
+		}
+	}
+	if (!placed) {
+		cout << "Using default place locator." << endl;
+		r=memory_space.GetFreeRange(req_size);
+	}
+	/*
+	 *
+	 */
 
 	RangeAddress_t fr_end=r.GetEnd();
 	RangeAddress_t fr_start=r.GetStart();
@@ -2182,7 +2149,7 @@ RangeAddress_t ZiprImpl_t::PlopWithCallback(Instruction_t* insn, RangeAddress_t
 	else
 		assert(0);
 
-	assert(CALLBACK_TRAMPOLINE_SIZE<=(at-originalAt));
+	assert(Utils::CALLBACK_TRAMPOLINE_SIZE<=(at-originalAt));
 	return at;
 }