package usda.weru.weps;

import de.schlichtherle.truezip.file.TFile;
import de.schlichtherle.truezip.file.TFileInputStream;
import de.schlichtherle.truezip.file.TFileOutputStream;
import de.schlichtherle.truezip.file.TFileReader;
import de.schlichtherle.truezip.file.TFileWriter;
import java.util.*;
import javax.swing.*;
import java.beans.*;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import javax.measure.unit.NonSI;
import org.apache.log4j.Logger;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.IllegalDataException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
import org.jscience.geography.coordinates.LatLong;
import usda.weru.gis.GISData;
import usda.weru.gis.GISLookup;
import usda.weru.util.Caster;
import usda.weru.util.ConfigData;
import usda.weru.util.ExceptionEventQueue;
import usda.weru.util.FireAllContext;
import usda.weru.util.LoadingContext;
import usda.weru.util.PropertyStackContext;
import usda.weru.util.RelativeFileContext;
import usda.weru.util.RestoringContext;
import usda.weru.util.Util;
import usda.weru.util.WepsFileChooser;
import usda.weru.util.WepsMessage;
import usda.weru.util.WepsMessageLog;
import usda.weru.weps.location.CligenDataModel;
import usda.weru.weps.location.CligenStation;
import usda.weru.weps.location.ElevationMode;
import usda.weru.weps.location.FileStation;
import usda.weru.weps.location.InterpolatedStation;
import usda.weru.weps.location.Site;
import usda.weru.weps.location.Site.Level0;
import usda.weru.weps.location.StationMode;
import usda.weru.weps.location.Station;
import usda.weru.weps.location.StationUtil;
import usda.weru.weps.location.WindgenDataModel;
import usda.weru.weps.location.WindgenStation;

/**
 * The "Run file Data" class/object manages, accesses, returns and updates data
 * for the WEPS application GUI where data modifications need to be propagated
 * to different screens that have registered their components to be recognized
 * for any property changes that happen.
 *
 */
public class RunFileData implements PropertyChangeListener {

    private static final Logger LOGGER = Logger.getLogger(RunFileData.class);
    private final WepsMessageLog c_log = new WepsMessageLog();

    /**
     *
     */
    protected boolean c_displayMessages = true;

    /**
     *
     */
    public static final double VERSION_WATER_EROSION = 1.01;

    /**
     *
     */
    public static final double VERSION_ROCK_FRAGMENTS = 1.02;

    /**
     *
     */
    public static final double VERSION_LOCPANEL_REWRITE = 1.03;

    /**
     *
     */
    public static final double VERSION_LOCPANEL_SITE = 1.04;

    /**
     *
     */
    public static final double VERSION_RELATIVE_PATHS = 1.05;
    //The current version is written out when a file is saved.

    /**
     *
     */
    public static final double VERSION_CURRENT = VERSION_RELATIVE_PATHS;
    /**
     * All the project files have this extension after the file names i:e file
     * extension to be used.
     */
    public static final String ProjectSuffix = ".wpj";
    /**
     * All the "RUN" files have this extension after their file names i:e file
     * extension to be used.
     */
    public static final String RunSuffix = ".wjr";
    /**
     * The wind generation file's default name with a ".win" extension for the
     * file to be recognized
     */
    public static final String DefaultWinGenName = "win_gen.win";
    /**
     * The climate generation file's default name with a ".cli" extension for
     * the file to be recognized
     */
    public static final String DefaultCliGenName = "cli_gen.cli";
    /**
     *
     */
    public static final String WarningsFile = "warnings.txt";

    /**
     * Default name for the daily submodel name of the Wind file to be used in
     * MCREW.
     */
    public static final String DefaultSubDailyWindName = "none";
    /**
     * Default name for the management file to be used in MCREW.
     */
    public static final String DefaultManageFileName = "none";
    /**
     * Default name for the soil file to be used in SOIL UI.
     */
    public static final String DefaultSoilFileName = "none";
    /**
     * All the IFC Template files are placed in this directory.
     */
    public static final String IFCTemplateDir = "{IFCTemplateDir}";
    /**
     * The name of the directory where the management initializationDatalate
     * files reside.
     */
    public static final String ManTemplateDir = "{ManTemplateDir}";
    /**
     * The name of "RUN" file used for the WEPS run
     */
    public static final String WepsRun = "weps.run";
    /**
     * The WEPS data file used to store all the initialization information for
     * the GUI when it's first executed.
     */
    public static final String WepsData = "weps.ini";
    /**
     * Default name to be assigned to a new project if saved without any name.
     */
    public static final String UntitledProject = "untitled.wpj";
    /**
     * name of the Notes text file used to save management file level notes or
     * notes from the notes section provided in the WEPS screen.
     */
    public static final String NotesFileName = "notes.txt";
    /**
     * Error file name to be used for re-directing the erros codes or messages
     * if any generated.
     */
    public static final String StdErr = "stderr.txt";
    /**
     * The text messages from the standard output such as screns dialogs which
     * need to be saved are directed to this file.
     */
    public static final String StdOut = "stdout.txt";
    /**
     * The output file for the calibration mode parameter for the harvest file.
     */
    public static final String CalibFileName = "harvest_calib_parm.out";
    /**
     * Data file name for the WEPS GUI related stored data
     */
    public static final String WepsOutput = "gui1_data.out";

    /**
     *
     */
    public static final String RFD = "RFD-";
    /**
     * The string used to fire the property changes using this stsndard text as
     * one of the input parameter.
     */
    public static final String FireProperty = RFD + "FireProperty";
    /**
     * The username to be used in the application
     */
    public static final String UserName = RFD + "UserName";
    /**
     * The farm identification number. Often an individual operator will have
     * more than one farm and therefore more than one farm number. It is saved
     * as part of the WEPS Run and appears on the summary and other output
     * reports. This information is not required for a simulation run but may be
     * useful in identifying specific WEPS Runs and output
     */
    public static final String FarmId = RFD + "FarmId";
    /**
     * Often used by FSA and NRCS to identify a field. It is a unit of
     * contiguous land that has both of the following: (1) under one ownership,
     * and (2) operated as a farm or a part of a farm. It is saved as part of a
     * WEPS Run and appears on the summary and other output reports. This
     * information is not required for a simulation run but may be useful in
     * identifying specific WEPS Runs and output.
     */
    public static final String TractId = RFD + "TractId";
    /**
     * The "Field No." is a part of a tract that is separated by permanent
     * boundaries, such as: (1) fences, (2) permanent waterways, (3) woodlands,
     * (4) croplines not subject to change because of farming practices, and (5)
     * other similar features. It is saved as part of the WEPS Run and appears
     * on the summary and other output reports. This information is not required
     * for a simulation run but may be useful in identifying specific WEPS Runs
     * and output
     */
    public static final String FieldId = RFD + "FieldId";
    //public static final String SiteState=RFD + "SiteState";  // still used for weps.run file documentation - LEW
    //public static final String SiteCounty = RFD + "SiteCounty";  // still used for weps.run file documentation - LEW
    /**
     * String that stores the text for the state name in run file data.
     */
    public static final String State = RFD + "StateUpdate";
    /**
     * String that stores the text for the site name in run file data.
     */
    @RunFileDataBeanBridge.BeanProperty(RunFileBean.PROP_SITE)
    public static final String Site = RFD + "Site";
    /**
     * String used to compare against the latitude data usually used to
     * set/modify latitude values.
     */
    //@Deprecated
    public static final String Latitude = RFD + "Latitude";
    /**
     * String used to compare against the latitude sign and if changed is used
     * to re-set/modify that latitude sign values.
     */
    //@Deprecated
    public static final String LatitudeSign = RFD + "LatitudeSign";
    /**
     * String used to coompare against the longitude data usually used to
     * set/modify longitude values.
     */
    //@Deprecated
    public static final String Longitude = RFD + "Longitude";
    /**
     * String used to coompare against the longitude sign and if changed is used
     * to re-set/modify that longitude sign values.
     */
    //@Deprecated
    public static final String LongitudeSign = RFD + "LongitudeSign";
    /**
     * The latitude nad longitude signs and information for their directions.
     */
    @RunFileDataBeanBridge.BeanProperty(RunFileBean.PROP_LATLONG)
    public static final String StrLatLong = RFD + "LatLong";

    /**
     *
     */
    @RunFileDataBeanBridge.BeanProperty(RunFileBean.PROP_ELEVATION_MODE)
    public static final String RFD_ELEVATION_MODE = RFD + "elevation.mode";

    /**
     * THe elevation above sea level for the specified station
     */
    @RunFileDataBeanBridge.BeanProperty(RunFileBean.PROP_ELEVATION)
    public static final String Elevation = RFD + "Elevation";
    /**
     * This string will be "0" (by default) and will be "1" if an alternate
     * Climate File is used - neha
     */
    @RunFileDataBeanBridge.BeanProperty(RunFileBean.PROP_CLIGEN_STATION_MODE)
    public static final String ClimateFlag = RFD + "ClimateFlag";
    /**
     * The selected name of the climate generation station.
     */
    //@Deprecated
    public static final String CliGenStationName = RFD + "CliGenStationName";
    /**
     * Name of the state in which tbis particular climate generation station
     * exists.
     */
    //@Deprecated
    public static final String CliGenState = RFD + "CliGenState";
    /**
     * numeric id of the Climate generation station
     */
    //@Deprecated
    public static final String CliGenStation = RFD + "CliGenStation";

    /**
     *
     */
    @RunFileDataBeanBridge.BeanProperty(RunFileBean.PROP_CLIGEN_STATION)
    public static final String CligenStation = RFD + "cligen.station";	//handled by the mode
    /**
     * This string will be "0" (by default) and will be "1" if an alternate Wind
     * File is used - neha
     */
    @RunFileDataBeanBridge.BeanProperty(RunFileBean.PROP_WINDGEN_STATION_MODE)
    public static final String WindFlag = RFD + "WindFlag";
    /**
     * Name of the Wind generation station
     */
    //@Deprecated
    public static final String WindGenStationName = RFD + "WindGenStationName";
    /**
     * Numeric id of the Wind generation station
     */
    //@Deprecated
    public static final String WinGenStation = RFD + "WinGenStation";

    /**
     *
     */
    @RunFileDataBeanBridge.BeanProperty(RunFileBean.PROP_WINDGEN_STATION)
    public static final String WindgenStation = RFD + "windgen.station";  //handled by the mode
    /**
     * The date from which you want the simulation to begin.
     */
    public static final String StartDate = RFD + "StartDate";
    /**
     * The date on which you want the simulation to end.
     */
    public static final String EndDate = RFD + "EndDate";
    /**
     * The number of years in which the crop cycle needs to be rotated.
     */
    public static final String RotationYears = RFD + "RotationYears";
    /**
     * The current count before the cycle is started over again.
     */
    public static final String CycleCount = RFD + "CycleCount";
    /**
     * The steps in which you can increment the time interval.
     */
    public static final String TimeSteps = RFD + "TimeSteps";
    //public static final String CliGen				= RFD + "CliGen";
    //public static final String WinGen				= RFD + "WinGen";
    //public static final String SubDaily			= RFD + "SubDaily";
    /**
     * The name of the current SOIL file selected.
     */
    public static final String SoilFile = RFD + "SoilFile";
    /**
     * The name of the current management file selected.
     */
    public static final String ManageFile = RFD + "ManageFile";
    /**
     * The name of the current output file.
     */
    public static final String OutputFile = RFD + "OutputFile";
    /**
     * The name of the report form.
     */
    public static final String ReportForm = RFD + "ReportForm";
    /**
     * Tells when the output period is.
     */
    public static final String OutputPeriod = RFD + "OutputPeriod";
    /**
     * Tells what the submodel output is.
     */
    public static final String SubmodelOutput = RFD + "SubmodelOutput";
    /**
     * Tells what the debug output is.
     */
    public static final String DebugOutput = RFD + "DebugOutput";
    /**
     * Value used for calculated SCI.
     */
    public static final String WaterErosionLoss = RFD + "WaterErosionLoss";
    /**
     * Value used to overide soil layer rock fragments
     */
    public static final String SoilRockFragments = RFD + "SoilRockFragments";
    /**
     * Indicates the simulation region angle assigned.
     */
    public static final String RegionAngle = RFD + "RegionAngle";
    private static final String SimPoint1 = RFD + "SimPoint1";
    private static final String SimPoint2 = RFD + "SimPoint2";
    private static final String Scales = RFD + "Scales";
    private static final String AccNo = RFD + "AccNo";
    private static final String AccPoint1 = RFD + "AccPoint1";
    private static final String AccPoint2 = RFD + "AccPoint2";
    private static final String SubregionNo = RFD + "SubregionNo";
    private static final String SubPoint1 = RFD + "SubPoint1";
    private static final String SubPoint2 = RFD + "SubPoint2";
    /**
     * The average slope of the field/area in study.
     */
    public static final String AverageSlope = RFD + "AverageSlope";
    private static final String BarrierNo = RFD + "BarrierNo";
    /**
     * The string used to compare and identify for something with barrier panel.
     */
    public static final String Barrier = RFD + "Barrier";
    /**
     * The string used to compare and identify north barrier for
     * selection/de-selection.
     */
    public static final String BarrierN = RFD + "BarrierN";
    /**
     * The string used to compare and identify west barrier for
     * selection/de-selection.
     */
    public static final String BarrierW = RFD + "BarrierW";
    /**
     * The string used to compare and identify south barrier for
     * selection/de-selection.
     */
    public static final String BarrierS = RFD + "BarrierS";
    /**
     * The string used to compare and identify east barrier for
     * selection/de-selection.
     */
    public static final String BarrierE = RFD + "BarrierE";
    /**
     * The string used to compare and identify none barrier for
     * selection/de-selection.
     */
    public static final String BarrierD = RFD + "BarrierD";
    /**
     * Area of the simulation region in the units of measure displayed on the
     * screen (acres or hectares) based upon the "X" length and "Y" length
     * values. X-Length happens to be the breadth of the field.
     */
    public static final String XLength = RFD + "XLength";
    /**
     * Area of the simulation region in the units of measure displayed on the
     * screen (acres or hectares) based upon the "X" length and "Y" length
     * values. Y-Length happens to be the length of the field.
     */
    public static final String YLength = RFD + "YLength";
    /**
     * Shape of the simulation region.
     */
    public static final String Shape = RFD + "Shape";
    /**
     * Shape of the simulation region.
     */
    public static final String Radius = RFD + "Radius";
    /**
     * The name of the wind file.
     */
    //@Deprecated
    public static final String WindFile = RFD + "wind file";
    /**
     * The name of the climate file.
     */
    //@Deprecated
    public static final String ClimateFile = RFD + "climate file";
    /**
     * The name of the sub-daily file.
     */
    public static final String SubDailyFile = RFD + "sub-daily file";
    /**
     * Number of years for which the simulation needs to be carried out.
     */
    public static final String TotalYears = RFD + "TotalYears";
    /**
     * The notes files name.
     */
    public static final String NotesFile = RFD + "NotesFile";
    /**
     * The text that goes into the notes file and in the notes text area of the
     * GUI like additional information regarding the current WEPS run which the
     * user wishes to record.
     */
    @RunFileDataBeanBridge.BeanProperty(RunFileBean.PROP_NOTES)
    public static final String NotesText = RFD + "NotesText";

    /**
     *
     */
    public static final String NotesReadonly = RFD + "NotesReadOnly";
    /**
     * String used to identify the run type to be displayed.
     */
    public static final String RunTypeDisp = RFD + "runtypedisp";
    /**
     * Tells the user what the last WEPS run was by storing its name.
     */
    public static final String LastRun = RFD + "lastrun";
    /**
     * Tells the location for storing runs.
     */
    public static final String RunsLocation = RFD + "runs location";
    /**
     * Most recent run atinitializationDatat
     */
    public static final String LastRunAttempt = RFD + "last run attempt";
    /**
     * Used to identify the instance of data changed on the panel registerd to
     * react.
     */
    public static final String DataChanged = "DataChanged " + RFD;
    /**
     * The data from "weps.ini" file which is the hash table containing the
     * details of Project.
     */
    public static final String WriteRunData = "WriteRunData";
    /**
     * The "weps.ini" file which contains the hash table containing the details
     * of Project.
     */
    public static final String WriteRunFile = "WriteRunFile";
    /**
     * The data to be read for the WEPS run usually from the weps.ini file or
     * from the hashtable that stores it.
     */
    public static final String ReadRunData = "ReadRunData";
    /**
     * The file that contains this WEPS run data is called the readrunfile.
     */
    public static final String ReadRunFile = "ReadRunFile";
    /**
     * The WEPS run data that gets the request to be shown.
     */
    public static final String ShowRunData = "ShowRunData";
    /**
     * Fired before and after fireAll(). 1 = before, 2 = after
     */
    public static final String LoadData = "LoadData";

    /**
     *
     */
    public static final String ResetBarriers = "reset barriers";

    public SubmodelOutput so = new SubmodelOutput(ConfigData.getDefault());

    /**
     * Hashtable used to store weps.run file data internally
     */
    Hashtable<String, String> ht = new Hashtable<>(200);
    // Jan 31 02 dkm no current man ===> zero years, ERRATA01
    // May 09 02
    private String curProj = "";
    private String NRCSRunLen = "";
    // This variable is to store the elevation of the Restore Run
    private String restoreRunElevation = "";

    /**
     *
     */
    public TFile fileObject = null;

    /**
     * This methods reads the data from the WEPS.ini file and shows it. Errors
     * will be shown in a WepsMessageDialog
     *
     * @param pathName The path where this file resides on the system.
     */
    public RunFileData(String pathName) {
        this(pathName, true);
    }

    /**
     * This method reads the data from the WEPS.ini file and shows it.
     *
     * @param pathName The path where this file resides on the system.
     * @param displayMessages If true, errors and warnings will be displayed in
     * a WepsMessageDialog.
     */
    public RunFileData(String pathName, boolean displayMessages) {
        c_displayMessages = displayMessages;
        readRunFile(pathName);
    }

    /**
     * Initializes the WEPS RUN data.
     */
    public RunFileData() {
        this(false);
    }

    /**
     *
     * @param initialize
     */
    public RunFileData(boolean initialize) {
        if (initialize) {
            initialize();
        }
    }

    /**
     * Entry point for testing standalone. Used if this dialog is rum as an
     * independent application. If executed, makes the GUI for Simulation Region
     * panel visible.
     *
     * @param args These are the command line arguments passed to the main
     * method.
     */
    static public void main(String args[]) {
        WepsFileChooser wfc = new WepsFileChooser(WepsFileChooser.Filetype.PROJECT, "",
                WepsFileChooser.OPEN);
        // initializationData testing fix
        wfc.setCurrentDirectory(new de.schlichtherle.truezip.file.TFile("h:/weps/weps.install/projects"));

        RunFileData rfd = new RunFileData();
        if (wfc.showDialog(null) == JFileChooser.APPROVE_OPTION) {
            de.schlichtherle.truezip.file.TFile sf = new TFile(wfc.getSelectedFile());
            String projectsDir = "";
            try {
                projectsDir = sf.getCanonicalPath();
            } catch (IOException e) {
            }//System.err.println(
            //      "Error getting canoncial path of projectsDir");}

            rfd.readRunData(projectsDir);
        } else {
            rfd.initialize();
        }
        rfd.showRunFileData("Standalone test");
        System.exit(1);
    }

    /**
     * This is the method where all the WEPS main GUI initialization takes place
     * with the default dataset used for initial display.
     */
    public void initialize() {

        setData(RunTypeDisp, ConfigData.getDefault().getData(ConfigData.DefaultRunMode));

        setData(UserName, "");
        setData(FarmId, "");
        setData(TractId, "");
        setData(FieldId, "");

        getBean().setSite(usda.weru.weps.location.Site.valueOf("fips:US00-KS-055"));

        setData(StrLatLong, "+37.73835;-100.43785");

        ////default to the cligen mode, only one working at the moment.
        getBean().setElevationMode(ElevationMode.Cligen);

        setData(Elevation, "801.0");
        setData(CliGenState, "");
        setData(CliGenStation, "");
        setData(StartDate, "01 01 2001");
        setData(EndDate, "31 12 2001");
        setData(RotationYears, "1");
        setData(CycleCount, "50");
        setData(TotalYears, "6");
        setData(TimeSteps, "24");
        setData(SubDailyFile, DefaultSubDailyWindName);
        setData(SoilFile, DefaultSoilFileName);
        setData(ManageFile, DefaultManageFileName);
        setData(ReportForm, "0 0 0 0 0 0");
        setData(OutputPeriod, "2");
        //setData(SubmodelOutput, "0 0 0 0 0 0");
        //setData(DebugOutput, "0 0 0 0 0 0");
        setData(RegionAngle, "0");
        setData(SimPoint1, "100.0 100.0");
        setData(SimPoint2, "904.7 904.7");
        setData(Scales, "10.0 0.25");
        setData(AccNo, "1");
        setData(AccPoint1, "100.0 100.0");
        setData(AccPoint2, "904.7 904.7");
        setData(SubregionNo, "1");
        setData(SubPoint1, "100.0 100.0");
        setData(SubPoint2, "904.7 904.7");

        //A negative slope is ignored by WEPS
        setData(AverageSlope, "-1");
        changes.firePropertyChange(ResetBarriers, null, null);
        setData(BarrierNo, "0");
        setData(BarrierN, "none|0.0|0.0|0.0");
        setData(BarrierS, "none|0.0|0.0|0.0");
        setData(BarrierE, "none|0.0|0.0|0.0");
        setData(BarrierW, "none|0.0|0.0|0.0");

        getBean().setCligenStationMode(StationMode.NRCS);
        getBean().setWindgenStationMode(StationMode.NRCS);
        setData(CliGenStationName, "CIMARRON");
        setData(CliGenState, "14");
        setData(CliGenStation, "1522");
        setData(NotesReadonly, "0");
        setData(NotesFile, NotesFileName);
        setData(NotesText, "", false);  // The "\n" is getting stripped off so text appended is not starting on a
        // new line - this is a quick fix - LEW
        //1148, added added false value so the string is not trimmed.

        setData(Shape, "rectangle");
        setData(Radius, "0");
        setData(LastRunAttempt, "");
        //Defaults to the config value
        if (!RestoringContext.isRestoring()) {
            setData(RunsLocation, ConfigData.getDefault().getData(ConfigData.DefaultRunsLocation));
        }
        setData(WaterErosionLoss, "0.00");

        setData(SoilRockFragments, "-1");

        fixUpData();
        changes.firePropertyChange(DataChanged, null, "xxx");

    }

    /**
     *
     * @param idxstr
     * @return
     */
    public String getData(String idxstr) {
        return ht.get(idxstr);
    }

    /**
     *
     * @param idxstr
     * @param newData
     * @param trimNewData
     */
    public void setData(final String idxstr, String newData, boolean trimNewData) {

        PropertyStackContext.enter(this, idxstr);
        try {
            String oldData;

            if (idxstr.equals(FireProperty)) {
                oldData = ht.get(newData);
                changes.firePropertyChange(newData, null, oldData);
                return;
            }

            if (newData == null) {
                oldData = ht.get(idxstr);
                ht.remove(idxstr);
            } else {
                if (trimNewData) {
                    newData = newData.trim();      //1148, only trim when told to.
                }
                oldData = ht.get(idxstr);
                if (newData.equals(oldData)) {
                    return;
                }
                ht.put(idxstr, newData);
            }

            changes.firePropertyChange(idxstr, oldData, newData);
            changes.firePropertyChange(DataChanged, null, DataChanged);
        } finally {
            PropertyStackContext.exit(this, idxstr);
        }

    }

    //1148, overiding method to pass a default true for trimNewData
    /**
     *
     * @param idxstr
     * @param newData
     */
    public void setData(String idxstr, String newData) {
        setData(idxstr, newData, true);
    }

    /**
     *
     */
    public void fireAll() {
        FireAllContext.enter();
        try {
            Enumeration<String> e = ht.keys();
            changes.firePropertyChange(DataChanged, null, "fireall");
            changes.firePropertyChange(LoadData, null, "1");

            while (e.hasMoreElements()) {
                String key = e.nextElement();
                String value = ht.get(key);

                changes.firePropertyChange(key, null, value);
            }

            changes.firePropertyChange(DataChanged, null, "fireall");
            changes.firePropertyChange(LoadData, null, "2");
        } finally {
            FireAllContext.exit();
        }

    }

    /**
     *
     * @param listeners
     */
    public void fireAll(PropertyChangeListener... listeners) {
        FireAllContext.enter();
        try {
            Enumeration<String> e = ht.keys();

            for (PropertyChangeListener listener : listeners) {
                PropertyChangeEvent event1 = new PropertyChangeEvent(this, DataChanged, null, "fireall");
                PropertyChangeEvent event2 = new PropertyChangeEvent(this, LoadData, null, 1);
                listener.propertyChange(event1);
                listener.propertyChange(event2);

            }
            while (e.hasMoreElements()) {
                String key = e.nextElement();
                String value = ht.get(key);
                PropertyChangeEvent event = new PropertyChangeEvent(this, key, null, value);
                for (PropertyChangeListener listener : listeners) {
                    listener.propertyChange(event);
                }
            }

            for (PropertyChangeListener listener : listeners) {
                PropertyChangeEvent event1 = new PropertyChangeEvent(this, DataChanged, null, "fireall");
                PropertyChangeEvent event2 = new PropertyChangeEvent(this, LoadData, null, 2);
                listener.propertyChange(event1);
                listener.propertyChange(event2);
            }
        } finally {
            FireAllContext.exit();
        }
    }

    private String getLine(BufferedReader in) throws IOException {
        String temp;
        while ((temp = in.readLine()) != null) {
            if (temp.length() == 0) {
                return temp;
            }
            if (temp.charAt(0) != '#') {
                return temp;
            }
        }
        return null;
    }

    /**
     * Sets the integer value to the rotation year's attribute from the
     * management file provided as an argument path where it exists on the
     * system.
     *
     * @param manageFile The management file that stores this integer value that
     * is used for setting.
     */
    // throws a warning when we manually close 'in'.
    @SuppressWarnings("try")
    public void setRotationYears(String manageFile) {
        //We need to have a file to work with.
        if (manageFile == null || manageFile.equals("none") || manageFile.length() == 0) {
            return;
        }

        try (BufferedReader in = new BufferedReader(new TFileReader(
                new TFile(manageFile)))) {
            String temp;
            while ((temp = in.readLine()) != null) {
                if (temp.startsWith("*START")) {
                    StringTokenizer st = new StringTokenizer(temp);
                    st.nextToken();
                    String rotationYears = st.nextToken().trim();
                    in.close();
                    setData(RunFileData.RotationYears, rotationYears);
                    changes.firePropertyChange(RunFileData.RotationYears, null, rotationYears);
                    return;
                }
            }

            //System.err.println("RFD_sRY: '*START' not found in management file");
            changes.firePropertyChange(RunFileData.RotationYears, null, "1");

        } catch (IOException e) {
            //System.err.println("RFD_sRY: " + e);
        }
    }

    private void readRunFileBarriers(BufferedReader in) throws java.io.IOException {
        //Awful hack to get the draw field to work. TODO
        changes.firePropertyChange(ResetBarriers, null, null);

        //Initially set all the barrier data to "none"
        setData(BarrierN, "none|0.0|0.0|0.0");
        setData(BarrierS, "none|0.0|0.0|0.0");
        setData(BarrierE, "none|0.0|0.0|0.0");
        setData(BarrierW, "none|0.0|0.0|0.0");

        String temp = getLine(in);
        int barrierNo = new Integer(temp.trim());
        // throw away dummy barrier
        if (barrierNo == 0) {

            for (int jdx = 0; jdx < 6; jdx++) {
                getLine(in);
            }
            return;
        }
        String temp1 = getData(SimPoint1);
        String temp2 = getData(SimPoint2);
        StringTokenizer st = new StringTokenizer(temp1, " ");
        String rx1 = st.nextToken();
        double Rx1 = Double.parseDouble(rx1);
        String ry1 = st.nextToken();
        double Ry1 = Double.parseDouble(ry1);
        st = new StringTokenizer(temp2, " ");
        String rx2 = st.nextToken();
        double Rx2 = Double.parseDouble(rx2);
        String ry2 = st.nextToken();
        double Ry2 = Double.parseDouble(ry2);

        for (int idx = 0; idx < barrierNo; idx++) {
            String line = getLine(in);
            st = new StringTokenizer(line, "| ");
            String bx1 = st.nextToken();
            double Bx1 = Double.parseDouble(bx1);
            String by1 = st.nextToken();
            double By1 = Double.parseDouble(by1);
            line = getLine(in);
            st = new StringTokenizer(line, "| ");
            String bx2 = st.nextToken();
            double Bx2 = Double.parseDouble(bx2);
            String by2 = st.nextToken();
            double By2 = Double.parseDouble(by2);
            StringBuilder sb = new StringBuilder(getLine(in).trim());
            for (int jdx = 0; jdx < 3; jdx++) {
                sb.append("|");
                sb.append(getLine(in).trim());
            }
            line = sb.toString();
            //    //System.out.println("readRunFileBarriers: Rx1:"+Rx1+"  Bx1:"+Bx1+"  Rx2:"+Rx2+"  Bx2:"+Bx2);
            //    //System.out.println("readRunFileBarriers: Ry1:"+Ry1+"  By1:"+By1+"  Ry2:"+Ry2+"  By2:"+By2);
            //		if (bx2.equals(rx1)) {
            if ((Ry1 == By1 && Ry2 == By2) || (Ry1 == By2 && Ry2 == By1)) {
                if (Rx1 == Bx1 || Rx1 == Bx2) {
                    setData(BarrierW, line);
                    //			} else if (bx1.equals(rx2)) {
                } else if (Rx2 == Bx1 || Rx2 == Bx2) {
                    setData(BarrierE, line);
                } else {
                    c_log.logMessage(WepsMessage.warningMessage("Unknown Barrier Position 1 " + line
                            + " field-bx1:" + bx1 + "   bx2:" + bx2 + "   by1:" + by1 + "  by2:" + by2
                            + " barrier-rx1: " + rx1 + "   rx2:" + rx2 + "  ry1:" + ry1 + "  ry2:" + ry2));
//                    //System.err.println("RFD_rDFB: unknown barrier position 1 " + line +
//                            " field-bx1:" + bx1 + "   bx2:" + bx2 + "   by1:" + by1 + "  by2:" + by2 +
//                            " barrier-rx1: " + rx1 + "   rx2:" + rx2 + "  ry1:" + ry1 + "  ry2:" + ry2);
                }
            } else if ((Rx1 == Bx1 && Rx2 == Bx2) || (Rx1 == Bx2 && Rx2 == Bx1)) {
//			} else if (by2.equals(ry1)) {
                if (Ry1 == By1 || Ry1 == By2) {
                    setData(BarrierS, line);

//			} else if (by1.equals(ry2)) {
                } else if (Ry2 == By1 || Ry2 == By2) {
                    setData(BarrierN, line);
                } else {
                    c_log.logMessage(WepsMessage.warningMessage("Unknown Barrier Position 2 " + line
                            + " field-bx1:" + bx1 + "   bx2:" + bx2 + "   by1:" + by1 + "  by2:" + by2
                            + " barrier-rx1: " + rx1 + "   rx2:" + rx2 + "  ry1:" + ry1 + "  ry2:" + ry2));

//                    //System.err.println("RFD_rDFB: unknown barrier position 2 " + line +
//                            " field-bx1:" + bx1 + "   bx2:" + bx2 + "   by1:" + by1 + "  by2:" + by2 +
//                            " barrier-rx1: " + rx1 + "   rx2:" + rx2 + "  ry1:" + ry1 + "  ry2:" + ry2);
                }
            } else {
                c_log.logMessage(WepsMessage.warningMessage("Unknown Barrier Position 3 " + line
                        + " field-bx1:" + bx1 + "   bx2:" + bx2 + "   by1:" + by1 + "  by2:" + by2
                        + " barrier-rx1: " + rx1 + "   rx2:" + rx2 + "  ry1:" + ry1 + "  ry2:" + ry2));
//                //System.err.println("RFD_rDFB: unknown barrier position 3 " + line +
//                        " field-bx1:" + bx1 + "   bx2:" + bx2 + "   by1:" + by1 + "  by2:" + by2 +
//                        " barrier-rx1: " + rx1 + "   rx2:" + rx2 + "  ry1:" + ry1 + "  ry2:" + ry2);
            }
        }

    }

    private void readNotesFile(String runFilePathName) {
        String temp = "";
        StringBuilder sb = new StringBuilder();
        TFile file = new TFile(runFilePathName, NotesFileName);
        BufferedReader in = null;
        try {
            in = new BufferedReader(new TFileReader(file));
            while ((temp = in.readLine()) != null) {
                sb.append(temp.trim() + "\n");
            }
        } catch (IOException e) {
            LOGGER.warn("Error while reading notes file. " + file.getPath());
            JOptionPane.showMessageDialog(null, "Notes file unreadable.",
                    "Notes Warning", JOptionPane.WARNING_MESSAGE);
            setData(NotesText, "");
            return;
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                LOGGER.error("Error closing stream. " + file.getPath(), e);
            }
        }
        setData(NotesText, sb.toString());
    }
    private static final String VERSION_MARKER = "#VERSION=";

    /**
     * This method reads the data in the RUN file meant for the GUI
     * initialization from the existing set of values and makes it visible on
     * the respective components of the interface.
     *
     * @param runFilePathName The system path to the RUN file from where this
     * data is retrieved.
     */
    static boolean lockMessage = true;

    void setLockMessage(boolean bool) {
        lockMessage = bool;
    }

    boolean getLockMessage() {
        return lockMessage;
    }

    static ArrayList<String> currentRanFiles = new ArrayList<>();

    public void readRunFile(String runFilePathName) {

        if (currentRanFiles.contains(runFilePathName)) {
            //System.out.println("run contained: " + runFilePathName);
            //System.out.println("run no longer eligible for error message");
        } else {
            currentRanFiles.add(runFilePathName);
            setLockMessage(true);
        }

        LoadingContext.enter();
        RelativeFileContext.enter(new TFile(runFilePathName));
        initialize();
        clearBean();
        try {
            //getBean().setLoading(true);
            c_log.clear();

            BufferedReader in = null;
            try {
                fileObject = new TFile(runFilePathName, WepsRun);
                if (!fileObject.exists()) {
                    LOGGER.warn("Run File \"" + fileObject.getAbsolutePath() + "\" does not exist.");
                    return;
                }
                in = new BufferedReader(new TFileReader(fileObject));
                double version = 1.00;  //Default when the version of the file is not included.

                String firstLine = in.readLine();
                if (firstLine == null) {
                    return;
                }
                firstLine = firstLine.trim();
                if (firstLine.startsWith(VERSION_MARKER)) {
                    firstLine = firstLine.replace(VERSION_MARKER, "");
                    version = Double.parseDouble(firstLine);
                }
                String tmp;
                tmp = getLine(in);
                if (tmp.length() > 65) {
                    setData(UserName, tmp.substring(0, 64));
                } else {
                    setData(UserName, tmp);
                }
                {
                    String temp = getLine(in);
                    StringTokenizer st = new StringTokenizer(temp, "|");
                    if (st.countTokens() < 3) {
                        if (temp.length() > 10) {
                            setData(FarmId, temp.substring(0, 9));
                        } else {
                            setData(FarmId, temp);
                        }
                        setData(TractId, "");
                        setData(FieldId, "");
                        setData(RunFileData.RunTypeDisp, ConfigData.Dates);
                        //					changes.firePropertyChange(RunFileData.RunTypeDisp, RunType,
                        //										 ConfigData.Dates);
                    } else if (st.countTokens() == 3) {
                        tmp = st.nextToken().trim();
                        if (tmp.length() > 10) {
                            setData(FarmId, tmp.substring(0, 9));
                        } else {
                            setData(TractId, tmp);
                        }
                        tmp = st.nextToken().trim();
                        if (tmp.length() > 10) {
                            setData(FieldId, tmp.substring(0, 9));
                        } else {
                            setData(FieldId, tmp);
                        }
                        tmp = st.nextToken().trim();
                        if (tmp.length() > 10) {
                            setData(FieldId, tmp.substring(0, 9));
                        } else {
                            setData(FieldId, tmp);
                        }
                        setData(RunFileData.RunTypeDisp, ConfigData.Dates);
                        //					changes.firePropertyChange(RunFileData.RunTypeDisp, RunType,
                        //										 st.nextToken().trim());

                        //					setData(RunFileData.RunTypeDisp, type);
                    } else {
                        //					try {
                        String tm = st.nextToken().trim();
                        if (tm.length() > 10) {
                            setData(FarmId, tm.substring(0, 9));
                        } else {
                            setData(FarmId, tm);
                        }
                        tm = st.nextToken().trim();
                        if (tm.length() > 10) {
                            setData(TractId, tm.substring(0, 9));
                        } else {
                            setData(TractId, tm);
                        }
                        tm = st.nextToken().trim();
                        if (tm.length() > 10) {
                            setData(FieldId, tm.substring(0, 9));
                        } else {
                            setData(FieldId, tm);
                        }
                        String type = st.nextToken().trim();
                        setData(RunFileData.RunTypeDisp, type);
                        setData(RotationYears, st.nextToken());
                        setData(CycleCount, st.nextToken());
                        //					} catch (ArrayIndexOutOfBounds e) {
                        //						//System.err.println("RFD_rRF: too few tokens in id line (should be 6) " +
                        //										   initializationData);
                        //					}
                    }
                }

                String siteString = getLine(in);
                if (version < VERSION_LOCPANEL_SITE) {
                    //old site format
                    usda.weru.weps.location.Site<?> site = upgradeSiteString(siteString);
                    setData(Site, site != null ? site.toString() : siteString);
                } else {
                    setData(Site, siteString);
                }

                {
                    //String initializationData = getLine(in);
                    //setData(LatitudeSign, initializationData.startsWith("-") ? "-" : "+");
                    // Added below code for second conditional statement 01/16/2004
                    //setData(Latitude, initializationData.substring(initializationData.startsWith("-") ? 1
                    //: ( initializationData.startsWith("+") ? 1 : 0 ) ));
                    //temp = getLine(in);
                    //setData(LongitudeSign, initializationData.startsWith("-") ? "-" : "+");
                    // Added below code for second conditional statement 01/16/2004
                    //setData(Longitude, initializationData.substring(initializationData.startsWith("-") ? 1
                    //: ( initializationData.startsWith("+") ? 1 : 0 ) ));
                    String latStr = getLine(in);
                    String longStr = getLine(in);
                    setData(StrLatLong, latStr.trim() + ";" + longStr.trim());
                    LatLong latlong = LatLong.valueOf(Double.parseDouble(latStr), Double.parseDouble(longStr), NonSI.DEGREE_ANGLE);
                    GISLookup<Site<?>> lookup
                            = GISData.getInstance().<Site<?>>getLookup(Caster.<Class<Site<?>>>cast(Site.class));
                    List<Site<?>> results = lookup.lookup(latlong);

                    if (results.size() > 0) {
                        Comparator<Site<?>> c = new Site.LevelComparator();
                        Collections.sort(results, c);
                        Site<?> mostDetail = results.get(results.size() - 1);
                        String FIPS = mostDetail.getFIPSCode();
                        if (FIPS.substring(0, 2).equals("US")) {
                            String[] FIPSSplit = FIPS.split("_");
                            FIPS = "FIPS:" + FIPSSplit[0] + "-" + FIPSSplit[2];
                        } else {
                            FIPS = "FIPS:" + FIPS;
                        }
                        if (getLockMessage()) {
                            String[] currentRun = runFilePathName.split("\\\\", -1);
                            int runName = currentRun.length - 1;
                            //System.out.println("checking current run:");
                            //System.out.println(currentRun[runName]);
                            //System.out.println("******* checking FIPS.equals(siteString) *******");
                            setLockMessage(false);
                            if (!FIPS.equals(siteString)) {
                                //set lock to only print unadded runfilepath
                                JOptionPane.showMessageDialog(null, "Site information didn't match Latitude Longitude.\n"
                                        + "Latitude Longitude overriding the site information.",
                                        "Location Warning", JOptionPane.WARNING_MESSAGE);
                                setData(Site, FIPS);

                            }
                        }
                    } else {
                    }
                }

                // This string is used to store the value of the Run's elevation value
                restoreRunElevation = getLine(in);
                setData(Elevation, restoreRunElevation);

                if (version >= VERSION_LOCPANEL_REWRITE) {
                    //new format delegated to StationModeHandlers
                    //cligen
                    String cligenLine = getLine(in);
                    int cligenModeIndex = cligenLine.indexOf("|");
                    String cligenModeText = cligenLine.substring(0, cligenModeIndex);
                    String cligenText = cligenLine.length() > cligenModeIndex
                            ? cligenLine.substring(cligenModeIndex + 1) : null;

                    StationMode cligenMode = StationMode.parse(cligenModeText);
                    Station cligenStation = StationUtil.deserializeStation(cligenText);

                    getBean().setCligenStationMode(cligenMode);
                    getBean().setCligenStation(cligenStation);

                    //windgen
                    String windgenLine = getLine(in);
                    int windgenModeIndex = windgenLine.indexOf("|");
                    String windgenModeText = windgenLine.substring(0, windgenModeIndex);
                    String windgenText = windgenLine.length() > windgenModeIndex
                            ? windgenLine.substring(windgenModeIndex + 1) : null;

                    StationMode windgenMode = StationMode.parse(windgenModeText);
                    Station windgenStation = StationUtil.deserializeStation(windgenText);

                    getBean().setWindgenStationMode(windgenMode);
                    getBean().setWindgenStation(windgenStation);

                } else {
                    //Handle the old station format, only supports choice (0) or file (1) or interpolated for windgen
                    //cligen                    
                    try {
                        String cligenLine = getLine(in);
                        String cligenParts[] = cligenLine.split("\\|");
                        StationMode cligenMode = StationMode.parse(cligenParts[3]);

                        getBean().setCligenStationMode(cligenMode);

                        if (StationMode.Choice == cligenMode) {
                            //choice station
                            String name = cligenParts[0];
                            long id = Long.valueOf(cligenParts[1].trim());
                            long state = Long.valueOf(cligenParts[2].trim());
                            CligenStation station = CligenDataModel.getInstance().getStation(state, id);
                            if (station == null) {
                                LOGGER.warn("Unable to find cligen record in database. State: " + state + ", Id: " + id);
                                station = new CligenStation(name, state, id);
                            }

                            getBean().setCligenStation(station);

                        } else if (StationMode.File == cligenMode) {
                            //file station
                            String name = cligenParts[0];
                            TFile file = new TFile(runFilePathName, name);
                            FileStation station = new FileStation(file);
                            getBean().setCligenStation(station);

                        } else {
                            //really not supposed to get here.
                        }
                    } catch (IOException | NumberFormatException e) {
                        LOGGER.warn("Unable to read old cligen station.", e);
                        getBean().setCligenStation(null);
                    }

                    //windgen                    
                    try {
                        String windgenLine = getLine(in);
                        String windgenParts[] = windgenLine.split("\\|");
                        StationMode windgenMode = StationMode.parse(windgenParts[2]);

                        getBean().setWindgenStationMode(windgenMode);

                        if (StationMode.Choice == windgenMode) {
                            //choice station
                            String name = windgenParts[0];
                            if (windgenParts[1].startsWith("I~")) {
                                //this was an interpolated station
                                getBean().setWindgenStationMode(StationMode.Interpolated);
                                getBean().setWindgenStation(new InterpolatedStation(getBean().getLatLong()));
                            } else {
                                long id = Long.valueOf(windgenParts[1].trim());
                                WindgenStation station = WindgenDataModel.getInstance().getStation(id);
                                if (station == null) {
                                    LOGGER.warn("Unable to find windgen record in database. Id: " + id);
                                    station = new WindgenStation(null, id, null, null, name);
                                }
                                getBean().setWindgenStation(station);
                            }

                        } else if (StationMode.File == windgenMode) {
                            //file station
                            String name = windgenParts[0];
                            name = name != null ? name.trim() : name;
                            if ("Interpolated".equalsIgnoreCase(name)) {
                                //handle an interpolated file
                                getBean().setWindgenStationMode(StationMode.Interpolated);
                                getBean().setWindgenStation(new InterpolatedStation(getBean().getLatLong()));
                            } else {
                                TFile file = new TFile(runFilePathName, name);
                                FileStation station = new FileStation(file);
                                getBean().setWindgenStation(station);
                            }
                        } else {
                            //really not supposed to get here.
                        }
                    } catch (IOException | NumberFormatException e) {
                        LOGGER.warn("Unable to read old windgen station.", e);
                        getBean().setWindgenStation(null);
                    }

                }

                setData(StartDate, getLine(in));
                setData(EndDate, getLine(in));
                setData(TimeSteps, getLine(in));
                setData(ClimateFile, getLine(in));
                setData(WindFile, getLine(in));
                setData(SubDailyFile, getLine(in));
                String fileName = getLine(in);
                if (!(new TFile(fileName)).isAbsolute()) {
                    fileName = new TFile(runFilePathName, fileName).getAbsolutePath();
                }
                final TFile soilFile = new TFile(fileName);
                if (!soilFile.exists()) {
                    ExceptionEventQueue.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            JOptionPane pane = new JOptionPane("The referenced soil file is missing.\n"
                                    + soilFile.getAbsolutePath(), JOptionPane.WARNING_MESSAGE) {
                                private static final long serialVersionUID = 1L;

                                @Override
                                public int getMaxCharactersPerLineCount() {
                                    return 80;
                                }

                            };

                            JDialog dialog = pane.createDialog("Loading Run");
                            dialog.setVisible(true);
                        }
                    });
                    setData(SoilFile, "");
                } else {
                    setData(SoilFile, fileName);
                }

                fileName = getLine(in);
                if (!(new TFile(fileName)).isAbsolute()) {
                    fileName = new TFile(runFilePathName, fileName).getAbsolutePath();
                }
                final TFile manFile = new TFile(fileName);
                if (!manFile.exists()) {
                    ExceptionEventQueue.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            JOptionPane pane = new JOptionPane("The referenced management file is missing.\n"
                                    + manFile.getAbsolutePath(), JOptionPane.WARNING_MESSAGE) {
                                private static final long serialVersionUID = 1L;

                                @Override
                                public int getMaxCharactersPerLineCount() {
                                    return 80;
                                }

                            };

                            JDialog dialog = pane.createDialog("Loading Run");
                            dialog.setVisible(true);
                        }
                    });
                    setData(ManageFile, "");
                } else {
                    setData(ManageFile, fileName);
                }

                setData(OutputFile, getLine(in));
                setData(ReportForm, getLine(in));
                setData(OutputPeriod, getLine(in));
                // skip over these two for now
                //setData(SubmodelOutput, getLine(in));
                //setData(DebugOutput, getLine(in));
                getLine(in);
                getLine(in);
                setData(RegionAngle, getLine(in));
                setData(SimPoint1, getLine(in));
                setData(SimPoint2, getLine(in));
                setData(Scales, getLine(in));
                setData(AccNo, getLine(in));
                setData(AccPoint1, getLine(in));
                setData(AccPoint2, getLine(in));
                setData(SubregionNo, getLine(in));
                setData(SubPoint1, getLine(in));
                setData(SubPoint2, getLine(in));
                {
                    String val = getLine(in);
                    if(val.trim().startsWith("-1")) val = "-1";
                    setData(AverageSlope, val);
                }
                readRunFileBarriers(in);

                //Shape and radius information used by the user interface to approximate a rectangular field shape.
                // Placed in try in case the run file does not have the shape fields.
                try {
                    setData(Shape, getLine(in));
                } catch (NullPointerException e) {
                    setData(Shape, "rectangle");
                }

                //consume the radius line
                getLine(in);

                //Only read the value if the correct version.
                if (version >= VERSION_WATER_EROSION) {
                    double d = 0;
                    String temp = getLine(in);
                    try {
                        temp = temp != null ? temp.trim() : null;
                        if (temp != null) {
                            d = Double.parseDouble(temp);
                        }
                    } catch (NumberFormatException e) {
                        LOGGER.debug("Unable to parse water erosion value: " + temp);
                    }

                    setData(WaterErosionLoss, String.valueOf(d));
                } else {
                    setData(WaterErosionLoss, "0");
                }

                //Only read the value if the correct version.
                if (version >= VERSION_ROCK_FRAGMENTS) {
                    String val = getLine(in);
                    if(val.trim().startsWith("-1")) val = "-1";
                    setData(SoilRockFragments, val);
                } else {
                    setData(SoilRockFragments, "-1");
                }

            } catch (IOException e) {
                LOGGER.error("unable to read run file: \"" + runFilePathName + "\"", e);
            } catch (java.lang.NullPointerException f) {
                JOptionPane.showMessageDialog(null,
                        "Error loading run file",
                        "Error (RFD-001)",
                        JOptionPane.ERROR_MESSAGE);
                f.printStackTrace();
                return;
            } finally {
                try {
                    if (in != null) {
                        in.close();
                    }
                } catch (IOException e) {
                    LOGGER.error("Error closing file stream.", e);
                }
            }
            readNotesFile(runFilePathName);
            fixUpData();
            changes.firePropertyChange(DataChanged, null, "xxx");
            fireAll();
            setData(Elevation, restoreRunElevation);

            //fire that we have finished loading the data
            //getBean().setLoading(false);
        } finally {
            RelativeFileContext.exit();
            LoadingContext.exit();
        }

    }

    /**
     * This method reads the data in the RUN file meant for the WEPS DIFF from
     * the existing set of values and makes it visible on the respective
     * components of the interface.
     *
     * @param runFile The system path to the RUN file from where this data is
     * retrieved.
     */
    public void readRunFile(TFile runFile) {

        LoadingContext.enter();
        RelativeFileContext.enter(runFile.getParentFile());
        initialize();
        clearBean();
        fileObject = runFile;
        try {
            //getBean().setLoading(true);
            c_log.clear();

            BufferedReader in = null;
            try {
                if (!runFile.exists()) {
                    LOGGER.warn("Run File \"" + runFile.getAbsolutePath() + "\" does not exist.");
                    return;
                }
                in = new BufferedReader(new TFileReader(runFile));
                double version = 1.00;  //Default when the version of the file is not included.

                String firstLine = in.readLine();
                if (firstLine == null) {
                    return;
                }
                firstLine = firstLine.trim();
                if (firstLine.startsWith(VERSION_MARKER)) {
                    firstLine = firstLine.replace(VERSION_MARKER, "");
                    version = Double.parseDouble(firstLine);
                }
                String tmp;
                tmp = getLine(in);
                if (tmp.length() > 65) {
                    setData(UserName, tmp.substring(0, 64));
                } else {
                    setData(UserName, tmp);
                }
                {
                    String temp = getLine(in);
                    StringTokenizer st = new StringTokenizer(temp, "|");
                    if (st.countTokens() < 3) {
                        if (temp.length() > 10) {
                            setData(FarmId, temp.substring(0, 9));
                        } else {
                            setData(FarmId, temp);
                        }
                        setData(TractId, "");
                        setData(FieldId, "");
                        setData(RunFileData.RunTypeDisp, ConfigData.Dates);
                        //					changes.firePropertyChange(RunFileData.RunTypeDisp, RunType,
                        //										 ConfigData.Dates);
                    } else if (st.countTokens() == 3) {
                        tmp = st.nextToken().trim();
                        if (tmp.length() > 10) {
                            setData(FarmId, tmp.substring(0, 9));
                        } else {
                            setData(TractId, tmp);
                        }
                        tmp = st.nextToken().trim();
                        if (tmp.length() > 10) {
                            setData(FieldId, tmp.substring(0, 9));
                        } else {
                            setData(FieldId, tmp);
                        }
                        tmp = st.nextToken().trim();
                        if (tmp.length() > 10) {
                            setData(FieldId, tmp.substring(0, 9));
                        } else {
                            setData(FieldId, tmp);
                        }
                        setData(RunFileData.RunTypeDisp, ConfigData.Dates);
                        //					changes.firePropertyChange(RunFileData.RunTypeDisp, RunType,
                        //										 st.nextToken().trim());

                        //					setData(RunFileData.RunTypeDisp, type);
                    } else {
                        //					try {
                        String tm = st.nextToken().trim();
                        if (tm.length() > 10) {
                            setData(FarmId, tm.substring(0, 9));
                        } else {
                            setData(FarmId, tm);
                        }
                        tm = st.nextToken().trim();
                        if (tm.length() > 10) {
                            setData(TractId, tm.substring(0, 9));
                        } else {
                            setData(TractId, tm);
                        }
                        tm = st.nextToken().trim();
                        if (tm.length() > 10) {
                            setData(FieldId, tm.substring(0, 9));
                        } else {
                            setData(FieldId, tm);
                        }
                        String type = st.nextToken().trim();
                        setData(RunFileData.RunTypeDisp, type);
                        setData(RotationYears, st.nextToken());
                        setData(CycleCount, st.nextToken());
                        //					} catch (ArrayIndexOutOfBounds e) {
                        //						//System.err.println("RFD_rRF: too few tokens in id line (should be 6) " +
                        //										   initializationData);
                        //					}
                    }
                }

                String siteString = getLine(in);
                if (version < VERSION_LOCPANEL_SITE) {
                    //old site format
                    usda.weru.weps.location.Site<?> site = upgradeSiteString(siteString);
                    setData(Site, site != null ? site.toString() : siteString);
                } else {
                    setData(Site, siteString);
                }

                {
                    //String initializationData = getLine(in);
                    //setData(LatitudeSign, initializationData.startsWith("-") ? "-" : "+");
                    // Added below code for second conditional statement 01/16/2004
                    //setData(Latitude, initializationData.substring(initializationData.startsWith("-") ? 1
                    //: ( initializationData.startsWith("+") ? 1 : 0 ) ));
                    //temp = getLine(in);
                    //setData(LongitudeSign, initializationData.startsWith("-") ? "-" : "+");
                    // Added below code for second conditional statement 01/16/2004
                    //setData(Longitude, initializationData.substring(initializationData.startsWith("-") ? 1
                    //: ( initializationData.startsWith("+") ? 1 : 0 ) ));
                    String latStr = getLine(in);
                    String longStr = getLine(in);
                    setData(StrLatLong, latStr.trim() + ";" + longStr.trim());
                    LatLong latlong = LatLong.valueOf(Double.parseDouble(latStr), Double.parseDouble(longStr), NonSI.DEGREE_ANGLE);
                    GISLookup<Site<?>> lookup
                            = GISData.getInstance().<Site<?>>getLookup(Caster.<Class<Site<?>>>cast(Site.class));
                    List<Site<?>> results = lookup.lookup(latlong);

                    if (results.size() > 0) {
                        Comparator<Site<?>> c = new Site.LevelComparator();
                        Collections.sort(results, c);
                        Site<?> mostDetail = results.get(results.size() - 1);
                        String FIPS = mostDetail.getFIPSCode();
                        if (FIPS.substring(0, 2).equals("US")) {
                            String[] FIPSSplit = FIPS.split("_");
                            FIPS = "FIPS:" + FIPSSplit[0] + "-" + FIPSSplit[2];
                        } else {
                            FIPS = "FIPS:" + FIPS;
                        }
                        if (!FIPS.equals(siteString)) {
                            JOptionPane.showMessageDialog(null, "Site information didn't match Latitude Longitude.\n"
                                    + "Latitude Longitude overriding the site information.",
                                    "Location Warning", JOptionPane.WARNING_MESSAGE);
                            setData(Site, FIPS);
                        }
                    } else {
                    }
                }

                // This string is used to store the value of the Run's elevation value
                restoreRunElevation = getLine(in);
                setData(Elevation, restoreRunElevation);

                if (version >= VERSION_LOCPANEL_REWRITE) {
                    //new format delegated to StationModeHandlers
                    //cligen
                    String cligenLine = getLine(in);
                    int cligenModeIndex = cligenLine.indexOf("|");
                    String cligenModeText = cligenLine.substring(0, cligenModeIndex);
                    String cligenText = cligenLine.length() > cligenModeIndex
                            ? cligenLine.substring(cligenModeIndex + 1) : null;

                    StationMode cligenMode = StationMode.parse(cligenModeText);
                    Station cligenStation = StationUtil.deserializeStation(cligenText);

                    getBean().setCligenStationMode(cligenMode);
                    getBean().setCligenStation(cligenStation);

                    //windgen
                    String windgenLine = getLine(in);
                    int windgenModeIndex = windgenLine.indexOf("|");
                    String windgenModeText = windgenLine.substring(0, windgenModeIndex);
                    String windgenText = windgenLine.length() > windgenModeIndex
                            ? windgenLine.substring(windgenModeIndex + 1) : null;

                    StationMode windgenMode = StationMode.parse(windgenModeText);
                    Station windgenStation = StationUtil.deserializeStation(windgenText);

                    getBean().setWindgenStationMode(windgenMode);
                    getBean().setWindgenStation(windgenStation);

                } else {
                    //Handle the old station format, only supports choice (0) or file (1) or interpolated for windgen
                    //cligen                    
                    try {
                        String cligenLine = getLine(in);
                        String cligenParts[] = cligenLine.split("\\|");
                        StationMode cligenMode = StationMode.parse(cligenParts[3]);

                        getBean().setCligenStationMode(cligenMode);

                        if (StationMode.Choice == cligenMode) {
                            //choice station
                            String name = cligenParts[0];
                            long id = Long.valueOf(cligenParts[1].trim());
                            long state = Long.valueOf(cligenParts[2].trim());
                            CligenStation station = CligenDataModel.getInstance().getStation(state, id);
                            if (station == null) {
                                LOGGER.warn("Unable to find cligen record in database. State: " + state + ", Id: " + id);
                                station = new CligenStation(name, state, id);
                            }

                            getBean().setCligenStation(station);

                        } else if (StationMode.File == cligenMode) {
                            //file station
                            String name = cligenParts[0];
                            TFile file = new TFile(runFile.getParentFile().getAbsolutePath(), name);
                            FileStation station = new FileStation(file);
                            getBean().setCligenStation(station);

                        } else {
                            //really not supposed to get here.
                        }
                    } catch (IOException | NumberFormatException e) {
                        LOGGER.warn("Unable to read old cligen station.", e);
                        getBean().setCligenStation(null);
                    }

                    //windgen                    
                    try {
                        String windgenLine = getLine(in);
                        String windgenParts[] = windgenLine.split("\\|");
                        StationMode windgenMode = StationMode.parse(windgenParts[2]);

                        getBean().setWindgenStationMode(windgenMode);

                        if (StationMode.Choice == windgenMode) {
                            //choice station
                            String name = windgenParts[0];
                            if (windgenParts[1].startsWith("I~")) {
                                //this was an interpolated station
                                getBean().setWindgenStationMode(StationMode.Interpolated);
                                getBean().setWindgenStation(new InterpolatedStation(getBean().getLatLong()));
                            } else {
                                long id = Long.valueOf(windgenParts[1].trim());
                                WindgenStation station = WindgenDataModel.getInstance().getStation(id);
                                if (station == null) {
                                    LOGGER.warn("Unable to find windgen record in database. Id: " + id);
                                    station = new WindgenStation(null, id, null, null, name);
                                }
                                getBean().setWindgenStation(station);
                            }

                        } else if (StationMode.File == windgenMode) {
                            //file station
                            String name = windgenParts[0];
                            name = name != null ? name.trim() : name;
                            if ("Interpolated".equalsIgnoreCase(name)) {
                                //handle an interpolated file
                                getBean().setWindgenStationMode(StationMode.Interpolated);
                                getBean().setWindgenStation(new InterpolatedStation(getBean().getLatLong()));
                            } else {
                                TFile file = new TFile(runFile.getParentFile().getAbsolutePath(), name);
                                FileStation station = new FileStation(file);
                                getBean().setWindgenStation(station);
                            }
                        } else {
                            //really not supposed to get here.
                        }
                    } catch (IOException | NumberFormatException e) {
                        LOGGER.warn("Unable to read old windgen station.", e);
                        getBean().setWindgenStation(null);
                    }

                }

                setData(StartDate, getLine(in));
                setData(EndDate, getLine(in));
                setData(TimeSteps, getLine(in));
                setData(ClimateFile, getLine(in));
                setData(WindFile, getLine(in));
                setData(SubDailyFile, getLine(in));
                String fileName = getLine(in);
                if (!(new TFile(fileName)).isAbsolute()) {
                    fileName = new TFile(runFile.getParentFile().getAbsolutePath(), fileName).getAbsolutePath();
                }
                final TFile soilFile = new TFile(fileName);
                if (!soilFile.exists()) {
                    ExceptionEventQueue.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            JOptionPane pane = new JOptionPane("The referenced soil file is missing.\n"
                                    + soilFile.getAbsolutePath(), JOptionPane.WARNING_MESSAGE) {
                                private static final long serialVersionUID = 1L;

                                @Override
                                public int getMaxCharactersPerLineCount() {
                                    return 80;
                                }

                            };

                            JDialog dialog = pane.createDialog("Loading Run");
                            dialog.setVisible(true);
                        }
                    });
                    setData(SoilFile, "");
                } else {
                    setData(SoilFile, fileName);
                }

                fileName = getLine(in);
                if (!(new TFile(fileName)).isAbsolute()) {
                    fileName = new TFile(runFile.getParentFile().getAbsolutePath(), fileName).getAbsolutePath();
                }
                final TFile manFile = new TFile(fileName);
                if (!manFile.exists()) {
                    ExceptionEventQueue.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            JOptionPane pane = new JOptionPane("The referenced management file is missing.\n"
                                    + manFile.getAbsolutePath(), JOptionPane.WARNING_MESSAGE) {
                                private static final long serialVersionUID = 1L;

                                @Override
                                public int getMaxCharactersPerLineCount() {
                                    return 80;
                                }

                            };

                            JDialog dialog = pane.createDialog("Loading Run");
                            dialog.setVisible(true);
                        }
                    });
                    setData(ManageFile, fileName);
                } else {
                    setData(ManageFile, fileName);
                }

                setData(OutputFile, getLine(in));
                setData(ReportForm, getLine(in));
                setData(OutputPeriod, getLine(in));
                // skip over these two for now
                //setData(SubmodelOutput, getLine(in));
                //setData(DebugOutput, getLine(in));
                getLine(in);
                getLine(in);
                setData(RegionAngle, getLine(in));
                setData(SimPoint1, getLine(in));
                setData(SimPoint2, getLine(in));
                setData(Scales, getLine(in));
                setData(AccNo, getLine(in));
                setData(AccPoint1, getLine(in));
                setData(AccPoint2, getLine(in));
                setData(SubregionNo, getLine(in));
                setData(SubPoint1, getLine(in));
                setData(SubPoint2, getLine(in));
                {
                    String val = getLine(in);
                    if(val.trim().startsWith("-1")) val = "-1";
                    setData(AverageSlope, val);
                }
                readRunFileBarriers(in);

                //Shape and radius information used by the user interface to approximate a rectangular field shape.
                // Placed in try in case the run file does not have the shape fields.
                try {
                    setData(Shape, getLine(in));
                } catch (NullPointerException e) {
                    setData(Shape, "rectangle");
                }

                //consume the radius line
                getLine(in);

                //Only read the value if the correct version.
                if (version >= VERSION_WATER_EROSION) {
                    double d = 0;
                    String temp = getLine(in);
                    try {
                        temp = temp != null ? temp.trim() : null;
                        if (temp != null) {
                            d = Double.parseDouble(temp);
                        }
                    } catch (NumberFormatException e) {
                        LOGGER.debug("Unable to parse water erosion value: " + temp);
                    }

                    setData(WaterErosionLoss, String.valueOf(d));
                } else {
                    setData(WaterErosionLoss, "0");
                }

                //Only read the value if the correct version.
                if (version >= VERSION_ROCK_FRAGMENTS) {
                    String val = getLine(in);
                    if(val.trim().startsWith("-1")) val = "-1";
                    setData(SoilRockFragments, val);
                } else {
                    setData(SoilRockFragments, "-1");
                }

            } catch (IOException e) {
                LOGGER.error("unable to read run file: \"" + runFile.getParentFile().getAbsolutePath() + "\"", e);
            } catch (java.lang.NullPointerException f) {
                JOptionPane.showMessageDialog(null,
                        "Error loading run file",
                        "Error (RFD-001)",
                        JOptionPane.ERROR_MESSAGE);
                f.printStackTrace();
                return;
            } finally {
                try {
                    if (in != null) {
                        in.close();
                    }
                } catch (IOException e) {
                    LOGGER.error("Error closing file stream.", e);
                }
            }
            readNotesFile(runFile.getParentFile().getAbsolutePath());
            fixUpData();
            changes.firePropertyChange(DataChanged, null, "xxx");
            fireAll();
            setData(Elevation, restoreRunElevation);

            //fire that we have finished loading the data
            //getBean().setLoading(false);
        } finally {
            RelativeFileContext.exit();
            LoadingContext.exit();
        }

    }

    private void fixUpData() {

        /* add additional factors */
        String temp1 = getData(SimPoint1);
        String temp2 = getData(SimPoint2);
        double x1 = 0.0;
        double y1 = 0.0;
        double x2 = 0.0;
        double y2 = 0.0;

        StringTokenizer st = new StringTokenizer(temp1);
        try {
            x1 = Double.parseDouble(st.nextToken());
            y1 = Double.parseDouble(st.nextToken());
            st = new StringTokenizer(temp2);
            x2 = Double.parseDouble(st.nextToken());
            y2 = Double.parseDouble(st.nextToken());
        } catch (NumberFormatException e) {
            //System.err.println("fUD: " + e);
            x1 = 0.0;
            y1 = 0.0;
            x2 = 0.0;
            y2 = 0.0;
        }
        double Xlen = Math.abs(x1 - x2);
        double Ylen = Math.abs(y1 - y2);

        NumberFormat nf = NumberFormat.getNumberInstance();
        nf.setMaximumFractionDigits(1);
        nf.setGroupingUsed(false);

        String shape = getData(Shape);
        if (shape.startsWith("circle")) {
            double radius = Math.sqrt((Xlen * Ylen) / Math.PI);
            setData(Radius, nf.format(radius));
        } else if (shape.startsWith("half_circle")) {
            double radius = Math.sqrt((Xlen * Ylen * 2) / Math.PI);
            setData(Radius, nf.format(radius));
        } else if (shape.startsWith("quarter_circle")) {
            double radius = Math.sqrt((Xlen * Ylen * 4) / Math.PI);
            setData(Radius, nf.format(radius));
        }

        setData(XLength, nf.format(Xlen));
        setData(YLength, nf.format(Ylen));
    }

    private String makeBarrier(String barPos, String barData) {

        if (barPos.equals(BarrierD)) {
            return "0.0 0.0" + java.lang.System.getProperty("line.separator")
                    + "0.0 0.0" + java.lang.System.getProperty("line.separator")
                    + "none" + java.lang.System.getProperty("line.separator")
                    + "0.0" + java.lang.System.getProperty("line.separator")
                    + "0.0" + java.lang.System.getProperty("line.separator")
                    + "0.0";
        }

        // get points for sim region
        String temp1 = getData(SimPoint1);
        String temp2 = getData(SimPoint2);
        double x1;
        double y1;
        double x2;
        double y2;

        StringTokenizer st = new StringTokenizer(temp1);
        try {
            x1 = Double.parseDouble(st.nextToken());
            y1 = Double.parseDouble(st.nextToken());
            st = new StringTokenizer(temp2);
            x2 = Double.parseDouble(st.nextToken());
            y2 = Double.parseDouble(st.nextToken());
        } catch (NumberFormatException e) {
            //System.err.println("RFD_mB: " + e);
            x1 = 0.0;
            y1 = 0.0;
            x2 = 0.0;
            y2 = 0.0;
            return "Error in makeBarrier -- can't get field dimensions";
        }

        st = new StringTokenizer(barData, "|");
        String type = st.nextToken();
        double widthDouble = 0.0;
        String height = st.nextToken();
        String width = st.nextToken();
        try {
            widthDouble = Double.parseDouble(width);
        } catch (NumberFormatException e) {
            //System.err.println("RFD_mB: " + e);
        }
        String porosity = st.nextToken();
        String x1s = "0.0";
        String x2s = "0.0";
        String y1s = "0.0";
        String y2s = "0.0";

        NumberFormat nf = NumberFormat.getNumberInstance();

        /* Since the fraction digits for the Simulation region co-ordinates is 2,
         ** the barrier co-ordinates SHOULD also have fraction digits of 2.
         ** Otherwise, they wont match while displaying the barriers.- added by Neha.
         */
        nf.setMaximumFractionDigits(2);
        nf.setGroupingUsed(false);
        switch (barPos) {
            case BarrierN:
                x1s = nf.format(x1);
                y1s = nf.format(y2);
                x2s = nf.format(x2);
                y2s = nf.format(y2 + widthDouble);
                break;
            case BarrierS:
                x1s = nf.format(x1);
                y1s = nf.format(y1 - widthDouble);
                x2s = nf.format(x2);
                y2s = nf.format(y1);
                break;
            case BarrierE:
                x1s = nf.format(x2);
                y1s = nf.format(y1);
                x2s = nf.format(x2 + widthDouble);
                y2s = nf.format(y2);
                break;
            case BarrierW:
                x1s = nf.format(x1 - widthDouble);
                y1s = nf.format(y1);
                x2s = nf.format(x1);
                y2s = nf.format(y2);
                break;
        }

        return x1s + " " + y1s + java.lang.System.getProperty("line.separator")
                + x2s + " " + y2s + java.lang.System.getProperty("line.separator")
                + type + java.lang.System.getProperty("line.separator")
                + height + java.lang.System.getProperty("line.separator")
                + width + java.lang.System.getProperty("line.separator")
                + porosity;
    }

    /**
     * This method writes the modifications done or text inserted to the notes
     * text field/area in the file that preserves it.
     *
     * @param dir The system path to the directory where this file exists.
     */
    public void writeNotesFile(String dir) {

        //Disabled large note files quick fix.
        //String value = getData(NotesReadonly);
        //if (value != null && value.equals("1")) return;
        PrintWriter out = null;
        try {
            out = new PrintWriter(new BufferedWriter(new TFileWriter(
                    new TFile(dir, RunFileData.NotesFileName))));

            String notes = getData(NotesText);
            out.println(notes);
        } catch (FileNotFoundException e) {
            //System.err.println("RFD_wNF: " + e);
        } finally {
            try {
                out.close();
            } catch (Exception e) {
                LOGGER.error("Error closing file stream", e);
            }
        }
    }

    /**
     * This method updates to the newly inserted date values in the dates column
     * of the interface.
     */
    public void updateDates() {
        String runType = getData(RunTypeDisp);
        if (runType.equals(ConfigData.Dates)) {
            String sD = getData(StartDate);
            // //System.out.println("RFD_uD: START DATE is :" + sD);  // TESTING
            String eD = getData(EndDate);
            // //System.out.println("RFD_uD: END DATE is :" + eD);  // TESTING
            StringTokenizer st = new StringTokenizer(sD);
            st.nextToken();
            st.nextToken();
            sD = st.nextToken();
            //System.out.println("RFD_uD: START DATE after TOKEN is :" + sD); // TESTING
            st = new StringTokenizer(eD);
            st.nextToken();
            st.nextToken();
            eD = st.nextToken();
            //System.out.println("RFD_uD: END DATE after TOKEN is :" + eD); // TESTING
            String totYrs = "" + ((Integer.parseInt(eD) - Integer.parseInt(sD)) + 1);
            //System.out.println("RFD_uD: Total Years are :" + totYrs); // TESTING
            setData(TotalYears, totYrs);
        } else {
            if (runType.equals(ConfigData.NRCS)) {
                setData(CycleCount, NRCSRunLen);
            }
            setData(StartDate, "01 01 01");
            String numYrs = getData(RotationYears);
            String numCyl = getData(CycleCount);
            int nY = Integer.parseInt(numYrs);
            int nC = Integer.parseInt(numCyl);
            setData(EndDate, "31 12 " + (nY * nC));
            String totYrs = "" + (nY * nC);
            setData(TotalYears, totYrs);
        }

    }

    public void writeRunFile(String runDirPath) {
        writeRunFile(runDirPath, false);
    }

    /**
     * This method creates the "weps.run" file in the run directory.
     *
     * @param runDirPath The system path string to this run directory.
     */
    public void writeRunFile(String runDirPath, boolean calMode) {
        PrintWriter out = null;
        TFile runDir = new TFile(runDirPath);
        RelativeFileContext.enter(runDir);
        try {
            out = new PrintWriter(new BufferedWriter(new TFileWriter(new TFile(runDir, WepsRun))));
            int count = 0;
            //First line is now a version line
            NumberFormat versionFormat = NumberFormat.getNumberInstance();
            versionFormat.setMaximumFractionDigits(2);
            out.println(VERSION_MARKER + versionFormat.format(VERSION_CURRENT));
            out.println("#------------ WEPS SIMULATION RUN FILE ------------");
            out.println("# Note: Lines beginning with '#' are comment lines.");
            out.println("#       Lines beginning with '#   RFD' are comments used by the interface.");
            out.println("#");
            out.println("# --USER INFORMATION");
            out.println("#   " + UserName);
            out.println(getData(UserName));
            out.println("#   " + FarmId + " " + TractId + " " + FieldId + " "
                    + RunTypeDisp + " " + RotationYears + " " + CycleCount);
            out.println(getData(FarmId) + " | " + getData(TractId) + " | "
                    + getData(FieldId) + " | " + getData(RunTypeDisp) + " | "
                    + getData(RotationYears) + " | " + getData(CycleCount));
            //out.println("#   " + SiteCounty + ", " + SiteState);
            //out.println(getData(SiteCounty) + ", " + getData(SiteState));
            out.println("#   " + Site);
            usda.weru.weps.location.Site<?> site = getBean().getSite();
            out.println(site != null ? site.toString() : "");
            out.println("#");
            out.println("# --SITE INFORMATION");
            //print out the parts of LatLong
            LatLong latlong = getBean().getLatLong();
            // Added digits here to see if problem still exists.
            NumberFormat latlongFormat = new DecimalFormat("+0.00000;-0.00000");
            out.println("#   Signed Latitude");
            out.println(latlongFormat.format(latlong.latitudeValue(NonSI.DEGREE_ANGLE)));
            out.println("#   Signed Longitude");
            out.println(latlongFormat.format(latlong.longitudeValue(NonSI.DEGREE_ANGLE)));

            out.println("#   " + Elevation + "(meters)");
            out.println(getData(Elevation));

            //cligen
            out.println("#   " + ClimateFlag + "|" + CligenStation);
            //the new station mode model handles serializing the station for each mode.
            StationMode cligenMode = getBean().getCligenStationMode();
            Station cligenStation = getBean().getCligenStation();
            if (cligenStation instanceof FileStation && cligenStation != null) {
                TFile file = ((FileStation) cligenStation).getFile();
                cligenStation = new FileStation(new TFile(runDir, file.getName()));
            }
            out.println(cligenMode.getName() + "|" + StationUtil.serializeStation(cligenStation));

            //windgen
            out.println("#   " + WindFlag + "|" + WindgenStation);
            //the new station mode model handles serializing the station for each mode.
            StationMode windgenMode = getBean().getWindgenStationMode();
            Station windgenStation = getBean().getWindgenStation();
            if (windgenStation instanceof FileStation && windgenStation != null) {
                TFile file = ((FileStation) windgenStation).getFile();
                windgenStation = new FileStation(new TFile(runDir, file.getName()));
            }
            out.println(windgenMode.getName() + "|" + StationUtil.serializeStation(windgenStation));

            out.println("#");
            out.println("# --SIMULATION PERIOD");
            out.println("#   " + StartDate + "(day month year)");
            out.println(getData(StartDate));
            out.println("#   " + EndDate + "(day month year)");
            out.println(getData(EndDate));
            out.println("#   " + TimeSteps + "(per day)");
            out.println(getData(TimeSteps));
            out.println("#");
            out.println("# --RUN FILE FILENAMES (INPUT)");
            out.println("#   " + ClimateFile);
            if (cligenStation instanceof FileStation) {
                FileStation fileStation = (FileStation) cligenStation;
                out.println(fileStation.getFile().getName());
            } else {
                out.println(DefaultCliGenName);
            }
            out.println("#   " + WindFile);
            //if it is a file station we use the name of the file, else we use the default name            
            if (windgenStation instanceof FileStation) {
                FileStation fileStation = (FileStation) windgenStation;
                out.println(fileStation.getFile().getName());
            } else if (windgenStation instanceof InterpolatedStation) {
                out.println("interpolated.win");
            } else {
                out.println(DefaultWinGenName);
            }
            out.println("#   " + SubDailyFile);
            out.println("none");
            out.println("#   " + SoilFile);
            out.println((new TFile(getData(SoilFile)).getName()));
            out.println("#   " + ManageFile);
            if (calMode) {
                String name = new TFile(getData(ManageFile)).getName();
                String[] insert = name.split("\\.");
                if (!(insert.length >= 2)) {
                    LOGGER.warn("Management file does not have extension");
                    out.println(new TFile(getData(ManageFile)).getName());
                } else if (!insert[insert.length - 1].equals("man")) {
                    LOGGER.warn("Management file does not end in .man");
                    out.println(new TFile(getData(ManageFile)).getName());
                } else {
                    name = "";
                    insert[insert.length - 2] += "_calib";
                    for (String item : insert) {
                        name += item + ".";
                    }
                    name = name.substring(0, name.length() - 1);
                    out.println(name);
                }
            } else {
                out.println((new TFile(getData(ManageFile)).getName()));
            }
            out.println("#");
            out.println("# --WEPS OUTPUT OPTIONS");
            out.println("#   " + OutputFile);
            out.println(getData(OutputFile));
            out.println("#   " + ReportForm);
            out.println(getData(ReportForm));
            out.println("#   " + OutputPeriod);
            out.println(getData(OutputPeriod));
            out.println("#   " + SubmodelOutput);
            out.println(so.getAllSubmodelOutput());
            out.println("#   " + DebugOutput);
            out.println("0 0 0 0 0 0");
            out.println("#");
            out.println("# --SIMULATION REGION INFORMATION");
            out.println("#   " + RegionAngle + "(degrees clockwise from North)");
            out.println(getData(RegionAngle));
            out.println("#   Origin coordinates of simulation region (meters)");
            out.println("0.0  0.0");
            setData(SimPoint1, "0.0 0.0");
            out.println("#    " + XLength + "(meters)" + "  " + YLength + "(meters)");
            String xLength = getData(XLength);
            String yLength = getData(YLength);
            out.println(xLength + "  " + yLength);
            setData(SimPoint2, xLength + "  " + yLength);
            out.println("#   " + Scales + "(place holder line - needed for older versions of WEPS)");
            out.println("5.5 5.5");
            out.println("#");
            out.println("#   " + AccNo);
            out.println(getData(AccNo));
            out.println("#   Accounting region coordinates (meters)");
            out.println("    0.0  0.0");
            out.println(xLength + "  " + yLength);
            out.println("#");
            out.println("#   " + SubregionNo);
            out.println(getData(SubregionNo));
            out.println("#   Subregion region coordinates (meters)");
            out.println("0.0  0.0");
            out.println(xLength + "  " + yLength);
            out.println("#   " + AverageSlope + "(ratio m/m)");
            out.println(Double.parseDouble(getData(AverageSlope)) == -1.0 ? Integer.toString(-1) : getData(AverageSlope));
            // out.println("#   Barriers");
            int barrierCnt = 0;
            if (!getData(BarrierN).startsWith("none|")) {
                barrierCnt++;
            }
            if (!getData(BarrierS).startsWith("none|")) {
                barrierCnt++;
            }
            if (!getData(BarrierE).startsWith("none|")) {
                barrierCnt++;
            }
            if (!getData(BarrierW).startsWith("none|")) {
                barrierCnt++;
            }
            out.println("#   " + BarrierNo);
            out.println(barrierCnt);
            if (barrierCnt == 0) {
                out.println(makeBarrier(BarrierD, ""));
            } else {
                String barrier = getData(BarrierN);
                if (barrier.length() > 0 && !barrier.startsWith("none|")) {
                    out.println("#   " + BarrierN + " coordinates (meters)" + " | type"
                            + " | height (meters)" + " | width (meters)" + " | porosity");
                    out.println(makeBarrier(BarrierN, barrier));
                }
                barrier = getData(BarrierW);
                if (barrier.length() > 0 && !barrier.startsWith("none|")) {
                    out.println("#   " + BarrierW + " coordinates (meters)" + " | type"
                            + " | height (meters)" + " | width (meters)" + " | porosity");
                    out.println(makeBarrier(BarrierW, barrier));
                }
                barrier = getData(BarrierE);
                if (barrier.length() > 0 && !barrier.startsWith("none|")) {
                    out.println("#   " + BarrierE + " coordinates (meters)" + " | type"
                            + " | height (meters)" + " | width (meters)" + " | porosity");
                    out.println(makeBarrier(BarrierE, barrier));
                }
                barrier = getData(BarrierS);
                if (barrier.length() > 0 && !barrier.startsWith("none|")) {
                    out.println("#   " + BarrierS + " coordinates (meters)" + " | type"
                            + " | height (meters)" + " | width (meters)" + " | porosity");
                    out.println(makeBarrier(BarrierS, barrier));
                }
            }
            out.println("#");
            out.println("# --CIRCULAR FIELD INFORMATION");
            out.println("# Note: These fields are not used by the weps simulation.");
            out.println("#       The shape and radius values are used by the user ");
            out.println("#       interface to approximate a rectangular field.  They");
            out.println("#       are included here so the reports can display the ");
            out.println("#       correct field shape.");
            out.println("#");
            out.println("#   " + Shape);
            out.println(getData(Shape));
            out.println("#   " + Radius);
            out.println(getData(Radius));
            out.println("#   " + WaterErosionLoss);
            out.println(getData(WaterErosionLoss));
            out.println("#   " + SoilRockFragments);
            out.println(Double.parseDouble(getData(SoilRockFragments)) == -1.0 ? Integer.toString(-1) : getData(SoilRockFragments));
            out.println("#---------- END OF SIMULATION RUN FILE ------------");
            writeNotesFile(runDirPath);
        } catch (FileNotFoundException e) {
            //System.err.println("RunFileData: " + e);
        } finally {
            RelativeFileContext.exit();
            try {
                out.close();
            } catch (Exception e) {
                LOGGER.error("Error closing stream", e);
            }
        }
        changes.firePropertyChange(WriteRunFile, null, "xxx");
    }

    /**
     * This method reads the file "weps.ini" in the project directory specified
     * in the path "runFilePathName" into hashtable "ht".
     *
     * @param runFilePathName The system path string to this run file directory.
     */
    @SuppressWarnings("unchecked") // Element.getChildren is not checked
    public void readRunData(String runFilePathName) {
        fileObject = new TFile(runFilePathName);
        TFile runData = new TFile(runFilePathName, WepsData);
        if (!runData.exists()) {
            initialize();
            writeRunDataXML(runFilePathName);
        }
        RelativeFileContext.enter(new TFile(runFilePathName));
        LoadingContext.enter();
        try {

            if (runFilePathName.length() == 0) {
                runFilePathName = curProj;
            }

            Map<String, String> initializationData = new HashMap<String, String>();
            boolean write = false;
            //first try the xml
            try {
                readRunDataXML(runData, initializationData);
                //now set all the data
            } catch (Exception e) {
                //xml failed, maybe it's really old in the binary format?
                LOGGER.info("Could not read weps.ini file as an XML document.  Will try using old binary format.");
                try {
                    readRunDataBinary(runData, initializationData);
                    write = true;
                } catch (Exception ex) {
                    //oh snap, even the binary failed.
                }
            }

            //Handle a few cases first                
            prioritySetData(initializationData, RunFileData.StrLatLong);
            prioritySetData(initializationData, RunFileData.ClimateFlag);
            prioritySetData(initializationData, RunFileData.CligenStation);
            prioritySetData(initializationData, RunFileData.WindFlag);
            prioritySetData(initializationData, RunFileData.WindgenStation);

            for (Map.Entry<String, String> entry : initializationData.entrySet()) {
                setData(entry.getKey(), entry.getValue());
            }
            //fixup the cligen/windgen modes
            String climateMode = initializationData.get(RunFileData.ClimateFlag);
            if (climateMode != null && climateMode.trim().length() == 0) {
                getBean().setCligenStationMode(null);
            }

            String windgenMode = initializationData.get(RunFileData.WindFlag);
            if (windgenMode != null && windgenMode.trim().length() == 0) {
                getBean().setWindgenStationMode(null);
            }

            if (write) {
                writeRunDataXML(runFilePathName);
            }
        } finally {
            LoadingContext.exit();
            RelativeFileContext.exit();
        }

    }

    private void prioritySetData(Map<String, String> map, String property) {
        String value = map.get(property);
        setData(property, value);
    }

    private void readRunDataXML(TFile file, Map<String, String> temp) throws Exception {
        RelativeFileContext.enter(new TFile(file.getParentFile()));
        LoadingContext.enter();
        clearBean();
        try {
            SAXBuilder in = new SAXBuilder();
            Document doc;
            Element root = null;
            //use the stream so zipped files will work
            doc = in.build(new TFileInputStream(file));
            if (doc != null) {
                root = doc.getRootElement();
            } else {
                throw new RuntimeException("no runFileData doc");
            }
            double version = 0;
            try {
                version = Double.valueOf(root.getAttributeValue("version"));
            } catch (NumberFormatException e) {
                //no version number;
                version = 0;
            }
            for (Element element : root.getChildren("key")) {
                String key = element.getAttributeValue("name");
                String value = element.getText();
                if(key.equals(AverageSlope) || key.equals(SoilRockFragments))
                {
                    if(value.trim().startsWith("-1")) value = "-1";
                }
                temp.put(key, value);
            }

            //upgrade data
            upgradeData(temp, version);

            //clean data
            cleanData(temp);
        } finally {
            LoadingContext.exit();
            RelativeFileContext.exit();
        }
    }

    private void readRunDataBinary(TFile file, Map<String, String> temp) throws Exception {
        LoadingContext.enter();
        try {
            ObjectInputStream objStream = null;
            try {

                TFileInputStream inStream = null;
                try {
                    inStream = new TFileInputStream(file);
                } catch (java.io.FileNotFoundException fnfe) {
                    LOGGER.info("Run file data not found. " + file.getPath());
                    initialize();
                    return;
                }

                objStream = new ObjectInputStream(inStream);
                //Load the file into a initializationData location.

                // I don't think that there's a way to get
                // objStream to safely return a Hashtable
                Hashtable<String, String> tempHashtable = Caster.<Hashtable<String, String>>cast(objStream.readObject());
                for (Map.Entry<String, String> entry : tempHashtable.entrySet()) {
                    String key = entry.getKey();
                    if (key.equals(RunsLocation)) {
                        continue;
                    }
                    String value = entry.getValue();
                    temp.put(key, value);
                }
                upgradeData(temp, 0);
                cleanData(temp);

            } finally {
                try {
                    if (objStream != null) {
                        objStream.close();
                    }
                } catch (IOException e) {
                    LOGGER.error("Error closing file stream. " + file.getPath(), e);
                }
            }
        } finally {
            LoadingContext.exit();
        }
    }

    /**
     * @param map map with the data to be upgraded
     * @param version version number, to find out how to upgrade the data
     */
    private void upgradeData(Map<String, String> map, double version) {

        if (version < VERSION_LOCPANEL_REWRITE) {
            //need to upgrade the station values
            //CLIGEN
            StationMode cligenMode = StationMode.parse(map.get(ClimateFlag));

            //convert id to name
            map.put(WindFlag, cligenMode.getName());

            Station cligenStation = null;
            switch (cligenMode) {
                case Choice:
                    try {
                        long cligenId = Long.valueOf(map.get(CliGenStation));
                        long cligenState = Long.valueOf(map.get(CliGenState));
                        //try to find a station for the give id
                        cligenStation = CligenDataModel.getInstance().getStation(cligenState, cligenId);

                    } catch (NumberFormatException e) {
                        //oh snap
                    }

                    break;
                case File:
                    String cligenFilePath = map.get(WindFile);
                    if (cligenFilePath != null) {
                        cligenStation = new FileStation(new TFile(cligenFilePath));
                    }
                    break;
                default:
                    //unexpected old mode
                    break;
            }

            String cligenStationSer = StationUtil.serializeStation(cligenStation);
            map.put(CligenStation, cligenStationSer);
            //END CLIGEN

            //WINDGEN
            StationMode windgenMode = StationMode.parse(map.get(WindFlag));

            //convert id to name
            map.put(WindFlag, windgenMode.getName());

            Station windgenStation = null;
            switch (windgenMode) {
                case Choice:
                    try {
                        long windgenId = Long.valueOf(map.get(WinGenStation));
                        //try to find a station for the give id
                        windgenStation = WindgenDataModel.getInstance().getStation(windgenId);

                    } catch (NumberFormatException e) {
                        //oh snap
                    }
                    break;
                case File:
                    String windgenFilePath = map.get(WindFile);
                    if (windgenFilePath != null) {
                        windgenStation = new FileStation(new TFile(windgenFilePath));
                    }
                    break;
                default:
                    //unexpected old mode
                    break;
            }

            String windgenStationSer = StationUtil.serializeStation(windgenStation);
            map.put(WindgenStation, windgenStationSer);
            //END WINDGEN

        }

        if (version < VERSION_LOCPANEL_SITE) {
            //site

            usda.weru.weps.location.Site<?> site = upgradeSiteString(map.get(Site));
            if (site != null) {
                map.put(Site, site.toString());
            }
        }

        if (version < VERSION_RELATIVE_PATHS) {
            TFile projectFile = new TFile(curProj);

            //need to fix up paths that might not be valid for soil and management
            String soilPath = map.get(SoilFile);
            TFile soilFile = new TFile(soilPath);

            if (!soilFile.exists()) {
                soilFile = new TFile(projectFile, soilFile.getName());
                if (soilFile.exists()) {
                    map.put(SoilFile, soilFile.getPath());
                    LOGGER.info("Resolved missing absolute soil file to relative path.");
                }
            }

            String managePath = map.get(ManageFile);
            TFile manageFile = new TFile(managePath);

            if (!manageFile.exists()) {
                manageFile = new TFile(projectFile, manageFile.getName());
                if (manageFile.exists()) {
                    map.put(ManageFile, manageFile.getPath());
                    LOGGER.info("Resolved missing absolute management file to relative path.");
                }
            }

        } else {
            //Need to take the relative paths and convert to absolute so the interface still works
            TFile projectFile = new TFile(curProj);

            String soilPath = map.get(SoilFile);
            String managePath = map.get(ManageFile);
            if (!(soilPath.split(":").length > 1)) {
                if (!"".equals(soilPath)) {
                    TFile soilFile = new TFile(projectFile, soilPath);
                    map.put(SoilFile, soilFile.getPath());
                }
            }
            if (!(managePath.split(":").length > 1)) {
                if (!"".equals(managePath)) {
                    TFile manageFile = new TFile(projectFile, managePath);
                    map.put(ManageFile, manageFile.getPath());
                }
            }
        }

    }

    private usda.weru.weps.location.Site<?> upgradeSiteString(String oldSiteString) {
        String parts[] = oldSiteString.split(",");
        String countyName = parts[0].trim();
        String stateName = parts[1].trim();

        Level0 usa = Level0.UNITED_STATES;
        usda.weru.weps.location.Site<?> temp = null;
        for (usda.weru.weps.location.Site<?> state : usa.getSubDivisions()) {
            if (state.getDisplayName().equalsIgnoreCase(stateName)) {
                temp = state;
                break;
            }
        }

        if (temp != null) {
            for (usda.weru.weps.location.Site<?> county : temp.getSubDivisions()) {
                if (county.getDisplayName().equalsIgnoreCase(countyName)) {
                    temp = county;
                    break;
                }
            }
        }

        return temp;

    }

    private void cleanData(Map<String, String> map) {
        for (Field field : RunFileData.class.getFields()) {
            if (field.getType().equals(String.class) && field.isAnnotationPresent(Deprecated.class)) {
                try {
                    String key = (String) field.get(this);
                    map.remove(key);
                    LOGGER.info("Deprecated RunFileData Key: " + key);
                } catch (IllegalArgumentException | IllegalAccessException e) {
                }
            }
        }
    }

    /**
     * Updates the data into the initialization RUN file (weps.ini) the user
     * modifications done on the screen which is a basically a hashtable
     * containing the details of the project.
     *
     * @param runFilePathName The system path string to this run file directory
     * where the screen data resides.
     */
    public void writeRunDataXML(String runFilePathName) {

        cleanData(ht);
        if (runFilePathName.length() == 0) {
            runFilePathName = curProj;
            /**
             * Create file "weps.ini" in the Project directory specified in the
             * path "runFilePathName". Write into this "weps.ini" file the hash
             * table containing the details of Project.
             */
        }
        TFile runData = new TFile(runFilePathName, WepsData);
        TFile runFolder = new TFile(runFilePathName);
        RelativeFileContext.enter(runFolder);
        try {

            Element root = new Element("weps");
            //add the version number so when read in we know how to handle station values
            root.setAttribute("version", String.valueOf(VERSION_CURRENT));
            synchronized (this) {
                //create a delay so when writing the default .ini, 
                //the initializing of the cligen and windgen stations can catch
                //up.
                try {
                    this.wait(4000);
                } catch (InterruptedException inter) {
                } catch (IllegalMonitorStateException ill) {
                }
            }
            for (Map.Entry<String, String> entry : ht.entrySet()) {
                try {
                    Element param = new Element("key");
                    String key = entry.getKey();

                    param.setAttribute("name", key);
                    String value = entry.getValue();
                    if (!"".equals(value) && (RunFileData.SoilFile.equals(key) || RunFileData.ManageFile.equals(key))) {
                        //if soil or manage file make relative paths

                        TFile valueFile = new TFile(value);
                        valueFile = Util.resolveFileAsRelativeChildOrAbsolute(runFolder, valueFile);
                        value = valueFile.getPath();
                    }

                    param.setText(value != null ? value : "");
                    root.addContent(param);
                } catch (IllegalDataException ide) {
                    LOGGER.warn("Unable to save data element.  Some data may be missing or corrupted. "
                            + ide.getMessage());
                }
            }
            TFileOutputStream stream = null;
            try {
                XMLOutputter out = new XMLOutputter(Format.getPrettyFormat());
                stream = new TFileOutputStream(runData);
                out.output(root, stream);
                stream.close();
            } catch (IOException ex) {
                LOGGER.error("Error writing run data.", ex);
            } finally {
                if (stream != null) {
                    try {
                        stream.close();
                    } catch (IOException ex) {
                    }
                }
            }
        } finally {
            RelativeFileContext.exit();
        }
    }

    /**
     * Removes the files/directories that contain the RUN data.
     *
     * @param dir The directory that contains the RUN data that will be removed.
     * @return True if the directory is deleted else false.
     */
    public boolean removeRunData(TFile dir) {
        return Util.deleteAll(dir);
    }

    /**
     * Displays information about the object on the console for use in
     * debugging.
     *
     * @param msg The message to be shown/displayed.
     */
    public void showRunFileData(String msg) {
        //System.err.println("sRFD " + msg + " " + ht.size());
        Enumeration<String> e = ht.keys();
        while (e.hasMoreElements()) {
            String key = e.nextElement();
            String value = ht.get(key);
            System.err.println(key + "=" + value);
        }
    }

    /**
     * RunFileData throws a property change each time setData is called. Wrapper
     * classes listen to determine if the the event is relevant to them.
     */
    private final PropertyChangeSupport changes = new PropertyChangeSupport(this);

    /**
     * Allows the container to add or register some other components to
     * recognize the changes that occur on this component.
     *
     * @param l The listener that listens and reacts towards the the changes to
     * be reflected.
     */
    public void addPropertyChangeListener(PropertyChangeListener l) {
        changes.addPropertyChangeListener(l);
    }

    /**
     *
     * @param propertyName
     * @param l
     */
    public void addPropertyChangeListener(String propertyName, PropertyChangeListener l) {
        changes.addPropertyChangeListener(propertyName, l);
    }

    /**
     * Allows the container to remove or de-register some other components and
     * stop recognizing the changes that occur on this component.
     *
     * @param l The listener that does not listen and react towards the the
     * changes to be reflected.
     */
    public void removePropertyChangeListener(PropertyChangeListener l) {
        changes.removePropertyChangeListener(l);
    }

    /**
     *
     * @param propertyName
     * @param l
     */
    public void removePropertyChangeListener(String propertyName, PropertyChangeListener l) {
        changes.removePropertyChangeListener(propertyName, l);
    }

    /**
     * Recognizes and takes appropriate actions on registered properties from
     * different screens to update and synchronize data and GUI screens as
     * needed.
     *
     * @param e The event itself that is responsible for triggering the change
     * required for registered properties/components.
     */
    @Override
    public void propertyChange(PropertyChangeEvent e) {

        String idxstr = e.getPropertyName();
        if (!idxstr.startsWith(RFD)) { 	// not an rfd file value
            switch (idxstr) {
                case WriteRunData:
                    writeRunDataXML((String) e.getNewValue());
                    break;
                case WriteRunFile:
                    writeRunFile((String) e.getNewValue());
                    break;
                case ReadRunData:
                    readRunData((String) e.getNewValue());
                    break;
                case ReadRunFile:
                    readRunFile((String) e.getNewValue());
                    break;
                case ShowRunData:
                    showRunFileData((String) e.getNewValue());
                    break;
                case ConfigData.CurrentProj:
                    curProj = Util.parse(e.getNewValue().toString());
                    break;
                case ConfigData.NRCSRunLen:
                    NRCSRunLen = (String) e.getNewValue();
                    break;
                case ConfigData.OutputFreq:
                    setData(OutputPeriod, (String) e.getNewValue());
                    break;
                case RunFileData.ClimateFlag:
                    setData(ClimateFlag, (String) e.getNewValue());
                    break;
                case RunFileData.WindFlag:
                    setData(WindFlag, (String) e.getNewValue());
                    break;
            }

            return;
        }
        String valstr = (String) e.getNewValue();
        setData(idxstr, valstr);
        if (idxstr.equals(ManageFile)) {
            setRotationYears(valstr);
        }
    }

    /**
     *
     * @return
     */
    public Set<String> keySet() {
        if (ht != null) {
            return ht.keySet();
        } else {
            return null;
        }
    }

    private RunFileBean c_bean;

    private synchronized void clearBean() {
    }

    /**
     *
     * @return
     */
    public synchronized RunFileBean getBean() {
        if (c_bean == null) {
            c_bean = new RunFileBean();
            //link the two together
            RunFileDataBeanBridge.bridge(this, c_bean);
        }
        return c_bean;
    }

}
