Cleaning up earlier [JACKSON-689] fix, related type specialization code

diff --git a/src/mapper/java/org/codehaus/jackson/map/MapperConfig.java b/src/mapper/java/org/codehaus/jackson/map/MapperConfig.java
index 88a7461..34c19e7 100644
--- a/src/mapper/java/org/codehaus/jackson/map/MapperConfig.java
+++ b/src/mapper/java/org/codehaus/jackson/map/MapperConfig.java
@@ -590,6 +590,13 @@
     public final JavaType constructType(TypeReference<?> valueTypeRef) {
         return getTypeFactory().constructType(valueTypeRef.getType(), (TypeBindings) null);
     }
+
+    /**
+     * @since 1.9.1
+     */
+    public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass) {
+        return getTypeFactory().constructSpecializedType(baseType, subclass);
+    }
     
     /*
     /**********************************************************
diff --git a/src/mapper/java/org/codehaus/jackson/map/SerializerProvider.java b/src/mapper/java/org/codehaus/jackson/map/SerializerProvider.java
index 60c5caf..4571213 100644
--- a/src/mapper/java/org/codehaus/jackson/map/SerializerProvider.java
+++ b/src/mapper/java/org/codehaus/jackson/map/SerializerProvider.java
@@ -182,6 +182,13 @@
     public JavaType constructType(Type type) {
          return _config.getTypeFactory().constructType(type);
     }
+
+    /**
+     * @since 1.9.1
+     */
+    public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass) {
+        return _config.constructSpecializedType(baseType, subclass);
+    }
     
     /*
     /**********************************************************
diff --git a/src/mapper/java/org/codehaus/jackson/map/deser/BasicDeserializerFactory.java b/src/mapper/java/org/codehaus/jackson/map/deser/BasicDeserializerFactory.java
index cdceda7..691c287 100644
--- a/src/mapper/java/org/codehaus/jackson/map/deser/BasicDeserializerFactory.java
+++ b/src/mapper/java/org/codehaus/jackson/map/deser/BasicDeserializerFactory.java
@@ -290,7 +290,7 @@
                 throw new IllegalArgumentException("Can not find a deserializer for non-concrete Collection type "+type);
             }
             collectionClass = fallback;
-            type = (CollectionType) type.forcedNarrowBy(collectionClass);
+            type = (CollectionType) config.constructSpecializedType(type, collectionClass);
             // But if so, also need to re-check creators...
             beanDesc = config.introspectForCreation(type);
         }
@@ -413,7 +413,7 @@
                 throw new IllegalArgumentException("Can not find a deserializer for non-concrete Map type "+type);
             }
             mapClass = fallback;
-            type = (MapType) type.forcedNarrowBy(mapClass);
+            type = (MapType) config.constructSpecializedType(type, mapClass);
             // But if so, also need to re-check creators...
             beanDesc = config.introspectForCreation(type);
         }
diff --git a/src/mapper/java/org/codehaus/jackson/map/jsontype/impl/TypeDeserializerBase.java b/src/mapper/java/org/codehaus/jackson/map/jsontype/impl/TypeDeserializerBase.java
index e2f60cc..3d6aa5c 100644
--- a/src/mapper/java/org/codehaus/jackson/map/jsontype/impl/TypeDeserializerBase.java
+++ b/src/mapper/java/org/codehaus/jackson/map/jsontype/impl/TypeDeserializerBase.java
@@ -61,6 +61,10 @@
         if (defaultImpl == null) {
             _defaultImpl = null;
         } else {
+            /* 16-Oct-2011, tatu: should call this via TypeFactory; this is
+             *    not entirely safe... however, since Collections/Maps are
+             *    seldom (if ever) base types, may be ok.
+             */
             _defaultImpl = baseType.forcedNarrowBy(defaultImpl);
         }
     }
diff --git a/src/mapper/java/org/codehaus/jackson/map/ser/BeanPropertyWriter.java b/src/mapper/java/org/codehaus/jackson/map/ser/BeanPropertyWriter.java
index 83fd1e8..e7e880d 100644
--- a/src/mapper/java/org/codehaus/jackson/map/ser/BeanPropertyWriter.java
+++ b/src/mapper/java/org/codehaus/jackson/map/ser/BeanPropertyWriter.java
@@ -457,7 +457,7 @@
     {
         PropertySerializerMap.SerializerAndMapResult result;
         if (_nonTrivialBaseType != null) {
-            JavaType t = _nonTrivialBaseType.forcedNarrowBy(type);
+            JavaType t = provider.constructSpecializedType(_nonTrivialBaseType, type);
             result = map.findAndAddSerializer(t, provider, this);
         } else {
             result = map.findAndAddSerializer(type, provider, this);
diff --git a/src/mapper/java/org/codehaus/jackson/map/ser/PropertyBuilder.java b/src/mapper/java/org/codehaus/jackson/map/ser/PropertyBuilder.java
index 68e8036..a1ff0f0 100644
--- a/src/mapper/java/org/codehaus/jackson/map/ser/PropertyBuilder.java
+++ b/src/mapper/java/org/codehaus/jackson/map/ser/PropertyBuilder.java
@@ -180,7 +180,7 @@
                  *   and actually accept subtypes too for serialization. Bit dangerous in theory
                  *   but need to trust user here...
                  */
-                declaredType = declaredType.forcedNarrowBy(serClass);
+                declaredType = _config.constructSpecializedType(declaredType, serClass);
             }
             useStaticTyping = true;
         }
diff --git a/src/mapper/java/org/codehaus/jackson/map/ser/impl/UnwrappingBeanPropertyWriter.java b/src/mapper/java/org/codehaus/jackson/map/ser/impl/UnwrappingBeanPropertyWriter.java
index 315744f..63c3796 100644
--- a/src/mapper/java/org/codehaus/jackson/map/ser/impl/UnwrappingBeanPropertyWriter.java
+++ b/src/mapper/java/org/codehaus/jackson/map/ser/impl/UnwrappingBeanPropertyWriter.java
@@ -85,8 +85,8 @@
     {
         JsonSerializer<Object> serializer;
         if (_nonTrivialBaseType != null) {
-            JavaType t = _nonTrivialBaseType.forcedNarrowBy(type);
-            serializer = provider.findValueSerializer(t, this);
+            JavaType subtype = provider.constructSpecializedType(_nonTrivialBaseType, type);
+            serializer = provider.findValueSerializer(subtype, this);
         } else {
             serializer = provider.findValueSerializer(type, this);
         }
diff --git a/src/mapper/java/org/codehaus/jackson/map/ser/std/CollectionSerializer.java b/src/mapper/java/org/codehaus/jackson/map/ser/std/CollectionSerializer.java
index 99a49c3..31bad2d 100644
--- a/src/mapper/java/org/codehaus/jackson/map/ser/std/CollectionSerializer.java
+++ b/src/mapper/java/org/codehaus/jackson/map/ser/std/CollectionSerializer.java
@@ -61,7 +61,8 @@
                     if (serializer == null) {
                         // To fix [JACKSON-508]
                         if (_elementType.hasGenericTypes()) {
-                            serializer = _findAndAddDynamic(serializers, _elementType.forcedNarrowBy(cc), provider);
+                            serializer = _findAndAddDynamic(serializers,
+                                    provider.constructSpecializedType(_elementType, cc), provider);
                         } else {
                             serializer = _findAndAddDynamic(serializers, cc, provider);
                         }
diff --git a/src/mapper/java/org/codehaus/jackson/map/ser/std/MapSerializer.java b/src/mapper/java/org/codehaus/jackson/map/ser/std/MapSerializer.java
index 8c15fb8..c2c447c 100644
--- a/src/mapper/java/org/codehaus/jackson/map/ser/std/MapSerializer.java
+++ b/src/mapper/java/org/codehaus/jackson/map/ser/std/MapSerializer.java
@@ -251,7 +251,8 @@
                 JsonSerializer<Object> serializer = serializers.serializerFor(cc);
                 if (serializer == null) {
                     if (_valueType.hasGenericTypes()) {
-                        serializer = _findAndAddDynamic(serializers, _valueType.forcedNarrowBy(cc), provider);
+                        serializer = _findAndAddDynamic(serializers,
+                                provider.constructSpecializedType(_valueType, cc), provider);
                     } else {
                         serializer = _findAndAddDynamic(serializers, cc, provider);
                     }
diff --git a/src/mapper/java/org/codehaus/jackson/map/ser/std/ObjectArraySerializer.java b/src/mapper/java/org/codehaus/jackson/map/ser/std/ObjectArraySerializer.java
index f02b4df..ef93788 100644
--- a/src/mapper/java/org/codehaus/jackson/map/ser/std/ObjectArraySerializer.java
+++ b/src/mapper/java/org/codehaus/jackson/map/ser/std/ObjectArraySerializer.java
@@ -114,7 +114,8 @@
                 if (serializer == null) {
                     // To fix [JACKSON-508]
                     if (_elementType.hasGenericTypes()) {
-                        serializer = _findAndAddDynamic(serializers, _elementType.forcedNarrowBy(cc), provider);
+                        serializer = _findAndAddDynamic(serializers,
+                                provider.constructSpecializedType(_elementType, cc), provider);
                     } else {
                         serializer = _findAndAddDynamic(serializers, cc, provider);
                     }
diff --git a/src/mapper/java/org/codehaus/jackson/map/ser/std/StdContainerSerializers.java b/src/mapper/java/org/codehaus/jackson/map/ser/std/StdContainerSerializers.java
index 7947abc..57a91e1 100644
--- a/src/mapper/java/org/codehaus/jackson/map/ser/std/StdContainerSerializers.java
+++ b/src/mapper/java/org/codehaus/jackson/map/ser/std/StdContainerSerializers.java
@@ -112,7 +112,8 @@
                         if (serializer == null) {
                             // To fix [JACKSON-508]
                             if (_elementType.hasGenericTypes()) {
-                                serializer = _findAndAddDynamic(serializers, _elementType.forcedNarrowBy(cc), provider);
+                                serializer = _findAndAddDynamic(serializers,
+                                        provider.constructSpecializedType(_elementType, cc), provider);
                             } else {
                                 serializer = _findAndAddDynamic(serializers, cc, provider);
                             }
@@ -174,7 +175,8 @@
                         if (serializer == null) {
                             // To fix [JACKSON-508]
                             if (_elementType.hasGenericTypes()) {
-                                serializer = _findAndAddDynamic(serializers, _elementType.forcedNarrowBy(cc), provider);
+                                serializer = _findAndAddDynamic(serializers,
+                                        provider.constructSpecializedType(_elementType, cc), provider);
                             } else {
                                 serializer = _findAndAddDynamic(serializers, cc, provider);
                             }
diff --git a/src/mapper/java/org/codehaus/jackson/map/type/SimpleType.java b/src/mapper/java/org/codehaus/jackson/map/type/SimpleType.java
index 5377228..dfc3dee 100644
--- a/src/mapper/java/org/codehaus/jackson/map/type/SimpleType.java
+++ b/src/mapper/java/org/codehaus/jackson/map/type/SimpleType.java
@@ -67,19 +67,6 @@
     protected JavaType _narrow(Class<?> subclass)
     {
         // Should we check that there is a sub-class relationship?
-        /* As per [JACKSON-689], Iterable-to-Collection can be problematic;
-         * needs handling. Not very clean, but can't think of better way
-         * quite yet... revisit if/when we find other special cases
-         */
-        if (_class == Iterable.class) {
-            // Specific issue here: should call TypeFactory, but we have no access...
-            if (Collection.class.isAssignableFrom(subclass)) {
-                JavaType elemType = (_typeParameters == null) ?
-                        constructUnsafe(Object.class) : _typeParameters[0];
-                // this is unclean too, ref to other impl type...
-                return CollectionType.construct(subclass, elemType);
-            }
-        }
         return new SimpleType(subclass, _typeNames, _typeParameters, _valueHandler, _typeHandler);
     }
 
diff --git a/src/mapper/java/org/codehaus/jackson/map/type/TypeFactory.java b/src/mapper/java/org/codehaus/jackson/map/type/TypeFactory.java
index a853f30..dfed4e2 100644
--- a/src/mapper/java/org/codehaus/jackson/map/type/TypeFactory.java
+++ b/src/mapper/java/org/codehaus/jackson/map/type/TypeFactory.java
@@ -301,7 +301,7 @@
 
     /**
      * Factory method for creating a subtype of given base type, as defined
-     * ny specified subclass; but retaining generic type information if any.
+     * by specified subclass; but retaining generic type information if any.
      * Can be used, for example, to get equivalent of "HashMap&lt;String,Integer>"
      * from "Map&ltString,Integer>" by giving <code>HashMap.class</code>
      * as subclass.