@Override
        @SuppressWarnings("unchecked")
        public <T> Field<T> create(int number, String name,
                final java.lang.reflect.Field f, IdStrategy strategy)
        {
            final Class<?> clazz = f.getType();
            final Morph morph = f.getAnnotation(Morph.class);
            
            if (0 != (IdStrategy.POJO_SCHEMA_ON_MAP_FIELDS & strategy.flags) && 
                    (morph == null || morph.value()))
            {
                if (!clazz.getName().startsWith("java.util") && 
                        pojo(clazz, morph, strategy))
                {
                    return POJO.create(number, name, f, strategy);
                }
                
                return OBJECT.create(number, name, f, strategy);
            }
            
            if (Modifier.isAbstract(clazz.getModifiers()))
            {
                if (!clazz.isInterface())
                {
                    // abstract class
                    return OBJECT.create(number, name, f, strategy);
                }

                if (morph == null)
                {
                    if (0 != (IdStrategy.MORPH_MAP_INTERFACES & strategy.flags))
                        return OBJECT.create(number, name, f, strategy);
                }
                else if (morph.value())
                    return OBJECT.create(number, name, f, strategy);
            }

            final MessageFactory messageFactory;
            if (EnumMap.class.isAssignableFrom(f.getType()))
            {
                final Class<Object> enumType = (Class<Object>) getGenericType(
                        f, 0);
                if (enumType == null)
                {
                    // still handle the serialization of EnumMaps even without
                    // generics
                    return RuntimeFieldFactory.OBJECT.create(number, name, f,
                            strategy);
                }

                messageFactory = strategy.getEnumIO(enumType)
                        .getEnumMapFactory();
            }
            else
            {
                messageFactory = strategy.getMapFactory(f.getType());
            }
            
            final Class<Object> clazzK = (Class<Object>) getGenericType(f, 0);
            if (clazzK == null ||
                    2 != ((ParameterizedType)f.getGenericType()).getActualTypeArguments().length ||
                    ((Map.class.isAssignableFrom(clazzK) || 
                    Collection.class.isAssignableFrom(clazzK)) && 
                    !strategy.isRegistered(clazzK)))
            {
                // the key is not a simple parameterized type.
                return createMapObjectKObjectV(number, name, f, messageFactory,
                        strategy.OBJECT_ELEMENT_SCHEMA,
                        strategy.OBJECT_ELEMENT_SCHEMA.pipeSchema,
                        strategy.OBJECT_ELEMENT_SCHEMA,
                        strategy.OBJECT_ELEMENT_SCHEMA.pipeSchema, strategy);
            }

            final Class<Object> clazzV = (Class<Object>) getGenericType(f, 1);
            if (clazzV == null || ((Map.class.isAssignableFrom(clazzV) || 
                    Collection.class.isAssignableFrom(clazzV)) && 
                    !strategy.isRegistered(clazzV)))
            {
                // the value is not a simple parameterized type.
                final Delegate<Object> inlineK = getDelegateOrInline(clazzK,
                        strategy);
                if (inlineK != null)
                {
                    return createMapInlineKObjectV(number, name, f,
                            messageFactory, inlineK,
                            strategy.OBJECT_ELEMENT_SCHEMA,
                            strategy.OBJECT_ELEMENT_SCHEMA.pipeSchema, strategy);
                }

                if (Message.class.isAssignableFrom(clazzK))
                {
                    return createMapPojoKObjectV(number, name, f,
                            messageFactory, clazzK,
                            strategy.OBJECT_ELEMENT_SCHEMA,
                            strategy.OBJECT_ELEMENT_SCHEMA.pipeSchema, strategy);
                }

                if (clazzK.isEnum())
                {
                    return createMapEnumKObjectV(number, name, f,
                            messageFactory, clazzK,
                            strategy.OBJECT_ELEMENT_SCHEMA,
                            strategy.OBJECT_ELEMENT_SCHEMA.pipeSchema, strategy);
                }

                final PolymorphicSchema psK = PolymorphicSchemaFactories
                        .getSchemaFromCollectionOrMapGenericType(clazzK,
                                strategy);

                if (psK != null)
                {
                    return createMapObjectKObjectV(number, name, f,
                            messageFactory, psK, psK.getPipeSchema(),
                            strategy.OBJECT_ELEMENT_SCHEMA,
                            strategy.OBJECT_ELEMENT_SCHEMA.pipeSchema, strategy);
                }

                if (pojo(clazzK, morph, strategy))
                {
                    return createMapPojoKObjectV(number, name, f,
                            messageFactory, clazzK,
                            strategy.OBJECT_ELEMENT_SCHEMA,
                            strategy.OBJECT_ELEMENT_SCHEMA.pipeSchema, strategy);
                }

                /*
                 * if(clazzK.isInterface()) { return createMapObjectKObjectV(number, name, f, messageFactory,
                 * strategy.OBJECT_COLLECTION_VALUE_SCHEMA, strategy.OBJECT_COLLECTION_VALUE_SCHEMA.pipeSchema,
                 * strategy.OBJECT_COLLECTION_VALUE_SCHEMA, strategy.OBJECT_COLLECTION_VALUE_SCHEMA.pipeSchema,
                 * strategy); }
                 * 
                 * // TODO add createMapPolymorphicKObjectV?
                 */
                return createMapObjectKObjectV(number, name, f, messageFactory,
                        strategy.OBJECT_ELEMENT_SCHEMA,
                        strategy.OBJECT_ELEMENT_SCHEMA.pipeSchema,
                        strategy.OBJECT_ELEMENT_SCHEMA,
                        strategy.OBJECT_ELEMENT_SCHEMA.pipeSchema, strategy);
            }

            final Delegate<Object> inlineK = getDelegateOrInline(clazzK,
                    strategy);

            if (inlineK != null)
            {
                final Delegate<Object> inlineV = getDelegateOrInline(clazzV,
                        strategy);
                if (inlineV != null)
                    return createMapInlineKInlineV(number, name, f,
                            messageFactory, inlineK, inlineV);

                if (Message.class.isAssignableFrom(clazzV))
                    return createMapInlineKPojoV(number, name, f,
                            messageFactory, inlineK, clazzV, strategy);

                if (clazzV.isEnum())
                    return createMapInlineKEnumV(number, name, f,
                            messageFactory, inlineK, clazzV, strategy);

                final PolymorphicSchema psV = PolymorphicSchemaFactories
                        .getSchemaFromCollectionOrMapGenericType(clazzV,
                                strategy);
                if (psV != null)
                {
                    return createMapInlineKObjectV(number, name, f,
                            messageFactory, inlineK, psV, psV.getPipeSchema(),
                            strategy);
                }

                if (pojo(clazzV, f.getAnnotation(Morph.class), strategy))
                    return createMapInlineKPojoV(number, name, f,
                            messageFactory, inlineK, clazzV, strategy);

                if (clazzV.isInterface())
                {
                    return createMapInlineKObjectV(number, name, f,
                            messageFactory, inlineK,
                            strategy.OBJECT_ELEMENT_SCHEMA,
                            strategy.OBJECT_ELEMENT_SCHEMA.pipeSchema, strategy);
                }

                return createMapInlineKPolymorphicV(number, name, f,
                        messageFactory, inlineK, clazzV, strategy);
            }

            if (clazzK.isEnum())
            {
                final Delegate<Object> inlineV = getDelegateOrInline(clazzV,
                        strategy);
                if (inlineV != null)
                    return createMapEnumKInlineV(number, name, f,
                            messageFactory, clazzK, inlineV, strategy);

                if (Message.class.isAssignableFrom(clazzV))
                    return createMapEnumKPojoV(number, name, f, messageFactory,
                            clazzK, clazzV, strategy);

                if (clazzV.isEnum())
                    return createMapEnumKEnumV(number, name, f, messageFactory,
                            clazzK, clazzV, strategy);

                final PolymorphicSchema psV = PolymorphicSchemaFactories
                        .getSchemaFromCollectionOrMapGenericType(clazzV,
                                strategy);
                if (psV != null)
                {
                    return createMapEnumKObjectV(number, name, f,
                            messageFactory, clazzK, psV, psV.getPipeSchema(),
                            strategy);
                }

                if (pojo(clazzV, f.getAnnotation(Morph.class), strategy))
                    return createMapEnumKPojoV(number, name, f, messageFactory,
                            clazzK, clazzV, strategy);

                if (clazzV.isInterface())
                {
                    return createMapEnumKObjectV(number, name, f,
                            messageFactory, clazzK,
                            strategy.OBJECT_ELEMENT_SCHEMA,
                            strategy.OBJECT_ELEMENT_SCHEMA.pipeSchema, strategy);
                }

                return createMapEnumKPolymorphicV(number, name, f,
                        messageFactory, clazzK, clazzV, strategy);
            }

            final PolymorphicSchema psK = PolymorphicSchemaFactories
                    .getSchemaFromCollectionOrMapGenericType(clazzK, strategy);
            if (psK != null)
            {
                return createMapObjectKObjectV(number, name, f, messageFactory,
                        psK, psK.getPipeSchema(),
                        strategy.OBJECT_ELEMENT_SCHEMA,
                        strategy.OBJECT_ELEMENT_SCHEMA.pipeSchema, strategy);
            }

            if (pojo(clazzK, f.getAnnotation(Morph.class), strategy))
            {
                final Delegate<Object> inlineV = getDelegateOrInline(clazzV,
                        strategy);
                if (inlineV != null)
                    return createMapPojoKInlineV(number, name, f,
                            messageFactory, clazzK, inlineV, strategy);

                if (Message.class.isAssignableFrom(clazzV))
                    return createMapPojoKPojoV(number, name, f, messageFactory,
                            clazzK, clazzV, strategy);

                if (clazzV.isEnum())
                    return createMapPojoKEnumV(number, name, f, messageFactory,
                            clazzK, clazzV, strategy);

                final PolymorphicSchema psV = PolymorphicSchemaFactories
                        .getSchemaFromCollectionOrMapGenericType(clazzV,
                                strategy);
                if (psV != null)
                {
                    return createMapPojoKObjectV(number, name, f,
                            messageFactory, clazzK, psV, psV.getPipeSchema(),
                            strategy);
                }

                if (pojo(clazzV, f.getAnnotation(Morph.class), strategy))
                    return createMapPojoKPojoV(number, name, f, messageFactory,
                            clazzK, clazzV, strategy);

                if (clazzV.isInterface())
                {
                    return createMapPojoKObjectV(number, name, f,
                            messageFactory, clazzK,
                            strategy.OBJECT_ELEMENT_SCHEMA,
                            strategy.OBJECT_ELEMENT_SCHEMA.pipeSchema, strategy);
                }

                return createMapPojoKPolymorphicV(number, name, f,
                        messageFactory, clazzK, clazzV, strategy);
            }

            return createMapObjectKObjectV(number, name, f, messageFactory,
                    strategy.OBJECT_ELEMENT_SCHEMA,
                    strategy.OBJECT_ELEMENT_SCHEMA.pipeSchema,
                    strategy.OBJECT_ELEMENT_SCHEMA,
                    strategy.OBJECT_ELEMENT_SCHEMA.pipeSchema, strategy);
        }
Static utility for creating runtime {@link java.util.Map} fields.

@author David Yu
@created Jan 21, 2011
protostuff-runtime/src/main/java/io/protostuff/runtime/RuntimeMapFieldFactory.java