/// <summary>
        ///
        /// </summary>
        /// <param name="message"></param>
        /// <param name="appendText"></param>
        /// <param name="eventId"></param>
        /// <param name="eventReference"></param>
        /// <param name="entryType"></param>
        /// <param name="enumPriority"></param>
        public void Write(string message, bool appendText, Int32 eventId, Int64 eventReference
                          , EventLogEntryType entryType, enumEventPriority enumPriority)
        {
            DateTime now      = DateTime.Now;
            string   filename = string.Format("{0}_{1}{2}.txt"
                                              , _logFilePrefix
                                              , string.Format("{0:##}{1:##}", now.Month, now.Day)
                                              , now.ToString("HH"));

            int writeAttempts = 0;

            while (writeAttempts < MAX_EventLogWriteAttemptCount)
            {
                try
                {
                    lock (_logFilePrefix)
                    {
                        // just in case there is an OS collision
                        FileMgr.WriteTextToFile(filename
                                                , message + Environment.NewLine
                                                , appendText, true);

                        return;
                    }
                }
                catch
                {
                    ++writeAttempts;   // try a number of times
                }
            }
            if (enumPriority == enumEventPriority.Critical)
            {
                // now we must bail out to caller because we could not write
                throw new ExceptionEvent(enumExceptionEventCodes.EventLogFailoverFileWriteFailed
                                         , string.Format("Failed to write exception text to file: {0} after {1} attempts"
                                                         + " Was attempting to write exception: {2}", filename
                                                         , writeAttempts
                                                         , message));
            }
            // otherwise, the message is lost but it was not critical
        }
        /// <summary>
        /// The function creates a ddl.bat file which calls the back-end specific
        /// command line tool.
        /// </summary>
        /// <param name="processCmd">OS Process Command Object</param>
        /// <param name="processBatchFile">The batch file that will call the command line tool</param>
        /// <param name="cmdFileName">The command file name to parse</param>
        /// <returns>True indicates success; false indicates an error</returns>
        bool ProcessFile(Process processCmd, string processBatchFile, string cmdFileName)
        {
            bool insideCommentBlock = false;

            using (StreamReader sr = new StreamReader(cmdFileName))
            {
                _results.Length = 0;
                string msg = string.Format("Parsing Command File: {0}{1}"
                                           , cmdFileName
                                           , Environment.NewLine);
                _results.Append(msg);
                FileMgr.WriteTextToFile(_outputFileName
                                        , msg
                                        , true
                                        , true);

                string line = sr.ReadLine();
                while (!_exit && line != null)
                {
                    while (_pause && !_exit) // have we been paused
                    {
                        Thread.Sleep(100);
                    }

                    line = line.Trim();
                    if (!insideCommentBlock &&
                        !line.StartsWith(Constants.CommentLineStart) &&
                        !line.StartsWith(Constants.CommentBlockEnd) &&
                        !line.StartsWith(Constants.CommentBlockStart) &&
                        line.Length > 0)
                    {
                        // check for the BreakWithMsg keyword
                        if (line.ToLower().StartsWith(Constants.BreakWithMsg.ToLower()))
                        {
                            // display the message and wait for user input
                            if (ContinueAfterPause(line))
                            {
                                line = sr.ReadLine();
                                continue;
                            }
                            else
                            {
                                _exit = true;
                                return(true);
                            }
                        }

                        if (line.Contains('{') && line.Contains('}'))
                        {
                            line = ReplaceMacros(line);
                        }

                        // check for the call keyword to process another command file
                        if (line.ToLower().StartsWith(Constants.RunCmdFile.ToLower()))
                        {
                            bool aborted = ProcessFile(processCmd, processBatchFile, _ddlSourceDir + "\\"
                                                       + line.ToLower().Replace(
                                                           Constants.RunCmdFile.ToLower(), "").Trim());
                            // check to see if we were aborted
                            if (aborted)
                            {
                                return(aborted);
                            }
                            line = sr.ReadLine();
                            continue;
                        }

                        bool serverOnly = false;
                        // check for the call keyword to process at server level only
                        if (line.ToLower().StartsWith(Constants.ServerOnly.ToLower()))
                        {
                            serverOnly = true;
                            line       = line.ToLower().Replace(Constants.ServerOnly.ToLower(), "").Trim();
                        }

                        string ddlObjectFile = _ddlSourceDir + "\\" + line;
                        if (!File.Exists(ddlObjectFile)) // line is script filename
                        {
                            FileMgr.WriteTextToFile(_outputFileName, string.Format("Error; File: {0} could not be found. {1}"
                                                                                   , ddlObjectFile, Environment.NewLine), true, true);
                        }
                        else
                        {
                            string cmdOutputFile = "cmdOutput.txt";
                            GenerateDDLBatch(ddlObjectFile, processBatchFile, serverOnly, cmdOutputFile);
                            ProcessDDLBatch(processCmd);
                            string results = null;
                            if (File.Exists(cmdOutputFile))
                            {
                                results = FileMgr.ReadTextFileIntoString(cmdOutputFile);
                                if (!string.IsNullOrEmpty(results))
                                {
                                    _results.Append(results);
                                    FileMgr.WriteTextToFile(_outputFileName, results, true, true);
                                    _results.Append(results);
                                }
                            }
                            else // there was some environment setup issue, because there was no cmdOutputFile found
                            {
                                results = string.Format("{0}Error; there was no output produced by the command.{0}"
                                                        + " Possible errors include that the command line utility could not be found.{0}"
                                                        + " Or that the listener for the database is not up or configured for tcpip.{0}"
                                                        + " Or the input credentials are not correct.{0}"
                                                        + " You can try executing the command listed from a dos prompt and viewing the results.{0}"
                                                        + " Please refer to the GettingStarted document.{0}"
                                                        , Environment.NewLine);
                                FileMgr.WriteTextToFile(_outputFileName, results, true, true);
                                _results.Append(results);
                                return(true); // abort the process
                            }
                        }
                    }
                    if (line.StartsWith(Constants.CommentBlockStart))
                    {
                        insideCommentBlock = true;
                    }
                    if (line.StartsWith(Constants.CommentBlockEnd))
                    {
                        insideCommentBlock = false;
                    }
                    line = sr.ReadLine();
                }
            }
            return(_exit ? true : false);
        }
        /// <summary>
        /// Function creates the ddl.bat file with the appropriate command line tool and parameters.
        /// </summary>
        /// <param name="ddlFile">The input file to pass into the command line tool</param>
        /// <param name="ddlBatchFile">The name of the batch file to create</param>
        /// <param name="serverOnly">Boolean indicating whether or not to connect only to the server (not the database);
        /// For example on a create database command.</param>
        /// <param name="cmdOutputFile">The output file name.</param>
        private void GenerateDDLBatch(string ddlFile, string ddlBatchFile, bool serverOnly, string cmdOutputFile)
        {
            string msg = string.Format("Executing Script File: {0}{1}"
                                       , ddlFile
                                       , Environment.NewLine);

            _results.Append(msg);

            FileMgr.WriteTextToFile(_outputFileName
                                    , msg
                                    , true
                                    , true);

            // Generate the BatchFile contents
            StringBuilder cmdScript = new StringBuilder();
            string        cmd       = null;

            if (_dbType == DataAccessMgr.EnumDbType.SqlServer)
            {
                cmd = string.Format("sqlcmd -S {0} {1} {2} -i \"{3}\" -o {4}"
                                    , _dbServer
                                    , (string.IsNullOrEmpty(_userName) ||
                                       string.IsNullOrEmpty(_userPassword))
                            ? "" : string.Format("-U{0} -P{1}", _userName, _userPassword)
                                    , string.IsNullOrEmpty(_dbName) || serverOnly
                            ? "" : string.Format("-d {0} ", _dbName)
                                    , ddlFile
                                    , cmdOutputFile);
                // record to results file indented under filename
                FileMgr.WriteTextToFile(_outputFileName
                                        , string.Format("    {0}{1}", cmd, Environment.NewLine), true, true);
            }
            else if (_dbType == DataAccessMgr.EnumDbType.Oracle)
            {
                // for Oracle we need to issue a spool command for the output
                // so we will be wrapping the actual script file with another file
                // which will issue the spool and exit commands

                string        cmdWrapperFile = "cmdWrapper.sql";
                StringBuilder wrapper        = new StringBuilder();
                wrapper.AppendFormat("spool {0}{1}", cmdOutputFile, Environment.NewLine);
                wrapper.AppendFormat("whenever sqlerror exit sql.sqlcode{0}", Environment.NewLine);
                wrapper.AppendFormat("start \"{0}\"{1}", ddlFile, Environment.NewLine);
                wrapper.AppendFormat("exit{0}", Environment.NewLine);

                FileMgr.WriteTextToFile(cmdWrapperFile, wrapper.ToString(), false, true);
                cmd = string.Format("sqlplus {0}@{1}{2} @{3}"
                                    , !string.IsNullOrEmpty(_userName) &&
                                    !string.IsNullOrEmpty(_userPassword)
                                ? string.Format("{0}/{1}"
                                                , _userName
                                                , _userPassword) : ""
                                    , string.IsNullOrEmpty(_dbServer) ? "" : _dbServer
                                    , _asSysDba ? " as SysDBA" : ""
                                    , cmdWrapperFile);
                // record to results file indented under filename
                FileMgr.WriteTextToFile(_outputFileName
                                        , string.Format("    {0}{1}", cmd, Environment.NewLine), true, true);
            }
            else
            {
                // Db2 does not have a single line option for setting server, db, username, and password
                // so these need to be seperate command lines
                StringBuilder wrapper = new StringBuilder();
                // if there is a server defined, then connect to it
                if (!string.IsNullOrEmpty(_dbServer))
                {
                    // generate the server connect cmd
                    cmd = string.Format("db2 connect to {0} {1}"
                                        , _dbServer
                                        , !string.IsNullOrEmpty(_userName) && // if there is a user/pwd
                                        !string.IsNullOrEmpty(_userPassword)
                                    ? string.Format("user {0} using {1}"
                                                    , _userName
                                                    , _userPassword) : Environment.NewLine);
                    // record to results file indented under filename
                    FileMgr.WriteTextToFile(_outputFileName
                                            , string.Format("    {0}{1}", cmd, Environment.NewLine), true, true);
                    wrapper.AppendFormat("{0}{1}", cmd, Environment.NewLine);
                }

                // if we need to connect to a database
                if (!serverOnly)
                {
                    cmd = string.Format("db2 connect to {0} {1}"
                                        , _dbName
                                        , !string.IsNullOrEmpty(_userName) &&
                                        !string.IsNullOrEmpty(_userPassword)
                                    ? string.Format("user {0} using {1}"
                                                    , _userName
                                                    , _userPassword) : Environment.NewLine);
                    // record to results file indented under filename
                    FileMgr.WriteTextToFile(_outputFileName
                                            , string.Format("    {0}{1}", cmd, Environment.NewLine), true, true);
                    wrapper.AppendFormat("{0}{1}", cmd, Environment.NewLine);
                }

                // format the actual command line command
                cmd = string.Format("db2 -f{0} -z{1}"
                                    , ddlFile
                                    , cmdOutputFile);
                // record to results file indented under filename
                FileMgr.WriteTextToFile(_outputFileName
                                        , string.Format("    {0}{1}", cmd, Environment.NewLine), true, true);
                wrapper.AppendFormat("{0}{1}", cmd, Environment.NewLine);

                cmd = "db2 terminate";
                // record to results file indented under filename
                FileMgr.WriteTextToFile(_outputFileName
                                        , string.Format("    {0}{1}", cmd, Environment.NewLine), true, true);

                cmd = wrapper.ToString() + cmd;
            }

            // remove existing cmdOutputFile and add command
            cmdScript.AppendFormat("if exist {1} del {1}{0}{2}{0}type {1} >> {3}"
                                   , Environment.NewLine
                                   , cmdOutputFile
                                   , cmd
                                   , _outputFileName);

            FileMgr.WriteTextToFile(ddlBatchFile, cmdScript.ToString(), false, true);
        }
        /// <summary>
        /// Begins the asynchronous process of parsing the command file
        /// and processing the embedded DDL files which are referenced in the command file.
        /// Files are processed using following code:
        /// <code>
        /// ProcessStartInfo psi = new ProcessStartInfo();
        /// string processBatchFile = "ddl.bat";
        /// if (_dbType == DbAccessManager.EnumDbType.Db2)
        /// {
        ///     psi.FileName = "db2cmd.exe";
        ///     psi.Arguments = "-c -w -i ddl.bat";
        /// }
        /// else
        /// {
        ///     psi.FileName = "cmd.exe";
        ///     psi.Arguments = "/C ddl.bat";
        /// }
        /// </code>
        /// </summary>
        internal void Start()
        {
            bool     aborted    = false;
            DateTime batchStart = DateTime.Now;
            TimeSpan totalBatch = new TimeSpan(0, 0, 0);

            try
            {
                if (!File.Exists(_inputFileName))
                {
                    throw new ExceptionEvent(enumExceptionEventCodes.FileNotFound
                                             , string.Format("Error; File: {0} could not be found.{1}"
                                                             , _inputFileName
                                                             , Environment.NewLine));
                }

                if (File.Exists(_outputFileName))
                {
                    File.SetAttributes(_outputFileName, FileAttributes.Normal);
                    File.Delete(_outputFileName);
                }

                ProcessStartInfo psi = new ProcessStartInfo();
                string           processBatchFile = "ddl.bat";
                if (_dbType == DataAccessMgr.EnumDbType.Db2)
                {
                    psi.FileName  = "db2cmd.exe";
                    psi.Arguments = "-c -w -i ddl.bat";
                }
                else
                {
                    psi.FileName  = "cmd.exe";
                    psi.Arguments = "/C ddl.bat";
                }
                psi.CreateNoWindow = true;
                psi.WindowStyle    = ProcessWindowStyle.Hidden;
                Process cmdProcess = new Process();
                cmdProcess.StartInfo = psi;

                string msg = string.Format("Batch Started: {0}{1}{1}"
                                           , batchStart
                                           , Environment.NewLine);
                FileMgr.WriteTextToFile(_outputFileName
                                        , msg
                                        , true
                                        , true);
                _results.Append(msg);

                aborted = ProcessFile(cmdProcess, processBatchFile, _inputFileName);

                DateTime batchEnd = DateTime.Now;
                totalBatch = batchEnd - batchStart;
                msg        = string.Format("{3}{3}Batch {0} {1}; Total Time: {2} seconds{3}"
                                           , aborted ? "Aborted:" : "Completed:"
                                           , batchEnd
                                           , totalBatch.TotalSeconds
                                           , Environment.NewLine);
                FileMgr.WriteTextToFile(_outputFileName
                                        , msg
                                        , true
                                        , true);
                _results.Append(msg);
            }
            catch (Exception Exc)
            {
                _results.Append(Exc.Message + Exc.StackTrace);
                totalBatch = DateTime.Now - batchStart;
                aborted    = true;
            }
            finally
            {
                // let caller know the process is completed
                _dbSetupCompletedDelegate(_results.ToString(), aborted, totalBatch);
            }
        }