public static LispIDEConfigSection GetSection(ConfigurationUserLevel configLevel)
        {
            string appData = Environment.GetFolderPath(
                Environment.SpecialFolder.ApplicationData);
            string localData = Environment.GetFolderPath(
                Environment.SpecialFolder.LocalApplicationData);

            ExeConfigurationFileMap exeMap = new ExeConfigurationFileMap();

            exeMap.ExeConfigFilename         = Application.ExecutablePath + ".config";
            exeMap.RoamingUserConfigFilename =
                Path.Combine(appData, @"LispIDEdotNet\user.config");
            exeMap.LocalUserConfigFilename =
                Path.Combine(localData, @"LispIDEdotNet\user.config");

            System.Configuration.Configuration config =
                System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(exeMap,
                                                                                     configLevel);

            LispIDEConfigSection configSection = (LispIDEConfigSection)config.GetSection("LispIDEConfig");

            if (configSection == null)
            {
                configSection = new LispIDEConfigSection();
                config.Sections.Add("LispIDEConfig", configSection);
            }
            configSection.config      = config;
            configSection.configLevel = configLevel;

            return(configSection);
        }
        private void InternalSave(bool external)
        {
            lock (_lock)
            {
                if (config != null)
                {
                    try
                    {
                        config.Save();
                    } catch (Exception)
                    {
                        /* If the config file was externally modified, we have to load the configuration file
                         * and merge the changes. Instead of merging, we'll just concern ourselves with the last
                         * closed instance of the application. This is not the most elegant solution
                         * but it seems to work. Unfortunately, the save method throws the same exception for
                         * an externally modified file and an unavailable or locked file. Therefore, we must
                         * make sure we don't end up in an infinite loop. So, we use the external flag to determine
                         * if the call to save was internal (and therefore the second iteration) or external.
                         */

                        try
                        {
                            if (!external)
                            {
                                throw;
                            }

                            LispIDEConfigSection configSection = GetSection(this.ConfigLevel);

                            foreach (ConfigurationProperty property in this.Properties)
                            {
                                configSection[property.Name] = this[property];
                            }

                            configSection.InternalSave(false);

                            this.ResetModified();
                        } catch (Exception)
                        {
                            MessageBox.Show("There was an error saving the configuration file.", "Configuration Save Error",
                                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                }
            }
        }