瀏覽代碼

* Configuration.cs, ConfigurationElement.cs, ConfigurationLocation.cs,
ConfigurationLocationCollection.cs, ConfigurationProperty.cs,
ConfigurationPropertyAttribute.cs, ConfigurationSection.cs,
ConfigurationSectionCollection.cs, ConfigurationSectionGroup.cs,
ConfigurationSectionGroupCollection.cs,IntegerConfigurationProperty.cs,
RuntimeOnlySection.cs: Initial implementation.
* ConfigurationAllowDefinition.cs: Removed XML_DEP ifdef
* ConfigurationException.cs: format fix.
* ConfigInfo.cs, SectionInfo.cs, SectionGroupInfo.cs: New support
classes.

svn path=/trunk/mcs/; revision=35640

Lluis Sanchez 21 年之前
父節點
當前提交
62d863de11

+ 13 - 0
mcs/class/System/System.Configuration/ChangeLog

@@ -1,3 +1,16 @@
+2004-11-04  Lluis Sanchez Gual <[email protected]>
+
+	* Configuration.cs, ConfigurationElement.cs, ConfigurationLocation.cs,
+	  ConfigurationLocationCollection.cs, ConfigurationProperty.cs,
+	  ConfigurationPropertyAttribute.cs, ConfigurationSection.cs,
+	  ConfigurationSectionCollection.cs, ConfigurationSectionGroup.cs,
+	  ConfigurationSectionGroupCollection.cs,IntegerConfigurationProperty.cs,
+	  RuntimeOnlySection.cs: Initial implementation.
+	* ConfigurationAllowDefinition.cs: Removed XML_DEP ifdef
+	* ConfigurationException.cs: format fix.
+	* ConfigInfo.cs, SectionInfo.cs, SectionGroupInfo.cs: New support
+	  classes.
+
 2004-09-10  Tim Coleman <[email protected]>
 	* ConfigurationElementCollection.cs ConfigurationElementCollectionType.cs:
 		New Fx 2.0 stubs

+ 67 - 0
mcs/class/System/System.Configuration/ConfigInfo.cs

@@ -0,0 +1,67 @@
+//
+// System.Configuration.ConfigInfo.cs
+//
+// Authors:
+//	Lluis Sanchez ([email protected])
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+#if NET_2_0 && XML_DEP
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Xml;
+using System.IO;
+
+namespace System.Configuration {
+
+	internal abstract class ConfigInfo
+	{
+		public string Name;
+		public string TypeName;
+		Type type;
+		public string FileName;
+		
+		public object CreateInstance ()
+		{
+			if (type == null) type = Type.GetType (TypeName);
+			return Activator.CreateInstance (type);
+		}
+		
+		public abstract bool HasConfigContent (Configuration cfg);
+		public abstract bool HasDataContent (Configuration cfg);
+		
+#if (XML_DEP)
+		protected void ThrowException (string text, XmlTextReader reader)
+		{
+			throw new ConfigurationException (text, FileName, reader.LineNumber);
+		}
+		
+		public abstract void ReadConfig (Configuration cfg, XmlTextReader reader);
+		public abstract void WriteConfig (Configuration cfg, XmlWriter writer, ConfigurationUpdateMode mode);
+		public abstract void ReadData (Configuration config, XmlTextReader reader);
+		public abstract void WriteData (Configuration config, XmlWriter writer, ConfigurationUpdateMode mode);
+#endif
+	}
+}
+
+#endif

+ 344 - 116
mcs/class/System/System.Configuration/Configuration.cs

@@ -3,6 +3,7 @@
 //
 // Authors:
 //	Duncan Mak ([email protected])
+//  Lluis Sanchez Gual ([email protected])
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -27,124 +28,351 @@
 //
 #if NET_2_0 && XML_DEP
 using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Xml;
+using System.IO;
 
 namespace System.Configuration {
 
-        public sealed class Configuration
-        {
-                internal Configuration ()
-                {
-                }
-
-                public AppSettingsSection AppSettings {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public PathLevel ConfigurationPathLevel {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public ConnectionStringsSection ConnectionStrings {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public string FilePath {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public bool HasFile {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public ConfigurationLocationCollection Locations {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public string Path {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public ConfigurationSectionGroup RootSectionGroup {
-                        get { throw new NotImplementedException (); }                        
-                }
-
-                public ConfigurationSectionGroupCollection SectionGroups {
-                        get { throw new NotImplementedException (); }                        
-                }
-
-                public ConfigurationSectionCollection Sections {
-                        get { throw new NotImplementedException (); }                        
-                }
-
-                public static Configuration GetExeConfiguration (string path, ConfigurationUserLevel level)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public static Configuration GetMachineConfiguration ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public static Configuration GetMachineConfiguration (string path)
-                {
-                        throw new NotImplementedException ();
-                }
-                
-                public static Configuration GetMachineConfiguration (string path, string server)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public static Configuration GetMachineConfiguration (
-                                string path, string server, IntPtr user_token)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public static Configuration GetMachineConfiguration (
-                                string path, string server, string username, string password)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public static Configuration GetWebConfiguration ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public static Configuration GetWebConfiguration (string path)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public static Configuration GetWebConfiguration (string path, string site)
-                {
-                        throw new NotImplementedException ();
-                }
-                
-                public static Configuration GetWebConfiguration (string path, string site, string subpath)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public static Configuration GetWebConfiguration (
-                                string path, string site, string subpath, string server)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public static Configuration GetWebConfiguration (
-                                string path, string site, string subpath, string server, IntPtr user_token)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public static Configuration GetWebConfiguration (
-                                string path, string site, string subpath, string server, string username, string password)
-                {
-                        throw new NotImplementedException ();
-                }
-        }
+	public sealed class Configuration
+	{
+		Configuration parent;
+		Hashtable elementData = new Hashtable ();
+		string fileName;
+		ConfigurationSectionGroup rootSectionGroup;
+		ConfigurationLocationCollection locations;
+		SectionGroupInfo rootGroup;
+		
+		internal Configuration (): this (null, null)
+		{
+		}
+		
+		internal Configuration (string file): this (file, null)
+		{
+		}
+		
+		internal Configuration (Configuration parent): this (null, parent)
+		{
+		}
+		
+		internal Configuration (string file, Configuration parent)
+		{
+			fileName = file;
+			this.parent = parent;
+			if (parent != null)
+				rootGroup = parent.rootGroup;
+			else {
+				rootGroup = new SectionGroupInfo ();
+				rootGroup.FileName = file;
+			}
+			
+			if (file != null) Load (file);
+		}
+		
+		internal Configuration Parent {
+			get { return parent; }
+		}
+		
+		internal string FileName {
+			get { return fileName; }
+		}
+
+		[MonoTODO]
+		public AppSettingsSection AppSettings {
+			get { throw new NotImplementedException (); }
+		}
+
+		[MonoTODO]
+		public PathLevel ConfigurationPathLevel {
+			get { throw new NotImplementedException (); }
+		}
+
+		[MonoTODO]
+		public ConnectionStringsSection ConnectionStrings {
+			get { throw new NotImplementedException (); }
+		}
+
+		[MonoTODO]
+		public string FilePath {
+			get { throw new NotImplementedException (); }
+		}
+
+		[MonoTODO]
+		public bool HasFile {
+			get { throw new NotImplementedException (); }
+		}
+
+		public ConfigurationLocationCollection Locations {
+			get {
+				if (locations == null) locations = new ConfigurationLocationCollection ();
+				return locations;
+			}
+		}
+
+		[MonoTODO]
+		public string Path {
+			get { throw new NotImplementedException (); }
+		}
+
+		public ConfigurationSectionGroup RootSectionGroup {
+			get {
+				if (rootSectionGroup == null) {
+					rootSectionGroup = new ConfigurationSectionGroup ();
+					rootSectionGroup.Initialize (this, rootGroup);
+				}
+				return rootSectionGroup;
+			}                        
+		}
+
+		public ConfigurationSectionGroupCollection SectionGroups {
+			get { return RootSectionGroup.SectionGroups; }                        
+		}
+
+		public ConfigurationSectionCollection Sections {
+			get { return RootSectionGroup.Sections; }
+		}
+
+		public static Configuration GetExeConfiguration (string path, ConfigurationUserLevel level)
+		{
+			return new Configuration (path + ".config", GetMachineConfiguration ());
+		}
+
+		public static Configuration GetMachineConfiguration ()
+		{
+			return GetMachineConfiguration (System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile);
+		}
+
+		public static Configuration GetMachineConfiguration (string path)
+		{
+			return new Configuration (path);
+		}
+		
+		[MonoTODO]
+		public static Configuration GetMachineConfiguration (string path, string server)
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		public static Configuration GetMachineConfiguration (
+						string path, string server, IntPtr user_token)
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		public static Configuration GetMachineConfiguration (
+						string path, string server, string username, string password)
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		public static Configuration GetWebConfiguration ()
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		public static Configuration GetWebConfiguration (string path)
+		{
+			return new Configuration (path, GetMachineConfiguration ());
+		}
+
+		[MonoTODO]
+		public static Configuration GetWebConfiguration (string path, string site)
+		{
+			throw new NotImplementedException ();
+		}
+		
+		[MonoTODO]
+		public static Configuration GetWebConfiguration (string path, string site, string subpath)
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		public static Configuration GetWebConfiguration (
+						string path, string site, string subpath, string server)
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		public static Configuration GetWebConfiguration (
+						string path, string site, string subpath, string server, IntPtr user_token)
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		public static Configuration GetWebConfiguration (
+						string path, string site, string subpath, string server, string username, string password)
+		{
+			throw new NotImplementedException ();
+		}
+		
+		internal ConfigurationSection GetSectionInstance (SectionInfo config, bool createDefaultInstance)
+		{
+			object data = elementData [config];
+			ConfigurationSection sec = data as ConfigurationSection;
+			if (sec != null || !createDefaultInstance) return sec;
+			
+			object secObj = config.CreateInstance () as ConfigurationSection;
+			if (!(secObj is ConfigurationSection))
+				sec = new RuntimeOnlySection ();
+			else
+				sec = (ConfigurationSection) secObj;
+				
+			ConfigurationSection parentSection = parent != null ? parent.GetSectionInstance (config, true) : null;
+			sec.RawXml = data as string;
+			sec.Reset (parentSection, this);
+			
+			if (data != null) {
+				XmlTextReader r = new XmlTextReader (new StringReader (data as string));
+				sec.ReadXml (r, this);
+				r.Close ();
+			}
+			
+			elementData [config] = sec;
+			return sec;
+		}
+		
+		internal ConfigurationSectionGroup GetSectionGroupInstance (SectionGroupInfo group)
+		{
+			ConfigurationSectionGroup gr = group.CreateInstance () as ConfigurationSectionGroup;
+			if (gr != null) gr.Initialize (this, group);
+			return gr;
+		}
+		
+		internal void SetConfigurationSection (SectionInfo config, ConfigurationSection sec)
+		{
+			elementData [config] = sec;
+		}
+		
+		internal void SetSectionData (SectionInfo config, string data)
+		{
+			elementData [config] = data;
+		}
+		
+		internal void CreateSection (SectionGroupInfo group, string name, ConfigurationSection sec)
+		{
+			if (group.HasChild (name)) throw new ConfigurationException ("Cannot add a ConfigurationSection. A section or section group already exists with the name '" + name + "'");
+			if (sec.TypeName == null) sec.TypeName = sec.GetType ().AssemblyQualifiedName;
+			sec.SetName (name);
+
+			SectionInfo section = new SectionInfo (name, sec.TypeName, sec.AllowLocation, sec.AllowDefinition);
+			section.FileName = FileName;
+			group.AddChild (section);
+			elementData [section] = sec;
+		}
+		
+		internal void CreateSectionGroup (SectionGroupInfo parentGroup, string name, ConfigurationSectionGroup sec)
+		{
+			if (parentGroup.HasChild (name)) throw new ConfigurationException ("Cannot add a ConfigurationSectionGroup. A section or section group already exists with the name '" + name + "'");
+			if (sec.TypeName == null) sec.TypeName = sec.GetType ().AssemblyQualifiedName;
+			sec.SetName (name);
+
+			SectionGroupInfo section = new SectionGroupInfo (name, sec.TypeName);
+			section.FileName = FileName;
+			parentGroup.AddChild (section);
+			elementData [section] = sec;
+		}
+		
+		internal void RemoveConfigInfo (ConfigInfo config)
+		{
+			elementData.Remove (config);
+		}
+		
+		public void Update ()
+		{
+			Update (ConfigurationUpdateMode.Full, true);
+		}
+		
+		public void Update (ConfigurationUpdateMode mode)
+		{
+			Update (mode, false);
+		}
+		
+		[MonoTODO]
+		public void Update (ConfigurationUpdateMode mode, bool forceUpdateAll)
+		{
+			XmlTextWriter tw = new XmlTextWriter (new StreamWriter (fileName));
+			tw.Formatting = Formatting.Indented;
+			try {
+				tw.WriteStartElement ("configuration");
+				if (rootGroup.HasConfigContent (this)) {
+					rootGroup.WriteConfig (this, tw, mode);
+				}
+				rootGroup.WriteRootData (tw, this, mode);
+				tw.WriteEndElement ();
+			}
+			finally {
+				tw.Close ();
+			}
+		}
+		
+		internal bool Load (string fileName)
+		{
+			this.fileName = fileName;
+			if (!File.Exists (fileName))
+				throw new ConfigurationException ("File '" + fileName + "' not found");
+#if (XML_DEP)
+			XmlTextReader reader = null;
+
+			try {
+				FileStream fs = new FileStream (fileName, FileMode.Open, FileAccess.Read);
+				reader = new XmlTextReader (fs);
+				ReadConfigFile (reader, fileName);
+/*			} catch (ConfigurationException) {
+				throw;
+			} catch (Exception e) {
+				throw new ConfigurationException ("Error reading " + fileName, e);
+*/			} finally {
+				if (reader != null)
+					reader.Close();
+			}
+#endif
+			return true;
+		}
+
+#if (XML_DEP)
+
+		internal void ReadConfigFile (XmlTextReader reader, string fileName)
+		{
+			reader.MoveToContent ();
+			if (reader.NodeType != XmlNodeType.Element || reader.Name != "configuration")
+				ThrowException ("Configuration file does not have a valid root element", reader);
+
+			if (reader.HasAttributes)
+				ThrowException ("Unrecognized attribute in root element", reader);
+
+			if (reader.IsEmptyElement) {
+				reader.Skip ();
+				return;
+			}
+			
+			reader.ReadStartElement ();
+			reader.MoveToContent ();
+
+			if (reader.LocalName == "configSections") {
+				if (reader.HasAttributes)
+					ThrowException ("Unrecognized attribute in <configSections>.", reader);
+				
+				rootGroup.ReadConfig (this, reader);
+			}
+			
+			rootGroup.ReadRootData (reader, this);
+		}
+		
+#endif
+
+		private void ThrowException (string text, XmlTextReader reader)
+		{
+			throw new ConfigurationException (text, fileName, reader.LineNumber);
+		}
+	}
 }
+
 #endif

+ 1 - 1
mcs/class/System/System.Configuration/ConfigurationAllowDefinition.cs

@@ -26,7 +26,7 @@
 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
 //
 
-#if NET_2_0 && XML_DEP
+#if NET_2_0
 namespace System.Configuration
 {
         public enum ConfigurationAllowDefinition

+ 404 - 148
mcs/class/System/System.Configuration/ConfigurationElement.cs

@@ -3,6 +3,7 @@
 //
 // Authors:
 //	Duncan Mak ([email protected])
+//  Lluis Sanchez Gual ([email protected])
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -30,157 +31,412 @@
 #if XML_DEP
 using System.Collections;
 using System.Xml;
+using System.Reflection;
+using System.IO;
+using System.ComponentModel;
 
 namespace System.Configuration
 {
-        public abstract class ConfigurationElement
-        {
-                protected ConfigurationElement ()
-                {
-                }
-
-                protected internal virtual ConfigurationPropertyCollection CollectionKeyProperties {
-                        get {
-                                throw new NotImplementedException ();
-                        }
-                }
-
-                protected internal object this [ConfigurationProperty property] {
-                        get {
-                                throw new NotImplementedException ();
-                        }
-
-                        set {
-                                throw new NotImplementedException ();
-                        }
-                }
-
-                protected internal object this [string property_name] {
-                        get {
-                                throw new NotImplementedException ();
-                        }
-
-                        set {
-                                throw new NotImplementedException ();
-                        }
-                }
-
-                protected internal virtual ConfigurationPropertyCollection Properties {
-                        get {
-                                throw new NotImplementedException ();
-                        }
-                }
-
-                public override bool Equals (object compareTo)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public override int GetHashCode ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool HasValue (string key)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public string PropertyFileName ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public int PropertyLineNumber ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                protected internal virtual void Deserialize (
-                        XmlReader reader, bool serialize_collection_key)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                protected virtual bool HandleUnrecognizedAttribute (
-                        string name, string value)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                protected virtual bool HandleUnrecognizedElement (
-                        string element, XmlReader reader)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                protected internal virtual void InitializeDefault ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                protected internal virtual bool IsModified ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                protected internal virtual void ReadXml (XmlReader reader, object context)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                protected internal virtual void Reset (
-                        ConfigurationElement parent_element, object context)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                protected internal virtual void ResetModified ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                protected internal virtual bool Serialize (
-                        XmlWriter writer, bool serialize_collection_key)
-                {
-                        throw new NotImplementedException ();
-                }
-                        
-                protected internal virtual bool SerializeAttributeOnRemove (
-                        ConfigurationProperty property)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                protected internal virtual bool SerializeToXmlElement (
-                        XmlWriter writer, string element_name)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                protected internal virtual void UnMerge (
-                        ConfigurationElement source, ConfigurationElement parent,
-                        bool serialize_collection_key, object context,
-                        ConfigurationUpdateMode update_mode)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                protected virtual void ValidateRequiredProperties (
-                        ConfigurationPropertyCollection properties,
-                        bool serialize_collection_key)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                protected internal virtual string WriteXml (
-                        ConfigurationElement parent,
-                        object context, string name,
-                        ConfigurationUpdateMode update_mode)
-                {
-                        throw new NotImplementedException ();
-                }
-        }
+	public abstract class ConfigurationElement
+	{
+		static Hashtable elementMaps = new Hashtable ();
+		Hashtable values;
+		string rawXml;
+		bool modified;
+		ElementMap map;
+		
+		protected ConfigurationElement ()
+		{
+			map = GetMap (GetType());
+		}
+		
+		internal string RawXml {
+			get { return rawXml; }
+			set { rawXml = value; }
+		}
+
+		protected internal virtual ConfigurationPropertyCollection CollectionKeyProperties {
+			get {
+				return map.KeyProperties;
+			}
+		}
+
+		protected internal object this [ConfigurationProperty property] {
+			get {
+				if (values == null || !values.ContainsKey (property)) {
+					if (property.IsElement) {
+						object elem = Activator.CreateInstance (property.Type);
+						this [property] = elem;
+						return elem;
+					}
+					else
+						return property.DefaultValue;
+				}
+				else
+					return values [property];
+			}
+
+			set {
+				if (object.Equals (value, property.DefaultValue)) {
+					if (values == null) return;
+					values.Remove (property);
+				}
+				else {
+					if (values == null) values = new Hashtable ();
+					values [property] = value;
+				}
+				modified = true;
+			}
+		}
+
+		protected internal object this [string property_name] {
+			get {
+				ConfigurationProperty prop = map.Properties [property_name];
+				if (prop == null) throw new InvalidOperationException ("Property '" + property_name + "' not found in configuration section");
+				return this [prop];
+			}
+
+			set {
+				ConfigurationProperty prop = map.Properties [property_name];
+				if (prop == null) throw new InvalidOperationException ("Property '" + property_name + "' not found in configuration section");
+				this [prop] = value;
+			}
+		}
+
+		protected internal virtual ConfigurationPropertyCollection Properties {
+			get {
+				return map.Properties;
+			}
+		}
+
+		[MonoTODO]
+		public override bool Equals (object compareTo)
+		{
+			return base.Equals (compareTo);
+		}
+
+		[MonoTODO]
+		public override int GetHashCode ()
+		{
+			return base.GetHashCode ();
+		}
+
+		public bool HasValue (string key)
+		{
+			ConfigurationProperty prop = map.Properties [key];
+			if (prop == null) return false;
+			if (values == null) return false;
+			return values.ContainsKey (prop);
+		}
+
+		[MonoTODO]
+		public string PropertyFileName ()
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		public int PropertyLineNumber ()
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		protected internal virtual void Deserialize (
+				XmlReader reader, bool serialize_collection_key)
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		protected virtual bool HandleUnrecognizedAttribute (
+				string name, string value)
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		protected virtual bool HandleUnrecognizedElement (
+				string element, XmlReader reader)
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		protected internal virtual void InitializeDefault ()
+		{
+			values = null;
+		}
+
+		protected internal virtual bool IsModified ()
+		{
+			return modified;
+		}
+
+		[MonoTODO]
+		protected internal virtual void ReadXml (XmlReader reader, object context)
+		{
+			Hashtable readProps = new Hashtable ();
+			
+			reader.MoveToContent ();
+			if (!map.HasProperties) {
+				reader.Skip ();
+				return;
+			}
+			
+			while (reader.MoveToNextAttribute ())
+			{
+				ConfigurationProperty prop = map.Properties [reader.LocalName];
+				if (prop == null)
+					throw new ConfigurationException ("Unrecognized attribute '" + reader.LocalName + "'.");
+				
+				if (readProps.Contains (prop))
+					throw new ConfigurationException ("The attribute '" + prop.Name + "' may only appear once in this element.");
+				
+				object val = prop.ConvertFromString (reader.Value);
+				if (!object.Equals (val, prop.DefaultValue))
+					this [prop] = val;
+				readProps [prop] = prop;
+			}
+			
+			reader.MoveToElement ();
+			if (reader.IsEmptyElement) {
+				reader.Skip ();
+				return;
+			}
+			
+			reader.ReadStartElement ();
+			reader.MoveToContent ();
+			
+			while (reader.NodeType != XmlNodeType.EndElement)
+			{
+				if (reader.NodeType != XmlNodeType.Element) {
+					reader.Skip ();
+					continue;
+				}
+				
+				ConfigurationProperty prop = map.Properties [reader.LocalName];
+				if (prop == null)
+					throw new ConfigurationException ("Unrecognized element '" + reader.LocalName + "'.");
+				
+				if (!prop.IsElement)
+					throw new ConfigurationException ("Property '" + prop.Name + "' is not a ConfigurationElement.");
+				
+				if (readProps.Contains (prop))
+					throw new ConfigurationException ("The element <" + prop.Name + "> may only appear once in this section.");
+				
+				ConfigurationElement val = this [prop] as ConfigurationElement;
+				val.ReadXml (reader, context);
+				readProps [prop] = prop;
+			}
+			modified = false;
+		}
+
+		[MonoTODO]
+		protected internal virtual void Reset (ConfigurationElement parent_element, object context)
+		{
+			if (parent_element != null) {
+				if (!map.HasProperties) return;
+				values = null;
+				foreach (ConfigurationProperty prop in map.Properties) {
+					if (parent_element.HasValue (prop.Name))
+						this [prop] = parent_element [prop.Name];
+				}
+			}
+			else
+				InitializeDefault ();
+		}
+
+		protected internal virtual void ResetModified ()
+		{
+			modified = false;
+		}
+
+		[MonoTODO ("Return value?")]
+		protected internal virtual bool Serialize (XmlWriter writer, bool serializeCollectionKey)
+		{
+			if (values == null || !map.HasProperties) return true;
+			
+			ArrayList elems = new ArrayList ();
+			foreach (DictionaryEntry entry in values)
+			{
+				ConfigurationProperty prop = (ConfigurationProperty) entry.Key;
+				if (serializeCollectionKey && !prop.IsKey) continue;
+				if (prop.IsElement) continue;
+				
+				if (!object.Equals (entry.Value, prop.DefaultValue))
+					writer.WriteAttributeString (prop.Name, prop.ConvertToString (entry.Value));
+			}
+			if (serializeCollectionKey) return true;
+			
+			foreach (DictionaryEntry entry in values)
+			{
+				ConfigurationProperty prop = (ConfigurationProperty) entry.Key;
+				if (!prop.IsElement) continue;
+				
+				ConfigurationElement val = entry.Value as ConfigurationElement;
+				if (val != null)
+					val.SerializeToXmlElement (writer, prop.Name);
+			}
+			return true;
+		}
+				
+		[MonoTODO]
+		protected internal virtual bool SerializeAttributeOnRemove (
+				ConfigurationProperty property)
+		{
+			throw new NotImplementedException ();
+		}
+
+		protected internal virtual bool SerializeToXmlElement (
+				XmlWriter writer, string elementName)
+		{
+			writer.WriteStartElement (elementName);
+			Serialize (writer, false);
+			writer.WriteEndElement ();
+			return true;
+		}
+
+		protected internal virtual void UnMerge (
+				ConfigurationElement source, ConfigurationElement parent,
+				bool serializeCollectionKey, object context,
+				ConfigurationUpdateMode updateMode)
+		{
+			if (source.map != parent.map)
+				throw new ConfigurationException ("Can't unmerge two elements of different type");
+			
+			ElementMap map = source.map;
+			if (!map.HasProperties) return;
+			
+			foreach (ConfigurationProperty prop in map.Properties) {
+				if (source.HasValue (prop.Name)) {
+					object sourceValue = source [prop];
+					if (!parent.HasValue (prop.Name)) {
+						this [prop] = sourceValue;
+					}
+					else if (sourceValue != null) {
+						object parentValue = parent [prop];
+						if (parentValue != null && prop.IsElement) {
+							ConfigurationElement copy = (ConfigurationElement) Activator.CreateInstance (prop.Type);
+							copy.UnMerge ((ConfigurationElement) sourceValue, (ConfigurationElement) parentValue, serializeCollectionKey, context, updateMode);
+							this [prop] = copy;
+						}
+						else {
+							if (!object.Equals (sourceValue, parentValue))
+								this [prop] = sourceValue;
+						}
+					}
+				}
+			}
+		}
+
+		[MonoTODO]
+		protected virtual void ValidateRequiredProperties (
+				ConfigurationPropertyCollection properties,
+				bool serialize_collection_key)
+		{
+			throw new NotImplementedException ();
+		}
+
+		protected internal virtual string WriteXml (
+				ConfigurationElement parent,
+				object context, string name,
+				ConfigurationUpdateMode updateMode)
+		{
+			ConfigurationElement elem;
+			if (parent != null) {
+				elem = (ConfigurationElement) Activator.CreateInstance (GetType());
+				elem.UnMerge (this, parent, false, context, updateMode);
+			}
+			else
+				elem = this;
+			
+			StringWriter sw = new StringWriter ();
+			XmlTextWriter tw = new XmlTextWriter (sw);
+			tw.Formatting = Formatting.Indented;
+			elem.SerializeToXmlElement (tw, name);
+			tw.Close ();
+			return sw.ToString ();
+		}
+		
+		internal static ElementMap GetMap (Type t)
+		{
+			lock (elementMaps) {
+				ElementMap map = elementMaps [t] as ElementMap;
+				if (map != null) return map;
+				
+				if (typeof(ConfigurationElementCollection).IsAssignableFrom (t))
+					map = new CollectionElementMap (t);
+				else
+					map = new ElementMap (t);
+				elementMaps [t] = map;
+				return map;
+			}
+		}
+	}
+	
+	internal class ElementMap
+	{
+		ConfigurationPropertyCollection properties;
+		ConfigurationPropertyCollection keyProperties;
+		
+		public ElementMap (Type t)
+		{
+			ReflectProperties (t);
+		}
+		
+		protected void ReflectProperties (Type t)
+		{
+			PropertyInfo[] props = t.GetProperties ();
+			foreach (PropertyInfo prop in props)
+			{
+				ConfigurationPropertyAttribute at = (ConfigurationPropertyAttribute) Attribute.GetCustomAttribute (prop, typeof(ConfigurationPropertyAttribute)) as ConfigurationPropertyAttribute;
+				if (at == null) continue;
+				string name = at.Name != null ? at.Name : prop.Name;
+				
+				ConfigurationValidationAttribute validator = (ConfigurationValidationAttribute) Attribute.GetCustomAttribute (t, typeof(ConfigurationValidationAttribute)) as ConfigurationValidationAttribute;
+				TypeConverter converter = TypeDescriptor.GetConverter (prop.PropertyType);
+				ConfigurationProperty cp = new ConfigurationProperty (name, prop.PropertyType, at.DefaultValue, converter, validator, at.Flags);
+				
+				if (properties == null) properties = new ConfigurationPropertyCollection ();
+				properties.Add (cp);
+			}
+		}
+		
+		public bool HasProperties
+		{
+			get { return properties != null && properties.Count > 0; }
+		}
+		
+		public ConfigurationPropertyCollection Properties
+		{
+			get {
+				if (properties == null) properties = new ConfigurationPropertyCollection ();
+				return properties;
+			}
+		}
+		
+		public ConfigurationPropertyCollection KeyProperties {
+			get {
+				if (keyProperties == null) {
+					keyProperties = new ConfigurationPropertyCollection ();
+					
+					if (properties != null)
+						foreach (ConfigurationProperty p in properties)
+							if (p.IsKey) keyProperties.Add (p);
+				}
+				return keyProperties;
+			}
+		}
+	}
+	
+	internal class CollectionElementMap: ElementMap
+	{
+		public CollectionElementMap (Type t): base (t)
+		{
+		}
+	}
 }
+
 #endif
 #endif

+ 1 - 1
mcs/class/System/System.Configuration/ConfigurationException.cs

@@ -133,7 +133,7 @@ namespace System.Configuration
 				string f = (filename == null) ? String.Empty : filename;
 				string l = (line == 0) ? String.Empty : (" line " + line);
 
-				return baseMsg + "(" + f + l + ")";
+				return baseMsg + " (" + f + l + ")";
 			}
 		}
 

+ 24 - 12
mcs/class/System/System.Configuration/ConfigurationLocation.cs

@@ -3,6 +3,7 @@
 //
 // Authors:
 //	Duncan Mak ([email protected])
+//  Lluis Sanchez Gual ([email protected])
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -30,19 +31,30 @@
 
 namespace System.Configuration {
 
-        public class ConfigurationLocation
-        {
-                string path;
-                
-                public string Path {
-                        get { return path; }
-                }
+	public class ConfigurationLocation
+	{
+		string path;
+		Configuration configuration;
+		
+		internal ConfigurationLocation()
+		{
+		}
+		
+		internal ConfigurationLocation (string path, Configuration config)
+		{
+			this.path = path;
+			configuration = config;
+		}
+		
+		public string Path {
+			get { return path; }
+		}
 
-                public Configuration GetConfiguration ()
-                {
-                        return null;
-                }
-        }
+		public Configuration GetConfiguration ()
+		{
+			return configuration;
+		}
+	}
 }
 
 #endif

+ 11 - 6
mcs/class/System/System.Configuration/ConfigurationLocationCollection.cs

@@ -32,12 +32,17 @@ using System.Collections;
 
 namespace System.Configuration {
 
-        public class ConfigurationLocationCollection : ReadOnlyCollectionBase
-        {
-                public ConfigurationLocation this [int index] {
-                        get { return this [index] as ConfigurationLocation; }
-                }
-        }
+	public class ConfigurationLocationCollection : ReadOnlyCollectionBase
+	{
+		public ConfigurationLocation this [int index] {
+			get { return this [index] as ConfigurationLocation; }
+		}
+		
+		internal void Add (ConfigurationLocation loc)
+		{
+			InnerList.Add (loc);
+		}
+	}
 }
 
 #endif

+ 76 - 66
mcs/class/System/System.Configuration/ConfigurationProperty.cs

@@ -3,6 +3,7 @@
 //
 // Authors:
 //	Duncan Mak ([email protected])
+//  Lluis Sanchez Gual ([email protected])
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -33,82 +34,91 @@ using System.ComponentModel;
 
 namespace System.Configuration
 {
-        public class ConfigurationProperty : ConfigurationElement
-        {
-                string name;
-                Type type;
-                object default_value;
-                TypeConverter converter;
-                ConfigurationValidationAttribute validation;
-                ConfigurationPropertyFlags flags;
-                
-                public ConfigurationProperty (string name, Type type, object default_value)
-                        : this (name, type, default_value, ConfigurationPropertyFlags.None)
-                {
-                }
+	public class ConfigurationProperty : ConfigurationElement
+	{
+		string name;
+		Type type;
+		object default_value;
+		TypeConverter converter;
+		ConfigurationValidationAttribute validation;
+		ConfigurationPropertyFlags flags;
+		
+		public ConfigurationProperty (string name, Type type, object default_value)
+			: this (name, type, default_value, ConfigurationPropertyFlags.None)
+		{
+		}
 
-                public ConfigurationProperty (
-                                string name, Type type, object default_value,
-                                ConfigurationPropertyFlags flags)
-                        :this (name, type, default_value, TypeDescriptor.GetConverter (type), null, flags)
-                {
-                }
+		public ConfigurationProperty (
+					string name, Type type, object default_value,
+					ConfigurationPropertyFlags flags)
+			:this (name, type, default_value, TypeDescriptor.GetConverter (type), null, flags)
+		{
+		}
+		
+		public ConfigurationProperty (
+					string name, Type type, object default_value,
+					TypeConverter converter,
+					ConfigurationValidationAttribute validation,
+					ConfigurationPropertyFlags flags)
+		{
+			this.name = name;
+			this.converter = converter;
+			this.default_value = default_value;
+			this.flags = flags;
+			this.type = type;
+			this.validation = validation;
+		}
 
-                public ConfigurationProperty (
-                                string name, Type type, object default_value,
-                                TypeConverter converter,
-                                ConfigurationValidationAttribute validation,
-                                ConfigurationPropertyFlags flags)
-                {
-                        this.name = name;
-                        this.converter = converter;
-                        this.default_value = default_value;
-                        this.flags = flags;
-                        this.type = type;
-                        this.validation = validation;
-                }
+		public TypeConverter Converter {
+			get { return converter; }
+		}
 
-                public TypeConverter Converter {
-                        get { return converter; }
-                }
+		public object DefaultValue {                        
+			get { return default_value; }
+		}
 
-                public object DefaultValue {                        
-                        get { return default_value; }
-                        
-                }
+		public bool IsKey {                        
+			get { return (flags & ConfigurationPropertyFlags.IsKey) != 0; }
+		}
 
-                public bool IsKey {                        
-                        get { return (flags & ConfigurationPropertyFlags.IsKey) != 0; }
-                }
+		public bool IsRequired {
+			get { return (flags & ConfigurationPropertyFlags.Required) != 0; }               
+		}
 
-                public bool IsRequired {
-                        get { return (flags & ConfigurationPropertyFlags.Required) != 0; }               
-                }
+		public string Name {
+			get { return name; }
+		}
 
-                public string Name {
-                        get { return name; }
-                }
+		public Type Type {
+			get { return type; }
+		}
 
-                public Type Type {
-                        get { return type; }
-                }
+		public ConfigurationValidationAttribute ValidationAttribute {
+			get { return validation; }
+		}
 
-                public ConfigurationValidationAttribute ValidationAttribute {
-                        get { return validation; }
-                }
+		protected internal virtual object ConvertFromString (string value)
+		{
+			if (converter != null)
+				return converter.ConvertFromInvariantString (value);
+			else
+				throw new NotImplementedException ();
+		}
 
-                [MonoTODO]
-                protected internal virtual object ConvertFromString (string value)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                [MonoTODO]
-                protected internal virtual string ConvertToString (object value)
-                {
-                        throw new NotImplementedException ();
-                }
-        }
+		protected internal virtual string ConvertToString (object value)
+		{
+			if (converter != null)
+				return converter.ConvertToInvariantString (value);
+			else
+				throw new NotImplementedException ();
+		}
+		
+		internal bool IsElement {
+			get {
+				return (typeof(ConfigurationElement).IsAssignableFrom (type));
+			}
+		}
+	}
 }
 #endif
 #endif

+ 51 - 42
mcs/class/System/System.Configuration/ConfigurationPropertyAttribute.cs

@@ -3,6 +3,7 @@
 //
 // Authors:
 //	Duncan Mak ([email protected])
+//  Lluis Sanchez Gual ([email protected])
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -30,47 +31,55 @@
 
 namespace System.Configuration
 {
-        public sealed class ConfigurationPropertyAttribute : Attribute
-        {
-                string name;
-                bool collection_key, default_collection_property, required_value;
-                object default_value;
-                ConfigurationPropertyFlags flags;
-                
-                public ConfigurationPropertyAttribute (string name)
-                {
-                        this.name = name;
-                }
-
-                public bool CollectionKey {
-                        get { return collection_key; }
-                        set { collection_key = value; }
-                }
-
-                public bool DefaultCollectionProperty {
-                        get { return default_collection_property; }
-                        set { default_collection_property = value; }
-                }
-
-                public object DefaultValue {
-                        get { return default_value; }
-                        set { default_value = value; }
-                }
-                
-                public ConfigurationPropertyFlags Flags {
-                        get { return flags; }
-                        set { flags = value; }
-                }
-
-                public string Name {
-                        get { return name; }
-                        set { name = value; }
-                }
-
-                public bool RequiredValue {
-                        get { return required_value; }
-                        set { required_value = value; }
-                }                        
-        }
+	public sealed class ConfigurationPropertyAttribute : Attribute
+	{
+		string name;
+		object default_value;
+		ConfigurationPropertyFlags flags;
+		
+		public ConfigurationPropertyAttribute (string name)
+		{
+			this.name = name;
+		}
+		
+		public bool CollectionKey {
+			get { return (flags & ConfigurationPropertyFlags.IsKey) != 0; }
+			set {
+				if (value) flags |= ConfigurationPropertyFlags.IsKey; 
+				else flags &= ~ConfigurationPropertyFlags.IsKey; 
+			}
+		}
+		
+		public bool DefaultCollectionProperty {
+			get { return (flags & ConfigurationPropertyFlags.DefaultCollection) != 0; }
+			set {
+				if (value) flags |= ConfigurationPropertyFlags.DefaultCollection; 
+				else flags &= ~ConfigurationPropertyFlags.DefaultCollection; 
+			}
+		}
+		
+		public object DefaultValue {
+			get { return default_value; }
+			set { default_value = value; }
+		}
+		
+		public ConfigurationPropertyFlags Flags {
+			get { return flags; }
+			set { flags = value; }
+		}
+		
+		public string Name {
+			get { return name; }
+			set { name = value; }
+		}
+		
+		public bool RequiredValue {
+			get { return (flags & ConfigurationPropertyFlags.Required) != 0; }
+			set {
+				if (value) flags |= ConfigurationPropertyFlags.Required; 
+				else flags &= ~ConfigurationPropertyFlags.Required; 
+			}
+		}
+	}
 }
 #endif

+ 159 - 138
mcs/class/System/System.Configuration/ConfigurationSection.cs

@@ -3,6 +3,7 @@
 //
 // Authors:
 //	Duncan Mak ([email protected])
+//  Lluis Sanchez Gual ([email protected])
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -33,144 +34,164 @@ using System.Xml;
 
 namespace System.Configuration
 {
-        public abstract class ConfigurationSection : ConfigurationElement
-        {
-                ConfigurationSection parent;
-                
-                ConfigurationAllowDefinition allow_definition;
-                bool allow_location, allow_override;
-                bool inherit_on_child_apps;
-                bool restart_on_external_changes;
-
-                string config_source;
-                bool force_update, is_declared, is_locked, is_protected;
-                string name, path, type_name;
-
-                ProtectedConfigurationProvider protected_provider;
-                
-                public ConfigurationSection ()
-                {
-                        allow_definition = ConfigurationAllowDefinition.Everywhere;
-                        allow_location = true;
-                        allow_override = true;
-                        inherit_on_child_apps = true;
-                        restart_on_external_changes = true;
-                }
-
-                public ConfigurationAllowDefinition AllowDefinition {
-                        get { return allow_definition; }
-                        set { allow_definition = value; }
-                }
-
-                public bool AllowLocation {
-                        get { return allow_location; }
-                        set { allow_location = value; }
-                }
-
-                public bool AllowOverride {
-                        get { return allow_override; }
-                        set { allow_override = value; }
-                }
-
-                public string ConfigSource {
-                        get { return config_source; }
-                        set { config_source = value; }
-                }
-
-                public bool ForceUpdate {
-                        get { return force_update; }
-                        set { force_update = value; }
-                }
-
-                public bool InheritInChildApplications {
-                        get { return inherit_on_child_apps; }
-                        set { inherit_on_child_apps = value; }
-                }
-
-                public bool IsDeclared {
-                        get { return is_declared; }
-                }
-
-                public bool IsLocked {
-                        get { return is_locked; }
-                }
-
-                public bool IsProtected {
-                        get { return is_protected; }
-                }
-
-                public string Name {
-                        get { return name; }
-                }
-
-                public string Path {
-                        get { return path; }
-                }
-
-                public ProtectedConfigurationProvider ProtectionProvider {
-                        get { return protected_provider; }
-                }
-
-                public bool RestartOnExternalChanges {
-                        get { return restart_on_external_changes; }
-                        set { restart_on_external_changes = value; }
-                }
-
-                public string TypeName {
-                        get { return type_name; }
-                        set { type_name = value; }
-                }
-
-                public ConfigurationSection GetParentSection ()
-                {
-                        return parent;
-                }
-
-                public XmlNode GetRawXml ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                protected internal virtual object GetRuntimeObject ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                protected internal override bool IsModified ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void ProtectSection (string provider)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void RequireDeclaration ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                protected internal override void ResetModified ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void RevertToParent ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void UnProtectSection ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void UpdateRawXml (string xml)
-                {
-                        throw new NotImplementedException ();
-                }
-        }
+	public abstract class ConfigurationSection : ConfigurationElement
+	{
+		ConfigurationSection parent;
+		
+		ConfigurationAllowDefinition allow_definition;
+		bool allow_location, allow_override;
+		bool inherit_on_child_apps;
+		bool restart_on_external_changes;
+
+		string config_source;
+		bool force_update, is_declared, is_locked, is_protected;
+		string name, path, type_name;
+
+		ProtectedConfigurationProvider protected_provider;
+		
+		public ConfigurationSection ()
+		{
+			allow_definition = ConfigurationAllowDefinition.Everywhere;
+			allow_location = true;
+			allow_override = true;
+			inherit_on_child_apps = true;
+			restart_on_external_changes = true;
+		}
+		
+		public ConfigurationAllowDefinition AllowDefinition {
+			get { return allow_definition; }
+			set { allow_definition = value; }
+		}
+
+		public bool AllowLocation {
+			get { return allow_location; }
+			set { allow_location = value; }
+		}
+
+		public bool AllowOverride {
+			get { return allow_override; }
+			set { allow_override = value; }
+		}
+
+		public string ConfigSource {
+			get { return config_source; }
+			set { config_source = value; }
+		}
+
+		public bool ForceUpdate {
+			get { return force_update; }
+			set { force_update = value; }
+		}
+
+		public bool InheritInChildApplications {
+			get { return inherit_on_child_apps; }
+			set { inherit_on_child_apps = value; }
+		}
+
+		[MonoTODO]
+		public bool IsDeclared {
+			get { return is_declared; }
+		}
+
+		[MonoTODO]
+		public bool IsLocked {
+			get { return is_locked; }
+		}
+
+		[MonoTODO]
+		public bool IsProtected {
+			get { return is_protected; }
+		}
+
+		public string Name {
+			get { return name; }
+		}
+
+		[MonoTODO]
+		public string Path {
+			get { return path; }
+		}
+
+		[MonoTODO]
+		public ProtectedConfigurationProvider ProtectionProvider {
+			get { return protected_provider; }
+		}
+
+		[MonoTODO]
+		public bool RestartOnExternalChanges {
+			get { return restart_on_external_changes; }
+			set { restart_on_external_changes = value; }
+		}
+
+		public string TypeName {
+			get { return type_name; }
+			set { type_name = value; }
+		}
+
+		public ConfigurationSection GetParentSection ()
+		{
+			return parent;
+		}
+
+		[MonoTODO]
+		public XmlNode GetRawXml ()
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		protected internal virtual object GetRuntimeObject ()
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		protected internal override bool IsModified ()
+		{
+			return base.IsModified ();
+		}
+
+		[MonoTODO]
+		public void ProtectSection (string provider)
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		public void RequireDeclaration (bool require)
+		{
+		}
+
+		[MonoTODO]
+		protected internal override void ResetModified ()
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		public void RevertToParent ()
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		public void UnProtectSection ()
+		{
+			throw new NotImplementedException ();
+		}
+
+		[MonoTODO]
+		public void UpdateRawXml (string xml)
+		{
+			throw new NotImplementedException ();
+		}
+		
+		[MonoTODO]
+		internal void SetName (string name)
+		{
+			this.name = name;
+		}
+	}
 }
 #endif
 #endif

+ 96 - 6
mcs/class/System/System.Configuration/ConfigurationSectionCollection.cs

@@ -3,6 +3,7 @@
 //
 // Authors:
 //	Duncan Mak ([email protected])
+//  Lluis Sanchez Gual ([email protected])
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -31,11 +32,100 @@ using System;
 using System.Collections;
 using System.Collections.Specialized;
 
-namespace System.Configuration {
-
-        public sealed class ConfigurationSectionCollection : NameObjectCollectionBase
-        {
-                
-        }
+namespace System.Configuration
+{
+	public sealed class ConfigurationSectionCollection : NameObjectCollectionBase
+	{
+		SectionGroupInfo group;
+		Configuration config;
+		
+		internal ConfigurationSectionCollection (Configuration config, SectionGroupInfo group)
+		{
+			this.config = config;
+			this.group = group;
+		}
+		
+		public ICollection AllKeys
+		{
+			get { return group.Sections.AllKeys; }
+		}
+		
+		public override int Count 
+		{
+			get { return group.Sections.Count; }
+		}
+	
+		public ConfigurationSection this [string name]
+		{
+			get {
+				ConfigurationSection sec = BaseGet (name) as ConfigurationSection;
+				if (sec == null) {
+					SectionInfo secData = group.Sections [name] as SectionInfo;
+					if (secData == null) return null;
+					sec = config.GetSectionInstance (secData, true);
+					if (sec == null) return null;
+					BaseSet (name, sec);
+				}
+				return sec;
+			}
+		}
+	
+		public ConfigurationSection this [int index]
+		{
+			get { return this [GetKey (index)]; }
+		}
+		
+		public void Add (string name, ConfigurationSection section)
+		{
+			config.CreateSection (group, name, section);
+		}
+		
+		public void Clear ()
+		{
+			if (group.Sections != null) {
+				foreach (ConfigInfo data in group.Sections)
+					config.RemoveConfigInfo (data);
+			}
+		}
+		
+		public void CopyTo (ConfigurationSection [] array, int index)
+		{
+			for (int n=0; n<group.Sections.Count; n++)
+				array [n + index] = this [n];
+		}
+		
+		public ConfigurationSection Get (int index)
+		{
+			return this [index];
+		}
+		
+		public ConfigurationSection Get (string name)
+		{
+			return this [name];
+		}
+		
+		public override IEnumerator GetEnumerator()
+		{
+			return group.Sections.AllKeys.GetEnumerator ();
+		}
+		
+		public string GetKey (int index)
+		{
+			return group.Sections.GetKey (index);
+		}
+		
+		public void Remove (string name)
+		{
+			SectionInfo secData = group.Sections [name] as SectionInfo;
+			if (secData != null)
+				config.RemoveConfigInfo (secData);
+		}
+		
+		public void RemoveAt (int index)
+		{
+			SectionInfo secData = group.Sections [index] as SectionInfo;
+			config.RemoveConfigInfo (secData);
+		}
+	}
 }
 #endif

+ 59 - 32
mcs/class/System/System.Configuration/ConfigurationSectionGroup.cs

@@ -3,6 +3,7 @@
 //
 // Authors:
 //	Duncan Mak ([email protected])
+//  Lluis Sanchez Gual ([email protected])
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -29,45 +30,71 @@
 #if NET_2_0 && XML_DEP
 using System;
 
-namespace System.Configuration {
+namespace System.Configuration
+{
+	public class ConfigurationSectionGroup
+	{
+		bool require_declaration;
+		string name, path, type_name;
 
-        public class ConfigurationSectionGroup
-        {
-                bool require_declaration;
-                string name, path, type_name;
+		ConfigurationSectionCollection sections;
+		ConfigurationSectionGroupCollection groups;
+		Configuration config;
+		SectionGroupInfo group;
+		
+		public ConfigurationSectionGroup ()
+		{
+		}
+		
+		internal void Initialize (Configuration config, SectionGroupInfo group)
+		{
+			this.config = config;
+			this.group = group;
+		}
+		
+		internal void SetName (string name)
+		{
+			this.name = name;
+		}
 
-                public ConfigurationSectionGroup ()
-                {
-                }
+		[MonoTODO]
+		public void RequireDeclaration (bool require)
+		{
+			this.require_declaration = require;
+		}
 
-                public void RequireDeclaration (bool require)
-                {
-                        this.require_declaration = require;
-                }
+		[MonoTODO]
+		public bool IsDeclared {
+			get { return require_declaration; }
+		}
 
-                public bool IsDeclared {
-                        get { return require_declaration; }
-                }
+		public string Name {
+			get { return name; }
+		}
 
-                public string Name {
-                        get { return path; }
-                }
+		[MonoTODO]
+		public string Path {
+			get { return path; }
+		}
 
-                public string Path {
-                        get { return path; }
-                }
+		public ConfigurationSectionGroupCollection SectionGroups {
+			get {
+				if (groups == null) groups = new ConfigurationSectionGroupCollection (config, group);
+				return groups;
+			}
+		}
 
-                public ConfigurationSectionGroupCollection SectionGroups {
-                        get { throw new NotImplementedException (); }
-                }
+		public ConfigurationSectionCollection Sections {
+			get {
+				if (sections == null) sections = new ConfigurationSectionCollection (config, group);
+				return sections;
+			}
+		}
 
-                public ConfigurationSectionCollection Sections {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public string TypeName {
-                        get { return type_name;}
-                }
-        }
+		public string TypeName {
+			get { return type_name;}
+			set { type_name = value; }
+		}
+	}
 }
 #endif

+ 89 - 67
mcs/class/System/System.Configuration/ConfigurationSectionGroupCollection.cs

@@ -3,6 +3,7 @@
 //
 // Authors:
 //	Duncan Mak ([email protected])
+//  Lluis Sanchez Gual ([email protected])
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -33,72 +34,93 @@ using System.Collections.Specialized;
 
 namespace System.Configuration {
 
-        public sealed class ConfigurationSectionGroupCollection : NameObjectCollectionBase
-        {
-                public ICollection AllKeys {
-                        get { return BaseGetAllKeys (); }
-                }
-
-                public override int Count {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public ConfigurationSectionGroup this [int index] {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public ConfigurationSectionGroup this [string index] {
-                        get { throw new NotImplementedException (); }                        
-                }
-
-                public override NameObjectCollectionBase.KeysCollection Keys {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public void Add (string name, ConfigurationSectionGroup section_group)
-                {
-                        BaseAdd (name, section_group);
-                }
-
-                public void Clear ()
-                {
-                        BaseClear ();
-                }
-
-                public void CopyTo (ConfigurationSectionGroup [] array, int index)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public ConfigurationSectionGroup Get (int index)
-                {
-                        return BaseGet (index) as ConfigurationSectionGroup;
-                }
-
-                public ConfigurationSectionGroup Get (string index)
-                {
-                        return BaseGet (index) as ConfigurationSectionGroup;
-                }
-
-                public override IEnumerator GetEnumerator ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public string GetKey (string index)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void Remove (string index)
-                {
-                        BaseRemove (index);
-                }
-
-                public void RemoveAt (int index)
-                {
-                        BaseRemoveAt (index);
-                }
-        }
+	public sealed class ConfigurationSectionGroupCollection : NameObjectCollectionBase
+	{
+		SectionGroupInfo group;
+		Configuration config;
+		
+		internal ConfigurationSectionGroupCollection (Configuration config, SectionGroupInfo group)
+		{
+			this.config = config;
+			this.group = group;
+		}
+		
+		public ICollection AllKeys {
+			get { return group.Groups.AllKeys; }
+		}
+
+		public override int Count {
+			get { return group.Groups.Count; }
+		}
+
+		public ConfigurationSectionGroup this [string name] {
+			get {
+				ConfigurationSectionGroup sec = BaseGet (name) as ConfigurationSectionGroup;
+				if (sec == null) {
+					SectionGroupInfo secData = group.Groups [name] as SectionGroupInfo;
+					if (secData == null) return null;
+					sec = config.GetSectionGroupInstance (secData);
+					BaseSet (name, sec);
+				}
+				return sec;
+			}
+		}
+
+		public ConfigurationSectionGroup this [int index] {
+			get { return this [GetKey (index)]; }
+		}
+
+		public void Add (string name, ConfigurationSectionGroup sectionGroup)
+		{
+			config.CreateSectionGroup (group, name, sectionGroup);
+		}
+
+		public void Clear ()
+		{
+			if (group.Groups != null) {
+				foreach (ConfigInfo data in group.Groups)
+					config.RemoveConfigInfo (data);
+			}
+		}
+
+		public void CopyTo (ConfigurationSectionGroup [] array, int index)
+		{
+			for (int n=0; n<group.Groups.Count; n++)
+				array [n + index] = this [n];
+		}
+
+		public ConfigurationSectionGroup Get (int index)
+		{
+			return this [index];
+		}
+
+		public ConfigurationSectionGroup Get (string name)
+		{
+			return this [name];
+		}
+
+		public override IEnumerator GetEnumerator ()
+		{
+			return group.Groups.AllKeys.GetEnumerator ();
+		}
+
+		public string GetKey (int index)
+		{
+			return group.Groups.GetKey (index);
+		}
+
+		public void Remove (string name)
+		{
+			SectionGroupInfo secData = group.Groups [name] as SectionGroupInfo;
+			if (secData != null)
+				config.RemoveConfigInfo (secData);
+		}
+		
+		public void RemoveAt (int index)
+		{
+			SectionGroupInfo secData = group.Groups [index] as SectionGroupInfo;
+			config.RemoveConfigInfo (secData);
+		}
+	}
 }
 #endif

+ 70 - 0
mcs/class/System/System.Configuration/IntegerConfigurationProperty.cs

@@ -0,0 +1,70 @@
+//
+// System.Configuration.ConfigurationProperty.cs
+//
+// Authors:
+//  Lluis Sanchez Gual ([email protected])
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+
+#if NET_2_0 && XML_DEP
+#if XML_DEP
+using System;
+using System.ComponentModel;
+
+namespace System.Configuration
+{
+	public class IntegerConfigurationProperty : ConfigurationProperty
+	{
+		int min;
+		int max;
+		
+		public IntegerConfigurationProperty (string name, int defaultValue, ConfigurationPropertyFlags flags)
+			: base (name, typeof(int), defaultValue, flags)
+		{
+			min = int.MinValue;
+			max = int.MaxValue;
+		}
+
+		public IntegerConfigurationProperty (string name, int defaultValue, int minimumValue, int maximumValue, ConfigurationPropertyFlags flags)
+			: base (name, typeof(int), defaultValue, flags)
+		{
+			min = minimumValue;
+			max = maximumValue;
+		}
+
+		protected internal override object ConvertFromString (string value)
+		{
+			return int.Parse (value);
+		}
+
+		protected internal override string ConvertToString (object value)
+		{
+			int val = (int)value;
+			if (val < min || val > max)
+				throw new ConfigurationException ("The property '" + Name + "' must have a value between '" + min + "' and '" + max + "'");
+			return value.ToString ();
+		}
+	}
+}
+#endif
+#endif

+ 67 - 0
mcs/class/System/System.Configuration/RuntimeOnlySection.cs

@@ -0,0 +1,67 @@
+//
+// System.Configuration.RuntimeOnlySection.cs
+//
+// Authors:
+//	Lluis Sanchez ([email protected])
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+#if NET_2_0 && XML_DEP
+using System;
+using System.Xml;
+using System.IO;
+
+namespace System.Configuration
+{
+	internal class RuntimeOnlySection: ConfigurationSection
+	{
+		string xml;
+		
+		protected internal override bool IsModified ()
+		{
+			return false;
+		}
+
+		protected internal override void ReadXml (XmlReader reader, object context)
+		{
+			xml = reader.ReadOuterXml ();
+		}
+
+		protected internal override void Reset (ConfigurationElement parent_element, object context)
+		{
+		}
+
+		protected internal override void ResetModified ()
+		{
+		}
+
+		protected internal override string WriteXml (
+				ConfigurationElement parent,
+				object context, string name,
+				ConfigurationUpdateMode updateMode)
+		{
+			return xml;
+		}
+	}
+}
+
+#endif

+ 363 - 0
mcs/class/System/System.Configuration/SectionGroupInfo.cs

@@ -0,0 +1,363 @@
+//
+// System.Configuration.SectionGroupInfo.cs
+//
+// Authors:
+//	Lluis Sanchez ([email protected])
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+#if NET_2_0 && XML_DEP
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Xml;
+using System.IO;
+
+namespace System.Configuration
+{
+	internal class SectionGroupInfo: ConfigInfo
+	{
+		ConfigInfoCollection sections;
+		ConfigInfoCollection groups;
+		static ConfigInfoCollection emptyList = new ConfigInfoCollection ();
+
+		public SectionGroupInfo ()
+		{
+			TypeName = "System.Configuration.ConfigurationSectionGroup";
+		}
+		
+		public SectionGroupInfo (string groupName, string typeName)
+		{
+			Name = groupName;
+			TypeName = typeName;
+		}
+		
+		public void AddChild (ConfigInfo data)
+		{
+			if (data is SectionInfo) {
+				if (sections == null) sections = new ConfigInfoCollection ();
+				sections [data.Name] = data;
+			}
+			else {
+				if (groups == null) groups = new ConfigInfoCollection ();
+				groups [data.Name] = data;
+			}
+		}
+		
+		public void Clear ()
+		{
+			if (sections != null) sections.Clear ();
+			if (groups != null) groups.Clear ();
+		}
+		
+		public bool HasChild (string name)
+		{
+			if (sections != null && sections [name] != null) return true;
+			return (groups != null && groups [name] != null);
+		}
+		
+		public void RemoveChild (string name)
+		{
+			if (sections != null)
+				sections.Remove (name);
+			if (groups != null)
+				groups.Remove (name);
+		}
+		
+		public SectionInfo GetChildSection (string name)
+		{
+			if (sections != null)
+				return sections [name] as SectionInfo;
+			else
+				return null;
+		}
+		
+		public SectionGroupInfo GetChildGroup (string name)
+		{
+			if (groups != null)
+				return groups [name] as SectionGroupInfo;
+			else
+				return null;
+		}
+		
+		public ConfigInfoCollection Sections
+		{
+			get { if (sections == null) return emptyList; else return sections; }
+		}
+		
+		public ConfigInfoCollection Groups
+		{
+			get { if (groups == null) return emptyList; else return groups; }
+		}
+		
+		public override bool HasDataContent (Configuration config)
+		{
+			foreach (ConfigInfoCollection col in new object[] {Sections, Groups}) {
+				foreach (string key in col) {
+					ConfigInfo cinfo = col [key];
+					if (cinfo.HasDataContent (config))
+						return true;
+				}
+			}
+			return false;
+		}
+		
+		public override bool HasConfigContent (Configuration cfg)
+		{
+			if (FileName == cfg.FileName) return true;
+			foreach (ConfigInfoCollection col in new object[] {Sections, Groups}) {
+				foreach (string key in col) {
+					ConfigInfo cinfo = col [key];
+					if (cinfo.HasConfigContent (cfg))
+						return true;
+				}
+			}
+			return false;
+		}
+		
+#if (XML_DEP)
+
+		public override void ReadConfig (Configuration cfg, XmlTextReader reader)
+		{
+			FileName = cfg.FileName;
+			
+			if (reader.LocalName != "configSections")
+			{
+				while (reader.MoveToNextAttribute ()) {
+					if (reader.Name == "name")
+						Name = reader.Value;
+					else if (reader.Name == "type")
+						TypeName = reader.Value;
+					else
+						ThrowException ("Unrecognized attribute", reader);
+				}
+				
+				if (Name == null)
+					ThrowException ("sectionGroup must have a 'name' attribute", reader);
+	
+				if (Name == "location")
+					ThrowException ("location is a reserved section name", reader);
+			}
+			
+			if (TypeName == null)
+				TypeName = "System.Configuration.ConfigurationSectionGroup";
+			
+			if (reader.IsEmptyElement) {
+				reader.Skip ();
+				return;
+			}
+			
+			reader.ReadStartElement ();
+			reader.MoveToContent ();
+			
+			while (reader.NodeType != XmlNodeType.EndElement)
+			{
+				if (reader.NodeType != XmlNodeType.Element) {
+					reader.Skip ();
+					continue;
+				}
+				
+				string name = reader.LocalName;
+				ConfigInfo cinfo = null;
+				
+				if (name == "remove") {
+					ReadRemoveSection (reader);
+					continue;
+				}
+
+				if (name == "clear") {
+					if (reader.HasAttributes)
+						ThrowException ("Unrecognized attribute.", reader);
+
+					Clear ();
+					reader.Skip ();
+					continue;
+				}
+
+				if (name == "section")
+					cinfo = new SectionInfo ();
+				else if (name == "sectionGroup")
+					cinfo = new SectionGroupInfo ();
+				else
+					ThrowException ("Unrecognized element: " + reader.Name, reader);
+					
+				cinfo.ReadConfig (cfg, reader);
+				if (HasChild (cinfo.Name))
+					ThrowException ("Already have a factory for " + name, reader);
+				AddChild (cinfo);
+			}
+			
+			reader.ReadEndElement ();
+		}
+		
+		public override void WriteConfig (Configuration cfg, XmlWriter writer, ConfigurationUpdateMode mode)
+		{
+			if (Name != null) {
+				writer.WriteStartElement ("sectionGroup");
+				writer.WriteAttributeString ("name", Name);
+				if (TypeName != null && TypeName != "" && TypeName != "System.Configuration.ConfigurationSectionGroup")
+					writer.WriteAttributeString ("type", TypeName);
+			}
+			else
+				writer.WriteStartElement ("configSections");
+			
+			foreach (ConfigInfoCollection col in new object[] {Sections, Groups}) {
+				foreach (string key in col) {
+					ConfigInfo cinfo = col [key];
+					if (cinfo.HasConfigContent (cfg))
+						cinfo.WriteConfig (cfg, writer, mode);
+				}
+			}
+			
+			writer.WriteEndElement ();
+		}
+
+		private void ReadRemoveSection (XmlTextReader reader)
+		{
+			if (!reader.MoveToNextAttribute () || reader.Name != "name")
+				ThrowException ("Unrecognized attribute.", reader);
+
+			string removeValue = reader.Value;
+			if (removeValue == null || removeValue.Length == 0)
+				ThrowException ("Empty name to remove", reader);
+
+			reader.MoveToElement ();
+
+			if (!HasChild (removeValue))
+				ThrowException ("No factory for " + removeValue, reader);
+
+			RemoveChild (removeValue);
+			reader.Skip ();
+		}
+
+		public void ReadRootData (XmlTextReader reader, Configuration config)
+		{
+			reader.MoveToContent ();
+			ReadContent (reader, config);
+		}
+		
+		public override void ReadData (Configuration config, XmlTextReader reader)
+		{
+			reader.MoveToContent ();
+			reader.ReadStartElement ();
+			ReadContent (reader, config);
+			reader.MoveToContent ();
+			reader.ReadEndElement ();
+		}
+		
+		void ReadContent (XmlTextReader reader, Configuration config)
+		{
+			while (reader.NodeType != XmlNodeType.EndElement) {
+				if (reader.NodeType != XmlNodeType.Element) {
+					reader.Skip ();
+					continue;
+				}
+				if (reader.LocalName == "location") {
+					Configuration locConfig = new Configuration (config);
+					string path = reader.GetAttribute ("path");
+					ConfigurationLocation loc = new ConfigurationLocation (path, locConfig);
+					config.Locations.Add (loc);
+					ReadData (locConfig, reader);
+				}
+				
+				ConfigInfo data = (sections != null) ? (ConfigInfo) sections [reader.LocalName] : (ConfigInfo) null;
+				if (data == null) data = (groups != null) ? (ConfigInfo) groups [reader.LocalName] : (ConfigInfo) null;
+				
+				if (data != null)
+					data.ReadData (config, reader);
+				else
+					ThrowException ("Unrecognized configuration section <" + reader.LocalName + ">", reader);
+			}
+		}
+		
+		public void WriteRootData (XmlWriter writer, Configuration config, ConfigurationUpdateMode mode)
+		{
+			WriteContent (writer, config, mode, false);
+		}
+		
+		public override void WriteData (Configuration config, XmlWriter writer, ConfigurationUpdateMode mode)
+		{
+			writer.WriteStartElement (Name);
+			WriteContent (writer, config, mode, true);
+			writer.WriteEndElement ();
+		}
+		
+		public void WriteContent (XmlWriter writer, Configuration config, ConfigurationUpdateMode mode, bool writeElem)
+		{
+			foreach (ConfigInfoCollection col in new object[] {Sections, Groups}) {
+				foreach (string key in col) {
+					ConfigInfo cinfo = col [key];
+					if (cinfo.HasDataContent (config))
+						cinfo.WriteData (config, writer, mode);
+				}
+			}
+		}
+#endif
+	}
+	
+	internal class ConfigInfoCollection : NameObjectCollectionBase
+	{
+		public ICollection AllKeys
+		{
+			get { return Keys; }
+		}
+		
+		public ConfigInfo this [string name]
+		{
+			get { return (ConfigInfo) BaseGet (name); }
+			set { BaseSet (name, value); }
+		}
+	
+		public ConfigInfo this [int index]
+		{
+			get { return (ConfigInfo) BaseGet (index); }
+			set { BaseSet (index, value); }
+		}
+		
+		public void Add (string name, ConfigInfo config)
+		{
+			BaseAdd (name, config);
+		}
+		
+		public void Clear ()
+		{
+			BaseClear ();
+		}
+		
+		public string GetKey (int index)
+		{
+			return BaseGetKey (index);
+		}
+		
+		public void Remove (string name)
+		{
+			BaseRemove (name);
+		}
+		
+		public void RemoveAt (int index)
+		{
+			BaseRemoveAt (index);
+		}
+	}
+}
+
+#endif

+ 145 - 0
mcs/class/System/System.Configuration/SectionInfo.cs

@@ -0,0 +1,145 @@
+//
+// System.Configuration.SectionInfo.cs
+//
+// Authors:
+//	Lluis Sanchez ([email protected])
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+#if NET_2_0 && XML_DEP
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Xml;
+using System.IO;
+
+namespace System.Configuration
+{
+	internal class SectionInfo: ConfigInfo
+	{
+		public bool AllowLocation = true;
+		public ConfigurationAllowDefinition AllowDefinition = ConfigurationAllowDefinition.Everywhere;
+
+		public SectionInfo ()
+		{
+		}
+		
+		public SectionInfo (string sectionName, string typeName,
+				    bool allowLocation, ConfigurationAllowDefinition allowDefinition)
+		{
+			Name = sectionName;
+			TypeName = typeName;
+			AllowLocation = allowLocation;
+			AllowDefinition = allowDefinition;
+		}
+		
+		public override bool HasDataContent (Configuration config)
+		{
+			return config.GetSectionInstance (this, false) != null;
+		}
+		
+		public override bool HasConfigContent (Configuration cfg)
+		{
+			return FileName == cfg.FileName;
+		}
+
+#if (XML_DEP)
+		public override void ReadConfig (Configuration cfg, XmlTextReader reader)
+		{
+			string attName;
+			ConfigurationAllowDefinition allowDefinition = ConfigurationAllowDefinition.Everywhere;
+			FileName = cfg.FileName;
+
+			while (reader.MoveToNextAttribute ()) {
+				switch (reader.Name)
+				{
+					case "allowLocation":
+						string allowLoc = reader.Value;
+						AllowLocation = (allowLoc == "true");
+						if (!AllowLocation && allowLoc != "false")
+							ThrowException ("Invalid attribute value", reader);
+						break;
+	
+					case "allowDefinition":
+						string allowDef = reader.Value;
+						try {
+							allowDefinition = (ConfigurationAllowDefinition) Enum.Parse (
+									   typeof (ConfigurationAllowDefinition), allowDef);
+						} catch {
+							ThrowException ("Invalid attribute value", reader);
+						}
+						break;
+	
+					case "type":
+						TypeName = reader.Value;
+						break;
+					
+					case "name":
+						Name = reader.Value;
+						if (Name == "location")
+							ThrowException ("location is a reserved section name", reader);
+						break;
+						
+					default:
+						ThrowException ("Unrecognized attribute.", reader);
+						break;
+				}
+			}
+
+			if (Name == null || TypeName == null)
+				ThrowException ("Required attribute missing", reader);
+
+			reader.MoveToElement();
+			reader.Skip ();
+		}
+		
+		public override void WriteConfig (Configuration cfg, XmlWriter writer, ConfigurationUpdateMode mode)
+		{
+			writer.WriteStartElement ("section");
+			writer.WriteAttributeString ("name", Name);
+			writer.WriteAttributeString ("type", TypeName);
+			if (!AllowLocation)
+				writer.WriteAttributeString ("allowLocation", "false");
+			if (AllowDefinition != ConfigurationAllowDefinition.Everywhere)
+				writer.WriteAttributeString ("allowDefinition", AllowDefinition.ToString ());
+			writer.WriteEndElement ();
+		}
+		
+		public override void ReadData (Configuration config, XmlTextReader reader)
+		{
+			config.SetSectionData (this, reader.ReadOuterXml ());
+		}
+		
+		public override void WriteData (Configuration config, XmlWriter writer, ConfigurationUpdateMode mode)
+		{
+			ConfigurationSection section = config.GetSectionInstance (this, false);
+			if (section != null) {
+				ConfigurationSection parentSection = config.Parent != null ? config.Parent.GetSectionInstance (this, false) : null;
+				string xml = section.WriteXml (parentSection, config, Name, mode);
+				writer.WriteRaw (xml);
+			}
+		}
+#endif
+	}
+}
+
+#endif