Index: trunk/src/tmcsim/application.properties
===================================================================
--- trunk/src/tmcsim/application.properties	(revision 66)
+++ trunk/src/tmcsim/application.properties	(revision 79)
@@ -1,5 +1,5 @@
-#Thu, 16 Mar 2017 12:41:52 -0700
+#Thu, 05 Oct 2017 10:44:21 -0700
 
-Application.revision=65
+Application.revision=67
 
 Application.buildnumber=46
Index: trunk/src/atmsdriver/ATMSDriver.java
===================================================================
--- trunk/src/atmsdriver/ATMSDriver.java	(revision 79)
+++ trunk/src/atmsdriver/ATMSDriver.java	(revision 79)
@@ -0,0 +1,124 @@
+package atmsdriver;
+
+import atmsdriver.model.Network;
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author John A. Torres
+ * @version 09/10/2017
+ */
+public class ATMSDriver implements Runnable {
+
+    /** ATMSDriver Error logger. */
+    private static Logger ATMSDriverLogger = Logger.getLogger("atmsdriver");
+
+    private static final String CONFIG_FILE_NAME = "atms_driver_config.properties";
+
+    /** Properties object for the CADClient class. */
+    private Properties ATMSDriverProperties;
+
+    /**
+     * Enumeration containing properties name values. See ATMSDriver class
+     * description for more information.
+     *
+     * @author John Torres
+     * @see ATMSDriver
+     */
+    private static enum PROPERTIES {
+
+        LDS_FILE_NAME("LDSFileName"),
+        LOOP_FILE_NAME("LoopFileName"),
+        NETWORK_FILE_NAME("NetworkFileName"),
+        EXCHANGE_FILE_NAME("ExchangeFileName");
+
+        public String name;
+
+        private PROPERTIES(String n) {
+            name = n;
+        }
+    }
+
+    /** Network model. */
+    final private Network network;
+    
+    /** Sleep Time (10 seconds). **/
+    private static final int SLEEP_TIME = 10000;
+    
+    /** Exchange Reader */
+    private ExchangeReader exchangeReader;
+    
+    @Override
+    public void run() {
+        // Check for packets and update the simulator
+        for (;;) {
+            // Flush the input file
+            ExchangeInfo exInfo = exchangeReader.parse(ATMSDriverProperties
+                    .getProperty(PROPERTIES.EXCHANGE_FILE_NAME.name));
+            network.toXML();
+            // Update if packet is recieved
+            if (exInfo != null) {
+                System.out.println("Grabbed");
+            }
+
+            // Sleep
+            try {
+                Thread.sleep(SLEEP_TIME);
+            } catch (InterruptedException ie) {
+                
+            }
+        }
+    }
+
+    public ATMSDriver(String propertiesFile) {
+
+        if (!verifyProperties(propertiesFile)) {
+            System.exit(0);
+        }
+
+        network = new Network(
+                new File(ATMSDriverProperties.getProperty(
+                                PROPERTIES.LDS_FILE_NAME.name)),
+                new File(ATMSDriverProperties.getProperty(
+                                PROPERTIES.LOOP_FILE_NAME.name)),
+                new File(ATMSDriverProperties.getProperty(
+                                PROPERTIES.NETWORK_FILE_NAME.name)));
+        network.toXML();
+        exchangeReader = new ExchangeReader();
+    }
+
+    private boolean verifyProperties(String propertiesFile) {
+        // Load the properties file.
+        try {
+            ATMSDriverProperties = new Properties();
+            ATMSDriverProperties.load(new FileInputStream(propertiesFile));
+        } catch (Exception e) {
+            ATMSDriverLogger.logp(Level.SEVERE, "ATMSDriver",
+                    "Constructor", "Exception in reading properties file.", e);
+        }
+
+        return true;
+    }
+
+    /**
+     * Runs the Paramics simulator.
+     */
+    public static void main(String[] args) {
+        try {
+            if (System.getProperty("ATMSDRIVER_PROPERTIES") != null) {
+                new Thread(new ATMSDriver(System.getProperty(
+                        "ATMSDRIVER_PROPERTIES"))).start();
+            } else {
+                throw new Exception("ATMSDRIVER_PROPERTIES system property not defined.");
+            }
+        } catch (Exception e) {
+            ATMSDriverLogger.logp(Level.SEVERE, "ATMSDriver", "Main",
+                    "Error occured initializing application", e);
+            System.exit(-1);
+        }
+    }
+}
Index: trunk/src/atmsdriver/NetworkLoader.java
===================================================================
--- trunk/src/atmsdriver/NetworkLoader.java	(revision 79)
+++ trunk/src/atmsdriver/NetworkLoader.java	(revision 79)
@@ -0,0 +1,277 @@
+package atmsdriver;
+
+import atmsdriver.model.FEPLine;
+import atmsdriver.model.LoopDetectorStation;
+import atmsdriver.model.LoopDetector;
+import atmsdriver.model.LoopDetectorStation.DIRECTION;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/** The NetworkReader loads all static data for the traffic network through
+ *  network lookup files. 
+ * 
+ *  The public method getFEPLines() method can be used to get all the FEPLines 
+ *  within a network. All other methods are private and are used to construct
+ *  the FEPLines.
+ * 
+ *  The "LDSFile" contains LoopDetectorStation and FEPLine information.
+ *  ex.
+ *   < Insert file here >
+ *  The "loopFile" contains individual LoopDetector information.
+ *  ex.
+ *   < Insert file here > 
+ *
+ * @author John A. Torres
+ * @version 09/10/2017
+ */
+public class NetworkLoader {
+    // Two network config files
+    private final File LDSFile;
+    private final File loopFile;
+    
+    // The list of FEPLines
+    private List<FEPLine> lines;
+    
+    /**
+     * Constructor
+     * @param LDSFile contains FEPLine and Station static data
+     * @param loopFile contains individual LoopDetector static data
+     */
+    public NetworkLoader(File LDSFile, File loopFile)
+    {
+        this.LDSFile = LDSFile;
+        this.loopFile = loopFile;
+        this.lines = new ArrayList<>();
+        constructFEPLines();
+    }
+    
+    /**
+     * Returns the list of FEPLines in the configured network
+    */
+    public List<FEPLine> getFEPLines()
+    {
+        return lines;
+    }
+    
+    // returns a list of the line numbers found in LDSFile
+    private ArrayList<Integer> getLineNums(Scanner sc)
+    {
+        ArrayList<Integer> lineNums = new ArrayList<>();
+        
+        sc.nextLine(); // skip first line
+        
+        while(sc.hasNext())
+        {
+            sc.nextInt(); // skip to line no
+            Integer lineNum = sc.nextInt(); // get the line number
+            
+            /* If the line is new, and has not been added, add it to lineNums */
+            if(!lineNums.contains(lineNum))
+            {
+                lineNums.add(lineNum);
+            }
+       
+            sc.nextLine(); // skip to next line
+        }
+        
+        sc.close();
+        
+        return lineNums;
+    }
+    
+    // returns a list of station numbers for a given line
+    private ArrayList<Integer> getStationNums(Integer lineNum, Scanner sc)
+    {
+        ArrayList<Integer> stnNums = new ArrayList<>();
+        
+        sc.nextLine(); // skip first line
+        
+        while(sc.hasNext())
+        {
+            Integer stnNum = sc.nextInt();
+            Integer theLine = sc.nextInt();
+            if(theLine.equals(lineNum))
+            {
+                stnNums.add(stnNum);
+            }
+            
+            sc.nextLine();
+        }
+        
+        sc.close();
+        
+        return stnNums;
+    }
+    
+    // returns a list of loop detectors for a given station
+    private ArrayList<LoopDetector> getLoops(Integer stnNum, Scanner sc)
+    {
+        ArrayList<LoopDetector> loops = new ArrayList<>();
+        
+        sc.nextLine(); // skip first line
+        
+        while(sc.hasNext())
+        {
+            sc.next(); // skip FWY
+            sc.next(); // skip dir
+            sc.next(); // skip postmile
+            Integer ldsID = sc.nextInt(); // lds id
+            sc.next(); // skip vdsID
+            Integer loopID = sc.nextInt(); // loop id
+            sc.next(); // skip LOC
+            Integer laneNum = sc.nextInt(); // lane number
+            String loopLoc = sc.next();
+            if(stnNum.equals(ldsID))
+            {
+                LoopDetector loop = new LoopDetector(loopID, loopLoc, laneNum);
+                loops.add(loop);
+            }
+            sc.nextLine();
+        }
+        
+        sc.close();
+        
+        return loops;
+    }
+    
+    // method called to actually build the network from config files
+    private void constructFEPLines()
+    {
+        try {
+            System.out.println("Building network...");
+            
+            // Get FEPLine IDs
+            ArrayList<Integer> lineNums = getLineNums(new Scanner(LDSFile));
+            
+            // Create each FEPLine in the network
+            for(Integer lineNum : lineNums)
+            {
+                // Get Station IDs for the current FEPLine
+                ArrayList<Integer> stnNums = getStationNums(lineNum,
+                        new Scanner(LDSFile));
+                
+                // Create each Station for the current FEPLine
+                ArrayList<LoopDetectorStation> stns = new ArrayList<>();
+                for(Integer stnNum : stnNums)
+                {
+                    // Get Loops for the current Station
+                    ArrayList<LoopDetector> loops =
+                            getLoops(stnNum, new Scanner(loopFile));
+                    
+                    // Create the Station and add to list for curr FEPLine
+                    LoopDetectorStation stn =
+                            createStation(stnNum, new Scanner(LDSFile), loops);
+                    stns.add(stn);
+                }
+                
+                // Now that stations are created, create the actual FEPLine and
+                // and to FEPLines list
+                FEPLine line = createLine(lineNum, new Scanner(LDSFile), stns);
+                lines.add(line);
+            }
+        } catch (FileNotFoundException ex) {
+            Logger.getLogger(NetworkLoader.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+    
+    // Creates  line
+    private FEPLine createLine(int lineNum, Scanner scLine, ArrayList<LoopDetectorStation> stns)
+    {
+        FEPLine line = null;
+        
+        scLine.nextLine();
+        
+        while(scLine.hasNext())
+        {
+            scLine.nextInt(); // skip ldsID
+            int currLineNum = scLine.nextInt(); // linenum
+            if(currLineNum == lineNum)
+            {
+                scLine.nextInt(); // skip drop
+                int sch = scLine.nextInt(); // schedule
+                int lineinfo = scLine.nextInt(); // lineinfo
+                int sysKey = scLine.nextInt(); // sysKey
+                int schSeq = scLine.nextInt(); // schSeq
+                int globSeq = scLine.nextInt(); // globSeq  
+                int count = scLine.nextInt(); // count
+                
+                line = new FEPLine(lineNum, stns, count, sch, lineinfo, sysKey, globSeq, schSeq);
+                
+                break;
+            }
+            
+            scLine.nextLine();
+        }
+        
+        scLine.close();
+        
+        return line;
+    }
+    
+    // Returns the loction given the whole line from the lookup file
+    private String getLocation(String line)
+    {
+        Scanner sc = new Scanner(line);
+        sc.nextInt(); // skip lds num
+        sc.nextInt(); // skip line num
+        int drop = sc.nextInt(); // drop num
+        sc.nextInt(); // skip schedule
+        sc.nextInt(); // skip lineinfo
+        sc.nextInt(); // skp systemkey
+        sc.nextInt(); // skip sch_seq
+        sc.nextInt(); // skip glob_seq
+        sc.nextInt(); // skip count
+        sc.nextInt(); // fwy
+        DIRECTION dir = DIRECTION.getEnum(sc.next()); // direction
+        sc.nextDouble();
+        
+        /** GRABS FROM CURRENT TO END OF LINE */
+        sc.useDelimiter("\\z"); 
+        String loc = sc.next().trim();
+        sc.close();
+        return loc;
+    }
+    
+    // creates a Station
+    private LoopDetectorStation createStation(int stnNum, Scanner sc, ArrayList<LoopDetector> detectors)
+    {
+        LoopDetectorStation LDS = null;
+        
+        sc.nextLine();
+        
+        while(sc.hasNext())
+        {        
+            String strLine = sc.nextLine();
+            Scanner scLine = new Scanner(strLine);
+            int ldsID = scLine.nextInt(); // get curr lds id
+            if(ldsID == stnNum) // if we are on correct stn
+            {
+                int lineNum = scLine.nextInt(); // skip line num
+                int drop = scLine.nextInt(); // drop num
+                scLine.nextInt(); // skip schedule
+                scLine.nextInt(); // skip lineinfo
+                scLine.nextInt(); // skp systemkey
+                scLine.nextInt(); // skip sch_seq
+                scLine.nextInt(); // skip glob_seq
+                scLine.nextInt(); // skip count
+                int fwy = scLine.nextInt(); // fwy
+                DIRECTION dir = DIRECTION.getEnum(scLine.next()); // direction
+                double postmile = scLine.nextDouble();
+                String ldsName = getLocation(strLine); /************* DOESNT GRAB WHOLE???? */////
+                LDS = new LoopDetectorStation(lineNum, ldsID, drop, ldsName, detectors, fwy, dir, postmile);
+                
+                break;
+            }
+            scLine.close();
+        }
+        
+        sc.close();
+        
+        return LDS;
+    }
+}
Index: trunk/src/atmsdriver/model/FEPLine.java
===================================================================
--- trunk/src/atmsdriver/model/FEPLine.java	(revision 79)
+++ trunk/src/atmsdriver/model/FEPLine.java	(revision 79)
@@ -0,0 +1,106 @@
+package atmsdriver.model;
+
+import java.util.List;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+
+
+/** An FEPLine is a simulated line of communication from the FEP to 
+ *  LoopDetectorStations in the traffic network.
+ * 
+ *  An FEPLine contains static meta data and a list of LoopDetectorStations.
+ *  A single FEPLine contains multiple LoopDetectorStations.
+ *
+ * @author John A. Torres
+ * @version 09/10/2017
+ */ 
+public class FEPLine {
+    /* Static FEPLine meta data */
+    final private int lineNum;
+    final private List<LoopDetectorStation> stations;
+    final private int count;
+    // NOT SURE IF NEXT IS FINAL
+    final private int schedule;
+    final private int lineInfo;
+    final private long systemKey;
+    final private long globalSeq;
+    final private long scheduleSeq;
+    
+    public FEPLine(int lineNum, List<LoopDetectorStation> stations, int count,
+            int schedule, int lineInfo, long systemKey, long globalSeq,
+            long scheduleSeq)
+    {
+        this.lineNum = lineNum;
+        this.stations = stations;
+        this.count = count;
+        this.schedule = schedule;
+        this.lineInfo = lineInfo;
+        this.systemKey = systemKey;
+        this.globalSeq = globalSeq;
+        this.scheduleSeq = scheduleSeq;
+    }
+    
+    public void toXML(Element currElem)
+    {
+        Document theDoc = currElem.getOwnerDocument();
+        
+        Element lineElement = theDoc.createElement(XML_TAGS.LINE.tag);
+        currElem.appendChild(lineElement);
+        
+        Element lineNumElement = theDoc.createElement(XML_TAGS.LINE_NUM.tag);
+        lineNumElement.appendChild(theDoc.createTextNode(String.valueOf(this.lineNum)));
+        lineElement.appendChild(lineNumElement);
+        
+        Element countElement = theDoc.createElement(XML_TAGS.COUNT.tag);
+        countElement.appendChild(theDoc.createTextNode(String.valueOf(this.count)));
+        lineElement.appendChild(countElement);
+        
+        Element scheduleElement = theDoc.createElement(XML_TAGS.SCHEDULE.tag);
+        scheduleElement.appendChild(theDoc.createTextNode(String.valueOf(this.schedule)));
+        lineElement.appendChild(scheduleElement);
+        
+        Element lineInfoElement = theDoc.createElement(XML_TAGS.LINE_INFO.tag);
+        lineInfoElement.appendChild(theDoc.createTextNode(String.valueOf(this.lineInfo)));
+        lineElement.appendChild(lineInfoElement);
+        
+        Element systemKeyElement = theDoc.createElement(XML_TAGS.SYSTEM_KEY.tag);
+        systemKeyElement.appendChild(theDoc.createTextNode(String.valueOf(this.systemKey)));
+        lineElement.appendChild(systemKeyElement);
+        
+        Element globalSeqElement = theDoc.createElement(XML_TAGS.GLOBAL_SEQ.tag);
+        globalSeqElement.appendChild(theDoc.createTextNode(String.valueOf(this.globalSeq)));
+        lineElement.appendChild(globalSeqElement);
+        
+        Element scheduleSeqElement = theDoc.createElement(XML_TAGS.SCHEDULE_SEQ.tag);
+        scheduleSeqElement.appendChild(theDoc.createTextNode(String.valueOf(this.scheduleSeq)));
+        lineElement.appendChild(scheduleSeqElement);
+        
+        Element stationsElement = theDoc.createElement(XML_TAGS.STATIONS.tag);
+        lineElement.appendChild(stationsElement);
+        for(LoopDetectorStation station : stations)
+        {
+            station.toXML(stationsElement);
+        }
+    }
+    
+    private static enum XML_TAGS
+    {
+        LINE("Line"),
+        LINE_NUM("Line_Num"),
+        STATIONS("Stations"),
+        COUNT("Count"),
+        SCHEDULE("Schedule"),
+        LINE_INFO("Line_Info"),
+        SYSTEM_KEY("System_Key"),
+        GLOBAL_SEQ("Global_Seq"),
+        SCHEDULE_SEQ("Schedule_Seq");
+        
+        String tag;
+        
+        private XML_TAGS(String n)
+        {
+            tag = n;
+        }
+    }
+}
Index: trunk/src/atmsdriver/model/LoopDetector.java
===================================================================
--- trunk/src/atmsdriver/model/LoopDetector.java	(revision 79)
+++ trunk/src/atmsdriver/model/LoopDetector.java	(revision 79)
@@ -0,0 +1,103 @@
+package atmsdriver.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/** A LoopDetector represents a single detector for a single lane in a network.
+ * 
+ *  A LoopDetector contains static meta data, and three dynamic attributes: vol,
+ *  occ, and spd.
+ *
+ * @author John A. Torres
+ * @version 09/10/2017
+ */
+public class LoopDetector 
+{
+    /* static data */
+    final private int loopID;
+    final private String loopLocation;
+    final private int laneNum;
+    
+    /* dynamic data */
+    private int vol;
+    private int occ;
+    private int spd;
+    
+    public LoopDetector(int loopID, String loopLocation, int laneNum)
+    {
+        /* Set static data */
+        this.loopID = loopID;
+        this.loopLocation = loopLocation;
+        this.laneNum = laneNum;
+        
+        /* Init dynamic data */
+        this.vol = 0;
+        this.spd = 0;
+        this.occ = 0;
+    }
+    
+    private static enum XML_TAGS
+    {
+        LOOP_ID("Loop_ID"),
+        LOOP_LOCATION("Loop_Location"),
+        LANE_NUM("Lane_Num"),
+        VOL("Vol"),
+        SPD("Spd"),
+        OCC("Occ"),
+        LOOP("Loop");
+        
+        String tag;
+        
+        private XML_TAGS(String n)
+        {
+            tag = n;
+        }
+    }
+    
+    /** 
+     * Updates loop detector dynamic attributes.
+     * @param vol volume
+     * @param occ occupancy
+     * @param spd speed
+     */
+    public void updateLoop(int vol, int occ, int spd)
+    {
+        this.vol = vol;
+        this.occ = occ;
+        this.spd = spd;
+    }
+    
+    public void toXML(Element currElem)
+    {
+        Document theDoc = currElem.getOwnerDocument();
+        
+        Element loopElement = theDoc.createElement(XML_TAGS.LOOP.tag);
+        currElem.appendChild(loopElement);
+        
+        Element loopIDElement = theDoc.createElement(XML_TAGS.LOOP_ID.tag);
+        loopIDElement.appendChild(theDoc.createTextNode(String.valueOf(this.loopID)));
+        loopElement.appendChild(loopIDElement);
+        
+        Element loopLocElement = theDoc.createElement(XML_TAGS.LOOP_LOCATION.tag);
+        loopLocElement.appendChild(theDoc.createTextNode(this.loopLocation));
+        loopElement.appendChild(loopLocElement);
+        
+        Element laneNumElement = theDoc.createElement(XML_TAGS.LANE_NUM.tag);
+        laneNumElement.appendChild(theDoc.createTextNode(String.valueOf(this.laneNum)));
+        loopElement.appendChild(laneNumElement);
+        
+        Element volElement = theDoc.createElement(XML_TAGS.VOL.tag);
+        volElement.appendChild(theDoc.createTextNode(String.valueOf(this.vol)));
+        loopElement.appendChild(volElement);
+        
+        Element occElement = theDoc.createElement(XML_TAGS.OCC.tag);
+        occElement.appendChild(theDoc.createTextNode(String.valueOf(this.occ)));
+        loopElement.appendChild(occElement);
+        
+        Element spdElement = theDoc.createElement(XML_TAGS.SPD.tag);
+        spdElement.appendChild(theDoc.createTextNode(String.valueOf(this.spd)));
+        loopElement.appendChild(spdElement);
+    }
+}
Index: trunk/src/atmsdriver/model/LoopDetectorStation.java
===================================================================
--- trunk/src/atmsdriver/model/LoopDetectorStation.java	(revision 79)
+++ trunk/src/atmsdriver/model/LoopDetectorStation.java	(revision 79)
@@ -0,0 +1,168 @@
+package atmsdriver.model;
+
+import java.util.List;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/** A LoopDetectorStation is a simulation of a station in a traffic network.
+ *  
+ *  A LoopDetectorStation (LDS) contains static meta data about the station, and
+ *  two dynamic attributes, MLTotVol and OppTotVol. 
+ * 
+ *  A single LDS contains multiple LoopDetectors, which
+ *  contain data for a single lane on one direction of the freeway. A LDS
+ *  is specific to a single freeway, direction, and postmile.
+ *
+ * @author John A. Torres
+ * @version 9/10/2017
+ */
+public class LoopDetectorStation {
+    /* Static LoopDetectorStation meta data */
+    final private int lineNum;
+    final private int ldsID; // double check
+    final private int drop;
+    final private String location;
+    final private List<LoopDetector> loops;
+    final private int freeway;
+    final private double postmile;
+    final private DIRECTION direction;
+    
+    /* Dynamic LoopDetectorStation data */
+    private int MLTotVol;
+    private int OppTotVol;
+    
+    /* Constructor */
+    public LoopDetectorStation(int lineNum, int ldsID, int drop,
+            String location, List<LoopDetector> loops, int fwy, 
+            DIRECTION direction, double postmile)
+    {
+        this.lineNum = lineNum;
+        this.ldsID = ldsID;
+        this.drop = drop;
+        this.loops = loops;
+        this.location = location;
+        this.postmile = postmile;
+        this.direction = direction;
+        this.freeway = fwy;
+        
+        this.MLTotVol = 0;
+        this.OppTotVol = 0;
+    }
+    
+    private static enum XML_TAGS
+    {
+        STATION("Station"),
+        LDS_ID("LDS_ID"),
+        LINE_NUM("Line_Num"),
+        DROP("Drop"),
+        LOOPS("Loops"),
+        LOCATION("Location"),
+        POST_MILE("Post_Mile"),
+        DIRECTION("Direction"),
+        FREEWAY("Freeway"),
+        ML_TOT_VOL("ML_Tot_Vol"),
+        OPP_TOT_VOL("Opp_Tot_Vol");
+        
+        String tag;
+        
+        private XML_TAGS(String n)
+        {
+            tag = n;
+        }
+    }
+    
+    public void toXML(Element currElem)
+    {
+        Document theDoc = currElem.getOwnerDocument();
+        
+        Element stationElement = theDoc.createElement(XML_TAGS.STATION.tag);
+        currElem.appendChild(stationElement);
+        
+        Element ldsIDElement = theDoc.createElement(XML_TAGS.LDS_ID.tag);
+        ldsIDElement.appendChild(theDoc.createTextNode(String.valueOf(this.ldsID)));
+        stationElement.appendChild(ldsIDElement);
+        
+        Element lineNumElement = theDoc.createElement(XML_TAGS.LINE_NUM.tag);
+        lineNumElement.appendChild(theDoc.createTextNode(String.valueOf(this.lineNum)));
+        stationElement.appendChild(lineNumElement);
+        
+        Element dropElement = theDoc.createElement(XML_TAGS.DROP.tag);
+        dropElement.appendChild(theDoc.createTextNode(String.valueOf(this.drop)));
+        stationElement.appendChild(dropElement);
+        
+        Element locationElement = theDoc.createElement(XML_TAGS.LOCATION.tag);
+        locationElement.appendChild(theDoc.createTextNode(this.location));
+        stationElement.appendChild(locationElement);
+        
+        Element postMileElement = theDoc.createElement(XML_TAGS.POST_MILE.tag);
+        postMileElement.appendChild(theDoc.createTextNode(String.valueOf(this.postmile)));
+        stationElement.appendChild(postMileElement);
+        
+        Element directionElement = theDoc.createElement(XML_TAGS.DIRECTION.tag);
+        directionElement.appendChild(theDoc.createTextNode(this.direction.name));
+        stationElement.appendChild(directionElement);
+        
+        Element freewayElement = theDoc.createElement(XML_TAGS.FREEWAY.tag);
+        freewayElement.appendChild(theDoc.createTextNode(String.valueOf(this.freeway)));
+        stationElement.appendChild(freewayElement);
+        
+        Element mlElement = theDoc.createElement(XML_TAGS.ML_TOT_VOL.tag);
+        mlElement.appendChild(theDoc.createTextNode(String.valueOf(this.MLTotVol)));
+        stationElement.appendChild(mlElement);
+        
+        Element oppElement = theDoc.createElement(XML_TAGS.OPP_TOT_VOL.tag);
+        oppElement.appendChild(theDoc.createTextNode(String.valueOf(this.OppTotVol)));
+        stationElement.appendChild(oppElement);
+        
+        Element loopsElement = theDoc.createElement(XML_TAGS.LOOPS.tag);
+        stationElement.appendChild(loopsElement);
+        
+        for(LoopDetector loop : loops)
+        {
+            loop.toXML(loopsElement);
+        }
+    }
+    
+    /**
+     * Enum for freeway direction.
+     * 
+     * @author John A. Torres
+     * @version 9/10/2017
+     */
+    public static enum DIRECTION
+    {
+        NORTH("N"),
+        SOUTH("S"),
+        EAST("E"),
+        WEST("W");
+        
+        String name;
+        
+        DIRECTION(String name)
+        {
+            this.name = name;
+        }
+        
+        /**
+         * Returns the direction enum, given a string value.
+         * @param name str value for enum
+         * @return enum for given str value
+         */
+        public static DIRECTION getEnum(String name)
+        {
+            switch(name)
+            {
+                case "S":
+                    return SOUTH;
+                case "N":
+                    return NORTH;
+                case "E":
+                    return EAST;
+                case "W":
+                    return WEST;
+                default:
+                    return null;
+            }
+        }
+    }
+}
Index: trunk/src/atmsdriver/model/Network.java
===================================================================
--- trunk/src/atmsdriver/model/Network.java	(revision 79)
+++ trunk/src/atmsdriver/model/Network.java	(revision 79)
@@ -0,0 +1,87 @@
+package atmsdriver.model;
+
+import atmsdriver.NetworkLoader;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ *
+ * @author andrew
+ */
+public class Network {
+    final private ArrayList<FEPLine> lines;
+    final private File networkFile;
+    
+    public Network(File LDSFile, File loopFile, File networkFile)
+    {
+        lines = (ArrayList<FEPLine>) 
+                new NetworkLoader(LDSFile, loopFile).getFEPLines();
+        this.networkFile = networkFile;
+    }
+    
+    public void toXML()
+    {
+        try {
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder = factory.newDocumentBuilder();
+            Document theDoc = builder.newDocument();
+            
+            Element networkElement = theDoc.createElement(XML_TAGS.NETWORK.tag);
+            theDoc.appendChild(networkElement);
+            
+            for(FEPLine line : lines)
+            {
+                line.toXML(networkElement);
+            }
+            
+            Transformer tf = TransformerFactory.newInstance().newTransformer();
+            
+            tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
+            tf.setOutputProperty(OutputKeys.INDENT, "yes");
+            tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+            
+            Writer out = new StringWriter();
+            tf.transform(new DOMSource(theDoc), new StreamResult(out));
+            String xml = out.toString();
+            out.close();
+            
+            Writer fileWr = new FileWriter(networkFile);
+            fileWr.write(xml);
+            fileWr.close();
+            
+            
+        } catch (Exception ex) {
+            Logger.getLogger(Network.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+    
+    private static enum XML_TAGS
+    {
+        NETWORK("Network");
+        
+        String tag;
+        
+        private XML_TAGS(String n)
+        {
+            tag = n;
+        }
+    }
+}
Index: trunk/src/atmsdriver/ExchangeReader.java
===================================================================
--- trunk/src/atmsdriver/ExchangeReader.java	(revision 79)
+++ trunk/src/atmsdriver/ExchangeReader.java	(revision 79)
@@ -0,0 +1,280 @@
+package atmsdriver;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ *
+ * @author John A Torres
+ */
+public class ExchangeReader {
+	/** Error Log **/
+	private static Logger ATMSDriverLogger = Logger.getLogger("atmsdriver");
+	
+	/** A SAX Handler that is used to parse received Incident Status Node. **/
+	private IncidentStatusHandler ish = null;
+	
+	/** The current networkId **/
+	private int networkId = 1;
+	
+	/** The Paramics Simulation Info for the most recent incident read **/
+	private ExchangeInfo exInfo = null;
+	
+	/** Value (seconds since 1/1/1970) of input file's last modification time. */
+	private long lastModified = 0;
+	
+	/**
+	 * Constructor.
+	 */
+	public ExchangeReader() 
+	{		
+		ish = new IncidentStatusHandler();
+	}
+	
+	/**
+	 * This method parses the received XML node with the local CameraStatusHandler.
+	 * All updated camera information is sent to the ParamicsSimulationManager.
+	 * 
+	 * If a successful read of the file occurs, the file is written with an empty string
+	 * and the date of the last modification is stored.
+	 *
+	 * @param filename The file to check for message in.
+	 * @return A ParamicsSimulationInfo object containing the file's information
+	 * 		   A null pointer on:
+	 * 		     - The file does not exist
+	 * 		     - No new modification
+	 * 		     - An error opening file 		  
+	 *           - An empty file
+	 *           - An error parsing the file
+	 *           
+	 *         The caller is able to call this function to check if there are any new messages
+	 *         in the file.  If there are, a PSI object is returned.  If there aren't any new
+	 *         messages, a null pointer is returned.
+	 */
+	public ExchangeInfo parse(String filename) 
+	{	
+		ExchangeInfo exInfo = null;
+		
+		File f = new File(filename);
+		BufferedReader r = null;
+		
+		// File does not exist: No information
+		if (!(f.exists()))
+		{
+			return null;
+		}
+		
+		// File not modified: No new information
+		if (f.lastModified() <= lastModified)
+		{
+			return null;
+		}
+		
+		try 
+		{
+			// Try to open the file
+			r = new BufferedReader(new FileReader(f));
+			
+			// Read the file to the end
+			StringBuilder xml = new StringBuilder("");
+			String line = r.readLine();
+			while (line != null)
+			{
+				xml.append(line + "\n");
+				line = r.readLine();
+			}
+			
+			// If the file has contents in it, read them and returned a PSI describing the contents
+			if(xml.length() > 0) 
+			{
+				// Parse the file
+				SAXParserFactory.newInstance().newSAXParser().parse(new InputSource(new StringReader(xml.toString())), ish);
+                                exInfo = new ExchangeInfo(networkId, xml.toString());
+			}
+			else if (xml.length() == 0)
+			{
+				lastModified = modifyFile(f);
+				r.close();
+			}
+		}
+		catch (FileNotFoundException fnfe)
+		{
+			ATMSDriverLogger.logp(Level.SEVERE, "ParamicsIncidentReader", "parse", 
+					filename + " dissapeared before reading.", fnfe);
+			exInfo = null;
+		}
+		catch (IOException ioe)
+		{
+			ATMSDriverLogger.logp(Level.SEVERE, "ParamicsIncidentReader", "parse", 
+					"Error while reading file " + filename + ".", ioe);
+			exInfo = null;
+		}
+		catch (SAXException saxe)
+		{
+			ATMSDriverLogger.logp(Level.SEVERE, "ParamicsIncidentReader", "parse", 
+					"Error while parsing file " + filename + ".", saxe);
+			exInfo = null;
+		}
+		catch (ParserConfigurationException pce)
+		{
+			ATMSDriverLogger.logp(Level.SEVERE, "ParamicsIncidentReader", "parse", 
+					"Error while configuring parser.", pce);
+		}
+		
+		// If a incident was read
+		if (exInfo != null)
+		{
+			lastModified = modifyFile(f);
+			try
+			{
+				r.close();
+			}
+			catch (IOException e)
+			{
+				ATMSDriverLogger.logp(Level.SEVERE, "ParamicsIncidentReader", "parse", 
+						"Error while closing file" + filename + ".", e);
+			}			
+		}
+		
+		// Return no object if there was an error while reading, or the psi created from
+		// parsing the file if the operation was successful.
+		return exInfo;
+	}
+	
+	private long modifyFile(File f)
+	{
+		FileWriter w = null;
+		
+		// Write to the file to show that it was read.
+		try
+		{
+			w = new FileWriter(f);
+			w.write("");
+			w.close();
+		}
+		catch (IOException e)
+		{
+			ATMSDriverLogger.logp(Level.SEVERE, "ParamicsIncidentReader", "parse", 
+					"Error while writing to file " + f.getName() + " to show that file was read.", e);
+		}
+		
+		// Save the last modified time
+		return f.lastModified();
+	}
+
+    /**
+     * Internal SAX Handler used to parse the Incident Status Document read by
+     * the remote Status Reader.  The schema for this document is: <br/>
+     *
+	 * <CAD_DATA><br>
+	 *    <Basic><br>
+	 *       <Comm_Interval/><br/>
+	 *       <Network_ID/><br/>
+	 *       <Simulation/><br/>
+	 *       <Incident/><br/>
+	 *    </Basic>
+	 *
+	 *    <Simulation_Data>
+	 *       <Simulation_speed/><br/>
+	 *       <CAD_clock><br/>
+	 *          <hour/><br/>
+	 *          <minute/><br/>
+	 *          <second/><br/>
+	 *          <Location><br/>
+	 *       </CAD_clock><br/>
+	 *    </Simulation_Data>
+	 *    
+	 *    <CAD_Incidents>
+	 *       <Incident><br/>
+	 *          <Identifier/><br/>
+	 *          <Status/><br/>
+	 *          <Location><br/>
+	 *              <Route/><br/>
+	 *              <Direction/><br/>
+	 *              <Location_type/><br/>
+	 *              <Postmile/><br/>
+	 *          </Location><br/>
+	 *          <Incident_type/><br/>
+	 *          <Lanes><br/>
+	 *             <Lane_number/><br/>
+	 *             ...
+	 *          </Lanes><br/>
+	 *       </Incident><br/>
+	 *       ...
+	 *    </CAD_Incidents>   
+	 *    
+	 *    <Management>
+	 *       <Diversion>
+     *          <Diversion_path>
+     *             <Identifier/>
+     *             <Percentage/>
+     *          <Diversion_path>
+     *          ...
+     *       </Diversion>
+     *       ...
+	 *    </Management>
+	 *  
+	 * </CAD_DATA>
+     */	
+	protected class IncidentStatusHandler extends DefaultHandler 
+	{
+		private final String NETWORK_ID   = "Network_ID";
+		
+		/** A buffer for reading characters **/
+		private StringBuffer parsedValue  = new StringBuffer();
+
+		public void startDocument() 
+		{ 
+		}	
+		
+		/** Appends characters to the xmlMessage and parsedValue buffers **/
+		public void characters(char[] ch, int start, int length) 
+		{
+			parsedValue.append(new String(ch, start, length).trim());
+		}
+		
+	    public void startElement (String uri, String localName, String qName, Attributes attributes)
+			throws SAXException
+		{
+	    }
+		
+		public void endElement(String uri, String localName, String qName)  
+		{
+			if(qName.equals(NETWORK_ID)) { networkId = Integer.parseInt(parsedValue.toString()); }
+			
+			parsedValue.setLength(0);
+		}	
+		
+		public void error(SAXParseException e) 
+		{
+			ATMSDriverLogger.logp(Level.SEVERE, "ParamicsIncidentReader", "error", 
+					"Error in parsing received incident status.", e);
+		}
+		
+		public void fatalError(SAXParseException e) 
+		{
+			ATMSDriverLogger.logp(Level.SEVERE, "ParamicsIncidentReader", "fatalError", 
+					"Fatal error in parsing received incident status.", e);
+		}
+		
+		public void warning(SAXParseException e) 
+		{
+			ATMSDriverLogger.logp(Level.WARNING, "ParamicsIncidentReader", "warning", 
+					"Warning in parsing received incident status.", e);
+		}		
+	}
+}
Index: trunk/src/atmsdriver/ExchangeInfo.java
===================================================================
--- trunk/src/atmsdriver/ExchangeInfo.java	(revision 79)
+++ trunk/src/atmsdriver/ExchangeInfo.java	(revision 79)
@@ -0,0 +1,20 @@
+package atmsdriver;
+
+/**
+ *
+ * @author John A Torres
+ */
+public class ExchangeInfo {
+	/** The network ID **/
+	public int networkId;
+
+	/** The XML message **/
+	public String xmlMessage;
+	
+	/** Constructor **/
+	public ExchangeInfo(int networkId, String xmlMessage)
+	{
+		this.networkId = networkId;
+		this.xmlMessage = xmlMessage;
+	}
+}
