diff --git a/classes/swen90006/machine/BoundaryTests.class b/classes/swen90006/machine/BoundaryTests.class
old mode 100644
new mode 100755
diff --git a/classes/swen90006/machine/BugException.class b/classes/swen90006/machine/BugException.class
old mode 100644
new mode 100755
diff --git a/classes/swen90006/machine/InvalidInstructionException.class b/classes/swen90006/machine/InvalidInstructionException.class
old mode 100644
new mode 100755
diff --git a/classes/swen90006/machine/Machine.class b/classes/swen90006/machine/Machine.class
old mode 100644
new mode 100755
diff --git a/classes/swen90006/machine/NoReturnValueException.class b/classes/swen90006/machine/NoReturnValueException.class
old mode 100644
new mode 100755
diff --git a/classes/swen90006/machine/PartitioningTests.class b/classes/swen90006/machine/PartitioningTests.class
old mode 100644
new mode 100755
diff --git a/classes/swen90006/machine/SimpleDriver.class b/classes/swen90006/machine/SimpleDriver.class
old mode 100644
new mode 100755
diff --git a/mutants/mutant-1/swen90006/machine/BugException.java b/mutants/mutant-1/swen90006/machine/BugException.java
old mode 100644
new mode 100755
diff --git a/mutants/mutant-1/swen90006/machine/InvalidInstructionException.java b/mutants/mutant-1/swen90006/machine/InvalidInstructionException.java
old mode 100644
new mode 100755
diff --git a/mutants/mutant-1/swen90006/machine/Machine.java b/mutants/mutant-1/swen90006/machine/Machine.java
old mode 100644
new mode 100755
index 9bf57316d1c736ea2bd1c62bd6df3c6c0282f331..7bc6c5c8212d8096f83fcc54f16736dda6fb4191
--- a/mutants/mutant-1/swen90006/machine/Machine.java
+++ b/mutants/mutant-1/swen90006/machine/Machine.java
@@ -237,7 +237,7 @@ public class Machine
       } else if (toks[0].equals(INSTRUCTION_RETURN)){
 	int rs = parseReg(toks[1]);
 	count++;
-	return regs[rs];
+	return Math.abs(regs[rs]);
       } else if (toks[0].equals(INSTRUCTION_LOAD)){
 	if (toks.length != 4){
 	  throw new InvalidInstructionException();
diff --git a/mutants/mutant-1/swen90006/machine/NoReturnValueException.java b/mutants/mutant-1/swen90006/machine/NoReturnValueException.java
old mode 100644
new mode 100755
diff --git a/mutants/mutant-1/swen90006/machine/SimpleDriver.java b/mutants/mutant-1/swen90006/machine/SimpleDriver.java
old mode 100644
new mode 100755
diff --git a/mutants/mutant-2/swen90006/machine/BugException.java b/mutants/mutant-2/swen90006/machine/BugException.java
old mode 100644
new mode 100755
diff --git a/mutants/mutant-2/swen90006/machine/InvalidInstructionException.java b/mutants/mutant-2/swen90006/machine/InvalidInstructionException.java
old mode 100644
new mode 100755
diff --git a/mutants/mutant-2/swen90006/machine/Machine.java b/mutants/mutant-2/swen90006/machine/Machine.java
old mode 100644
new mode 100755
index 9bf57316d1c736ea2bd1c62bd6df3c6c0282f331..511c04ab54619aaa178cc1cc6b5a40b69eefd059
--- a/mutants/mutant-2/swen90006/machine/Machine.java
+++ b/mutants/mutant-2/swen90006/machine/Machine.java
@@ -83,7 +83,7 @@ public class Machine
   private void do_load(int dest, int src, int offs) {
     if (regs[src] + offs > MAX_ADDR){
       /* no op */
-    }else if(regs[src] + offs < 0){
+    }else if(regs[src] + offs <= 0){
       /* no op */
     }else{
       regs[dest] = memory[regs[src] + offs];
diff --git a/mutants/mutant-2/swen90006/machine/NoReturnValueException.java b/mutants/mutant-2/swen90006/machine/NoReturnValueException.java
old mode 100644
new mode 100755
diff --git a/mutants/mutant-2/swen90006/machine/SimpleDriver.java b/mutants/mutant-2/swen90006/machine/SimpleDriver.java
old mode 100644
new mode 100755
diff --git a/mutants/mutant-3/swen90006/machine/BugException.java b/mutants/mutant-3/swen90006/machine/BugException.java
old mode 100644
new mode 100755
diff --git a/mutants/mutant-3/swen90006/machine/InvalidInstructionException.java b/mutants/mutant-3/swen90006/machine/InvalidInstructionException.java
old mode 100644
new mode 100755
diff --git a/mutants/mutant-3/swen90006/machine/Machine.java b/mutants/mutant-3/swen90006/machine/Machine.java
old mode 100644
new mode 100755
index 9bf57316d1c736ea2bd1c62bd6df3c6c0282f331..bc76510f5a37026b3503ff5ea34eebd26fa7d15d
--- a/mutants/mutant-3/swen90006/machine/Machine.java
+++ b/mutants/mutant-3/swen90006/machine/Machine.java
@@ -170,7 +170,7 @@ public class Machine
     int pc = 0;
     final int progLength = instructions.size();
     while(true){
-      if (pc < 0 || pc >= progLength){
+      if (pc < 0 && pc >= progLength){
 	/* will cause NoReturnValueException to be thrown
 	 * but that is not a bug and and indeed is what the
 	 * VM is supposed to do if the pc becomes negative,
@@ -278,7 +278,7 @@ public class Machine
 	if (regs[ra] == 0){
 	  pc = pc + offs;
 	}else{
-	  pc = pc + 1;
+	  pc = pc / 1;
 	}
 	count++;
 	continue; /* avoid default increment the pc below */
diff --git a/mutants/mutant-3/swen90006/machine/NoReturnValueException.java b/mutants/mutant-3/swen90006/machine/NoReturnValueException.java
old mode 100644
new mode 100755
diff --git a/mutants/mutant-3/swen90006/machine/SimpleDriver.java b/mutants/mutant-3/swen90006/machine/SimpleDriver.java
old mode 100644
new mode 100755
diff --git a/mutants/mutant-4/swen90006/machine/BugException.java b/mutants/mutant-4/swen90006/machine/BugException.java
old mode 100644
new mode 100755
diff --git a/mutants/mutant-4/swen90006/machine/InvalidInstructionException.java b/mutants/mutant-4/swen90006/machine/InvalidInstructionException.java
old mode 100644
new mode 100755
diff --git a/mutants/mutant-4/swen90006/machine/Machine.java b/mutants/mutant-4/swen90006/machine/Machine.java
old mode 100644
new mode 100755
index 9bf57316d1c736ea2bd1c62bd6df3c6c0282f331..eb7249fbb435213fb71a654147ec88aca585d522
--- a/mutants/mutant-4/swen90006/machine/Machine.java
+++ b/mutants/mutant-4/swen90006/machine/Machine.java
@@ -140,7 +140,7 @@ public class Machine
   private void validate_reg(int reg)
     throws InvalidInstructionException
   {
-    if (reg < 0 || reg > MAX_REG) {
+    if (reg < 0 || reg >= MAX_REG) {
       throw new InvalidInstructionException();
     }
   }
diff --git a/mutants/mutant-4/swen90006/machine/NoReturnValueException.java b/mutants/mutant-4/swen90006/machine/NoReturnValueException.java
old mode 100644
new mode 100755
diff --git a/mutants/mutant-4/swen90006/machine/SimpleDriver.java b/mutants/mutant-4/swen90006/machine/SimpleDriver.java
old mode 100644
new mode 100755
diff --git a/mutants/mutant-5/swen90006/machine/BugException.java b/mutants/mutant-5/swen90006/machine/BugException.java
old mode 100644
new mode 100755
diff --git a/mutants/mutant-5/swen90006/machine/InvalidInstructionException.java b/mutants/mutant-5/swen90006/machine/InvalidInstructionException.java
old mode 100644
new mode 100755
diff --git a/mutants/mutant-5/swen90006/machine/Machine.java b/mutants/mutant-5/swen90006/machine/Machine.java
old mode 100644
new mode 100755
index 9bf57316d1c736ea2bd1c62bd6df3c6c0282f331..a56907ab061d2c2cdfa9b43385b06b0bcd136701
--- a/mutants/mutant-5/swen90006/machine/Machine.java
+++ b/mutants/mutant-5/swen90006/machine/Machine.java
@@ -148,7 +148,7 @@ public class Machine
   private void validate_offset(int offset)
     throws InvalidInstructionException
   {
-    if (offset < -MAX_ADDR || offset > MAX_ADDR) {
+    if (offset < -MAX_ADDR || offset >= MAX_ADDR) {
       throw new InvalidInstructionException();
     }
   }
diff --git a/mutants/mutant-5/swen90006/machine/NoReturnValueException.java b/mutants/mutant-5/swen90006/machine/NoReturnValueException.java
old mode 100644
new mode 100755
diff --git a/mutants/mutant-5/swen90006/machine/SimpleDriver.java b/mutants/mutant-5/swen90006/machine/SimpleDriver.java
old mode 100644
new mode 100755
diff --git a/src/swen90006/machine/BugException.java b/src/swen90006/machine/BugException.java
old mode 100644
new mode 100755
diff --git a/src/swen90006/machine/InvalidInstructionException.java b/src/swen90006/machine/InvalidInstructionException.java
old mode 100644
new mode 100755
diff --git a/src/swen90006/machine/Machine.java b/src/swen90006/machine/Machine.java
old mode 100644
new mode 100755
index 9bf57316d1c736ea2bd1c62bd6df3c6c0282f331..92d3b56553b579c2419f7ff1245bcee45f1af3f8
--- a/src/swen90006/machine/Machine.java
+++ b/src/swen90006/machine/Machine.java
@@ -3,301 +3,301 @@ package swen90006.machine;
 import java.util.Arrays;
 import java.util.List;
 
-public class Machine 
+public class Machine
 {
-  /** arithmetic instructions each take three registers as arguments with the
-   *  destination register appearing first
-   */
-
-  /** add rd rs1 rs2   =~   rd = rs1 + rs2 */
-  public static final String INSTRUCTION_ADD = "add";
-
-  /** sub rd rs1 rs2   =~   rd = rs1 - rs2 */    
-  public static final String INSTRUCTION_SUBTRACT = "sub";
-
-  /** mul rd rs1 rs2   =~   rd = rs1 * rs2 */        
-  public static final String INSTRUCTION_MULT = "mul";
-
-  /** div rd rs1 rs2   =~   rd = rs1 / rs2 */            
-  public static final String INSTRUCTION_DIVIDE = "div";
-
-  /** ret rs           =~   return rs */
-  public static final String INSTRUCTION_RETURN = "ret";
-
-  /** ldr rd rs offs  =~    rd = rs[offs] */
-  public static final String INSTRUCTION_LOAD = "ldr";
-
-  /** str ra offs rb   =~    ra[offs] = rb */
-  public static final String INSTRUCTION_STORE = "str";
-
-  /** mov rd val       =~    rd = val */
-  public static final String INSTRUCTION_MOVE = "mov";
-
-  /** jmp offs         =~    pc = pc + offs */
-  public static final String INSTRUCTION_JUMP = "jmp";
-
-  /** jz ra offs       =~   if (ra == 0) pc = pc + offs else pc = pc + 1 */
-  public static final String INSTRUCTION_JZ = "jz";
-    
-  public static final int NUM_REGS = 32;
-  public static final int MAX_REG = (NUM_REGS - 1);
-  public static final int MEMORY_SIZE = 65536; /* 4 x as much memory as a 64 */
-  public static final int MAX_ADDR = MEMORY_SIZE-1;
-    
-  private int[] memory;
-  private int[] regs;
-
-  private int count = 0; /* counts number of instructions executed so far */
-    
-  public Machine()
-  {
-    memory = new int[MEMORY_SIZE];
-    regs = new int[NUM_REGS];
-    count = 0;
-  }
-
-  private void do_add(int dest, int src1, int src2)
-  {
-    regs[dest] = regs[src1] + regs[src2];
-  }
-    
-  private void do_sub(int dest, int src1, int src2)
-  {
-    regs[dest] = regs[src1] - regs[src2];
-  }
-    
-  private void do_mult(int dest, int src1, int src2)
-  {
-    regs[dest] = regs[src1] * regs[src2];
-  }
-    
-  private void do_div(int dest, int src1, int src2)
-  {
-    if (regs[src2] == 0){
-      /* no op */
-    }else{
-      regs[dest] = regs[src1] / regs[src2];
+    /** arithmetic instructions each take three registers as arguments with the
+     *  destination register appearing first
+     */
+
+    /** add rd rs1 rs2   =~   rd = rs1 + rs2 */
+    public static final String INSTRUCTION_ADD = "add";
+
+    /** sub rd rs1 rs2   =~   rd = rs1 - rs2 */
+    public static final String INSTRUCTION_SUBTRACT = "sub";
+
+    /** mul rd rs1 rs2   =~   rd = rs1 * rs2 */
+    public static final String INSTRUCTION_MULT = "mul";
+
+    /** div rd rs1 rs2   =~   rd = rs1 / rs2 */
+    public static final String INSTRUCTION_DIVIDE = "div";
+
+    /** ret rs           =~   return rs */
+    public static final String INSTRUCTION_RETURN = "ret";
+
+    /** ldr rd rs offs  =~    rd = rs[offs] */
+    public static final String INSTRUCTION_LOAD = "ldr";
+
+    /** str ra offs rb   =~    ra[offs] = rb */
+    public static final String INSTRUCTION_STORE = "str";
+
+    /** mov rd val       =~    rd = val */
+    public static final String INSTRUCTION_MOVE = "mov";
+
+    /** jmp offs         =~    pc = pc + offs */
+    public static final String INSTRUCTION_JUMP = "jmp";
+
+    /** jz ra offs       =~   if (ra == 0) pc = pc + offs else pc = pc + 1 */
+    public static final String INSTRUCTION_JZ = "jz";
+
+    public static final int NUM_REGS = 32;
+    public static final int MAX_REG = (NUM_REGS - 1);
+    public static final int MEMORY_SIZE = 65536; /* 4 x as much memory as a 64 */
+    public static final int MAX_ADDR = MEMORY_SIZE-1;
+
+    private int[] memory;
+    private int[] regs;
+
+    private int count = 0; /* counts number of instructions executed so far */
+
+    public Machine()
+    {
+        memory = new int[MEMORY_SIZE];
+        regs = new int[NUM_REGS];
+        count = 0;
     }
-  }
-
-  private void do_load(int dest, int src, int offs) {
-    if (regs[src] + offs > MAX_ADDR){
-      /* no op */
-    }else if(regs[src] + offs < 0){
-      /* no op */
-    }else{
-      regs[dest] = memory[regs[src] + offs];
+
+    private void do_add(int dest, int src1, int src2)
+    {
+        regs[dest] = regs[src1] + regs[src2];
     }
-  }
-
-  private void do_store(int a, int offs, int b)  {
-    if (regs[a] + offs > MAX_ADDR){
-      /* no op */
-    }else if(regs[a] + offs < 0){
-      /* no op */
-    }else{
-      memory[regs[a] + offs] = regs[b];
+
+    private void do_sub(int dest, int src1, int src2)
+    {
+        regs[dest] = regs[src1] - regs[src2];
     }
-  }
 
-  private void do_move(int rd, int val){
-    regs[rd] = val;
-  }
+    private void do_mult(int dest, int src1, int src2)
+    {
+        regs[dest] = regs[src1] * regs[src2];
+    }
 
-  private int parseReg(String s) throws InvalidInstructionException
-  {
-    if (s.length() < 2){
-      throw new InvalidInstructionException();
+    private void do_div(int dest, int src1, int src2)
+    {
+        if (regs[src2] == 0){
+            /* no op */
+        }else{
+            regs[dest] = regs[src1] / regs[src2];
+        }
     }
-    if (s.charAt(0) != 'r'){
-      throw new InvalidInstructionException();
+
+    private void do_load(int dest, int src, int offs) {
+        if (regs[src] + offs > MAX_ADDR){
+            /* no op */
+        }else if(regs[src] + offs < 0){
+            /* no op */
+        }else{
+            regs[dest] = memory[regs[src] + offs];
+        }
     }
-    String numstr = s.substring(1);
-    int num = 0;
-    try {
-      num = Integer.parseInt(numstr);
-    } catch (Exception e){
-      throw new InvalidInstructionException();
+
+    private void do_store(int a, int offs, int b)  {
+        if (regs[a] + offs > MAX_ADDR){
+            /* no op */
+        }else if(regs[a] + offs < 0){
+            /* no op */
+        }else{
+            memory[regs[a] + offs] = regs[b];
+        }
     }
-    validate_reg(num);
-    return num;
-  }
-
-  private int parseOffset(String s)
-    throws InvalidInstructionException
-  {
-    int num = 0;
-    try {
-      num = Integer.parseInt(s);
-    } catch (Exception e){
-      throw new InvalidInstructionException();
+
+    private void do_move(int rd, int val){
+        regs[rd] = val;
     }
-    validate_offset(num);
-    return num;
-  }
 
+    private int parseReg(String s) throws InvalidInstructionException
+    {
+        if (s.length() < 2){
+            throw new InvalidInstructionException();
+        }
+        if (s.charAt(0) != 'r'){
+            throw new InvalidInstructionException();
+        }
+        String numstr = s.substring(1);
+        int num = 0;
+        try {
+            num = Integer.parseInt(numstr);
+        } catch (Exception e){
+            throw new InvalidInstructionException();
+        }
+        validate_reg(num);
+        return num;
+    }
 
-  private void validate_reg(int reg)
-    throws InvalidInstructionException
-  {
-    if (reg < 0 || reg > MAX_REG) {
-      throw new InvalidInstructionException();
+    private int parseOffset(String s)
+            throws InvalidInstructionException
+    {
+        int num = 0;
+        try {
+            num = Integer.parseInt(s);
+        } catch (Exception e){
+            throw new InvalidInstructionException();
+        }
+        validate_offset(num);
+        return num;
     }
-  }
 
-  private void validate_offset(int offset)
-    throws InvalidInstructionException
-  {
-    if (offset < -MAX_ADDR || offset > MAX_ADDR) {
-      throw new InvalidInstructionException();
+
+    private void validate_reg(int reg)
+            throws InvalidInstructionException
+    {
+        if (reg < 0 || reg > MAX_REG) {
+            throw new InvalidInstructionException();
+        }
     }
-  }
-    
-  /** Execute an assembly program.
-   *
-   * @param prog is the program to execute as an iterable collection of strings, 
-   *        each of which is a single instruction.
-   * @return the program's return value.
-   * @throws Exception when program has unrecognised or 
-   *         invalid instructions, or when it returns no result when it finishes
-   */
-  int execute(List<String> instructions) 
-    throws InvalidInstructionException,
-	   NoReturnValueException
-  {
-
-    int instructionsExecuted = 0;
-    int pc = 0;
-    final int progLength = instructions.size();
-    while(true){
-      if (pc < 0 || pc >= progLength){
-	/* will cause NoReturnValueException to be thrown
-	 * but that is not a bug and and indeed is what the
-	 * VM is supposed to do if the pc becomes negative,
-	 * since in this case the program's execution
-	 * finishes early without a return value having
-	 * been produced. */
-	break;
-      }
-      String inst = instructions.get(pc);
-      /* strip leading and trailing whitespace */ 
-      inst = inst.toLowerCase().replaceAll("^\\s+","").replaceAll("\\s+$","");
-      /* strip out any comments */
-      String[] toks = inst.split(";");
-      inst = toks[0];
-
-      /* check for blank lines */
-      if (inst.equals("")){
-	pc = pc + 1;
-	count++;
-	continue;
-      }
-
-      instructionsExecuted++;
-      /* now  tokenize by splitting on whitespace */
-      toks = inst.split("\\s+");
-
-      /* check minimum number of tokens */
-      if (toks.length < 2){
-	throw new InvalidInstructionException();
-      }
-
-      if (toks[0].equals(INSTRUCTION_ADD)){
-	if (toks.length != 4){
-	  throw new InvalidInstructionException();
-	}
-	int rd = parseReg(toks[1]);
-	int rs1 = parseReg(toks[2]);
-	int rs2 = parseReg(toks[3]);
-	do_add(rd,rs1,rs2);
-      } else if (toks[0].equals(INSTRUCTION_SUBTRACT)){
-	if (toks.length != 4){
-	  throw new InvalidInstructionException();
-	}
-	int rd = parseReg(toks[1]);
-	int rs1 = parseReg(toks[2]);
-	int rs2 = parseReg(toks[3]);
-	do_sub(rd,rs1,rs2);
-      } else if (toks[0].equals(INSTRUCTION_MULT)){
-	if (toks.length != 4){
-	  throw new InvalidInstructionException();
-	}
-	int rd = parseReg(toks[1]);
-	int rs1 = parseReg(toks[2]);
-	int rs2 = parseReg(toks[3]);
-	do_mult(rd,rs1,rs2);
-      } else if (toks[0].equals(INSTRUCTION_DIVIDE)){
-	if (toks.length != 4){
-	  throw new InvalidInstructionException();
-	}
-	int rd = parseReg(toks[1]);
-	int rs1 = parseReg(toks[2]);
-	int rs2 = parseReg(toks[3]);
-	do_div(rd,rs1,rs2);
-      } else if (toks[0].equals(INSTRUCTION_RETURN)){
-	int rs = parseReg(toks[1]);
-	count++;
-	return regs[rs];
-      } else if (toks[0].equals(INSTRUCTION_LOAD)){
-	if (toks.length != 4){
-	  throw new InvalidInstructionException();
-	}
-	int rd = parseReg(toks[1]);
-	int rs = parseReg(toks[2]);
-	int offs = parseOffset(toks[3]);
-	do_load(rd,rs,offs);
-      } else if (toks[0].equals(INSTRUCTION_STORE)){
-	if (toks.length != 4){
-	  throw new InvalidInstructionException();
-	}
-	int ra = parseReg(toks[1]);
-	int offs = parseOffset(toks[2]);
-	int rb = parseReg(toks[3]);
-	do_store(ra,offs,rb);
-      } else if (toks[0].equals(INSTRUCTION_MOVE)){
-	if (toks.length != 3){
-	  throw new InvalidInstructionException();
-	}
-	int rd = parseReg(toks[1]);
-	int offs = parseOffset(toks[2]);
-	do_move(rd,offs);
-      } else if (toks[0].equals(INSTRUCTION_JUMP)){
-	if (toks.length != 2){
-	  throw new InvalidInstructionException();
-	}
-	int offs = parseOffset(toks[1]);
-	pc  = pc + offs;
-	count++;
-	continue; /* avoid default increment of pc below */
-      } else if (toks[0].equals(INSTRUCTION_JZ)){
-	if (toks.length != 3){
-	  throw new InvalidInstructionException();
-	}
-	int ra = parseReg(toks[1]);
-	int offs = parseOffset(toks[2]);
-	if (regs[ra] == 0){
-	  pc = pc + offs;
-	}else{
-	  pc = pc + 1;
-	}
-	count++;
-	continue; /* avoid default increment the pc below */
-      } else {
-	System.err.println("Unrecognised instruction: " + inst);
-	throw new InvalidInstructionException();
-      }
-      count++;
-      pc = pc + 1;
+
+    private void validate_offset(int offset)
+            throws InvalidInstructionException
+    {
+        if (offset < -MAX_ADDR || offset > MAX_ADDR) {
+            throw new InvalidInstructionException();
+        }
     }
 
-    /* got here without returning already... */
-    throw new NoReturnValueException();
-  }
+    /** Execute an assembly program.
+     *
+     * @param prog is the program to execute as an iterable collection of strings,
+     *        each of which is a single instruction.
+     * @return the program's return value.
+     * @throws Exception when program has unrecognised or
+     *         invalid instructions, or when it returns no result when it finishes
+     */
+    int execute(List<String> instructions)
+            throws InvalidInstructionException,
+            NoReturnValueException
+    {
+
+        int instructionsExecuted = 0;
+        int pc = 0;
+        final int progLength = instructions.size();
+        while(true){
+            if (pc < 0 || pc >= progLength){
+                /* will cause NoReturnValueException to be thrown
+                 * but that is not a bug and and indeed is what the
+                 * VM is supposed to do if the pc becomes negative,
+                 * since in this case the program's execution
+                 * finishes early without a return value having
+                 * been produced. */
+                break;
+            }
+            String inst = instructions.get(pc);
+            /* strip leading and trailing whitespace */
+            inst = inst.toLowerCase().replaceAll("^\\s+","").replaceAll("\\s+$","");
+            /* strip out any comments */
+            String[] toks = inst.split(";");
+            inst = toks[0];
 
-  /**
-   * get the number of instructions successfully executed by the VM so far
-   */
-  public int getCount(){
-    return count;
-  }
+            /* check for blank lines */
+            if (inst.equals("")){
+                pc = pc + 1;
+                count++;
+                continue;
+            }
+
+            instructionsExecuted++;
+            /* now  tokenize by splitting on whitespace */
+            toks = inst.split("\\s+");
+
+            /* check minimum number of tokens */
+            if (toks.length < 2){
+                throw new InvalidInstructionException();
+            }
+
+            if (toks[0].equals(INSTRUCTION_ADD)){
+                if (toks.length != 4){
+                    throw new InvalidInstructionException();
+                }
+                int rd = parseReg(toks[1]);
+                int rs1 = parseReg(toks[2]);
+                int rs2 = parseReg(toks[3]);
+                do_add(rd,rs1,rs2);
+            } else if (toks[0].equals(INSTRUCTION_SUBTRACT)){
+                if (toks.length != 4){
+                    throw new InvalidInstructionException();
+                }
+                int rd = parseReg(toks[1]);
+                int rs1 = parseReg(toks[2]);
+                int rs2 = parseReg(toks[3]);
+                do_sub(rd,rs1,rs2);
+            } else if (toks[0].equals(INSTRUCTION_MULT)){
+                if (toks.length != 4){
+                    throw new InvalidInstructionException();
+                }
+                int rd = parseReg(toks[1]);
+                int rs1 = parseReg(toks[2]);
+                int rs2 = parseReg(toks[3]);
+                do_mult(rd,rs1,rs2);
+            } else if (toks[0].equals(INSTRUCTION_DIVIDE)){
+                if (toks.length != 4){
+                    throw new InvalidInstructionException();
+                }
+                int rd = parseReg(toks[1]);
+                int rs1 = parseReg(toks[2]);
+                int rs2 = parseReg(toks[3]);
+                do_div(rd,rs1,rs2);
+            } else if (toks[0].equals(INSTRUCTION_RETURN)){
+                int rs = parseReg(toks[1]);
+                count++;
+                return regs[rs];
+            } else if (toks[0].equals(INSTRUCTION_LOAD)){
+                if (toks.length != 4){
+                    throw new InvalidInstructionException();
+                }
+                int rd = parseReg(toks[1]);
+                int rs = parseReg(toks[2]);
+                int offs = parseOffset(toks[3]);
+                do_load(rd,rs,offs);
+            } else if (toks[0].equals(INSTRUCTION_STORE)){
+                if (toks.length != 4){
+                    throw new InvalidInstructionException();
+                }
+                int ra = parseReg(toks[1]);
+                int offs = parseOffset(toks[2]);
+                int rb = parseReg(toks[3]);
+                do_store(ra,offs,rb);
+            } else if (toks[0].equals(INSTRUCTION_MOVE)){
+                if (toks.length != 3){
+                    throw new InvalidInstructionException();
+                }
+                int rd = parseReg(toks[1]);
+                int offs = parseOffset(toks[2]);
+                do_move(rd,offs);
+            } else if (toks[0].equals(INSTRUCTION_JUMP)){
+                if (toks.length != 2){
+                    throw new InvalidInstructionException();
+                }
+                int offs = parseOffset(toks[1]);
+                pc  = pc + offs;
+                count++;
+                continue; /* avoid default increment of pc below */
+            } else if (toks[0].equals(INSTRUCTION_JZ)){
+                if (toks.length != 3){
+                    throw new InvalidInstructionException();
+                }
+                int ra = parseReg(toks[1]);
+                int offs = parseOffset(toks[2]);
+                if (regs[ra] == 0){
+                    pc = pc + offs;
+                }else{
+                    pc = pc + 1;
+                }
+                count++;
+                continue; /* avoid default increment the pc below */
+            } else {
+                System.err.println("Unrecognised instruction: " + inst);
+                throw new InvalidInstructionException();
+            }
+            count++;
+            pc = pc + 1;
+        }
+
+        /* got here without returning already... */
+        throw new NoReturnValueException();
+    }
+
+    /**
+     * get the number of instructions successfully executed by the VM so far
+     */
+    public int getCount(){
+        return count;
+    }
 }
diff --git a/src/swen90006/machine/NoReturnValueException.java b/src/swen90006/machine/NoReturnValueException.java
old mode 100644
new mode 100755
diff --git a/src/swen90006/machine/SimpleDriver.java b/src/swen90006/machine/SimpleDriver.java
old mode 100644
new mode 100755
diff --git a/test/swen90006/machine/BoundaryTests.java b/test/swen90006/machine/BoundaryTests.java
old mode 100644
new mode 100755
index 61ce1ca647f325fbf452047408c1e22d9befcb99..84bd4c05426f58682183be0d2295e212460185e5
--- a/test/swen90006/machine/BoundaryTests.java
+++ b/test/swen90006/machine/BoundaryTests.java
@@ -1,5 +1,7 @@
 package swen90006.machine;
 
+import java.io.File;
+import java.io.IOException;
 import java.util.List;
 import java.util.ArrayList;
 import java.nio.charset.Charset;
@@ -8,83 +10,570 @@ import java.nio.file.Files;
 import java.nio.file.FileSystems;
 
 import org.junit.*;
+
 import static org.junit.Assert.*;
 
-public class BoundaryTests
-{
-  //Any method annotated with "@Before" will be executed before each test,
-  //allowing the tester to set up some shared resources.
-  @Before public void setUp()
-  {
-  }
-
-  //Any method annotated with "@After" will be executed after each test,
-  //allowing the tester to release any shared resources used in the setup.
-  @After public void tearDown()
-  {
-  }
-
-  //Any method annotation with "@Test" is executed as a test.
-  @Test public void aTest()
-  {
-    //the assertEquals method used to check whether two values are
-    //equal, using the equals method
-    final int expected = 2;
-    final int actual = 1 + 1;
-    assertEquals(expected, actual);
-  }
-
-  @Test public void anotherTest()
-  {
-    List<String> list = new ArrayList<String>();
-    list.add("a");
-    list.add("b");
-
-    //the assertTrue method is used to check whether something holds.
-    assertTrue(list.contains("a"));
-  }
-
-  //Test test opens a file and executes the machine
-  @Test public void aFileOpenTest()
-  {
-    final List<String> lines = readInstructions("examples/array.s");
-    Machine m = new Machine();
-    assertEquals(m.execute(lines), 45);
-  }
-  
-  //To test an exception, specify the expected exception after the @Test
-  @Test(expected = java.io.IOException.class) 
-    public void anExceptionTest()
-    throws Throwable
-  {
-    throw new java.io.IOException();
-  }
-
-  //This test should fail.
-  //To provide additional feedback when a test fails, an error message
-  //can be included
-  @Test public void aFailedTest()
-  {
-    //include a message for better feedback
-    final int expected = 2;
-    final int actual = 1 + 2;
-    assertEquals("Some failure message", expected, actual);
-  }
-
-  //Read in a file containing a program and convert into a list of
-  //string instructions
-  private List<String> readInstructions(String file)
-  {
-    Charset charset = Charset.forName("UTF-8");
-    List<String> lines = null;
-    try {
-      lines = Files.readAllLines(FileSystems.getDefault().getPath(file), charset);
-    }
-    catch (Exception e){
-      System.err.println("Invalid input file! (stacktrace follows)");
-      e.printStackTrace(System.err);
-      System.exit(1);
-    }
-    return lines;
-  }
-}
+
+public class BoundaryTests {
+    /*
+     * Any method annotated with "@Before" will be executed before each test,
+     * allowing the tester to set up some shared resources.
+     **/
+    @Before
+    public void setUp() {
+    }
+
+    /*
+     * Any method annotated with "@After" will be executed after each test,
+     * allowing the tester to release any shared resources used in the setup.
+     **/
+    @After
+    public void tearDown() {
+    }
+
+
+    //******************************* EC1 ********************************
+    /*
+     * boundary : no RET instruction
+     * on point : no RET instruction
+     */
+    @Test(expected = NoReturnValueException.class)
+    public void onPointEC1Test()
+            throws Throwable {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R0 10");
+        machineExeLines(lines);
+    }
+
+    /*
+     * boundary : no RET instruction
+     * off point : one RET instruction
+     */
+    @Test
+    public void offPointEC1Test() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("RET R0");
+        machineExeLines(lines);
+        assertEquals(0, machineExeLines(lines));
+    }
+
+
+    //******************************* EC2 ********************************
+    /*
+     * boundary : more than one RET instructions
+     * on point : two RET instruction
+     */
+    @Test
+    public void onPointEC2Test() {
+        List<String> lines = new ArrayList<String>();
+        final int expected = -10;
+        lines.add("MOV R1 " + expected);
+        lines.add("RET R1");
+        lines.add("MOV R2 " + expected * 10);
+        lines.add("RET R2");
+        assertEquals(expected, machineExeLines(lines));
+    }
+
+
+    //******************************* EC3 ********************************
+    /*
+     * boundary: i < 0
+     * on point: i = 0
+     * */
+    @Test
+    public void onPointEC3Test() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R0 0");
+        lines.add("RET R0");
+        assertEquals(0, machineExeLines(lines));
+    }
+
+    /*
+     * boundary: i < 0
+     * off point: i = -1
+     * */
+    @Test(expected = InvalidInstructionException.class)
+    public void offPointEC3Test()
+            throws Throwable {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R-1 0");
+        machineExeLines(lines);
+    }
+
+
+    //******************************* EC4 ********************************
+    /*
+     * boundary: i > 31
+     * on point: i = 31
+     * */
+    @Test
+    public void onPointEC4Test() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R31 -2");
+        lines.add("RET R31");
+        assertEquals(-2, machineExeLines(lines));
+    }
+
+    /*
+     * boundary: i > 31
+     * off point: i = 32
+     * */
+    @Test(expected = InvalidInstructionException.class)
+    public void offPointEC4Test()
+            throws Throwable {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R32 0");
+        machineExeLines(lines);
+    }
+
+
+    //******************************* EC5 ********************************
+    /*
+     * boundary: val < -65535
+     * on point: val = -65535
+     * */
+    @Test
+    public void onPointEC5Test() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R1 -65535");
+        lines.add("RET R1");
+        assertEquals(-65535, machineExeLines(lines));
+    }
+
+    /*
+     * boundary: val < -65535
+     * off point: val = -65536
+     * */
+    @Test(expected = InvalidInstructionException.class)
+    public void offPointEC5Test()
+            throws Throwable {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R1 -65536");
+        lines.add("RET R1");
+        machineExeLines(lines);
+    }
+
+
+    //******************************* EC6 ********************************
+    /*
+     * boundary: val > 65535
+     * on point: val = 65535
+     * */
+    @Test
+    public void onPointEC6Test() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R1 65535");
+        lines.add("RET R1");
+        assertEquals(65535, machineExeLines(lines));
+    }
+
+    /*
+     * boundary: val > 65535
+     * off point: val = 65536
+     * */
+    @Test(expected = InvalidInstructionException.class)
+    public void offPointEC6Test()
+            throws Throwable {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R1 65536");
+        lines.add("RET R1");
+        machineExeLines(lines);
+    }
+
+
+    //******************************* EC7 ********************************
+    /*
+     * boundary: regV <= -(2^31)
+     * on point: regV = -(2^31)
+     * */
+
+    /*
+     * boundary: regV <= -(2^31)
+     * off point: regV = -(2^31 + 1)
+     * */
+
+    //EC7 cannot give a test
+
+
+    //******************************* EC8 ********************************
+    /*
+     * boundary: regV >= 2^31
+     * on point: regV = 2^31
+     * */
+
+    /*
+     * boundary: regV >= 2^31
+     * off point: regV = 2^31 + 1
+     * */
+
+    //EC8 cannot give a test
+
+
+    //******************************* EC9 ********************************
+    /*
+     * boundary: ADD > 0
+     * off point: one ADD
+     * */
+    @Test
+    public void offPointEC9Test() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R1 1");
+        lines.add("ADD R1 R1 R1");
+        lines.add("RET R1");
+        assertEquals("Wrong ADD result.", 2, machineExeLines(lines));
+    }
+
+
+    //******************************* EC10 ********************************
+    /*
+     * boundary: SUB > 0
+     * off point: one SUB
+     * */
+    @Test
+    public void offPointEC10Test() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R1 1");
+        lines.add("SUB R1 R1 R1");
+        lines.add("RET R1");
+        assertEquals("Wrong SUB result.", 0, machineExeLines(lines));
+    }
+
+
+    //******************************* EC11 ********************************
+    /*
+     * boundary: MUL > 0
+     * off point: one MUL
+     * */
+    @Test
+    public void offPointEC11Test() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R1 1");
+        lines.add("MUL R1 R1 R1");
+        lines.add("RET R1");
+        assertEquals("Wrong MUL result.", 1, machineExeLines(lines));
+    }
+
+
+    //******************************* EC12 ********************************
+    /*
+     * boundary: div by 0
+     * on point: divisor = 0
+     * */
+    @Test
+    public void onPointEC12Test() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R1 0");
+        lines.add("MOV R0 3");
+        lines.add("DIV R0 R0 R1");
+        lines.add("RET R0");
+        assertEquals(3, machineExeLines(lines));
+    }
+
+    /*
+     * boundary: div by 0
+     * off point one: divisor = 1
+     * return a normal value
+     * */
+    @Test
+    public void offPointOneEC12Test() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R1 1");
+        lines.add("MOV R0 -3");
+        lines.add("DIV R0 R0 R1");
+        lines.add("RET R0");
+        assertEquals(-3, machineExeLines(lines));
+    }
+
+    /*
+     * boundary: div by 0
+     * off point two: divisor = -1
+     * return a normal value
+     * */
+    @Test
+    public void offPointTwoEC12Test() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R1 -1");
+        lines.add("MOV R0 3");
+        lines.add("DIV R0 R0 R1");
+        lines.add("RET R0");
+        assertEquals(-3, machineExeLines(lines));
+
+    }
+
+
+    //EC13 has no test
+
+
+    //******************************* EC14 ********************************
+    /*
+     * boundary: MOV > 0
+     * on point: one MOV
+     * */
+    @Test
+    public void onPointEC14Test() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R0 1");
+        lines.add("RET R0");
+        assertEquals("Wrong ADD result.", 1, machineExeLines(lines));
+    }
+
+
+    //******************************* EC15 ********************************
+    /*
+     * boundary: RET undefined reg
+     * on point: RET undefined reg
+     * return a normal value
+     * */
+    @Test
+    public void onPointEC15Test() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("RET R0");
+        assertEquals(0, machineExeLines(lines));
+    }
+
+    /*
+     * boundary: RET undefined reg
+     * off point: RET defined reg
+     * return a normal value
+     * */
+    @Test
+    public void offPointEC15Test() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R0 1");
+        lines.add("RET R0");
+        assertEquals("Wrong RET result.", 1, machineExeLines(lines));
+    }
+
+
+    //EC16 has no test
+
+
+    //******************************* EC17 ********************************
+    /*
+     * test for JMP
+     * boundary: val = 0
+     * on point: val = 0
+     * cause an infinite loop
+     * but can not have a test case since it will loop forever
+     * */
+
+
+    //******************************* EC18 ********************************
+    /*
+     * boundary: val < 0 && |val| > _pc
+     * off point one: val = -1 && _pc = 0
+     * throw the NoReturnValueException
+     * */
+    @Test(expected = NoReturnValueException.class)
+    public void offPointEC18Test()
+            throws Throwable {
+        List<String> lines = new ArrayList<String>();
+        lines.add("JMP -1");
+        lines.add("RET R0");
+        machineExeLines(lines);
+    }
+
+
+    //******************************* EC19 ********************************
+    /*
+     * boundary: val > pc_ && val > 0
+     * off point one: val = 1 && _pc = 0
+     * throw the NoReturnValueException
+     * */
+    @Test(expected = NoReturnValueException.class)
+    public void offPointEC19Test()
+            throws Throwable {
+        List<String> lines = new ArrayList<String>();
+        lines.add("JMP 1");
+        machineExeLines(lines);
+    }
+
+
+    //******************************* EC20 ********************************
+    /*
+     * boundary: _pc <= v <= pc_ && v != 0
+     * off point: v = pc_ = _pc = 1
+     * return a normal value
+     * */
+    @Test
+    public void offPointEC20Test() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R0 1");
+        lines.add("JMP 1");
+        lines.add("MOV R0 2");
+        lines.add("RET R0");
+        assertEquals("Wrong JMP result.", 2, machineExeLines(lines));
+    }
+
+
+    //******************************* EC21 ********************************
+    /*
+     * test for JZ
+     * boundary: val = 0
+     * on point: val = 0
+     * cause an infinite loop
+     * but can not have a test case since it will loop forever
+     * */
+
+
+    //******************************* EC22 ********************************
+    /*
+     * boundary: val < 0 && |val| > _pc
+     * off point one: val = -1 && _pc = 0
+     * throw the NoReturnValueException
+     * */
+    @Test(expected = NoReturnValueException.class)
+    public void offPointEC22Test()
+            throws Throwable {
+        List<String> lines = new ArrayList<String>();
+        lines.add("JZ R0 -1");
+        lines.add("RET R0");
+        machineExeLines(lines);
+    }
+
+
+
+
+    //******************************* EC23 ********************************
+    /*
+     * boundary: val > pc_ && val > 0
+     * off point one: val = 1 && _pc = 0
+     * throw the NoReturnValueException
+     * */
+    @Test(expected = NoReturnValueException.class)
+    public void offPointEC23Test()
+            throws Throwable {
+        List<String> lines = new ArrayList<String>();
+        lines.add("JZ R0 1");
+        machineExeLines(lines);
+    }
+
+
+    //******************************* EC24 ********************************
+    /*
+     * boundary: _pc <= v <= pc_ && v != 0
+     * off point: v = pc_ = _pc = 1
+     * return a normal value
+     * */
+    @Test
+    public void offPointEC24Test() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R0 1");
+        lines.add("JZ R0 3");
+        lines.add("SUB R0 R0 R0");
+        lines.add("MOV R0 2");
+        lines.add("RET R0");
+        assertEquals("Wrong JMP result.", 2, machineExeLines(lines));
+    }
+
+
+    //******************************* EC25 ********************************
+    /*
+     * test for LDR
+     * boundary: b + v <= -(2^31)
+     * on point: b + v = -(2^31)
+     * stop the programme and print out the error
+     * /
+
+    /*
+     * boundary: b + v <= -(2^31)
+     * off point: b + v = -(2^31 + 1)
+     * stop the programme and print out the error
+     * */
+
+    //EC25 cannot give a test
+
+
+    //******************************* EC26 ********************************
+    /*
+     * test for LDR
+     * boundary: b + v in -(2^31-1) ... (2^31-1)
+     * on point one: b + v = -(2^31-1)
+     * return a normal value
+     * */
+
+    /*
+     * test for LDR
+     * boundary: b + v in -(2^31-1) ... (2^31-1)
+     * on point two: b + v = (2^31-1)
+     * return a normal value
+     * */
+
+
+    //******************************* EC27 ********************************
+    /*
+     * test for LDR
+     * boundary: b + v >= 2^31
+     * on point: b + v = 2^31
+     * stop the programme and print out the error
+     */
+
+    /*
+     * test for LDR
+     * boundary: b + v >= 2^31
+     * off point: b + v = 2^31 + 1
+     * stop the programme and print out the error
+     */
+
+    //EC27 can not test here
+
+
+    //******************************* EC28 ********************************
+    /*
+     * test for STR
+     * boundary: b + v <= -(2^31)
+     * on point: b + v = -(2^31)
+     * stop the programme and print out the error
+     * /
+
+    /*
+     * boundary: b + v <= -(2^31)
+     * off point: b + v = -(2^31 + 1)
+     * stop the programme and print out the error
+     * */
+
+    //EC28 cannot give a test
+
+
+    //******************************* EC29 ********************************
+    /*
+     * test for STR
+     * boundary: b + v in -(2^31-1) ... (2^31-1)
+     * on point one: b + v = -(2^31-1)
+     * return a normal value
+     * */
+
+    /*
+     * test for STR
+     * boundary: b + v in -(2^31-1) ... (2^31-1)
+     * on point two: b + v = (2^31-1)
+     * return a normal value
+     * */
+
+
+    //******************************* EC30 ********************************
+    /*
+     * test for STR
+     * boundary: b + v >= 2^31
+     * on point: b + v = 2^31
+     * stop the programme and print out the error
+     */
+
+    /*
+     * test for STR
+     * boundary: b + v >= 2^31
+     * off point: b + v = 2^31 + 1
+     * stop the programme and print out the error
+     */
+
+    //EC30 can not test here
+
+
+    /*
+     *  Machine executes input lines
+     * */
+    private int machineExeLines(List<String> lines) {
+        Machine m = new Machine();
+        return m.execute(lines);
+    }
+}
\ No newline at end of file
diff --git a/test/swen90006/machine/PartitioningTests.java b/test/swen90006/machine/PartitioningTests.java
old mode 100644
new mode 100755
index 5494b44f4615351a610fc7b0b649d30b4b2d0a40..41092c667f213710f4a9d78c892c70a838509538
--- a/test/swen90006/machine/PartitioningTests.java
+++ b/test/swen90006/machine/PartitioningTests.java
@@ -1,5 +1,7 @@
 package swen90006.machine;
 
+import java.io.File;
+import java.io.IOException;
 import java.util.List;
 import java.util.ArrayList;
 import java.nio.charset.Charset;
@@ -8,83 +10,475 @@ import java.nio.file.Files;
 import java.nio.file.FileSystems;
 
 import org.junit.*;
+
 import static org.junit.Assert.*;
 
-public class PartitioningTests
-{
-  //Any method annotated with "@Before" will be executed before each test,
-  //allowing the tester to set up some shared resources.
-  @Before public void setUp()
-  {
-  }
-
-  //Any method annotated with "@After" will be executed after each test,
-  //allowing the tester to release any shared resources used in the setup.
-  @After public void tearDown()
-  {
-  }
-
-  //Any method annotation with "@Test" is executed as a test.
-  @Test public void aTest()
-  {
-    //the assertEquals method used to check whether two values are
-    //equal, using the equals method
-    final int expected = 2;
-    final int actual = 1 + 1;
-    assertEquals(expected, actual);
-  }
-
-  @Test public void anotherTest()
-  {
-    List<String> list = new ArrayList<String>();
-    list.add("a");
-    list.add("b");
-
-    //the assertTrue method is used to check whether something holds.
-    assertTrue(list.contains("a"));
-  }
-
-  //Test test opens a file and executes the machine
-  @Test public void aFileOpenTest()
-  {
-    final List<String> lines = readInstructions("examples/array.s");
-    Machine m = new Machine();
-    assertEquals(m.execute(lines), 45);
-  }
-  
-  //To test an exception, specify the expected exception after the @Test
-  @Test(expected = java.io.IOException.class) 
-    public void anExceptionTest()
-    throws Throwable
-  {
-    throw new java.io.IOException();
-  }
-
-  //This test should fail.
-  //To provide additional feedback when a test fails, an error message
-  //can be included
-  @Test public void aFailedTest()
-  {
-    //include a message for better feedback
-    final int expected = 2;
-    final int actual = 1 + 2;
-    assertEquals("Some failure message", expected, actual);
-  }
-
-  //Read in a file containing a program and convert into a list of
-  //string instructions
-  private List<String> readInstructions(String file)
-  {
-    Charset charset = Charset.forName("UTF-8");
-    List<String> lines = null;
-    try {
-      lines = Files.readAllLines(FileSystems.getDefault().getPath(file), charset);
-    }
-    catch (Exception e){
-      System.err.println("Invalid input file! (stacktrace follows)");
-      e.printStackTrace(System.err);
-      System.exit(1);
-    }
-    return lines;
-  }
-}
+
+public class PartitioningTests {
+    /*
+     * Any method annotated with "@Before" will be executed before each test,
+     * allowing the tester to set up some shared resources.
+     **/
+    @Before
+    public void setUp() {
+    }
+
+    /*
+     * Any method annotated with "@After" will be executed after each test,
+     * allowing the tester to release any shared resources used in the setup.
+     **/
+    @After
+    public void tearDown() {
+    }
+
+    /*
+     * EC1
+     * test for no RET instruction
+     * if there is no RET instruction
+     * throw the NoReturnValueException
+     * */
+    @Test(expected = NoReturnValueException.class)
+    public void noRetTest()
+            throws Throwable {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R0 10");
+        machineExeLines(lines);
+    }
+
+    /*
+     * EC2
+     * test for more than one RET instructions
+     * return the value of first RET
+     * */
+    @Test
+    public void multiRetTest() {
+        List<String> lines = new ArrayList<String>();
+        final int expected = -10;
+        lines.add("MOV R0 " + expected);
+        lines.add("RET R0");
+        lines.add("MOV R1 " + expected * 10);
+        lines.add("RET R1");
+        assertEquals(expected, machineExeLines(lines));
+    }
+
+    /*
+     * EC3
+     * test for the index i of a register less than 0
+     * if i < 0
+     * throw the InvalidInstructionException
+     * */
+    @Test(expected = InvalidInstructionException.class)
+    public void smallRegIndexTest()
+            throws Throwable {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R-1 0");
+        machineExeLines(lines);
+    }
+
+    /*
+     * EC4
+     * test for the index i of a register bigger than 31
+     * if i > 31
+     * throw the InvalidInstructionException
+     * */
+    @Test(expected = InvalidInstructionException.class)
+    public void bigRegIndexTest()
+            throws Throwable {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R32 0");
+        machineExeLines(lines);
+    }
+
+    /*
+     * EC5
+     * test for the value val
+     * use MOV for an example
+     * if val < -65535
+     * throw the InvalidInstructionException
+     * */
+    @Test(expected = InvalidInstructionException.class)
+    public void smallValTest()
+            throws Throwable {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R1 -65536");
+        lines.add("RET R1");
+        machineExeLines(lines);
+    }
+
+    /*
+     * EC6
+     * test for the value val
+     * use MOV for an example
+     * if val > 65535
+     * throw the InvalidInstructionException
+     * */
+    @Test(expected = InvalidInstructionException.class)
+    public void bigValTest()
+            throws Throwable {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R1 65536");
+        lines.add("RET R1");
+        machineExeLines(lines);
+    }
+
+    /*
+    * EC7
+    * test for the value of a register
+    * if regV < -(2^31) + 1
+    * stop the function, show the error
+    * EC7 cannot give a test
+    *
+    @Test
+    public void smallRegVTest() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R0 -2");
+        lines.add("MOV R1 2");
+        int minRegV = 2;
+
+        for (int i = 0; i < 30; i++) {
+            lines.add("MUL R0 R0 R1");
+            minRegV *= 2;
+        }
+        //regV_of_R0 = -(2^31), minRegV = -(2^31)
+        minRegV += 1;
+        lines.add("MUL R0 R0 R1");
+        lines.add("RET R0");
+        assertEquals("The value of register if overflow.", minRegV, machineExeLines(lines));
+        //System.exit(1);
+    }*/
+
+    /*
+     * EC8
+     * test for the value of a register
+     * if regV > 2^31
+     * stop the function, show the error
+     *
+    @Test
+    public void bigRegVTest() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R0 2");
+        lines.add("MOV R1 2");
+        int maxRegV = 2;
+
+        for (int i = 0; i < 30; i++) {
+            lines.add("MUL R0 R0 R1");
+            maxRegV *= 2;
+        }
+        //regV_of_R0 = (2^31), minRegV = (2^31)
+
+        lines.add("MUL R0 R0 R1");
+        lines.add("RET R0");
+        assertEquals("The value of register if overflow.", maxRegV, machineExeLines(lines));
+        //System.exit(1);
+    }*/
+
+    /*
+     * EC9
+     * test for ADD
+     * return a normal value
+     * */
+    @Test
+    public void addNormalTest() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R0 1");
+        lines.add("ADD R0 R0 R0");
+        lines.add("RET R0");
+        assertEquals("Wrong ADD result.", 2, machineExeLines(lines));
+    }
+
+    /*
+     * EC10
+     * test for SUB
+     * return a normal value
+     * */
+    @Test
+    public void subNormalTest() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R0 1");
+        lines.add("SUB R0 R0 R0");
+        lines.add("RET R0");
+        assertEquals("Wrong SUB result.", 0, machineExeLines(lines));
+    }
+
+    /*
+     * EC11
+     * test for MUL
+     * return a normal value
+     * */
+    @Test
+    public void mulNoramlTest() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R0 1");
+        lines.add("MUL R0 R0 R0");
+        lines.add("RET R0");
+        assertEquals("Wrong MUL result.", 1, machineExeLines(lines));
+    }
+
+    /*
+     * EC12
+     * test for DIV
+     * if divisor = 0
+     * return a normal value (still the value of the dividend)
+     * */
+    @Test
+    public void divByZeroTest() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R1 0");
+        lines.add("MOV R0 -3");
+        lines.add("DIV R0 R0 R1");
+        lines.add("RET R0");
+        assertEquals(-3, machineExeLines(lines));
+    }
+
+    /*
+     * EC13
+     * test for DIV
+     * if divisor != 0
+     * return a normal value
+     * */
+    @Test
+    public void divByNonZeroTest() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R1 1");
+        lines.add("MOV R0 3");
+        lines.add("DIV R0 R0 R1");
+        lines.add("RET R0");
+        assertEquals(3, machineExeLines(lines));
+    }
+
+    /*
+     * EC14
+     * test for MOV
+     * return a normal value
+     * */
+    @Test
+    public void movNormalTest() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R0 1");
+        lines.add("RET R0");
+        assertEquals("Wrong ADD result.", 1, machineExeLines(lines));
+    }
+
+    /*
+     * EC15
+     * test for RET
+     * if the register is undefined
+     * return a normal value
+     * */
+    @Test
+    public void retUndefinedTest() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("RET R0");
+        assertEquals(0, machineExeLines(lines));
+    }
+
+    /*
+     * EC16
+     * test for RET
+     * if the register is defined
+     * return a normal value
+     * */
+    @Test
+    public void retNormalTest() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R0 1");
+        lines.add("RET R0");
+        assertEquals("Wrong RET result.", 1, machineExeLines(lines));
+    }
+
+    /*
+     * EC17
+     * test for JMP
+     * if val = 0
+     * cause an infinite loop
+     * but can not have a test case since it will loop forever
+     * */
+
+    /*
+     * EC18
+     * test for JMP
+     * if v < 0 && |v| > the amount of previous pc count
+     * throw the NoReturnValueException
+     * */
+    @Test(expected = NoReturnValueException.class)
+    public void jmpMinusPCNoReturnTest()
+            throws Throwable {
+        List<String> lines = new ArrayList<String>();
+        lines.add("JMP -1");
+        lines.add("RET R0");
+        machineExeLines(lines);
+    }
+
+    /*
+     * EC19
+     * test for JMP
+     * if v > 0 && v > the amount of pc count above
+     * throw the NoReturnValueException
+     * */
+    @Test(expected = NoReturnValueException.class)
+    public void jmpPositivePCNoReturnTest()
+            throws Throwable {
+        List<String> lines = new ArrayList<String>();
+        lines.add("JMP 2");
+        lines.add("RET R0");
+        machineExeLines(lines);
+    }
+
+    /*
+     * EC20
+     * test for JMP
+     * if _pc <= v <= pc_ && v != 0
+     * return a normal value
+     * */
+    @Test
+    public void jmpNormalTest() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("JMP 2");
+        lines.add("MOV R0 1");
+        lines.add("MOV R0 2");
+        lines.add("RET R0");
+        assertEquals("Wrong JMP result.", 2, machineExeLines(lines));
+    }
+
+    /*
+     * EC21
+     * test for JZ
+     * if val = 0
+     * cause an infinite loop
+     * but can not have a test case since it will loop forever
+     * */
+
+    /*
+     * EC22
+     * test for JZ
+     * if v < 0 && |v| > the amount of previous pc count
+     * throw the NoReturnValueException
+     * */
+    @Test(expected = NoReturnValueException.class)
+    public void jzMinusPCNoReturnTest()
+            throws Throwable {
+        List<String> lines = new ArrayList<String>();
+        lines.add("JZ R0 -1");
+        lines.add("RET R0");
+        machineExeLines(lines);
+    }
+
+    /*
+     * EC23
+     * test for JZ
+     * if v > 0 && v > the amount of pc count above
+     * throw the NoReturnValueException
+     * */
+    @Test(expected = NoReturnValueException.class)
+    public void jzPositivePCNoReturnTest()
+            throws Throwable {
+        List<String> lines = new ArrayList<String>();
+        lines.add("JZ R0 2");
+        lines.add("RET R0");
+        machineExeLines(lines);
+    }
+
+    /*
+     * EC24
+     * test for JZ
+     * if _pc <= v <= pc_ && v != 0
+     * return a normal value
+     * */
+    @Test
+    public void jzNormalTest() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R1 1");
+        lines.add("JZ R1 3");
+        lines.add("SUB R1 R1 R1");
+        lines.add("MOV R1 2");
+        lines.add("RET R1");
+        assertEquals("Wrong JMP result.", 2, machineExeLines(lines));
+    }
+
+    /*
+     * EC25
+     * test for LDR
+     * if b + v <= -(2^31)
+     * stop the programme and print out the error
+     *
+    @Test
+    public void ldrSmallAddressTest() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R0 2");
+        lines.add("MOV R1 2");
+        lines.add("MOV R2 2");
+        int m = 2;
+
+        for (int i = 0; i < 29; i++) {
+            lines.add("MUL R0 R0 R2");
+            lines.add("MUL R1 R1 R2");
+            m *= 2;
+        }
+        System.out.println(m);
+        lines.add("LDR R0 R1 -65535");
+        lines.add("RET R0");
+        machineExeLines(lines);
+    }*/
+
+    /*
+     * EC26
+     * test for LDR
+     * if b + v in -(2^31-1) ... (2^31-1)
+     * return a normal value
+     * */
+    @Test
+    public void ldrNormalAddressTest() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R0 1");
+        lines.add("MOV R1 2");
+        lines.add("LDR R0 R1 -2");
+        lines.add("RET R0");
+        assertEquals("Wrong LDR result.", 0, machineExeLines(lines));
+    }
+
+    /*
+     * EC27
+     * test for LDR
+     * if b + v >= 2^31
+     * stop the programme and print out the error
+     */
+
+    /*
+     * EC28
+     * test for STR
+     * if b + v <= -(2^31)
+     * stop the programme and print out the error
+     */
+
+    /*
+     * EC29
+     * test for STR
+     * if b + v in -(2^31-1) ... (2^31-1)
+     * return a normal value
+     * */
+    @Test
+    public void strNormalAddressTest() {
+        List<String> lines = new ArrayList<String>();
+        lines.add("MOV R0 1");
+        lines.add("MOV R1 2");
+        lines.add("STR R0 -1 R1");
+        lines.add("RET R0");
+        machineExeLines(lines);
+    }
+
+    /*
+     * EC30
+     * test for STR
+     * if b + v >= 2^31
+     * stop the programme and print out the error
+     */
+
+
+    /*
+     *  Machine executes input lines
+     * */
+    private int machineExeLines(List<String> lines) {
+        Machine m = new Machine();
+        return m.execute(lines);
+    }
+}
\ No newline at end of file