/// <summary>
        ///
        /// </summary>
        /// <param name="content">Raw configuration file content.</param>
        /// <param name="configuration">The configuration object, implementing IConfigurable.</param>
        /// <param name="customParsers">Optional array of parser allowing to parse any type the way you want.</param>
        public static void AssignConfiguration(string content, IConfigurable configuration, params ICustomParser[] customParsers)
        {
            Dictionary <string, string> rawConfiguration = ParseConfiguration(content);
            var configurableProperties =
                (from p in configuration.GetType().GetProperties()
                 let attr = p.GetCustomAttributes(typeof(MatchingKeyAttribute), true)
                            where attr.Length == 1
                            select new { Property = p, Attribute = attr.First() as MatchingKeyAttribute })
                .ToList();

            foreach (var item in rawConfiguration)
            {
                string               key               = item.Key.ToLowerInvariant();
                var                  matchingProps     = configurableProperties.Where(x => x.Attribute.Key == key);
                PropertyInfo         matchingProp      = null;
                MatchingKeyAttribute matchingAttribute = null;
                if (matchingProps.Any())
                {
                    try
                    {
                        // try to find a matching property for this key
                        var single = matchingProps.Single();
                        matchingProp      = single.Property;
                        matchingAttribute = single.Attribute;
                        configurableProperties.Remove(single);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(string.Format("The key \"{0}\" was found multiple times!", key), ex);
                    }
                    // parse value
                    var appropriateParser = customParsers.FirstOrDefault(x => x.ReturnType == matchingProp.PropertyType);
                    if (appropriateParser != null)
                    {
                        object parsed = appropriateParser.Parse(item.Value, matchingAttribute.CustomParameter);
                        matchingProp.SetValue(configuration, parsed, null);
                    }
                    // default parsers
                    else if (matchingProp.PropertyType == typeof(string))
                    {
                        // todo: handle default values for strings
                        matchingProp.SetValue(configuration, item.Value, null);
                    }
                    else if (matchingProp.PropertyType == typeof(bool))
                    {
                        if (matchingAttribute.CustomParameter is bool)
                        {
                            matchingProp.SetValue(configuration, ParseBool(item.Value, (bool)matchingAttribute.CustomParameter), null);
                        }
                        else
                        {
                            matchingProp.SetValue(configuration, ParseBool(item.Value), null);
                        }
                    }
                    else if (matchingProp.PropertyType == typeof(int))
                    {
                        if (matchingAttribute.CustomParameter is int)
                        {
                            matchingProp.SetValue(configuration, ParseInt(item.Value, (int)matchingAttribute.CustomParameter), null);
                        }
                        else
                        {
                            matchingProp.SetValue(configuration, ParseInt(item.Value), null);
                        }
                    }
                    // TODO: default parser for other simple types (int, float...)
                    else
                    {
                        throw new Exception(string.Format("Could not find a parser for type \"{0}\"!", matchingProp.PropertyType));
                    }
                }
                else
                {
                    // no matching assignable property
                    configuration.HandleDynamicKey(item.Key, item.Value);
                }
            }
            // assign default value if present for remaining properties not found in configuration
            foreach (var remainingPropery in configurableProperties)
            {
                // todo : throw exception if no default parameter to avoid impredictable errors?
                // >> need to differentiate default null from provided null
                if (remainingPropery.Attribute.CustomParameter != null)
                {
                    remainingPropery.Property.SetValue(configuration, remainingPropery.Attribute.CustomParameter, null);
                }
            }
        }