/// <summary>Gets parse function.</summary>
        /// <exception cref="ArgumentException">Thrown when one or more arguments have unsupported or
        /// illegal values.</exception>
        /// <returns>The parse function.</returns>
        public static ParseStringDelegate GetParseFn()
        {
            var enumerableInterface = typeof(T).GetTypeWithGenericInterfaceOf(typeof(IEnumerable <>));

            if (enumerableInterface == null)
            {
                throw new ArgumentException(string.Format("Type {0} is not of type IEnumerable<>", typeof(T).FullName));
            }

            //optimized access for regularly used types
            if (typeof(T) == typeof(IEnumerable <string>))
            {
                return(DeserializeListWithElements <TSerializer> .ParseStringList);
            }

            if (typeof(T) == typeof(IEnumerable <int>))
            {
                return(DeserializeListWithElements <TSerializer> .ParseIntList);
            }

            var elementType = enumerableInterface.GenericTypeArguments()[0];

            var supportedTypeParseMethod = DeserializeListWithElements <TSerializer> .Serializer.GetParseFn(elementType);

            if (supportedTypeParseMethod != null)
            {
                const Type createListTypeWithNull = null; //Use conversions outside this class. see: Queue

                var parseFn = DeserializeListWithElements <TSerializer> .GetListTypeParseFn(
                    createListTypeWithNull, elementType, supportedTypeParseMethod);

                return(value => parseFn(value, createListTypeWithNull, supportedTypeParseMethod));
            }

            return(null);
        }
        /// <summary>Gets parse function.</summary>
        /// <exception cref="ArgumentException">Thrown when one or more arguments have unsupported or
        /// illegal values.</exception>
        /// <returns>The parse function.</returns>
        public static ParseStringDelegate GetParseFn()
        {
            var listInterface = typeof(T).GetTypeWithGenericInterfaceOf(typeof(IList <>));

            if (listInterface == null)
            {
                throw new ArgumentException(string.Format("Type {0} is not of type IList<>", typeof(T).FullName));
            }

            //optimized access for regularly used types
            if (typeof(T) == typeof(List <string>))
            {
                return(DeserializeListWithElements <TSerializer> .ParseStringList);
            }

            if (typeof(T) == typeof(List <int>))
            {
                return(DeserializeListWithElements <TSerializer> .ParseIntList);
            }

            var elementType = listInterface.GenericTypeArguments()[0];

            var supportedTypeParseMethod = DeserializeListWithElements <TSerializer> .Serializer.GetParseFn(elementType);

            if (supportedTypeParseMethod != null)
            {
                var createListType = typeof(T).HasAnyTypeDefinitionsOf(typeof(List <>), typeof(IList <>))
                    ? null : typeof(T);

                var parseFn = DeserializeListWithElements <TSerializer> .GetListTypeParseFn(createListType, elementType, supportedTypeParseMethod);

                return(value => parseFn(value, createListType, supportedTypeParseMethod));
            }

            return(null);
        }