diff --git a/src/main/java/net/onrc/onos/apps/bgproute/Prefix.java b/src/main/java/net/onrc/onos/apps/bgproute/Prefix.java
index 8539759..5e5ba91 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/Prefix.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/Prefix.java
@@ -7,129 +7,129 @@
 import com.google.common.net.InetAddresses;
 
 public class Prefix {
-	private final int MAX_BYTES = 4;
-	
-	private final int prefixLength;
-	private final byte[] address;
-	
-	//For verifying the arguments and pretty printing
-	private final InetAddress inetAddress;
-	
-	public Prefix(byte[] addr, int prefixLength) {
-		if (addr == null || addr.length != MAX_BYTES || 
-				prefixLength < 0 || prefixLength > MAX_BYTES * Byte.SIZE) {
-			throw new IllegalArgumentException();
-		}
+    private final int MAX_BYTES = 4;
 
-		address = canonicalizeAddress(addr, prefixLength);
-		this.prefixLength = prefixLength;
-		
-		try {
-			inetAddress = InetAddress.getByAddress(address);
-		} catch (UnknownHostException e) {
-			throw new IllegalArgumentException();
-		}
-	}
+    private final int prefixLength;
+    private final byte[] address;
 
-	public Prefix(String strAddress, int prefixLength) {
-		byte[] addr = null;
-		addr = InetAddresses.forString(strAddress).getAddress();
-				
-		if (addr == null || addr.length != MAX_BYTES || 
-				prefixLength < 0 || prefixLength > MAX_BYTES * Byte.SIZE) {
-			throw new IllegalArgumentException();
-		}
-		
-		address = canonicalizeAddress(addr, prefixLength);
-		this.prefixLength = prefixLength;
-		
-		try {
-			inetAddress = InetAddress.getByAddress(address);
-		} catch (UnknownHostException e) {
-			throw new IllegalArgumentException();
-		}
-	}
-	
-	private byte[] canonicalizeAddress(byte[] address, int prefixLength) {
-		byte[] result = new byte[address.length];
-		
-		if (prefixLength == 0) {
-			for (int i = 0; i < MAX_BYTES; i++) {
-				result[i] = 0;
-			}
-			
-			return result;
-		}
-		
-		result = Arrays.copyOf(address, address.length);
-		
-		//Set all bytes after the end of the prefix to 0
-		int lastByteIndex = (prefixLength - 1) / Byte.SIZE;
-		for (int i = lastByteIndex; i < MAX_BYTES; i++) {
-			result[i] = 0;
-		}
-		
-		byte lastByte = address[lastByteIndex];
-		byte mask = 0;
-		byte msb = (byte) 0x80;
-		int lastBit = (prefixLength - 1) % Byte.SIZE;
-		for (int i = 0; i < Byte.SIZE; i++) {
-			if (i <= lastBit) {
-				mask |= (msb >> i);
-			}
-		}
+    //For verifying the arguments and pretty printing
+    private final InetAddress inetAddress;
 
-		result[lastByteIndex] = (byte) (lastByte & mask);
-		
-		return result;
-	}
+    public Prefix(byte[] addr, int prefixLength) {
+        if (addr == null || addr.length != MAX_BYTES ||
+                prefixLength < 0 || prefixLength > MAX_BYTES * Byte.SIZE) {
+            throw new IllegalArgumentException();
+        }
 
-	public int getPrefixLength() {
-		return prefixLength;
-	}
-	
-	public byte[] getAddress() {
-		return address;
-	}
-	
-	@Override
-	public boolean equals(Object other) {
-		if (other == null || !(other instanceof Prefix)) {
-			return false;
-		}
-		
-		Prefix otherPrefix = (Prefix) other;
-		
-		return (Arrays.equals(address, otherPrefix.address)) &&
-				(prefixLength == otherPrefix.prefixLength);
-	}
-	
-	@Override
-	public int hashCode() {
-		int hash = 17;
-		hash = 31 * hash + prefixLength;
-		hash = 31 * hash + Arrays.hashCode(address);
-		return hash;
-	}
-	
-	@Override
-	public String toString() {
-		return inetAddress.getHostAddress() + "/" + prefixLength;
-	}
-	
-	public String printAsBits() {
-		String result = "";
-		for (int i = 0; i < address.length; i++) {
-			byte b = address[i];
-			for (int j = 0; j < Byte.SIZE; j++) {
-				byte mask = (byte) (0x80 >>> j);
-				result += ((b & mask) == 0)? "0" : "1";
-				if (i*Byte.SIZE+j == prefixLength-1) {
-					return result;
-				}
-			}
-			result += " ";
-		}
-		return result.substring(0, result.length() - 1);
-	}
+        address = canonicalizeAddress(addr, prefixLength);
+        this.prefixLength = prefixLength;
+
+        try {
+            inetAddress = InetAddress.getByAddress(address);
+        } catch (UnknownHostException e) {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    public Prefix(String strAddress, int prefixLength) {
+        byte[] addr = null;
+        addr = InetAddresses.forString(strAddress).getAddress();
+
+        if (addr == null || addr.length != MAX_BYTES ||
+                prefixLength < 0 || prefixLength > MAX_BYTES * Byte.SIZE) {
+            throw new IllegalArgumentException();
+        }
+
+        address = canonicalizeAddress(addr, prefixLength);
+        this.prefixLength = prefixLength;
+
+        try {
+            inetAddress = InetAddress.getByAddress(address);
+        } catch (UnknownHostException e) {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    private byte[] canonicalizeAddress(byte[] address, int prefixLength) {
+        byte[] result = new byte[address.length];
+
+        if (prefixLength == 0) {
+            for (int i = 0; i < MAX_BYTES; i++) {
+                result[i] = 0;
+            }
+
+            return result;
+        }
+
+        result = Arrays.copyOf(address, address.length);
+
+        //Set all bytes after the end of the prefix to 0
+        int lastByteIndex = (prefixLength - 1) / Byte.SIZE;
+        for (int i = lastByteIndex; i < MAX_BYTES; i++) {
+            result[i] = 0;
+        }
+
+        byte lastByte = address[lastByteIndex];
+        byte mask = 0;
+        byte msb = (byte) 0x80;
+        int lastBit = (prefixLength - 1) % Byte.SIZE;
+        for (int i = 0; i < Byte.SIZE; i++) {
+            if (i <= lastBit) {
+                mask |= (msb >> i);
+            }
+        }
+
+        result[lastByteIndex] = (byte) (lastByte & mask);
+
+        return result;
+    }
+
+    public int getPrefixLength() {
+        return prefixLength;
+    }
+
+    public byte[] getAddress() {
+        return address;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other == null || !(other instanceof Prefix)) {
+            return false;
+        }
+
+        Prefix otherPrefix = (Prefix) other;
+
+        return (Arrays.equals(address, otherPrefix.address)) &&
+                (prefixLength == otherPrefix.prefixLength);
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 17;
+        hash = 31 * hash + prefixLength;
+        hash = 31 * hash + Arrays.hashCode(address);
+        return hash;
+    }
+
+    @Override
+    public String toString() {
+        return inetAddress.getHostAddress() + "/" + prefixLength;
+    }
+
+    public String printAsBits() {
+        String result = "";
+        for (int i = 0; i < address.length; i++) {
+            byte b = address[i];
+            for (int j = 0; j < Byte.SIZE; j++) {
+                byte mask = (byte) (0x80 >>> j);
+                result += ((b & mask) == 0) ? "0" : "1";
+                if (i * Byte.SIZE + j == prefixLength - 1) {
+                    return result;
+                }
+            }
+            result += " ";
+        }
+        return result.substring(0, result.length() - 1);
+    }
 }
