/// <summary>
        /// Initialises the object to work with the given executable.
        /// </summary>
        /// <param name="executableFileName">The executable to be managed.</param>
        public void Initialize(string executableFileName)
        {
            if (!File.Exists(executableFileName))
            {
                throw new UserException(string.Format(CultureInfo.CurrentCulture, Messages.SRMExeNotFound, executableFileName));
            }

            this.exeFileName     = executableFileName;
            this.configFileName  = executableFileName + ".config";
            this.configFileState = ConfigFileState.Unknown;
        }
        /// <summary>
        /// Restores the executable's configuration file to its original state.
        /// </summary>
        public void RestoreOriginalConfiguration()
        {
            Trace.WriteLine(string.Format(CultureInfo.InvariantCulture, "Restoring original application configuration"));
            if (this.configFileState == ConfigFileState.Missing || this.configFileState == ConfigFileState.Moved)
            {
                File.Delete(this.configFileName);
            }

            if (this.configFileState == ConfigFileState.Moved)
            {
                File.Move(this.renamedConfigFileName, this.configFileName);
            }

            this.configFileState = ConfigFileState.Unknown; // so it is safe to do a Dispose even if restore has been called explicitly
            Trace.WriteLine(string.Format(CultureInfo.InvariantCulture, "Finished restoring original application configuration"));
        }
        /// <summary>
        /// Kept separate so get good stack trace in case of an exception
        /// </summary>
        private void SetupForTraceImpl()
        {
            this.configFileState = File.Exists(this.configFileName) ? ConfigFileState.Existed : ConfigFileState.Missing;

            XmlDocument config = new XmlDocument();

            if (this.configFileState == ConfigFileState.Existed)
            {
                config.Load(this.configFileName);
            }

            XPathNavigator configNav = config.CreateNavigator();

            // Add <configuration> element if not already present
            XPathNavigator configurationElementNav = configNav.SelectSingleNode("/configuration");

            if (configurationElementNav == null)
            {
                configNav.AppendChildElement(null, "configuration", null, null);
                configurationElementNav = configNav.SelectSingleNode("/configuration");
            }

            // Add system.diagnostics section, replace any existing section
            XPathNavigator systemDiagnosticsElementNav = configNav.SelectSingleNode("/configuration/system.diagnostics");

            if (systemDiagnosticsElementNav != null)
            {
                systemDiagnosticsElementNav.ReplaceSelf(DiagnosticsSectionTemplate.Replace("#LOGFILE#", this.traceFileName));
            }
            else
            {
                configurationElementNav.PrependChild(DiagnosticsSectionTemplate.Replace("#LOGFILE#", this.traceFileName));
            }

            // Add <system.serviceModel> element if not already present
            XPathNavigator serviceModelNav = configNav.SelectSingleNode("/configuration/system.serviceModel");

            if (serviceModelNav == null)
            {
                configurationElementNav.AppendChildElement(null, "system.serviceModel", null, null);
                serviceModelNav = configNav.SelectSingleNode("/configuration/system.serviceModel");
            }

            // Add service model diagnostics section, replace any existing section
            XPathNavigator serviceModelDiagnosticsElementNav = configNav.SelectSingleNode("/configuration/system.serviceModel/diagnostics");

            if (serviceModelDiagnosticsElementNav != null)
            {
                serviceModelDiagnosticsElementNav.ReplaceSelf(ServiceModelSection);
            }
            else
            {
                serviceModelNav.PrependChild(ServiceModelSection);
            }

            // Write the new config file
            try
            {
                if (this.configFileState == ConfigFileState.Existed)
                {
                    this.renamedConfigFileName = this.configFileName + "._wcfunit";
                    File.Move(this.configFileName, this.renamedConfigFileName);
                    this.configFileState = ConfigFileState.Moved;
                    Trace.WriteLine(string.Format(CultureInfo.InvariantCulture, "Renamed application config file for the program under test to {0}", this.renamedConfigFileName));
                }

                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Indent      = true;
                settings.CloseOutput = true;
                settings.Encoding    = Encoding.UTF8;
                using (XmlWriter xw = XmlWriter.Create(this.configFileName, settings))
                {
                    config.WriteTo(xw);
                }
            }
            catch (UnauthorizedAccessException uae)
            {
                if (this.configFileState == ConfigFileState.Moved)
                {
                    File.Move(this.renamedConfigFileName, this.configFileName);
                    this.configFileState = ConfigFileState.Unknown;
                }

                throw new UserException(Messages.SRMAccessDenied, uae);
            }
            catch (Exception)
            {
                // Make sure we put things back if we can whatever happens
                if (this.configFileState == ConfigFileState.Moved)
                {
                    File.Move(this.renamedConfigFileName, this.configFileName);
                    this.configFileState = ConfigFileState.Unknown;
                }

                throw;
            }
        }