diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..27bb48f7a41b5c818394b28967a19b8232757f31
Binary files /dev/null and b/.DS_Store differ
diff --git a/os-simulator/OSInput.txt.txt b/os-simulator/OSInput.txt.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1321be9ee2be0a2f6a6fc5225ac65fde4ed40b09
--- /dev/null
+++ b/os-simulator/OSInput.txt.txt
@@ -0,0 +1,4 @@
+1, A, 0, 4, 10
+2, B, 4, 50, 2
+3, C, 10, 4, 10
+4, D, 20, 2, 10
\ No newline at end of file
diff --git a/os-simulator/src/.DS_Store b/os-simulator/src/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6
Binary files /dev/null and b/os-simulator/src/.DS_Store differ
diff --git a/os-simulator/src/main/.DS_Store b/os-simulator/src/main/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6
Binary files /dev/null and b/os-simulator/src/main/.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
new file mode 100644
index 0000000000000000000000000000000000000000..b9acd91cc01b1c287ab0459ba1e1c4141624422a
--- /dev/null
+++ b/os-simulator/src/main/java/com/com1032/assignment/Clock.java
@@ -0,0 +1,21 @@
+/**
+ * 
+ */
+package com.com1032.assignment;
+
+/**
+ * @author felipedabrantes
+ *
+ */
+public class Clock {
+	
+	public int time = 0;
+	
+	
+	
+	@Override
+	public String toString() {
+		return String.valueOf(this.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
new file mode 100644
index 0000000000000000000000000000000000000000..8372bb98e699c8315c0c545368d85a5405704dc7
--- /dev/null
+++ b/os-simulator/src/main/java/com/com1032/assignment/OS.java
@@ -0,0 +1,103 @@
+/**
+ * OS.java
+ */
+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
+ *
+ */
+public class OS {
+
+	/**The global time of the OS.*/
+	private Clock globalTime = new Clock();
+	/**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>();
+
+	
+	/**
+	 * Constructor. Initialises fields.
+	 */
+	public OS() {
+		
+		this.pss = new ProcessSchedulerSimulator(this.globalTime);
+	}
+
+	/**
+	 * @param args
+	 * @throws FileNotFoundException
+	 * @throws IOException
+	 */
+	public static void main(String[] args) throws FileNotFoundException {
+		OS os = new OS();
+
+		os.addProcess("OSInput.txt");
+		os.runProcessScheduling();
+
+	}
+
+	
+	/**
+	 * Used to a single process to OS.
+	 * @param process
+	 */
+	public void addProcess(Process process) {
+		this.processes.add(process);
+	}
+	
+	
+	/**
+	 * Used to add processes from a file to the OS.
+	 * 
+	 * @param fileName of the processes file.
+	 * 
+	 * @throws FileNotFoundException if no file is found.
+	 */
+	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.");
+		}
+
+	}
+
+	
+	/**
+	 * Runs process scheduling simulation with processes in OS.
+	 */
+	public void runProcessScheduling() {
+		pss.addProcessToJob(this.processes);
+		pss.run(SchedulingAlgorithm.SPF, 3);
+		System.out.println(pss.getReport());
+	}
+
+}
diff --git a/os-simulator/src/main/java/com/com1032/assignment/Process.java b/os-simulator/src/main/java/com/com1032/assignment/Process.java
new file mode 100644
index 0000000000000000000000000000000000000000..4efbf0631998bf2b3692fd53c41013996782b53c
--- /dev/null
+++ b/os-simulator/src/main/java/com/com1032/assignment/Process.java
@@ -0,0 +1,173 @@
+/**
+ * Process.java
+ */
+package com.com1032.assignment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author felipedabrantes
+ *
+ */
+public class Process {
+	/**The unique ID to identify the process.*/
+	private int id = 0;
+	/**The name of the process.*/
+	private String name = null;
+	/**The state of the process.*/
+	private ProcessState state = ProcessState.NEW;
+	
+	//---Attributes for process scheduling. ---
+	/**States the importance of the process. Higher is more important.*/
+	private int priority = 0;
+	/**Global time at which process arrives to ready queue.*/
+	private int arrivalTime = 0;
+	/**Global time at which process completes its execution.*/
+	private int completionTime = -1;
+	/**Time required for CPU execution.*/
+	private final int burstTime;
+	/**Time remaining for process finished.*/
+	private int remainingTime = 0;
+	
+	
+//	private List<Thread> threads = new ArrayList<Thread> ();
+	
+	
+	/**
+	 * Constructor. Initialises fields.
+	 *
+	 * @param id
+	 * @param state
+	 * @param priority
+	 * @param arrivalTime
+	 * @param completionTime
+	 * @param burstTime
+	 */
+	public Process(int id, String name, int priority, int burstTime, int arrivalTime) {
+		super();
+		this.id = id;
+		this.name = name;
+		this.priority = priority;
+		this.arrivalTime = arrivalTime;
+		this.burstTime = burstTime;
+		this.remainingTime = burstTime;
+	}
+
+
+	/**
+	 * @param id
+	 */
+	public void setId(int id) {
+		this.id = id;
+	}
+	
+	public void setState(ProcessState state) {
+		this.state = state;
+	}
+
+
+	/**
+	 * @param completionTime
+	 */
+	public void setCompletionTime(int completionTime) {
+		this.completionTime = completionTime;
+	}
+	
+	
+	/**
+	 * @param remainingTime
+	 */
+	public void setRemainingTime(int remainingTime) {
+		this.remainingTime = remainingTime;
+	}
+
+	/**
+	 * @param arrivalTime
+	 */
+	public void setArrivalTime(int arrivalTime) {
+		this.arrivalTime = arrivalTime;
+	}
+
+	/**
+	 * @return the id
+	 */
+	public int getId() {
+		return this.id;
+	}
+
+	/**
+	 * @return the name
+	 */
+	public String getName() {
+		return this.name;
+	}
+	
+	/**
+	 * @return the state
+	 */
+	public ProcessState getState() {
+		return this.state;
+	}
+
+	/**
+	 * @return the priority
+	 */
+	public int getPriority() {
+		return this.priority;
+	}
+
+	/**
+	 * @return the arrivalTime
+	 */
+	public int getArrivalTime() {
+		return this.arrivalTime;
+	}
+
+	/**
+	 * @return the completionTime
+	 */
+	public int getCompletionTime() {
+		return this.completionTime;
+	}
+	
+	/**
+	 * @return the burstTime
+	 */
+	public int getBurstTime() {
+		return this.burstTime;
+	}
+	
+	/**
+	 * @return the burstTime
+	 */
+	public int getRemainingTime() {
+		return this.remainingTime;
+	}
+
+
+
+	public String toString() {
+		
+		StringBuffer info = new StringBuffer();
+		
+		info.append("\nProcess #");
+		info.append(this.id);
+		info.append(" | Name: ");
+		info.append(this.name);
+		info.append(" | State: ");
+		info.append(this.state);
+		info.append(" | Arrival Time: ");
+		info.append(this.arrivalTime);
+		info.append(" | Burst Time: ");
+		info.append(this.burstTime);
+		info.append(" | Remaining Time: ");
+		info.append(this.remainingTime);
+		info.append(" | Completion Time: ");
+		info.append(this.completionTime);
+		
+		return info.toString(); 
+		
+	}
+
+}
diff --git a/os-simulator/src/main/java/com/com1032/assignment/ProcessSchedulerSimulator.java b/os-simulator/src/main/java/com/com1032/assignment/ProcessSchedulerSimulator.java
new file mode 100644
index 0000000000000000000000000000000000000000..546e17530cfcd52f4a411c3f3d3297904d7e5905
--- /dev/null
+++ b/os-simulator/src/main/java/com/com1032/assignment/ProcessSchedulerSimulator.java
@@ -0,0 +1,331 @@
+/**
+ * ProcessScheduler.java
+ */
+package com.com1032.assignment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author felipedabrantes
+ *
+ */
+public class ProcessSchedulerSimulator {
+	/**New processes added to the system.*/
+	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;
+	
+	/**The time spent running of the previous process.*/
+	private int previousProcessTimeSpent = 0;
+	
+	/**The global time of the system.*/
+	private Clock globalTime = null;
+	
+	/**The info report of the process scheduler.*/
+	private StringBuffer report = new StringBuffer();
+	
+	
+	/**
+	 * Constructor. Sets global time.
+	 * 
+	 * @param globalTime
+	 */
+	public ProcessSchedulerSimulator(Clock globalTime) {
+		this.globalTime = globalTime;
+	}
+	
+	
+	/**
+	 * @return report of scheduler as string.
+	 */
+	public String getReport() {
+		return this.report.toString();
+	}
+	
+	
+	/**
+	 * Main function to run processes with the desired algorithm.
+	 * 
+	 * Quantum is needed for specific algorithms.
+	 * 
+	 * @param algorithm to use.
+	 * 
+	 * @param quantum for round robin algorithm.
+	 */
+	public void run(SchedulingAlgorithm algorithm, int quantum) {
+		
+		//Adding configuration info.
+		this.report.insert(0, "---Process Scheduler---\n* Algorithm: " + algorithm + "\n* Quantum: " + quantum + "\n\n");
+//		this.report.append("Process Scheduler");
+//		this.report.append("\n* Algorithm: " + algorithm);
+//		this.report.append("\n* Quantum: " + quantum);
+		
+		
+		while(!this.jobQueue.isEmpty() || !this.readyQueue.isEmpty() || this.scheduledProcess != null) {		
+			
+			//---Arrival---
+			//Update ready queue to see if any processes are ready.
+			this.updateReadyQueue();
+			
+			
+			//---Termination Check---
+			//Checks if any processes have finished.
+			if(this.scheduledProcess != null) {
+				//Terminates process if process is done.
+				if(this.scheduledProcess.getRemainingTime() == 0) {
+					this.terminateProcess(this.scheduledProcess);
+				}	
+			}
+		
+			//---Empty Ready Queue---
+			//If no processes are ready yet, increase time by 1.
+			if(this.readyQueue.isEmpty()) {
+				
+				if(this.scheduledProcess != null) {
+					
+					//In case of round robin, resets the time spent when above quantum.
+					if(algorithm == SchedulingAlgorithm.RR && this.previousProcessTimeSpent >= quantum) {
+						this.previousProcessTimeSpent = 0;
+					}
+					
+					this.runProcess(this.scheduledProcess);
+				}
+				else {
+					this.globalTime.time++;
+				}
+				
+				continue;
+			}
+			
+			//---Scheduling---
+			//Preemptive means processes can be interrupted. Constantly checked.
+			//Non-Preemptive means processes run until finished.
+			switch(algorithm) {
+			case FIFO:
+				runFIFO();
+				break;
+			case SRTF:
+				runSRTF();
+				break;
+			case SPF:
+				runSPF();
+				break;
+			case RR:
+				runRR(quantum);
+				break;
+			}
+			
+			//---Running---
+			//Run the scheduled process, if any.
+			if(this.scheduledProcess != null) {
+				this.runProcess(this.scheduledProcess);
+			}
+			
+		}
+		
+	}
+	
+	
+	/**
+	 * Adds process to system (job queue).
+	 * 
+	 * @param process to add to system.
+	 */
+	public void addProcessToJob(Process process) {
+		this.jobQueue.add(process);
+		this.report.append("\n- Added to Job Queue: " + process + "\n");
+	}
+	
+	
+	/**
+	 * Adds processes given in list to system (job queue).
+	 * 
+	 * @param processes list to add to system.
+	 */
+	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");
+		}
+	}
+	
+	
+	/**
+	 * Function used to schedule a process to CPU.
+	 * 
+	 * @param process to schedule.
+	 */
+	public void scheduleProcess(Process 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.contextSwitch(process);
+			}
+			
+			//Update scheduler attributes.
+			this.report.append("\n- Schedule @ " + this.globalTime.time + ":" + process + "\n");
+			process.setState(ProcessState.RUNNING);
+			this.scheduledProcess = process;
+			this.readyQueue.remove(process);
+		}
+	}
+	
+	
+	/**
+	 * Function used to run a process.
+	 * 
+	 * @param process to run.
+	 */
+	public void runProcess(Process process) {
+		this.previousProcessTimeSpent++;
+		process.setRemainingTime(process.getRemainingTime() - 1);
+		this.globalTime.time++;
+	}
+	
+	
+	/**
+	 * Function used when terminating a process.
+	 * 
+	 * @param process to terminate.
+	 */
+	public void terminateProcess(Process process) {
+		//Update process properties.
+		process.setCompletionTime(this.globalTime.time);
+		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");
+	}
+	
+	
+	/**
+	 * Function used when suspending a process.
+	 * 
+	 * @param process to suspend.
+	 */
+	public void contextSwitch(Process process) {
+		this.readyQueue.add(this.scheduledProcess);
+		this.report.append("\n- Suspending @ " + this.globalTime.time + ":" + this.scheduledProcess + "\n");
+		this.scheduledProcess.setState(ProcessState.READY);
+	}
+	
+	
+	/**
+	 * Updates ready queue by checking arrival times of processes in job queue.
+	 * 
+	 * If arrival time equals global time add it to ready queue.
+	 */
+	public void updateReadyQueue() {
+		List<Process> updatedProcesses = new ArrayList<Process> ();
+		
+		for(Process process: this.jobQueue) {
+			if(process.getArrivalTime() == this.globalTime.time) {
+				updatedProcesses.add(process);
+			}
+		}
+		
+		for(Process process: updatedProcesses) {
+			process.setState(ProcessState.READY);
+			this.jobQueue.remove(process);
+			this.readyQueue.add(process);
+			
+			this.report.append("\n- Added to Ready Queue @ " + this.globalTime.time + ":" + process + "\n");
+		}
+	}	
+	
+	/**
+	 * Runs the FIFO algorithm.
+	 * 
+	 * First-In-First-Out.
+	 */
+	public void runFIFO() {
+		//Non-Preemptive, won't access new process from ready queue if one is already running.
+		if(this.scheduledProcess == null) {
+			Process currentProcess = this.readyQueue.get(0);
+			this.scheduleProcess(currentProcess);
+		}
+		else {
+			this.scheduleProcess(this.scheduledProcess);
+		}
+		
+	}
+	
+	
+	/**
+	 * Runs the SPF algorithm.
+	 * 
+	 * Shortest Process First.
+	 */
+	public void runSPF() {
+		//Non-Preemptive, won't access new process from ready queue if one is already running.
+		if(this.scheduledProcess == null) {
+			
+			//Find smallest burst time process.
+			Process currentProcess = this.readyQueue.get(0);
+			for(Process process: this.readyQueue) {
+				if(process.getBurstTime() < currentProcess.getBurstTime()) {
+					currentProcess = process;
+				}
+			}
+			
+			this.scheduleProcess(currentProcess);
+		}
+		else {
+			this.scheduleProcess(this.scheduledProcess);
+		}
+		
+	}
+	
+	
+	/**
+	 * Runs the SRTF algorithm.
+	 * 
+	 * Shortest Remaining Time First.
+	 */
+	public void runSRTF() {
+		//Find smallest remaining time process.
+		Process currentProcess = this.readyQueue.get(0);
+		for(Process process: this.readyQueue) {
+			if(process.getRemainingTime() < currentProcess.getRemainingTime()) {
+				currentProcess = process;
+			}
+		}
+		
+		this.scheduleProcess(currentProcess);
+		
+	}
+	
+	
+	/**
+	 * Runs the RR algorithm with the given quantum..
+	 * 
+	 * Round Robin.
+	 * 
+	 * @param quantum to use.
+	 */
+	public void runRR(int quantum) {
+		Process currentProcess = this.readyQueue.get(0);
+		
+		if(this.previousProcessTimeSpent >= quantum || this.scheduledProcess == null) {
+			this.scheduleProcess(currentProcess);
+		}
+	}
+	
+}
diff --git a/os-simulator/src/main/java/com/com1032/assignment/ProcessState.java b/os-simulator/src/main/java/com/com1032/assignment/ProcessState.java
new file mode 100644
index 0000000000000000000000000000000000000000..06dd3ada400dddb31989910959ba9b9d2b9c4913
--- /dev/null
+++ b/os-simulator/src/main/java/com/com1032/assignment/ProcessState.java
@@ -0,0 +1,27 @@
+/**
+ * State.java
+ */
+package com.com1032.assignment;
+
+/**
+ * An enumeration to access all possible states of a process.
+ * 
+ * @author felipedabrantes
+ *
+ */
+public enum ProcessState {
+	/**Process is being created.*/
+	NEW,
+	
+	/**Process is being executed on a processor.*/
+	RUNNING,
+	
+	/**Process can execute when a processor is available.*/
+	READY,
+	
+	/**Process is waiting for event to occur.*/
+	BLOCKED,
+	
+	/**Process has finished execution.*/
+	TERMINATED
+}
\ No newline at end of file
diff --git a/os-simulator/src/main/java/com/com1032/assignment/SchedulingAlgorithm.java b/os-simulator/src/main/java/com/com1032/assignment/SchedulingAlgorithm.java
new file mode 100644
index 0000000000000000000000000000000000000000..2e74a2d57356dda98a028199717e3e62608dcc5c
--- /dev/null
+++ b/os-simulator/src/main/java/com/com1032/assignment/SchedulingAlgorithm.java
@@ -0,0 +1,48 @@
+/**
+ * SchedulingAlgorithm.java
+ */
+package com.com1032.assignment;
+
+/**
+ * Enumeration of scheduling algorithms.
+ * 
+ * Preemptive: Might temporarily interrupt the process scheduled to resume it later.
+ * 
+ * Non-Preemptive: Process scheduled does not stop until it is completed.
+ * 
+ * @author felipedabrantes
+ *
+ */
+public enum SchedulingAlgorithm {
+	
+	/**First-In-First-Out.*/
+	FIFO(false),
+	/**Shortest Process First.*/
+	SPF(false),
+	/**Shortest Remaining Time First.*/
+	SRTF(true),
+	/**Round Robin.*/
+	RR(true);
+	
+
+	/**True if algorithm is preemptive.*/
+	private boolean preemptive;
+	
+	
+	/**
+	 * Constructor.
+	 * 
+	 * @param preemptive or not.
+	 */
+	private SchedulingAlgorithm(boolean preemptive) {
+		this.preemptive = preemptive;
+	}
+	
+	
+	/**
+	 * @return preemptive or not.
+	 */
+	public boolean getPreemptive() {
+		return this.preemptive;
+	}
+}