/**
   * Method that is to actually build a bean deserializer instance. All basic sanity checks have
   * been done to know that what we have may be a valid bean type, and that there are no default
   * simple deserializers.
   */
  @SuppressWarnings("unchecked")
  public JsonDeserializer<Object> buildBeanDeserializer(
      DeserializationContext ctxt, JavaType type, BeanDescription beanDesc)
      throws JsonMappingException {
    // First: check what creators we can use, if any
    ValueInstantiator valueInstantiator = findValueInstantiator(ctxt, beanDesc);
    BeanDeserializerBuilder builder = constructBeanDeserializerBuilder(ctxt, beanDesc);
    builder.setValueInstantiator(valueInstantiator);
    // And then setters for deserializing from JSON Object
    addBeanProps(ctxt, beanDesc, builder);
    addObjectIdReader(ctxt, beanDesc, builder);

    // managed/back reference fields/setters need special handling... first part
    addReferenceProperties(ctxt, beanDesc, builder);
    addInjectables(ctxt, beanDesc, builder);

    final DeserializationConfig config = ctxt.getConfig();
    // [JACKSON-440]: update builder now that all information is in?
    if (_factoryConfig.hasDeserializerModifiers()) {
      for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
        builder = mod.updateBuilder(config, beanDesc, builder);
      }
    }
    JsonDeserializer<?> deserializer;

    /* 19-Mar-2012, tatu: This check used to be done earlier; but we have to defer
     *   it a bit to collect information on ObjectIdReader, for example.
     */
    if (type.isAbstract() && !valueInstantiator.canInstantiate()) {
      deserializer = builder.buildAbstract();
    } else {
      deserializer = builder.build();
    }

    // [JACKSON-440]: may have modifier(s) that wants to modify or replace serializer we just built:
    if (_factoryConfig.hasDeserializerModifiers()) {
      for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
        deserializer = mod.modifyDeserializer(config, beanDesc, deserializer);
      }
    }
    return (JsonDeserializer<Object>) deserializer;
  }
  @SuppressWarnings("unchecked")
  public JsonDeserializer<Object> buildThrowableDeserializer(
      DeserializationContext ctxt, JavaType type, BeanDescription beanDesc)
      throws JsonMappingException {
    final DeserializationConfig config = ctxt.getConfig();
    // first: construct like a regular bean deserializer...
    BeanDeserializerBuilder builder = constructBeanDeserializerBuilder(ctxt, beanDesc);
    builder.setValueInstantiator(findValueInstantiator(ctxt, beanDesc));

    addBeanProps(ctxt, beanDesc, builder);
    // (and assume there won't be any back references)

    // But then let's decorate things a bit
    /* To resolve [JACKSON-95], need to add "initCause" as setter
     * for exceptions (sub-classes of Throwable).
     */
    AnnotatedMethod am = beanDesc.findMethod("initCause", INIT_CAUSE_PARAMS);
    if (am != null) { // should never be null
      SimpleBeanPropertyDefinition propDef = new SimpleBeanPropertyDefinition(am, "cause");
      SettableBeanProperty prop =
          constructSettableProperty(ctxt, beanDesc, propDef, am.getGenericParameterType(0));
      if (prop != null) {
        /* 21-Aug-2011, tatus: We may actually have found 'cause' property
         *   to set (with new 1.9 code)... but let's replace it just in case,
         *   otherwise can end up with odd errors.
         */
        builder.addOrReplaceProperty(prop, true);
      }
    }

    // And also need to ignore "localizedMessage"
    builder.addIgnorable("localizedMessage");
    // [JACKSON-794]: JDK 7 also added "getSuppressed", skip if we have such data:
    builder.addIgnorable("suppressed");
    /* As well as "message": it will be passed via constructor,
     * as there's no 'setMessage()' method
     */
    builder.addIgnorable("message");

    // [JACKSON-440]: update builder now that all information is in?
    if (_factoryConfig.hasDeserializerModifiers()) {
      for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
        builder = mod.updateBuilder(config, beanDesc, builder);
      }
    }
    JsonDeserializer<?> deserializer = builder.build();

    /* At this point it ought to be a BeanDeserializer; if not, must assume
     * it's some other thing that can handle deserialization ok...
     */
    if (deserializer instanceof BeanDeserializer) {
      deserializer = new ThrowableDeserializer((BeanDeserializer) deserializer);
    }

    // [JACKSON-440]: may have modifier(s) that wants to modify or replace serializer we just built:
    if (_factoryConfig.hasDeserializerModifiers()) {
      for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
        deserializer = mod.modifyDeserializer(config, beanDesc, deserializer);
      }
    }
    return (JsonDeserializer<Object>) deserializer;
  }