public PropertiesDictionary(
     PropertiesDictionary initializer,
     IEqualityComparer <string> comparer)
     : base(initializer, comparer)
 {
 }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JArray ja;

            if (objectType == typeof(StringSet))
            {
                ja = JArray.Load(reader);
                return(new StringSet(ja.Values().Select(token => token.ToString())));
            }
            else if (objectType == typeof(IntegerSet))
            {
                ja = JArray.Load(reader);
                return(new IntegerSet(ja.Values().Select(token => Int32.Parse(token.ToString()))));
            }
            else if (objectType == typeof(Version))
            {
                return(JsonConvert.DeserializeObject <Version>(reader.ReadAsString(), _versionConverter));
            }

            JObject jo     = JObject.Load(reader);
            var     result = new PropertiesDictionary();

            foreach (JProperty property in jo.Properties())
            {
                string key   = property.Name;
                JToken token = property.Value;

                switch (property.Value.Type)
                {
                case JTokenType.String:
                {
                    result[key] = token.ToObject <string>(serializer);
                    break;
                }

                case JTokenType.Integer:
                {
                    result[key] = token.ToObject <int>(serializer);
                    break;
                }

                case JTokenType.Boolean:
                {
                    result[key] = token.ToObject <bool>(serializer);
                    break;
                }

                case JTokenType.Object:
                {
                    result[key] = token.ToObject <PropertiesDictionary>(serializer);
                    break;
                }

                case JTokenType.Array:
                {
                    ja = (JArray)property.Value;
                    if (ja.Children().First().Type == JTokenType.Integer)
                    {
                        result[key] = token.ToObject <IntegerSet>(serializer);
                    }
                    else
                    {
                        Debug.Assert(ja.Children().First().Type == JTokenType.String);
                        result[key] = token.ToObject <StringSet>(serializer);
                    }
                    break;
                }
                }
            }

            return(result);
        }
 public PropertiesDictionary(PropertiesDictionary initializer) :
     this(initializer, null)
 {
 }
        public static void LoadPropertiesFromXmlStream(this IDictionary propertyBag, XmlReader reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            if (propertyBag == null)
            {
                throw new ArgumentNullException(nameof(propertyBag));
            }

            while (reader.IsStartElement(PROPERTIES_ID) || reader.IsStartElement(PROPERTY_ID))
            {
                string key   = null;
                string value = null;
                bool   isEmpty;

                if (reader.IsStartElement(PROPERTIES_ID))
                {
                    key = reader.GetAttribute(KEY_ID);

                    string typeName = reader.GetAttribute(TYPE_ID);

                    IDictionary nestedPropertyBag;

                    if (string.IsNullOrEmpty(typeName))
                    {
                        nestedPropertyBag = new PropertiesDictionary();
                    }
                    else
                    {
                        Type type = GetPropertiesDictionaryType(typeName);
                        nestedPropertyBag = (IDictionary)Activator.CreateInstance(type);
                    }

                    propertyBag[key] = nestedPropertyBag;
                    isEmpty          = reader.IsEmptyElement;
                    if (!isEmpty)
                    {
                        reader.ReadStartElement(PROPERTIES_ID);
                        LoadPropertiesFromXmlStream(nestedPropertyBag, reader);
                        reader.ReadEndElement();
                    }
                    else
                    {
                        reader.Read();
                    }
                }
                else
                {
                    key   = reader.GetAttribute(KEY_ID);
                    value = reader.GetAttribute(VALUE_ID);
                    string typeName = reader.GetAttribute(TYPE_ID);
                    isEmpty = reader.IsEmptyElement;

                    if (typeName == STRING_SET_ID ||
                        typeName == INTEGER_SET_ID)
                    {
                        if (typeName == STRING_SET_ID)
                        {
                            StringSet set = new StringSet();
                            propertyBag[key] = set;
                            LoadSet(set, reader);
                        }
                        else
                        {
                            IntegerSet set = new IntegerSet();
                            propertyBag[key] = set;
                            LoadSet(set, reader);
                        }

                        if (!isEmpty)
                        {
                            reader.ReadEndElement();
                        }
                        continue;
                    }

                    reader.ReadStartElement(PROPERTY_ID);
                    Type propertyType = GetPropertiesDictionaryType(typeName);

                    if (typeName == "System.Version")
                    {
                        Version version;
                        bool    succeeded = Version.TryParse(value, out version);
                        Debug.Assert(succeeded);
                        propertyBag[key] = version;
                        continue;
                    }

                    TypeConverter tc = TypeDescriptor.GetConverter(propertyType);
                    Debug.Assert(tc.CanConvertFrom(typeof(string)));

                    object propertyValue = tc.ConvertFromString(value);
                    propertyBag[key] = propertyValue;

                    Debug.Assert(isEmpty);
                }
            }
        }