diff --git a/os-simulator/.DS_Store b/os-simulator/.DS_Store
index fe2504a4ceeb00af03fb4bed185906386aafdd76..9b55c518acb39ab0a363b602e4975a9e1fab812e 100644
Binary files a/os-simulator/.DS_Store and b/os-simulator/.DS_Store differ
diff --git a/os-simulator/Processes/.DS_Store b/os-simulator/Processes/.DS_Store
index fa8bc6ec33bfb5b17b4bb0465acc7f38a9163397..78344d393449df37c49b645fba70c93197292268 100644
Binary files a/os-simulator/Processes/.DS_Store and b/os-simulator/Processes/.DS_Store differ
diff --git a/os-simulator/src/main/java/com/com1032/assignment/Clock.java b/os-simulator/src/main/java/com/com1032/assignment/Clock.java
index b9acd91cc01b1c287ab0459ba1e1c4141624422a..43f70808dcf50880cdbc4f3c171ad9ff6352dc92 100644
--- a/os-simulator/src/main/java/com/com1032/assignment/Clock.java
+++ b/os-simulator/src/main/java/com/com1032/assignment/Clock.java
@@ -9,13 +9,19 @@ package com.com1032.assignment;
  */
 public class Clock {
 	
-	public int time = 0;
-	
-	
+	private int time = 0;
 	
 	@Override
 	public String toString() {
 		return String.valueOf(this.time);
 	}
+	
+	public int getTime() {
+		return time;
+	}
+	
+	public void increaseTime(int time) {
+		this.time += time;
+	}
 
 }
diff --git a/os-simulator/src/main/java/com/com1032/assignment/OS.java b/os-simulator/src/main/java/com/com1032/assignment/OS.java
index 8372bb98e699c8315c0c545368d85a5405704dc7..11c480aa2a51cd2d01d73e94baccb6be5cb9b95d 100644
--- a/os-simulator/src/main/java/com/com1032/assignment/OS.java
+++ b/os-simulator/src/main/java/com/com1032/assignment/OS.java
@@ -3,12 +3,10 @@
  */
 package com.com1032.assignment;
 
-import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Scanner;
 
 /**
  * @author felipedabrantes
@@ -18,20 +16,21 @@ public class OS {
 
 	/**The global time of the OS.*/
 	private Clock globalTime = new Clock();
+	/**The hardware of the OS.*/
+	private Hardware hardware = null;
 	/**The class the handles the process scheduling.*/
-	private ProcessSchedulerSimulator pss = null;
-	/**A list of processes of the OS.*/
-	private List<Process> processes = new ArrayList<Process>();
+	private ProcessScheduler ps = null;
 
 	
 	/**
 	 * Constructor. Initialises fields.
 	 */
 	public OS() {
-		
-		this.pss = new ProcessSchedulerSimulator(this.globalTime);
+		this.ps = new ProcessScheduler(this);
+		this.hardware = new Hardware();
 	}
-
+	
+	
 	/**
 	 * @param args
 	 * @throws FileNotFoundException
@@ -39,65 +38,40 @@ public class OS {
 	 */
 	public static void main(String[] args) throws FileNotFoundException {
 		OS os = new OS();
-
-		os.addProcess("OSInput.txt");
-		os.runProcessScheduling();
-
+		os.ps.setAlgorithm(SchedulingAlgorithm.RR, 3);
+		os.turnOn();
 	}
 
 	
 	/**
-	 * Used to a single process to OS.
-	 * @param process
+	 * Runs process scheduling simulation with processes in OS.
 	 */
-	public void addProcess(Process process) {
-		this.processes.add(process);
+	public void turnOn() {
+		this.ps.startThreads();
 	}
-	
-	
+
 	/**
-	 * Used to add processes from a file to the OS.
-	 * 
-	 * @param fileName of the processes file.
-	 * 
-	 * @throws FileNotFoundException if no file is found.
+	 * @return the globalTime
 	 */
-	public void addProcess(String fileName){
-		//Tries to open file.
-		try {
-			File file = new File(fileName);
-			Scanner fileReader = new Scanner(file);
-			
-			//Reads file line by line.
-			while (fileReader.hasNextLine()) {
-				//Splits process info to make a process object.
-				String[] data = fileReader.nextLine().split(", ");
-				this.processes.add(new Process(
-						Integer.valueOf(data[0]), 
-						data[1], 
-						Integer.valueOf(data[4]), 
-						Integer.valueOf(data[3]), 
-						Integer.valueOf(data[2])));
-			}
-			
-			//Closes file.
-			fileReader.close();
-		}
-		//Ran if no file is found.
-		catch(FileNotFoundException e) {
-			System.out.println("File not found.");
-		}
+	public Clock getGlobalTime() {
+		return this.globalTime;
+	}
+
 
+	/**
+	 * @return the hardware
+	 */
+	public Hardware getHardware() {
+		return this.hardware;
 	}
 
-	
+
 	/**
-	 * Runs process scheduling simulation with processes in OS.
+	 * @return the ps
 	 */
-	public void runProcessScheduling() {
-		pss.addProcessToJob(this.processes);
-		pss.run(SchedulingAlgorithm.SPF, 3);
-		System.out.println(pss.getReport());
+	public ProcessScheduler getPs() {
+		return this.ps;
 	}
+	
 
 }
diff --git a/os-simulator/src/main/java/com/com1032/assignment/PCB.java b/os-simulator/src/main/java/com/com1032/assignment/PCB.java
index 6c8f538c27eefa6dfa0ea65e787dd6172b3604cd..2e6f58560cd7e7e2fcd71d2ea389680a80dd6339 100644
--- a/os-simulator/src/main/java/com/com1032/assignment/PCB.java
+++ b/os-simulator/src/main/java/com/com1032/assignment/PCB.java
@@ -3,6 +3,9 @@
  */
 package com.com1032.assignment;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * @author felipedabrantes
  *
@@ -15,7 +18,14 @@ public class PCB {
 	/**The state of the process.*/
 	private ProcessState state = ProcessState.NEW;
 	
+	/**The code of the process.*/
 	private String code = null;
+	/**States line number of the code.*/
+	private int programCounter = -1;
+	/**The variables stored in a process.*/
+	private Map<String, Integer> variables = new HashMap<String, Integer> ();
+	/**States whether process failed due to code error.*/
+	private boolean failed = false;
 	
 	//---Attributes for process scheduling. ---
 	/**States the importance of the process. Higher is more important.*/
@@ -29,9 +39,7 @@ public class PCB {
 	/**Time remaining for process finished.*/
 	private int remainingTime = 0;
 	
-	
-//	private List<Thread> threads = new ArrayList<Thread> ();
-	
+	private int consecutiveTimeOnCPU = 0;
 	
 	/**
 	 * Constructor. Initialises fields.
@@ -60,6 +68,25 @@ public class PCB {
 	}
 	
 	
+	public void increaseProgramCounter() {
+		this.programCounter++;
+	}
+	
+	public void decreaseProgramCounter() {
+		this.programCounter--;
+	}
+	
+	public void decreaseRemainingTime(int time) {
+		this.remainingTime -= time;
+	}
+	
+	public void increaseConsecutiveTimeOnCPU() {
+		this.consecutiveTimeOnCPU++;
+	}
+	
+	public void resetConsecutiveTimeOnCPU() {
+		this.consecutiveTimeOnCPU = 0;
+	}
 	/**
 	 * @param id
 	 */
@@ -70,7 +97,10 @@ public class PCB {
 	public void setState(ProcessState state) {
 		this.state = state;
 	}
-
+	
+	public void setFailed(boolean failed) {
+		this.failed = failed;
+	}
 
 	/**
 	 * @param completionTime
@@ -115,6 +145,34 @@ public class PCB {
 		return this.state;
 	}
 
+	/**
+	 * @return the code
+	 */
+	public String getCode() {
+		return this.code;
+	}
+	
+	/**
+	 * @return the program counter.
+	 */
+	public int getProgramCounter() {
+		return this.programCounter;
+	}
+	
+	/**
+	 * @return the process variables.
+	 */
+	public Map<String, Integer> getVariables() {
+		return this.variables;
+	}
+	
+	/**
+	 * @return the failed status
+	 */
+	public boolean getFailed() {
+		return this.failed;
+	}
+	
 	/**
 	 * @return the priority
 	 */
@@ -149,6 +207,14 @@ public class PCB {
 	public int getRemainingTime() {
 		return this.remainingTime;
 	}
+	
+	/**
+	 * @return the consecutiveTimeOnCPU
+	 */
+	public int getConsecutiveTimeOnCPU() {
+		return this.consecutiveTimeOnCPU;
+	}
+
 
 
 
@@ -156,20 +222,28 @@ public class PCB {
 		
 		StringBuffer info = new StringBuffer();
 		
-		info.append("\nProcess #");
+		info.append("PCB #");
 		info.append(this.id);
 		info.append(" | Name: ");
 		info.append(this.name);
+		
+		if(this.failed) {
+			info.append(" | FAILED");
+		}
+		
 		info.append(" | State: ");
 		info.append(this.state);
-		info.append(" | Arrival Time: ");
+		info.append(" | Arrival: ");
 		info.append(this.arrivalTime);
-		info.append(" | Burst Time: ");
+		info.append(" | Burst: ");
 		info.append(this.burstTime);
-		info.append(" | Remaining Time: ");
+		info.append(" | Remaining: ");
 		info.append(this.remainingTime);
-		info.append(" | Completion Time: ");
+		info.append(" | Completion: ");
 		info.append(this.completionTime);
+		info.append(" | Program Counter: ");
+		info.append(this.programCounter);
+		
 		
 		return info.toString(); 
 		
diff --git a/os-simulator/src/main/java/com/com1032/assignment/ProcessCreation.java b/os-simulator/src/main/java/com/com1032/assignment/ProcessCreation.java
index 097ceba7aa8ce71dc5c21ec163f9175ff403b2a6..a9045e5429b54fb0e050326b2711bf76170bbe1c 100644
--- a/os-simulator/src/main/java/com/com1032/assignment/ProcessCreation.java
+++ b/os-simulator/src/main/java/com/com1032/assignment/ProcessCreation.java
@@ -21,19 +21,19 @@ public class ProcessCreation extends Thread {
 	/**A list of files with valid/invalid processes.*/
 	public List<File> processFiles = new ArrayList<File> ();
 	
-	/**Valid new processes added to the system.*/
-	private List<PCB> readyQueue = new ArrayList<PCB> ();
+	/**New processes added to the system.*/
+	private List<PCB> jobQueue = new ArrayList<PCB> ();
 	
+	/**The global time of the system.*/
 	private Clock globalTime = null;
 	
-	
 	/**
 	 * Constructor. Initialises fields.
 	 * 
 	 * @param jobQueue of the system.
 	 */
-	public ProcessCreation(List<PCB> readyQueue, Clock globalTime) {
-		this.readyQueue = readyQueue;
+	public ProcessCreation(Clock globalTime, List<PCB> jobQueue) {
+		this.jobQueue = jobQueue;
 		this.globalTime = globalTime;
 	}
 	
@@ -43,7 +43,7 @@ public class ProcessCreation extends Thread {
 	 */
 	@Override
 	public void run() {		
-		while(true) {			
+		while(true) {
 			//Fetches files where new processes are added.
 			this.fetchFiles();
 			
@@ -52,12 +52,10 @@ public class ProcessCreation extends Thread {
 			
 			//Temporarily stop executing for however milliseconds.
 			try {
-				Thread.sleep(200);
+				Thread.sleep(10);
 			} catch (InterruptedException e) {
 				e.printStackTrace();
 			}
-			
-			System.out.println("C" + this.readyQueue.size());
 		}
 	}
 	
@@ -71,11 +69,14 @@ public class ProcessCreation extends Thread {
 		File folder = new File("Processes/New_Processes");
 		File[] listOfFiles = folder.listFiles();
 		
+		
 		//Cycles through folder 'New_Processes' to look for files.
 		for(File processFile: listOfFiles) {
 			//If it finds file, store it.
 			if(processFile.isFile()) {
-				this.processFiles.add(processFile);
+				if(!this.processFiles.contains(processFile)) {
+					this.processFiles.add(processFile);	
+				}
 			}
 		}
 	}
@@ -100,20 +101,26 @@ public class ProcessCreation extends Thread {
 			
 			//Reads file line by line to read code.
 			while (fileReader.hasNextLine()) {
-				code.append("\n");
 				code.append(fileReader.nextLine());
+				
+				//Only adds a line break if there is another line.
+				if(fileReader.hasNextLine()) {
+					code.append("\n");
+				}
+				
 			}
 			
 			//Makes PCB object.
 			PCB pcb = new PCB(processName, priority, code.toString());
-			pcb.setArrivalTime(this.globalTime.time);
-			this.readyQueue.add(pcb);
+			pcb.setArrivalTime(this.globalTime.getTime());
+			this.jobQueue.add(pcb);
 			
 			//Closes file.
 			fileReader.close();
 			
 			//Moves file to Valid folder.
 			this.fileHandling(this.processFiles.get(0), true);
+			this.processFiles.remove(0);
 		}
 		
 		//Ran when file is in wrong format.
diff --git a/os-simulator/src/main/java/com/com1032/assignment/ProcessDispatcher.java b/os-simulator/src/main/java/com/com1032/assignment/ProcessDispatcher.java
index c2a0ad48487ecfc9812551282ac4f6efdc41e865..870162e94f069cee6b23d436f2b2f6435340e1d3 100644
--- a/os-simulator/src/main/java/com/com1032/assignment/ProcessDispatcher.java
+++ b/os-simulator/src/main/java/com/com1032/assignment/ProcessDispatcher.java
@@ -16,22 +16,18 @@ public class ProcessDispatcher extends Thread {
 	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> waitingQueue = new ArrayList<PCB> ();
+	/**Processes blocked because of I/O.*/
+	private List<PCB> blockedQueue = new ArrayList<PCB> ();
 	/**Processes that have finished executing.*/
 	private List<PCB> terminatedQueue = new ArrayList<PCB> ();
-	/**Processes that are using CPU.*/
-	private List<PCB> cpuQueue = new ArrayList<PCB> ();
-	
-	/**The latest ran process.*/
-	private PCB scheduledProcess = null;
 	
-	/**The time spent running of the previous process.*/
-	private int previousProcessTimeSpent = 0;
+	private List<PCB> cpuQueue = new ArrayList<PCB> ();
 	
 	/**The global time of the system.*/
 	private Clock globalTime = null;
 	
+	private Hardware hardware = null;
+	
 	/**The info report of the process scheduler.*/
 	private StringBuffer report = new StringBuffer();
 	
@@ -44,39 +40,24 @@ public class ProcessDispatcher extends Thread {
 	/**
 	 * Constructor. Initialises fields
 	 * 
-	 * @param jobQueue
 	 * @param readyQueue
-	 * @param waitingQueue
+	 * @param blockedQueue
 	 * @param terminatedQueue
-	 * @param cPUQueue
+	 * @param cpuQueue
+	 * @param globalTime
 	 */
-	public ProcessDispatcher(List<PCB> jobQueue, List<PCB> readyQueue, List<PCB> waitingQueue, List<PCB> terminatedQueue, List<PCB> cpuQueue, Clock globalTime) {
+	public ProcessDispatcher(Clock globalTime, Hardware hardware, List<PCB> jobQueue, List<PCB> readyQueue,
+			List<PCB> blockedQueue, List<PCB> terminatedQueue, 
+			List<PCB> cpuQueue) {
 		super();
 		this.jobQueue = jobQueue;
 		this.readyQueue = readyQueue;
-		this.waitingQueue = waitingQueue;
+		this.blockedQueue = blockedQueue;
 		this.terminatedQueue = terminatedQueue;
 		this.cpuQueue = cpuQueue;
 		
 		this.globalTime = globalTime;
-	}
-	
-	
-	/**
-	 * @return report of scheduler as string.
-	 */
-	public String getReport() {
-		return this.report.toString();
-	}
-	
-	
-	/**
-	 * @param algorithm wanted.
-	 * @param quantum wanted.
-	 */
-	public void setAlgorithm(SchedulingAlgorithm algorithm, int quantum) {
-		this.algorithm = algorithm;
-		this.quantum = quantum;
+		this.hardware = hardware;
 	}
 	
 	
@@ -88,47 +69,82 @@ public class ProcessDispatcher extends Thread {
 	public void run() {
 		
 		while(true) {
-			System.out.println("D" + this.readyQueue.size());
+//			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(100);
+				Thread.sleep(0);
 			} catch (InterruptedException e) {
 				e.printStackTrace();
 			}
 			
-			//---Termination Check---
-			//Checks if any processes have finished.
-			if(this.scheduledProcess != null) {
+			
+			//---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));
+			}
+			
+			//---Termination/Block Check---
+			//Checks if any CPU processes have updated.
+			if(!this.cpuQueue.isEmpty()) {
 				//Terminates process if process is done.
-				if(this.scheduledProcess.getRemainingTime() <= 0) {
-					this.terminateProcess(this.scheduledProcess);
-				}	
+				if(this.cpuQueue.get(0).getState() == ProcessState.TERMINATED) {
+					this.terminateProcess(this.cpuQueue.get(0));
+				}
+				
+				//Block process if process is blocked.
+				else if(this.cpuQueue.get(0).getState() == ProcessState.BLOCKED) {
+					this.blockProcess(this.cpuQueue.get(0));
+				}
 			}
-		
+			
+			//---Termination/Block Check---
+			//Checks if any blocked processes have updated.
+			if(!this.blockedQueue.isEmpty()) {
+				//Terminates process if process is done.
+				if(this.blockedQueue.get(0).getState() == ProcessState.TERMINATED) {
+					this.terminateProcess(this.blockedQueue.get(0));
+				}
+				
+				//Block process if process is blocked.
+				else if(this.blockedQueue.get(0).getState() == ProcessState.READY) {
+					this.readyProcess(this.blockedQueue.get(0));
+				}
+			}
+			
+			
 			//---Empty Ready Queue---
 			//If no processes are ready yet, increase time by 1.
 			if(this.readyQueue.isEmpty()) {
 				
-				if(this.scheduledProcess != null) {
+				if(!this.cpuQueue.isEmpty()) {
 					
 					//In case of round robin, resets the time spent when above quantum.
-					if(algorithm == SchedulingAlgorithm.RR && this.previousProcessTimeSpent >= quantum) {
-						this.previousProcessTimeSpent = 0;
+					if(algorithm == SchedulingAlgorithm.RR && this.cpuQueue.get(0).getConsecutiveTimeOnCPU() >= quantum) {
+						this.cpuQueue.get(0).resetConsecutiveTimeOnCPU();
 					}
 					
-//					this.runProcess(this.scheduledProcess);
 				}
 				else {
-					this.globalTime.time++;
+					this.globalTime.increaseTime(1);
 				}
 				
 				continue;
 			}
 			
-			
 			//---Scheduling---
 			//Preemptive means processes can be interrupted. Constantly checked.
 			//Non-Preemptive means processes run until finished.
-			switch(algorithm) {
+			switch(this.algorithm) {
 			case FIFO:
 				runFIFO();
 				break;
@@ -142,57 +158,64 @@ public class ProcessDispatcher extends Thread {
 				runRR(quantum);
 				break;
 			}
-			
-//			//---Running---
-//			//Run the scheduled process, if any.
-//			if(this.scheduledProcess != null) {
-//				this.runProcess(this.scheduledProcess);
-//			}
 
 		}
 		
 	}
 	
 	
+	/**
+	 * @return report of scheduler as string.
+	 */
+	public String getReport() {
+		return this.report.toString();
+	}
+	
+	
+	/**
+	 * @param algorithm wanted.
+	 * @param quantum wanted.
+	 */
+	public void setAlgorithm(SchedulingAlgorithm algorithm, int quantum) {
+		this.algorithm = algorithm;
+		this.quantum = quantum;
+	}
+	
 	/**
 	 * Function used to schedule a process to CPU.
 	 * 
 	 * @param process to schedule.
 	 */
 	public void scheduleProcess(PCB process) {
-		//Only schedules if not running already.
-		if(this.scheduledProcess != process) {
-			
-			this.previousProcessTimeSpent = 0;
-			
-			//Ran if there is already a process running.
-			if(this.scheduledProcess != null) {
-				this.cpuQueue.remove(this.scheduledProcess);
-				this.contextSwitch(process);
+		//Checks if queue is empty first.
+		if(!this.cpuQueue.isEmpty()) {
+			//If it is not, check it is not same process being scheduled.
+			if(this.cpuQueue.get(0) != process) {
+				
+				this.cpuQueue.get(0).resetConsecutiveTimeOnCPU();
+				
+				//Ran if there is already a process running.
+				this.contextSwitch(this.cpuQueue.get(0));
+				
+				//Update scheduler attributes.
+				this.report.append("\n- Schedule @ " + this.globalTime.getTime() + ": " + process + "\n");
+				process.setState(ProcessState.RUNNING);
+				this.cpuQueue.add(process);
+				this.readyQueue.remove(process);
 			}
-			
+		}
+		else {
 			//Update scheduler attributes.
-			this.report.append("\n- Schedule @ " + this.globalTime.time + ":" + process + "\n");
+			this.report.append("\n- Schedule @ " + this.globalTime.getTime() + ": " + process + "\n");
+//			System.out.println(process);
 			process.setState(ProcessState.RUNNING);
-			this.scheduledProcess = process;
-			this.cpuQueue.add(this.scheduledProcess);
+			this.cpuQueue.add(process);
 			this.readyQueue.remove(process);
 		}
+
 	}
 	
 	
-//	/**
-//	 * Function used to run a process.
-//	 * 
-//	 * @param process to run.
-//	 */
-//	public void runProcess(PCB process) {
-//		this.previousProcessTimeSpent++;
-//		process.setRemainingTime(process.getRemainingTime() - 1);
-//		this.globalTime.time++;
-//	}
-	
-	
 	/**
 	 * Function used when terminating a process.
 	 * 
@@ -200,15 +223,42 @@ public class ProcessDispatcher extends Thread {
 	 */
 	public void terminateProcess(PCB process) {
 		//Update process properties.
-		process.setCompletionTime(this.globalTime.time);
+		process.setCompletionTime(this.globalTime.getTime());
 		process.setState(ProcessState.TERMINATED);
 		
 		//Update scheduler info.
-		this.scheduledProcess = null;
-		this.cpuQueue.remove(this.scheduledProcess);
+		this.cpuQueue.remove(process);
 		this.readyQueue.remove(process);
+		this.blockedQueue.remove(process);
 		this.terminatedQueue.add(process);
-		this.report.append("\n- Terminated @ " + this.globalTime.time + ":" + process + "\n");
+		this.report.append("\n- Terminated @ " + this.globalTime.getTime() + ": " + process + "\n");
+	}
+	
+	/**
+	 * Function used when blocking a process.
+	 * 
+	 * @param process to block.
+	 */
+	public void blockProcess(PCB process) {
+		//Update scheduler info.
+		this.cpuQueue.remove(process);
+		this.readyQueue.remove(process);
+		this.blockedQueue.add(process);
+		this.report.append("\n- Blocking @ " + this.globalTime.getTime() + ": " + process + "\n");
+	}
+	
+	/**
+	 * Function used when blocking a process.
+	 * 
+	 * @param process to block.
+	 */
+	public void readyProcess(PCB process) {
+		//Update scheduler info.
+		this.jobQueue.remove(process);
+		this.cpuQueue.remove(process);
+		this.blockedQueue.remove(process);
+		this.readyQueue.add(process);
+		this.report.append("\n- Ready @ " + this.globalTime.getTime() + ": " + process + "\n");
 	}
 	
 	
@@ -218,9 +268,10 @@ public class ProcessDispatcher extends Thread {
 	 * @param process to suspend.
 	 */
 	public void contextSwitch(PCB process) {
-		this.readyQueue.add(this.scheduledProcess);
-		this.report.append("\n- Suspending @ " + this.globalTime.time + ":" + this.scheduledProcess + "\n");
-		this.scheduledProcess.setState(ProcessState.READY);
+		this.cpuQueue.remove(process);
+		this.readyQueue.add(process);
+		this.report.append("\n- Suspending @ " + this.globalTime.getTime() + ": " + process + "\n");
+		process.setState(ProcessState.READY);
 	}
 	
 	
@@ -231,12 +282,12 @@ public class ProcessDispatcher extends Thread {
 	 */
 	public void runFIFO() {
 		//Non-Preemptive, won't access new process from ready queue if one is already running.
-		if(this.scheduledProcess == null) {
+		if(this.cpuQueue.isEmpty()) {
 			PCB currentProcess = this.readyQueue.get(0);
 			this.scheduleProcess(currentProcess);
 		}
 		else {
-			this.scheduleProcess(this.scheduledProcess);
+			this.scheduleProcess(this.cpuQueue.get(0));
 		}
 		
 	}
@@ -249,7 +300,7 @@ public class ProcessDispatcher extends Thread {
 	 */
 	public void runSPF() {
 		//Non-Preemptive, won't access new process from ready queue if one is already running.
-		if(this.scheduledProcess == null) {
+		if(this.cpuQueue.isEmpty()) {
 			
 			//Find smallest burst time process.
 			PCB currentProcess = this.readyQueue.get(0);
@@ -262,7 +313,7 @@ public class ProcessDispatcher extends Thread {
 			this.scheduleProcess(currentProcess);
 		}
 		else {
-			this.scheduleProcess(this.scheduledProcess);
+			this.scheduleProcess(this.cpuQueue.get(0));
 		}
 		
 	}
@@ -282,7 +333,15 @@ public class ProcessDispatcher extends Thread {
 			}
 		}
 		
-		this.scheduleProcess(currentProcess);
+		if(!this.cpuQueue.isEmpty()) {
+			if(currentProcess.getRemainingTime() < this.cpuQueue.get(0).getRemainingTime()) {
+				this.scheduleProcess(currentProcess);
+			}
+		}
+		else {
+			this.scheduleProcess(currentProcess);
+		}
+
 		
 	}
 	
@@ -297,7 +356,17 @@ public class ProcessDispatcher extends Thread {
 	public void runRR(int quantum) {
 		PCB currentProcess = this.readyQueue.get(0);
 		
-		if(this.previousProcessTimeSpent >= quantum || this.scheduledProcess == null) {
+		if(!this.cpuQueue.isEmpty()) {
+			//One core = 4 ticks per instruction, therefore quantum + 3
+			//Two core = 3 ticks per instruction, therefore quantum + 2
+			//Three core = 2 ticks per instruction, therefore quantum + 1
+			//Four core = 1 ticks per instruction, therefore quantum + 0
+			
+			if(this.cpuQueue.get(0).getConsecutiveTimeOnCPU() >= (quantum + (4 - this.hardware.getCoresPerProcessor()))) {
+				this.scheduleProcess(currentProcess);
+			}
+		}
+		else {
 			this.scheduleProcess(currentProcess);
 		}
 	}
diff --git a/os-simulator/src/main/java/com/com1032/assignment/ProcessScheduler.java b/os-simulator/src/main/java/com/com1032/assignment/ProcessScheduler.java
index 1f79fdd2b68d1d3a301858592428c626785b785f..2706c213bdd1135531a03b6da0d76e0ce1eea102 100644
--- a/os-simulator/src/main/java/com/com1032/assignment/ProcessScheduler.java
+++ b/os-simulator/src/main/java/com/com1032/assignment/ProcessScheduler.java
@@ -17,36 +17,47 @@ public class ProcessScheduler {
 	/**Processes ready to be executed.*/
 	private List<PCB> readyQueue = new ArrayList<PCB> ();
 	/**Processes waiting for I/O.*/
-	private List<PCB> waitingQueue = new ArrayList<PCB> ();
+	private List<PCB> blockedQueue = new ArrayList<PCB> ();
 	/**Processes that have finished executing.*/
 	private List<PCB> terminatedQueue = new ArrayList<PCB> ();
-	/**Processes that are using CPU.*/
+	/**Processes running on CPU.*/
 	private List<PCB> cpuQueue = new ArrayList<PCB> ();
 	
-	/**The latest ran process.*/
-	private Process scheduledProcess = null;
+	/**The scheduling algorithm to use.*/
+	private SchedulingAlgorithm algorithm = SchedulingAlgorithm.FIFO;
 	
-	/**The time spent running of the previous process.*/
-	private int previousProcessTimeSpent = 0;
+	/**The quantum to use.*/
+	private int quantum = 0;
 	
 	/**The global time of the system.*/
-	private Clock globalTime = new Clock();
+	private OS os = null;
 	
-	/**The info report of the process scheduler.*/
-	private StringBuffer report = new StringBuffer();
 	
+	public ProcessScheduler(OS os) {
+		this.os = os;
+	}
 	
 	
-	/**
-	 * @param args
-	 */
-	public static void main(String[] args) {
-		ProcessScheduler PS = new ProcessScheduler();
-		ProcessCreation pc = new ProcessCreation(PS.readyQueue, PS.globalTime);
-		ProcessDispatcher pd = new ProcessDispatcher(PS.jobQueue, PS.readyQueue, PS.waitingQueue, PS.terminatedQueue, PS.cpuQueue, PS.globalTime);
+	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/Process.java b/os-simulator/src/main/java/com/com1032/pss/Process.java
similarity index 97%
rename from os-simulator/src/main/java/com/com1032/assignment/Process.java
rename to os-simulator/src/main/java/com/com1032/pss/Process.java
index 4efbf0631998bf2b3692fd53c41013996782b53c..b7aff81616ec7c6293819ab6b90b74a09ce740c6 100644
--- a/os-simulator/src/main/java/com/com1032/assignment/Process.java
+++ b/os-simulator/src/main/java/com/com1032/pss/Process.java
@@ -1,10 +1,9 @@
 /**
  * Process.java
  */
-package com.com1032.assignment;
+package com.com1032.pss;
 
-import java.util.ArrayList;
-import java.util.List;
+import com.com1032.assignment.ProcessState;
 
 /**
  * @author felipedabrantes
diff --git a/os-simulator/src/main/java/com/com1032/assignment/ProcessSchedulerSimulator.java b/os-simulator/src/main/java/com/com1032/pss/ProcessSchedulerSimulator.java
similarity index 90%
rename from os-simulator/src/main/java/com/com1032/assignment/ProcessSchedulerSimulator.java
rename to os-simulator/src/main/java/com/com1032/pss/ProcessSchedulerSimulator.java
index 546e17530cfcd52f4a411c3f3d3297904d7e5905..f216e600867a48850a605e9c5d2b6fe0bd3a2ac3 100644
--- a/os-simulator/src/main/java/com/com1032/assignment/ProcessSchedulerSimulator.java
+++ b/os-simulator/src/main/java/com/com1032/pss/ProcessSchedulerSimulator.java
@@ -1,11 +1,15 @@
 /**
  * ProcessScheduler.java
  */
-package com.com1032.assignment;
+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;
+
 /**
  * @author felipedabrantes
  *
@@ -15,12 +19,8 @@ public class ProcessSchedulerSimulator {
 	private List<Process> jobQueue = new ArrayList<Process> ();
 	/**Processes ready to be executed.*/
 	private List<Process> readyQueue = new ArrayList<Process> ();
-	/**Processes waiting for I/O.*/
-	private List<Process> waitingQueue = new ArrayList<Process> ();
 	/**Processes that have finished executing.*/
 	private List<Process> terminatedQueue = new ArrayList<Process> ();
-	/**Processes that are using CPU.*/
-	private List<Process> CPUQueue = new ArrayList<Process> ();
 	
 	/**The latest ran process.*/
 	private Process scheduledProcess = null;
@@ -101,7 +101,7 @@ public class ProcessSchedulerSimulator {
 					this.runProcess(this.scheduledProcess);
 				}
 				else {
-					this.globalTime.time++;
+					this.globalTime.increaseTime(1);
 				}
 				
 				continue;
@@ -155,7 +155,7 @@ public class ProcessSchedulerSimulator {
 	public void addProcessToJob(List<Process> processes) {
 		for(Process process: processes) {
 			this.jobQueue.add(process);
-			this.report.append("\n- Added to Job Queue @ " + this.globalTime.time + ":" + process + "\n");
+			this.report.append("\n- Added to Job Queue @ " + this.globalTime.getTime() + ":" + process + "\n");
 		}
 	}
 	
@@ -177,7 +177,7 @@ public class ProcessSchedulerSimulator {
 			}
 			
 			//Update scheduler attributes.
-			this.report.append("\n- Schedule @ " + this.globalTime.time + ":" + process + "\n");
+			this.report.append("\n- Schedule @ " + this.globalTime.getTime() + ":" + process + "\n");
 			process.setState(ProcessState.RUNNING);
 			this.scheduledProcess = process;
 			this.readyQueue.remove(process);
@@ -193,7 +193,7 @@ public class ProcessSchedulerSimulator {
 	public void runProcess(Process process) {
 		this.previousProcessTimeSpent++;
 		process.setRemainingTime(process.getRemainingTime() - 1);
-		this.globalTime.time++;
+		this.globalTime.increaseTime(1);
 	}
 	
 	
@@ -204,14 +204,14 @@ public class ProcessSchedulerSimulator {
 	 */
 	public void terminateProcess(Process process) {
 		//Update process properties.
-		process.setCompletionTime(this.globalTime.time);
+		process.setCompletionTime(this.globalTime.getTime());
 		process.setState(ProcessState.TERMINATED);
 		
 		//Update scheduler info.
 		this.scheduledProcess = null;
 		this.readyQueue.remove(process);
 		this.terminatedQueue.add(process);
-		this.report.append("\n- Terminated @ " + this.globalTime.time + ":" + process + "\n");
+		this.report.append("\n- Terminated @ " + this.globalTime.getTime() + ":" + process + "\n");
 	}
 	
 	
@@ -222,7 +222,7 @@ public class ProcessSchedulerSimulator {
 	 */
 	public void contextSwitch(Process process) {
 		this.readyQueue.add(this.scheduledProcess);
-		this.report.append("\n- Suspending @ " + this.globalTime.time + ":" + this.scheduledProcess + "\n");
+		this.report.append("\n- Suspending @ " + this.globalTime.getTime() + ":" + this.scheduledProcess + "\n");
 		this.scheduledProcess.setState(ProcessState.READY);
 	}
 	
@@ -236,7 +236,7 @@ public class ProcessSchedulerSimulator {
 		List<Process> updatedProcesses = new ArrayList<Process> ();
 		
 		for(Process process: this.jobQueue) {
-			if(process.getArrivalTime() == this.globalTime.time) {
+			if(process.getArrivalTime() == this.globalTime.getTime()) {
 				updatedProcesses.add(process);
 			}
 		}
@@ -246,7 +246,7 @@ public class ProcessSchedulerSimulator {
 			this.jobQueue.remove(process);
 			this.readyQueue.add(process);
 			
-			this.report.append("\n- Added to Ready Queue @ " + this.globalTime.time + ":" + process + "\n");
+			this.report.append("\n- Added to Ready Queue @ " + this.globalTime.getTime() + ":" + process + "\n");
 		}
 	}