// ============================================================
objectMapper.setSerializerFactory(new CompactBeanSerializerFactory(objectMapper));

// ============================================================
/** Parses an empty object using readValue("{}", type). */
private static Object defaultInstance(Class<?> type, ObjectMapper objectMapper) {
	try {
		return objectMapper.readValue(EMPTY_OBJECT_JSON, type);
		// EMPTY_OBJECT_JSON == "{}", set in a static initializer by getting
		// a JsonGenerator and calling writeStartObject and writeEndObject. 
	} catch (IOException e) {
		// hmm, shouldn't readValue(String,...) throw only JsonProcessingExceptions, not general IOE?
		throw new RuntimeException("cannot parse " + EMPTY_OBJECT_JSON + " as " + type, e);
	}
}

// ============================================================
class CompactBeanSerializerFactory extends CustomSerializerFactory {
	private final ObjectMapper mapper;
	CompactBeanSerializerFactory(ObjectMapper mapper) { this.mapper = mapper; }

	@Override public JsonSerializer<Object> findBeanSerializer(Class<?> type, SerializationConfig config) {
		// code for caching already created serializers omitted
    
		JsonSerializer<Object> serializer = super.findBeanSerializer(type, config);
		return serializer instanceof BeanSerializer
			? new CompactBeanSerializer(type, mapper, (BeanSerializer) serializer,
					findBeanProperties(config, (BasicBeanDescription) config.introspect(type)) )
			: serializer;
	}
}

// ============================================================
class CompactBeanSerializer extends JsonSerializer<Object> {
	private final Class<?> type;
	private final BeanSerializer beanSerializer;
	private final Collection<? extends BeanPropertyWriter> properties;
	private final ObjectMapper objectMapper;

	CompactBeanSerializer(Class<?> type, ObjectMapper objectMapper, BeanSerializer beanSerializer,
			Collection<? extends BeanPropertyWriter> properties) { /* set all fields */  }

	@Override public void serialize(Object bean, JsonGenerator jgen, SerializerProvider provider) {
		try {
			// -- build collection of initialized properties
			List<BeanPropertyWriter> setProperties = new ArrayList<BeanPropertyWriter>(properties.size());
			JsonGenerator nullGen = objectMapper.getJsonFactory().createJsonGenerator(NullWriter.INSTANCE);
			nullGen.writeStartObject();
			StoringSerializerProvider storingSP = new StoringSerializerProvider(provider);
			Object defaultValuesBean = defaultInstance(bean.getClass(), objectMapper);

			for (BeanPropertyWriter prop : properties) {
				prop.serializeAsField(defaultValuesBean, nullGen, storingSP);
				Object defaultValue = storingSP.getAndResetLastValue();
        
				prop.serializeAsField(bean, nullGen, storingSP);
				Object value = storingSP.getAndResetLastValue();
        
				boolean equals = defaultValue == value || (defaultValue != null && defaultValue.equals(value));
				if (!equals) { setProperties.add(prop); }
			}

			// -- serialize only changed properties
			if (setProperties.size() != properties.size()) {
				if (setProperties.isEmpty()) {
					jgen.writeStartObject();
					jgen.writeEndObject();
				} else {
					new BeanSerializer(bean.getClass(), setProperties).serialize(bean, jgen, provider);
				}
				return;
			}
		} catch (Exception e) { // OK, invoke default impl
			logger.warn("failed to determine which properties are set for " + bean, e);
		}
		beanSerializer.serialize(bean, jgen, provider);
	}
}

// ============================================================
/** A null device which does nothing. */
class NullWriter extends Writer { ... }

// ============================================================
/** Decorates a given SerializerProvider to store the most recently serialized value. */
class StoringSerializerProvider extends SerializerProvider {
	private final SerializerProvider decoratee;
	private Object lastValue;

	StoringSerializerProvider(SerializerProvider decoratee) {
		super(decoratee.getConfig());
		this.decoratee = decoratee;
	}

	Object getAndResetLastValue() { Object v = lastValue; lastValue = null; return v; }

	@Override public JsonSerializer<Object> findValueSerializer(Class<?> type) {
		final JsonSerializer<Object> defaultSerializer = decoratee.findValueSerializer(type);
    
		return new JsonSerializer<Object>() {
			@Override public void serialize(Object value, JsonGenerator g, SerializerProvider p) {
				lastValue = value;
				defaultSerializer.serialize(value, g, p);
			} };
	}

	@Override public void defaultSerializeDateValue(long timestamp, JsonGenerator g) {
		lastValue = timestamp;
		decoratee.defaultSerializeDateValue(timestamp, g);
	}

	// Also set lastValue in defaultSerializeDateValue(Date, JsonGenerator) and
	// serializeValue(SerializationConfig, JsonGenerator, Object, SerializerFactory)
  
	// Other methods just delegate to decoratee.
}

