diff --git a/src/test/java/net/onrc/onos/ofcontroller/bgproute/PatriciaTrieTest.java b/src/test/java/net/onrc/onos/ofcontroller/bgproute/PatriciaTrieTest.java
new file mode 100644
index 0000000..d462d3e
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/bgproute/PatriciaTrieTest.java
@@ -0,0 +1,189 @@
+package net.onrc.onos.ofcontroller.bgproute;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class PatriciaTrieTest {
+
+	IPatriciaTrie ptrie;
+	Prefix[] prefixes;
+	Map<Prefix, Rib> mappings;
+	
+	@Before
+	public void setUp() throws Exception {
+		ptrie = new PatriciaTrie(32);
+		mappings = new HashMap<Prefix, Rib>();
+		
+		prefixes = new Prefix[] {
+			new Prefix("192.168.10.0", 24),
+			new Prefix("192.168.8.0", 23),
+			new Prefix("192.168.8.0", 22),
+			new Prefix("192.0.0.0", 7),
+			new Prefix("192.168.11.0", 24),
+			new Prefix("10.0.23.128", 25),
+			new Prefix("206.17.144.0", 20),
+			new Prefix("9.17.0.0", 12),
+			new Prefix("192.168.0.0", 16)
+		};
+				
+		for (int i = 0; i < prefixes.length; i++) {
+			mappings.put(prefixes[i], new Rib("192.168.10.101", "192.168.20." + i, 32));
+			ptrie.put(prefixes[i], new Rib("192.168.10.101", "192.168.20." + i, 32));
+		}
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testPut() {
+		IPatriciaTrie ptrie = new PatriciaTrie(32);
+		
+		Prefix p1 = new Prefix("192.168.240.0", 20);
+		Rib r1 = new Rib("192.168.10.101", "192.168.60.2", 20);
+		Rib retval = ptrie.put(p1, r1);
+		assertNull(retval);
+		retval = ptrie.lookup(p1);
+		assertTrue(r1 == retval); //should be the same object
+		
+		Prefix p2 = new Prefix("192.160.0.0", 12);
+		Rib r2 = new Rib("192.168.10.101", "192.168.20.1", 12);
+		retval = ptrie.put(p2, r2);
+		assertNull(retval);
+		
+		Prefix p3 = new Prefix("192.168.208.0", 20);
+		Rib r3 = new Rib("192.168.10.101", "192.168.30.1", 20);
+		retval = ptrie.put(p3,  r3);
+		assertNull(retval);
+		
+		//Insert a new Rib entry over a previous one
+		Rib r3new = new Rib("192.168.10.101", "192.168.60.2", 20);
+		retval = ptrie.put(p3, r3new);
+		assertNotNull(retval);
+		assertTrue(retval.equals(r3));
+		assertTrue(retval == r3); //should be the same object
+		
+		//Now we have an aggregate node with prefix 192.168.192.0/18.
+		//We will insert a Rib at this prefix
+		Prefix p4 = new Prefix("192.168.192.0", 18);
+		Rib r4 = new Rib("192.168.10.101", "192.168.40.1", 18);
+		retval = ptrie.put(p4, r4);
+		assertNull(retval);
+		retval = ptrie.lookup(p4);
+		assertTrue(retval == r4); //should be the same object
+	}
+
+	@Test
+	public void testLookup() {
+		for (Map.Entry<Prefix, Rib> entry : mappings.entrySet()) {
+			Rib r = ptrie.lookup(entry.getKey());
+			assertTrue(entry.getValue().equals(r));
+		}
+		
+		//These are aggregate nodes in the tree. Shouldn't be returned by lookup
+		Prefix p1 = new Prefix("0.0.0.0", 0);
+		Rib retval = ptrie.lookup(p1);
+		assertNull(retval);
+		
+		//We'll put a Rib at an aggregate node and check if lookup returns correctly
+		Prefix p2 = new Prefix("192.0.0.0", 4);
+		Rib r2 = new Rib("192.168.10.101", "192.168.60.1", 4);
+		retval = ptrie.put(p2, r2);
+		assertNull(retval);
+		retval = ptrie.lookup(p2);
+		assertTrue(retval.equals(r2));
+	}
+
+	@Ignore
+	@Test
+	public void testMatch() {
+		fail("Not yet implemented");
+	}
+
+	@Test
+	public void testRemove() {
+		Prefix p1 = new Prefix("192.168.8.0", 23);
+		Rib retval = ptrie.lookup(p1);
+		assertNotNull(retval);
+		boolean success = ptrie.remove(p1, retval);
+		assertTrue(success);
+		
+		Prefix p2 = new Prefix("192.168.8.0", 22);
+		Prefix p3 = new Prefix("192.168.10.0", 24);
+		
+		//Test it does the right thing with null arguments
+		success = ptrie.remove(null, null);
+		assertFalse(success);
+		success = ptrie.remove(p2, null);
+		assertFalse(success);
+		
+		//Check other prefixes are still there
+		retval = ptrie.lookup(p2);
+		assertNotNull(retval);
+		retval = ptrie.lookup(p3);
+		assertNotNull(retval);
+		
+		Prefix p4 = new Prefix("9.17.0.0", 12);
+		retval = ptrie.lookup(p4);
+		assertNotNull(retval);
+		success = ptrie.remove(p4, retval);
+		assertTrue(success);
+		success = ptrie.remove(p4, retval);
+		assertFalse(success);
+		
+		//Check other prefixes are still there
+		retval = ptrie.lookup(p2);
+		assertNotNull(retval);
+		retval = ptrie.lookup(p3);
+		assertNotNull(retval);
+		
+		Prefix p5 = new Prefix("192.0.0.0", 7);
+		retval = ptrie.lookup(p5);
+		assertNotNull(retval);
+		success = ptrie.remove(p5, retval);
+		assertTrue(success);
+		
+		//Check other prefixes are still there
+		retval = ptrie.lookup(p2);
+		assertNotNull(retval);
+		retval = ptrie.lookup(p3);
+		assertNotNull(retval);
+		
+		
+	}
+
+	@Test(expected=java.util.NoSuchElementException.class)
+	public void testIterator() {		
+		int[] order = new int[] {7, 5, 3, 8, 2, 1, 0, 4, 6};
+		
+		Iterator<IPatriciaTrie.Entry> it = ptrie.iterator();
+		int i = 0;
+		assertTrue(it.hasNext());
+		while (it.hasNext()) {
+			IPatriciaTrie.Entry entry = it.next();
+			assertTrue(entry.getPrefix().equals(prefixes[order[i]]));
+			i++;
+		}
+		assertFalse(it.hasNext());
+		assertTrue(i == order.length);
+		
+		IPatriciaTrie pt = new PatriciaTrie(32);
+		Iterator<IPatriciaTrie.Entry> it2 = pt.iterator();
+		assertFalse(it2.hasNext());
+		it.next(); //throws NoSuchElementException
+	}
+
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/bgproute/PrefixTest.java b/src/test/java/net/onrc/onos/ofcontroller/bgproute/PrefixTest.java
new file mode 100644
index 0000000..01c5ea7
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/bgproute/PrefixTest.java
@@ -0,0 +1,66 @@
+package net.onrc.onos.ofcontroller.bgproute;
+
+import static org.junit.Assert.*;
+
+import java.util.Arrays;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class PrefixTest {
+
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testPrefixByteArray() {
+		byte[] b1 = new byte[] {(byte)0x8f, (byte)0xa0, (byte)0x00, (byte)0x00};
+		byte[] b2 = new byte[] {(byte)0x8f, (byte)0xa0, (byte)0xff, (byte)0xff};
+		byte[] b3 = new byte[] {(byte)0x8f, (byte)0xac, (byte)0x00, (byte)0x00};
+		byte[] b4 = new byte[] {(byte)0x8f, (byte)0xa0, (byte)0x00, (byte)0x00};
+		
+		Prefix p1 = new Prefix(b1, 12);
+		Prefix p2 = new Prefix(b2, 12);
+		Prefix p3 = new Prefix(b3, 12);
+		Prefix p4 = new Prefix(b4, 11);
+		
+		//Have different byte arrays, but should be equal after construction
+		assertTrue(p1.equals(p2));
+		assertTrue(p2.equals(p3));
+		
+		//Same byte array, but should be false
+		assertFalse(p1.equals(p4));
+		
+		assertTrue(Arrays.equals(p1.getAddress(), p3.getAddress()));
+		assertTrue(p1.toString().equals(p2.toString()));
+		assertTrue(Arrays.equals(p1.getAddress(), p4.getAddress()));
+		assertFalse(p1.toString().equals(p4.toString()));
+	}
+
+	@Test
+	public void testPrefixString() {
+		Prefix p1 = new Prefix("192.168.166.0", 24);
+		Prefix p2 = new Prefix("192.168.166.0", 23);
+		Prefix p3 = new Prefix("192.168.166.128", 24);
+		Prefix p4 = new Prefix("192.168.166.128", 25);
+		
+		assertFalse(p1.equals(p2));
+		assertTrue(Arrays.equals(p1.getAddress(), p2.getAddress()));
+		
+		assertTrue(p1.equals(p3));
+		assertTrue(Arrays.equals(p1.getAddress(), p2.getAddress()));
+		
+		assertFalse(p3.equals(p4));
+		assertFalse(Arrays.equals(p3.getAddress(), p4.getAddress()));
+		
+		assertTrue(p1.toString().equals(p3.toString()));
+		assertEquals(p1.hashCode(), p3.hashCode());
+	}
+
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/bgproute/PtreeTest.java b/src/test/java/net/onrc/onos/ofcontroller/bgproute/PtreeTest.java
new file mode 100644
index 0000000..1aa451c
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/bgproute/PtreeTest.java
@@ -0,0 +1,227 @@
+package net.onrc.onos.ofcontroller.bgproute;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.net.InetAddresses;
+
+public class PtreeTest {
+	
+	private Logger log = LoggerFactory.getLogger(PtreeTest.class);
+	
+	private Ptree ptree;
+	private PatriciaTrie ooptrie;
+	
+	private Map<String, byte[]> byteAddresses;
+
+	@Before
+	public void setUp() throws Exception {
+		ptree = new Ptree(32);
+		ooptrie = new PatriciaTrie(32);
+			
+		String[] strPrefixes = {
+			"192.168.10.0/24",
+			"192.168.10.0/23",
+			"192.168.10.0/22",
+			"192.0.0.0/7",
+			"192.168.11.0/24",
+			"10.0.23.128/25",
+			"206.17.144.0/20",
+			"9.17.0.0/12",
+			"192.168.0.0/16"
+		};
+		
+		byteAddresses = new HashMap<String, byte[]>(strPrefixes.length+10);
+		for (String prefix : strPrefixes) {
+			String address = prefix.split("/")[0];
+			int prefixLength = Integer.parseInt(prefix.split("/")[1]);
+			byteAddresses.put(prefix, InetAddresses.forString(address).getAddress());
+			
+			PtreeNode node = ptree.acquire(byteAddresses.get(prefix), prefixLength);
+			node.rib = new Rib("192.168.10.101", "192.168.60.1", prefixLength);
+			ooptrie.put(new Prefix(byteAddresses.get(prefix), prefixLength), 
+					new Rib("192.168.10.101", "192.168.60.1", prefixLength));
+		}
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Ignore
+	@Test
+	public void testAcquireByteArray() {
+		fail("Not yet implemented");
+	}
+
+	@Ignore
+	@Test
+	public void testAcquireByteArrayInt() {
+		//First let's test an empty Ptree
+		Ptree localPtree = new Ptree(32);
+		PtreeNode node = localPtree.acquire(new byte[] {0x00, 0x00, 0x00, 0x00});
+		assertTrue(node != null && node.rib == null);
+		
+		//Now let's look at the prepopulated tree
+		String testPrefix = "206.17.144.0/20";
+		PtreeNode existingNode = ptree.acquire(byteAddresses.get(testPrefix), 20);
+		printByteArray(existingNode.key);
+		printByteArray(byteAddresses.get(testPrefix));
+		assertTrue(existingNode != null && existingNode.rib == null);
+		
+		assertTrue(Arrays.equals(existingNode.key, byteAddresses.get(testPrefix)));
+	}
+
+	@Test
+	public void testLookup() {
+		String prefix1 = "192.168.10.12";
+		int length1 = 29;
+		PtreeNode node1 = ptree.lookup(InetAddresses.forString(prefix1).getAddress(), length1);
+		
+		//There should be no direct match
+		assertTrue(node1 == null);
+		
+		log.debug("{} null: {}", "node1", node1 == null ? "true" : "false");
+		
+		String prefix2 = "206.17.144.0";
+		int length2 = 20;
+		PtreeNode node2 = ptree.lookup(InetAddresses.forString(prefix2).getAddress(), length2);
+		
+		assertTrue(node2 != null);
+		assertTrue(Arrays.equals(node2.key, byteAddresses.get(prefix2 + "/" + length2)));
+		
+		log.debug("{} null: {}", "node2", node2 == null ? "true" : "false");
+		if (node2 != null) {
+			log.debug("{} key: {}, keybits: {}", new Object[] {"node2", node2.key, node2.keyBits});
+		}
+		
+		String prefix3 = "192.0.0.0";
+		int length3 = 7;
+		PtreeNode node3 = ptree.lookup(InetAddresses.forString(prefix3).getAddress(), length3);
+		assertTrue(node3 != null);
+	}
+
+	@Test
+	public void testMatch() {
+		String prefix1 = "192.168.10.12";
+		int length1 = 29;
+		PtreeNode node1 = ptree.match(InetAddresses.forString(prefix1).getAddress(), length1);
+		
+		//There should be no direct match, but we should get the covering prefix
+		assertTrue(node1 != null);
+		assertTrue(Arrays.equals(node1.key, byteAddresses.get("192.168.10.0/24")));
+		
+		log.debug("{} null: {}", "node1", node1 == null ? "true" : "false");
+		if (node1 != null) {
+			log.debug("{} key: {}, keybits: {}", new Object[] {"node1", node1.key, node1.keyBits});
+		}
+	}
+	
+	@Ignore
+	@Test
+	public void testTraverse() {
+		
+		String expected = "[0, 0, 0, 0]/0\n";
+		expected += "[8, 0, 0, 0]/6\n";
+		expected += "[9, 17, 0, 0]/12\n";
+		expected += "[10, 0, 23, -128]/25\n";
+		expected += "[-64, 0, 0, 0]/4\n";
+		expected += "[-64, -88, 0, 0]/16\n";
+		expected += "[-64, -88, 8, 0]/22\n";
+		expected += "[-64, -88, 10, 0]/23\n";
+		expected += "[-64, -88, 10, 0]/24\n";
+		expected += "[-64, -88, 11, 0]/24\n";
+		expected += "[-50, 17, -112, 0]/20\n";
+		
+		PtreeNode node;
+		String result = "";
+		
+		for (node = ptree.begin(); node != null; node = ptree.next(node)) {
+			result += printByteArray(node.key) + "/" + node.keyBits + "\n";
+		}
+		
+		assertEquals(expected, result);
+	}
+
+	@Ignore
+	@Test
+	public void testBegin() {
+		fail("Not yet implemented");
+	}
+
+	@Ignore
+	@Test
+	public void testNext() {
+		fail("Not yet implemented");
+	}
+
+	@Ignore
+	@Test
+	public void testDelReference() {
+		fail("Not yet implemented");
+	}
+	
+	@Test
+	public void testMisc() {
+		int bitIndex = -1;
+		int index = (int)(bitIndex / Byte.SIZE);
+	    int bit = (int)(bitIndex % Byte.SIZE);
+	    
+	    log.debug("index {} bit {}", index, bit); 
+	    log.debug("percent {}", 1%8);
+	    
+	    //PtreeNode node1 = new PtreeNode(new byte[] {0x0, 0x0, 0x0, 0x0}, 0, 4);
+	    PtreeNode node1 = new PtreeNode(null, 0, 4);
+	    log.debug("node1: key {}, keybits {}", printByteArray(node1.key), node1.keyBits);
+	    
+	    //PtreeNode node2 = new PtreeNode(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff}, 
+	    PtreeNode node2 = new PtreeNode(null,
+	    		32, 4);
+	    log.debug("node2: key {}, keybits {}", printByteArray(node2.key), node2.keyBits);
+	}
+	
+	@Test
+	public void testIteration() {
+		Iterator<IPatriciaTrie.Entry> it = ooptrie.iterator();
+		
+		while (it.hasNext()) {
+			IPatriciaTrie.Entry entry = it.next();
+			log.debug("PatriciaTrie prefix {} \t {}", entry.getPrefix(), entry.getPrefix().printAsBits());
+		}
+		
+		try {
+			PtreeNode node;
+			for (node = ptree.begin(); node != null; node = ptree.next(node)) {
+				log.debug("Ptree prefix {}/{}", InetAddress.getByAddress(node.key).getHostAddress(), node.keyBits);
+			}
+		} catch (UnknownHostException e) {
+			
+		}
+	}
+	
+	private String printByteArray(byte[] array) {
+		String result = "[";
+		for (byte b : array) {
+			result += b + ", ";
+		}
+		result = result.substring(0, result.length() - 2);
+		result += "]";
+		return result;
+	}
+
+}
