Update release notes wrt #2133, minor code cleanup
diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x
index e97ec27..f83031c 100644
--- a/release-notes/CREDITS-2.x
+++ b/release-notes/CREDITS-2.x
@@ -837,6 +837,9 @@
 Semyon Levin (remal@github)
   * Contributed #2120: `NioPathDeserializer` improvement
    (2.9.7)
+  * Contributed #2133: Improve `DeserializationProblemHandler.handleUnexpectedToken()`
+    to allow handling of Collection problems
+   (2.10.0)
 
 Pavel Nikitin (morj@github)
   * Requested #2181: Don't re-use dynamic serializers for property-updating copy constructors
diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x
index 60e7cc8..0a55cc4 100644
--- a/release-notes/VERSION-2.x
+++ b/release-notes/VERSION-2.x
@@ -8,6 +8,9 @@
 
 #2129: Add `SerializationFeature.WRITE_ENUM_KEYS_USING_INDEX`, separate from value setting
  (suggested by renzihui@github)
+#2133: Improve `DeserializationProblemHandler.handleUnexpectedToken()` to allow handling of
+  Collection problems
+ (contributed by Semyon L)
 #2149: Add `MapperFeature.ACCEPT_CASE_INSENSITIVE_VALUES`
  (suggested by Craig P)
 #2164: `FactoryBasedEnumDeserializer` does not respect
diff --git a/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java b/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java
index 36cf0a4..ea65485 100644
--- a/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java
+++ b/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java
@@ -1111,7 +1111,7 @@
     public Object handleUnexpectedToken(Class<?> instClass, JsonParser p)
         throws IOException
     {
-        return handleUnexpectedToken(instClass, p.getCurrentToken(), p, null);
+        return handleUnexpectedToken(constructType(instClass), p.getCurrentToken(), p, null);
     }
 
     /**
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java
index 8db39de..dc8776b 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java
@@ -195,12 +195,7 @@
             default:
             }
         }
-        JavaType valueType = getValueType();
-        if (valueType != null) {
-            return ctxt.handleUnexpectedToken(valueType, p);
-        } else {
-            return ctxt.handleUnexpectedToken(handledType(), p);
-        }
+        return ctxt.handleUnexpectedToken(getValueType(ctxt), p);
     }
 
     @Deprecated // since 2.8; remove unless getting used
@@ -564,12 +559,7 @@
             p2.close();
             return ob;
         }
-        JavaType valueType = getValueType();
-        if (valueType != null) {
-            return ctxt.handleUnexpectedToken(valueType, p);
-        } else {
-            return ctxt.handleUnexpectedToken(handledType(), p);
-        }
+        return ctxt.handleUnexpectedToken(getValueType(ctxt), p);
     }
 
     /*
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java
index bcfb9c9..82cacd1 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java
@@ -1455,19 +1455,9 @@
             if (t == JsonToken.END_ARRAY) {
                 return null;
             }
-            JavaType valueType = getValueType();
-            if (valueType != null) {
-                return ctxt.handleUnexpectedToken(valueType, JsonToken.START_ARRAY, p, null);
-            } else {
-                return ctxt.handleUnexpectedToken(handledType(), JsonToken.START_ARRAY, p, null);
-            }
+            return ctxt.handleUnexpectedToken(getValueType(ctxt), JsonToken.START_ARRAY, p, null);
         }
-        JavaType valueType = getValueType();
-        if (valueType != null) {
-            return ctxt.handleUnexpectedToken(valueType, p);
-        } else {
-            return ctxt.handleUnexpectedToken(handledType(), p);
-        }
+        return ctxt.handleUnexpectedToken(getValueType(ctxt), p);
     }
 
     public Object deserializeFromEmbedded(JsonParser p, DeserializationContext ctxt)
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BuilderBasedDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/BuilderBasedDeserializer.java
index 0952b36..a92cbb6 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/BuilderBasedDeserializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/BuilderBasedDeserializer.java
@@ -216,12 +216,7 @@
             return finishBuild(ctxt, deserializeFromObject(p, ctxt));
         default:
         }
-        JavaType valueType = getValueType();
-        if (valueType != null) {
-            return ctxt.handleUnexpectedToken(valueType, p);
-        } else {
-            return ctxt.handleUnexpectedToken(handledType(), p);
-        }
+        return ctxt.handleUnexpectedToken(getValueType(ctxt), p);
     }
 
     /**
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/DeserializationProblemHandler.java b/src/main/java/com/fasterxml/jackson/databind/deser/DeserializationProblemHandler.java
index 2524f18..2d6b88c 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/DeserializationProblemHandler.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/DeserializationProblemHandler.java
@@ -202,32 +202,14 @@
     }
 
     /**
-     * Method that deserializers should call if the first token of the value to
-     * deserialize is of unexpected type (that is, type of token that deserializer
-     * cannot handle). This could occur, for example, if a Number deserializer
-     * encounter {@link JsonToken#START_ARRAY} instead of
-     * {@link JsonToken#VALUE_NUMBER_INT} or {@link JsonToken#VALUE_NUMBER_FLOAT}.
-     *<ul>
-     * <li>Indicate it does not know what to do by returning {@link #NOT_HANDLED}
-     *  </li>
-     * <li>Throw a {@link IOException} to indicate specific fail message (instead of
-     *    standard exception caller would throw
-     *  </li>
-     * <li>Handle content to match (by consuming or skipping it), and return actual
-     *    instantiated value (of type <code>targetType</code>) to use as replacement;
-     *    value may be `null` as well as expected target type.
-     *  </li>
-     * </ul>
-     *
-     * @param failureMsg Message that will be used by caller
-     *    to indicate type of failure unless handler produces value to use
-     *
-     * @return Either {@link #NOT_HANDLED} to indicate that handler does not know
-     *    what to do (and exception may be thrown), or value to use (possibly
-     *    <code>null</code>
+     * Deprecated variant of
+     * {@link #handleUnexpectedToken(DeserializationContext, JavaType, JsonToken, JsonParser, String)
      *
      * @since 2.8
+     *
+     * @deprecated Since 2.10
      */
+    @SuppressWarnings("javadoc")
     @Deprecated
     public Object handleUnexpectedToken(DeserializationContext ctxt,
             Class<?> targetType, JsonToken t, JsonParser p,
@@ -269,7 +251,7 @@
             String failureMsg)
         throws IOException
     {
-        // Calling class-version handler for backward compatibility
+        // Calling class-version handler for backward compatibility, as of 2.10
         return handleUnexpectedToken(ctxt, targetType.getRawClass(), t, p, failureMsg);
     }
 
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/impl/BeanAsArrayBuilderDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/impl/BeanAsArrayBuilderDeserializer.java
index 99924f4..6d3a507 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/impl/BeanAsArrayBuilderDeserializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/impl/BeanAsArrayBuilderDeserializer.java
@@ -344,12 +344,7 @@
         // Let's start with failure
         String message = "Cannot deserialize a POJO (of type %s) from non-Array representation (token: %s): "
             + "type/property designed to be serialized as JSON Array";
-        JavaType valueType = getValueType();
-        if (valueType != null) {
-            return ctxt.handleUnexpectedToken(valueType, p.getCurrentToken(), p, message, _beanType.getRawClass().getName(), p.getCurrentToken());
-        } else {
-            return ctxt.handleUnexpectedToken(handledType(), p.getCurrentToken(), p, message, _beanType.getRawClass().getName(), p.getCurrentToken());
-        }
+        return ctxt.handleUnexpectedToken(getValueType(ctxt), p.getCurrentToken(), p, message, _beanType.getRawClass().getName(), p.getCurrentToken());
         // in future, may allow use of "standard" POJO serialization as well; if so, do:
         //return _delegate.deserialize(p, ctxt);
     }
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/impl/BeanAsArrayDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/impl/BeanAsArrayDeserializer.java
index 8152ca8..832afd0 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/impl/BeanAsArrayDeserializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/impl/BeanAsArrayDeserializer.java
@@ -364,12 +364,7 @@
     {
         String message = "Cannot deserialize a POJO (of type %s) from non-Array representation (token: %s): "
                 +"type/property designed to be serialized as JSON Array";
-        JavaType valueType = getValueType();
-        if (valueType != null) {
-            return ctxt.handleUnexpectedToken(valueType, p.getCurrentToken(), p, message, _beanType.getRawClass().getName(), p.getCurrentToken());
-        } else {
-            return ctxt.handleUnexpectedToken(handledType(), p.getCurrentToken(), p, message, _beanType.getRawClass().getName(), p.getCurrentToken());
-        }
+        return ctxt.handleUnexpectedToken(getValueType(ctxt), p.getCurrentToken(), p, message, _beanType.getRawClass().getName(), p.getCurrentToken());
         // in future, may allow use of "standard" POJO serialization as well; if so, do:
         //return _delegate.deserialize(p, ctxt);
     }
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java
index 83e3692..dd2a549 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java
@@ -110,6 +110,26 @@
     public JavaType getValueType() { return _valueType; }
 
     /**
+     * Convenience method for getting handled type as {@link JavaType}, regardless
+     * of whether deserializer has one already resolved (and accessible via
+     * {@link #getValueType()}) or not: equivalent to:
+     *<pre>
+     *   if (getValueType() != null) {
+     *        return getValueType();
+     *   }
+     *   return ctxt.constructType(handledType());
+     *</pre>
+     * 
+     * @since 2.10
+     */
+    public JavaType getValueType(DeserializationContext ctxt) {
+        if (_valueType != null) {
+            return _valueType;
+        }
+        return ctxt.constructType(_valueClass);
+    }
+
+    /**
      * Method that can be called to determine if given deserializer is the default
      * deserializer Jackson uses; as opposed to a custom deserializer installed by
      * a module or calling application. Determination is done using
@@ -677,15 +697,9 @@
         } else {
             t = p.getCurrentToken();
         }
-        if (_valueType != null) {
-            @SuppressWarnings("unchecked")
-            T result = (T) ctxt.handleUnexpectedToken(_valueType, t, p, null);
-            return result;
-        } else {
-            @SuppressWarnings("unchecked")
-            T result = (T) ctxt.handleUnexpectedToken(_valueClass, t, p, null);
-            return result;
-        }
+        @SuppressWarnings("unchecked")
+        T result = (T) ctxt.handleUnexpectedToken(getValueType(ctxt), p.getCurrentToken(), p, null);
+        return result;
     }
 
     /**
@@ -705,15 +719,9 @@
 "Cannot deserialize instance of %s out of %s token: nested Arrays not allowed with %s",
                     ClassUtil.nameOf(_valueClass), JsonToken.START_ARRAY,
                     "DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS");
-            if (_valueType != null) {
-                @SuppressWarnings("unchecked")
-                T result = (T) ctxt.handleUnexpectedToken(_valueType, p.getCurrentToken(), p, msg);
-                return result;
-            } else {
-                @SuppressWarnings("unchecked")
-                T result = (T) ctxt.handleUnexpectedToken(_valueClass, p.getCurrentToken(), p, msg);
-                return result;
-            }
+            @SuppressWarnings("unchecked")
+            T result = (T) ctxt.handleUnexpectedToken(getValueType(ctxt), p.getCurrentToken(), p, msg);
+            return result;
         }
         return (T) deserialize(p, ctxt);
     }