package com.fasterxml.jackson.databind.ser.impl;

import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.io.SerializedString;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.*;
import com.fasterxml.jackson.databind.util.NameTransformer;

/**
 * Variant of {@link BeanPropertyWriter} which will handle unwrapping
 * of JSON Object (including of properties of Object within surrounding
 * JSON object, and not as sub-object).
 */
public class UnwrappingBeanPropertyWriter
    extends BeanPropertyWriter
{
    protected final NameTransformer _unwrapper;
    
    public UnwrappingBeanPropertyWriter(BeanPropertyWriter base, NameTransformer unwrapper) {
        super(base);
        _unwrapper = unwrapper;
    }

    private UnwrappingBeanPropertyWriter(UnwrappingBeanPropertyWriter base, SerializedString name) {
        super(base, name);
        _unwrapper = base._unwrapper;
    }

    @Override
    public UnwrappingBeanPropertyWriter withName(String newName) {
        if (newName.equals(_name.toString())) {
            return this;
        }
        return new UnwrappingBeanPropertyWriter(this, new SerializedString(newName));
    }
    
    @Override
    public void serializeAsField(Object bean, JsonGenerator jgen, SerializerProvider prov)
        throws Exception
    {
        Object value = get(bean);
        if (value == null) {
            // Hmmh. I assume we MUST pretty much suppress nulls, since we
            // can't really unwrap them...
            return;
        }
        // For non-nulls, first: simple check for direct cycles
        if (value == bean) {
            _reportSelfReference(bean);
        }
        JsonSerializer<Object> ser = _serializer;
        if (ser == null) {
            Class<?> cls = value.getClass();
            PropertySerializerMap map = _dynamicSerializers;
            ser = map.serializerFor(cls);
            if (ser == null) {
                ser = _findAndAddDynamic(map, cls, prov);
            }
        }
        if (_suppressableValue != null) {
            if (MARKER_FOR_EMPTY == _suppressableValue) {
                if (ser.isEmpty(value)) {
                    return;
                }
            } else if (_suppressableValue.equals(value)) {
                return;
            }
        }

        // note: must verify we are using unwrapping serializer; if not, will write field name
        if (!ser.isUnwrappingSerializer()) {
            jgen.writeFieldName(_name);
        }

        if (_typeSerializer == null) {
            ser.serialize(value, jgen, prov);
        } else {
            ser.serializeWithType(value, jgen, prov, _typeSerializer);
        }
    }

    // need to override as we must get unwrapping instance...
    @Override
    protected JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map,
            Class<?> type, SerializerProvider provider) throws JsonMappingException
    {
        JsonSerializer<Object> serializer;
        if (_nonTrivialBaseType != null) {
            JavaType subtype = provider.constructSpecializedType(_nonTrivialBaseType, type);
            serializer = provider.findValueSerializer(subtype, this);
        } else {
            serializer = provider.findValueSerializer(type, this);
        }
        if (!serializer.isUnwrappingSerializer()) {
            serializer = serializer.unwrappingSerializer(_unwrapper);
        }
        _dynamicSerializers = _dynamicSerializers.newWith(type, serializer);
        return serializer;
    }
}

@@ -775,24 +775,190 @@
 apper;%0A    %0A
+    /*%0A    /**********************************************************%0A    /* Life-cycle%0A    /**********************************************************%0A     */%0A    %0A
     public U
@@ -1035,24 +1035,24 @@
 nwrapper) %7B%0A
-
         supe
@@ -1523,24 +1523,185 @@
 ame));%0A    %7D
+%0A%0A    /*%0A    /**********************************************************%0A    /* Overrides%0A    /**********************************************************%0A     */
 %0A    %0A    @O
@@ -3195,24 +3195,332 @@
    %7D%0A    %7D%0A%0A
+    // need to override as we must get unwrapping instance...%0A    @Override%0A    public void assignSerializer(JsonSerializer%3CObject%3E ser)%0A    %7B%0A        super.assignSerializer(ser);%0A        if (_serializer != null) %7B%0A            _serializer = _serializer.unwrappingSerializer(_unwrapper);%0A        %7D%0A    %7D%0A    %0A
     // need 
@@ -4103,64 +4103,8 @@
   %7D%0A
-        if (!serializer.isUnwrappingSerializer()) %7B%0A    
     
@@ -4161,34 +4161,24 @@
 unwrapper);%0A
-        %7D%0A
         _dyn

Fix a problem with unwrapping serialization; was not working for final classes