private static <T> Field<T> createCollectionEnumV(
      int number,
      String name,
      final java.lang.reflect.Field f,
      final MessageFactory messageFactory,
      final Class<Object> genericType,
      IdStrategy strategy) {
    final EnumIO<?> eio = strategy.getEnumIO(genericType);
    return new Field<T>(FieldType.ENUM, number, name, true, f.getAnnotation(Tag.class)) {
      {
        f.setAccessible(true);
      }

      @SuppressWarnings("unchecked")
      protected void mergeFrom(Input input, T message) throws IOException {
        final Enum<?> value = eio.readFrom(input);
        try {
          final Collection<Enum<?>> existing = (Collection<Enum<?>>) f.get(message);
          if (existing == null) {
            final Collection<Enum<?>> collection = messageFactory.newMessage();
            collection.add(value);
            f.set(message, collection);
          } else existing.add(value);
        } catch (IllegalArgumentException e) {
          throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
          throw new RuntimeException(e);
        }
      }

      @SuppressWarnings("unchecked")
      protected void writeTo(Output output, T message) throws IOException {
        final Collection<Enum<?>> collection;
        try {
          collection = (Collection<Enum<?>>) f.get(message);
        } catch (IllegalArgumentException e) {
          throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
          throw new RuntimeException(e);
        }

        if (collection != null && !collection.isEmpty()) {
          for (Enum<?> en : collection) EnumIO.writeTo(output, number, true, en);
        }
      }

      protected void transfer(Pipe pipe, Input input, Output output, boolean repeated)
          throws IOException {
        EnumIO.transfer(pipe, input, output, number, repeated);
      }
    };
  }
        @SuppressWarnings("unchecked")
        public <T> Field<T> create(
            int number, String name, final java.lang.reflect.Field f, IdStrategy strategy) {
          if (null != f.getAnnotation(Morph.class)) {
            // can be used to override the configured system property:
            // RuntimeEnv.COLLECTION_SCHEMA_ON_REPEATED_FIELDS

            // In this context, Morph annotation will force using a
            // collection
            // schema only for this particular field.
            return RuntimeCollectionFieldFactory.getFactory().create(number, name, f, strategy);
          }

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

            return createCollectionEnumV(
                number,
                name,
                f,
                strategy.getEnumIO(enumType).getEnumSetFactory(),
                enumType,
                strategy);
          }

          final MessageFactory messageFactory = strategy.getCollectionFactory(f.getType());

          final Class<Object> genericType = (Class<Object>) getGenericType(f, 0);
          if (genericType == null) {
            // the value is not a simple parameterized type.
            return createCollectionObjectV(
                number,
                name,
                f,
                messageFactory,
                genericType,
                PolymorphicSchemaFactories.OBJECT,
                strategy);
          }

          final Delegate<Object> inline = getDelegateOrInline(genericType, strategy);
          if (inline != null)
            return createCollectionInlineV(number, name, f, messageFactory, inline);

          if (Message.class.isAssignableFrom(genericType))
            return createCollectionPojoV(number, name, f, messageFactory, genericType, strategy);

          if (genericType.isEnum())
            return createCollectionEnumV(number, name, f, messageFactory, genericType, strategy);

          final PolymorphicSchema.Factory factory =
              PolymorphicSchemaFactories.getFactoryFromRepeatedValueGenericType(genericType);
          if (factory != null) {
            return createCollectionObjectV(
                number, name, f, messageFactory, genericType, factory, strategy);
          }

          if (pojo(genericType, f.getAnnotation(Morph.class), strategy))
            return createCollectionPojoV(number, name, f, messageFactory, genericType, strategy);

          if (genericType.isInterface()) {
            return createCollectionObjectV(
                number,
                name,
                f,
                messageFactory,
                genericType,
                PolymorphicSchemaFactories.OBJECT,
                strategy);
          }

          return createCollectionPolymorphicV(
              number, name, f, messageFactory, genericType, strategy);
        }