diff --git a/data/EDFIsWrong.sl b/data/EDFIsWrong.sl
new file mode 100644
index 0000000000000000000000000000000000000000..5e8b52982ce2b46f0cf5d1396ad84a1e0df41a98
--- /dev/null
+++ b/data/EDFIsWrong.sl
@@ -0,0 +1,4 @@
+1,3,3
+1,4,3
+1,4,4
+1,6,6
diff --git a/data/EDFnotRMS.sl b/data/EDFnotRMS.sl
new file mode 100644
index 0000000000000000000000000000000000000000..27d1ab428e5e0070b14992a9ce7a88454930d441
--- /dev/null
+++ b/data/EDFnotRMS.sl
@@ -0,0 +1,3 @@
+2,5,3
+2,4,4
+2,20,15
diff --git a/data/harmonic.sl b/data/harmonic.sl
new file mode 100644
index 0000000000000000000000000000000000000000..5d71b7a47c0716c48e99a6c0c51a55b98ba9ec6a
--- /dev/null
+++ b/data/harmonic.sl
@@ -0,0 +1,4 @@
+1,2,2
+1,4,4
+1,8,8
+1,16,16
diff --git a/gui/tasksetgui/AbstractGrid.java b/gui/tasksetgui/AbstractGrid.java
new file mode 100644
index 0000000000000000000000000000000000000000..59f10bb4785e931c49b72c384943eddb6cdc1b15
--- /dev/null
+++ b/gui/tasksetgui/AbstractGrid.java
@@ -0,0 +1,114 @@
+package gui.tasksetgui;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.awt.Color;
+
+import gui.GridPanel;
+import gui.UpdateListener;
+
+public abstract class AbstractGrid extends GridPanel implements UpdateListener, MarkListener {
+
+    private String[] attributes = new String[] {"Pri", "e", "p", "d"};
+    private Map<String, GridLabel> labelMap;
+    private UpdateListener updateListener;
+    private MarkListener markListener;
+
+    // attributes should contain [prio, exectime, period, deadline]
+    public AbstractGrid(String[] taskAttributes) {
+        super(1, 4);
+        labelMap = new HashMap<>();
+        
+        for (int i = 0; i < 4; i++) {
+            GridLabel label = getLabel(taskAttributes[i]); //new GridLabel(taskAttributes[i]);
+            label.addUpdateListener(this);
+            label.addMarkListener(this);
+
+            if (i == 0) label.setEditable(false); // Forbids people from changing priority
+
+            add(label);
+            labelMap.put(attributes[i], label);
+        }
+    }
+    
+    public AbstractGrid(String prio, String exec, String period, String deadline) {
+        this(new String[] {prio, exec, period, deadline});
+    }
+
+    /*
+     * return: attributes from this gridLine
+     */
+    public int[] getAttributes() {
+        int[] attr = new int[4];
+        for (int i = 0; i < 4; i++) {
+            TaskLabel label = (TaskLabel)labelMap.get(attributes[i]);
+            attr[i] = Integer.parseInt(label.getText());
+        }
+        return attr;
+    }
+
+    /*
+     * Get label based on subclass type
+     */
+    protected abstract GridLabel getLabel(String taskAttributes);
+
+    /*
+     * Compares two taskgrid objects and returns the equality between the two
+     */
+    public boolean equals(AbstractGrid ag) {
+        return getAttributes()[0] == ag.getAttributes()[0];
+    }
+
+    /*
+     * The function to be performed when the observable class is updated.
+     * NOTE: TWO INTERFACES ARE NEEDED SUCH THAT THE UI ISN'T UPDATED ONLY WHEN MARKED.
+     */
+    public void update(Object obj) {
+        updateListener.update(this);
+    }
+
+    /*
+     * The function to be performed when the tasklabel class is marked.
+     * NOTE: TWO INTERFACES ARE NEEDED SUCH THAT THE UI ISN'T UPDATED ONLY WHEN MARKED.
+     */
+    public void markUpdate(Object obj) {
+        markListener.markUpdate(this);
+    }
+
+    /*
+     * Sets observer of this class 
+     * (Would have used observable superclass unless I already had a superclass)
+     */
+    public void addUpdateListener(UpdateListener updateListener) {
+        this.updateListener = updateListener;
+    }
+
+    /*
+     * Sets observer of this class 
+     * (Would have used observable superclass unless I already had a superclass)
+     */
+    public void addMarkListener(MarkListener markListener) {
+        this.markListener = markListener;
+    }
+
+    /*
+     * Marks all the tasklabels of this taskgrid.
+     */
+    public void mark() {
+        colorize(Color.YELLOW);
+    }
+
+    /*
+     * Unmarks all the tasklabels of this taskgrid.
+     */
+    public void unmark() {
+        colorize(Color.WHITE);
+    }
+
+    //Private help function to reduce code size
+    private void colorize(Color c) {
+        for (GridLabel tl : labelMap.values()) {
+            tl.setBackground(c);
+        }
+    }
+}
diff --git a/gui/tasksetgui/AddButton.java b/gui/tasksetgui/AddButton.java
index be83bd664bcb09ca1956c6ce4caed87125371a56..2381d2eb8f075b7a4808de0d0bcf8cfe8c3fc2cb 100644
--- a/gui/tasksetgui/AddButton.java
+++ b/gui/tasksetgui/AddButton.java
@@ -30,3 +30,23 @@ public class AddButton extends ActionButton {
     }
 
 }
+//package gui.tasksetgui;
+//
+//import java.awt.event.ActionEvent;
+//import java.awt.event.ActionListener;
+//import javax.swing.JButton;
+//
+//public class AddButton extends JButton {
+//    protected AddButton(TasksetDisplay display) {
+//        super("Add Task");
+//        addEventHandler(display);
+//    }
+//    
+//    protected void addEventHandler(TasksetDisplay display) {
+//        addActionListener(new ActionListener() {
+//            public void actionPerformed(ActionEvent e) {
+//                display.addEmpty();
+//            }
+//        });
+//    }
+//}
diff --git a/gui/tasksetgui/EmptyGrid.java b/gui/tasksetgui/EmptyGrid.java
new file mode 100644
index 0000000000000000000000000000000000000000..236d62fb89fa3f0e4e86a7e2845ca88ba09cb0b2
--- /dev/null
+++ b/gui/tasksetgui/EmptyGrid.java
@@ -0,0 +1,24 @@
+package gui.tasksetgui;
+
+public class EmptyGrid extends AbstractGrid {
+
+    // attributes should contain [prio, exectime, period, deadline]
+    public EmptyGrid(String[] taskAttributes) {
+        super(taskAttributes);
+    }
+
+    public EmptyGrid() {
+        super(new String[4]);
+    }
+    
+    public EmptyGrid(String prio, String exec, String period, String deadline) {
+        super(new String[] {prio, exec, period, deadline});
+    }
+
+    /*
+     * Get label based on subclass type
+     */
+    protected GridLabel getLabel(String taskAttribute) {
+        return new EmptyLabel(taskAttribute);
+    }
+}
diff --git a/gui/tasksetgui/EmptyLabel.java b/gui/tasksetgui/EmptyLabel.java
new file mode 100644
index 0000000000000000000000000000000000000000..6921702865ad00a695fdced2ae9b129a479e1cc5
--- /dev/null
+++ b/gui/tasksetgui/EmptyLabel.java
@@ -0,0 +1,18 @@
+package gui.tasksetgui;
+
+public class EmptyLabel extends GridLabel {
+
+    public EmptyLabel() {
+        super("");
+    }
+
+    public EmptyLabel(String text) {
+        super("");
+    }
+    /*
+     * Sets the text filter for this label
+     */
+    protected void setFilter() {
+        setDocument(new EmptyLabelFilter());
+    }
+}
diff --git a/gui/tasksetgui/EmptyLabelFilter.java b/gui/tasksetgui/EmptyLabelFilter.java
new file mode 100644
index 0000000000000000000000000000000000000000..0463840ca5af9c924fbedace9e56c3c53b8dbdc2
--- /dev/null
+++ b/gui/tasksetgui/EmptyLabelFilter.java
@@ -0,0 +1,21 @@
+package gui.tasksetgui;
+
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.PlainDocument;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+public class EmptyLabelFilter extends PlainDocument {
+    public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
+        if (str == null) return;
+
+        String oldString = getText(0, getLength());
+        String newString = oldString.substring(0, offs) + str + oldString.substring(offs);
+        try {
+            Pattern p = Pattern.compile("[^0-9 ]");
+            Matcher m = p.matcher(newString);
+            if (!m.find()) super.insertString(offs, str, a);
+        } catch (NumberFormatException e) {}
+    }
+}
diff --git a/gui/tasksetgui/GridLabel.java b/gui/tasksetgui/GridLabel.java
new file mode 100644
index 0000000000000000000000000000000000000000..243593010d01a2aae8159b0391dd05954aa3f8d2
--- /dev/null
+++ b/gui/tasksetgui/GridLabel.java
@@ -0,0 +1,86 @@
+package gui.tasksetgui;
+
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseEvent;
+import java.awt.Color;
+import javax.swing.JTextField;
+
+import gui.UpdateListener;
+
+public abstract class GridLabel extends JTextField implements MouseListener {
+
+    private UpdateListener updateListener;
+    private MarkListener markListener;
+
+    public GridLabel(String text) {
+        // Front-end Characteristics
+        super(text);
+        setBackground(Color.WHITE);
+        setOpaque(true);
+        setFilter(); 
+        setText(text);
+
+        // Add Listener for when mouse does something with object
+        addMouseListener(this);
+
+        // Add Listener that does something with object when <Enter> is pressed
+        addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                if (getText().matches("[0-9]+")) {
+                    updateListener.update();
+                }
+            }
+        });
+    }
+
+    /*
+     * Sets the text filter for this label
+     */
+    protected abstract void setFilter();
+
+    /*
+     * Sets observer of this class 
+     * (Would have used observable superclass unless I already had a superclass)
+     */
+    public void addUpdateListener(UpdateListener updateListener) {
+        this.updateListener = updateListener;
+    }
+
+    /*
+     * Sets observer of this class 
+     * (Would have used observable superclass unless I already had a superclass)
+     */
+    public void addMarkListener(MarkListener markListener) {
+        this.markListener = markListener;
+    }
+    
+    // MouseListener Functions.
+    /*
+     * Invoked when the mouse button has been clicked (pressed and released) on a component.
+     */
+    public void mouseClicked(MouseEvent e) {
+        markListener.markUpdate(this);
+    }
+
+    /*
+     * Invoked when a mouse button has been pressed on a component.
+     */
+    public void mousePressed(MouseEvent e) {}
+
+    /*
+     * Invoked when a mouse button has been released on a component.
+     */
+    public void mouseReleased(MouseEvent e) {}
+
+    /*
+     * Invoked when the mouse enters a component.
+     */
+    public void mouseEntered(MouseEvent e) {}
+
+    /*
+     * Invoked when the mouse exits a component.
+     */
+    public void mouseExited(MouseEvent e) {}
+}
diff --git a/gui/tasksetgui/TaskGrid.java b/gui/tasksetgui/TaskGrid.java
index a8770e24cca333e109eb1ce65ae168febfa4ab16..4e2c373af594455376cccce8ab54fd457f8b98c2 100644
--- a/gui/tasksetgui/TaskGrid.java
+++ b/gui/tasksetgui/TaskGrid.java
@@ -1,109 +1,20 @@
 package gui.tasksetgui;
 
-import java.util.HashMap;
-import java.util.Map;
-import java.awt.Color;
-
-import gui.GridPanel;
-import gui.UpdateListener;
-
-public class TaskGrid extends GridPanel implements UpdateListener, MarkListener {
-
-    private String[] attributes = new String[] {"Pri", "e", "p", "d"};
-    private Map<String, TaskLabel> labelMap;
-    private UpdateListener updateListener;
-    private MarkListener markListener;
+public class TaskGrid extends AbstractGrid {
 
     // attributes should contain [prio, exectime, period, deadline]
     public TaskGrid(String[] taskAttributes) {
-        super(1, 4);
-        labelMap = new HashMap<>();
-        
-        for (int i = 0; i < 4; i++) {
-            TaskLabel label = new TaskLabel(taskAttributes[i]);
-            label.addUpdateListener(this);
-            label.addMarkListener(this);
-
-            if (i == 0) label.setEditable(false); // Forbids people from changing priority
-
-            add(label);
-            labelMap.put(attributes[i], label);
-        }
+        super(taskAttributes);
     }
     
     public TaskGrid(String prio, String exec, String period, String deadline) {
-        this(new String[] {prio, exec, period, deadline});
-    }
-
-    /*
-     * return: attributes from this gridLine
-     */
-    public int[] getAttributes() {
-        int[] attr = new int[4];
-        for (int i = 0; i < 4; i++) {
-            TaskLabel label = labelMap.get(attributes[i]);
-            attr[i] = Integer.parseInt(label.getText());
-        }
-        return attr;
+        super(new String[] {prio, exec, period, deadline});
     }
 
     /*
-     * Compares two taskgrid objects and returns the equality between the two
+     * Get label based on subclass type
      */
-    public boolean equals(TaskGrid tg) {
-        return getAttributes()[0] == tg.getAttributes()[0];
-    }
-
-    /*
-     * The function to be performed when the observable class is updated.
-     * NOTE: TWO INTERFACES ARE NEEDED SUCH THAT THE UI ISN'T UPDATED ONLY WHEN MARKED.
-     */
-    public void update(Object obj) {
-        updateListener.update(this);
-    }
-
-    /*
-     * The function to be performed when the tasklabel class is marked.
-     * NOTE: TWO INTERFACES ARE NEEDED SUCH THAT THE UI ISN'T UPDATED ONLY WHEN MARKED.
-     */
-    public void markUpdate(Object obj) {
-        markListener.markUpdate(this);
-    }
-
-    /*
-     * Sets observer of this class 
-     * (Would have used observable superclass unless I already had a superclass)
-     */
-    public void addUpdateListener(UpdateListener updateListener) {
-        this.updateListener = updateListener;
-    }
-
-    /*
-     * Sets observer of this class 
-     * (Would have used observable superclass unless I already had a superclass)
-     */
-    public void addMarkListener(MarkListener markListener) {
-        this.markListener = markListener;
-    }
-
-    /*
-     * Marks all the tasklabels of this taskgrid.
-     */
-    public void mark() {
-        colorize(Color.YELLOW);
-    }
-
-    /*
-     * Unmarks all the tasklabels of this taskgrid.
-     */
-    public void unmark() {
-        colorize(Color.WHITE);
-    }
-
-    //Private help function to reduce code size
-    private void colorize(Color c) {
-        for (TaskLabel tl : labelMap.values()) {
-            tl.setBackground(c);
-        }
+    protected GridLabel getLabel(String taskAttribute) {
+        return new TaskLabel(taskAttribute);
     }
 }
diff --git a/gui/tasksetgui/TaskLabel.java b/gui/tasksetgui/TaskLabel.java
index 1de7b6d619bdba9a7c75c1347d767cc569b40b41..d837fa25117a4642a345b7fe22fe0e5543c8776a 100644
--- a/gui/tasksetgui/TaskLabel.java
+++ b/gui/tasksetgui/TaskLabel.java
@@ -1,81 +1,16 @@
 package gui.tasksetgui;
 
-import java.awt.event.ActionListener;
-import java.awt.event.ActionEvent;
-import java.awt.event.MouseListener;
-import java.awt.event.MouseEvent;
-import java.awt.Color;
-import javax.swing.JTextField;
-
-import gui.UpdateListener;
-
-public class TaskLabel extends JTextField implements MouseListener {
-
-    private UpdateListener updateListener;
-    private MarkListener markListener;
+public class TaskLabel extends GridLabel {
 
     public TaskLabel(String text) {
         // Front-end Characteristics
         super(text);
-        setBackground(Color.WHITE);
-        setOpaque(true);
-        setDocument(new TaskLabelFilter());
-        setText(text);
-
-        // Add Listener for when mouse does something with object
-        addMouseListener(this);
-
-        // Add Listener that does something with object when <Enter> is pressed
-        addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
-                if (getText().matches("[0-9]+")) {
-                    updateListener.update();
-                }
-            }
-        });
     }
 
     /*
-     * Sets observer of this class 
-     * (Would have used observable superclass unless I already had a superclass)
-     */
-    public void addUpdateListener(UpdateListener updateListener) {
-        this.updateListener = updateListener;
-    }
-
-    /*
-     * Sets observer of this class 
-     * (Would have used observable superclass unless I already had a superclass)
-     */
-    public void addMarkListener(MarkListener markListener) {
-        this.markListener = markListener;
-    }
-    
-    // MouseListener Functions.
-    /*
-     * Invoked when the mouse button has been clicked (pressed and released) on a component.
+     * Sets the text filter for this label
      */
-    public void mouseClicked(MouseEvent e) {
-        markListener.markUpdate(this);
+    protected void setFilter() {
+        setDocument(new TaskLabelFilter());
     }
-
-    /*
-     * Invoked when a mouse button has been pressed on a component.
-     */
-    public void mousePressed(MouseEvent e) {}
-
-    /*
-     * Invoked when a mouse button has been released on a component.
-     */
-    public void mouseReleased(MouseEvent e) {}
-
-    /*
-     * Invoked when the mouse enters a component.
-     */
-    public void mouseEntered(MouseEvent e) {}
-
-    /*
-     * Invoked when the mouse exits a component.
-     */
-    public void mouseExited(MouseEvent e) {}
 }
diff --git a/gui/tasksetgui/TasksetDisplay.java b/gui/tasksetgui/TasksetDisplay.java
index 2dd86729b3261d422b80e298593e3364bf91b93a..1d8730c15b20335260d776b6fe10114d4bfdae84 100644
--- a/gui/tasksetgui/TasksetDisplay.java
+++ b/gui/tasksetgui/TasksetDisplay.java
@@ -23,6 +23,7 @@ public class TasksetDisplay extends BoxPanel implements Observer, UpdateListener
     private TaskGridHeader header = new TaskGridHeader(" Priority", "Exectime", " Period", "Deadline");
     private List<TaskGrid> gridList = new ArrayList<>();
     private Optional<TaskGrid> marked = Optional.empty(); // Used to indicate which taskgrid is marked
+    private Optional<TaskGrid> emptyTask = Optional.empty(); // Used to indicate which taskgrid is marked
     private final int offset = 200;
 
     public TasksetDisplay(Taskset taskset) {
@@ -114,6 +115,19 @@ public class TasksetDisplay extends BoxPanel implements Observer, UpdateListener
         } catch (NoSuchElementException e) {}
     }
 
+    /*
+     * Add empty grid. Not if one already exists
+     */
+    public void addEmpty() {
+        if (!emptyTask.isPresent()) {
+            /*
+            emptyTask = Optional.of(new EmptyGrid());
+            marked = emptyTask;
+            markUpdate(emptyTask.get());
+            */
+        }
+    }
+
     // Private help method.
     private String parse(int i) {
         return String.valueOf(i);