/**
  * Contextualization is needed to see whether we can "inline" deserialization of String values, or
  * if we have to use separate value deserializer.
  */
 @Override
 public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)
     throws JsonMappingException {
   JsonDeserializer<?> deser = _elementDeserializer;
   // May have a content converter
   deser = findConvertingContentDeserializer(ctxt, property, deser);
   JavaType type = ctxt.constructType(String.class);
   if (deser == null) {
     deser = ctxt.findContextualValueDeserializer(type, property);
   } else { // if directly assigned, probably not yet contextual, so:
     deser = ctxt.handleSecondaryContextualization(deser, property, type);
   }
   // One more thing: allow unwrapping?
   Boolean unwrapSingle =
       findFormatFeature(
           ctxt, property, String[].class, JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
   // Ok ok: if all we got is the default String deserializer, can just forget about it
   if ((deser != null) && isDefaultDeserializer(deser)) {
     deser = null;
   }
   if ((_elementDeserializer == deser) && (_unwrapSingle == unwrapSingle)) {
     return this;
   }
   return new StringArrayDeserializer(deser, unwrapSingle);
 }
 @Override
 public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)
     throws JsonMappingException {
   // May need to resolve types for delegate-based creators:
   JsonDeserializer<Object> delegate = null;
   if (_valueInstantiator != null) {
     AnnotatedWithParams delegateCreator = _valueInstantiator.getDelegateCreator();
     if (delegateCreator != null) {
       JavaType delegateType = _valueInstantiator.getDelegateType(ctxt.getConfig());
       delegate = findDeserializer(ctxt, delegateType, property);
     }
   }
   JsonDeserializer<?> valueDeser = _valueDeserializer;
   if (valueDeser == null) {
     // #125: May have a content converter
     valueDeser = findConvertingContentDeserializer(ctxt, property, valueDeser);
     if (valueDeser == null) {
       // And we may also need to get deserializer for String
       valueDeser =
           ctxt.findContextualValueDeserializer(_collectionType.getContentType(), property);
     }
   } else { // if directly assigned, probably not yet contextual, so:
     valueDeser = ctxt.handleSecondaryContextualization(valueDeser, property);
   }
   if (isDefaultDeserializer(valueDeser)) {
     valueDeser = null;
   }
   return withResolved(delegate, valueDeser);
 }
 /**
  * Method called to finalize setup of this deserializer, when it is known for which property
  * deserializer is needed for.
  */
 @Override
 public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)
     throws JsonMappingException {
   // note: instead of finding key deserializer, with enums we actually
   // work with regular deserializers (less code duplication; but not
   // quite as clean as it ought to be)
   KeyDeserializer kd = _keyDeserializer;
   if (kd == null) {
     kd = ctxt.findKeyDeserializer(_mapType.getKeyType(), property);
   }
   JsonDeserializer<?> vd = _valueDeserializer;
   final JavaType vt = _mapType.getContentType();
   if (vd == null) {
     vd = ctxt.findContextualValueDeserializer(vt, property);
   } else { // if directly assigned, probably not yet contextual, so:
     vd = ctxt.handleSecondaryContextualization(vd, property, vt);
   }
   TypeDeserializer vtd = _valueTypeDeserializer;
   if (vtd != null) {
     vtd = vtd.forProperty(property);
   }
   return withResolved(kd, vd, vtd);
 }