/// <summary>
        /// Processes the file at the given path.
        /// </summary>
        /// <param name="fileGroupID">The identifier for the file group to be processed.</param>
        /// <returns>False if the file was not able to be processed and needs to be processed again later.</returns>
        public bool ProcessFileGroup(int fileGroupID)
        {
            SystemSettings systemSettings;

            FileInfoDataContext fileInfo;
            FileGroup fileGroup;
            DataFile dataFile = null;

            List<MeterDataSet> meterDataSets;

            try
            {
                systemSettings = new SystemSettings(m_connectionString);

                using (DbAdapterContainer dbAdapterContainer = new DbAdapterContainer(systemSettings.DbConnectionString, systemSettings.DbTimeout))
                {
                    fileInfo = dbAdapterContainer.GetAdapter<FileInfoDataContext>();

                    // Create a file group for this file in the database
                    fileGroup = LoadFileGroup(fileInfo, fileGroupID);

                    if ((object)fileGroup == null)
                        return true;

                    dataFile = fileGroup.DataFiles.FirstOrDefault();

                    if ((object)dataFile == null)
                        return true;

                    // Parse the file
                    meterDataSets = LoadMeterDataSets(dbAdapterContainer, fileGroup);

                    // Set properties on each of the meter data sets
                    foreach (MeterDataSet meterDataSet in meterDataSets)
                    {
                        meterDataSet.ConnectionString = m_connectionString;
                        meterDataSet.FilePath = dataFile.FilePath;
                        meterDataSet.FileGroup = fileGroup;
                    }

                    // Process meter data sets
                    OnStatusMessage("Processing meter data from file \"{0}\"...", dataFile.FilePath);
                    ProcessMeterDataSets(meterDataSets, systemSettings, dbAdapterContainer);
                    OnStatusMessage("Finished processing data from file \"{0}\".", dataFile.FilePath);
                }
            }
            catch (Exception ex)
            {
                string message;

                if ((object)dataFile != null)
                    message = string.Format("Failed to process file \"{0}\" due to exception: {1}", dataFile.FilePath, ex.Message);
                else
                    message = string.Format("Failed to process file group \"{0}\" due to exception: {1}", fileGroupID, ex.Message);

                OnHandleException(new InvalidOperationException(message, ex));
            }

            return true;
        }
        /// <summary>
        /// Reloads system settings from the database.
        /// </summary>
        public void ReloadSystemSettings()
        {
            ConfigurationFile configurationFile;
            CategorizedSettingsElementCollection category;

            // Reload the configuration file
            configurationFile = ConfigurationFile.Current;
            configurationFile.Reload();

            // Retrieve the connection string from the config file
            category = configurationFile.Settings["systemSettings"];
            category.Add("ConnectionString", "Data Source=localhost; Initial Catalog=openXDA; Integrated Security=SSPI", "Defines the connection to the openXDA database.");
            m_dbConnectionString = category["ConnectionString"].Value;

            // Load system settings from the database
            m_systemSettings = new SystemSettings(LoadSystemSettings());
        }
        public void ProcessMeterDataSets(List<MeterDataSet> meterDataSets, SystemSettings systemSettings, DbAdapterContainer dbAdapterContainer)
        {
            TimeZoneInfo xdaTimeZone;
            DateTime processingEndTime;

            try
            {
                foreach (MeterDataSet meterDataSet in meterDataSets)
                    ProcessMeterData(meterDataSet, dbAdapterContainer);

                xdaTimeZone = systemSettings.XDATimeZoneInfo;
                processingEndTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, xdaTimeZone);

                foreach (MeterDataSet meterDataSet in meterDataSets)
                    meterDataSet.FileGroup.ProcessingEndTime = processingEndTime;

                dbAdapterContainer.GetAdapter<FileInfoDataContext>().SubmitChanges();
            }
            catch (Exception ex)
            {
                OnHandleException(ex);
            }
        }