diff --git a/src/test/java/net/onrc/onos/apps/bgproute/PrefixTest.java b/src/test/java/net/onrc/onos/apps/bgproute/PrefixTest.java
index 3b9bef2..8c4b8d5 100644
--- a/src/test/java/net/onrc/onos/apps/bgproute/PrefixTest.java
+++ b/src/test/java/net/onrc/onos/apps/bgproute/PrefixTest.java
@@ -12,92 +12,90 @@
 
 public class PrefixTest {
 
-	@Before
-	public void setUp() throws Exception {
-	}
+    @Before
+    public void setUp() throws Exception {
+    }
 
-	@After
-	public void tearDown() 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 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};
 
-	@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());
-	}
+        Prefix p1 = new Prefix(b1, 12);
+        Prefix p2 = new Prefix(b2, 12);
+        Prefix p3 = new Prefix(b3, 12);
+        Prefix p4 = new Prefix(b4, 11);
 
-	@Test
-	public void testPrefixReturnsSame() {
-		//Create a prefix of all 1s for each prefix length.
-		//Check that Prefix doesn't mangle it
-		int MAX_PREFIX_LENGTH = 32;
-		for (int prefixLength = 1; prefixLength <= MAX_PREFIX_LENGTH; prefixLength++) {
-			byte address[] = new byte[MAX_PREFIX_LENGTH/Byte.SIZE];
-			
-			int lastByte = (prefixLength - 1) / Byte.SIZE;
-			int lastBit = (prefixLength - 1) % Byte.SIZE;
-			
-			for (int j = 0; j < address.length; j++) {
-				if (j < lastByte) {
-					address[j] = (byte)0xff;
-				}
-				else if (j == lastByte) {
-					byte b = 0;
-					byte msb = (byte) 0x80;
-					for (int k = 0; k < Byte.SIZE; k++) {
-						if (k <= lastBit) {
-							b |= (msb >> k);
-						}
-					}
-					address[j] = b;
-				}
-				else {
-					address[j] = 0;
-				}
-			}
-			
-			Prefix p = new Prefix(address, prefixLength);
-			System.out.println(p.printAsBits());
-			assertTrue(Arrays.equals(address, p.getAddress()));
-		}
-	}
+        //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());
+    }
+
+    @Test
+    public void testPrefixReturnsSame() {
+        //Create a prefix of all 1s for each prefix length.
+        //Check that Prefix doesn't mangle it
+        int MAX_PREFIX_LENGTH = 32;
+        for (int prefixLength = 1; prefixLength <= MAX_PREFIX_LENGTH; prefixLength++) {
+            byte address[] = new byte[MAX_PREFIX_LENGTH / Byte.SIZE];
+
+            int lastByte = (prefixLength - 1) / Byte.SIZE;
+            int lastBit = (prefixLength - 1) % Byte.SIZE;
+
+            for (int j = 0; j < address.length; j++) {
+                if (j < lastByte) {
+                    address[j] = (byte) 0xff;
+                } else if (j == lastByte) {
+                    byte b = 0;
+                    byte msb = (byte) 0x80;
+                    for (int k = 0; k < Byte.SIZE; k++) {
+                        if (k <= lastBit) {
+                            b |= (msb >> k);
+                        }
+                    }
+                    address[j] = b;
+                } else {
+                    address[j] = 0;
+                }
+            }
+
+            Prefix p = new Prefix(address, prefixLength);
+            System.out.println(p.printAsBits());
+            assertTrue(Arrays.equals(address, p.getAddress()));
+        }
+    }
 }
