gt:             if (buffer.readIdProperty(propName)) {
context: package com.fasterxml.jackson.databind.deser;
  
  import java.io.IOException;
  import java.util.*;
  
  import com.fasterxml.jackson.core.*;
  import com.fasterxml.jackson.databind.*;
  import com.fasterxml.jackson.databind.deser.impl.*;
  import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
  import com.fasterxml.jackson.databind.util.NameTransformer;
  import com.fasterxml.jackson.databind.util.TokenBuffer;
  
  /**
   * Class that handles deserialization using a separate
   * Builder class, which is used for data binding and
   * produces actual deserialized value at the end
   * of data binding.
   *<p>
   * Note on implementation: much of code has been copied from
   * {@link BeanDeserializer}; there may be opportunities to
   * refactor this in future.
   */
  public class BuilderBasedDeserializer
      extends BeanDeserializerBase
  {
      private static final long serialVersionUID = 1L;
  
      protected final AnnotatedMethod _buildMethod;
  
      /**
       * Type that the builder will produce, target type; as opposed to
       * `handledType()` which refers to Builder class.
       *
       * @since 2.9
       */
      protected final JavaType _targetType;
  
      /*
      /**********************************************************
      /* Life-cycle, construction, initialization
      /**********************************************************
       */
  
      /**
       * Constructor used by {@link BeanDeserializerBuilder}.
       */
      public BuilderBasedDeserializer(BeanDeserializerBuilder builder,
              BeanDescription beanDesc, JavaType targetType,
              BeanPropertyMap properties, Map<String, SettableBeanProperty> backRefs,
              Set<String> ignorableProps, boolean ignoreAllUnknown,
              boolean hasViews)
      {
          super(builder, beanDesc, properties, backRefs,
                  ignorableProps, ignoreAllUnknown, hasViews);
          _targetType = targetType;
          _buildMethod = builder.getBuildMethod();
          // 05-Mar-2012, tatu: Cannot really make Object Ids work with builders, not yet anyway
          if (_objectIdReader != null) {
              throw new IllegalArgumentException("Cannot use Object Id with Builder-based deserialization (type "
                      +beanDesc.getType()+")");
          }
      }
  
      /**
       * @deprecated Since 2.9
       */
      @Deprecated
      public BuilderBasedDeserializer(BeanDeserializerBuilder builder,
              BeanDescription beanDesc,
              BeanPropertyMap properties, Map<String, SettableBeanProperty> backRefs,
              Set<String> ignorableProps, boolean ignoreAllUnknown,
              boolean hasViews)
      {
          this(builder, beanDesc,
                  beanDesc.getType(), // Wrong! But got no access via `BeanDeserializerBuilder`
                  properties, backRefs, ignorableProps, ignoreAllUnknown, hasViews);
      }
  
      /**
       * Copy-constructor that can be used by sub-classes to allow
       * copy-on-write styling copying of settings of an existing instance.
       */
      protected BuilderBasedDeserializer(BuilderBasedDeserializer src)
      {
          this(src, src._ignoreAllUnknown);
      }
  
      protected BuilderBasedDeserializer(BuilderBasedDeserializer src, boolean ignoreAllUnknown)
      {
          super(src, ignoreAllUnknown);
          _buildMethod = src._buildMethod;
          _targetType = src._targetType;
      }
  
      protected BuilderBasedDeserializer(BuilderBasedDeserializer src, NameTransformer unwrapper) {
          super(src, unwrapper);
          _buildMethod = src._buildMethod;
          _targetType = src._targetType;
      }
  
      public BuilderBasedDeserializer(BuilderBasedDeserializer src, ObjectIdReader oir) {
          super(src, oir);
          _buildMethod = src._buildMethod;
          _targetType = src._targetType;
      }
  
      public BuilderBasedDeserializer(BuilderBasedDeserializer src, Set<String> ignorableProps) {
          super(src, ignorableProps);
          _buildMethod = src._buildMethod;
          _targetType = src._targetType;
      }
  
      public BuilderBasedDeserializer(BuilderBasedDeserializer src, BeanPropertyMap props) {
          super(src, props);
          _buildMethod = src._buildMethod;
          _targetType = src._targetType;
      }
  
      @Override
      public JsonDeserializer<Object> unwrappingDeserializer(NameTransformer unwrapper)
      {
          /* main thing really is to just enforce ignoring of unknown
           * properties; since there may be multiple unwrapped values
           * and properties for all may be interleaved...
           */
          return new BuilderBasedDeserializer(this, unwrapper);
      }
  
      @Override
      public BeanDeserializerBase withObjectIdReader(ObjectIdReader oir) {
          return new BuilderBasedDeserializer(this, oir);
      }
  
      @Override
      public BeanDeserializerBase withIgnorableProperties(Set<String> ignorableProps) {
          return new BuilderBasedDeserializer(this, ignorableProps);
      }
  
      @Override
      public BeanDeserializerBase withBeanProperties(BeanPropertyMap props) {
          return new BuilderBasedDeserializer(this, props);
      }
  
      @Override
      protected BeanDeserializerBase asArrayDeserializer() {
          SettableBeanProperty[] props = _beanProperties.getPropertiesInInsertionOrder();
          return new BeanAsArrayBuilderDeserializer(this, _targetType, props, _buildMethod);
      }
  
      /*
      /**********************************************************
      /* JsonDeserializer implementation
      /**********************************************************
       */
  
      @Override // since 2.9
      public Boolean supportsUpdate(DeserializationConfig config) {
          // 26-Oct-2016, tatu: No, we can't merge Builder-based POJOs as of now
          return Boolean.FALSE;
      }
      
      /*
      /**********************************************************
      /* JsonDeserializer implementation
      /**********************************************************
       */
  
      protected Object finishBuild(DeserializationContext ctxt, Object builder)
              throws IOException
      {
          // As per [databind#777], allow returning builder itself
          if (null == _buildMethod) {
              return builder;
          }
          try {
              return _buildMethod.getMember().invoke(builder, (Object[]) null);
          } catch (Exception e) {
              return wrapInstantiationProblem(e, ctxt);
          }
      }
  
      /**
       * Main deserialization method for bean-based objects (POJOs).
       */
      @Override
      public Object deserialize(JsonParser p, DeserializationContext ctxt)
          throws IOException
      {
          // common case first:
          if (p.isExpectedStartObjectToken()) {
              JsonToken t = p.nextToken();
              if (_vanillaProcessing) {
                  return finishBuild(ctxt, vanillaDeserialize(p, ctxt, t));
              }
              Object builder = deserializeFromObject(p, ctxt);
              return finishBuild(ctxt, builder);
          }
          // and then others, generally requiring use of @JsonCreator
          switch (p.getCurrentTokenId()) {
          case JsonTokenId.ID_STRING:
              return finishBuild(ctxt, deserializeFromString(p, ctxt));
          case JsonTokenId.ID_NUMBER_INT:
              return finishBuild(ctxt, deserializeFromNumber(p, ctxt));
          case JsonTokenId.ID_NUMBER_FLOAT:
              return finishBuild(ctxt, deserializeFromDouble(p, ctxt));
          case JsonTokenId.ID_EMBEDDED_OBJECT:
              return p.getEmbeddedObject();
          case JsonTokenId.ID_TRUE:
          case JsonTokenId.ID_FALSE:
              return finishBuild(ctxt, deserializeFromBoolean(p, ctxt));
          case JsonTokenId.ID_START_ARRAY:
              // these only work if there's a (delegating) creator...
              return finishBuild(ctxt, deserializeFromArray(p, ctxt));
          case JsonTokenId.ID_FIELD_NAME:
          case JsonTokenId.ID_END_OBJECT:
              return finishBuild(ctxt, deserializeFromObject(p, ctxt));
          default:
          }
          return ctxt.handleUnexpectedToken(handledType(), p);
      }
  
      /**
       * Secondary deserialization method, called in cases where POJO
       * instance is created as part of deserialization, potentially
       * after collecting some or all of the properties to set.
       */
      @Override
      public Object deserialize(JsonParser p, DeserializationContext ctxt,
      		Object value) throws IOException
      {
          // 26-Oct-2016, tatu: I cannot see any of making this actually
          //    work correctly, so let's indicate problem right away
          JavaType valueType = _targetType;
          // Did they try to give us builder?
          Class<?> builderRawType = handledType();
          Class<?> instRawType = value.getClass();
          if (builderRawType.isAssignableFrom(instRawType)) {
              return ctxt.reportBadDefinition(valueType, String.format(
                      "Deserialization of %s by passing existing Builder (%s) instance not supported",
                      valueType, builderRawType.getName()));
          }
          return ctxt.reportBadDefinition(valueType, String.format(
                  "Deserialization of %s by passing existing instance (of %s) not supported",
                  valueType, instRawType.getName()));
      }
  
      /*
      /**********************************************************
      /* Concrete deserialization methods
      /**********************************************************
       */
  
      /**
       * Streamlined version that is only used when no "special"
       * features are enabled.
       */
      private final Object vanillaDeserialize(JsonParser p,
      		DeserializationContext ctxt, JsonToken t)
          throws IOException
      {
          Object bean = _valueInstantiator.createUsingDefault(ctxt);
          for (; p.getCurrentToken() == JsonToken.FIELD_NAME; p.nextToken()) {
              String propName = p.getCurrentName();
              // Skip field name:
              p.nextToken();
              SettableBeanProperty prop = _beanProperties.find(propName);
              if (prop != null) { // normal case
                  try {
                      bean = prop.deserializeSetAndReturn(p, ctxt, bean);
                  } catch (Exception e) {
                      wrapAndThrow(e, bean, propName, ctxt);
                  }
              } else {
                  handleUnknownVanilla(p, ctxt, bean, propName);
              }
          }
          return bean;
      }
  
      /**
       * General version used when handling needs more advanced
       * features.
       */
      @Override
      public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt)
          throws IOException
      {
          if (_nonStandardCreation) {
              if (_unwrappedPropertyHandler != null) {
                  return deserializeWithUnwrapped(p, ctxt);
              }
              if (_externalTypeIdHandler != null) {
                  return deserializeWithExternalTypeId(p, ctxt);
              }
              return deserializeFromObjectUsingNonDefault(p, ctxt);
          }
          Object bean = _valueInstantiator.createUsingDefault(ctxt);
          if (_injectables != null) {
              injectValues(ctxt, bean);
          }
          if (_needViewProcesing) {
              Class<?> view = ctxt.getActiveView();
              if (view != null) {
                  return deserializeWithView(p, ctxt, bean, view);
              }
          }
          for (; p.getCurrentToken() == JsonToken.FIELD_NAME; p.nextToken()) {
              String propName = p.getCurrentName();
              // Skip field name:
              p.nextToken();
              SettableBeanProperty prop = _beanProperties.find(propName);
              if (prop != null) { // normal case
                  try {
                      bean = prop.deserializeSetAndReturn(p, ctxt, bean);
                  } catch (Exception e) {
                      wrapAndThrow(e, bean, propName, ctxt);
                  }
                  continue;
              }
              handleUnknownVanilla(p, ctxt, bean, propName);
          }
          return bean;
      }
  
      /**
       * Method called to deserialize bean using "property-based creator":
       * this means that a non-default constructor or factory method is
       * called, and then possibly other setters. The trick is that
       * values for creator method need to be buffered, first; and
       * due to non-guaranteed ordering possibly some other properties
       * as well.
       *
       * @return Builder instance constructed
       */
      @Override
      @SuppressWarnings("resource")
      protected Object _deserializeUsingPropertyBased(final JsonParser p,
              final DeserializationContext ctxt)
          throws IOException
      { 
          final PropertyBasedCreator creator = _propertyBasedCreator;
          PropertyValueBuffer buffer = creator.startBuilding(p, ctxt, _objectIdReader);
          final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
  
          // 04-Jan-2010, tatu: May need to collect unknown properties for polymorphic cases
          TokenBuffer unknown = null;
  
          JsonToken t = p.getCurrentToken();
          for (; t == JsonToken.FIELD_NAME; t = p.nextToken()) {
              String propName = p.getCurrentName();
              p.nextToken(); // to point to value
              // creator property?
              SettableBeanProperty creatorProp = creator.findCreatorProperty(propName);
              if (creatorProp != null) {
                  if ((activeView != null) && !creatorProp.visibleInView(activeView)) {
                      p.skipChildren();
                      continue;
                  }
                  // Last creator property to set?
                  if (buffer.assignParameter(creatorProp, creatorProp.deserialize(p, ctxt))) {
                      p.nextToken(); // to move to following FIELD_NAME/END_OBJECT
                      Object builder;
                      try {
                          builder = creator.build(ctxt, buffer);
                      } catch (Exception e) {
                          wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt);
                          continue; // never gets here
                      }
                      //  polymorphic?
                      if (builder.getClass() != _beanType.getRawClass()) {
                          return handlePolymorphic(p, ctxt, builder, unknown);
                      }
                      if (unknown != null) { // nope, just extra unknown stuff...
                          builder = handleUnknownProperties(ctxt, builder, unknown);
                      }
                      // or just clean?
                      return _deserialize(p, ctxt, builder);
                  }
                  continue;
              }
              // Object Id property?
              if (buffer.readIdProperty(propName)) {
                  continue;
              }
              // regular property? needs buffering
              SettableBeanProperty prop = _beanProperties.find(propName);
              if (prop != null) {
                  buffer.bufferProperty(prop, prop.deserialize(p, ctxt));
                  continue;
              }
              // As per [JACKSON-313], things marked as ignorable should not be
              // passed to any setter
              if (_ignorableProps != null && _ignorableProps.contains(propName)) {
                  handleIgnoredProperty(p, ctxt, handledType(), propName);
                  continue;
              }
              // "any property"?
              if (_anySetter != null) {
                  buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(p, ctxt));
                  continue;
              }
              // Ok then, let's collect the whole field; name and value
              if (unknown == null) {
                  unknown = new TokenBuffer(p, ctxt);
              }
              unknown.writeFieldName(propName);
              unknown.copyCurrentStructure(p);
          }
  
          // We hit END_OBJECT, so:
          Object builder;
          try {
              builder = creator.build(ctxt, buffer);
          } catch (Exception e) {
              builder = wrapInstantiationProblem(e, ctxt);
          }
          if (unknown != null) {
              // polymorphic?
              if (builder.getClass() != _beanType.getRawClass()) {
                  return handlePolymorphic(null, ctxt, builder, unknown);
              }
              // no, just some extra unknown properties
              return handleUnknownProperties(ctxt, builder, unknown);
          }
          return builder;
      }
  
      @SuppressWarnings("resource")
      protected final Object _deserialize(JsonParser p,
              DeserializationContext ctxt, Object builder) throws IOException
      {        
          if (_injectables != null) {
              injectValues(ctxt, builder);
          }
          if (_unwrappedPropertyHandler != null) {
              if (p.hasToken(JsonToken.START_OBJECT)) {
                  p.nextToken();
              }
              TokenBuffer tokens = new TokenBuffer(p, ctxt);
              tokens.writeStartObject();
              return deserializeWithUnwrapped(p, ctxt, builder, tokens);
          }
          if (_externalTypeIdHandler != null) {
              return deserializeWithExternalTypeId(p, ctxt, builder);
          }
          if (_needViewProcesing) {
              Class<?> view = ctxt.getActiveView();
              if (view != null) {
                  return deserializeWithView(p, ctxt, builder, view);
              }
          }
          JsonToken t = p.getCurrentToken();
          // 23-Mar-2010, tatu: In some cases, we start with full JSON object too...
          if (t == JsonToken.START_OBJECT) {
              t = p.nextToken();
          }
          for (; t == JsonToken.FIELD_NAME; t = p.nextToken()) {
              String propName = p.getCurrentName();
              // Skip field name:
              p.nextToken();
              SettableBeanProperty prop = _beanProperties.find(propName);
              
              if (prop != null) { // normal case
                  try {
                      builder = prop.deserializeSetAndReturn(p, ctxt, builder);
                  } catch (Exception e) {
                      wrapAndThrow(e, builder, propName, ctxt);
                  }
                  continue;
              }
              handleUnknownVanilla(p, ctxt, handledType(), propName);
          }
          return builder;
      }
  
      /*
      /**********************************************************
      /* Deserializing when we have to consider an active View
      /**********************************************************
       */
  
      protected final Object deserializeWithView(JsonParser p, DeserializationContext ctxt,
              Object bean, Class<?> activeView)
          throws IOException
      {
          JsonToken t = p.getCurrentToken();
          for (; t == JsonToken.FIELD_NAME; t = p.nextToken()) {
              String propName = p.getCurrentName();
              // Skip field name:
              p.nextToken();
              SettableBeanProperty prop = _beanProperties.find(propName);
              if (prop != null) {
                  if (!prop.visibleInView(activeView)) {
                      p.skipChildren();
                      continue;
                  }
                  try {
                      bean = prop.deserializeSetAndReturn(p, ctxt, bean);
                  } catch (Exception e) {
                      wrapAndThrow(e, bean, propName, ctxt);
                  }
                  continue;
              }
              handleUnknownVanilla(p, ctxt, bean, propName);
          }
          return bean;
      }
  
      /*
      /**********************************************************
      /* Handling for cases where we have "unwrapped" values
      /**********************************************************
       */
  
      /**
       * Method called when there are declared "unwrapped" properties
       * which need special handling
       */
      @SuppressWarnings("resource")
      protected Object deserializeWithUnwrapped(JsonParser p, DeserializationContext ctxt)
          throws IOException
      {
          if (_delegateDeserializer != null) {
              return _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(p, ctxt));
          }
          if (_propertyBasedCreator != null) {
              return deserializeUsingPropertyBasedWithUnwrapped(p, ctxt);
          }
          TokenBuffer tokens = new TokenBuffer(p, ctxt);
          tokens.writeStartObject();
          Object bean = _valueInstantiator.createUsingDefault(ctxt);
  
          if (_injectables != null) {
              injectValues(ctxt, bean);
          }
  
          final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
          for (; p.getCurrentToken() == JsonToken.FIELD_NAME; p.nextToken()) {
              String propName = p.getCurrentName();
              p.nextToken();
              SettableBeanProperty prop = _beanProperties.find(propName);
              if (prop != null) { // normal case
                  if (activeView != null && !prop.visibleInView(activeView)) {
                      p.skipChildren();
                      continue;
                  }
                  try {
                      bean = prop.deserializeSetAndReturn(p, ctxt, bean);
                  } catch (Exception e) {
                      wrapAndThrow(e, bean, propName, ctxt);
                  }
                  continue;
              }
              // ignorable things should be ignored
              if (_ignorableProps != null && _ignorableProps.contains(propName)) {
                  handleIgnoredProperty(p, ctxt, bean, propName);
                  continue;
              }
              // but... others should be passed to unwrapped property deserializers
              tokens.writeFieldName(propName);
              tokens.copyCurrentStructure(p);
              // how about any setter? We'll get copies but...
              if (_anySetter != null) {
                  try {
                      _anySetter.deserializeAndSet(p, ctxt, bean, propName);
                  } catch (Exception e) {
                      wrapAndThrow(e, bean, propName, ctxt);
                  }
                  continue;
              }
          }
          tokens.writeEndObject();
          return _unwrappedPropertyHandler.processUnwrapped(p, ctxt, bean, tokens);
      }
  
      @SuppressWarnings("resource")
      protected Object deserializeUsingPropertyBasedWithUnwrapped(JsonParser p,
      		DeserializationContext ctxt)
          throws IOException
      {
          final PropertyBasedCreator creator = _propertyBasedCreator;
          PropertyValueBuffer buffer = creator.startBuilding(p, ctxt, _objectIdReader);
  
          TokenBuffer tokens = new TokenBuffer(p, ctxt);
          tokens.writeStartObject();
          Object builder = null;
  
          JsonToken t = p.getCurrentToken();
          for (; t == JsonToken.FIELD_NAME; t = p.nextToken()) {
              String propName = p.getCurrentName();
              p.nextToken(); // to point to value
              // creator property?
              SettableBeanProperty creatorProp = creator.findCreatorProperty(propName);
              if (creatorProp != null) {
                  // Last creator property to set?
                  if (buffer.assignParameter(creatorProp, creatorProp.deserialize(p, ctxt))) {
                      t = p.nextToken(); // to move to following FIELD_NAME/END_OBJECT
                      try {
                          builder = creator.build(ctxt, buffer);
                      } catch (Exception e) {
                          wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt);
                          continue; // never gets here
                      }
                      if (builder.getClass() != _beanType.getRawClass()) {
                          return handlePolymorphic(p, ctxt, builder, tokens);
                      }
                      return deserializeWithUnwrapped(p, ctxt, builder, tokens);
                  }
                  continue;
              }
              // Object Id property?
  