diff --git a/rt/route.go b/rt/route.go
index f902748611fdad60b03a31e1194c35930c27587c..f309d3c108241ab2e62d0c5536b6275b7a35ddf8 100644
--- a/rt/route.go
+++ b/rt/route.go
@@ -23,11 +23,12 @@ type Route struct {
 }
 
 func NewRoute(pfx *net.Prefix, paths []*Path) *Route {
-	return &Route{
-		pfx:         pfx,
-		activePaths: make([]*Path, 0),
-		paths:       paths,
+	r := &Route{
+		pfx:   pfx,
+		paths: paths,
 	}
+
+	return r
 }
 
 func (r *Route) Pfxlen() uint8 {
@@ -95,7 +96,7 @@ func (r *Route) AddPaths(paths []*Path) {
 }
 
 func (r *Route) bestPaths() {
-	var best []*Path
+	best := []*Path{}
 	protocol := getBestProtocol(r.paths)
 
 	switch protocol {
diff --git a/rt/route_test.go b/rt/route_test.go
index ecd88a04168a225a513f07f6d2fb2b96b05d2f22..3bac4e87cf7907e57fce7af3ac8192370f048bec 100644
--- a/rt/route_test.go
+++ b/rt/route_test.go
@@ -26,8 +26,7 @@ func TestNewRoute(t *testing.T) {
 				},
 			},
 			expected: &Route{
-				pfx:         net.NewPfx(158798889, 24),
-				activePaths: make([]*Path, 0),
+				pfx: net.NewPfx(158798889, 24),
 				paths: []*Path{
 					{
 						Type: 2,
diff --git a/rt/routing_table.go b/rt/routing_table.go
index c86526e966c28329a45381f59bf1741d358887da..6ce2785cdbc5bb6fdcbe2342b17e037ae2147180 100644
--- a/rt/routing_table.go
+++ b/rt/routing_table.go
@@ -4,11 +4,13 @@ import (
 	"github.com/bio-routing/bio-rd/net"
 )
 
+// RT represents a routing table
 type RT struct {
 	root  *node
 	nodes uint64
 }
 
+// node is a node in the compressed trie that is used to implement a routing table
 type node struct {
 	skip  uint8
 	dummy bool
@@ -32,31 +34,32 @@ func newNode(route *Route, skip uint8, dummy bool) *node {
 }
 
 // LPM performs a longest prefix match for pfx on lpm
-func (lpm *RT) LPM(pfx *net.Prefix) (res []*Route) {
-	if lpm.root == nil {
+func (rt *RT) LPM(pfx *net.Prefix) (res []*Route) {
+	if rt.root == nil {
 		return nil
 	}
 
-	lpm.root.lpm(pfx, &res)
+	rt.root.lpm(pfx, &res)
 	return res
 }
 
 // RemovePath removes a path from the trie
-func (lpm *RT) RemovePath(route *Route) {
-	lpm.root.removePath(route)
+func (rt *RT) RemovePath(route *Route) {
+	rt.root.removePath(route)
 }
 
-func (lpm *RT) RemovePfx(pfx *net.Prefix) {
-	lpm.root.removePfx(pfx)
+// RemovePfx removes a prefix from the rt including all it's paths
+func (rt *RT) RemovePfx(pfx *net.Prefix) {
+	rt.root.removePfx(pfx)
 }
 
 // Get get's prefix pfx from the LPM
-func (lpm *RT) Get(pfx *net.Prefix, moreSpecifics bool) (res []*Route) {
-	if lpm.root == nil {
+func (rt *RT) Get(pfx *net.Prefix, moreSpecifics bool) (res []*Route) {
+	if rt.root == nil {
 		return nil
 	}
 
-	node := lpm.root.get(pfx)
+	node := rt.root.get(pfx)
 	if moreSpecifics {
 		return node.dumpPfxs(res)
 	}
@@ -71,13 +74,14 @@ func (lpm *RT) Get(pfx *net.Prefix, moreSpecifics bool) (res []*Route) {
 }
 
 // Insert inserts a route into the LPM
-func (lpm *RT) Insert(route *Route) {
-	if lpm.root == nil {
-		lpm.root = newNode(route, route.Pfxlen(), false)
+func (rt *RT) Insert(route *Route) {
+	if rt.root == nil {
+		route.bestPaths()
+		rt.root = newNode(route, route.Pfxlen(), false)
 		return
 	}
 
-	lpm.root = lpm.root.insert(route)
+	rt.root = rt.root.insert(route)
 }
 
 func (n *node) removePath(route *Route) {
@@ -204,6 +208,7 @@ func (n *node) insert(route *Route) *node {
 
 	// is pfx NOT a subnet of this node?
 	if !n.route.Prefix().Contains(route.Prefix()) {
+		route.bestPaths()
 		if route.Prefix().Contains(n.route.Prefix()) {
 			return n.insertBefore(route, n.route.Pfxlen()-n.skip-1)
 		}
@@ -221,6 +226,7 @@ func (n *node) insert(route *Route) *node {
 
 func (n *node) insertLow(route *Route, parentPfxLen uint8) *node {
 	if n.l == nil {
+		route.bestPaths()
 		n.l = newNode(route, route.Pfxlen()-parentPfxLen-1, false)
 		return n
 	}
@@ -230,6 +236,7 @@ func (n *node) insertLow(route *Route, parentPfxLen uint8) *node {
 
 func (n *node) insertHigh(route *Route, parentPfxLen uint8) *node {
 	if n.h == nil {
+		route.bestPaths()
 		n.h = newNode(route, route.Pfxlen()-parentPfxLen-1, false)
 		return n
 	}
@@ -288,9 +295,10 @@ func (n *node) insertBefore(route *Route, parentPfxLen uint8) *node {
 	return new
 }
 
-func (lpm *RT) Dump() []*Route {
+// Dump dumps all routes in table rt into a slice
+func (rt *RT) Dump() []*Route {
 	res := make([]*Route, 0)
-	return lpm.root.dump(res)
+	return rt.root.dump(res)
 }
 
 func (n *node) dump(res []*Route) []*Route {
diff --git a/rt/routing_table_test.go b/rt/routing_table_test.go
index 602c1da960ec9be66196decf59eb47e2794a5bfc..6a80752c9d9047bf94e7a2ff9de3e8c59ce6eaf6 100644
--- a/rt/routing_table_test.go
+++ b/rt/routing_table_test.go
@@ -52,18 +52,24 @@ func TestRemovePath(t *testing.T) {
 				}),
 			},
 			expected: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 9), []*Path{
-					{
-						Type:    BGPPathType,
-						BGPPath: &BGPPath{},
+				{
+					pfx: net.NewPfx(strAddr("10.0.0.0"), 9),
+					paths: []*Path{
+						{
+							Type:    BGPPathType,
+							BGPPath: &BGPPath{},
+						},
 					},
-				}),
-				NewRoute(net.NewPfx(strAddr("10.128.0.0"), 9), []*Path{
-					{
-						Type:    BGPPathType,
-						BGPPath: &BGPPath{},
+				},
+				{
+					pfx: net.NewPfx(strAddr("10.128.0.0"), 9),
+					paths: []*Path{
+						{
+							Type:    BGPPathType,
+							BGPPath: &BGPPath{},
+						},
 					},
-				}),
+				},
 			},
 		},
 		{
@@ -107,14 +113,25 @@ func TestRemovePath(t *testing.T) {
 				}),
 			},
 			expected: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), []*Path{
-					{
-						Type: BGPPathType,
-						BGPPath: &BGPPath{
-							LocalPref: 2000,
+				{
+					pfx: net.NewPfx(strAddr("10.0.0.0"), 8),
+					paths: []*Path{
+						{
+							Type: BGPPathType,
+							BGPPath: &BGPPath{
+								LocalPref: 2000,
+							},
 						},
 					},
-				}),
+					activePaths: []*Path{
+						{
+							Type: BGPPathType,
+							BGPPath: &BGPPath{
+								LocalPref: 2000,
+							},
+						},
+					},
+				},
 				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 9), []*Path{
 					{
 						Type:    BGPPathType,
@@ -132,16 +149,16 @@ func TestRemovePath(t *testing.T) {
 	}
 
 	for _, test := range tests {
-		lpm := New()
+		rt := New()
 		for _, route := range test.routes {
-			lpm.Insert(route)
+			rt.Insert(route)
 		}
 
 		for _, route := range test.remove {
-			lpm.RemovePath(route)
+			rt.RemovePath(route)
 		}
 
-		res := lpm.Dump()
+		res := rt.Dump()
 		assert.Equal(t, test.expected, res)
 	}
 }
@@ -219,6 +236,371 @@ func TestRemovePfx(t *testing.T) {
 	}
 }
 
+func TestGetBitUint32(t *testing.T) {
+	tests := []struct {
+		name     string
+		input    uint32
+		offset   uint8
+		expected bool
+	}{
+		{
+			name:     "test 1",
+			input:    167772160, // 10.0.0.0
+			offset:   8,
+			expected: false,
+		},
+		{
+			name:     "test 2",
+			input:    184549376, // 11.0.0.0
+			offset:   8,
+			expected: true,
+		},
+	}
+
+	for _, test := range tests {
+		b := getBitUint32(test.input, test.offset)
+		if b != test.expected {
+			t.Errorf("%s: Unexpected failure: Bit %d of %d is %v. Expected %v", test.name, test.offset, test.input, b, test.expected)
+		}
+	}
+}
+
+func TestLPM(t *testing.T) {
+	tests := []struct {
+		name     string
+		routes   []*Route
+		needle   *net.Prefix
+		expected []*Route
+	}{
+		{
+			name:     "LPM for non-existent route",
+			routes:   []*Route{},
+			needle:   net.NewPfx(strAddr("10.0.0.0"), 32),
+			expected: nil,
+		},
+		{
+			name: "Positive LPM test",
+			routes: []*Route{
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
+				NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
+			},
+			needle: net.NewPfx(167772160, 32), // 10.0.0.0/32
+			expected: []*Route{
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
+			},
+		},
+		/*{
+			name: "Exact match",
+			routes: []*Route{
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
+				NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
+			},
+			needle: net.NewPfx(strAddr("10.0.0.0"), 10),
+			expected: []*Route{
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
+			},
+		},*/
+	}
+
+	for _, test := range tests {
+		rt := New()
+		for _, route := range test.routes {
+			rt.Insert(route)
+		}
+		assert.Equal(t, test.expected, rt.LPM(test.needle))
+	}
+}
+
+func TestGet(t *testing.T) {
+	tests := []struct {
+		name          string
+		moreSpecifics bool
+		routes        []*Route
+		needle        *net.Prefix
+		expected      []*Route
+	}{
+		{
+			name:          "Test 1: Search pfx and dump route + more specifics",
+			moreSpecifics: true,
+			routes: []*Route{
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
+				NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
+			},
+			needle: net.NewPfx(strAddr("10.0.0.0"), 8),
+			expected: []*Route{
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
+			},
+		},
+		{
+			name: "Test 2: Search pfx and don't dump more specifics",
+			routes: []*Route{
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
+				NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
+			},
+			needle: net.NewPfx(strAddr("10.0.0.0"), 8),
+			expected: []*Route{
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
+			},
+		},
+		{
+			name:     "Test 3: Empty table",
+			routes:   []*Route{},
+			needle:   net.NewPfx(strAddr("10.0.0.0"), 32),
+			expected: nil,
+		},
+		{
+			name: "Test 4: Get Dummy",
+			routes: []*Route{
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
+				NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
+			},
+			needle:   net.NewPfx(strAddr("10.0.0.0"), 7),
+			expected: nil,
+		},
+		{
+			name: "Test 5",
+			routes: []*Route{
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
+				NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
+			},
+			needle: net.NewPfx(strAddr("11.100.123.0"), 24),
+			expected: []*Route{
+				NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
+			},
+		},
+		{
+			name: "Test 4: Get nonexistent #1",
+			routes: []*Route{
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
+				NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
+			},
+			needle:   net.NewPfx(strAddr("10.0.0.0"), 10),
+			expected: nil,
+		},
+		{
+			name: "Test 4: Get nonexistent #2",
+			routes: []*Route{
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
+			},
+			needle:   net.NewPfx(strAddr("10.0.0.0"), 10),
+			expected: nil,
+		},
+	}
+
+	for _, test := range tests {
+		rt := New()
+		for _, route := range test.routes {
+			rt.Insert(route)
+		}
+		p := rt.Get(test.needle, test.moreSpecifics)
+
+		if p == nil {
+			if test.expected != nil {
+				t.Errorf("Unexpected nil result for test %q", test.name)
+			}
+			continue
+		}
+
+		assert.Equal(t, test.expected, p)
+	}
+}
+
+func TestInsert(t *testing.T) {
+	tests := []struct {
+		name     string
+		routes   []*Route
+		expected *node
+	}{
+		{
+			name: "Insert first node",
+			routes: []*Route{
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
+			},
+			expected: &node{
+				route: &Route{
+					pfx:         net.NewPfx(strAddr("10.0.0.0"), 8),
+					activePaths: []*Path{},
+				},
+				skip: 8,
+			},
+		},
+		{
+			name: "Insert duplicate node",
+			routes: []*Route{
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
+				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
+			},
+			expected: &node{
+				route: &Route{
+					pfx:         net.NewPfx(strAddr("10.0.0.0"), 8),
+					activePaths: []*Path{},
+				},
+				skip: 8,
+			},
+		},
+		/*{
+			name: "Insert triangle",
+			prefixes: []*net.Prefix{
+				net.NewPfx(167772160, 8), // 10.0.0.0
+				net.NewPfx(167772160, 9), // 10.0.0.0
+				net.NewPfx(176160768, 9), // 10.128.0.0
+			},
+			expected: &node{
+				route: &Route{
+					pfx: net.NewPfx(167772160, 8), // 10.0.0.0/8
+				},
+				skip: 8,
+				l: &node{
+					route: &Route{
+						pfx: net.NewPfx(167772160, 9), // 10.0.0.0
+					},
+				},
+				h: &node{
+					route: &Route{
+						pfx: net.NewPfx(176160768, 9), // 10.128.0.0
+					},
+				},
+			},
+		},
+		{
+			name: "Insert disjunct prefixes",
+			prefixes: []*net.Prefix{
+				net.NewPfx(167772160, 8),  // 10.0.0.0
+				net.NewPfx(191134464, 24), // 11.100.123.0/24
+			},
+			expected: &node{
+				route: &Route{
+					pfx: net.NewPfx(167772160, 7), // 10.0.0.0/7
+				},
+				skip:  7,
+				dummy: true,
+				l: &node{
+					route: &Route{
+						pfx: net.NewPfx(167772160, 8), // 10.0.0.0/8
+					},
+				},
+				h: &node{
+					route: &Route{
+						pfx: net.NewPfx(191134464, 24), // 10.0.0.0/8
+					},
+					skip: 16,
+				},
+			},
+		},
+		{
+			name: "Insert disjunct prefixes plus one child low",
+			prefixes: []*net.Prefix{
+				net.NewPfx(167772160, 8),  // 10.0.0.0
+				net.NewPfx(191134464, 24), // 11.100.123.0/24
+				net.NewPfx(167772160, 12), // 10.0.0.0
+				net.NewPfx(167772160, 10), // 10.0.0.0
+			},
+			expected: &node{
+				route: &Route{
+					pfx: net.NewPfx(167772160, 7), // 10.0.0.0/7
+				},
+				skip:  7,
+				dummy: true,
+				l: &node{
+					route: &Route{
+						pfx: net.NewPfx(167772160, 8), // 10.0.0.0/8
+					},
+					l: &node{
+						skip: 1,
+						route: &Route{
+							pfx: net.NewPfx(167772160, 10), // 10.0.0.0/10
+						},
+						l: &node{
+							skip: 1,
+							route: &Route{
+								pfx: net.NewPfx(167772160, 12), // 10.0.0.0
+							},
+						},
+					},
+				},
+				h: &node{
+					route: &Route{
+						pfx: net.NewPfx(191134464, 24), // 10.0.0.0/8
+					},
+					skip: 16,
+				},
+			},
+		},
+		{
+			name: "Insert disjunct prefixes plus one child high",
+			prefixes: []*net.Prefix{
+				net.NewPfx(167772160, 8),  // 10.0.0.0
+				net.NewPfx(191134464, 24), // 11.100.123.0/24
+				net.NewPfx(167772160, 12), // 10.0.0.0
+				net.NewPfx(167772160, 10), // 10.0.0.0
+				net.NewPfx(191134592, 25), // 11.100.123.128/25
+			},
+			expected: &node{
+				route: &Route{
+					pfx: net.NewPfx(167772160, 7), // 10.0.0.0/7
+				},
+				skip:  7,
+				dummy: true,
+				l: &node{
+					route: &Route{
+						pfx: net.NewPfx(167772160, 8), // 10.0.0.0/8
+					},
+					l: &node{
+						skip: 1,
+						route: &Route{
+							pfx: net.NewPfx(167772160, 10), // 10.0.0.0/10
+						},
+						l: &node{
+							skip: 1,
+							route: &Route{
+								pfx: net.NewPfx(167772160, 12), // 10.0.0.0
+							},
+						},
+					},
+				},
+				h: &node{
+					route: &Route{
+						pfx: net.NewPfx(191134464, 24), //11.100.123.0/24
+					},
+					skip: 16,
+					h: &node{
+						route: &Route{
+							pfx: net.NewPfx(191134592, 25), //11.100.123.128/25
+						},
+					},
+				},
+			},
+		},*/
+	}
+
+	for _, test := range tests {
+		rt := New()
+		for _, route := range test.routes {
+			rt.Insert(route)
+		}
+
+		assert.Equal(t, test.expected, rt.root)
+	}
+}
+
 func strAddr(s string) uint32 {
 	ret, _ := net.StrToAddr(s)
 	return ret