// Path: src/main/java/org/springframework/data/cloudant/config/ICloudantConnector.java
// public interface ICloudantConnector {
//     CloudantClient getClient();
// 
//     String getDbName();
// }
// 
// Path: src/main/java/org/springframework/data/cloudant/core/mapping/event/AfterSaveEvent.java
// public class AfterSaveEvent<E extends BaseDocument> extends CloudantMappingEvent<E> {
// 
//     public AfterSaveEvent(E source) {
//         super(source, null);
//     }
// }
// 
// Path: src/main/java/org/springframework/data/cloudant/core/mapping/event/BeforeSaveEvent.java
// public class BeforeSaveEvent<E extends BaseDocument> extends CloudantMappingEvent<E> {
// 
//     public BeforeSaveEvent(E source) {
//         super(source, null);
//     }
// }
// 
// Path: src/main/java/org/springframework/data/cloudant/core/mapping/event/CloudantMappingEvent.java
// public class CloudantMappingEvent<T> extends ApplicationEvent {
// 
//     private final Document document;
// 
//     public CloudantMappingEvent(T source, Document document) {
//         super(source);
//         this.document = document;
//     }
// 
//     public Document getDocument() {
//         return document;
//     }
// 
//     @SuppressWarnings("unchecked")
//     @Override
//     public T getSource() {
//         return (T) super.getSource();
//     }
// }
// 
// Path: src/main/java/org/springframework/data/cloudant/core/model/BaseDocument.java
// @JsonInclude(JsonInclude.Include.ALWAYS)
// public class BaseDocument {
// 
//     @SerializedName("_id")
//     @Id
//     private String id;
// 
//     @SerializedName("_rev")
//     private String revision;
// 
//     //json ignore
//     @JsonIgnore
//     private Map<String, Object> unmappedFields;
// 
//     @JsonProperty("_id")
//     public String getId() {
//         return id;
//     }
// 
//     @JsonProperty("_id")
//     public void setId(String id) {
//         this.id = id;
//     }
// 
//     @JsonProperty("_rev")
//     public String getRevision() {
//         return revision;
//     }
// 
//     @JsonProperty("_rev")
//     public void setRevision(String revision) {
//         this.revision = revision;
//     }
// 
//     public void setUnmappedFields(Map<String, Object> unmappedFields) {
//         this.unmappedFields = unmappedFields;
//     }
// 
//     public Map<String, Object> getUnmappedFields() {
//         return unmappedFields;
//     }
// 
//     public void addUnmappedField(String key, Object value) {
//         if (unmappedFields == null) {
//             unmappedFields = new HashMap<String, Object>();
//         }
//         unmappedFields.put(key,value);
//     }
// }


import com.cloudant.client.api.CloudantClient;
import com.cloudant.client.api.Database;
import com.cloudant.client.api.model.*;
import com.google.gson.GsonBuilder;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.data.cloudant.config.ICloudantConnector;
import org.springframework.data.cloudant.core.mapping.event.AfterSaveEvent;
import org.springframework.data.cloudant.core.mapping.event.BeforeSaveEvent;
import org.springframework.data.cloudant.core.mapping.event.CloudantMappingEvent;
import org.springframework.data.cloudant.core.model.BaseDocument;
import org.springframework.data.domain.Pageable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
            bulkDeleteObjects.add(createDeleteDocument(entity.getId(),entity.getRevision()));
        }
        database.bulk(bulkDeleteObjects);
        for (T entity : batchOfObj) {
            maybeEmitEvent(new AfterSaveEvent<T>(entity));
        }
    }

    @Override
    public CloudantClient getCloudantClient() {
        return client;
    }

    public void setUnmappedDataAdapter() {
        setDataAdapter(null);
    }

    public void setDataAdapter(Map<Class<?>, Object> adapters) {
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.registerTypeAdapter(DateTime.class, new DateTimeDataAdapter());
        gsonBuilder.registerTypeHierarchyAdapter(BaseDocument.class, new UnmappedDataAdapter());
        if(adapters != null) {
            for (Class<?> type : adapters.keySet()) {
                gsonBuilder.registerTypeAdapter(type, adapters.get(type));
            }
        }
        gsonBuilder.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
        this.client.setGsonBuilder(gsonBuilder);
    }

// Path: src/main/java/org/springframework/data/cloudant/config/ICloudantConnector.java
// public interface ICloudantConnector {
//     CloudantClient getClient();
// 
//     String getDbName();
// }
// 
// Path: src/main/java/org/springframework/data/cloudant/core/mapping/event/AfterSaveEvent.java
// public class AfterSaveEvent<E extends BaseDocument> extends CloudantMappingEvent<E> {
// 
//     public AfterSaveEvent(E source) {
//         super(source, null);
//     }
// }
// 
// Path: src/main/java/org/springframework/data/cloudant/core/mapping/event/BeforeSaveEvent.java
// public class BeforeSaveEvent<E extends BaseDocument> extends CloudantMappingEvent<E> {
// 
//     public BeforeSaveEvent(E source) {
//         super(source, null);
//     }
// }
// 
// Path: src/main/java/org/springframework/data/cloudant/core/mapping/event/CloudantMappingEvent.java
// public class CloudantMappingEvent<T> extends ApplicationEvent {
// 
//     private final Document document;
// 
//     public CloudantMappingEvent(T source, Document document) {
//         super(source);
//         this.document = document;
//     }
// 
//     public Document getDocument() {
//         return document;
//     }
// 
//     @SuppressWarnings("unchecked")
//     @Override
//     public T getSource() {
//         return (T) super.getSource();
//     }
// }
// 
// Path: src/main/java/org/springframework/data/cloudant/core/model/BaseDocument.java
// @JsonInclude(JsonInclude.Include.ALWAYS)
// public class BaseDocument {
// 
//     @SerializedName("_id")
//     @Id
//     private String id;
// 
//     @SerializedName("_rev")
//     private String revision;
// 
//     //json ignore
//     @JsonIgnore
//     private Map<String, Object> unmappedFields;
// 
//     @JsonProperty("_id")
//     public String getId() {
//         return id;
//     }
// 
//     @JsonProperty("_id")
//     public void setId(String id) {
//         this.id = id;
//     }
// 
//     @JsonProperty("_rev")
//     public String getRevision() {
//         return revision;
//     }
// 
//     @JsonProperty("_rev")
//     public void setRevision(String revision) {
//         this.revision = revision;
//     }
// 
//     public void setUnmappedFields(Map<String, Object> unmappedFields) {
//         this.unmappedFields = unmappedFields;
//     }
// 
//     public Map<String, Object> getUnmappedFields() {
//         return unmappedFields;
//     }
// 
//     public void addUnmappedField(String key, Object value) {
//         if (unmappedFields == null) {
//             unmappedFields = new HashMap<String, Object>();
//         }
//         unmappedFields.put(key,value);
//     }
// }


// Path: src/main/java/org/springframework/data/cloudant/core/CloudantTemplate.java
import com.cloudant.client.api.CloudantClient;
import com.cloudant.client.api.Database;
import com.cloudant.client.api.model.*;
import com.google.gson.GsonBuilder;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.data.cloudant.config.ICloudantConnector;
import org.springframework.data.cloudant.core.mapping.event.AfterSaveEvent;
import org.springframework.data.cloudant.core.mapping.event.BeforeSaveEvent;
import org.springframework.data.cloudant.core.mapping.event.CloudantMappingEvent;
import org.springframework.data.cloudant.core.model.BaseDocument;
import org.springframework.data.domain.Pageable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

            bulkDeleteObjects.add(createDeleteDocument(entity.getId(),entity.getRevision()));
        }
        database.bulk(bulkDeleteObjects);
        for (T entity : batchOfObj) {
            maybeEmitEvent(new AfterSaveEvent<T>(entity));
        }
    }

    @Override
    public CloudantClient getCloudantClient() {
        return client;
    }

    public void setUnmappedDataAdapter() {
        setDataAdapter(null);
    }

    public void setDataAdapter(Map<Class<?>, Object> adapters) {
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.registerTypeAdapter(DateTime.class, new DateTimeDataAdapter());
        gsonBuilder.registerTypeHierarchyAdapter(BaseDocument.class, new UnmappedDataAdapter());
        if(adapters != null) {
            for (Class<?> type : adapters.keySet()) {
                gsonBuilder.registerTypeAdapter(type, adapters.get(type));
            }
        }
        gsonBuilder.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
        this.client.setGsonBuilder(gsonBuilder);
    }

    protected <T> void maybeEmitEvent(final CloudantMappingEvent<T> event) {