Index: /trunk/IDE_metadata/NetBeans/TMCSim/nbproject/configs/Paramics_Sim.properties
===================================================================
--- /trunk/IDE_metadata/NetBeans/TMCSim/nbproject/configs/Paramics_Sim.properties	(revision 66)
+++ /trunk/IDE_metadata/NetBeans/TMCSim/nbproject/configs/Paramics_Sim.properties	(revision 66)
@@ -0,0 +1,3 @@
+$label=Paramics Sim
+main.class=paramsim.paramicssimulator.ParamicsSimulator
+run.jvmargs=-DPARAMICS_SIM_PROPERTIES=config/paramics_simulator_config.properties
Index: /trunk/src/paramsim/paramicssimulator/SimulationCamera.java
===================================================================
--- /trunk/src/paramsim/paramicssimulator/SimulationCamera.java	(revision 66)
+++ /trunk/src/paramsim/paramicssimulator/SimulationCamera.java	(revision 66)
@@ -0,0 +1,75 @@
+package paramsim.paramicssimulator;
+
+/**
+ * A class which encapsulates all information pertaining to a ParamicSimulator
+ * camera.
+ * 
+ * @author Greg Eddington
+ */
+public class SimulationCamera 
+{
+	/**
+	 * A road direction enumeration.
+	 * 
+	 * @author Greg Eddington
+	 */
+	public static enum ROAD_DIRECTION
+	{
+		/** North **/
+		NORTH("NB"),
+		
+		/** South **/
+		SOUTH("SB"),
+		
+		/** East **/
+		EAST("EB"),
+		
+		/** West **/
+		WEST("WB");
+		
+		/** The XML string of the field, used for updating camera_status.xml **/
+		public String xml;
+		
+		/** Constructor **/
+		private ROAD_DIRECTION(String str)
+		{
+			this.xml = str;
+		}
+	}
+	
+	/** Camera ID **/
+	public int id;
+	
+	/** The route the camera is watching **/
+	public String route;
+	
+	/** The route direction **/
+	public ROAD_DIRECTION direction;
+	
+	/** The postmile of the route **/
+	public float postmile;
+	
+	/** The average speed the camera is recording North or East **/
+	public float averageSpeedNE;
+	
+	/** The average speed the camera is recording South or West **/
+	public float averageSpeedSW;
+	
+	/** The minimum speed for the camera to show stopped footage **/
+	public float minStoppedSpeed;
+	
+	/** The maxmimum speed for the camera to show stopped footage **/
+	public float maxStoppedSpeed;
+	
+	/** The minimum speed for the camera to show slowed footage **/
+	public float minSlowSpeed;
+	
+	/** The maximum speed for the camera to show slowed footage **/
+	public float maxSlowSpeed;
+	
+	/** The minimum speed for the camera to show free flow footage **/
+	public float minFreeFlowSpeed;
+	
+	/** The maximum speed for the camera to show free flow footage **/
+	public float maxFreeFlowSpeed;
+}
Index: /trunk/src/paramsim/paramicssimulator/ParamicsSimulator.java
===================================================================
--- /trunk/src/paramsim/paramicssimulator/ParamicsSimulator.java	(revision 66)
+++ /trunk/src/paramsim/paramicssimulator/ParamicsSimulator.java	(revision 66)
@@ -0,0 +1,412 @@
+package paramsim.paramicssimulator;
+
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Observable;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.swing.JOptionPane;
+
+import paramsim.paramicssimulator.ParamicsSimulatorLogMessage.PARAMICS_SIMULATOR_LOG;
+import paramsim.paramicssimulator.gui.ParamicsSimulatorGUI;
+
+/**
+ * ParamicsSimulator is the main class for this module.  The ParamicsSimulator
+ * can be used to simulate the Paramics device.<br><br>  
+ * The properties file for the ParamicsCommunicator class contains the following data.<br>
+ * <code>
+ * -----------------------------------------------------------------------------<br>
+ * WorkingDirectory      The working directory of the Paramics Communicator<br>
+ * ParamicsStatusLog     The Paramics status log file <br>
+ * CameraStatusLog       The camera status log file <br>
+ * ExchangeLog			 The exchange log file <br> 
+ * CameraControlConfig   The camera control file which maps the camera information <br>
+ * DVDPlayersConfig      The DVD Players XML file which contains camera information <br>
+ * -----------------------------------------------------------------------------<br>
+ * Example File: <br>
+ * WorkingDirectory    = c:/paramics/out <br>
+ * ParamicsStatusLog   = paramics_status.log <br>
+ * CameraStatusLog     = camera_status.log <br>
+ * IncidentLog     	   = exchange.log <br>
+ * CameraControlConfig = camera_control.txt
+ * DVDPlayersConfig    = dvdplayers.xml
+ * -----------------------------------------------------------------------------<br>
+ * </code>
+ *
+ * @author Greg Eddington (geddingt@calpoly.edu)
+ */
+public class ParamicsSimulator extends Observable implements Runnable
+{
+	/** Error Log **/
+	private static Logger paramLogger = Logger.getLogger("paramsim.paramicssimulator");
+	
+	/** Incident file **/
+	private static final String INCIDENT_FILE = "exchange.xml";
+	
+	/** Paramics Status file **/
+	private static final String PARAM_STATUS_FILE = "paramics_status.xml";
+	
+	/** Camera Status file **/
+	private static final String CAMERA_STATUS_FILE = "camera_status.xml";
+	
+	/** Sleep Time (10 seconds) **/
+	private static final int SLEEP_TIME = 10000;
+	
+	/**
+	 * Enumeration containing property names.
+	 * @author Greg Eddington
+	 */
+	private static enum PROPERTIES 
+	{
+		/** The working directory for Paramics **/
+		WORKING_DIR ("WorkingDirectory"),
+		
+		/** The Paramics log **/
+		PARAM_STATUS_LOG ("ParamicsStatusLog"),
+		
+		/** The camera status log **/
+		CAMERA_STATUS_LOG ("CameraStatusLog"),
+		
+		/** The exchange log **/
+		INCIDENT_LOG ("IncidentLog"),
+		
+		/** The camera control file **/
+		CAMERA_CONTROL ("CameraControlConfig"),
+		
+		/** The still images XML file **/
+		DVD_PLAYERS ("DVDPlayersConfig");
+		
+		public String name;
+		
+		private PROPERTIES(String n) 
+		{
+			name = n;
+		}
+	}
+	
+	/** 
+	 * Enumeration of network statuses.
+	 * @author Greg Eddington
+	 **/
+	public static enum NETWORK_STATUS
+	{
+		LOADING ("LOADING"),
+		WARMING ("WARMING"),
+		LOADED ("LOADED"),
+		UNKNOWN ("UNKNOWN");
+		
+		public String message;
+		
+		private NETWORK_STATUS(String n) 
+		{
+			message = n;
+		}
+	}
+	
+	/** Properties object. */
+	private Properties paramicsSimProp = null;	
+	
+	/** Working Directory **/
+	private String workingDirectory = null;
+	
+	/** Incidents File **/
+	private String incidentFile = null;
+	
+	/** Paramics Status File **/
+	private String paramStatusFile = null;
+	
+	/** Camera Status File **/
+	private String cameraStatusFile = null;
+
+	/** Incidents Log **/
+	private String incidentLog = null;
+	
+	/** Paramics Status Log **/
+	private String paramStatusLog = null;
+
+	/** Camera Status Log **/
+	private String cameraStatusLog = null;
+	
+	/** Incident Reader **/
+	private ParamicsIncidentReader incidentReader = null;
+	
+	/** The paramics simulator GUI **/
+	private ParamicsSimulatorGUI theGUI;
+	
+	/** The network ID **/
+	private int networkId = 1;
+	
+	/** Simulation Cameras **/
+	private List<SimulationCamera> cameras;
+	
+	/**
+	 * Creates a ParamicsSimulator object with properties defined in the propertiesFile
+	 * parameter.  It will initialize all file locations.
+	 */
+	public ParamicsSimulator(String propertiesFile) 
+	{		
+		try 
+		{
+			paramicsSimProp = new Properties();
+			paramicsSimProp.load(new FileInputStream(propertiesFile));
+			
+			/** Check property file **/
+			for (PROPERTIES property : PROPERTIES.values())
+			{
+				if (paramicsSimProp.getProperty(property.name) == null || 
+					paramicsSimProp.getProperty(property.name).length() == 0) 
+				{				
+					System.err.println("Invalid Configuration: Properties file missing " +
+						property.name + " property.");
+					System.exit(0);
+				}
+			}
+			
+			// Directory
+			workingDirectory = paramicsSimProp.getProperty(PROPERTIES.WORKING_DIR.name).trim();			
+			boolean endsWithSlash = workingDirectory.charAt(workingDirectory.length()-1) == '/' || 
+				workingDirectory.charAt(workingDirectory.length()-1) == '\\';
+			
+			// Files
+			paramStatusFile = workingDirectory + (endsWithSlash ? "" : "/") + PARAM_STATUS_FILE;
+			cameraStatusFile = workingDirectory + (endsWithSlash ? "" : "/") + CAMERA_STATUS_FILE;
+			incidentFile = workingDirectory + (endsWithSlash ? "" : "/") + INCIDENT_FILE;
+			
+			// Logs
+			incidentLog = paramicsSimProp.getProperty(PROPERTIES.INCIDENT_LOG.name).trim();
+			paramStatusLog = paramicsSimProp.getProperty(PROPERTIES.PARAM_STATUS_LOG.name).trim();
+			cameraStatusLog = paramicsSimProp.getProperty(PROPERTIES.CAMERA_STATUS_LOG.name).trim();
+			
+			// Delete any old logs
+			File ilFile = new File(incidentLog);
+			File pslFile = new File(paramStatusLog);
+			File cslFile = new File(cameraStatusLog);
+			ilFile.delete();
+			pslFile.delete();
+			cslFile.delete();
+			
+			// Cameras
+			String cameraConfig = paramicsSimProp.getProperty(PROPERTIES.CAMERA_CONTROL.name).trim();
+			String stillImages = paramicsSimProp.getProperty(PROPERTIES.DVD_PLAYERS.name).trim();
+			try
+			{
+				// Load the cameras
+				cameras = CameraParser.loadCameras(stillImages, cameraConfig);
+			}
+			catch (IOException e)
+			{
+				// Create an empty camera array
+				cameras = new ArrayList<SimulationCamera>();
+				
+				// Log Error
+				paramLogger.logp(Level.SEVERE, "ParamicsSimulator", "Constructor", 
+						"Error loading camera config from files \"" + stillImages +
+						"\" and \"" + cameraConfig + "\".", e);
+			}
+			
+			// Initialize GUI
+			theGUI = new ParamicsSimulatorGUI(this);
+			addObserver(theGUI);
+			theGUI.addWindowListener
+			(
+				new WindowListener() 
+				{			
+					public void windowActivated(WindowEvent arg0) {};
+					public void windowClosed(WindowEvent arg0) {};
+					public void windowClosing(WindowEvent arg0) { System.exit(0); };
+					public void windowDeactivated(WindowEvent arg0) {};
+					public void windowDeiconified(WindowEvent arg0) {};
+					public void windowIconified(WindowEvent arg0) {};
+					public void windowOpened(WindowEvent arg0) {};
+				}
+			);
+			
+			// Write an initial packets
+			writeParamicsStatus(NETWORK_STATUS.LOADING);
+			writeCameraStatus(cameras);
+		} 
+		catch (Exception e) 
+		{
+			paramLogger.logp(Level.SEVERE, "ParamicsSimulator", "Constructor", 
+					"Exception in reading properties file.", e);
+		}
+		
+		incidentReader = new ParamicsIncidentReader();
+	}
+	
+	/**
+	 * Appends a message to a log file.
+	 * @param logName The name of the log file.
+	 * @param message The message to append.
+	 */
+	private void writeToLog(String logName, String message)
+	{
+		try
+		{
+			FileWriter w = new FileWriter(logName, true);
+			w.write(message + "\n\n");
+			w.close();
+		}
+		catch (IOException e)
+		{
+			paramLogger.logp(Level.WARNING, "ParamicsSimulator", "writeToLog", 
+				"Error writing to file " + logName + ".", e);
+		}
+	}
+	
+	/**
+	 * Runs the Paramics simulator thread.
+	 */
+	public void run() 
+	{
+		// Check for packets and update the simulator
+		for(;;)
+		{
+			// Flush the input file
+			ParamicsSimulationInfo psi = incidentReader.parse(incidentFile);
+			
+			// Update the network ID if a packet is received
+			if (psi != null)
+			{
+				networkId = psi.networkId;
+				writeToLog(incidentLog, psi.xmlMessage);
+				setChanged();
+				notifyObservers(new ParamicsSimulatorLogMessage(PARAMICS_SIMULATOR_LOG.EXCHANGE, psi.xmlMessage));
+			}
+			
+			// Write camera status
+			writeCameraStatus(cameras);
+			
+			// Sleep
+			try
+			{
+				Thread.sleep(SLEEP_TIME);
+			}
+			catch (InterruptedException ie) {}
+		}
+	}
+
+	/**
+	 * Writes the camera status to the camera status XML file read by the Paramics Communicator,
+	 * as well as to the camera status log file.  All observers are notified with the new status,
+	 * so they can also log it.
+	 * 
+	 * @param id Camera ID
+	 * @param route Route
+	 * @param direction The direction of traffic
+	 * @param postmile The postmile
+	 * @param averageSpeedNE The average speed North or East
+	 * @param averageSpeedSW The average speed South or West
+	 */
+	public void writeCameraStatus(List<SimulationCamera> cameras)
+	{
+		StringBuilder message = new StringBuilder("<Camera_Status>\n");
+		for (SimulationCamera camera : cameras)
+		{
+			message.append
+			(
+				"   <Camera>\n" +
+				"      <Identifier>" + camera.id + "</Identifier>\n" +
+				"      <Route>" + camera.route + "</Route>\n" + 
+				"      <Direction>" + camera.direction.xml + "</Direction>\n" +
+				"      <Postmile>" + camera.postmile + "</Postmile>\n" + 
+				"      <Ave_Speed_NE>" + camera.averageSpeedNE + "</Ave_Speed_NE>\n" +
+				"      <Ave_Speed_SW>" + camera.averageSpeedSW + "</Ave_Speed_SW>\n" +
+				"   </Camera>\n"
+			);
+		}
+		message.append("</Camera_Status>");
+		
+		try
+		{
+			FileWriter w = new FileWriter(cameraStatusFile);
+			w.write(message.toString());
+			w.close();
+		}
+		catch (IOException e)
+		{
+			paramLogger.logp(Level.SEVERE, "ParamicsSimulator", "writeCameraStatus", 
+				"Error writing to file " + cameraStatusFile + ".", e);
+		}
+
+		writeToLog(cameraStatusLog, message.toString());
+		
+		setChanged();
+		notifyObservers(new ParamicsSimulatorLogMessage(PARAMICS_SIMULATOR_LOG.CAMERA_STATUS, message.toString()));	
+	}
+	
+	/**
+	 * Writes the Paramics status to the camera status XML file read by the Paramics Communicator,
+	 * as well as to the Paramics status log file.  All observers are notified with the new status,
+	 * so they can also log it.
+	 * 
+	 * @param status The current Paramics status
+	 */
+	public void writeParamicsStatus(NETWORK_STATUS status)
+	{
+		String message = "<Paramics>\n   <Network_Status>" + status.message +
+						 "</Network_Status>\n   <Network_ID>" + networkId + "</Network_ID>\n</Paramics>";
+		
+		try
+		{
+			FileWriter w = new FileWriter(paramStatusFile);
+			w.write(message);
+			w.close();
+		}
+		catch (IOException e)
+		{
+			paramLogger.logp(Level.SEVERE, "TrafficSimulator", "writeParamicsStatus", 
+					"Error writing to file " + paramStatusFile + ".", e);
+		}
+		
+		writeToLog(paramStatusLog, message);
+		
+		setChanged();
+		notifyObservers(new ParamicsSimulatorLogMessage(PARAMICS_SIMULATOR_LOG.PARAMICS_STATUS, message));	
+	}	
+	
+	/**
+	 * Runs the Paramics simulator.
+	 */
+	public static void main(String[] args) 
+	{
+		try
+		{
+			if(System.getProperty("PARAMICS_SIM_PROPERTIES") != null)
+			{
+				new Thread(new ParamicsSimulator(System.getProperty(
+					"PARAMICS_SIM_PROPERTIES"))).start();
+			}
+			else
+			{
+				throw new Exception ("PARAMICS_SIM_PROPERTIES system property not defined.");
+			}
+		} 
+		catch (Exception e) 
+		{
+			paramLogger.logp(Level.SEVERE, "ParamicsSimulator", "Main", 
+					"Error occured initializing application", e);
+			
+			JOptionPane.showMessageDialog(null, e.getMessage(), "Error - Program Exiting", JOptionPane.ERROR_MESSAGE);	
+	        	
+			System.exit(-1);
+		}
+	}
+	
+	/**
+	 * Gets the simulation cameras being used by the Paramics Simulator.
+	 * @return A list of Simulation Cameras.
+	 */
+	public List<SimulationCamera> getCameras()
+	{
+		return cameras;
+	}
+}
Index: /trunk/src/paramsim/paramicssimulator/ParamicsIncidentReader.java
===================================================================
--- /trunk/src/paramsim/paramicssimulator/ParamicsIncidentReader.java	(revision 66)
+++ /trunk/src/paramsim/paramicssimulator/ParamicsIncidentReader.java	(revision 66)
@@ -0,0 +1,285 @@
+package paramsim.paramicssimulator;
+
+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;
+
+/**
+ * A class which will read a FileReader stream, parsing it as an XML document,
+ * and return a IncidentStatus object which contains the parsed information.
+ * 
+ * @author Greg Eddington (geddingt@calpoly.edu)
+ */
+public class ParamicsIncidentReader 
+{	
+	/** Error Log **/
+	private static Logger paramLogger = Logger.getLogger("paramsim.paramicssimulator");
+	
+	/** A SAX Handler that is used to parse received Incident Status Node. **/
+	protected IncidentStatusHandler ish = null;
+	
+	/** The current networkId **/
+	private int networkId = 1;
+	
+	/** The Paramics Simulation Info for the most recent incident read **/
+	protected ParamicsSimulationInfo psi = null;
+	
+	/** Value (seconds since 1/1/1970) of input file's last modification time. */
+	protected long lastModified = 0;
+	
+	/**
+	 * Constructor.
+	 */
+	public ParamicsIncidentReader() 
+	{		
+		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 ParamicsSimulationInfo parse(String filename) 
+	{	
+		ParamicsSimulationInfo psi = 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);
+				psi = new ParamicsSimulationInfo(networkId, xml.toString());
+			}
+			else if (xml.length() == 0)
+			{
+				lastModified = modifyFile(f);
+				r.close();
+			}
+		}
+		catch (FileNotFoundException fnfe)
+		{
+			paramLogger.logp(Level.SEVERE, "ParamicsIncidentReader", "parse", 
+					filename + " dissapeared before reading.", fnfe);
+			psi = null;
+		}
+		catch (IOException ioe)
+		{
+			paramLogger.logp(Level.SEVERE, "ParamicsIncidentReader", "parse", 
+					"Error while reading file " + filename + ".", ioe);
+			psi = null;
+		}
+		catch (SAXException saxe)
+		{
+			paramLogger.logp(Level.SEVERE, "ParamicsIncidentReader", "parse", 
+					"Error while parsing file " + filename + ".", saxe);
+			psi = null;
+		}
+		catch (ParserConfigurationException pce)
+		{
+			paramLogger.logp(Level.SEVERE, "ParamicsIncidentReader", "parse", 
+					"Error while configuring parser.", pce);
+		}
+		
+		// If a incident was read
+		if (psi != null)
+		{
+			lastModified = modifyFile(f);
+			try
+			{
+				r.close();
+			}
+			catch (IOException e)
+			{
+				paramLogger.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 psi;
+	}
+	
+	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)
+		{
+			paramLogger.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) 
+		{
+			paramLogger.logp(Level.SEVERE, "ParamicsIncidentReader", "error", 
+					"Error in parsing received incident status.", e);
+		}
+		
+		public void fatalError(SAXParseException e) 
+		{
+			paramLogger.logp(Level.SEVERE, "ParamicsIncidentReader", "fatalError", 
+					"Fatal error in parsing received incident status.", e);
+		}
+		
+		public void warning(SAXParseException e) 
+		{
+			paramLogger.logp(Level.WARNING, "ParamicsIncidentReader", "warning", 
+					"Warning in parsing received incident status.", e);
+		}		
+	}		
+}
Index: /trunk/src/paramsim/paramicssimulator/ParamicsSimulationInfo.java
===================================================================
--- /trunk/src/paramsim/paramicssimulator/ParamicsSimulationInfo.java	(revision 66)
+++ /trunk/src/paramsim/paramicssimulator/ParamicsSimulationInfo.java	(revision 66)
@@ -0,0 +1,22 @@
+package paramsim.paramicssimulator;
+
+/**
+ * A class which encapsulates the data present in an Paramics incident status document.
+ * 
+ * @author Greg Eddington (geddingt@calpoly.edu)
+ */
+public class ParamicsSimulationInfo 
+{
+	/** The network ID **/
+	public int networkId;
+
+	/** The XML message **/
+	public String xmlMessage;
+	
+	/** Constructor **/
+	public ParamicsSimulationInfo(int networkId, String xmlMessage)
+	{
+		this.networkId = networkId;
+		this.xmlMessage = xmlMessage;
+	}
+}
Index: /trunk/src/paramsim/paramicssimulator/gui/ParamicsControlPanel.java
===================================================================
--- /trunk/src/paramsim/paramicssimulator/gui/ParamicsControlPanel.java	(revision 66)
+++ /trunk/src/paramsim/paramicssimulator/gui/ParamicsControlPanel.java	(revision 66)
@@ -0,0 +1,215 @@
+package paramsim.paramicssimulator.gui;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.ButtonGroup;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+
+import paramsim.paramicssimulator.ParamicsSimulator;
+import paramsim.paramicssimulator.SimulationCamera;
+import paramsim.paramicssimulator.ParamicsSimulator.NETWORK_STATUS;
+
+/**
+ * A JPanel which provides an interface to control the Paramics Simulator.
+ * Contains a Paramics Status interface using radio buttons, and multiple
+ * Camera Status interfaces using radio buttons.
+ * 
+ * @author Greg Eddington
+ */
+@SuppressWarnings("serial")
+public class ParamicsControlPanel extends JPanel implements ActionListener
+{
+	/** The simulator **/
+	private ParamicsSimulator simulator;
+	
+	/** Loading Status **/
+	private final static String LOADING = "Loading";
+	
+	/** Warming Status **/
+	private final static String WARMING = "Warming";
+	
+	/** Loaded Status **/
+	private final static String LOADED = "Loaded";
+	
+	/** Free Flow Speed Label **/
+	private final static String FREE_FLOW = "Free Flow";
+	
+	/** Slow Speed Label **/
+	private final static String SLOW = "Slow";
+	
+	/** Stopped Speed Label **/
+	private final static String STOPPED = "Stopped";
+	
+	/** Fast Camera Status Character ID **/
+	private final static Character FAST_CHARACTER = 'F';
+	
+	/** Medium Camera Status Character ID **/
+	private final static Character MEDIUM_CHARACTER = 'M';
+	
+	/** Slow Camera Status Character ID **/
+	private final static Character SLOW_CHARACTER = 'S';
+	
+	/** Constructor **/
+	public ParamicsControlPanel(ParamicsSimulator simulator)
+	{
+		this.simulator = simulator;
+		
+		Box controlsBox = new Box(BoxLayout.Y_AXIS);
+		controlsBox.setAlignmentY(Box.CENTER_ALIGNMENT);
+
+		controlsBox.add(Box.createVerticalStrut(20));
+		controlsBox.add(CreateStatusBox());
+		controlsBox.add(Box.createVerticalStrut(20));
+		controlsBox.add(CreateCameraBox());
+		
+		add(controlsBox);
+	}
+	
+	/** Create a Paramics Status GUI box **/
+	private Box CreateStatusBox()
+	{
+		Box radioBox = new Box(BoxLayout.X_AXIS);
+		
+		ButtonGroup radioButtons = new ButtonGroup();	
+		
+		JRadioButton loadingButton = new JRadioButton(LOADING);
+		loadingButton.setActionCommand(LOADING);
+		JRadioButton warmingButton = new JRadioButton(WARMING);
+		warmingButton.setActionCommand(WARMING);
+		JRadioButton loadedButton = new JRadioButton(LOADED);
+		loadedButton.setActionCommand(LOADED);
+		
+		loadingButton.addActionListener(this);
+		warmingButton.addActionListener(this);
+		loadedButton.addActionListener(this);
+		
+		loadingButton.setSelected(true);
+		
+		radioButtons.add(loadingButton);
+		radioButtons.add(warmingButton);
+		radioButtons.add(loadedButton);
+		
+		radioBox.add(loadingButton);
+		radioBox.add(Box.createHorizontalStrut(25));
+		radioBox.add(warmingButton);
+		radioBox.add(Box.createHorizontalStrut(25));
+		radioBox.add(loadedButton);
+		
+		Box statusBox = new Box(BoxLayout.Y_AXIS);
+		statusBox.setBorder( BorderFactory.createCompoundBorder(
+								BorderFactory.createTitledBorder("Paramics Status"), 
+								BorderFactory.createEmptyBorder(0, 40, 10, 40) ) );
+		statusBox.add(radioBox);
+		
+		return statusBox;
+	}
+	
+	/** Creates a Camera Status GUI box **/
+	private Box CreateCameraBox()
+	{
+		Box camerasBox = new Box(BoxLayout.Y_AXIS);
+		Box cameraLineBox = new Box(BoxLayout.X_AXIS);
+		
+		for (int i = 1; i <= simulator.getCameras().size(); i++)
+		{
+			Box cameraBox = new Box(BoxLayout.Y_AXIS);
+			cameraBox.setBorder( BorderFactory.createCompoundBorder(
+				BorderFactory.createTitledBorder("Camera " + simulator.getCameras().get(i-1).id), 
+				BorderFactory.createEmptyBorder(0, 5, 10, 5) ) );
+			ButtonGroup radioButtons = new ButtonGroup();
+			
+			JRadioButton fastButton = new JRadioButton(FREE_FLOW);
+			JRadioButton mediumButton = new JRadioButton(SLOW);
+			JRadioButton slowButton = new JRadioButton(STOPPED);
+			slowButton.setSelected(true);
+	
+			fastButton.setActionCommand(FAST_CHARACTER + Integer.toString(i-1));
+			mediumButton.setActionCommand(MEDIUM_CHARACTER + Integer.toString(i-1));
+			slowButton.setActionCommand(SLOW_CHARACTER + Integer.toString(i-1));
+			
+			fastButton.addActionListener(this);
+			mediumButton.addActionListener(this);
+			slowButton.addActionListener(this);
+			
+			radioButtons.add(fastButton);
+			radioButtons.add(mediumButton);
+			radioButtons.add(slowButton);
+			cameraBox.add(fastButton);
+			cameraBox.add(mediumButton);
+			cameraBox.add(slowButton);
+			
+			cameraLineBox.add(cameraBox);
+			cameraLineBox.add(Box.createHorizontalStrut(20));
+			
+			if (i % 3 == 0 && i != simulator.getCameras().size())
+			{
+				camerasBox.add(cameraLineBox);
+				camerasBox.add(Box.createVerticalStrut(15));
+				cameraLineBox = new Box(BoxLayout.X_AXIS);
+			}
+		}
+		camerasBox.add(cameraLineBox);
+		camerasBox.add(Box.createVerticalStrut(15));
+		cameraLineBox = new Box(BoxLayout.X_AXIS);
+		
+		return camerasBox;
+	}
+
+	/** 
+	 * Listens for actions performed in the GUI.
+	 * 
+	 * A Paramics Status action will be either LOADING, WARMING, or LOADED.  If
+	 * recieved, the writeParamicsStatus function will be called from the simulator
+	 * with the appropriate message.
+	 * 
+	 * Any other action is considered a Camera Status Action.  The first character
+	 * of the action command is either FAST_CHARACTER, MEDIUM_CHARACTER, or SLOW_CHARACTER,
+	 * with the remainder of the command being the ID# of the camera.  The writeCameraStatus
+	 * function of the simulator will be called with the appropriate information.
+	 */
+	public void actionPerformed(ActionEvent e) 
+	{
+		String command = e.getActionCommand();
+		if (command == LOADING)
+		{
+			simulator.writeParamicsStatus(NETWORK_STATUS.LOADING);
+		}
+		else if (command == WARMING)
+		{
+			simulator.writeParamicsStatus(NETWORK_STATUS.WARMING);
+		}
+		else if (command == LOADED)
+		{
+			simulator.writeParamicsStatus(NETWORK_STATUS.LOADED);
+		}
+		else // Camera Speed Status
+		{
+			List<SimulationCamera> cameras = simulator.getCameras();
+			SimulationCamera camera = cameras.get(Integer.parseInt(command.substring(1)));
+			
+			if (e.getActionCommand().charAt(0) == FAST_CHARACTER)
+			{
+				camera.averageSpeedNE = camera.averageSpeedSW =
+					((camera.minFreeFlowSpeed + camera.maxFreeFlowSpeed) / 2);
+			}
+			else if (e.getActionCommand().charAt(0) == MEDIUM_CHARACTER)
+			{
+				camera.averageSpeedNE = camera.averageSpeedSW =
+					((camera.minSlowSpeed + camera.maxSlowSpeed) / 2);
+			}
+			else if (e.getActionCommand().charAt(0) == SLOW_CHARACTER)
+			{
+				camera.averageSpeedNE = camera.averageSpeedSW =
+					((camera.minStoppedSpeed + camera.maxStoppedSpeed) / 2);
+			}
+			
+			simulator.writeCameraStatus(cameras);
+		}
+	}
+}
Index: /trunk/src/paramsim/paramicssimulator/gui/ParamicsLogPanel.java
===================================================================
--- /trunk/src/paramsim/paramicssimulator/gui/ParamicsLogPanel.java	(revision 66)
+++ /trunk/src/paramsim/paramicssimulator/gui/ParamicsLogPanel.java	(revision 66)
@@ -0,0 +1,51 @@
+package paramsim.paramicssimulator.gui;
+
+import java.awt.Insets;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+
+/** 
+ * A JPanel which records of a log of errors and messages written or recieved
+ * by the Paramics Simulator.
+ * 
+ * @author Greg Eddington
+ **/
+@SuppressWarnings("serial")
+public class ParamicsLogPanel extends JPanel
+{
+	/** The timestamp format **/
+	private static SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
+	
+	/** The log text area **/
+	private JTextArea log;
+
+	/** Constructor **/
+	public ParamicsLogPanel()
+	{
+		log = new JTextArea();
+		log.setColumns(35);
+		log.setLineWrap(true);
+		log.setRows(24);
+		log.setWrapStyleWord(true);
+		log.setEditable(false);
+		log.setText("");
+		log.setMargin(new Insets(0, 10, 0, 10));
+		JScrollPane logPane = new JScrollPane(log);
+		add(logPane);
+	}
+	
+	/**
+	 * Write a string appended to the end of the log.
+	 * 
+	 * @param message
+	 */
+	public void write(String message)
+	{
+		log.setText(log.getText() + sdf.format(Calendar.getInstance().getTime()) + ":\n" + 
+				message + "\n\n");
+	}
+}
Index: /trunk/src/paramsim/paramicssimulator/gui/ParamicsSimulatorGUI.java
===================================================================
--- /trunk/src/paramsim/paramicssimulator/gui/ParamicsSimulatorGUI.java	(revision 66)
+++ /trunk/src/paramsim/paramicssimulator/gui/ParamicsSimulatorGUI.java	(revision 66)
@@ -0,0 +1,137 @@
+package paramsim.paramicssimulator.gui;
+
+import java.awt.Dimension;
+import java.text.DateFormat;
+import java.util.Observable;
+import java.util.Observer;
+import java.util.logging.Handler;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JFrame;
+import javax.swing.JTabbedPane;
+
+import paramsim.paramicssimulator.ParamicsSimulator;
+import paramsim.paramicssimulator.ParamicsSimulatorLogMessage;
+
+/**
+ * A class which interfaces a ParamicsSimulator.
+ * Contains tabs for the controls, logs for all file IO performed by the Simulator, as well
+ * as an error log.
+ * 
+ * @author Greg Eddington
+ */
+@SuppressWarnings("serial")
+public class ParamicsSimulatorGUI extends JFrame implements Observer
+{	
+	/** The tabs of the GUI **/
+	private JTabbedPane tabs;
+	
+	/** The Paramics Status Panel **/
+	private ParamicsLogPanel paramicsStatusPanel;
+	
+	/** The Camera Status Panel **/
+	private ParamicsLogPanel cameraStatusPanel;
+	
+	/** The Incident Panel **/
+	private ParamicsLogPanel incidentPanel;
+	
+	/** The Error Panel **/
+	private ParamicsLogPanel errorPanel;
+	
+	/** The Paramics Simulator the GUI is interfacing **/
+	private ParamicsSimulator simulator;
+	
+	/**
+	 * Logging handler that writes all received log records to the
+	 * error text area.
+	 * @author Greg Eddington
+	 */
+	protected class ParamicsSimulatorErrorLoggerHandler extends Handler 
+	{
+		DateFormat timeFormat = DateFormat.getTimeInstance();
+		public void close() throws SecurityException {}
+		public void flush() {}
+		public void publish(LogRecord record) { errorPanel.write(record.getMessage()); }		
+	}
+
+	/**
+	 * Creates a new GUI for the Paramics Simulator.
+	 * 
+	 * @param simulator The Simulator to interface
+	 */
+	public ParamicsSimulatorGUI(ParamicsSimulator simulator) 
+	{		
+		super("Paramics Simulator");
+	
+		// Set the logger handler
+		Logger.getLogger("paramsim.paramicssimulator").addHandler(new ParamicsSimulatorErrorLoggerHandler());
+		
+		this.simulator = simulator;
+		
+		initializeGUI();
+	}	
+	
+	/**
+	 * Updates the GUI when something being observed changes.
+	 * 
+	 * If the argument is a ParamicSimulatorLogMessage, switch on which log the message
+	 * is for and update the appropriate log panel.
+	 */
+	public void update(Observable o, Object arg) 
+	{	
+		if(arg instanceof ParamicsSimulatorLogMessage) 
+		{
+			ParamicsSimulatorLogMessage logMessage = (ParamicsSimulatorLogMessage)arg;
+			switch (logMessage.log)
+			{
+				case PARAMICS_STATUS:
+					paramicsStatusPanel.write(logMessage.message);
+					break;
+				case CAMERA_STATUS:
+					cameraStatusPanel.write(logMessage.message);
+					break;
+				case EXCHANGE:
+					incidentPanel.write(logMessage.message);
+					break;
+			}
+		}
+	}
+	
+	/** Initializes the GUI **/
+	public void initializeGUI() 
+	{	
+		// Create tab layout
+		tabs = new JTabbedPane();
+		tabs.setAlignmentX(Box.CENTER_ALIGNMENT);
+		tabs.setMinimumSize(new Dimension(440, 440));
+		tabs.setPreferredSize(new Dimension(440, 440));
+		tabs.setMaximumSize(new Dimension(440, 440));
+		tabs.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+		
+		Box guiBox = new Box(BoxLayout.Y_AXIS);
+		guiBox.add(tabs);
+		add(guiBox);
+	
+		// Add tabs
+		tabs.add("Control", new ParamicsControlPanel(simulator));
+		paramicsStatusPanel = new ParamicsLogPanel();
+		tabs.add("Paramics Status", paramicsStatusPanel);
+		cameraStatusPanel = new ParamicsLogPanel();
+		tabs.add("Camera Status", cameraStatusPanel);
+		incidentPanel = new ParamicsLogPanel();
+		tabs.add("Incidents", incidentPanel);
+		errorPanel = new ParamicsLogPanel();
+		tabs.add("Errors", errorPanel);
+		
+		// Set size
+		setMinimumSize(new Dimension(450, 450));
+		setPreferredSize(new Dimension(450, 450));
+		setResizable(false);
+		pack();
+		setVisible(true);
+	}
+}
Index: /trunk/src/paramsim/paramicssimulator/CameraParser.java
===================================================================
--- /trunk/src/paramsim/paramicssimulator/CameraParser.java	(revision 66)
+++ /trunk/src/paramsim/paramicssimulator/CameraParser.java	(revision 66)
@@ -0,0 +1,201 @@
+package paramsim.paramicssimulator;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import paramsim.paramicssimulator.SimulationCamera.ROAD_DIRECTION;
+
+/**
+ * Creates a list of Simulation Cameras by parsing two configuration files: 
+ * the camera_control file used by Paramics, and the dvdplayers.xml file 
+ * used by the CAD Simulator.
+ * 
+ * @author Greg Eddington
+ */
+public class CameraParser
+{
+	/** Stopped DVD Title **/
+	private static final String STOPPED_TITLE = "3";
+	/** Slow DVD Titlee **/
+	private static final String SLOW_TITLE = "2";
+	/** Free Flow DVD Title **/
+	private static final String FREE_FLOW_TITLE = "1";
+	
+	/**
+	 * Enumeration containing XML tag names used to parse the XML
+	 * document containing information about DVD Cameras.
+	 * @author Matthew Cechini
+	 * @author Greg Eddington
+	 */
+	private static enum CAMERA_TAGS 
+	{	
+		/** Top level tag. */
+		DVD_PLAYERS ("DVD_PLAYERS"),
+		/** DVD player info. */	
+		DVD_PLAYER ("DVD_PLAYER"),
+		/** CCTV camera info. */
+		CCTV         ("CCTV"),
+		/** CCTV camera id. */
+		ID           ("id"),
+		/** CCTV camera direction. */
+		DIRECTION    ("dir"),
+		/** Speed range mapping to a title number. */
+		RANGE        ("RANGE"),
+		/** Minimum speed in a range. */
+		MIN_SPEED    ("min_speed"),
+		/** Maximum speed in a range. */
+		MAX_SPEED    ("max_speed"),
+		/** Title name. */
+		TITLE        ("title");
+		
+		/** XML Tag name. */
+		public String tag;
+		
+		/** Constructor **/
+		private CAMERA_TAGS(String t) { tag = t; }
+	}
+	
+	/**
+	 * Constructor.
+	 */
+	public CameraParser() 
+	{
+	}
+
+	/**
+	 * Parses two input files and creates a list of Simulation Cameras.
+	 * 
+	 * @param dvdPlayersXml The XML file which contains DVD information for the CAD Simulator.
+	 * @param cameraControlFile The camera_control file used by Paramics to map cameras to a simulation.
+	 * @return A list of cameras configured from the parsed files.
+	 * @throws IOException On error reading or parsing one of the files.
+	 */
+	public static List<SimulationCamera> loadCameras(String dvdPlayersXml, String cameraControlFile) 
+		throws IOException
+	{
+		List<SimulationCamera> cameras = new ArrayList<SimulationCamera>();
+		
+		// XML document
+		try
+		{
+			Document newDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
+				.parse(new File(dvdPlayersXml));
+
+			Element rootElement = newDoc.getDocumentElement();		
+			
+			NodeList players   = rootElement.getElementsByTagName(CAMERA_TAGS.DVD_PLAYER.tag);
+			
+			for(int i = 0; i < players.getLength(); i++) 
+			{
+				SimulationCamera camera = new SimulationCamera();
+				
+				Element playerElement = (Element)players.item(i);
+						
+				Element cctvElement = (Element)playerElement.getElementsByTagName(CAMERA_TAGS.CCTV.tag).item(0);
+				camera.id = Integer.parseInt(cctvElement.getAttribute(CAMERA_TAGS.ID.tag));
+				switch(cctvElement.getAttribute(CAMERA_TAGS.DIRECTION.tag).charAt(0))
+				{
+					case 'N':
+						camera.direction = ROAD_DIRECTION.NORTH; 
+						break;
+					case 'E':
+						camera.direction = ROAD_DIRECTION.EAST;
+						break;
+					case 'S':
+						camera.direction = ROAD_DIRECTION.SOUTH;
+						break;
+					default:
+						camera.direction = ROAD_DIRECTION.WEST;
+						break;
+				}
+				
+				NodeList ranges = playerElement.getElementsByTagName(CAMERA_TAGS.RANGE.tag);		
+							
+				for(int j = 0; j < ranges.getLength(); j++) 
+				{
+					Element rangeElement = (Element)ranges.item(j);
+					
+					if (rangeElement.getAttribute(CAMERA_TAGS.TITLE.tag).contains(STOPPED_TITLE))
+					{
+				 		camera.minStoppedSpeed = 
+							Float.parseFloat(rangeElement.getAttribute(CAMERA_TAGS.MIN_SPEED.tag)); 
+						camera.maxStoppedSpeed = 
+							Float.parseFloat(rangeElement.getAttribute(CAMERA_TAGS.MAX_SPEED.tag)); 
+					}
+					else if (rangeElement.getAttribute(CAMERA_TAGS.TITLE.tag).contains(SLOW_TITLE))
+					{
+						camera.minSlowSpeed = 
+							Float.parseFloat(rangeElement.getAttribute(CAMERA_TAGS.MIN_SPEED.tag)); 
+						camera.maxSlowSpeed = 
+							Float.parseFloat(rangeElement.getAttribute(CAMERA_TAGS.MAX_SPEED.tag)); 
+					}
+					else if (rangeElement.getAttribute(CAMERA_TAGS.TITLE.tag).contains(FREE_FLOW_TITLE))
+					{
+						camera.minFreeFlowSpeed = 
+							Float.parseFloat(rangeElement.getAttribute(CAMERA_TAGS.MIN_SPEED.tag)); 
+						camera.maxFreeFlowSpeed = 
+							Float.parseFloat(rangeElement.getAttribute(CAMERA_TAGS.MAX_SPEED.tag)); 
+					}
+				}
+				
+				// Initialize Speed
+				camera.averageSpeedNE = camera.averageSpeedSW =
+					((camera.minStoppedSpeed + camera.maxStoppedSpeed) / 2);
+				
+				cameras.add(camera);
+			}		
+		}
+		catch (ParserConfigurationException pce)
+		{
+			throw new IOException(pce.toString());
+		}
+		catch (SAXException se)
+		{
+			throw new IOException(se.toString());
+		}
+		
+		// Camera Control File
+		Scanner f = new Scanner(new FileReader(cameraControlFile));
+		
+		// Throw away the first line
+		f.nextLine();
+		while (f.hasNextInt())
+		{
+			int id = f.nextInt();
+			
+			for (SimulationCamera camera : cameras)
+			{
+				if (camera.id == id)
+				{
+					// Route
+					camera.route = f.next();
+
+					// Direction
+					f.next();
+					
+					// Postmile
+					camera.postmile = f.nextFloat();
+					
+					break;
+				}
+			}
+			
+			// Ignore the rest
+			f.nextLine();
+		}
+		
+		return cameras;
+	}
+}
Index: /trunk/src/paramsim/paramicssimulator/ParamicsSimulatorLogMessage.java
===================================================================
--- /trunk/src/paramsim/paramicssimulator/ParamicsSimulatorLogMessage.java	(revision 66)
+++ /trunk/src/paramsim/paramicssimulator/ParamicsSimulatorLogMessage.java	(revision 66)
@@ -0,0 +1,36 @@
+package paramsim.paramicssimulator;
+
+/** 
+ * A class which encapsulates a message to a Paramics Simulator log.
+ * Contains both the log the message is intended to be recieved by,
+ * and the message itself.
+ * 
+ * @author Greg Eddington
+ **/
+public class ParamicsSimulatorLogMessage 
+{
+	/** 
+	 * Enumeration of message logs
+	 * @author Greg Eddington
+	 **/
+	public static enum PARAMICS_SIMULATOR_LOG
+	{
+		PARAMICS_STATUS,
+		CAMERA_STATUS,
+		EXCHANGE,
+		ERROR
+	}
+	
+	/** The log message **/
+	public String message;
+	
+	/** The specific log **/
+	public PARAMICS_SIMULATOR_LOG log;
+	
+	/** Constructor **/
+	public ParamicsSimulatorLogMessage(PARAMICS_SIMULATOR_LOG log, String message)
+	{
+		this.message = message;
+		this.log = log;
+	}
+}
Index: /trunk/src/tmcsim/application.properties
===================================================================
--- /trunk/src/tmcsim/application.properties	(revision 65)
+++ /trunk/src/tmcsim/application.properties	(revision 66)
@@ -1,5 +1,5 @@
-#Thu, 16 Mar 2017 08:31:30 -0700
+#Thu, 16 Mar 2017 12:41:52 -0700
 
-Application.revision=64
+Application.revision=65
 
-Application.buildnumber=45
+Application.buildnumber=46
Index: /trunk/src/tmcsim/client/cadclientgui/data/CADData.java
===================================================================
--- /trunk/src/tmcsim/client/cadclientgui/data/CADData.java	(revision 65)
+++ /trunk/src/tmcsim/client/cadclientgui/data/CADData.java	(revision 66)
@@ -233,4 +233,5 @@
             toUnitTableVector.add(units.get(i).toVector());
         }
+        // Exception occurred here: http://pastebin.com/fvifM5i8
         unitStatusTableModel
                 .setDataVector(toUnitTableVector, unitStatusHeaders);
