Index: trunk/test/tmcsim/highwaymodel/ConsoleTrafficDriver.java
===================================================================
--- trunk/test/tmcsim/highwaymodel/ConsoleTrafficDriver.java	(revision 457)
+++ trunk/test/tmcsim/highwaymodel/ConsoleTrafficDriver.java	(revision 457)
@@ -0,0 +1,355 @@
+package tmcsim.highwaymodel;
+
+import tmcsim.highwaymodel.Highways;
+import tmcsim.highwaymodel.Station.DIRECTION;
+import tmcsim.highwaymodel.Highway;
+import tmcsim.highwaymodel.Station;
+import tmcsim.highwaymodel.LoopDetector.DOTCOLOR;
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.Scanner;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import tmcsim.common.SimulationException;
+import tmcsim.highwaymodel.Highway;
+import tmcsim.highwaymodel.Highways;
+import tmcsim.highwaymodel.Station;
+
+/**
+ * A console application to drive the ATMS Server.
+ * Use for test driving the Highway Model.
+ *
+ * @author jdalbey, John A. Torres
+ * @version 10/11/2017
+ */
+public final class ConsoleTrafficDriver {
+    // highways model
+    private final Highways highways;
+    
+    // lists used for user input validation
+    private final List<Integer> routeNumInputList;
+    /**
+     * Properties for the ConsoleTrafficDriver
+     */
+    private static Properties ConsoleDriverProperties;
+    
+
+    /** Entry point for the application.
+     * 
+     * @param args unused
+     */
+    public static void main(String[] args) {
+        try {
+            if (System.getProperty("ATMSDRIVER_PROPERTIES") != null) 
+            {
+                // Load properties of runtime parameters
+                if (!loadProperties()) 
+                {
+                    System.exit(0);
+                }        
+                // Create the Highway Model
+                Highways highways = new Highways(
+                    "config/vds_data/highways_fullmap.txt");
+
+                // Construct the console driver using the highways model
+                ConsoleTrafficDriver driver = new ConsoleTrafficDriver(highways);
+                driver.runConsole();    
+            } else {
+                throw new Exception("ATMSDRIVER_PROPERTIES system property not defined.");
+            }
+        } catch (Exception e) {
+            Logger.getLogger("ConsoleDriver").logp(Level.SEVERE, "ConsoleDriver", "Main",
+                    "Error occured initializing application", e);
+            System.exit(-1);
+        }
+    }    
+    /**
+     * Load the properties file containing values for runtime parameters.
+     * 
+     * @param propertiesFile
+     * @return 
+     */
+    private static boolean loadProperties() 
+    {
+        // Load the properties file.
+        try {
+            ConsoleDriverProperties = new Properties();
+            ConsoleDriverProperties.load(new FileInputStream(System.getProperty("ATMSDRIVER_PROPERTIES")));
+        } catch (Exception e) {
+            Logger.getLogger("ConsoleDriver").logp(Level.SEVERE, "ConsoleDriver",
+                    "Constructor", "Exception in reading properties file.", e);
+        }
+
+        return true;
+    }
+    /**
+     * Constructor. Sets the highways model and generates the input validation
+     * lists, and then runs the console driver application.
+     * @param highways 
+     */
+    public ConsoleTrafficDriver(Highways highways) {
+        // set highways model
+        this.highways = highways;
+        
+        // set input validation lists
+        routeNumInputList = generateRouteNumInputList();
+    }
+    
+    /**
+     * Generates the route number list, used for user input validation.
+     * @return list of route numbers.
+     */
+    private ArrayList<Integer> generateRouteNumInputList()
+    {
+        ArrayList<Integer> routeNums = new ArrayList<>();
+        // add the route number for each highway to the list
+        for(Highway hwy : highways.highways)
+        {
+            routeNums.add(hwy.routeNumber);
+        }
+        return routeNums;
+    }
+
+    /**
+     * Runs the console driver application.
+     */
+    public void runConsole() {
+        Scanner sc = new Scanner(System.in);
+        char choice = 'A';
+        // Run continuously
+        while (choice != 'Q')
+        {
+            // Get necessary values for colorization of highways
+            Integer routeNumber = getRouteNumber(sc);
+            DIRECTION direction = getDirection(sc, routeNumber);
+            Double postmile = getPostmile(sc, routeNumber, direction);
+            Double range = getRange(sc, postmile);
+            DOTCOLOR dotcolor = getDotColor(sc);
+
+            // apply colorization to highways
+            highways.applyColorToHighwayStretch(routeNumber, direction, postmile, range, dotcolor);
+
+            System.out.println("Add another entry or Send now? (A/S)");
+            choice = sc.next().toUpperCase().trim().charAt(0);
+            System.out.println("");
+            if (choice == 'S')
+            {
+                // Send highway model to FEP for transmit to ATMS
+                highways.toJson();
+                System.out.println("Add another entry or Quit? (A/Q)");
+                choice = sc.next().toUpperCase().trim().charAt(0);
+            }
+        }
+    }
+    
+    
+    /**
+     * Gets the highway route number from user and validates the input.
+     * 
+     * @param sc stdIn scanner
+     * @return highway route number
+     */
+    private Integer getRouteNumber(Scanner sc) {
+        Integer routeNum = null;
+        Boolean verified = false;
+        
+        // validation loop
+        while(!verified)
+        {
+            // Prints out available route numbers to user to select from
+            System.out.print("Available route numbers: [");
+            for(Integer rtNum : routeNumInputList)
+            {
+                System.out.print(rtNum.toString() + ", ");
+            }
+            System.out.print("]");
+            System.out.println("");
+            
+            // Prompt user to input a route number
+            System.out.println("Enter a route number: ");
+            routeNum = sc.nextInt();
+            System.out.println("");
+            
+            // validate the user's input
+            if(routeNumInputList.contains(routeNum))
+            {
+                verified = true;
+            }
+            else
+            {
+                System.out.println("Invalid route number, please re-enter: ");
+            }
+        }
+        
+        return routeNum;
+    }
+    
+    /**
+     * Gets the highway direction from the user and validates the input.
+     * 
+     * @param sc stdIn scanner
+     * @return highway direction
+     */
+    private DIRECTION getDirection(Scanner sc, Integer routeNum) {
+        DIRECTION direction;
+        String directionInput = null;
+        Boolean verified = false;
+        
+        // validation loop
+        while(!verified)
+        {
+            // Get available directions for route
+            ArrayList<DIRECTION> availDirs = new ArrayList<>();
+            for(Station stn : highways.getHighwayByRouteNumber(routeNum).stations)
+            {
+                if(!availDirs.contains(stn.direction))
+                {
+                    availDirs.add(stn.direction);
+                }
+            }
+            
+            // prompt user for input
+            System.out.print("Available directions for highway " + routeNum + ": [");
+            for(DIRECTION dir : availDirs)
+            {
+                System.out.print(dir.getLetter() + ", ");
+            }
+            System.out.print("]");
+            System.out.println("");
+            System.out.println("Enter a direction:");
+            directionInput = sc.next().toUpperCase();
+            System.out.println("");
+            
+            // validate the user's input
+            if(availDirs.contains(DIRECTION.toDirection(directionInput)))
+            {
+                verified = true;
+            }
+            else
+            {
+                System.out.println("Invalid direction, please re-enter: ");
+            }
+        }
+        
+        return DIRECTION.toDirection(directionInput);
+    }
+    
+    /**
+     * Gets the starting/origin postmile value for the highway section from the 
+     * user and validates the input.
+     * 
+     * @param sc stdIn scanner
+     * @param routeNumber highway route number
+     * @param dir highway direction
+     * @return highway section start/origin postmile value
+     */
+    private Double getPostmile(Scanner sc, Integer routeNumber, DIRECTION dir) {
+        Double postmile = null;
+        Boolean verified = false;
+        
+        // validation loop
+        while(!verified)
+        {
+            // Get highway, and grab the floor and ceiling for postmile values
+            // from the highway stations to present to the user
+            Highway hwy = highways.getHighwayByRouteNumber(routeNumber);
+            Double floorPostmile = hwy.stations.get(0).postmile;
+            Double ceilPostmile = hwy.stations
+                    .get(hwy.stations.size() - 1).postmile;
+            
+            // present user with range of postmiles for given highway
+            System.out.println("Route " + hwy.routeNumber + " " + dir 
+                    + " postmile range: [" + floorPostmile + ", " 
+                    + ceilPostmile + "]");
+            
+            // prompt user for postmile value
+            System.out.println("Enter a postmile value (Integer/Double): ");
+            postmile = sc.nextDouble();
+            System.out.println("");
+            
+            // validate user's input, ensures that the postmile is within given
+            // postmile range (floorPostmile, ceilPostmile)
+            if(postmile >= floorPostmile && postmile <= ceilPostmile)
+            {
+                verified = true;
+            }
+            else
+            {
+                System.out.println("Postmile must be within postmile range: [" + floorPostmile + ", " 
+                    + ceilPostmile + "] please re-enter: ");
+            }
+        }
+        
+        return postmile;
+    }
+    
+    /**
+     * Gets the range to extend the highway stretch from the start/origin postmile
+     * value from the user and validates the input.
+     * 
+     * @param sc stdIn scanner
+     * @param postmile origin/start postmile value for highway stretch
+     * @return range value
+     */
+    private Double getRange(Scanner sc, Double postmile) {
+        Double range = null;
+        Boolean verified = false;
+        
+        // validation loop
+        while(!verified)
+        {
+            // prompt user for range value
+            System.out.println("Enter a range value (decimal):");
+            range = sc.nextDouble();
+            System.out.println("");
+            
+            // range must be greater than or equal to 0
+            if(range >= 0)
+            {
+                verified = true;
+            }
+            else
+            {
+                System.out.println("Range must be >= 0");
+            }
+        }
+        
+        return range;
+    }
+
+    /**
+     * Gets the dot color from the user, to be applied to specified highway
+     * stretch and validates the user's input.
+     * 
+     * @param sc stdIn scanner
+     * @return dot color to be applied to highway stretch
+     */
+    private DOTCOLOR getDotColor(Scanner sc) {
+        DOTCOLOR dotColor;
+        String dotColorInput = null;
+        Boolean verified = false;
+        
+        // validationloop
+        while(!verified)
+        {
+            // prompt user for color
+            System.out.println("Enter a dot color (G/Y/R):");
+            dotColorInput = sc.next().toUpperCase();
+            System.out.println("");
+            // validate user's input
+            if(DOTCOLOR.allLetters.contains(dotColorInput))
+            {
+                verified = true;
+            }
+            else
+            {
+                System.out.println("Invalid dot color, please re-enter: ");
+            }
+        }
+        
+        return DOTCOLOR.toDotColor(dotColorInput);
+    }
+    
+}
Index: trunk/test/tmcsim/highwaymodel/TrafficModelEventDriver.java
===================================================================
--- trunk/test/tmcsim/highwaymodel/TrafficModelEventDriver.java	(revision 457)
+++ trunk/test/tmcsim/highwaymodel/TrafficModelEventDriver.java	(revision 457)
@@ -0,0 +1,127 @@
+package tmcsim.highwaymodel;
+
+import tmcsim.highwaymodel.Highways;
+import tmcsim.highwaymodel.TrafficEvent;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.rmi.RemoteException;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Scanner;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JOptionPane;
+import javax.swing.JWindow;
+import tmcsim.cadsimulator.managers.TrafficModelManager;
+import tmcsim.common.SimulationException;
+
+/**
+ * OBSOLETE: An interactive version is now available:
+ *    atmsdriver.TrafficEventsAnimator.java
+ * Read and process all Traffic Events in a file and show
+ * resulting highway network. 
+ * A console display of the highway network is output
+ * for each event.
+ * This application is used by Traffic Event authors to assist
+ * in verifying the correctness of their data file.
+ * Because the output is sent immediately to the console the
+ * author doesn't have to sit through simulation time to
+ * observe dots changing on ATMS client.
+ * @author jdalbey
+ */
+public class TrafficModelEventDriver 
+{
+    /**
+     * Error logger.
+     */
+    private static Logger logger = Logger.getLogger("trafficmodeleventdriver");
+
+    /**
+     * Highways in traffic network
+     */
+    final private Highways highways;
+
+    /**
+     * LinkedList of batch events
+     */
+    private LinkedList<TrafficEvent> eventQueue;
+    /**
+     * Map of incidents to events
+     */
+    private Map<String, List<TrafficEvent>> incidents;
+
+    /**
+     * Constructor. Load highways and events.
+     *
+     */
+    public TrafficModelEventDriver() throws RemoteException, SimulationException
+    {
+        // Initialize the highway model
+        incidents = new HashMap<String, List<TrafficEvent>>();
+        highways = new Highways(
+                "config/vds_data/highways_fullmap.txt");
+        final String CONFIG_FILE_NAME = "traffic_model_config.properties";
+        String propertiesFile = "config" + System.getProperty("file.separator") 
+                 + CONFIG_FILE_NAME;
+        Properties props = TrafficModelManager.loadProperties(propertiesFile);
+
+        FileInputStream fis = null;
+        try
+        {
+            fis = new FileInputStream(props.getProperty("Events_File"));
+        } catch (FileNotFoundException ex)
+        {
+            Logger.getLogger(TrafficModelManager.class.getName()).log(Level.SEVERE, null, 
+                    "Missing Traffic Events file " + props.getProperty("Events_File"));
+            System.exit(-1);
+        }
+        Scanner fileScanner = new Scanner(fis);        
+        // Read all lines from the file of events and put in a queue
+        eventQueue = TrafficModelManager.readBatchFile(fileScanner);
+    }
+    public void run()
+    {
+        // If we have any events left to process
+        while (!eventQueue.isEmpty())
+        {
+            // Get next event
+            TrafficEvent nextEvent = eventQueue.peek();
+            System.out.println("LAUNCHING EVENT: " + nextEvent.toString());
+            // apply colorization to highways
+            highways.applyColorToHighwayStretch(nextEvent.routeNumber, nextEvent.dir,
+                    nextEvent.postmile, nextEvent.range, nextEvent.color);
+            System.out.println(highways.toString());
+            // Remove this event from the queue, we're done with it.
+            eventQueue.remove();
+        }
+    }
+
+    /**
+     * local main to launch the app.
+     *
+     * @param args Command line arguments.
+     */
+    public static void main(String[] args)
+    {
+        try
+        {
+            TrafficModelEventDriver driver = new TrafficModelEventDriver();
+            driver.run();
+        }
+        catch (Exception e)
+        {
+            logger.logp(Level.SEVERE, "Traffic Model Event Driver", "Main",
+                    "Error initializing application.");
+
+            JOptionPane.showMessageDialog(new JWindow(), e.getMessage(),
+                    "Error - Program Exiting", JOptionPane.ERROR_MESSAGE);
+
+            System.exit(-1);
+        }
+
+    }
+
+}
Index: trunk/test/tmcsim/highwaymodel/runtraffic.bash
===================================================================
--- trunk/test/tmcsim/highwaymodel/runtraffic.bash	(revision 457)
+++ trunk/test/tmcsim/highwaymodel/runtraffic.bash	(revision 457)
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+java -DATMSDRIVER_PROPERTIES=config/console_driver_config.properties -jar deploy/ConsoleTrafficDriver.jar << EOF
+5 S 10 24.0 Y
+A
+405 S 0.6 13.0 R
+S
+Q
+EOF
+
