/**
  * 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<Object> createBuilderBasedDeserializer(
     DeserializationContext ctxt,
     JavaType valueType,
     BeanDescription beanDesc,
     Class<?> builderClass)
     throws JsonMappingException {
   // First: need a BeanDescription for builder class
   JavaType builderType = ctxt.constructType(builderClass);
   BeanDescription builderDesc = ctxt.getConfig().introspectForBuilder(builderType);
   return buildBuilderBasedDeserializer(ctxt, valueType, builderDesc);
 }
  protected void addObjectIdReader(
      DeserializationContext ctxt, BeanDescription beanDesc, BeanDeserializerBuilder builder)
      throws JsonMappingException {
    ObjectIdInfo objectIdInfo = beanDesc.getObjectIdInfo();
    if (objectIdInfo == null) {
      return;
    }
    Class<?> implClass = objectIdInfo.getGeneratorType();
    JavaType idType;
    SettableBeanProperty idProp;
    ObjectIdGenerator<?> gen;

    // Just one special case: Property-based generator is trickier
    if (implClass
        == ObjectIdGenerators.PropertyGenerator.class) { // most special one, needs extra work
      String propName = objectIdInfo.getPropertyName();
      idProp = builder.findProperty(propName);
      if (idProp == null) {
        throw new IllegalArgumentException(
            "Invalid Object Id definition for "
                + beanDesc.getBeanClass().getName()
                + ": can not find property with name '"
                + propName
                + "'");
      }
      idType = idProp.getType();
      gen = new PropertyBasedObjectIdGenerator(objectIdInfo.getScope());
    } else {
      JavaType type = ctxt.constructType(implClass);
      idType = ctxt.getTypeFactory().findTypeParameters(type, ObjectIdGenerator.class)[0];
      idProp = null;
      gen = ctxt.objectIdGeneratorInstance(beanDesc.getClassInfo(), objectIdInfo);
    }
    // also: unlike with value deserializers, let's just resolve one we need here
    JsonDeserializer<?> deser = ctxt.findRootValueDeserializer(idType);
    builder.setObjectIdReader(
        ObjectIdReader.construct(idType, objectIdInfo.getPropertyName(), gen, deser, idProp));
  }
 public void testDeserializationContext() throws Exception {
   DeserializationContext ctxt = MAPPER.getDeserializationContext();
   // should be ok to try to resolve `null`
   assertNull(ctxt.constructType((Class<?>) null));
   assertNull(ctxt.constructType((java.lang.reflect.Type) null));
 }