diff --git a/Automail/src/automail/Automail.java b/Automail/src/automail/Automail.java
index 2eb9e1b07a8ab9d4885ee3eaf584cced9f8e07b0..fff050fe088a03f7b4734a1fe61e078169f5e828 100644
--- a/Automail/src/automail/Automail.java
+++ b/Automail/src/automail/Automail.java
@@ -1,20 +1,29 @@
 package automail;
 
+import com.unimelb.swen30006.wifimodem.WifiModem;
 import simulation.IMailDelivery;
+import simulation.Simulation;
 
 public class Automail {
 	      
     public Robot[] robots;
     public MailPool mailPool;
     
-    public Automail(MailPool mailPool, IMailDelivery delivery, int numRobots) {  	
-    	/** Initialize the MailPool */
-    	
+    public Automail(MailPool mailPool, IMailDelivery delivery, int numRobots, StatisticsLog statisticsLog, ChargeCalculator chargeCalculator ) {
+
+        /** Initialize the MailPool */
     	this.mailPool = mailPool;
     	
     	/** Initialize robots */
     	robots = new Robot[numRobots];
-    	for (int i = 0; i < numRobots; i++) robots[i] = new Robot(delivery, mailPool, i);
+    	for (int i = 0; i < numRobots; i++){
+            robots[i] = new Robot(delivery, mailPool, i);
+
+            // Each robots gets personal device to access statistics and charge calculator
+            RobotDevice newDevice = new RobotDevice(statisticsLog, chargeCalculator);
+            robots[i].device = newDevice;
+
+        }
     }
-    
+
 }
diff --git a/Automail/src/automail/ChargeCalculator.java b/Automail/src/automail/ChargeCalculator.java
new file mode 100644
index 0000000000000000000000000000000000000000..5ae2ff0df33e182940e9357c9b386f3c1b50c3ba
--- /dev/null
+++ b/Automail/src/automail/ChargeCalculator.java
@@ -0,0 +1,41 @@
+package automail;
+
+import com.unimelb.swen30006.wifimodem.WifiModem;
+import simulation.Building;
+import simulation.Simulation;
+
+public class ChargeCalculator {
+
+    public final WifiModem wifiModem;
+    private double activityUnitPrice;
+    private double markupPercentage;
+
+    public ChargeCalculator(WifiModem wifiModem, double activityUnitPrice, double markupPercentage) {
+        this.wifiModem = wifiModem;
+        this.activityUnitPrice = activityUnitPrice;
+        this.markupPercentage = markupPercentage;
+    }
+
+
+    public double calculateCharge(MailItem item) {
+        int destination = item.destination_floor;
+        double activityUnits = ((2*(destination - Building.MAILROOM_LOCATION)) * Simulation.MOVEMENT_COST) + Simulation.LOOKUP_COST;
+        item.setActivityUnitsUtilized(activityUnits);
+        double activityCost = activityUnits * activityUnitPrice;
+        item.setActivityCost(activityCost);
+        double latestServiceFee = wifiModem.forwardCallToAPI_LookupPrice(destination);
+        double serviceFee = item.getServiceFee();
+        if (latestServiceFee >= 0 ) {
+            item.setSuccessfulLookupCount(item.getSuccessfulLookupCount()+1);
+            serviceFee = latestServiceFee;
+            item.setServiceFee(latestServiceFee);
+        }
+        double charge = (activityCost + serviceFee) * (1 + markupPercentage);
+        item.setCharge(charge);
+        return charge;
+    }
+
+    public double getActivityUnitPrice() {
+        return activityUnitPrice;
+    }
+}
diff --git a/Automail/src/automail/MailItem.java b/Automail/src/automail/MailItem.java
index 2bdf9f2f8531b4494d96f326b8dd21cf4e3a2edc..493981ff46edd96242733f21d3cf6ee11dce5ecb 100644
--- a/Automail/src/automail/MailItem.java
+++ b/Automail/src/automail/MailItem.java
@@ -19,7 +19,13 @@ public class MailItem {
     /** The weight in grams of the mail item */
     protected final int weight;
 
+    /* Holds the financial information associated with item's delivery */
     private double serviceFee;
+    private int successfulLookupCount;
+    private double activityUnitsUtilized;
+    private double charge;
+    private double cost;
+    private double activityCost;
 
     /**
      * Constructor for a MailItem
@@ -39,10 +45,17 @@ public class MailItem {
     }
 
     @Override
+    // The toString for the older version
     public String toString(){
         return String.format("Mail Item:: ID: %6s | Arrival: %4d | Destination: %2d | Weight: %4d", id, arrival_time, destination_floor, weight);
     }
 
+    // The toString for the new version with the new statistics
+    public String toStringv2(){
+        return String.format("Mail Item:: ID: %6s | Arrival: %4d | Destination: %2d | Weight: %4d | Charge %.2f " +
+                "| Cost: %.2f | Fee: %.2f | Activity: %.2f", id, arrival_time, destination_floor, weight, charge,
+                activityCost, serviceFee, activityUnitsUtilized);
+    }
     /**
      *
      * @return the destination floor of the mail item
@@ -74,6 +87,10 @@ public class MailItem {
    public int getWeight(){
        return weight;
    }
+
+    public double getServiceFee() {
+        return serviceFee;
+    }
    
 	static private int count = 0;
 	static private Map<Integer, Integer> hashMap = new TreeMap<Integer, Integer>();
@@ -85,4 +102,44 @@ public class MailItem {
 		if (hash == null) { hash = count++; hashMap.put(hash0, hash); }
 		return hash;
 	}
+
+    public double getActivityUnitsUtilized() {
+        return activityUnitsUtilized;
+    }
+
+    public void setActivityUnitsUtilized(double activityUnitsUtilized) {
+        this.activityUnitsUtilized = activityUnitsUtilized;
+    }
+
+    public double getCharge() {
+        return charge;
+    }
+
+    public void setCharge(double charge) {
+        this.charge = charge;
+    }
+
+    public double getCost() {
+        return cost;
+    }
+
+    public void setCost(double cost) {
+        this.cost = cost;
+    }
+
+    public double getActivityCost() {
+        return activityCost;
+    }
+
+    public void setActivityCost(double activityCost) {
+        this.activityCost = activityCost;
+    }
+
+    public int getSuccessfulLookupCount() {
+        return successfulLookupCount;
+    }
+
+    public void setSuccessfulLookupCount(int successfulLookupCount) {
+        this.successfulLookupCount = successfulLookupCount;
+    }
 }
diff --git a/Automail/src/automail/MailPool.java b/Automail/src/automail/MailPool.java
index 7977178aa28fece927ce960c9ab4011a86bc620b..9d3ce33a9aa315fd573a5a33aa5f1aae19d56b6d 100644
--- a/Automail/src/automail/MailPool.java
+++ b/Automail/src/automail/MailPool.java
@@ -14,6 +14,11 @@ import java.util.ListIterator;
  * 
  */
 public class MailPool {
+
+	public MailItem getItem(int i) {
+		return pool.get(i).mailItem;
+	}
+
 	private class Item {
 		int destination;
 		double charge;
@@ -59,15 +64,7 @@ public class MailPool {
 		pool.sort(new ItemComparator());
 	}
 
-	public double calculateCharge(int itemIndex, double serviceFee, double activityUnitPrice, double markupPercentage){
-		double robotsMovement = 5.0D;
-		double remoteLookup = 0.1D;
-		int destination = pool.get(itemIndex).destination;
-		double activityUnits = ((destination - Building.MAILROOM_LOCATION) * robotsMovement) + remoteLookup;
-		double activityCost = activityUnits * activityUnitPrice;
-		double charge = (activityCost + serviceFee) * (1 + markupPercentage);
-		return charge;
-	}
+
 
 	public void setItemCharge(int itemIndex, double charge){
 		Item item = new Item(pool.get(itemIndex).mailItem);
@@ -107,6 +104,17 @@ public class MailPool {
 		}
 	}
 
+	public double calculateCharge(int itemIndex, double serviceFee, double activityUnitPrice, double markupPercentage){
+		double robotsMovement = 5.0D;
+		double remoteLookup = 0.1D;
+		int destination = pool.get(itemIndex).destination;
+		double activityUnits = ((destination - Building.MAILROOM_LOCATION) * robotsMovement) + remoteLookup;
+		double activityCost = activityUnits * activityUnitPrice;
+		double charge = (activityCost + serviceFee) * (1 + markupPercentage);
+		return charge;
+	}
+
+
 	/**
      * load up any waiting robots with mailItems, if any.
      */
diff --git a/Automail/src/automail/Robot.java b/Automail/src/automail/Robot.java
index ff066165a2608fe944268beeae2596be77659d47..55ad972ac98f4908902512672a684b4ededb561b 100644
--- a/Automail/src/automail/Robot.java
+++ b/Automail/src/automail/Robot.java
@@ -5,6 +5,7 @@ import exceptions.ItemTooHeavyException;
 import simulation.Building;
 import simulation.Clock;
 import simulation.IMailDelivery;
+import simulation.Simulation;
 
 /**
  * The robot delivers mail!
@@ -13,8 +14,11 @@ public class Robot {
 	
     static public final int INDIVIDUAL_MAX_WEIGHT = 2000;
 
+    /** Personal information in Robot class */
     IMailDelivery delivery;
+    RobotDevice device;
     protected final String id;
+
     /** Possible states the robot can be in */
     public enum RobotState { DELIVERING, WAITING, RETURNING }
     public RobotState current_state;
@@ -31,7 +35,6 @@ public class Robot {
     /**
      * Initiates the robot's location at the start to be at the mailroom
      * also set it to be waiting for mail.
-     * @param behaviour governs selection of mail items for delivery and behaviour on priority arrivals
      * @param delivery governs the final delivery
      * @param mailPool is the source of mail items
      */
@@ -87,8 +90,13 @@ public class Robot {
                 break;
     		case DELIVERING:
     			if(current_floor == destination_floor){ // If already here drop off either way
+
                     /** Delivery complete, report this to the simulator! */
+                    double charge = device.calculateFinalCharge(deliveryItem);
+                    device.recordDeliverySuccess(deliveryItem);
                     delivery.deliver(deliveryItem);
+
+
                     deliveryItem = null;
                     deliveryCounter++;
                     if(deliveryCounter > 2){  // Implies a simulation bug
diff --git a/Automail/src/automail/RobotDevice.java b/Automail/src/automail/RobotDevice.java
new file mode 100644
index 0000000000000000000000000000000000000000..21ac18e7b71501b27505b52982fb6390ee4f15e7
--- /dev/null
+++ b/Automail/src/automail/RobotDevice.java
@@ -0,0 +1,26 @@
+package automail;
+
+import com.unimelb.swen30006.wifimodem.WifiModem;
+import simulation.Simulation;
+
+public class RobotDevice {
+
+    public final StatisticsLog statisticsLog;
+    public final ChargeCalculator chargeCalculator;
+
+    public RobotDevice(StatisticsLog statisticsLog, ChargeCalculator chargeCalculator) {
+        this.statisticsLog = statisticsLog;
+        this.chargeCalculator = chargeCalculator;
+    }
+
+    public double calculateFinalCharge (MailItem item) {
+        double final_charge = chargeCalculator.calculateCharge(item) - Simulation.LOOKUP_COST;
+        return final_charge;
+    }
+
+    public void recordDeliverySuccess(MailItem item) {
+        double activity_unit_price = chargeCalculator.getActivityUnitPrice();
+        statisticsLog.recordDeliverySuccess(item, activity_unit_price);
+    }
+
+}
diff --git a/Automail/src/automail/StatisticsLog.java b/Automail/src/automail/StatisticsLog.java
new file mode 100644
index 0000000000000000000000000000000000000000..8ef7e45dfe9c4a35c741a180c3c0f8dd0de9dc38
--- /dev/null
+++ b/Automail/src/automail/StatisticsLog.java
@@ -0,0 +1,39 @@
+package automail;
+
+import simulation.Building;
+import simulation.Simulation;
+
+public class StatisticsLog {
+    private int totalItemsDelivered;
+    private double totalBillableActivity;
+    private double totalActivityCost;
+    private double totalServiceCost;
+    private int numSuccessfulLookup;
+    private int numFailedLookup;
+    private int totalLookup;
+
+    private final int ONE_LOOKUP = 1;
+
+
+    public void recordDeliverySuccess(MailItem deliveryItem, double activityUnitPrice) {
+        totalItemsDelivered++;
+        totalBillableActivity = totalBillableActivity + 2*(deliveryItem.getDestFloor() - Building.MAILROOM_LOCATION) + ONE_LOOKUP;
+        totalActivityCost = totalBillableActivity * activityUnitPrice;
+        totalServiceCost = totalServiceCost + deliveryItem.getServiceFee();
+        numSuccessfulLookup = numSuccessfulLookup + deliveryItem.getSuccessfulLookupCount();
+        numFailedLookup = numFailedLookup + (2 - deliveryItem.getSuccessfulLookupCount());
+        totalLookup = numSuccessfulLookup+numFailedLookup;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("Total items delivered: %d \n" +
+                "Total billable activity: %.2f \n" +
+                "Total activity cost: %.2f \n" +
+                "Total service cost: %.2f \n" +
+                "Total failed lookups: %d \n" +
+                "Total successful lookups: %d \n" +
+                "Total lookups: %d",totalItemsDelivered, totalBillableActivity, totalActivityCost, totalServiceCost,
+                numFailedLookup, numSuccessfulLookup, totalLookup );
+    }
+}
diff --git a/Automail/src/simulation/Simulation.java b/Automail/src/simulation/Simulation.java
index 1dea0886e81f313ccc2fbc33f240cd85ade4425e..3fe8e05979e29faf89fb409bb33c1b673132d247 100644
--- a/Automail/src/simulation/Simulation.java
+++ b/Automail/src/simulation/Simulation.java
@@ -1,8 +1,6 @@
 package simulation;
 
-import automail.Automail;
-import automail.MailItem;
-import automail.MailPool;
+import automail.*;
 import com.unimelb.swen30006.wifimodem.WifiModem;
 import exceptions.ExcessiveDeliveryException;
 import exceptions.ItemTooHeavyException;
@@ -21,6 +19,11 @@ public class Simulation {
 	private static boolean CHARGE_DISPLAY;
 	private static double ACTIVITY_UNIT_PRICE;
 	private static double MARKUP_PERCENTAGE;
+	public static final double MOVEMENT_COST = 5.0D;
+	public static final double LOOKUP_COST = 0.1D;
+	private static final boolean NEW = true;
+	private static final boolean OLD = false;
+	private static boolean version = OLD;
 	
     /** Constant for the mail generator */
     private static int MAIL_TO_CREATE;
@@ -28,12 +31,20 @@ public class Simulation {
     
     private static ArrayList<MailItem> MAIL_DELIVERED;
     private static double total_delay = 0;
+
     private static WifiModem wModem = null;
+    private static ChargeCalculator chargeCalculator = null;
+    private static StatisticsLog statisticsLog = null;
+
+	/*---------------------------------------------------------------------------------------------------------------*/
 
     public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, IOException {
     	
     	/** Load properties for simulation based on either default or a properties file.**/
     	Properties automailProperties = setUpProperties();
+
+    	/* Check which version to run based on the following condition */
+		version = (CHARGE_DISPLAY && CHARGE_THRESHOLD != 0);
     	
     	//An array list to record mails that have been delivered
         MAIL_DELIVERED = new ArrayList<MailItem>();
@@ -42,7 +53,7 @@ public class Simulation {
          * If a program argument is entered, the first argument will be a random seed.
          * If not a random seed will be from a properties file. 
          * Otherwise, no a random seed. */
-        
+
         /** Used to see whether a seed is initialized or not */
         HashMap<Boolean, Integer> seedMap = new HashMap<>();
         if (args.length == 0 ) { // No arg
@@ -57,7 +68,8 @@ public class Simulation {
         }
         Integer seed = seedMap.get(true);
         System.out.println("#A Random Seed: " + (seed == null ? "null" : seed.toString()));
-        
+
+
         // Install the modem & turn on the modem
         try {
         	System.out.println("Setting up Wifi Modem");
@@ -66,33 +78,35 @@ public class Simulation {
 		} catch (Exception mException) {
 			mException.printStackTrace();
 		}
-        /**
-         * This code section is for running a simulation
-         */
-        /* Instantiate MailPool and Automail */
-     	MailPool mailPool = new MailPool(NUM_ROBOTS);
-        Automail automail = new Automail(mailPool, new ReportDelivery(), NUM_ROBOTS);
+
+        /* Instantiate the main objects in the simulation */
+		statisticsLog = new StatisticsLog();
+		chargeCalculator = new ChargeCalculator(wModem, ACTIVITY_UNIT_PRICE, MARKUP_PERCENTAGE);
+		MailPool mailPool = new MailPool(NUM_ROBOTS);
+		Automail automail = new Automail(mailPool, new ReportDelivery(), NUM_ROBOTS, statisticsLog, chargeCalculator);
         MailGenerator mailGenerator = new MailGenerator(MAIL_TO_CREATE, MAIL_MAX_WEIGHT, mailPool, seedMap);
-        /** Generate all the mails */
+
+        /** Generate all the mail */
         mailGenerator.generateAllMail();
+
+        /* START the simulation  */
         while(MAIL_DELIVERED.size() != mailGenerator.MAIL_TO_CREATE) {
-        	// System.out.printf("Delivered: %4d; Created: %4d%n", MAIL_DELIVERED.size(), mailGenerator.MAIL_TO_CREATE);
             mailGenerator.addToMailPool();
-            if(CHARGE_DISPLAY){
+            if (version == NEW){
+            	// Calculate expected charge for each item
             	int poolSize = mailPool.getPoolSize();
             	for(int i=0; i<poolSize; i++){
             		if(mailPool.isNewItem(i)) {
-            			int destination = mailPool.getItemDestination(i);
-						double serviceFee = wModem.forwardCallToAPI_LookupPrice(destination);
-						double charge = mailPool.calculateCharge(i, serviceFee, ACTIVITY_UNIT_PRICE, MARKUP_PERCENTAGE);
+						double charge = chargeCalculator.calculateCharge(mailPool.getItem(i));
 						mailPool.setItemCharge(i, charge);
 						mailPool.getItemInfo(i);
 					}
             	}
-            	if(CHARGE_THRESHOLD != 0){
-					mailPool.sortPriorityMailItems(CHARGE_THRESHOLD);
-				}
-			}
+				// Priority sort the items
+				mailPool.sortPriorityMailItems(CHARGE_THRESHOLD);
+			} // All items have been prioritized
+
+            // Now send the Robots to deliver the mail
             try {
                 automail.mailPool.loadItemsToRobot();
 				for (int i=0; i < NUM_ROBOTS; i++) {
@@ -103,12 +117,16 @@ public class Simulation {
 				System.out.println("Simulation unable to complete.");
 				System.exit(0);
 			}
+            // All robots out for delivery
             Clock.Tick();
         }
+        // Simulation is finished. print results
         printResults();
         System.out.println(wModem.Turnoff());
+        //
     }
-    
+    /*---------------------------------------------------------------------------------------------------------------*/
+
     static private Properties setUpProperties() throws IOException {
     	Properties automailProperties = new Properties();
 		// Default properties
@@ -123,7 +141,7 @@ public class Simulation {
     	// Read properties
 		FileReader inStream = null;
 		try {
-			inStream = new FileReader("automail.properties");
+			inStream = new FileReader("swen30006-group-work-master/Automail/automail.properties");
 			automailProperties.load(inStream);
 		} finally {
 			 if (inStream != null) {
@@ -161,14 +179,21 @@ public class Simulation {
 		System.out.println("Activity_Unit_Price: " + ACTIVITY_UNIT_PRICE);
 		return automailProperties;
     }
+	/*---------------------------------------------------------------------------------------------------------------*/
 
     static class ReportDelivery implements IMailDelivery {
-    	
+
     	/** Confirm the delivery and calculate the total score */
     	public void deliver(MailItem deliveryItem){
     		if(!MAIL_DELIVERED.contains(deliveryItem)){
     			MAIL_DELIVERED.add(deliveryItem);
-                System.out.printf("T: %3d > Delivered(%4d) [%s]%n", Clock.Time(), MAIL_DELIVERED.size(), deliveryItem.toString());
+    			if (version == NEW) {
+					System.out.printf("T: %3d > Delivered(%4d) [%s]%n", Clock.Time(), MAIL_DELIVERED.size(),
+							deliveryItem.toStringv2());
+				} else {
+					System.out.printf("T: %3d > Delivered(%4d) [%s]%n", Clock.Time(), MAIL_DELIVERED.size(),
+							deliveryItem.toString());
+				}
     			// Calculate delivery score
     			total_delay += calculateDeliveryDelay(deliveryItem);
     		}
@@ -182,7 +207,9 @@ public class Simulation {
     	}
 
     }
-    
+
+	/*---------------------------------------------------------------------------------------------------------------*/
+
     private static double calculateDeliveryDelay(MailItem deliveryItem) {
     	// Penalty for longer delivery times
     	final double penalty = 1.2;
@@ -191,9 +218,15 @@ public class Simulation {
         return Math.pow(Clock.Time() - deliveryItem.getArrivalTime(),penalty)*(1+Math.sqrt(priority_weight));
     }
 
+	/*---------------------------------------------------------------------------------------------------------------*/
+
     public static void printResults(){
         System.out.println("T: "+Clock.Time()+" | Simulation complete!");
         System.out.println("Final Delivery time: "+Clock.Time());
         System.out.printf("Delay: %.2f%n", total_delay);
+        if (version == NEW) System.out.println(statisticsLog.toString());
     }
+
+	/*---------------------------------------------------------------------------------------------------------------*/
+
 }