diff --git a/MV3302ClassCode/src/mv3302/SimpleMover.java b/MV3302ClassCode/src/mv3302/SimpleMover.java
index b631b6cc556625677c784712ba22abb2a2799912..a28e919049ebf27842408d74851267f8327cd67a 100644
--- a/MV3302ClassCode/src/mv3302/SimpleMover.java
+++ b/MV3302ClassCode/src/mv3302/SimpleMover.java
@@ -1,66 +1,106 @@
-/*
- * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
- * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
- */
 package mv3302;
 
 import java.awt.geom.Point2D;
-import static java.lang.Double.NaN;
+import static mv3302.SimplestMover.NaP;
 import simkit.Schedule;
 import simkit.SimEntityBase;
+
 import simkit.smd.Mover;
 
 /**
+ * A simple implementation of the DES "Mover" concept.
  *
  * @author ahbuss
  */
 public class SimpleMover extends SimEntityBase implements Mover {
 
-    public static Point2D NaP = new Point2D.Double(NaN, NaN);
-
-    public Point2D initialLocation;
+    /**
+     * Start here
+     */
+    private Point2D initialLocation;
 
-    public double maxSpeed;
+    /**
+     * All movement will be at this speed
+     */
+    private double maxSpeed;
 
-    public Point2D lastStopLocation;
+    /**
+     * Current velocity vector
+     */
+    protected Point2D velocity;
 
-    public Point2D velocity;
+    /**
+     * Location where SimpleMover last stopped
+     */
+    protected Point2D lastStopLocation;
 
-    public Point2D destination;
+    /**
+     * Current destination
+     */
+    protected Point2D destination;
 
-    public double startMoveTime;
+    /**
+     * simTime when move starts (or when it stops)
+     */
+    protected double startMoveTime;
 
+    /**
+     * Instantiate Point2D states by cloning NaP
+     */
     public SimpleMover() {
         lastStopLocation = (Point2D) NaP.clone();
         velocity = (Point2D) NaP.clone();
         destination = (Point2D) NaP.clone();
     }
 
+    /**
+     * Instantiate with the given parameters
+     *
+     * @param initialLocation Given initial location
+     * @param maxSpeed Given maxSpeed
+     */
     public SimpleMover(Point2D initialLocation, double maxSpeed) {
         this();
         setInitialLocation(initialLocation);
         setMaxSpeed(maxSpeed);
     }
 
+    /**
+     * set destination location to NaP<br>
+     * set lastStopLocation to initialLocation<br>
+     * set velocity to (0.0, 0.0)<br>
+     * set startMoveTime to 0.0
+     *
+     */
     @Override
     public void reset() {
         super.reset();
-        lastStopLocation.setLocation(initialLocation);
+        destination = (Point2D) NaP.clone();
+        lastStopLocation = getInitialLocation();
         velocity.setLocation(0.0, 0.0);
-        destination.setLocation(NaP);
         startMoveTime = 0.0;
     }
 
+    /**
+     * Nothing scheduled - waiting to hear MoveTo event
+     */
     public void doRun() {
+        firePropertyChange("startMoveTime", getStartMoveTime());
         firePropertyChange("lastStopLocation", getLastStopLocation());
         firePropertyChange("velocity", getVelocity());
         firePropertyChange("destination", getDestination());
-        firePropertyChange("startMoveTime", getStartMoveTime());
     }
 
-    public void doMoveTo(Point2D newDestination) {
+    /**
+     * To be "heard" from a mover manager.<br>
+     * set destination to the given argument<br>
+     * schedule StartMove if non-zero travel distance
+     *
+     * @param destination Given new destination
+     */
+    public void doMoveTo(Point2D destination) {
         Point2D oldDestination = getDestination();
-        this.destination.setLocation(newDestination);
+        this.destination = destination;
         firePropertyChange("destination", oldDestination, getDestination());
 
         if (lastStopLocation.distance(destination) > 0.0) {
@@ -68,26 +108,43 @@ public class SimpleMover extends SimEntityBase implements Mover {
         }
     }
 
+    /**
+     * set velocity per the new destination and maxSpeed<br>
+     * set startMoveTime to current simTime<br>
+     * schedule EndMove with delay of travel time
+     *
+     * @param mover Should be "this" Mover
+     */
+    @Override
     public void doStartMove(Mover mover) {
-        double oldStartMoveTime = getStartMoveTime();
-        startMoveTime = Schedule.getSimTime();
-        firePropertyChange("startMoveTime", oldStartMoveTime, getStartMoveTime());
+        Point2D oldVelocity = getVelocity();
+        velocity = new Point2D.Double(
+                destination.getX() - lastStopLocation.getX(),
+                destination.getY() - lastStopLocation.getY()
+        );
+
         double distance = lastStopLocation.distance(destination);
-        double a = getMaxSpeed() / distance;
 
-        Point2D oldVelocity = getVelocity();
-        velocity.setLocation(destination.getX() - lastStopLocation.getX(), destination.getY() - lastStopLocation.getY());
-        velocity.setLocation(a * velocity.getX(), a * velocity.getY());
+        velocity.setLocation(velocity.getX() * maxSpeed / distance,
+                velocity.getY() * maxSpeed / distance);
         firePropertyChange("velocity", oldVelocity, getVelocity());
 
-        waitDelay("EndMove", 1.0/a, mover);
-    }
-
-    public void doEndMove(Mover mover) {
         double oldStartMoveTime = getStartMoveTime();
         startMoveTime = Schedule.getSimTime();
         firePropertyChange("startMoveTime", oldStartMoveTime, getStartMoveTime());
 
+        double travelTime = distance / maxSpeed;
+        waitDelay("EndMove", travelTime, mover);
+    }
+
+    /**
+     * Set lastStopLocation coordinates to destination<br>
+     * set velocity to (0.0, 0.0)<br>
+     * set destination of NaP
+     *
+     * @param mover Should be "this" Mover
+     */
+    public void doEndMove(Mover mover) {
         Point2D oldLastStopLocation = getLastStopLocation();
         lastStopLocation.setLocation(destination);
         firePropertyChange("lastStopLocation", oldLastStopLocation, getLastStopLocation());
@@ -95,36 +152,74 @@ public class SimpleMover extends SimEntityBase implements Mover {
         Point2D oldVelocity = getVelocity();
         velocity.setLocation(0.0, 0.0);
         firePropertyChange("velocity", oldVelocity, getVelocity());
+
+        Point2D oldDestination = getDestination();
+        destination.setLocation(NaP);
+        firePropertyChange("destination", oldDestination, getDestination());
+    }
+
+    /**
+     * Scheduled when Mover "stops" for a period of time.<br>
+     * Set lastStopLocation to currentLocation<br>
+     * setVelocity to (0.0, 0.0)
+     *
+     * @param mover Should be "this" Mover
+     */
+    @Override
+    public void doStop(Mover mover) {
+        Point2D oldLastStopLocation = getLastStopLocation();
+        lastStopLocation.setLocation(getCurrentLocation());
+        firePropertyChange("lastStopLocation", oldLastStopLocation, getLastStopLocation());
+
+        Point2D oldVelocity = getVelocity();
+        velocity.setLocation(0.0, 0.0);
+        firePropertyChange("velocity", oldVelocity, getVelocity());
+
     }
-    
-    public void doOrderStop(){
+
+    /**
+     * to be "heard" from Mover Manager when stopping<br>
+     * Schedule Stop
+     */
+    public void doOrderStop() {
         waitDelay("Stop", 0.0, this);
     }
-    
-    public void doStop(Mover mover){
-        Point2D oldLastStopLocation = lastStopLocation;
-        lastStopLocation = getCurrentLocation();
-        firePropertyChange("lastStopLocation", oldLastStopLocation, lastStopLocation);
-        velocity.setLocation(0.0, 0.0);
-        interrupt("EndMove", mover);
+
+    /**
+     * "Implicit" state - determined using the linear equation of motion.
+     *
+     * @return The current location of this Mover
+     */
+    @Override
+    public Point2D getCurrentLocation() {
+        Point2D currentLocation = (Point2D) NaP.clone();
+        double elapsedTime = Schedule.getSimTime() - getStartMoveTime();
+        currentLocation.setLocation(lastStopLocation.getX() + elapsedTime * velocity.getX(),
+                lastStopLocation.getY() + elapsedTime * velocity.getY());
+        return currentLocation;
+
     }
-    
+
     /**
-     * @return the NaP
+     *
+     * @return the maxSpeed
      */
-    public static Point2D getNaP() {
-        return NaP;
+    @Override
+    public double getMaxSpeed() {
+        return this.maxSpeed;
     }
 
     /**
-     * @param aNaP the NaP to set
+     *
+     * @return copy of velocity
      */
-    public static void setNaP(Point2D aNaP) {
-        NaP = aNaP;
+    @Override
+    public Point2D getVelocity() {
+        return (Point2D) velocity.clone();
     }
 
     /**
-     * @return the initialLocation
+     * @return copy of the initialLocation
      */
     public Point2D getInitialLocation() {
         return (Point2D) initialLocation.clone();
@@ -138,28 +233,25 @@ public class SimpleMover extends SimEntityBase implements Mover {
     }
 
     /**
-     * @return the maxSpeed
+     * @param maxSpeed the maxSpeed to set
+     * @throws IllegalArgumentException if maxSpeed &lt; 0.0
      */
-    public double getMaxSpeed() {
-        return maxSpeed;
+    public void setMaxSpeed(double maxSpeed) {
+        if (maxSpeed < 0.0) {
+            throw new IllegalArgumentException("maxSpeed must be 0.0: " + maxSpeed);
+        }
+        this.maxSpeed = maxSpeed;
     }
 
     /**
-     * @return the lastStopLocation
+     * @return copy of the lastStopLocation
      */
     public Point2D getLastStopLocation() {
         return (Point2D) lastStopLocation.clone();
     }
 
     /**
-     * @return the velocity
-     */
-    public Point2D getVelocity() {
-        return (Point2D) velocity.clone();
-    }
-
-    /**
-     * @return the destination
+     * @return copy of the destination
      */
     public Point2D getDestination() {
         return (Point2D) destination.clone();
@@ -173,32 +265,20 @@ public class SimpleMover extends SimEntityBase implements Mover {
     }
 
     /**
-     * @param maxSpeed the maxSpeed to set
+     * 
+     * @return Name currentLocation velocity
      */
-    public void setMaxSpeed(double maxSpeed) {
-        if (maxSpeed < 0.0) {
-            throw new IllegalArgumentException("maxSpeed must be >= 0.0: " + maxSpeed);
-        }
-        this.maxSpeed = maxSpeed;
-    }
-
-    public Point2D getCurrentLocation() {
-        double updateTime = Schedule.getSimTime() - getStartMoveTime();
-        return new Point2D.Double(lastStopLocation.getX() + updateTime * velocity.getX(),
-                lastStopLocation.getY() + updateTime * velocity.getY());
-//        Point2D currentLocation = getVelocity();
-//        currentLocation.setLocation(currentLocation.getX() * updateTime, currentLocation.getY() * updateTime);
-//        currentLocation.setLocation(lastStopLocation.getX() + currentLocation.getX(), lastStopLocation.getY() + currentLocation.getY());
-//        return currentLocation;    
-
-    }
-
     @Override
     public String toString() {
         return String.format("%s %s %s", getName(), getCurrentLocation(), getVelocity());
     }
 
+    /**
+     * 
+     * @return super toString()
+     */
     public String paramString() {
         return super.toString();
     }
+
 }
diff --git a/MV3302ClassCode/src/mv3302/SimplePathMoverManager.java b/MV3302ClassCode/src/mv3302/SimplePathMoverManager.java
index 9090d7665e79486709c93a3d9907785f6ec65705..d971360051fb1a330452131bf8cd8ea638076660 100644
--- a/MV3302ClassCode/src/mv3302/SimplePathMoverManager.java
+++ b/MV3302ClassCode/src/mv3302/SimplePathMoverManager.java
@@ -1,81 +1,112 @@
-/*
- * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
- * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
- */
 package mv3302;
 
 import java.awt.geom.Point2D;
-import static java.lang.Double.NaN;
+import static mv3302.SimplestMover.NaP;
 import simkit.SimEntityBase;
 import simkit.smd.Mover;
 
 /**
+ * Simple Path Mover Manager. Directs a listening Mover to each wayPoint in
+ * order until the last, when it "stops"
  *
- * @author dansl
+ * @author ahbuss
  */
 public class SimplePathMoverManager extends SimEntityBase {
 
+    /**
+     * If true, start immediately
+     */
     private boolean startOnRun;
 
-    protected Point2D[] path;
+    /**
+     * Given list of wayPoints
+     */
+    private Point2D[] path;
 
+    /**
+     * index of next wayPoint
+     */
     protected int nextIndex;
 
-    protected Point2D nextWaypoint;
+    /**
+     * next destination
+     */
+    protected Point2D nextDestination;
 
+    /**
+     * Instantiate nextDestination as copy of NaP
+     */
     public SimplePathMoverManager() {
+        nextDestination = (Point2D) NaP.clone();
     }
 
+    /**
+     * Instantiate with the given parameters
+     *
+     * @param path Given path
+     * @param startOnRun if true, start on Run event
+     */
     public SimplePathMoverManager(Point2D[] path, boolean startOnRun) {
+        this();
         setPath(path);
         setStartOnRun(startOnRun);
     }
 
+    /**
+     * Set nextIndex to -1<br>
+     * set nextDestination to NaP coordinates
+     */
     @Override
     public void reset() {
         super.reset();
-        nextIndex = 0;
-
+        nextIndex = -1;
+        nextDestination.setLocation(NaP);
     }
 
+    /**
+     * If startOnRun is true, schedule NextWayPoint
+     */
     public void doRun() {
-        int oldNextIndex = getNextIndex();
-        nextIndex -= 1;
         firePropertyChange("nextIndex", getNextIndex());
-        nextWaypoint = new Point2D.Double(NaN, NaN);
+
         if (isStartOnRun()) {
-            waitDelay("NextWP", 0.0);
+            waitDelay("NextWayPoint", 0.0);
         }
     }
-    
-    public void doNextWP(){
+
+    /**
+     * Increment nextIndex<br>
+     * set nextDestination to path[nextIndex]<br>
+     * schedule MoveTo with nextDestination
+     */
+    public void doNextWayPoint() {
         int oldNextIndex = getNextIndex();
         nextIndex += 1;
-        firePropertyChange("nextIndex", getNextIndex());
-        Point2D oldNextWaypoint = getNextWaypoint();
-        nextWaypoint = path[nextIndex];
-        firePropertyChange("nextWaypoint", getNextWaypoint());
-        waitDelay("MoveTo", 0.0, nextWaypoint);
+        firePropertyChange("nextIndex", oldNextIndex, getNextIndex());
+
+        Point2D oldDestination = getNextDestination();
+        nextDestination.setLocation(path[nextIndex]);
+        firePropertyChange("nextDestination", oldDestination, getNextDestination());
+
+        waitDelay("MoveTo", 0.0, getNextDestination());
     }
-    
-    public void doEndMove(Mover mover){
-        if (nextIndex < path.length -1){
-            waitDelay("NextWP", 0.0);
+
+    /**
+     * If more way points on path, schedule NextWayPoint<br>
+     * Else schedule OrderStop
+     *
+     * @param mover Given Mover (should be the one this is listening to)
+     */
+    public void doEndMove(Mover mover) {
+        if (nextIndex < path.length - 1) {
+            waitDelay("NextWayPoint", 0.0);
         }
-        if (nextIndex == path.length -1){
-            waitDelay("Stop", 0.0);
+
+        if (nextIndex == path.length - 1) {
+            waitDelay("OrderStop", 0.0);
         }
     }
-    
-    public void doStop(){
-    }
 
-    public void doOrderStop(){
-    }
-    
-    public void doMoveTo(Point2D nextWaypoint){
-    }
-    
     /**
      * @return the startOnRun
      */
@@ -91,12 +122,17 @@ public class SimplePathMoverManager extends SimEntityBase {
     }
 
     /**
-     * @return the path
+     * @return topy of he path
      */
     public Point2D[] getPath() {
-        return path;
+        return path.clone();
     }
 
+    /**
+     * 
+     * @param index Given index
+     * @return path[index]
+     */
     public Point2D getPath(int index) {
         return path[index];
     }
@@ -105,11 +141,16 @@ public class SimplePathMoverManager extends SimEntityBase {
      * @param path the path to set
      */
     public void setPath(Point2D[] path) {
-        if (path.length > 0) {
-            this.path = path.clone();
-        } else {
-            throw new IllegalArgumentException("path must be at least lengt 1: " + path.length);
-        }
+        this.path = path.clone();
+    }
+
+    /**
+     * 
+     * @param index Given index
+     * @param path Given waypoint
+     */
+    public void setPath(int index, Point2D path) {
+        this.path[index] = path;
     }
 
     /**
@@ -120,9 +161,10 @@ public class SimplePathMoverManager extends SimEntityBase {
     }
 
     /**
-     * @return the nextWaypoint
+     * @return copy of the nextDestination
      */
-    public Point2D getNextWaypoint() {
-        return (Point2D) nextWaypoint;
+    public Point2D getNextDestination() {
+        return (Point2D) nextDestination.clone();
     }
+
 }
diff --git a/MV3302ClassCode/src/mv3302/SimplePatrolMoverManager.java b/MV3302ClassCode/src/mv3302/SimplePatrolMoverManager.java
index ed4c0fc37bb76c6d3189bccf778cfd0a744a1949..0773257d7b43d078e917b776f66a82af0f78f9a6 100644
--- a/MV3302ClassCode/src/mv3302/SimplePatrolMoverManager.java
+++ b/MV3302ClassCode/src/mv3302/SimplePatrolMoverManager.java
@@ -1,56 +1,59 @@
-/*
- * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
- * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
- */
 package mv3302;
 
 import java.awt.geom.Point2D;
 import simkit.smd.Mover;
 
 /**
+ * Similar to PathMoverManager; directs a Mover to a sequence of way points.
+ * Instead of stopping at the end, return to the first and cycle through again
+ * until stopped by an external component.
  *
- * @author dansl
+ * @author ahbuss
  */
-public class SimplePatrolMoverManager extends SimplePathMoverManager{
+public class SimplePatrolMoverManager extends SimplePathMoverManager {
 
     /**
-     * Zero-argument constructor
+     * Zero argument constructor
      */
     public SimplePatrolMoverManager() {
     }
 
     /**
-     * Instantiate with given given parameters
+     * Instantiate with the given parameters
      *
-     * @param path Given waypoints
-     * @param startOnRun true if start immediately
+     * @param path Given path
+     * @param startOnRun if true, start on Run event
      */
     public SimplePatrolMoverManager(Point2D[] path, boolean startOnRun) {
         super(path, startOnRun);
     }
-        /**
-     * Increment nextIndex; if it is beyond the last index, modulo back to
-     * 0.<br>
-     * Schedule MoveTo with path[nextIndex] (using getter, since path is
-     * private)
+
+    /**
+     * Always schedule NextWayPoint
+     *
+     * @param mover Given Mover
      */
     @Override
     public void doEndMove(Mover mover) {
-        waitDelay("NextWP", 0.0, getPath(nextIndex));
+        waitDelay("NextWaypoint", 0.0);
+
     }
-    
-    @Override
-    public void doNextWP(){
+
+    /**
+     * Increment nextIndext and set modulo the length of the path<br>
+     * setNextDestination<br>
+     * Schedule MoveTo
+     */
+    public void doNextWaypoint() {
         int oldNextIndex = getNextIndex();
-        nextIndex = (nextIndex+1)%path.length;
+        nextIndex = (nextIndex + 1) % getPath().length;
         firePropertyChange("nextIndex", oldNextIndex, getNextIndex());
-        Point2D oldNextWaypoint = getNextWaypoint();
-        nextWaypoint = path[nextIndex];
-        firePropertyChange("nextWaypoint", oldNextWaypoint, getNextWaypoint());
-        waitDelay("MoveTo", 0.0, nextWaypoint);        
-    }
-    
-    public void doMoveTo(Mover mover){
+
+        Point2D oldDestination = getNextDestination();
+        nextDestination.setLocation(getPath(nextIndex));
+        firePropertyChange("nextDestination", oldDestination, getNextDestination());
+
+        waitDelay("MoveTo", 0.0, getNextDestination());
     }
-    
+
 }
diff --git a/MV3302ClassCode/src/mv3302/SimpleRandomMoverManager.java b/MV3302ClassCode/src/mv3302/SimpleRandomMoverManager.java
index ec2ab863feb7e67ed60774c15522d7b716cfbd82..b703beb2e369998d4262ae903d05903f4e66951d 100644
--- a/MV3302ClassCode/src/mv3302/SimpleRandomMoverManager.java
+++ b/MV3302ClassCode/src/mv3302/SimpleRandomMoverManager.java
@@ -1,113 +1,118 @@
-/*
- * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
- * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
- */
 package mv3302;
 
 import java.awt.geom.Point2D;
-import static java.lang.Double.NaN;
+import static mv3302.SimplestMover.NaP;
+import simkit.SimEntity;
+import simkit.SimEntityBase;
 import simkit.random.RandomVariate;
-import simkit.smd.Mover;
 
 /**
+ * A MoverManager that generates a random destination and directs a Mover there.
+ * When the Mover reaches that destination, generate the next, etc.
  *
- * @author dansl
+ * @author ahbuss
  */
-public class SimpleRandomMoverManager extends SimplePathMoverManager {
+public class SimpleRandomMoverManager extends SimEntityBase {
 
     /**
-     * Array to generate coordinates randomly
+     * Generates the coordinates
      */
-    public RandomVariate[] coordinateGenerator;
+    private RandomVariate[] coordinateGenerator;
 
     /**
-     * If true start immediately
+     * If true, start on the Run event
      */
-    public boolean startOnRun;
+    private boolean startOnRun;
 
+    /**
+     * Next destination
+     */
+    protected Point2D nextWayPoint;
+
+    /**
+     * set nextWayPoint to clone of NaP
+     */
     public SimpleRandomMoverManager() {
+        this.nextWayPoint = (Point2D) NaP.clone();
     }
 
     /**
-     * Instantiate with the given parameters
      *
-     * @param coordinateGenerator Given random coordinate generator
-     * @param startOnRun true if starting immediately
+     * @param coordinateGenerator Given coordinate generators
+     * @param startOnRun if true, start in Run event
      */
-    public SimpleRandomMoverManager(RandomVariate[] coordinateGenerator,
-            boolean startOnRun) {
+    public SimpleRandomMoverManager(RandomVariate[] coordinateGenerator, boolean startOnRun) {
+        this();
         this.setCoordinateGenerator(coordinateGenerator);
         this.setStartOnRun(startOnRun);
     }
 
     /**
-     * If startOnRun is true, generate random coordinates and schedule MoveTo
-     * with that destination
+     * set nextWayPoint to NaP coordinates
      */
     @Override
+    public void reset() {
+        super.reset();
+        nextWayPoint.setLocation(NaP);
+    }
+
+    /**
+     * If startOnRun, schedule Start event
+     */
     public void doRun() {
-        Point2D oldNextWaypoint = getNextWaypoint();
-        nextWaypoint = new Point2D.Double(NaN, NaN);
-        firePropertyChange("nextWaypoint", oldNextWaypoint, nextWaypoint);
+        firePropertyChange("nextWayPoint", getNextWayPoint());
         if (isStartOnRun()) {
-            waitDelay("NextWP", 0.0);
+            waitDelay("Start", 0.0);
         }
     }
 
-    @Override
-    public void doNextWP() {
-        Point2D oldNextWaypoint = getNextWaypoint();
-        nextWaypoint = new Point2D.Double(
-                coordinateGenerator[0].generate(),
-                coordinateGenerator[1].generate());
-        firePropertyChange("nextWaypoint", oldNextWaypoint, nextWaypoint);
-        waitDelay("MoveTo", 0.0, nextWaypoint);
-    }
+    /**
+     * Generate nextWaypoint<br>
+     * schedule MoveTo
+     */
+    public void doStart() {
+        nextWayPoint = new Point2D.Double(coordinateGenerator[0].generate(), coordinateGenerator[1].generate());
+        firePropertyChange("nextWaypoint", getNextWayPoint());
 
-    @Override
-    public void doMoveTo(Point2D nextWayPoint) {
+        waitDelay("MoveTo", 0.0, nextWayPoint);
     }
 
-    @Override
-    public void doEndMove(Mover mover) {
-        waitDelay("NextWP", 0.0);
+    /**
+     * To be "heard" from Mover. generate nextWayPoint and schedule MoveTo
+     *
+     * @param mover Given Mover
+     */
+    public void doEndMove(SimEntity mover) {
+        nextWayPoint = new Point2D.Double(coordinateGenerator[0].generate(), coordinateGenerator[1].generate());
+        firePropertyChange("nextWaypoint", getNextWayPoint());
+
+        waitDelay("MoveTo", 0.0, nextWayPoint);
     }
-    
-    @Override
-    public void doStop(){
+
+    /**
+     * Schedule OrderStop (which should "Stop" the Mover listening)
+     */
+    public void doStop() {
         waitDelay("OrderStop", 0.0);
     }
-    
-    @Override
-    public void doOrderStop(){
-    }
 
     /**
-     * @return the coordinateGenerator
+     * @return copy of the coordinateGenerator
      */
     public RandomVariate[] getCoordinateGenerator() {
         return coordinateGenerator.clone();
     }
 
-    public RandomVariate getCoordinateGenerator(int index) {
-        return coordinateGenerator[index];
-    }
-
     /**
-     * @param coordinateGenerator the coordinateGenerator to set
+     * @param coordinateGenerator the coordinateGenerator to set (copy of)
      */
     public void setCoordinateGenerator(RandomVariate[] coordinateGenerator) {
         this.coordinateGenerator = coordinateGenerator.clone();
     }
 
-    public void setCoordinateGenerator(int index, RandomVariate coordinateGenerator) {
-        this.coordinateGenerator[index] = coordinateGenerator;
-    }
-
     /**
      * @return the startOnRun
      */
-    @Override
     public boolean isStartOnRun() {
         return startOnRun;
     }
@@ -115,9 +120,15 @@ public class SimpleRandomMoverManager extends SimplePathMoverManager {
     /**
      * @param startOnRun the startOnRun to set
      */
-    @Override
     public void setStartOnRun(boolean startOnRun) {
         this.startOnRun = startOnRun;
     }
 
+    /**
+     * @return the nextWayPoint
+     */
+    public Point2D getNextWayPoint() {
+        return nextWayPoint;
+    }
+
 }
diff --git a/MV3302ClassCode/src/mv3302/SimplestMover.java b/MV3302ClassCode/src/mv3302/SimplestMover.java
new file mode 100644
index 0000000000000000000000000000000000000000..f24607b670bbc41a915b912b6c77effa795b6fb7
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/SimplestMover.java
@@ -0,0 +1,170 @@
+package mv3302;
+
+import java.awt.geom.Point2D;
+import static java.lang.Double.NaN;
+import simkit.Schedule;
+import simkit.SimEntityBase;
+
+/**
+ *
+ * @author ahbuss
+ */
+public class SimplestMover extends SimEntityBase {
+
+    public static final Point2D NaP = new Point2D.Double(NaN, NaN);
+
+    private Point2D initialLocation;
+
+    private double maxSpeed;
+
+    protected Point2D lastStopLocation;
+
+    protected Point2D velocity;
+
+    protected Point2D destination;
+
+    protected double startMoveTime;
+
+    public SimplestMover() {
+        lastStopLocation = (Point2D) NaP.clone();
+        velocity = (Point2D) NaP.clone();
+        destination = (Point2D) NaP.clone();
+    }
+
+    public SimplestMover(Point2D initialLocation, double maxSpeed) {
+        this();
+        setInitialLocation(initialLocation);
+        setMaxSpeed(maxSpeed);
+    }
+
+    @Override
+    public void reset() {
+        super.reset();
+        lastStopLocation.setLocation(initialLocation);
+        velocity.setLocation(0.0, 0.0);
+        destination.setLocation(NaP);
+        startMoveTime = 0.0;
+    }
+
+    public void doRun() {
+        firePropertyChange("lastStopLocation", getLastStopLocation());
+        firePropertyChange("velocity", getVelocity());
+        firePropertyChange("destination", getDestination());
+        firePropertyChange("startMoveTime", getStartMoveTime());
+    }
+
+    public void doMoveTo(Point2D newDestination) {
+        Point2D oldDestination = getDestination();
+        this.destination.setLocation(newDestination);
+        firePropertyChange("destination", oldDestination, getDestination());
+
+        if (lastStopLocation.distance(destination) > 0.0) {
+            waitDelay("StartMove", 0.0);
+        }
+    }
+
+    public void doStartMove() {
+        double oldStartMoveTime = getStartMoveTime();
+        startMoveTime = Schedule.getSimTime();
+        firePropertyChange("startMoveTime", oldStartMoveTime, getStartMoveTime());
+
+        double distance = lastStopLocation.distance(destination);
+        double a = getMaxSpeed() / distance;
+
+        Point2D oldVelocity = getVelocity();
+        velocity.setLocation(destination.getX() - lastStopLocation.getX(), destination.getY() - lastStopLocation.getY());
+        velocity.setLocation(a * velocity.getX(), a * velocity.getY());
+        firePropertyChange("velocity", oldVelocity, getVelocity());
+
+        waitDelay("EndMove", 1.0 / a);
+    }
+
+    public void doEndMove() {
+        double oldStartMoveTime = getStartMoveTime();
+        startMoveTime = Schedule.getSimTime();
+        firePropertyChange("startMoveTime", oldStartMoveTime, getStartMoveTime());
+
+        Point2D oldLastStopLocation = getLastStopLocation();
+        lastStopLocation.setLocation(destination);
+        firePropertyChange("lastStopLocation", oldLastStopLocation, getLastStopLocation());
+
+        Point2D oldVelocity = getVelocity();
+        velocity.setLocation(0.0, 0.0);
+        firePropertyChange("velocity", oldVelocity, getVelocity());
+
+    }
+
+    /**
+     * @return the initialLocation
+     */
+    public Point2D getInitialLocation() {
+        return (Point2D) initialLocation.clone();
+    }
+
+    /**
+     * @param initialLocation the initialLocation to set
+     */
+    public void setInitialLocation(Point2D initialLocation) {
+        this.initialLocation = (Point2D) initialLocation.clone();
+    }
+
+    /**
+     * @return the maxSpeed
+     */
+    public double getMaxSpeed() {
+        return maxSpeed;
+    }
+
+    /**
+     * @param maxSpeed the maxSpeed to set
+     */
+    public void setMaxSpeed(double maxSpeed) {
+        if (maxSpeed < 0.0) {
+            throw new IllegalArgumentException("maxSpeed must be >= 0.0: " + maxSpeed);
+        }
+        this.maxSpeed = maxSpeed;
+    }
+
+    /**
+     * @return the lastStopLocation
+     */
+    public Point2D getLastStopLocation() {
+        return (Point2D) lastStopLocation.clone();
+    }
+
+    /**
+     * @return the velocity
+     */
+    public Point2D getVelocity() {
+        return (Point2D) velocity.clone();
+    }
+
+    /**
+     * @return the destination
+     */
+    public Point2D getDestination() {
+        return (Point2D) destination.clone();
+    }
+
+    /**
+     * @return the startMoveTime
+     */
+    public double getStartMoveTime() {
+        return startMoveTime;
+    }
+
+    public Point2D getCurrentLocation() {
+        double elapsedTime = Schedule.getSimTime() - getStartMoveTime();
+        return new Point2D.Double(lastStopLocation.getX() + elapsedTime * velocity.getX() , 
+            lastStopLocation.getY() + elapsedTime * velocity.getY());
+    }
+    
+    @Override
+    public String toString() {
+        return String.format("%s %s", getName(), getCurrentLocation());
+    }
+    
+    public String paramString() {
+        return super.toString();
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/run/Assignment7.java b/MV3302ClassCode/src/mv3302/run/Assignment7.java
new file mode 100644
index 0000000000000000000000000000000000000000..241d6c5094be559537b9b628d05e693e76a6107a
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/run/Assignment7.java
@@ -0,0 +1,73 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Main.java to edit this template
+ */
+package mv3302.run;
+
+import java.awt.geom.Point2D;
+import mv3302.SimpleMover;
+import mv3302.SimplePathMoverManager;
+import mv3302.sensor.SimpleConstantRateSensor;
+import mv3302.sensor.SimpleConstantTimeSensor;
+import mv3302.sensor.SimpleCookieCutterSensor;
+import simkit.Schedule;
+import simkit.util.SimplePropertyDumper;
+
+/**
+ *
+ * @author dansl
+ */
+public class Assignment7 {
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        SimpleCookieCutterSensor cookieCutterSensor = new SimpleCookieCutterSensor();
+        cookieCutterSensor.setSimpleMover(new SimpleMover());
+        cookieCutterSensor.setMaxRange(10.0);
+        System.out.println(cookieCutterSensor);
+
+        SimpleConstantTimeSensor constantTimeSensor = new SimpleConstantTimeSensor();
+        constantTimeSensor.setSimpleMover(new SimpleMover());
+        constantTimeSensor.setMaxRange(10);
+        constantTimeSensor.setTimeToDetect(5.0);
+        System.out.println(constantTimeSensor);
+
+        SimpleConstantRateSensor constantRateSensor = new SimpleConstantRateSensor();
+        constantRateSensor.setSimpleMover(new SimpleMover());
+        constantRateSensor.setMaxRange(10.0);
+        constantRateSensor.setMeanTimeToDetect(3.0);
+        System.out.println(constantRateSensor);
+
+        Point2D sensorLocation = new Point2D.Double(0.0, 0.0);
+        SimpleMover simpleSensorMover = new SimpleMover();
+        double maxRange = 20.0;
+        double timeToDetect = 5.0;
+        SimpleConstantTimeSensor simpleConstantTimeSensor = new SimpleConstantTimeSensor(simpleSensorMover, maxRange, timeToDetect);
+        System.out.println(simpleSensorMover.paramString());
+
+        Point2D targetLocation = new Point2D.Double(0.0, 10.0);
+        double targetMaxSpeed = 40;
+        SimpleMover simpleMover = new SimpleMover(targetLocation, targetMaxSpeed);
+        System.out.println(simpleMover.paramString());
+
+        Point2D[] path = new Point2D[]{new Point2D.Double(50.0, -20.0)};
+        SimplePathMoverManager simplePathMoverManager = new SimplePathMoverManager(path, true);
+        System.out.println(simplePathMoverManager);
+
+        simplePathMoverManager.addSimEventListener(simpleMover);
+        simpleMover.addSimEventListener(simplePathMoverManager);
+
+        SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper(true);
+        simpleConstantTimeSensor.addPropertyChangeListener(simplePropertyDumper);
+        simpleMover.addPropertyChangeListener(simplePropertyDumper);
+        simplePathMoverManager.addPropertyChangeListener(simplePropertyDumper);       
+                
+        Schedule.setVerbose(true);
+        
+        Schedule.reset();
+        Schedule.startSimulation();
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/sensor/AbstractSimpleSensor.java b/MV3302ClassCode/src/mv3302/sensor/AbstractSimpleSensor.java
new file mode 100644
index 0000000000000000000000000000000000000000..09568c82ebd9a3751613ae2b3da326c5ecf58c7f
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/sensor/AbstractSimpleSensor.java
@@ -0,0 +1,109 @@
+
+package mv3302.sensor;
+
+import java.awt.geom.Point2D;
+import java.util.HashSet;
+import java.util.Set;
+import mv3302.SimpleMover;
+import simkit.SimEntityBase;
+
+/**
+ *
+ * @author dansl
+ */
+public abstract class AbstractSimpleSensor extends SimEntityBase implements Sensor {
+
+    public double maxRange;
+    public SimpleMover simpleMover;
+    public Set<SimpleMover> contacts;
+
+    public AbstractSimpleSensor() {
+        contacts = new HashSet<>();
+    }
+
+    public AbstractSimpleSensor(SimpleMover simpleMover, double maxRange) {
+        this();
+        setSimpleMover(simpleMover);
+        setMaxRange(maxRange);
+    }
+
+    public void doRun() {
+        contacts.clear();
+    }
+
+    public void doDetection(SimpleMover simpleMover) {
+        Set<SimpleMover> oldContacts = getContacts();
+        contacts.add(simpleMover);
+        firePropertyChange("contacts", oldContacts, getContacts());
+
+        firePropertyChange("detection", simpleMover);
+    }
+
+    public void doUndetection(SimpleMover simpleMover) {
+        Set<SimpleMover> oldContacts = getContacts();
+        contacts.remove(simpleMover);
+        firePropertyChange("contacts", oldContacts, getContacts());
+
+        firePropertyChange("undetection", simpleMover);
+    }
+
+    public void doStartMove(SimpleMover simpleMover) {
+        waitDelay("StartMove", 0.0, this);
+    }
+
+    public void doStartMove(Sensor sensor) {
+    }
+
+    public void doStop(SimpleMover simpleMover) {
+        waitDelay("Stop", 0.0, this);
+    }
+
+    public void doStop(Sensor sensor) {
+
+    }
+
+    @Override
+    public Point2D getCurrentLocation() {
+        return simpleMover.getCurrentLocation();
+    }
+
+    public Point2D getVelocity() {
+        return simpleMover.getVelocity();
+    }
+
+    public void setSimpleMover(SimpleMover simpleMover) {
+        this.simpleMover = simpleMover;
+    }
+
+    public void setMaxRange(double maxRange) {
+        if (maxRange <= 0.0) {
+            throw new IllegalArgumentException("maxRange must be > 0.0: " + maxRange);
+        }
+        this.maxRange = maxRange;
+    }
+
+    public Set<SimpleMover> getContacts() {
+        return new HashSet<>(contacts);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s %s", getSimpleMover(), getMaxRange());
+    }
+
+    /**
+     * @return the maxRange
+     */
+    @Override
+    public double getMaxRange() {
+        return maxRange;
+    }
+
+    /**
+     * @return the simpleMover
+     */
+    @Override
+    public SimpleMover getSimpleMover() {
+        return simpleMover;
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/sensor/Sensor.java b/MV3302ClassCode/src/mv3302/sensor/Sensor.java
new file mode 100644
index 0000000000000000000000000000000000000000..7c2c05bd81558e534bc9f21be360080f822d6f4b
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/sensor/Sensor.java
@@ -0,0 +1,22 @@
+package mv3302.sensor;
+
+import java.awt.geom.Point2D;
+import java.util.Set;
+import mv3302.SimpleMover;
+import simkit.SimEntity;
+
+/**
+ *
+ * @author dansl
+ */
+interface Sensor extends SimEntity {
+
+    public Point2D getCurrentLocation();
+    public Point2D getVelocity();
+    public double getMaxRange();
+    public void doStartMove(SimpleMover simpleMover);
+    public void doStop(SimpleMover simpleMover);
+    public SimpleMover getSimpleMover();
+    public Set<SimpleMover> getContacts();
+
+}
diff --git a/MV3302ClassCode/src/mv3302/sensor/SimpleConstantRateSensor.java b/MV3302ClassCode/src/mv3302/sensor/SimpleConstantRateSensor.java
new file mode 100644
index 0000000000000000000000000000000000000000..ba79c9b4884364f0ba510e33877fcd260ccc81fa
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/sensor/SimpleConstantRateSensor.java
@@ -0,0 +1,36 @@
+
+package mv3302.sensor;
+
+import java.util.HashSet;
+import mv3302.SimpleMover;
+
+/**
+ *
+ * @author dansl
+ */
+public class SimpleConstantRateSensor extends AbstractSimpleSensor {
+
+    private double meanTimeToDetect;
+
+    public SimpleConstantRateSensor() {
+        contacts = new HashSet<>();
+    }
+
+    public SimpleConstantRateSensor(SimpleMover simpleMover, double maxRange, double meanTimeToDetect) {
+        this();
+        setSimpleMover(simpleMover);
+        setMaxRange(maxRange);
+        setMeanTimeToDetect(meanTimeToDetect);
+    }
+
+    public double getMeanTimeToDetect() {
+        return meanTimeToDetect;
+    }
+
+    public void setMeanTimeToDetect(double meanTimeToDetect) {
+        if (meanTimeToDetect < 0.0) {
+            throw new IllegalArgumentException("meanTimeToDetect must be >= 0.0: " + meanTimeToDetect);
+        }
+        this.meanTimeToDetect = meanTimeToDetect;
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/sensor/SimpleConstantTimeSensor.java b/MV3302ClassCode/src/mv3302/sensor/SimpleConstantTimeSensor.java
new file mode 100644
index 0000000000000000000000000000000000000000..da862ca78440a0fe7629004d82c6e0a69c79d553
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/sensor/SimpleConstantTimeSensor.java
@@ -0,0 +1,36 @@
+
+package mv3302.sensor;
+
+import java.util.HashSet;
+import mv3302.SimpleMover;
+
+/**
+ *
+ * @author dansl
+ */
+public class SimpleConstantTimeSensor extends AbstractSimpleSensor {
+
+    private double timeToDetect;
+
+    public SimpleConstantTimeSensor() {
+        contacts = new HashSet<>();
+    }
+
+    public SimpleConstantTimeSensor(SimpleMover simpleMover, double maxRange, double timeToDetect) {
+        this();
+        setSimpleMover(simpleMover);
+        setMaxRange(maxRange);
+        setTimeToDetect(timeToDetect);
+    }
+
+    double getTimeToDetect() {
+        return timeToDetect;
+    }
+
+    public void setTimeToDetect(double timeToDetect) {
+        if (timeToDetect < 0.0) {
+            throw new IllegalArgumentException("timeToDetect must be >= 0.0: " + timeToDetect);
+        }
+        this.timeToDetect = timeToDetect;
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/sensor/SimpleCookieCutterSensor.java b/MV3302ClassCode/src/mv3302/sensor/SimpleCookieCutterSensor.java
new file mode 100644
index 0000000000000000000000000000000000000000..b1d3fdc10fa4bb13a711bf3329f1508cebe61050
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/sensor/SimpleCookieCutterSensor.java
@@ -0,0 +1,23 @@
+
+package mv3302.sensor;
+
+import java.util.HashSet;
+import mv3302.SimpleMover;
+
+/**
+ *
+ * @author dansl
+ */
+public class SimpleCookieCutterSensor extends AbstractSimpleSensor {
+
+    public SimpleCookieCutterSensor() {
+        contacts = new HashSet<>();
+    }
+
+    public SimpleCookieCutterSensor(SimpleMover simpleMover, double maxRange) {
+        this();
+        setSimpleMover(simpleMover);
+        setMaxRange(maxRange);
+    }
+
+}