public TypeSerializer GetSerializerForType(Type valueType)
        {
            if (valueType == null)
            {
                throw new ArgumentNullException("valueType");
            }

            if (valueType.BaseType == typeof(MulticastDelegate) || valueType.BaseType == typeof(Delegate))
            {
                throw new InvalidOperationException(string.Format("Unable to serialize delegate type '{0}'.", valueType));
            }

            var serializer = default(TypeSerializer);

            if (this.serializers.TryGetValue(valueType, out serializer))
            {
                return(serializer);
            }


            var typeSerializerAttribute = valueType.GetCustomAttributes(typeof(TypeSerializerAttribute), inherit: false).FirstOrDefault() as TypeSerializerAttribute;

            if (typeSerializerAttribute != null)
            {
                serializer = this.CreateCustomSerializer(valueType, typeSerializerAttribute);
            }
            else if (valueType.IsEnum)
            {
                serializer = this.CreateEnumSerializer(valueType);
            }
            else if (typeof(IDictionary).IsAssignableFrom(valueType) &&
                     (!valueType.IsInstanceOfType(typeof(IDictionary <,>)) || DictionarySerializer.IsStringKeyType(valueType.GetInstantiationArguments(typeof(IDictionary <,>))[0])))
            {
                serializer = this.CreateDictionarySerializer(valueType);
            }
            else if (valueType.IsArray || typeof(IEnumerable).IsAssignableFrom(valueType))
            {
                serializer = this.CreateArraySerializer(valueType);
            }
            else
            {
                serializer = (this.SerializerFactory != null ? this.SerializerFactory(valueType) : null) ?? this.CreateObjectSerializer(valueType);
            }

            this.serializers.Add(valueType, serializer);
            return(serializer);
        }