diff --git a/.DS_Store b/.DS_Store
index 27bb48f7a41b5c818394b28967a19b8232757f31..9cdbe11ce06d3b7fc569d32b8facdf6f13981f65 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/os-simulator/.DS_Store b/os-simulator/.DS_Store
index 9b55c518acb39ab0a363b602e4975a9e1fab812e..ebc51b3142584b9874ae55bc3dbebb8aa97f5b22 100644
Binary files a/os-simulator/.DS_Store and b/os-simulator/.DS_Store differ
diff --git a/os-simulator/Peripherals/.DS_Store b/os-simulator/Peripherals/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..d7f1bc377f9afefab3ee5bf433cffce86f7a3d99
Binary files /dev/null and b/os-simulator/Peripherals/.DS_Store differ
diff --git a/os-simulator/Processes/New_Processes/.DS_Store b/os-simulator/Processes/_Tests/.DS_Store
similarity index 100%
rename from os-simulator/Processes/New_Processes/.DS_Store
rename to os-simulator/Processes/_Tests/.DS_Store
diff --git a/os-simulator/hardware.txt b/os-simulator/hardware.txt
new file mode 100644
index 0000000000000000000000000000000000000000..db55ffb6b8a24d3e6069978c90cf70c852aa2146
--- /dev/null
+++ b/os-simulator/hardware.txt
@@ -0,0 +1,7 @@
+1
+4
+16
+500
+printer printerBuffer o
+monitor monitorBuffer o
+keyboard keyboardBuffer i
\ No newline at end of file
diff --git a/os-simulator/src/main/java/com/com1032/assignment/CPUSimulator.java b/os-simulator/src/main/java/com/com1032/assignment/CPUSimulator.java
deleted file mode 100644
index 42cbcedde65dd980bee2606e4a679a725348faea..0000000000000000000000000000000000000000
--- a/os-simulator/src/main/java/com/com1032/assignment/CPUSimulator.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/**
- * 
- */
-package com.com1032.assignment;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author felipedabrantes
- *
- */
-public class CPUSimulator extends Thread{
-	/**Processes running on CPU.*/
-	private List<PCB> cpuQueue = new ArrayList<PCB> ();
-	
-	/**The global time of the system.*/
-	private Clock globalTime = null;
-	
-	/**The hardware to use.*/
-	private Hardware hardware = null;
-
-	
-	/**
-	 * Constructor. Initialises fields.
-	 * 
-	 * @param os
-	 * @param cpuQueue
-	 */
-	public CPUSimulator(Clock globalTime, List<PCB> cpuQueue, Hardware hardware) {
-		this.cpuQueue = cpuQueue;	
-		this.globalTime = globalTime;
-		this.hardware = hardware;
-	}
-	
-	
-	@Override
-	public void run() {
-		while(true) {
-			
-			//Temporarily stop executing for however milliseconds.
-			try {
-				Thread.sleep(50);
-			} catch (InterruptedException e) {
-				e.printStackTrace();
-			}
-			
-			//Runs process in queue.
-			this.runCode();
-		}
-	}
-	
-	public void runCode() {
-		if(!this.cpuQueue.isEmpty()) {
-			
-			if(this.cpuQueue.get(0).getState() == ProcessState.RUNNING) {
-				//The process the CPU runs.
-				PCB processRunning = this.cpuQueue.get(0);
-				
-				//Split code string into lines.
-				String[] codeLines = processRunning.getCode().split("\\r\\n|\\r|\\n");
-				
-				//Increase program counter by one to run next line.
-				processRunning.increaseProgramCounter();
-				
-				//Compile and run the program counter line.
-				this.compileLine(processRunning, codeLines[processRunning.getProgramCounter()]);
-				
-				//If not blocked, then decrease remaining time and global time by one.
-				if(processRunning.getState() != ProcessState.BLOCKED) {
-					processRunning.increaseConsecutiveTimeOnCPU();
-					processRunning.decreaseRemainingTime(1);
-					
-					//Instruction takes 4 ticks. Each core in processor decreases it by 1.
-					this.globalTime.increaseTime(5 - this.hardware.getCoresPerProcessor());
-					
-					//If all code finished, then terminate process.
-					if(processRunning.getProgramCounter() == codeLines.length - 1) {
-						processRunning.setState(ProcessState.TERMINATED);
-					}
-				}
-			}
-		}
-	}
-	
-	
-	public void compileLine(PCB processRunning, String line) {
-		
-		try {
-		
-			Map<String, Integer> variables = processRunning.getVariables();
-			
-			if(line.equals("")) {
-				return;
-			}
-	
-			String command = line.split(" ")[0];
-			
-			//STORE NAME VALUE
-			if(command.toLowerCase().equals("store")) {
-				String newVariableName = line.split(" ")[1];
-				Integer newVariableValue = 0;
-				
-				if(line.split(" ")[2].startsWith("#")) {
-					newVariableValue = Integer.valueOf(line.split(" ")[2].substring(1));
-				}
-				else {
-					Integer storedVariableValue = variables.get(line.split(" ")[2]);
-					newVariableValue = storedVariableValue;
-				}
-				
-				//Store result to new variable.
-				variables.put(newVariableName, newVariableValue);
-			
-			}
-			
-			//ADD NAME VALUE1 VALUE2
-			else if(command.toLowerCase().equals("add")) {
-				String newVariableName = line.split(" ")[1];
-				Integer newVariableValue = 0;
-				
-				//Find VALUE1.
-				if(line.split(" ")[2].startsWith("#")) {
-					newVariableValue = Integer.valueOf(line.split(" ")[2].substring(1));
-				}
-				else {
-					Integer storedVariableValue = variables.get(line.split(" ")[2]);
-					newVariableValue = storedVariableValue;
-				}
-				
-				//Add VALUE2 to VALUE1.
-				if(line.split(" ")[3].startsWith("#")) {
-					newVariableValue += Integer.valueOf(line.split(" ")[3].substring(1));
-				}
-				else {
-					Integer storedVariableValue = variables.get(line.split(" ")[3]);
-					newVariableValue += storedVariableValue;
-				}
-				
-				//Store result to new variable.
-				variables.put(newVariableName, newVariableValue);
-			}
-			
-			
-			//SUB NAME VALUE1 VALUE2
-			else if(command.toLowerCase().equals("sub")) {
-				String newVariableName = line.split(" ")[1];
-				Integer newVariableValue = 0;
-				
-				//Find VALUE1.
-				if(line.split(" ")[2].startsWith("#")) {
-					newVariableValue = Integer.valueOf(line.split(" ")[2].substring(1));
-				}
-				else {
-					Integer storedVariableValue = variables.get(line.split(" ")[2]);
-					newVariableValue = storedVariableValue;
-				}
-				
-				//Subtract VALUE1 from VALUE2.
-				if(line.split(" ")[3].startsWith("#")) {
-					newVariableValue -= Integer.valueOf(line.split(" ")[3].substring(1));
-				}
-				else {
-					Integer storedVariableValue = variables.get(line.split(" ")[3]);
-					newVariableValue -= storedVariableValue;
-				}
-				
-				//Store result to new variable.
-				variables.put(newVariableName, newVariableValue);
-			}
-			
-			
-			//PRINT VALUE
-			else if(command.toLowerCase().equals("print")) {
-				processRunning.setState(ProcessState.BLOCKED);
-			}
-		}
-		
-		catch(IndexOutOfBoundsException e) {
-			StringBuffer errorMessage = new StringBuffer();
-			errorMessage.append("Error in Line ");
-			errorMessage.append(processRunning.getProgramCounter());
-			errorMessage.append(": ");
-			errorMessage.append(processRunning);
-			processRunning.setFailed(true);
-			processRunning.setState(ProcessState.TERMINATED);
-			
-			System.out.println(errorMessage);
-		}
-		
-	}
-	
-}
diff --git a/os-simulator/src/main/java/com/com1032/assignment/IOManager.java b/os-simulator/src/main/java/com/com1032/assignment/IOManager.java
deleted file mode 100644
index b2dd8884e343a67f536550feb662d30a9f14b7c4..0000000000000000000000000000000000000000
--- a/os-simulator/src/main/java/com/com1032/assignment/IOManager.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/**
- * 
- */
-package com.com1032.assignment;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author felipedabrantes
- *
- */
-public class IOManager extends Thread {
-
-	/**Processes waiting for I/O.*/
-	private List<PCB> blockedQueue = new ArrayList<PCB> ();
-	
-	
-	/**
-	 * Constructor. Initialises fields.
-	 * 
-	 * @param globalTime
-	 * @param cores
-	 * @param readyQueue
-	 * @param blockedQueue
-	 * @param terminatedQueue
-	 */
-	public IOManager(List<PCB> blockedQueue) {
-		this.blockedQueue = blockedQueue;
-	}
-	
-	
-	@Override
-	public void run() {
-		
-		while(true) {
-			try {
-				Thread.sleep(50);
-			} catch (InterruptedException e) {
-				e.printStackTrace();
-			}
-			
-			this.runBlockedProcess();
-		}
-	}
-	
-	
-	public void runBlockedProcess() {
-//		System.out.println("IO B: " + this.blockedQueue);
-//		System.out.println("CP" + this.blockedQueue.size());
-		if(!this.blockedQueue.isEmpty()) {
-			
-			if(this.blockedQueue.get(0).getState() == ProcessState.BLOCKED) {
-				//The process the CPU runs.
-				PCB processRunning = this.blockedQueue.get(0);
-				
-				//Split code string into lines.
-				String[] codeLines = processRunning.getCode().split("\\r\\n|\\r|\\n");
-				
-				//Compile and run the program counter line.
-				this.compileLine(processRunning, codeLines[processRunning.getProgramCounter()]);
-				//Decrease expected remaining time.
-				processRunning.decreaseRemainingTime(1);
-				
-				//Reset time used on CPU.
-				processRunning.resetConsecutiveTimeOnCPU();
-				
-				//If all code finished, then terminate process.
-				if(processRunning.getProgramCounter() == codeLines.length - 1) {
-					processRunning.setState(ProcessState.TERMINATED);
-				}
-				else {
-					processRunning.increaseProgramCounter();
-					processRunning.setState(ProcessState.READY);
-				}
-			}
-		}
-	}
-	
-	
-	public void compileLine(PCB processRunning, String line) {
-		
-		try {
-			Map<String, Integer> variables = processRunning.getVariables();
-			
-			String command = line.split(" ")[0];
-			
-			//PRINT VALUE
-			if(command.toLowerCase().equals("print")) {
-				Integer variableValue = null;
-				
-				if(line.split(" ")[1].startsWith("#")) {
-					variableValue = Integer.valueOf(line.split(" ")[1].substring(1));
-				}
-				else {
-					Integer storedVariableValue = variables.get(line.split(" ")[1]);
-					variableValue = storedVariableValue;
-				}
-				
-				this.print(variableValue);
-			}
-		}
-		
-		catch(Exception e) {
-			StringBuffer errorMessage = new StringBuffer();
-			errorMessage.append("Error in Line ");
-			errorMessage.append(processRunning.getProgramCounter());
-			errorMessage.append(": ");
-			errorMessage.append(processRunning);
-			processRunning.setFailed(true);
-			processRunning.setState(ProcessState.TERMINATED);
-			
-			System.out.println(errorMessage);
-		}
-	}
-	
-	
-	public void print(int value) {
-		System.out.println(value);
-	}
-
-}
diff --git a/os-simulator/src/main/java/com/com1032/assignment/IOsystem/IOSystem.java b/os-simulator/src/main/java/com/com1032/assignment/IOsystem/IOSystem.java
new file mode 100644
index 0000000000000000000000000000000000000000..3fc30331035b4ffceb9e886a7ca1e3111d7c421a
--- /dev/null
+++ b/os-simulator/src/main/java/com/com1032/assignment/IOsystem/IOSystem.java
@@ -0,0 +1,25 @@
+package com.com1032.assignment.IOsystem;
+
+import java.io.IOException;
+
+/*  Java IO system project
+ * This is a very high level abstraction for the IO operations, without scheduling, Interrupt Handling, DMA, Caching, spooling, locking, protection, streams,  
+ * and many more functions can be added later on
+ * The project Define Buffers for the various peripherals using 
+ * Java Memory Mapped files for faster IO operations 
+ * Developed by Manal Helal for COM1032 Operating Systems Spring 2020 - Surrey University
+*/
+
+import java.util.ArrayList;
+
+public interface IOSystem {
+	ArrayList<MemoryMappedFile> peripherals = new ArrayList<MemoryMappedFile>();
+	
+	public void addDevice (String deviceName, String BufferFileName, IOType deviceType) throws IllegalArgumentException, IOException;
+	public void removeDevice(String deviceName) throws IllegalArgumentException, IOException;
+	
+	public void write(String deviceName, String inputData) throws IllegalArgumentException, IOException;
+	public String read(String deviceName, int size) throws IllegalArgumentException, IOException;
+	public void clear(String deviceName) throws IllegalArgumentException, IOException;
+	
+}
diff --git a/os-simulator/src/main/java/com/com1032/assignment/IOsystem/IOType.java b/os-simulator/src/main/java/com/com1032/assignment/IOsystem/IOType.java
new file mode 100644
index 0000000000000000000000000000000000000000..673cdc27a5625b16313764068401e950da2b19cc
--- /dev/null
+++ b/os-simulator/src/main/java/com/com1032/assignment/IOsystem/IOType.java
@@ -0,0 +1,15 @@
+/**
+ * 
+ */
+package com.com1032.assignment.IOsystem;
+
+/**
+ * @author felipedabrantes
+ *
+ */
+public enum IOType {
+	
+	INPUT,
+	OUTPUT
+	
+}
diff --git a/os-simulator/src/main/java/com/com1032/assignment/IOsystem/JavaIOSystem.java b/os-simulator/src/main/java/com/com1032/assignment/IOsystem/JavaIOSystem.java
new file mode 100644
index 0000000000000000000000000000000000000000..0a27edf872d26fe9dbeca1930dd1b273232f0fcf
--- /dev/null
+++ b/os-simulator/src/main/java/com/com1032/assignment/IOsystem/JavaIOSystem.java
@@ -0,0 +1,249 @@
+package com.com1032.assignment.IOsystem;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Scanner;
+
+
+public class JavaIOSystem implements IOSystem{
+	/**A list of peripherals stored as Memory Mapped Files.*/
+	private ArrayList<MemoryMappedFile> peripherals = new ArrayList<MemoryMappedFile>();
+	
+	
+	/**
+	 * Constructor. Initialises fields.
+	 * @throws IOException 
+	 * 
+	 * @throws IOException if there is an error accessing hardware file.
+	 * @throws IndexOutOfBoundsException if there is an error with hardware file parameters.
+	 */
+    public JavaIOSystem() throws IOException, IndexOutOfBoundsException {
+		try {
+			
+			for(File file: (new File("Peripherals/Buffers")).listFiles()) {
+				if(!file.isDirectory()) {
+					
+					file.delete();
+				}
+			}
+			
+			File file = new File("hardware.txt");
+			Scanner fileReader = new Scanner(file);
+			
+			//First four lines are internal hardware info. 
+			for(int i = 0; i < 4; i++) {
+				fileReader.nextLine();
+			}
+			
+			while(fileReader.hasNextLine()) {
+				String next = fileReader.nextLine();
+				
+				String deviceName = next.split(" ")[0];
+				String bufferFileName = next.split(" ")[1];
+				IOType deviceType;
+            	
+				
+            	if(next.split(" ")[2].toLowerCase().equals("i")) {
+            		deviceType = IOType.INPUT;
+            	}
+            	else {
+            		deviceType = IOType.OUTPUT;
+            	}
+            	
+            	this.addDevice(deviceName, bufferFileName, deviceType);
+			}
+			
+			//Closes file.
+			fileReader.close();
+		}
+		
+		catch(IOException e) {
+			throw new IOException("Error using Hardware file.");
+		}
+		catch(IndexOutOfBoundsException e) {
+			throw new IndexOutOfBoundsException("Error with Hardware file parameters.");
+		}
+    }
+    
+    
+	/**
+	 * Adds a device to the IO System.
+	 * 
+	 * Checks names are not already in system.
+	 * 
+	 * @param deviceName to add.
+	 * @param BufferFileName
+	 * 
+	 * @throws IllegalArgumentException if device info is invalid.
+	 * @throws IOException if there is an error interacting with memory file.
+	 */
+    @Override
+    public void addDevice(String deviceName, String bufferFileName, IOType deviceType) throws IllegalArgumentException, IOException {
+    	boolean error = false;
+    	
+    	for(MemoryMappedFile peripheral: this.peripherals) {
+    		if(peripheral.getDeviceName().equals(deviceName)) {
+    			error = true;
+    			throw new IllegalArgumentException("Error: Device with same name already in system.");
+    		}
+    		
+    		if(peripheral.getFileName().equals(bufferFileName)) {
+    			error = true;
+    			throw new IllegalArgumentException("Error: Buffer File with same name already in system.");
+    		}
+    	}
+    	
+    	if(error == false) {
+    		MemoryMappedFile newPeripheral = new MemoryMappedFile(deviceName, bufferFileName, deviceType);
+    		this.peripherals.add(newPeripheral);	
+    	}
+    }
+
+    
+	/**
+	 * Removes device from IO System.
+	 * 
+	 * @param deviceName to remove.
+	 * 
+	 * @throws IllegalArgumentException if device info is invalid.
+	 * @throws IOException if there is an error interacting with memory file.
+	 */
+	@Override
+	public void removeDevice(String deviceName) throws IOException {
+		boolean deviceFound = false;
+		
+		for (MemoryMappedFile peripheral: this.peripherals) {
+			if (peripheral.getDeviceName().equals(deviceName)) {
+				deviceFound = true;
+				peripheral.clear();
+				peripherals.remove(peripheral);
+				break;
+			}
+		}
+		
+		if(deviceFound == false) {
+			throw new IllegalArgumentException("Error: Device not found.");
+		}
+	}
+	
+	
+    /**
+     * Writes at the end of the given device buffer file in memory.
+     * 
+     * @param deviceName
+     * @param inputData to write.
+     * 
+	 * @throws IllegalArgumentException if device info is invalid.
+	 * @throws IOException if there is an error interacting with memory file.
+     */
+    @Override
+	public void write(String deviceName, String inputData) throws IllegalArgumentException, IOException{
+        //Turn string input data into bytes array.
+        byte[] dataArray = inputData.getBytes();
+        
+        //Turn byte[] into Byte[] for Memory Mapped Files.
+        Byte[] bytesBuffer = new Byte[dataArray.length];
+        
+        for(int i = 0; i < bytesBuffer.length; i++) {
+        	bytesBuffer[i] = dataArray[i];
+        }
+       
+        
+    	//Find the Memory Mapped File for the device and write to it.
+        boolean deviceFound = false;
+		for (MemoryMappedFile peripheral: this.peripherals) {
+			if (peripheral.getDeviceName().equals(deviceName)) {
+				deviceFound = true;
+				peripheral.write(bytesBuffer);
+			}
+		}
+		
+		if(deviceFound == false) {
+			throw new IllegalArgumentException("Error: Device " + deviceName + " not found.");
+		}
+	}
+
+    
+    /**
+     * Function to read the given device buffer file in memory.
+     * 
+     * @param deviceName
+     * @param size to read.
+     * 
+	 * @throws IllegalArgumentException if device info is invalid.
+	 * @throws IOException if there is an error interacting with memory file.
+     */
+    @Override
+	public String read(String deviceName, int size) throws IllegalArgumentException, IOException{
+		///The wanted data as a string.
+		String requiredData = null;
+		
+		//Bytes accessed from file.
+		Byte[] bytesBuffer = null;
+		
+		//Find the Memory Mapped File for the device and read from it.
+		boolean deviceFound = false;
+		for (MemoryMappedFile peripheral: this.peripherals) {
+			if (peripheral.getDeviceName().equals(deviceName)) {
+				deviceFound = true;
+				bytesBuffer = peripheral.read(size);
+			}
+		}
+		
+		if(deviceFound == false) {
+			throw new IllegalArgumentException("Error: Device " + deviceName + " not found.");
+		}
+		
+		int bytesArraySize = 0;
+		
+		for(int j = 0; j < bytesBuffer.length; j++) {
+			if(bytesBuffer[j] != 0) {
+				bytesArraySize++;
+			}
+		}
+		
+		if(bytesBuffer != null) {
+			//Turn Byte[] into byte[].
+	        byte[] bytes = new byte[bytesArraySize];
+	        
+	        for(int j = 0; j < bytesBuffer.length; j++) {
+	        	if(bytesBuffer[j] != 0) {
+	        		bytes[j] = bytesBuffer[j].byteValue();
+	        	}
+	        }
+	        
+	        requiredData = new String(bytes);
+		}
+        
+		return requiredData;
+	}
+
+
+    /**
+     * Function to clear the given device buffer file.
+     * 
+     * @param deviceName file to clear.
+     * 
+	 * @throws IllegalArgumentException if device info is invalid.
+	 * @throws IOException if there is an error interacting with memory file.
+     */
+	@Override
+	public void clear(String deviceName) throws IllegalArgumentException, IOException {
+		boolean deviceFound = false;
+		
+    	//Find the Memory Mapped File for the device and clear it.
+		for (MemoryMappedFile peripheral: this.peripherals) {
+			if (peripheral.getDeviceName().equals(deviceName)) {
+				deviceFound = true;
+				peripheral.clear();
+				break;
+			}
+		}
+		
+		if(deviceFound == false) {
+			throw new IllegalArgumentException("Error: Device " + deviceName + " not found.");
+		}
+	}
+
+}
diff --git a/os-simulator/src/main/java/com/com1032/assignment/IOsystem/MemoryMappedFile.java b/os-simulator/src/main/java/com/com1032/assignment/IOsystem/MemoryMappedFile.java
new file mode 100644
index 0000000000000000000000000000000000000000..90fe045d3d42a8134183115afdbbf10f1b1372a6
--- /dev/null
+++ b/os-simulator/src/main/java/com/com1032/assignment/IOsystem/MemoryMappedFile.java
@@ -0,0 +1,187 @@
+package com.com1032.assignment.IOsystem;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+
+public class MemoryMappedFile {
+
+	/**The peripheral name.*/
+	private String deviceName = null;
+	/**The peripheral buffer file name.*/
+	private String filename = null;
+	/**The length of data in the file*/
+	private int dataLength = 0;
+	/**Whether peripheral is input or output.*/
+	private IOType type;
+	
+	
+	private final String BUFFERS_DIRECTORY = "Peripherals/Buffers/";
+	
+	/**
+	 * Constructor. Initialises fields.
+	 * 
+	 * @param deviceName
+	 * @param filename
+	 * 
+	 * @throws IOException if there is an error interacting with memory file.
+	 * 
+	 */
+	public MemoryMappedFile (String deviceName, String filename, IOType type) throws IOException {
+		if (deviceName != null)
+			this.setDeviceName(deviceName);
+		else
+			this.setDeviceName("");
+		
+		if (filename != null)
+			this.filename = filename;
+		else
+			this.filename = "largeFile.txt";
+		
+		this.type = type;
+		this.create();
+	}
+	
+	
+	/**
+	 * Function used to write to file in memory without having to open all of file.
+	 * 
+	 * @param bytesBuffer to add to file.
+	 * 
+	 * @throws IllegalArgumentException if device does not exist.
+	 * @throws IOException if there is an error interacting with memory file.
+	 */
+	public void write(Byte[] bytesBuffer) throws IllegalArgumentException, IOException{	
+		//Checks peripheral is output type.
+		if(this.type == IOType.INPUT) {
+			throw new IllegalArgumentException("Error: Input peripheral cannot output data.");
+		}
+		
+		else {
+			//Size of data being added to file.
+			int size = bytesBuffer.length;
+			
+			RandomAccessFile memoryMappedFile;
+			try {
+				//Opens file.
+				memoryMappedFile = new RandomAccessFile(this.BUFFERS_DIRECTORY + this.filename + ".txt", "rw");
+	
+				//Lets us write to file in memory without having to access all of it.
+				MappedByteBuffer out = memoryMappedFile.getChannel().map(FileChannel.MapMode.READ_WRITE, this.dataLength, size);
+				
+				//Writing bit data Memory Mapped File
+				for (int i = 0; i < size; i++) {
+					out.put(bytesBuffer[i]);
+				}
+				
+				//Increases data length attribute by size being added to file.
+				this.dataLength += size;
+				
+				memoryMappedFile.close();
+				
+			} catch (IOException e) {
+				throw new IOException("Error using " + this.filename + ".");
+			}	
+		}
+	}
+	
+	
+	/**
+	 * Function used to read from a file in memory without having to open all of file.
+	 * 
+	 * @param size amount from file to read.
+	 * 
+	 * @return byte data.
+	 * 
+	 * @throws IllegalArgumentException if device does not exist.
+	 * @throws IOException if there is an error interacting with memory file.
+	 */
+	public Byte[] read(int size) throws IllegalArgumentException, IOException{
+		//Checks peripheral is output type.
+		if(this.type == IOType.OUTPUT) {
+			throw new IllegalArgumentException("Error: Input peripheral cannot output data.");
+		}
+		
+		//The desired byte data.
+		Byte[] wantedData = new Byte[size];
+		
+		RandomAccessFile memoryMappedFile;
+		
+		try {
+			//Open file.
+			memoryMappedFile = new RandomAccessFile(this.BUFFERS_DIRECTORY + this.filename + ".txt", "rw");
+
+			//Lets us read file in memory without having to access all of it.
+			MappedByteBuffer in = memoryMappedFile.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, size);
+			
+			//Reading from memory file.
+			for (int i = 0; i < size ; i++) {
+				wantedData[i] = in.get(i);
+			}
+			
+			memoryMappedFile.close();
+			
+		} catch (IOException e) {
+			throw new IOException("Error using " + this.filename + ".");
+		}
+		
+		return wantedData;
+	}
+
+	
+	/**
+	 * Function used to clear the file in memory without having to open all of file.
+	 * 
+	 * @throws IOException if there is an error interacting with memory file.
+	 */
+	public void clear() throws IOException {
+		//Opens file and deletes it.
+		File file = new File(this.BUFFERS_DIRECTORY + this.filename + ".txt");
+		file.delete();
+		
+		this.dataLength = 0;
+		
+		this.create();
+	}
+	
+	
+	/**
+	 * Function used to create the buffer file.
+	 * 
+	 * @throws IOException if there is an error interacting with memory file.
+	 */
+	public void create() throws IOException {
+		RandomAccessFile memoryMappedFile;
+		try {
+			//Creates file.
+			memoryMappedFile = new RandomAccessFile(this.BUFFERS_DIRECTORY + this.filename + ".txt", "rw");
+			memoryMappedFile.close();
+			
+		} catch (IOException e) {
+			throw new IOException("Error using file.");
+		}
+	}
+	
+	/**
+	 * @return the deviceName
+	 */
+	public String getDeviceName() {
+		return this.deviceName;
+	}
+
+	/**
+	 * @param deviceName to set
+	 */
+	public void setDeviceName(String deviceName) {
+		this.deviceName = deviceName;
+	}
+	
+	/**
+	 * @return the fileName
+	 */
+	public String getFileName() {
+		return this.filename;
+	}
+}
diff --git a/os-simulator/src/main/java/com/com1032/assignment/IOsystem/TestIO.java b/os-simulator/src/main/java/com/com1032/assignment/IOsystem/TestIO.java
new file mode 100644
index 0000000000000000000000000000000000000000..8c0557f0e9c738bf5f0c1ce3b9031a8660ce2b5a
--- /dev/null
+++ b/os-simulator/src/main/java/com/com1032/assignment/IOsystem/TestIO.java
@@ -0,0 +1,248 @@
+package com.com1032.assignment.IOsystem;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+/**
+ **    It can be run in two modes:
+ **        Interactive:         java TestIO 
+ **        With a test file:    java TestIO testfile    
+ **     
+ **    To get a list of supported commands, type 'help' at the command line.
+ **
+ **    The testfile consists of commands to the driver program (one per line)
+ **      as well as comments.  Comments beginning with /* will be ignored
+ **      completely by the driver.  Comments beginning with // will be echoed
+ **      to the output.  See the sample testfile for an example.
+ */
+
+public class TestIO 
+{
+    /** File System object to be used for the function calls.*/
+    private static JavaIOSystem io;
+    
+    /**Table mapping variables to values.*/
+    private static Hashtable vars = new Hashtable();
+
+    
+    /**
+     * The main method ran when running application.
+     * 
+     * @param args
+     * @throws Exception 
+     */
+    public static void main(String [] args) throws Exception{
+
+        // Check for correct number of arguments
+        if (args.length > 1) System.err.println ("Usage: TestFS [filename]");
+
+        // Is the input coming from a file
+        boolean fromFile = (args.length==1);
+
+        // Create our test fileSystem
+        io = new JavaIOSystem();
+
+        // Create a stream for input
+        BufferedReader data = null;
+
+        // Open our input stream
+        if (fromFile) {
+            try {
+                data = new BufferedReader (new FileReader(new File(args[0])));
+            }
+            catch (FileNotFoundException e) {
+                System.err.println("Error: File " + args[0] + " not found.");
+                System.exit(1);
+            }
+        }
+        else data = new BufferedReader (new InputStreamReader(System.in));
+
+        // Cycle through user or file input
+        while (true) {
+            try {
+                // Print out the prompt for the user
+                if (!fromFile) {
+                    System.out.print("--> ");
+                    System.out.flush();
+                }
+
+                // Read in a line
+                String line = data.readLine();
+                //System.out.println(line);
+
+                // Check for various conditions
+                if (line == null) System.exit(0);  // Ctrl-D check
+                line = line.trim();                // Trim off extra whitespace
+                if (line.length() == 0) {          // Is anything left?
+                    System.out.println();
+                    continue;
+                }
+
+                // Handle comments and file input
+                if (line.startsWith("//")) {
+                    if (fromFile)
+                        System.out.println(line);
+                    continue;
+                }
+                if (line.startsWith("/*")) continue;
+                if (fromFile) System.out.println("--> " + line);
+
+                // See if the command has the format of an assignment
+                String target = null;
+                int equals = line.indexOf('=');
+                if (equals > 0) {
+                    target = line.substring(0,equals).trim();
+                    line = line.substring(equals+1).trim();
+                }
+
+                // Tokenize command line
+                StringTokenizer cmds = new StringTokenizer (line);
+                String cmd = cmds.nextToken();
+
+                // Call the function that corresponds to the command
+                int result = 0;
+                if (cmd.equalsIgnoreCase("addDevice") || cmd.equalsIgnoreCase("format")) {
+                	String deviceName = cmds.nextToken();
+                	String bufferFileName = cmds.nextToken();
+                	IOType deviceType;
+                	
+                	String next = cmds.nextToken();
+                	
+                	if(next.toLowerCase().equals("i")) {
+                		deviceType = IOType.INPUT;
+                	}
+                	else if(next.toLowerCase().equals("o")) {
+                		deviceType = IOType.OUTPUT;
+                	}
+                	else {
+                		throw new IllegalArgumentException("Invalid IO Type.");
+                	}
+                	
+                	io.addDevice(deviceName, bufferFileName, deviceType);
+                	
+                	System.out.println("Added device.");
+                }
+            
+                else if (cmd.equalsIgnoreCase("read")) {
+                	String deviceName = cmds.nextToken();
+                    int size = nextValue(cmds);
+                    
+                    String wantedData = io.read(deviceName, size);
+                    
+                    System.out.println(wantedData);
+                }
+                
+                else if (cmd.equalsIgnoreCase("write")) {
+                	String inputData = "";
+                	
+                	//Access device name.
+                	String deviceName = cmds.nextToken();
+                    
+                    //Cycles all text input.
+                    while (cmds.hasMoreTokens()) {
+                    	inputData += cmds.nextToken();
+                    	
+                    	//Adds space if there is another word.
+                    	if(cmds.hasMoreTokens()) {
+                    		inputData += " ";
+                    	}
+                    }
+                    
+                    io.write(deviceName, inputData);
+                    
+                    System.out.println("Written.");
+                }
+                
+                else if (cmd.equalsIgnoreCase("clear")) {
+                	//Access device name.
+                	String deviceName = cmds.nextToken();
+                    
+                    io.clear(deviceName);
+                } 
+        
+                else if (cmd.equalsIgnoreCase("removeDevice")) {
+                    io.removeDevice(cmds.nextToken());
+                }
+                
+                else if (cmd.equalsIgnoreCase("quit")) {
+                    System.exit(0);
+                }
+                
+                else if (cmd.equalsIgnoreCase("vars")) {
+                    for (Enumeration e = vars.keys(); e.hasMoreElements(); ) {
+                        Object key = e.nextElement();
+                        Object val = vars.get(key);
+                        System.out.println("\t" + key + " = " + val);
+                    }
+                    continue;
+                }
+                
+                else if (cmd.equalsIgnoreCase("help")) {
+                    help();
+                    continue;
+                }
+                
+                else {
+                    System.out.println("Unknown command.");
+                    continue;
+                }
+                
+                // Print out the result of the function call
+                if (target != null) {
+                    vars.put(target,new Integer(result));
+                    System.out.println("    " + target + " = " + result);
+                }
+            }
+            
+            // Handler for Integer.parseInt(...)
+            catch (NumberFormatException e) {
+                System.out.println("Incorrect argument type.");
+            }
+            // Handler for nextToken()
+            catch (NoSuchElementException e) {
+                System.out.println("Incorrect number of elements.");
+            }
+            // Handler for IOType
+            catch (IllegalArgumentException e) {
+            	System.out.println(e.getMessage());
+            }
+            catch (IOException e) {
+                System.err.println(e);
+            }
+        }
+    }
+
+    
+    /** Helper function for main, to interpret a command argument */
+    static private int nextValue(StringTokenizer cmds)
+    {
+        String arg = cmds.nextToken();
+        Object val = vars.get(arg);
+        return
+            (val == null) ?  Integer.parseInt(arg) : ((Integer)val).intValue();
+    }
+
+    
+    /**
+     * Help will just print out a listing of the commands available on the system.
+     */
+    private static void help() {
+        System.out.println ("\taddDevice DeviceName DeviceBufferFileName");
+        System.out.println ("\tremoveDevice deviceName");
+        System.out.println ("\tread deviceName size");
+        System.out.println ("\twrite deviceName data1 data2 ...");
+        System.out.println ("\tclear deviceName");
+        System.out.println ("\tquit");
+        System.out.println ("\tvars");
+        System.out.println ("\thelp");
+    }
+
+}
diff --git a/os-simulator/src/main/java/com/com1032/assignment/ProcessScheduler.java b/os-simulator/src/main/java/com/com1032/assignment/ProcessScheduler.java
deleted file mode 100644
index 2706c213bdd1135531a03b6da0d76e0ce1eea102..0000000000000000000000000000000000000000
--- a/os-simulator/src/main/java/com/com1032/assignment/ProcessScheduler.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * 
- */
-package com.com1032.assignment;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author felipedabrantes
- *
- */
-public class ProcessScheduler {
-	
-	/**New processes added to the system.*/
-	private List<PCB> jobQueue = new ArrayList<PCB> ();
-	/**Processes ready to be executed.*/
-	private List<PCB> readyQueue = new ArrayList<PCB> ();
-	/**Processes waiting for I/O.*/
-	private List<PCB> blockedQueue = new ArrayList<PCB> ();
-	/**Processes that have finished executing.*/
-	private List<PCB> terminatedQueue = new ArrayList<PCB> ();
-	/**Processes running on CPU.*/
-	private List<PCB> cpuQueue = new ArrayList<PCB> ();
-	
-	/**The scheduling algorithm to use.*/
-	private SchedulingAlgorithm algorithm = SchedulingAlgorithm.FIFO;
-	
-	/**The quantum to use.*/
-	private int quantum = 0;
-	
-	/**The global time of the system.*/
-	private OS os = null;
-	
-	
-	public ProcessScheduler(OS os) {
-		this.os = os;
-	}
-	
-	
-	public void startThreads() {
-		ProcessCreation pc = new ProcessCreation(this.os.getGlobalTime(), this.jobQueue);
-		ProcessDispatcher pd = new ProcessDispatcher(this.os.getGlobalTime(), this.os.getHardware(), this.jobQueue, this.readyQueue, this.blockedQueue, this.terminatedQueue, this.cpuQueue);
-		CPUSimulator cpu = new CPUSimulator(this.os.getGlobalTime(), this.cpuQueue, this.os.getHardware());
-		IOManager io = new IOManager(this.blockedQueue);
-		
-		pd.setAlgorithm(this.algorithm, this.quantum);
-		
-		pc.start();
-		pd.start();
-		cpu.start();
-		io.start();
-	}
-	
-	
-	public void setAlgorithm(SchedulingAlgorithm algorithm, int quantum) {
-		this.algorithm = algorithm;
-		this.quantum = quantum;
-	}
-	
-	
-
-}
diff --git a/os-simulator/src/main/java/com/com1032/assignment/processscheduler/CPUSimulator.java b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/CPUSimulator.java
new file mode 100644
index 0000000000000000000000000000000000000000..189a7d2a30a8050dab7b7ec2407b773b14c2358a
--- /dev/null
+++ b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/CPUSimulator.java
@@ -0,0 +1,214 @@
+/**
+ * 
+ */
+package com.com1032.assignment.processscheduler;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author felipedabrantes
+ *
+ */
+public class CPUSimulator extends Thread{
+	/**Processes running on CPU.*/
+	private List<PCB> cpuQueue = new ArrayList<PCB> ();
+	
+	/**A report of all the errors in the OS.*/
+	private StringBuffer errorReport = new StringBuffer();
+	
+	/**The global time of the system.*/
+	private Clock globalTime = null;
+	
+	/**The hardware to use.*/
+	private Hardware hardware = null;
+
+	
+	/**
+	 * Constructor. Initialises fields.
+	 * 
+	 * @param os
+	 * @param cpuQueue
+	 */
+	public CPUSimulator(StringBuffer errorReport, Clock globalTime, List<PCB> cpuQueue, Hardware hardware) {
+		this.cpuQueue = cpuQueue;	
+		this.globalTime = globalTime;
+		this.hardware = hardware;
+		this.errorReport = errorReport;
+	}
+	
+	
+	@Override
+	public void run() {
+		while(true) {
+			
+			//Temporarily stop executing for however milliseconds.
+			try {
+				Thread.sleep(50);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+			
+			//Runs process in queue.
+			this.runCode();
+		}
+	}
+	
+	public void runCode() {
+		if(!this.cpuQueue.isEmpty()) {
+			
+			if(this.cpuQueue.get(0).getState() == ProcessState.RUNNING) {
+				//The process the CPU runs.
+				PCB processRunning = this.cpuQueue.get(0);
+				
+				//Split code string into lines.
+				String[] codeLines = processRunning.getCode().split("\\r\\n|\\r|\\n");
+				
+				//Increase program counter by one to run next line.
+				processRunning.increaseProgramCounter();
+				
+				//Surround in try-catch.
+				try {
+					//Compile and run the program counter line.
+					this.compileLine(processRunning, codeLines[processRunning.getProgramCounter()]);
+				}
+				catch (IndexOutOfBoundsException e) {
+					StringBuffer errorMessage = new StringBuffer();
+					errorMessage.append("\n - Error in Line ");
+					errorMessage.append(processRunning.getProgramCounter());
+					errorMessage.append(": ");
+					errorMessage.append(processRunning);
+					errorMessage.append("\n  * Code wrong format.");
+					
+					processRunning.setFailed(true);
+					processRunning.setState(ProcessState.TERMINATED);
+					
+					this.errorReport.append(errorMessage);
+				}
+				
+				//If not blocked, then decrease remaining time and global time by one.
+				if(processRunning.getState() != ProcessState.BLOCKED) {
+					processRunning.increaseConsecutiveTimeOnCPU();
+					processRunning.decreaseRemainingTime(1);
+					
+					//Instruction takes 4 ticks. Each core in processor decreases it by 1.
+					this.globalTime.increaseTime(5 - this.hardware.getCoresPerProcessor());
+					
+					//If all code finished, then terminate process.
+					if(processRunning.getProgramCounter() == codeLines.length - 1) {
+						processRunning.setState(ProcessState.TERMINATED);
+					}
+				}
+			}
+		}
+	}
+	
+	
+	public void compileLine(PCB processRunning, String line) {
+		
+		Map<String, Integer> variables = processRunning.getVariables();
+		
+		if(line.equals("")) {
+			return;
+		}
+
+		String command = line.split(" ")[0];
+		
+		//STORE NAME VALUE
+		if(command.toLowerCase().equals("store")) {
+			String newVariableName = line.split(" ")[1];
+			Integer newVariableValue = 0;
+			
+			if(line.split(" ")[2].startsWith("#")) {
+				newVariableValue = Integer.valueOf(line.split(" ")[2].substring(1));
+			}
+			else {
+				Integer storedVariableValue = variables.get(line.split(" ")[2]);
+				newVariableValue = storedVariableValue;
+			}
+			
+			//Store result to new variable.
+			variables.put(newVariableName, newVariableValue);
+		
+		}
+		
+		//ADD NAME VALUE1 VALUE2
+		else if(command.toLowerCase().equals("add")) {
+			String newVariableName = line.split(" ")[1];
+			Integer newVariableValue = 0;
+			
+			//Find VALUE1.
+			if(line.split(" ")[2].startsWith("#")) {
+				newVariableValue = Integer.valueOf(line.split(" ")[2].substring(1));
+			}
+			else {
+				Integer storedVariableValue = variables.get(line.split(" ")[2]);
+				newVariableValue = storedVariableValue;
+			}
+			
+			//Add VALUE2 to VALUE1.
+			if(line.split(" ")[3].startsWith("#")) {
+				newVariableValue += Integer.valueOf(line.split(" ")[3].substring(1));
+			}
+			else {
+				Integer storedVariableValue = variables.get(line.split(" ")[3]);
+				newVariableValue += storedVariableValue;
+			}
+			
+			//Store result to new variable.
+			variables.put(newVariableName, newVariableValue);
+		}
+		
+		
+		//SUB NAME VALUE1 VALUE2
+		else if(command.toLowerCase().equals("sub")) {
+			String newVariableName = line.split(" ")[1];
+			Integer newVariableValue = 0;
+			
+			//Find VALUE1.
+			if(line.split(" ")[2].startsWith("#")) {
+				newVariableValue = Integer.valueOf(line.split(" ")[2].substring(1));
+			}
+			else {
+				Integer storedVariableValue = variables.get(line.split(" ")[2]);
+				newVariableValue = storedVariableValue;
+			}
+			
+			//Subtract VALUE1 from VALUE2.
+			if(line.split(" ")[3].startsWith("#")) {
+				newVariableValue -= Integer.valueOf(line.split(" ")[3].substring(1));
+			}
+			else {
+				Integer storedVariableValue = variables.get(line.split(" ")[3]);
+				newVariableValue -= storedVariableValue;
+			}
+			
+			//Store result to new variable.
+			variables.put(newVariableName, newVariableValue);
+		}
+		
+		
+		//PRINT VALUE
+		else if(command.toLowerCase().equals("print")) {
+			processRunning.setState(ProcessState.BLOCKED);
+		}
+		
+		//DISPLAY VALUE
+		else if(command.toLowerCase().equals("display")) {
+			processRunning.setState(ProcessState.BLOCKED);
+		}
+		
+		//READ VALUE
+		else if(command.toLowerCase().equals("read")) {
+			processRunning.setState(ProcessState.BLOCKED);
+		}
+		
+		//Throws exception if code is invalid.
+		else {
+			throw new IndexOutOfBoundsException();
+		}
+		
+	}
+	
+}
diff --git a/os-simulator/src/main/java/com/com1032/assignment/Clock.java b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/Clock.java
similarity index 85%
rename from os-simulator/src/main/java/com/com1032/assignment/Clock.java
rename to os-simulator/src/main/java/com/com1032/assignment/processscheduler/Clock.java
index 43f70808dcf50880cdbc4f3c171ad9ff6352dc92..ef73455b97cd643f55f2733bd50a881e34790f43 100644
--- a/os-simulator/src/main/java/com/com1032/assignment/Clock.java
+++ b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/Clock.java
@@ -1,7 +1,7 @@
 /**
  * 
  */
-package com.com1032.assignment;
+package com.com1032.assignment.processscheduler;
 
 /**
  * @author felipedabrantes
diff --git a/os-simulator/src/main/java/com/com1032/assignment/Hardware.java b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/Hardware.java
similarity index 75%
rename from os-simulator/src/main/java/com/com1032/assignment/Hardware.java
rename to os-simulator/src/main/java/com/com1032/assignment/processscheduler/Hardware.java
index ed11cdb69c8d151bc7f08fd4846daad5a0c35b39..043ba5cc05f912fefce1de070453baf96b4c83fb 100644
--- a/os-simulator/src/main/java/com/com1032/assignment/Hardware.java
+++ b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/Hardware.java
@@ -1,9 +1,10 @@
 /**
  * 
  */
-package com.com1032.assignment;
+package com.com1032.assignment.processscheduler;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.Scanner;
 
 /**
@@ -38,8 +39,11 @@ public class Hardware {
 	 * Constructor. Initialises fields using a text file.
 	 * 
 	 * @param fileName
+	 * 
+	 * @throws IOException if there is an error accessing hardware file.
+	 * @throws NumberFormatException if there is an error with hardware file parameters.
 	 */
-	public Hardware() {
+	public Hardware() throws IOException, NumberFormatException {
 		try {
 			
 			File file = new File("hardware.txt");
@@ -54,8 +58,11 @@ public class Hardware {
 			fileReader.close();
 		}
 		
-		catch(Exception e) {
-			System.out.println("Error with Hardware file.");
+		catch(IOException e) {
+			throw new IOException("Error using Hardware file.");
+		}
+		catch(NumberFormatException e) {
+			throw new IndexOutOfBoundsException("Error with Hardware file parameters.");
 		}
 	
 	}
diff --git a/os-simulator/src/main/java/com/com1032/assignment/processscheduler/IOProcessManager.java b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/IOProcessManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..a3f7906398901b9f81c60c0ad67cc3ca7dcd8b86
--- /dev/null
+++ b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/IOProcessManager.java
@@ -0,0 +1,292 @@
+/**
+ * 
+ */
+package com.com1032.assignment.processscheduler;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import com.com1032.assignment.IOsystem.JavaIOSystem;
+
+/**
+ * @author felipedabrantes
+ *
+ */
+public class IOProcessManager extends Thread {
+
+	/**A report of all the errors in the OS.*/
+	private StringBuffer errorReport = new StringBuffer();
+	
+	/**A report of all the IO operations in the OS.*/
+	private StringBuffer IOReport = new StringBuffer();
+	
+	/**Processes waiting for I/O.*/
+	private List<PCB> blockedQueue = new ArrayList<PCB> ();
+	
+	/**The IO System used to control peripherals.*/
+	private JavaIOSystem IOSystem = null;
+	
+	
+	/**
+	 * Constructor. Initialises fields.
+	 * 
+	 * @param globalTime
+	 * @param cores
+	 * @param readyQueue
+	 * @param blockedQueue
+	 * @param terminatedQueue
+	 * 
+	 * @throws IOException if there is an error accessing hardware file.
+	 * @throws IndexOutOfBoundsException if there is an error with hardware file parameters.
+	 * 
+	 */
+	public IOProcessManager(StringBuffer errorReport, StringBuffer IOReport, List<PCB> blockedQueue) throws IndexOutOfBoundsException, IOException {
+		this.errorReport = errorReport;
+		this.blockedQueue = blockedQueue;
+		this.IOReport = IOReport;
+		
+		this.IOSystem = new JavaIOSystem();
+	}
+	
+	
+	@Override
+	public void run() {
+		
+		while(true) {
+			try {
+				Thread.sleep(50);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+			
+			this.runBlockedProcess();
+		}
+	}
+	
+	
+	/**
+	 * Function used when running a blocked process.
+	 */
+	public void runBlockedProcess() {
+		
+		if(!this.blockedQueue.isEmpty()) {
+			
+			if(this.blockedQueue.get(0).getState() == ProcessState.BLOCKED) {
+				//The process the CPU runs.
+				PCB processRunning = this.blockedQueue.get(0);
+				
+				//Split code string into lines.
+				String[] codeLines = processRunning.getCode().split("\\r\\n|\\r|\\n");
+				
+				//Surround in try-catch.
+				try {
+					//Compile and run the program counter line.
+					this.compileLine(processRunning, codeLines[processRunning.getProgramCounter()]);
+				}
+				
+				catch (IndexOutOfBoundsException e) {
+					StringBuffer errorMessage = new StringBuffer();
+					errorMessage.append("\n - Error in Line ");
+					errorMessage.append(processRunning.getProgramCounter());
+					errorMessage.append(": ");
+					errorMessage.append(processRunning);
+					errorMessage.append("\n  * Code wrong format.");
+					
+					processRunning.setFailed(true);
+					processRunning.setState(ProcessState.TERMINATED);
+					
+					this.errorReport.append(errorMessage);
+				}
+				
+				catch (NumberFormatException e) {
+					StringBuffer errorMessage = new StringBuffer();
+					errorMessage.append("\n - Error in Line ");
+					errorMessage.append(processRunning.getProgramCounter());
+					errorMessage.append(": ");
+					errorMessage.append(processRunning);
+					errorMessage.append("\n  * Input device must only contain integers.");
+					
+					processRunning.setFailed(true);
+					processRunning.setState(ProcessState.TERMINATED);
+					
+					this.errorReport.append(errorMessage);
+				}
+				
+				catch (IllegalArgumentException | IOException e) {
+					StringBuffer errorMessage = new StringBuffer();
+					errorMessage.append("\n - Error in Line ");
+					errorMessage.append(processRunning.getProgramCounter());
+					errorMessage.append(": ");
+					errorMessage.append(processRunning);
+					errorMessage.append("\n  * ");
+					errorMessage.append(e);
+					
+					processRunning.setFailed(true);
+					processRunning.setState(ProcessState.TERMINATED);
+					
+					this.errorReport.append(errorMessage);
+				}
+				
+				//Decrease expected remaining time.
+				processRunning.decreaseRemainingTime(1);
+				
+				//Reset time used on CPU.
+				processRunning.resetConsecutiveTimeOnCPU();
+				
+				//If process got an error, then leave it.
+				if(!processRunning.getFailed()) {
+					//If all code finished, then terminate process.
+					if(processRunning.getProgramCounter() == codeLines.length - 1) {
+						processRunning.setState(ProcessState.TERMINATED);
+					}
+					else {
+						processRunning.setState(ProcessState.READY);
+					}
+				}
+			}
+		}
+	}
+	
+	
+	/**
+	 * Function used to compile a code line.
+	 * 
+	 * @param processRunning
+	 * @param line to compile.
+	 * 
+	 * @throws IOException 
+	 * @throws IllegalArgumentException 
+	 */
+	public void compileLine(PCB processRunning, String line) throws IllegalArgumentException, IOException {
+		
+		Map<String, Integer> variables = processRunning.getVariables();
+		
+		String command = line.split(" ")[0];
+		
+		//PRINT VALUE DEVICE
+		if(command.toLowerCase().equals("print")) {
+			Integer variableValue = null;
+			
+			if(line.split(" ")[1].startsWith("#")) {
+				variableValue = Integer.valueOf(line.split(" ")[1].substring(1));
+			}
+			else {
+				Integer storedVariableValue = variables.get(line.split(" ")[1]);
+				variableValue = storedVariableValue;
+			}
+			
+			String deviceName = line.split(" ")[2];
+			
+			this.print(variableValue, deviceName);
+		}
+		
+		
+		//DISPLAY VALUE DEVICE
+		if(command.toLowerCase().equals("display")) {
+			Integer variableValue = null;
+			
+			if(line.split(" ")[1].startsWith("#")) {
+				variableValue = Integer.valueOf(line.split(" ")[1].substring(1));
+			}
+			else {
+				Integer storedVariableValue = variables.get(line.split(" ")[1]);
+				variableValue = storedVariableValue;
+			}
+			
+			String deviceName = line.split(" ")[2];
+			
+			this.display(variableValue, deviceName);
+		}
+		
+		
+		//READ STORE SIZE DEVICE
+		if(command.toLowerCase().equals("read")) {
+			String storeVariable = line.split(" ")[1];
+			Integer sizeVariable = null;
+			
+			if(line.split(" ")[2].startsWith("#")) {
+				sizeVariable = Integer.valueOf(line.split(" ")[2].substring(1));
+			}
+			else {
+				Integer storedVariableValue = variables.get(line.split(" ")[2]);
+				sizeVariable = storedVariableValue;
+			}
+			
+			String deviceName = line.split(" ")[3];
+			
+			this.read(storeVariable, sizeVariable, deviceName);
+		}
+	}
+	
+	
+	/**
+	 * Function used to run print command.
+	 * 
+	 * @param value
+	 * @param deviceName
+	 * 
+	 * @throws IllegalArgumentException
+	 * @throws IOException
+	 */
+	public void print(int value, String deviceName) throws IllegalArgumentException, IOException {
+		this.IOSystem.write(deviceName, String.valueOf(value));
+		
+		this.IOReport.append("\n - Printed to ");
+		this.IOReport.append(deviceName);
+	}
+	
+	
+	/**
+	 * Function used to run display command.
+	 * @param value
+	 * @param deviceName
+	 * 
+	 * @throws IllegalArgumentException
+	 * @throws IOException
+	 */
+	public void display(int value, String deviceName) throws IllegalArgumentException, IOException {
+		this.IOSystem.write(deviceName, String.valueOf(value));
+		
+		this.IOReport.append("\n - Displayed to ");
+		this.IOReport.append(deviceName);
+	}
+	
+	
+	/**
+	 * Function used to run read command.
+	 * 
+	 * @param storeVariable
+	 * @param size
+	 * @param deviceName
+	 * 
+	 * @throws IllegalArgumentException
+	 * @throws IOException
+	 * @throws NumberFormatException
+	 */
+	public void read(String storeVariable, int size, String deviceName) throws IllegalArgumentException, IOException, NumberFormatException {
+		String result = this.IOSystem.read(deviceName, size);
+		
+		this.blockedQueue.get(0).getVariables().put(storeVariable, Integer.valueOf(result));
+		
+		this.IOReport.append("\n - Read from ");
+		this.IOReport.append(deviceName);
+	}
+	
+	
+	/**
+	 * @return errorReport
+	 */
+	public String getErrorReport() {
+		return this.errorReport.toString();
+	}
+	
+	/**
+	 * @return IOReport
+	 */
+	public String getIOReport() {
+		return this.IOReport.toString();
+	}
+
+}
diff --git a/os-simulator/src/main/java/com/com1032/assignment/OS.java b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/OS.java
similarity index 63%
rename from os-simulator/src/main/java/com/com1032/assignment/OS.java
rename to os-simulator/src/main/java/com/com1032/assignment/processscheduler/OS.java
index 11c480aa2a51cd2d01d73e94baccb6be5cb9b95d..fa76a68ad6c401d155aa252f3d088064a1abb236 100644
--- a/os-simulator/src/main/java/com/com1032/assignment/OS.java
+++ b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/OS.java
@@ -1,12 +1,7 @@
+package com.com1032.assignment.processscheduler;
 /**
  * OS.java
  */
-package com.com1032.assignment;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
 
 /**
  * @author felipedabrantes
@@ -27,19 +22,11 @@ public class OS {
 	 */
 	public OS() {
 		this.ps = new ProcessScheduler(this);
-		this.hardware = new Hardware();
-	}
-	
-	
-	/**
-	 * @param args
-	 * @throws FileNotFoundException
-	 * @throws IOException
-	 */
-	public static void main(String[] args) throws FileNotFoundException {
-		OS os = new OS();
-		os.ps.setAlgorithm(SchedulingAlgorithm.RR, 3);
-		os.turnOn();
+		try {
+			this.hardware = new Hardware();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
 	}
 
 	
@@ -47,7 +34,12 @@ public class OS {
 	 * Runs process scheduling simulation with processes in OS.
 	 */
 	public void turnOn() {
-		this.ps.startThreads();
+		try {
+			this.ps.startThreads();	
+		}
+		catch(Exception e) {
+			e.printStackTrace();;
+		}
 	}
 
 	/**
diff --git a/os-simulator/src/main/java/com/com1032/assignment/processscheduler/OSCommandLine.java b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/OSCommandLine.java
new file mode 100644
index 0000000000000000000000000000000000000000..834cf33b1d16ae14e74565f7994e5763e9bdeb96
--- /dev/null
+++ b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/OSCommandLine.java
@@ -0,0 +1,141 @@
+/**
+ * 
+ */
+package com.com1032.assignment.processscheduler;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+/**
+ * @author felipedabrantes
+ *
+ */
+public class OSCommandLine {
+	
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		OS os = new OS();
+		os.turnOn();
+		
+        // Create a stream for input
+        BufferedReader data = null;
+
+        data = new BufferedReader (new InputStreamReader(System.in));
+
+        // Cycle through user or file input
+        while (true) {
+            try {
+                // Print out the prompt for the user
+
+                System.out.print("--> ");
+                System.out.flush();
+
+                // Read in a line
+                String line = data.readLine();
+
+                // Check for various conditions
+                if (line == null) System.exit(0);  // Ctrl-D check
+                line = line.trim();                // Trim off extra whitespace
+                if (line.length() == 0) {          // Is anything left?
+                    System.out.println();
+                    continue;
+                }
+
+                // Tokenize command line
+                StringTokenizer cmds = new StringTokenizer (line);
+                String cmd = cmds.nextToken();
+
+                if (cmd.equalsIgnoreCase("processReport") || cmd.equalsIgnoreCase("pR")) {
+                    System.out.println(os.getPs().getProcessReport());
+                    continue;
+                }
+                
+                else if (cmd.equalsIgnoreCase("errorReport") || cmd.equalsIgnoreCase("eR")) {
+                    System.out.println(os.getPs().getErrorReport() + "\n");
+                    continue;
+                }
+                
+                else if (cmd.equalsIgnoreCase("IOReport") || cmd.equalsIgnoreCase("ioR")) {
+                    System.out.println(os.getPs().getIOReport() + "\n");
+                    continue;
+                }
+                
+                else if (cmd.equalsIgnoreCase("algorithm")) {
+                	String algorithm = cmds.nextToken();
+                	String quantumString = cmds.nextToken();
+                	
+                	int quantum = Integer.valueOf(quantumString);
+                	
+                	if(algorithm.equals("FIFO")) {
+                		os.getPs().setAlgorithm(SchedulingAlgorithm.FIFO, quantum);
+                	}
+                	else if(algorithm.equals("SRTF")) {
+                		os.getPs().setAlgorithm(SchedulingAlgorithm.SRTF, quantum);
+                	}
+                	else if(algorithm.equals("SPF")) {
+                		os.getPs().setAlgorithm(SchedulingAlgorithm.SPF, quantum);
+                	}
+                	else if(algorithm.equals("RR")) {
+                		os.getPs().setAlgorithm(SchedulingAlgorithm.RR, quantum);
+                	}
+                	else {
+                		throw new IllegalArgumentException("No such algorithm.");
+                	}
+                	
+                	System.out.println("Changed algorithm.");
+                	
+                }
+                
+                else if (cmd.equalsIgnoreCase("quit")) {
+                    System.exit(0);
+                }
+                
+                else if (cmd.equalsIgnoreCase("help")) {
+                    OSCommandLine.help();
+                    continue;
+                }
+                
+                else {
+                    System.out.println("Unknown command.");
+                    continue;
+                }
+            }
+            
+            // Handler for Integer.parseInt(...)
+            catch (NumberFormatException e) {
+                System.out.println("Incorrect argument type.");
+            }
+            // Handler for nextToken()
+            catch (NoSuchElementException e) {
+                System.out.println("Incorrect number of elements.");
+            }
+            // Handler for IOType
+            catch (IllegalArgumentException e) {
+            	System.out.println(e.getMessage());
+            }
+            catch (IOException e) {
+                System.err.println(e);
+            }
+        }
+
+	}
+    
+    
+    /**
+     * Help will just print out a listing of the commands available on the system.
+     */
+    private static void help() {
+    	System.out.println (" - processReport");
+        System.out.println (" - errorReport");
+        System.out.println (" - ioReport");
+        System.out.println (" - algorithm");
+        System.out.println (" - quit");
+        System.out.println (" - help");
+    }
+
+}
diff --git a/os-simulator/src/main/java/com/com1032/assignment/PCB.java b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/PCB.java
similarity index 98%
rename from os-simulator/src/main/java/com/com1032/assignment/PCB.java
rename to os-simulator/src/main/java/com/com1032/assignment/processscheduler/PCB.java
index 2e6f58560cd7e7e2fcd71d2ea389680a80dd6339..f6e2a56ba3b16cd409d7caf3d27e223bec3f2799 100644
--- a/os-simulator/src/main/java/com/com1032/assignment/PCB.java
+++ b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/PCB.java
@@ -1,7 +1,7 @@
 /**
  * 
  */
-package com.com1032.assignment;
+package com.com1032.assignment.processscheduler;
 
 import java.util.HashMap;
 import java.util.Map;
diff --git a/os-simulator/src/main/java/com/com1032/assignment/ProcessCreation.java b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/ProcessCreation.java
similarity index 91%
rename from os-simulator/src/main/java/com/com1032/assignment/ProcessCreation.java
rename to os-simulator/src/main/java/com/com1032/assignment/processscheduler/ProcessCreation.java
index a9045e5429b54fb0e050326b2711bf76170bbe1c..a22c6ca2457aef28f6ff0d1f79de41c9c8a16a12 100644
--- a/os-simulator/src/main/java/com/com1032/assignment/ProcessCreation.java
+++ b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/ProcessCreation.java
@@ -1,7 +1,7 @@
 /**
  * 
  */
-package com.com1032.assignment;
+package com.com1032.assignment.processscheduler;
 
 import java.io.File;
 import java.io.IOException;
@@ -24,6 +24,9 @@ public class ProcessCreation extends Thread {
 	/**New processes added to the system.*/
 	private List<PCB> jobQueue = new ArrayList<PCB> ();
 	
+	/**A report of all the errors in the OS.*/
+	private StringBuffer errorReport = new StringBuffer();
+	
 	/**The global time of the system.*/
 	private Clock globalTime = null;
 	
@@ -32,8 +35,9 @@ public class ProcessCreation extends Thread {
 	 * 
 	 * @param jobQueue of the system.
 	 */
-	public ProcessCreation(Clock globalTime, List<PCB> jobQueue) {
+	public ProcessCreation(StringBuffer errorReport, Clock globalTime, List<PCB> jobQueue) {
 		this.jobQueue = jobQueue;
+		this.errorReport = errorReport;
 		this.globalTime = globalTime;
 	}
 	
@@ -169,7 +173,8 @@ public class ProcessCreation extends Thread {
 				Files.move(file.toPath(), Paths.get(newFileName));
 				
 				if(!valid) {
-					System.out.println(file.getName() + " wrong format. Moved to Invalid_Processes folder.");
+					this.errorReport.append("\n -");
+					this.errorReport.append(file.getName() + " wrong format. Moved to Invalid_Processes folder.");
 				}
 						
 				//Successfully moved file so remove it from system array.
diff --git a/os-simulator/src/main/java/com/com1032/assignment/ProcessDispatcher.java b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/ProcessDispatcher.java
similarity index 84%
rename from os-simulator/src/main/java/com/com1032/assignment/ProcessDispatcher.java
rename to os-simulator/src/main/java/com/com1032/assignment/processscheduler/ProcessDispatcher.java
index 870162e94f069cee6b23d436f2b2f6435340e1d3..6f63fe3204894d33176c64c8fdf2971a6c92cf11 100644
--- a/os-simulator/src/main/java/com/com1032/assignment/ProcessDispatcher.java
+++ b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/ProcessDispatcher.java
@@ -1,7 +1,7 @@
 /**
  * 
  */
-package com.com1032.assignment;
+package com.com1032.assignment.processscheduler;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -28,8 +28,8 @@ public class ProcessDispatcher extends Thread {
 	
 	private Hardware hardware = null;
 	
-	/**The info report of the process scheduler.*/
-	private StringBuffer report = new StringBuffer();
+	/**The info processReport of the process scheduler.*/
+	private StringBuffer processReport = null;
 	
 	/**The algorithm used for scheduling.*/
 	private SchedulingAlgorithm algorithm = SchedulingAlgorithm.FIFO;
@@ -46,9 +46,10 @@ public class ProcessDispatcher extends Thread {
 	 * @param cpuQueue
 	 * @param globalTime
 	 */
-	public ProcessDispatcher(Clock globalTime, Hardware hardware, List<PCB> jobQueue, List<PCB> readyQueue,
-			List<PCB> blockedQueue, List<PCB> terminatedQueue, 
-			List<PCB> cpuQueue) {
+	public ProcessDispatcher(Clock globalTime, Hardware hardware, StringBuffer processReport, 
+			SchedulingAlgorithm algorithm, int quantum,
+			List<PCB> jobQueue, List<PCB> readyQueue, List<PCB> blockedQueue, List<PCB> terminatedQueue, List<PCB> cpuQueue) {
+		
 		super();
 		this.jobQueue = jobQueue;
 		this.readyQueue = readyQueue;
@@ -58,6 +59,11 @@ public class ProcessDispatcher extends Thread {
 		
 		this.globalTime = globalTime;
 		this.hardware = hardware;
+		
+		this.algorithm = algorithm;
+		this.quantum = quantum;
+		
+		this.processReport = processReport;
 	}
 	
 	
@@ -69,13 +75,6 @@ public class ProcessDispatcher extends Thread {
 	public void run() {
 		
 		while(true) {
-//			System.out.println("R: " + this.readyQueue);
-//			System.out.println("C: " + this.cpuQueue);
-//			System.out.println("B: " + this.blockedQueue);
-//			System.out.println("T: " + this.terminatedQueue);
-//			System.out.println("\n");
-			System.out.println(this.getReport());
-			
 			try {
 				Thread.sleep(0);
 			} catch (InterruptedException e) {
@@ -85,11 +84,6 @@ public class ProcessDispatcher extends Thread {
 			
 			//---Job Queue Check---
 			if(!this.jobQueue.isEmpty()) {
-				
-				if(this.jobQueue.get(0) == null) {
-					System.out.println("********1: " + this.jobQueue.get(0));
-				}
-				
 				this.readyProcess(this.jobQueue.get(0));
 			}
 			
@@ -165,10 +159,10 @@ public class ProcessDispatcher extends Thread {
 	
 	
 	/**
-	 * @return report of scheduler as string.
+	 * @return processReport of scheduler as string.
 	 */
-	public String getReport() {
-		return this.report.toString();
+	public String getProcessReport() {
+		return this.processReport.toString();
 	}
 	
 	
@@ -198,7 +192,7 @@ public class ProcessDispatcher extends Thread {
 				this.contextSwitch(this.cpuQueue.get(0));
 				
 				//Update scheduler attributes.
-				this.report.append("\n- Schedule @ " + this.globalTime.getTime() + ": " + process + "\n");
+				this.processReport.append("\n- Schedule @ " + this.globalTime.getTime() + ": " + process + "\n");
 				process.setState(ProcessState.RUNNING);
 				this.cpuQueue.add(process);
 				this.readyQueue.remove(process);
@@ -206,8 +200,7 @@ public class ProcessDispatcher extends Thread {
 		}
 		else {
 			//Update scheduler attributes.
-			this.report.append("\n- Schedule @ " + this.globalTime.getTime() + ": " + process + "\n");
-//			System.out.println(process);
+			this.processReport.append("\n- Schedule @ " + this.globalTime.getTime() + ": " + process + "\n");
 			process.setState(ProcessState.RUNNING);
 			this.cpuQueue.add(process);
 			this.readyQueue.remove(process);
@@ -231,7 +224,7 @@ public class ProcessDispatcher extends Thread {
 		this.readyQueue.remove(process);
 		this.blockedQueue.remove(process);
 		this.terminatedQueue.add(process);
-		this.report.append("\n- Terminated @ " + this.globalTime.getTime() + ": " + process + "\n");
+		this.processReport.append("\n- Terminated @ " + this.globalTime.getTime() + ": " + process + "\n");
 	}
 	
 	/**
@@ -244,7 +237,7 @@ public class ProcessDispatcher extends Thread {
 		this.cpuQueue.remove(process);
 		this.readyQueue.remove(process);
 		this.blockedQueue.add(process);
-		this.report.append("\n- Blocking @ " + this.globalTime.getTime() + ": " + process + "\n");
+		this.processReport.append("\n- Blocking @ " + this.globalTime.getTime() + ": " + process + "\n");
 	}
 	
 	/**
@@ -258,7 +251,7 @@ public class ProcessDispatcher extends Thread {
 		this.cpuQueue.remove(process);
 		this.blockedQueue.remove(process);
 		this.readyQueue.add(process);
-		this.report.append("\n- Ready @ " + this.globalTime.getTime() + ": " + process + "\n");
+		this.processReport.append("\n- Ready @ " + this.globalTime.getTime() + ": " + process + "\n");
 	}
 	
 	
@@ -270,7 +263,7 @@ public class ProcessDispatcher extends Thread {
 	public void contextSwitch(PCB process) {
 		this.cpuQueue.remove(process);
 		this.readyQueue.add(process);
-		this.report.append("\n- Suspending @ " + this.globalTime.getTime() + ": " + process + "\n");
+		this.processReport.append("\n- Suspending @ " + this.globalTime.getTime() + ": " + process + "\n");
 		process.setState(ProcessState.READY);
 	}
 	
diff --git a/os-simulator/src/main/java/com/com1032/assignment/processscheduler/ProcessScheduler.java b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/ProcessScheduler.java
new file mode 100644
index 0000000000000000000000000000000000000000..7665aa6087d11da94f6783b29bcb631641062549
--- /dev/null
+++ b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/ProcessScheduler.java
@@ -0,0 +1,101 @@
+/**
+ * 
+ */
+package com.com1032.assignment.processscheduler;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author felipedabrantes
+ *
+ */
+public class ProcessScheduler {
+	
+	/**New processes added to the system.*/
+	private List<PCB> jobQueue = new ArrayList<PCB> ();
+	/**Processes ready to be executed.*/
+	private List<PCB> readyQueue = new ArrayList<PCB> ();
+	/**Processes waiting for I/O.*/
+	private List<PCB> blockedQueue = new ArrayList<PCB> ();
+	/**Processes that have finished executing.*/
+	private List<PCB> terminatedQueue = new ArrayList<PCB> ();
+	/**Processes running on CPU.*/
+	private List<PCB> cpuQueue = new ArrayList<PCB> ();
+	
+	/**The info report of the process scheduler.*/
+	private StringBuffer processReport = new StringBuffer();
+	
+	/**A report of all the errors in the OS.*/
+	private StringBuffer errorReport = new StringBuffer();
+	
+	/**A report of all the IO operations in the OS.*/
+	private StringBuffer IOReport = new StringBuffer();
+	
+	
+	/**The scheduling algorithm to use.*/
+	private SchedulingAlgorithm algorithm = SchedulingAlgorithm.FIFO;
+	
+	/**The quantum to use.*/
+	private int quantum = 0;
+	
+	/**The global time of the system.*/
+	private OS os = null;
+	
+	private ProcessCreation pc = null;
+	private ProcessDispatcher pd = null;
+	private CPUSimulator cpu = null;
+	private IOProcessManager io = null;
+	
+	public ProcessScheduler(OS os) {
+		this.os = os;
+	}
+	
+	
+	/**
+	 * Starts running the threads needed.
+	 * 
+	 * @throws IOException if there is an error accessing hardware file.
+	 * @throws IndexOutOfBoundsException if there is an error with hardware file parameters.
+	 */
+	public void startThreads() throws IndexOutOfBoundsException, IOException {
+		//Thread responsible for creating processes from files.
+		this.pc = new ProcessCreation(this.errorReport, this.os.getGlobalTime(), this.jobQueue);
+		
+		//Thread responsible for handling processes states.
+		this.pd = new ProcessDispatcher(this.os.getGlobalTime(), this.os.getHardware(), 
+				this.processReport, this.algorithm, this.quantum, 
+				this.jobQueue, this.readyQueue, this.blockedQueue, this.terminatedQueue, this.cpuQueue);
+		
+		//Thread responsible for running processes and simulating CPU.
+		this.cpu = new CPUSimulator(this.errorReport, this.os.getGlobalTime(), this.cpuQueue, this.os.getHardware());
+		
+		//Thread responsible for running blocked processes.
+		this.io = new IOProcessManager(this.errorReport, this.IOReport, this.blockedQueue);
+		
+		//Start threads.
+		pc.start();
+		pd.start();
+		cpu.start();
+		io.start();
+	}
+	
+	
+	public void setAlgorithm(SchedulingAlgorithm algorithm, int quantum) {
+		this.pd.setAlgorithm(algorithm, quantum);
+	}
+	
+	public String getProcessReport() {
+		return this.processReport.toString();
+	}
+	
+	public String getErrorReport() {
+		return this.errorReport.toString();
+	}
+	
+	public String getIOReport() {
+		return this.IOReport.toString();
+	}
+
+}
diff --git a/os-simulator/src/main/java/com/com1032/assignment/ProcessState.java b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/ProcessState.java
similarity index 89%
rename from os-simulator/src/main/java/com/com1032/assignment/ProcessState.java
rename to os-simulator/src/main/java/com/com1032/assignment/processscheduler/ProcessState.java
index 06dd3ada400dddb31989910959ba9b9d2b9c4913..afc23c069ca91bc96fd11e8b6913067a1c099816 100644
--- a/os-simulator/src/main/java/com/com1032/assignment/ProcessState.java
+++ b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/ProcessState.java
@@ -1,7 +1,7 @@
 /**
  * State.java
  */
-package com.com1032.assignment;
+package com.com1032.assignment.processscheduler;
 
 /**
  * An enumeration to access all possible states of a process.
diff --git a/os-simulator/src/main/java/com/com1032/assignment/SchedulingAlgorithm.java b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/SchedulingAlgorithm.java
similarity index 94%
rename from os-simulator/src/main/java/com/com1032/assignment/SchedulingAlgorithm.java
rename to os-simulator/src/main/java/com/com1032/assignment/processscheduler/SchedulingAlgorithm.java
index 2e74a2d57356dda98a028199717e3e62608dcc5c..8d17399d6fb5bf678151aaa4cf69b0a830bfdbc1 100644
--- a/os-simulator/src/main/java/com/com1032/assignment/SchedulingAlgorithm.java
+++ b/os-simulator/src/main/java/com/com1032/assignment/processscheduler/SchedulingAlgorithm.java
@@ -1,7 +1,7 @@
 /**
  * SchedulingAlgorithm.java
  */
-package com.com1032.assignment;
+package com.com1032.assignment.processscheduler;
 
 /**
  * Enumeration of scheduling algorithms.
diff --git a/os-simulator/src/main/java/com/com1032/pss/OSSim.java b/os-simulator/src/main/java/com/com1032/pss/OSSim.java
index 9f0b70740141938a9e6f6dac2ed8a1eefceca25f..34aefcf67ea618441e9e94305203cfe0f0e90997 100644
--- a/os-simulator/src/main/java/com/com1032/pss/OSSim.java
+++ b/os-simulator/src/main/java/com/com1032/pss/OSSim.java
@@ -10,8 +10,8 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Scanner;
 
-import com.com1032.assignment.Clock;
-import com.com1032.assignment.SchedulingAlgorithm;
+import com.com1032.assignment.processscheduler.Clock;
+import com.com1032.assignment.processscheduler.SchedulingAlgorithm;
 import com.com1032.pss.Process;
 import com.com1032.pss.ProcessSchedulerSimulator;
 
diff --git a/os-simulator/src/main/java/com/com1032/pss/Process.java b/os-simulator/src/main/java/com/com1032/pss/Process.java
index b7aff81616ec7c6293819ab6b90b74a09ce740c6..543487231dfe04b4ef4fb0c2ea700fdd0e73de89 100644
--- a/os-simulator/src/main/java/com/com1032/pss/Process.java
+++ b/os-simulator/src/main/java/com/com1032/pss/Process.java
@@ -3,7 +3,7 @@
  */
 package com.com1032.pss;
 
-import com.com1032.assignment.ProcessState;
+import com.com1032.assignment.processscheduler.ProcessState;
 
 /**
  * @author felipedabrantes
diff --git a/os-simulator/src/main/java/com/com1032/pss/ProcessSchedulerSimulator.java b/os-simulator/src/main/java/com/com1032/pss/ProcessSchedulerSimulator.java
index f216e600867a48850a605e9c5d2b6fe0bd3a2ac3..d9c2b6be1346e8bb27ee374568f23a45b534dbf7 100644
--- a/os-simulator/src/main/java/com/com1032/pss/ProcessSchedulerSimulator.java
+++ b/os-simulator/src/main/java/com/com1032/pss/ProcessSchedulerSimulator.java
@@ -6,9 +6,9 @@ package com.com1032.pss;
 import java.util.ArrayList;
 import java.util.List;
 
-import com.com1032.assignment.Clock;
-import com.com1032.assignment.ProcessState;
-import com.com1032.assignment.SchedulingAlgorithm;
+import com.com1032.assignment.processscheduler.Clock;
+import com.com1032.assignment.processscheduler.ProcessState;
+import com.com1032.assignment.processscheduler.SchedulingAlgorithm;
 
 /**
  * @author felipedabrantes