private void DetermineSerializationStrategy(
            TContext context,
            Type concreteType,
            out SerializationTarget targetInfo,
            out bool isUnpackFromRequired,
            out bool isAddItemRequired
            )
        {
            targetInfo =
                UnpackHelpers.DetermineCollectionSerializationStrategy(
                    concreteType ?? this.TargetType,
                    context.SerializationContext.CompatibilityOptions.AllowAsymmetricSerializer
                    );

            switch (this.CollectionTraits.DetailedCollectionType)
            {
            case CollectionDetailedKind.NonGenericEnumerable:
            case CollectionDetailedKind.NonGenericCollection:
            {
                isUnpackFromRequired = true;
                isAddItemRequired    = true;
                break;
            }

            case CollectionDetailedKind.NonGenericList:
            {
                isUnpackFromRequired = false;
                isAddItemRequired    = false;
                break;
            }

            case CollectionDetailedKind.NonGenericDictionary:
            {
                isUnpackFromRequired = false;
                isAddItemRequired    = false;
                break;
            }

            case CollectionDetailedKind.GenericEnumerable:
            {
                isUnpackFromRequired = true;
                isAddItemRequired    = true;
                break;
            }

            case CollectionDetailedKind.GenericDictionary:
            {
                isUnpackFromRequired = false;
                isAddItemRequired    = false;
                break;
            }

#if !NETFX_35 && !UNITY && !NETFX_40 && !(SILVERLIGHT && !WINDOWS_PHONE)
            case CollectionDetailedKind.GenericReadOnlyDictionary:
            {
                isUnpackFromRequired = false;
                isAddItemRequired    = true;
                break;
            }

            case CollectionDetailedKind.GenericReadOnlyList:
            case CollectionDetailedKind.GenericReadOnlyCollection:
            {
                isUnpackFromRequired = false;
                isAddItemRequired    = true;
                break;
            }
#endif // !NETFX_35 && !UNITY && !NETFX_40 && !( SILVERLIGHT && !WINDOWS_PHONE )
            default:
            {
                isUnpackFromRequired = false;
                isAddItemRequired    = false;
                break;
            }
            }             // switch
        }
        public static MessagePackSerializer CreateCollectionSerializer <T>(
#endif // !UNITY
            SerializationContext context,
            Type targetType,
            CollectionTraits traits,
            PolymorphismSchema schema
            )
        {
            var targetInfo = UnpackHelpers.DetermineCollectionSerializationStrategy(targetType, context.CompatibilityOptions.AllowAsymmetricSerializer);

            switch (traits.DetailedCollectionType)
            {
            case CollectionDetailedKind.Array:
            {
                return(ArraySerializer.Create <T>(context, schema));
            }

            case CollectionDetailedKind.GenericList:
#if !NETFX_35 && !UNITY
            case CollectionDetailedKind.GenericSet:
#endif // !NETFX_35 && !UNITY
            case CollectionDetailedKind.GenericCollection:
            {
                return
                    (#if !UNITY
                     (MessagePackSerializer <T>)
                     ReflectionExtensions.CreateInstancePreservingExceptionType <IVariantReflectionSerializerFactory>(
                         typeof(CollectionSerializerFactory <,>).MakeGenericType(typeof(T), traits.ElementType)
                         ).Create(context, targetType, traits, schema, targetInfo));
#else
                     new ReflectionCollectionMessagePackSerializer(context, typeof(T), targetType, traits, schema, targetInfo);
#endif // !UNITY
            }

            case CollectionDetailedKind.GenericEnumerable:
            {
                return
                    (#if !UNITY
                     (MessagePackSerializer <T>)
                     ReflectionExtensions.CreateInstancePreservingExceptionType <IVariantReflectionSerializerFactory>(
                         typeof(EnumerableSerializerFactory <,>).MakeGenericType(typeof(T), traits.ElementType)
                         ).Create(context, targetType, traits, schema, targetInfo));
#else
                     new ReflectionEnumerableMessagePackSerializer(context, typeof(T), targetType, traits, schema, targetInfo);
#endif // !Enumerable
            }

            case CollectionDetailedKind.GenericDictionary:
            {
                var genericArgumentOfKeyValuePair = traits.ElementType.GetGenericArguments();
                return
                    (#if !UNITY
                     (MessagePackSerializer <T>)
                     ReflectionExtensions.CreateInstancePreservingExceptionType <IVariantReflectionSerializerFactory>(
                         typeof(DictionarySerializerFactory <, ,>).MakeGenericType(
                             typeof(T),
                             genericArgumentOfKeyValuePair[0],
                             genericArgumentOfKeyValuePair[1]
                             )
                         ).Create(context, targetType, traits, schema, targetInfo));
#else
                     new ReflectionDictionaryMessagePackSerializer(
                         context,
                         typeof(T),
                         targetType,
                         genericArgumentOfKeyValuePair[0],
                         genericArgumentOfKeyValuePair[1],
                         traits,
                         schema,
                         targetInfo
                         );
#endif // !UNITY
            }

            case CollectionDetailedKind.NonGenericList:
            {
                return
                    (#if !UNITY
                     (MessagePackSerializer <T>)
                     ReflectionExtensions.CreateInstancePreservingExceptionType <IVariantReflectionSerializerFactory>(
                         typeof(NonGenericListSerializerFactory <>).MakeGenericType(typeof(T))
                         ).Create(context, targetType, traits, schema, targetInfo));
#else
                     new ReflectionNonGenericListMessagePackSerializer(context, typeof(T), targetType, traits, schema, targetInfo);
#endif // !UNITY
            }

            case CollectionDetailedKind.NonGenericCollection:
            {
                return
                    (#if !UNITY
                     (MessagePackSerializer <T>)
                     ReflectionExtensions.CreateInstancePreservingExceptionType <IVariantReflectionSerializerFactory>(
                         typeof(NonGenericCollectionSerializerFactory <>).MakeGenericType(typeof(T))
                         ).Create(context, targetType, traits, schema, targetInfo));
#else
                     new ReflectionNonGenericCollectionMessagePackSerializer(context, typeof(T), targetType, traits, schema, targetInfo);
#endif // !UNITY
            }

            case CollectionDetailedKind.NonGenericEnumerable:
            {
                return
                    (#if !UNITY
                     (MessagePackSerializer <T>)
                     ReflectionExtensions.CreateInstancePreservingExceptionType <IVariantReflectionSerializerFactory>(
                         typeof(NonGenericEnumerableSerializerFactory <>).MakeGenericType(typeof(T))
                         ).Create(context, targetType, traits, schema, targetInfo));
#else
                     new ReflectionNonGenericEnumerableMessagePackSerializer(context, typeof(T), targetType, traits, schema, targetInfo);
#endif // !UNITY
            }

            case CollectionDetailedKind.NonGenericDictionary:
            {
                return
                    (#if !UNITY
                     (MessagePackSerializer <T>)
                     ReflectionExtensions.CreateInstancePreservingExceptionType <IVariantReflectionSerializerFactory>(
                         typeof(NonGenericDictionarySerializerFactory <>).MakeGenericType(typeof(T))
                         ).Create(context, targetType, traits, schema, targetInfo));
#else
                     new ReflectionNonGenericDictionaryMessagePackSerializer(context, typeof(T), targetType, traits, schema, targetInfo);
#endif // !UNITY
            }

            default:
            {
                return(null);
            }
            }
        }