diff --git a/Controller.java b/Controller.java
index cbfe8fc675d7cd8ff4be73649f240802f640df6a..89530607ca938c373a739e0fa430f3862b1ca7ed 100644
--- a/Controller.java
+++ b/Controller.java
@@ -203,6 +203,7 @@ public class Controller {
 		}
 		
 		protected void runRebalance() {
+			System.out.println("About to start a rebalance...");
 			synchronized(rebalanceLock) {
 				try {
 					rebalanceLock.waitForFinish();
@@ -309,8 +310,8 @@ public class Controller {
 				IndexEntry entryf = entry;
 				new Thread(() -> {
 					try {
-						String[] receivedMessage = dstores.get(thisStore).receive(Protocol.STORE_ACK_TOKEN + " " + filename).split(" ");
-						if(receivedMessage[0].equals(Protocol.STORE_ACK_TOKEN)) {
+						String receivedMessage = dstores.get(thisStore).receive(Protocol.STORE_ACK_TOKEN + " " + filename);
+						if(receivedMessage != null) {
 							try {
 								storeAck(thisStore, entryf, latch);
 							}
@@ -322,7 +323,7 @@ public class Controller {
 						}
 						else {
 							//Log error
-							System.err.println("Dstore " + thisStore + " should have sent STORE_ACK but Controller received " + receivedMessage[0]);
+							System.err.println("Dstore " + thisStore + " timed out receiving STORE_ACK");
 						}
 					}
 					catch(DstoreDisconnectException e) {
@@ -461,14 +462,14 @@ public class Controller {
 				Integer dstore = it.next();
 				new Thread(() -> {
 					try {
-						String[] message = dstores.get(dstore).sendAndReceive(Protocol.REMOVE_TOKEN + " " + filename, Protocol.REMOVE_ACK_TOKEN + " " + filename, Protocol.ERROR_FILE_DOES_NOT_EXIST_TOKEN).split(" ");
-						if((message[0].equals(Protocol.REMOVE_ACK_TOKEN) && message[1].equals(filename)) || message[0].equals(Protocol.ERROR_FILE_DOES_NOT_EXIST_TOKEN)) {
+						String message = dstores.get(dstore).sendAndReceive(Protocol.REMOVE_TOKEN + " " + filename, Protocol.REMOVE_ACK_TOKEN + " " + filename, Protocol.ERROR_FILE_DOES_NOT_EXIST_TOKEN);
+						if(message != null) {
 							entry.removeStoredBy(dstore.intValue());
 							latch.countDown();
 						}
 						else {
 							//Log error
-							System.err.println("Dstore " + dstore + " should have sent REMOVE_ACK but Controller received " + message[0]);
+							System.err.println("Dstore " + dstore + " timed out receiving REMOVE_ACK");
 						}
 					}
 					catch(DstoreDisconnectException e) {
@@ -534,16 +535,23 @@ public class Controller {
 	}
 	
 	void rebalance() throws Exception {
-		Map<Integer,List<String>> dstoreFiles = new HashMap<Integer,List<String>>();
+		Map<Integer,List<String>> dstoreFilesR = new HashMap<Integer,List<String>>();
 		CountDownLatch listLatch = new CountDownLatch(dstores.size());
+		boolean locked = false;
 		try {
 			//Send LIST message to each Dstore and receive their file list
 			List<Thread> activeThreads = new ArrayList<Thread>();
 			for(Integer dstore : dstores.keySet()) {
 				Thread thisThread = new Thread(() -> {
 					try {
-						String[] message = dstores.get(dstore).sendAndReceive(Protocol.LIST_TOKEN).split(" ");
-						receiveDstoreList(dstore.intValue(), message, dstoreFiles, listLatch);
+						//String[] message = dstores.get(dstore).sendAndReceive(Protocol.LIST_TOKEN).split(" ");
+						String message = dstores.get(dstore).sendAndReceive(Protocol.LIST_TOKEN);
+						if(message != null) {
+							receiveDstoreList(dstore.intValue(), message, dstoreFilesR, listLatch);
+						}
+						else {
+							System.err.println("Dstore " + dstore + " timed out receiving file list");
+						}
 					}
 					catch(DstoreDisconnectException e) {
 						e.printStackTrace();
@@ -556,19 +564,22 @@ public class Controller {
 				activeThreads.add(thisThread);
 			}
 			
+			Map<Integer,List<String>> dstoreFiles = null;
 			try {
-				if(!listLatch.await(timeout, TimeUnit.MILLISECONDS)) {
-					//Log error
-					System.err.println("Not all file lists have been received");
-					for(Thread t : activeThreads) {
-						t.interrupt();
-					}
-					synchronized(dstoreFiles) {
+				boolean allReceived = listLatch.await(timeout, TimeUnit.MILLISECONDS);
+				synchronized(dstoreFilesR) {
+					if(!allReceived) {
+						//Log error
+						System.err.println("Not all file lists have been received");
 						Set<Integer> storesToRemove = new HashSet<Integer>(dstores.keySet());
-						storesToRemove.removeAll(dstoreFiles.keySet());
+						storesToRemove.removeAll(dstoreFilesR.keySet());
 						for(Integer dstore : storesToRemove) {
 							removeDstore(dstores.get(dstore).getDisconnectData());
 						}
+						dstoreFiles = new HashMap<Integer,List<String>>(dstoreFilesR);
+					}
+					else {
+						dstoreFiles = dstoreFilesR;
 					}
 				}
 			}
@@ -584,9 +595,9 @@ public class Controller {
 					try {
 						DstoreConnection connection = dstores.get(dstore);
 						String returnMessage = connection.sendAndReceive(sendIndex.get(dstore), Protocol.REBALANCE_COMPLETE_TOKEN);
-						if(!returnMessage.equals(Protocol.REBALANCE_COMPLETE_TOKEN)) {
+						if(returnMessage == null) {
 							//Log error
-							System.out.println("Dstore " + dstore + " should have sent REBALANCE_COMPLETE but Controller received " + returnMessage);
+							System.out.println("Dstore " + dstore + " timed out receiving REBALANCE_COMPLETE");
 						}
 						
 						latch.countDown();
@@ -621,10 +632,10 @@ public class Controller {
 		}
 	}
 	
-	void receiveDstoreList(int port, String[] list, Map<Integer,List<String>> dstoreFiles, CountDownLatch latch) {
+	void receiveDstoreList(int port, String list, Map<Integer,List<String>> dstoreFiles, CountDownLatch latch) {
 		List<String> toList = new ArrayList<String>();
-		if(!list[0].equals("ERROR_EMPTY")) {
-			for(String file : list) {
+		if(!list.equals("")) {
+			for(String file : list.split(" ")) {
 				toList.add(file);
 			}
 		}
diff --git a/DeadStoreException.java b/DeadStoreException.java
index 7520f8920b15db96c9a10d087a200340ef233418..a749e17d5806d71caacb0376e87f0315af4f635f 100644
--- a/DeadStoreException.java
+++ b/DeadStoreException.java
@@ -1,6 +1,10 @@
 import java.lang.Throwable;
 import java.net.Socket;
 
+/*
+DeadStoreException is used when a process tries to send/receive to a store which is already known to be crashed
+This is done so that the controller knows that a store is already being removed
+*/
 public class DeadStoreException extends Exception {
 	DstoreConnection connection;
 	
diff --git a/Dstore.java b/Dstore.java
index 44a1bbc5c5d1d6cfb9a8899e4d4384a3267c11e7..7b01d72634790923213b9abeef751fc06f65ebab 100644
--- a/Dstore.java
+++ b/Dstore.java
@@ -265,7 +265,6 @@ public class Dstore {
 			for(File file : fileFolder.listFiles()) {
 				message = message + " " + file.getName();
 			}
-			if(message.equals("")) message = "ERROR_EMPTY";
 			synchronized(controllerOut) {
 				controllerOut.println(message.trim());
 			}
diff --git a/DstoreConnection.java b/DstoreConnection.java
index 134280e11d7e53e240594a360c8385582f465091..d7105e5545914cbfbd3c6fe24bb7bf37c16e77f1 100644
--- a/DstoreConnection.java
+++ b/DstoreConnection.java
@@ -7,7 +7,9 @@ import java.util.ArrayList;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Iterator;
+import java.util.Arrays;
 
 public class DstoreConnection {
 	protected final int MAX_QUEUE_SIZE = 50;
@@ -17,18 +19,23 @@ public class DstoreConnection {
 	protected BufferedReader reader;
 	protected PrintWriter writer;
 	protected boolean available;
+	protected boolean disconnectThrown;
 	protected List<String> queue;
+	protected final List<String> TOKENS;
 	protected int timeout;
 	
 	public DstoreConnection(Socket socket, int port, int timeout) {
 		this.socket = socket;
 		this.port = port;
 		this.timeout = timeout;
+		TOKENS = Arrays.asList(Protocol.ACK_TOKEN, Protocol.STORE_ACK_TOKEN, Protocol.REMOVE_ACK_TOKEN, Protocol.JOIN_TOKEN, Protocol.REBALANCE_STORE_TOKEN, Protocol.REBALANCE_COMPLETE_TOKEN);
 		try {
 			reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
-			writer = new PrintWriter(socket.getOutputStream());
+			writer = new PrintWriter(socket.getOutputStream(), true);
 			available = true;
+			disconnectThrown = false;
 			queue = new ArrayList<String>();
+			new Thread(new Receiver()).start();
 		}
 		catch(IOException e) {
 			e.printStackTrace();
@@ -52,10 +59,112 @@ public class DstoreConnection {
 		return new DstoreDisconnectException(this);
 	}
 	
-	public void checkAvailable() throws DeadStoreException {
-		if(!available) throw new DeadStoreException(this);
+	public void checkAvailable() throws DeadStoreException, DstoreDisconnectException {
+		if(!available) {
+			if(!disconnectThrown) {
+				disconnectThrown = true;
+				throw getDisconnectData();
+			}
+			else {
+				throw new DeadStoreException(this);
+			}
+		}
+	}
+	
+	protected void enqueue(String message) {
+		synchronized(queue) {
+			queue.add(0, message);
+			if(queue.size() > MAX_QUEUE_SIZE) queue.remove(queue.size() - 1);
+		}
+	}
+	
+	//Check the queue for the message before trying to receive any new messages
+	protected String checkQueue(String[] expectedMessages) {
+		Iterator<String> it;
+		synchronized(queue) {
+			it = queue.iterator();
+		}
+		
+		try {
+			while(it.hasNext()) {
+				String message = it.next();
+				if(isExpected(message, expectedMessages)) {
+					synchronized(queue) {it.remove();}
+					return message;
+				}
+			}
+		}
+		catch(Exception e) {}
+		
+		return null;
+	}
+	
+	protected boolean isExpected(String message, String[] expectedMessages) {
+		if(expectedMessages.length == 0) {
+			return !TOKENS.contains(message);
+		}
+		else {
+			for(String s : expectedMessages) {
+				if(s.equals(message)) return true;
+			}
+		}
+		
+		return false;
+	}
+	
+	protected class Receiver implements Runnable {
+		public void run() {
+			while(available) {
+				String message = null;
+				try {
+					message = reader.readLine();
+					ControllerLogger.getInstance().messageReceived(socket, message);
+				}
+				catch(IOException e) {e.printStackTrace();}
+				if(message == null) {
+					//Disconnect
+					available = false;
+				}
+				else {
+					enqueue(message);
+				}
+			}
+		}
 	}
 	
+	public String sendAndReceive(String message, String... expectedMessages) throws DstoreDisconnectException, DeadStoreException {
+		synchronized(writer) {
+			checkAvailable();
+			writer.println(message);
+			ControllerLogger.getInstance().messageSent(socket, message);
+		}
+		return receive(expectedMessages);
+	}
+	
+	public String receive(String... expectedMessages) throws DstoreDisconnectException, DeadStoreException {
+		class Timer implements Runnable {
+			public boolean terminated = false;
+			
+			public void run() {
+				try {
+					synchronized(this) {this.wait(timeout);}
+				}
+				catch(InterruptedException e) {}
+				terminated = true;
+			}
+		}
+		
+		String receivedMessage = null;
+		Timer timer = new Timer();
+		new Thread(timer).start();
+		while(receivedMessage == null && !timer.terminated) {
+			checkAvailable();
+			receivedMessage = checkQueue(expectedMessages);
+		}
+		return receivedMessage;
+	}
+	
+	/*
 	public String sendAndReceive(String message, String... expectedMessages) throws DstoreDisconnectException, DeadStoreException {
 		System.out.println("Getting lock...");
 		synchronized(this) {
@@ -118,8 +227,9 @@ public class DstoreConnection {
 	}
 	
 	protected String localReceive(String[] expectedMessages) throws DstoreDisconnectException {
+		ReceiveContext rc = null;
 		try {
-			ReceiveContext rc = new ReceiveContext(expectedMessages);
+			rc = new ReceiveContext(expectedMessages);
 			rc.start();
 			if(rc.latch.await(timeout, TimeUnit.MILLISECONDS)) {
 				if(rc.disconnected()) throw getDisconnectData();
@@ -131,7 +241,7 @@ public class DstoreConnection {
 			}
 		}
 		catch(InterruptedException e) {
-			e.printStackTrace();
+			if(rc != null) rc.end();
 		}
 		
 		return "";
@@ -143,47 +253,55 @@ public class DstoreConnection {
 		}
 		return false;
 	}
+	*/
 	
+	/*
 	//Seperate class for enabling timeouts while receiving messages
 	protected class ReceiveContext {
 		protected String[] expectedMessages;
+		protected String currentMessage;
 		protected String returnMessage;
 		protected Thread thread;
+		protected Body runnable;
 		protected boolean disconnected;
 		public CountDownLatch latch;
 		
 		public ReceiveContext(String[] expectedMessages) {
 			this.expectedMessages = expectedMessages;
+			currentMessage = null;
 			returnMessage = "";
 			disconnected = false;
 			latch = new CountDownLatch(1);
 		}
 		
-		public String getReturnMessage() {
-			return returnMessage;
-		}
-		
-		public void start() {
-			thread = new Thread(() -> {
+		public class Body implements Runnable {
+			public boolean active = true;
+				
+			public void run() {
 				try {
-					String message = null;
 					do {
-						message = reader.readLine();
-						if(message == null) {
+						while(!reader.ready() && active) {}
+						if(!active) return;
+						currentMessage = reader.readLine();
+						if(currentMessage == null) {
 							available = false;
 							disconnected = true;
 							break;
 						}
-						ControllerLogger.getInstance().messageReceived(socket, message);
-						if(expectedMessages.length > 0 && !isExpected(message, expectedMessages)) {
-							queue.add(message);
-							if(queue.size() > MAX_QUEUE_SIZE) queue.remove(0);
-							message = null;
+						ControllerLogger.getInstance().messageReceived(socket, currentMessage);
+						if(expectedMessages.length > 0 && !isExpected(currentMessage, expectedMessages)) {
+							enqueue();
 						}
 					}
-					while(message == null);
+					while(currentMessage == null && active);
 					//System.out.println("Controller received " + message + " from port " + port);
-					returnMessage = message;
+					returnMessage = currentMessage;
+				}
+				catch(SocketException e) {
+					System.err.println("Trying to receive messages from " + port + " but socket is closed");
+					available = false;
+					disconnected = true;
+					returnMessage = "";
 				}
 				catch(IOException e) {
 					e.printStackTrace();
@@ -192,14 +310,32 @@ public class DstoreConnection {
 				finally {
 					latch.countDown();
 				}
-			});
+			}
+			
+			protected void enqueue() {
+				queue.add(currentMessage);
+				if(queue.size() > MAX_QUEUE_SIZE) queue.remove(0);
+				currentMessage = null;
+			}
+		}
+			
+		public String getReturnMessage() {
+			return returnMessage;
+		}
+		
+		public void start() {
+			runnable = new Body();
+			thread = new Thread(runnable);
 			thread.start();
 		}
 		
 		public void end() {
 			if(thread.isAlive()) {
 				thread.interrupt();
-				System.err.println("Controller read timed out");
+				runnable.active = false;
+			}
+			if(currentMessage != null) {
+				queue.add(currentMessage);
 			}
 		}
 		
@@ -207,4 +343,5 @@ public class DstoreConnection {
 			return disconnected;
 		}
 	}
+	*/
 }
diff --git a/DstoreDisconnectException.java b/DstoreDisconnectException.java
index e720122bceb9d00117fc3197c7194b727d0635c0..76e55f2c419e81cd2c2be3e53d74e88bd0a2d1f9 100644
--- a/DstoreDisconnectException.java
+++ b/DstoreDisconnectException.java
@@ -1,6 +1,9 @@
 import java.lang.Throwable;
 import java.net.Socket;
 
+/*
+DstoreDisconnectException is thrown by the DstoreConnection class when a dstore's output stream is null
+*/
 public class DstoreDisconnectException extends Exception {
 	DstoreConnection connection;
 	
diff --git a/ExecuteWithCrash.sh b/ExecuteWithCrash.sh
index 78066640c7a05599854a10d4191415bc9b990e7b..4e2f72c4a3a51c5dd1319b258d18427bbe9f536c 100755
--- a/ExecuteWithCrash.sh
+++ b/ExecuteWithCrash.sh
@@ -18,3 +18,4 @@ sleep $(((2*$4)/3000))
 kill ${processes[0]}
 sleep 2
 java -cp .:loggers Dstore 8081 8080 $3 store1 &
+java -cp .:client-1.0.2.jar ClientMain 8080 $3
diff --git a/RebalanceLock.java b/RebalanceLock.java
index effa59d838121bc0c330378e92421467fc72e02a..9d79247c8ea8beb5bfea99b2f927844a27d9abfe 100644
--- a/RebalanceLock.java
+++ b/RebalanceLock.java
@@ -35,10 +35,12 @@ public class RebalanceLock {
 		while(processes > 0) {
 			highPriorityWait = true;
 			try {
+				System.out.println("Waiting for all processes to finish...");
 				this.wait();
 			}
 			catch(InterruptedException e) {e.printStackTrace();}
 		}
+		System.out.println("All processes have finished!");
 		highPriorityWait = false;
 	}
 	
@@ -51,10 +53,8 @@ public class RebalanceLock {
 	public boolean waitToRebalance() {
 		try {
 			boolean dstoreJoined = periodBlock.await(rebalancePeriod, TimeUnit.MILLISECONDS);
-			if(dstoreJoined) {
-				synchronized(blockLock) {
-					periodBlock = new CountDownLatch(1);
-				}
+			synchronized(blockLock) {
+				periodBlock = new CountDownLatch(1);
 			}
 			return dstoreJoined;
 		}
diff --git a/error.txt b/error.txt
index c0e41ea4fef346e83901d561aebe4dca4537e2b4..a5997eaf47a252fe8ab1e850ede43fd2c5b0d39e 100644
--- a/error.txt
+++ b/error.txt
@@ -1,413 +1,210 @@
-FileAlreadyExistsException: Error trying to store file Look_Away.mp3 - file already exists
+FileAlreadyExistsException: Error trying to store file Grandad.txt - file already exists
 	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-FileAlreadyExistsException: Error trying to store file Look_Away.mp3 - file already exists
+FileAlreadyExistsException: Error trying to store file Grandad.txt - file already exists
 	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-FileAlreadyExistsException: Error trying to store file rap.mp3 - file already exists
+FileAlreadyExistsException: Error trying to store file Grandad.txt - file already exists
 	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-FileAlreadyExistsException: Error trying to store file AllStar.txt - file already exists
+FileAlreadyExistsException: Error trying to store file Look_Away.mp3 - file already exists
 	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-FileAlreadyExistsException: Error trying to store file rap.mp3 - file already exists
+FileAlreadyExistsException: Error trying to store file GameDotCom.jpg - file already exists
 	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-FileAlreadyExistsException: Error trying to store file PumpkinHill.txt - file already exists
+FileAlreadyExistsException: Error trying to store file rap.mp3 - file already exists
 	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-FileAlreadyExistsException: Error trying to store file Look_Away.mp3 - file already exists
+FileAlreadyExistsException: Error trying to store file rap.mp3 - file already exists
 	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-FileAlreadyExistsException: Error trying to store file PumpkinHill.txt - file already exists
+FileAlreadyExistsException: Error trying to store file Grandad.txt - file already exists
 	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-FileAlreadyExistsException: Error trying to store file PumpkinHill.txt - file already exists
+FileAlreadyExistsException: Error trying to store file rap.mp3 - file already exists
 	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-FileAlreadyExistsException: Error trying to store file GameDotCom.jpg - file already exists
+FileAlreadyExistsException: Error trying to store file AllStar.txt - file already exists
 	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-FileAlreadyExistsException: Error trying to store file PumpkinHill.txt - file already exists
+FileAlreadyExistsException: Error trying to store file spurk.jpg - file already exists
 	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-FileAlreadyExistsException: Error trying to store file rap.mp3 - file already exists
+FileAlreadyExistsException: Error trying to store file PumpkinHill.txt - file already exists
 	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-FileAlreadyExistsException: Error trying to store file rap.mp3 - file already exists
+FileAlreadyExistsException: Error trying to store file PumpkinHill.txt - file already exists
 	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-FileAlreadyExistsException: Error trying to store file PumpkinHill.txt - file already exists
+FileAlreadyExistsException: Error trying to store file Unknown.txt - file already exists
 	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-DstoreDisconnectException: Dstore at port 8081 has been disconnected
-	at DstoreConnection.getDisconnectData(DstoreConnection.java:52)
-	at DstoreConnection.localReceive(DstoreConnection.java:125)
-	at DstoreConnection.receive(DstoreConnection.java:96)
-	at Controller.lambda$store$1(Controller.java:312)
-	at java.base/java.lang.Thread.run(Thread.java:832)
-Store for Unknown.txt failed due to dead dstore
-Store for rap.mp3 failed due to dead dstore
-Store for GameDotCom.jpg failed due to dead dstore
-Store for PumpkinHill.txt failed due to dead dstore
-Store for SnowHalation.txt failed due to dead dstore
-Store for AllStar.txt failed due to dead dstore
-Store for Grandad.txt failed due to dead dstore
-Not all STORE_ACKs have been received
-Not all STORE_ACKs have been received
-Not all STORE_ACKs have been received
-Not all STORE_ACKs have been received
-Not all STORE_ACKs have been received
-Not all STORE_ACKs have been received
-Not all STORE_ACKs have been received
-Not all STORE_ACKs have been received
-java.net.SocketTimeoutException: Read timed out
-	at java.base/sun.nio.ch.NioSocketImpl.timedRead(NioSocketImpl.java:283)
-	at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:309)
-	at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
-	at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
-	at java.base/java.net.Socket$SocketInputStream.read(Socket.java:982)
-	at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:297)
-	at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
-	at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:188)
-	at java.base/java.io.InputStreamReader.read(InputStreamReader.java:181)
-	at java.base/java.io.BufferedReader.fill(BufferedReader.java:161)
-	at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326)
-	at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392)
-	at Client.store(SourceFile:239)
-	at Client.store(SourceFile:156)
-	at ClientMain.test2Client(ClientMain.java:44)
-	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.a(SourceFile:280)
+FileAlreadyExistsException: Error trying to store file spurk.jpg - file already exists
+	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.list(SourceFile:107)
-	at ClientMain.list(ClientMain.java:113)
-	at ClientMain.test2Client(ClientMain.java:52)
-	at ClientMain$1.run(ClientMain.java:26)
-Exception in thread "Thread-0" java.lang.NullPointerException
-	at ClientMain.test2Client(ClientMain.java:54)
-	at ClientMain$1.run(ClientMain.java:26)
-java.net.SocketTimeoutException: Read timed out
-	at java.base/sun.nio.ch.NioSocketImpl.timedRead(NioSocketImpl.java:283)
-	at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:309)
-	at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
-	at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
-	at java.base/java.net.Socket$SocketInputStream.read(Socket.java:982)
-	at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:297)
-	at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
-	at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:188)
-	at java.base/java.io.InputStreamReader.read(InputStreamReader.java:181)
-	at java.base/java.io.BufferedReader.fill(BufferedReader.java:161)
-	at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326)
-	at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392)
-	at Client.store(SourceFile:239)
-	at Client.store(SourceFile:156)
-	at ClientMain.test2Client(ClientMain.java:44)
-	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.a(SourceFile:280)
+FileAlreadyExistsException: Error trying to store file GameDotCom.jpg - file already exists
+	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.a(SourceFile:280)
+FileAlreadyExistsException: Error trying to store file Grandad.txt - file already exists
+	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.list(SourceFile:107)
-	at ClientMain.list(ClientMain.java:113)
-	at ClientMain.test2Client(ClientMain.java:52)
-	at ClientMain$1.run(ClientMain.java:26)
-Exception in thread "Thread-2" java.lang.NullPointerException
-	at ClientMain.test2Client(ClientMain.java:54)
-	at ClientMain$1.run(ClientMain.java:26)
-java.net.SocketTimeoutException: Read timed out
-	at java.base/sun.nio.ch.NioSocketImpl.timedRead(NioSocketImpl.java:283)
-	at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:309)
-	at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
-	at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
-	at java.base/java.net.Socket$SocketInputStream.read(Socket.java:982)
-	at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:297)
-	at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
-	at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:188)
-	at java.base/java.io.InputStreamReader.read(InputStreamReader.java:181)
-	at java.base/java.io.BufferedReader.fill(BufferedReader.java:161)
-	at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326)
-	at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392)
-	at Client.store(SourceFile:239)
-	at Client.store(SourceFile:156)
-	at ClientMain.test2Client(ClientMain.java:44)
-	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.a(SourceFile:280)
+FileAlreadyExistsException: Error trying to store file PumpkinHill.txt - file already exists
+	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.a(SourceFile:280)
+FileAlreadyExistsException: Error trying to store file AllStar.txt - file already exists
+	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.a(SourceFile:280)
+FileAlreadyExistsException: Error trying to store file PumpkinHill.txt - file already exists
+	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.list(SourceFile:107)
-	at ClientMain.list(ClientMain.java:113)
-	at ClientMain.test2Client(ClientMain.java:52)
-	at ClientMain$1.run(ClientMain.java:26)
-Exception in thread "Thread-9" java.lang.NullPointerException
-	at ClientMain.test2Client(ClientMain.java:54)
-	at ClientMain$1.run(ClientMain.java:26)
-java.net.SocketTimeoutException: Read timed out
-	at java.base/sun.nio.ch.NioSocketImpl.timedRead(NioSocketImpl.java:283)
-	at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:309)
-	at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
-	at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
-	at java.base/java.net.Socket$SocketInputStream.read(Socket.java:982)
-	at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:297)
-	at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
-	at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:188)
-	at java.base/java.io.InputStreamReader.read(InputStreamReader.java:181)
-	at java.base/java.io.BufferedReader.fill(BufferedReader.java:161)
-	at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326)
-	at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392)
-	at Client.store(SourceFile:239)
-	at Client.store(SourceFile:156)
-	at ClientMain.test2Client(ClientMain.java:44)
-	at ClientMain$1.run(ClientMain.java:26)
-java.net.SocketTimeoutException: Read timed out
-	at java.base/sun.nio.ch.NioSocketImpl.timedRead(NioSocketImpl.java:283)
-	at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:309)
-	at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
-	at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
-	at java.base/java.net.Socket$SocketInputStream.read(Socket.java:982)
-	at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:297)
-	at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
-	at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:188)
-	at java.base/java.io.InputStreamReader.read(InputStreamReader.java:181)
-	at java.base/java.io.BufferedReader.fill(BufferedReader.java:161)
-	at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326)
-	at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392)
-	at Client.store(SourceFile:239)
-	at Client.store(SourceFile:156)
-	at ClientMain.test2Client(ClientMain.java:44)
-	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.a(SourceFile:280)
+FileAlreadyExistsException: Error trying to store file GameDotCom.jpg - file already exists
+	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.a(SourceFile:280)
+FileAlreadyExistsException: Error trying to store file spurk.jpg - file already exists
+	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.a(SourceFile:280)
+FileAlreadyExistsException: Error trying to store file spurk.jpg - file already exists
+	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.list(SourceFile:107)
-	at ClientMain.list(ClientMain.java:113)
-	at ClientMain.test2Client(ClientMain.java:52)
-	at ClientMain$1.run(ClientMain.java:26)
-Exception in thread "Thread-3" java.lang.NullPointerException
-	at ClientMain.test2Client(ClientMain.java:54)
-	at ClientMain$1.run(ClientMain.java:26)
-java.net.SocketTimeoutException: Read timed out
-	at java.base/sun.nio.ch.NioSocketImpl.timedRead(NioSocketImpl.java:283)
-	at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:309)
-	at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
-	at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
-	at java.base/java.net.Socket$SocketInputStream.read(Socket.java:982)
-	at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:297)
-	at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
-	at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:188)
-	at java.base/java.io.InputStreamReader.read(InputStreamReader.java:181)
-	at java.base/java.io.BufferedReader.fill(BufferedReader.java:161)
-	at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326)
-	at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392)
-	at Client.store(SourceFile:239)
-	at Client.store(SourceFile:156)
-	at ClientMain.test2Client(ClientMain.java:44)
-	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.a(SourceFile:280)
+FileAlreadyExistsException: Error trying to store file AllStar.txt - file already exists
+	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.list(SourceFile:107)
-	at ClientMain.list(ClientMain.java:113)
-	at ClientMain.test2Client(ClientMain.java:52)
-	at ClientMain$1.run(ClientMain.java:26)
-Exception in thread "Thread-6" java.lang.NullPointerException
-	at ClientMain.test2Client(ClientMain.java:54)
-	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.a(SourceFile:280)
+FileAlreadyExistsException: Error trying to store file GameDotCom.jpg - file already exists
+	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.a(SourceFile:280)
+FileAlreadyExistsException: Error trying to store file GameDotCom.jpg - file already exists
+	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.a(SourceFile:280)
+FileAlreadyExistsException: Error trying to store file Unknown.txt - file already exists
+	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.list(SourceFile:107)
-	at ClientMain.list(ClientMain.java:113)
-	at ClientMain.test2Client(ClientMain.java:52)
-	at ClientMain$1.run(ClientMain.java:26)
-Exception in thread "Thread-4" java.lang.NullPointerException
-	at ClientMain.test2Client(ClientMain.java:54)
-	at ClientMain$1.run(ClientMain.java:26)
-java.net.SocketTimeoutException: Read timed out
-	at java.base/sun.nio.ch.NioSocketImpl.timedRead(NioSocketImpl.java:283)
-	at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:309)
-	at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
-	at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
-	at java.base/java.net.Socket$SocketInputStream.read(Socket.java:982)
-	at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:297)
-	at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
-	at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:188)
-	at java.base/java.io.InputStreamReader.read(InputStreamReader.java:181)
-	at java.base/java.io.BufferedReader.fill(BufferedReader.java:161)
-	at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326)
-	at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392)
-	at Client.store(SourceFile:239)
-	at Client.store(SourceFile:156)
-	at ClientMain.test2Client(ClientMain.java:44)
-	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.a(SourceFile:280)
+FileAlreadyExistsException: Error trying to store file AllStar.txt - file already exists
+	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-java.net.SocketTimeoutException: Read timed out
-	at java.base/sun.nio.ch.NioSocketImpl.timedRead(NioSocketImpl.java:283)
-	at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:309)
-	at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
-	at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
-	at java.base/java.net.Socket$SocketInputStream.read(Socket.java:982)
-	at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:297)
-	at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
-	at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:188)
-	at java.base/java.io.InputStreamReader.read(InputStreamReader.java:181)
-	at java.base/java.io.BufferedReader.fill(BufferedReader.java:161)
-	at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326)
-	at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392)
-	at Client.store(SourceFile:239)
-	at Client.store(SourceFile:156)
-	at ClientMain.test2Client(ClientMain.java:44)
+FileDoesNotExistException: Error trying to load or remove file PumpkinHill.txt - file does not exist
+	at Client.remove(SourceFile:505)
+	at ClientMain.test2Client(ClientMain.java:57)
 	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.a(SourceFile:280)
+FileAlreadyExistsException: Error trying to store file rap.mp3 - file already exists
+	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.a(SourceFile:280)
+FileAlreadyExistsException: Error trying to store file Unknown.txt - file already exists
+	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.list(SourceFile:107)
-	at ClientMain.list(ClientMain.java:113)
-	at ClientMain.test2Client(ClientMain.java:52)
+FileDoesNotExistException: Error trying to load or remove file spurk.jpg - file does not exist
+	at Client.remove(SourceFile:505)
+	at ClientMain.test2Client(ClientMain.java:57)
 	at ClientMain$1.run(ClientMain.java:26)
-Exception in thread "Thread-5" java.lang.NullPointerException
-	at ClientMain.test2Client(ClientMain.java:54)
-	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.a(SourceFile:280)
+FileAlreadyExistsException: Error trying to store file Look_Away.mp3 - file already exists
+	at Client.a(SourceFile:277)
 	at Client.store(SourceFile:183)
 	at Client.store(SourceFile:156)
 	at ClientMain.test2Client(ClientMain.java:44)
 	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.a(SourceFile:280)
-	at Client.store(SourceFile:183)
-	at Client.store(SourceFile:156)
-	at ClientMain.test2Client(ClientMain.java:44)
+FileDoesNotExistException: Error trying to load or remove file Look_Away.mp3 - file does not exist
+	at Client.remove(SourceFile:505)
+	at ClientMain.test2Client(ClientMain.java:57)
+	at ClientMain$1.run(ClientMain.java:26)
+FileDoesNotExistException: Error trying to load or remove file spurk.jpg - file does not exist
+	at Client.remove(SourceFile:505)
+	at ClientMain.test2Client(ClientMain.java:57)
 	at ClientMain$1.run(ClientMain.java:26)
-NotEnoughDstoresException
-	at Client.list(SourceFile:107)
-	at ClientMain.list(ClientMain.java:113)
-	at ClientMain.test2Client(ClientMain.java:52)
+FileDoesNotExistException: Error trying to load or remove file Grandad.txt - file does not exist
+	at Client.remove(SourceFile:505)
+	at ClientMain.test2Client(ClientMain.java:57)
 	at ClientMain$1.run(ClientMain.java:26)
-Exception in thread "Thread-7" java.lang.NullPointerException
-	at ClientMain.test2Client(ClientMain.java:54)
+FileDoesNotExistException: Error trying to load or remove file rap.mp3 - file does not exist
+	at Client.remove(SourceFile:505)
+	at ClientMain.test2Client(ClientMain.java:57)
 	at ClientMain$1.run(ClientMain.java:26)