2008-12-06 Ivan N. Zlatev <contact@i-nz.net>
[mono.git] / mcs / class / System.Configuration / System.Configuration / ConfigurationElementCollection.cs
index ceff8e0b27f3e10df81a657c0537e168dcc02e61..db98f4c4067d25ffe4617febe9cbdcfd4d3c0504 100644 (file)
@@ -38,7 +38,7 @@ using System.Xml;
 namespace System.Configuration 
 {
        [DebuggerDisplayAttribute ("Count = {Count}")]
-       public abstract class ConfigurationElementCollection : ConfigurationElement, ICollection, IEnumerable
+       public abstract partial class ConfigurationElementCollection : ConfigurationElement, ICollection, IEnumerable
        {
                ArrayList list = new ArrayList ();
                ArrayList removed;
@@ -66,8 +66,10 @@ namespace System.Configuration
                internal override void InitFromProperty (PropertyInformation propertyInfo)
                {
                        ConfigurationCollectionAttribute colat = propertyInfo.Property.CollectionAttribute;
+       
                        if (colat == null)
-                               colat = ElementMap.GetMap (GetType ()).CollectionAttribute;
+                               colat = Attribute.GetCustomAttribute (propertyInfo.Type, typeof (ConfigurationCollectionAttribute)) as ConfigurationCollectionAttribute;
+
                        if (colat != null) {
                                addElementName = colat.AddItemName;
                                clearElementName = colat.ClearItemsName;
@@ -120,7 +122,13 @@ namespace System.Configuration
                }
 
                protected virtual bool ThrowOnDuplicate {
-                       get { return true; }
+                       get {
+                               if (CollectionType != ConfigurationElementCollectionType.AddRemoveClearMap &&
+                                   CollectionType != ConfigurationElementCollectionType.AddRemoveClearMapAlternate)
+                                       return false;
+                               
+                               return true;
+                       }
                }
                
                protected internal string AddElementName {
@@ -149,21 +157,25 @@ namespace System.Configuration
 
                protected void BaseAdd (ConfigurationElement element, bool throwIfExists)
                {
-                       if (throwIfExists && BaseIndexOf (element) != -1)
-                               throw new ConfigurationException ("Duplicate element in collection");
                        if (IsReadOnly ())
                                throw new ConfigurationErrorsException ("Collection is read only.");
                        
-                       int old_index = IndexOfKey (GetElementKey (element));
                        if (IsAlternate) {
                                list.Insert (inheritedLimitIndex, element);
                                inheritedLimitIndex++;
                        }
                        else {
+                               int old_index = IndexOfKey (GetElementKey (element));
+                               if (old_index >= 0) {
+                                       if (element.Equals (list [old_index]))
+                                               return;
+                                       if (throwIfExists)
+                                               throw new ConfigurationException ("Duplicate element in collection");
+                                       list.RemoveAt (old_index);
+                               }
                                list.Add (element);
                        }
-                       if (!IsAlternate && old_index != -1)
-                               list.RemoveAt (old_index);
+
                        modified = true;
                }
 
@@ -475,9 +487,10 @@ namespace System.Configuration
                                        return true;
                                }
                                else if (elementName == removeElementName) {
-                                       ConfigurationElement elem = CreateNewElementInternal (removeElementName);
-                                       elem.DeserializeElement (reader, true);
-                                       BaseRemove (GetElementKey (elem));
+                                       ConfigurationElement elem = CreateNewElementInternal (null);
+                                       ConfigurationRemoveElement removeElem = new ConfigurationRemoveElement (elem, this);
+                                       removeElem.DeserializeElement (reader, true);
+                                       BaseRemove (removeElem.KeyValue);
                                        modified = false;
                                        return true;
                                }