// Path: esjc-axon-eventstore/lib/src/main/java/de/qyotta/axonframework/eventstore/utils/Constants.java
// @SuppressWarnings("nls")
// public interface Constants {
//    public static final String ES_EVENT_TYPE_STREAM_PREFIX = "$et-";
//    public static final String DOMAIN_EVENT_TYPE = DomainEventMessage.class.getSimpleName();
//    public static final String AGGREGATE_ID_KEY = "AgregateIdentifier";
//    public static final String PAYLOAD_REVISION_KEY = "PayloadRevision";
//    public static final String EVENT_METADATA_KEY = "EventMetaData";
// }
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/EventStoreClient.java
// public class EventStoreClient {
//    private final ESContext context;
// 
//    public EventStoreClient(ESContext context) {
//       this.context = context;
//    }
// 
//    /**
//     * Creates a new {@link EventStreamReaderImpl}. Catch up is scheduled at the given interval. If the given interval is 0 or negative it will not be scheduled but can be invoked manually.
//     *
//     * @param streamName
//     * @param intervalMillis
//     * @param callback
//     * @return
//     */
//    public EventStreamReader newEventStreamReader(final String streamName, final int intervalMillis, final EventStreamReaderCallback callback) {
//       return new EventStreamReaderImpl(streamUrlForName(streamName), context, intervalMillis, callback);
//    }
// 
//    public EventStreamReader newEventStreamReader(final String streamName, final int intervalMillis, final EventStreamReaderCallback callback, final EventStreamReaderImpl.EventStreamReaderErrorCallback errorCallback) {
//       return new EventStreamReaderImpl(streamUrlForName(streamName), context, intervalMillis, callback, errorCallback);
//    }
// 
//    public EventStream readEvents(final String streamName) {
//       return new EventStreamImpl(streamUrlForName(streamName), context);
//    }
// 
//    public void createProjection(String name, final String... includedStreams) {
//       context.getWriter()
//             .createLinkedProjection(context.getSettings()
//                   .getHost(), name, includedStreams);
//    }
// 
//    public void appendEvent(final String streamName, final Event event) {
//       context.getWriter()
//             .appendEvent(streamUrlForName(streamName), event);
//    }
// 
//    public void appendEvents(final String streamName, final Collection<Event> collection) {
//       context.getWriter()
//             .appendEvents(streamUrlForName(streamName), collection);
//    }
// 
//    public void deleteStream(final String streamName, final boolean deletePermanently) {
//       context.getWriter()
//             .deleteStream(streamUrlForName(streamName), deletePermanently);
//    }
// 
//    private String streamUrlForName(final String streamName) {
//       return context.getSettings()
//             .getHost() + STREAMS_PATH + streamName;
//    }
// }
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/EventStream.java
// public interface EventStream {
// 
//    boolean hasNext();
// 
//    EventResponse next();
// 
//    EventResponse peek();
// 
//    void setAfterTimestamp(final Date timestamp);
// 
//    void setAfterTitle(final String eventId);
// 
//    /**
//     * Attempts to load the next event in the stream from the current point. If the next event was already loaded this method does nothing. This method is only useful after hasNext returned false.
//     * After this method has been called use hasNext to check whether a new event arrived.
//     */
//    void loadNext();
// 
// }
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/model/Event.java
// @Getter
// @Setter
// @Builder(toBuilder = true)
// @ToString
// @EqualsAndHashCode
// @NoArgsConstructor(access = AccessLevel.PUBLIC)
// @AllArgsConstructor(access = AccessLevel.PUBLIC)
// public class Event {
//    private String eventId;
//    private String eventType;
//    private Long eventNumber;
//    private String streamId;
//    private Boolean isLinkMetaData;
//    private Long positionEventNumber;
//    private String positionStreamId;
//    private String title;
//    private String id;
//    private String updated;
//    private Author author;
//    private String summary;
// 
//    private String eventStreamId;
//    private String data;
//    private String metadata;
// }
// 
// Path: axon-eventstore/lib/src/main/java/de/qyotta/axonframework/eventstore/utils/EsEventStoreUtils.java
// public static final String getStreamName(final String type, final Object identifier, final String prefix) {
//    return prefix + "-" + type.toLowerCase() + "-" + identifier.toString();
// }


import de.qyotta.axonframework.eventstore.utils.Constants;
import de.qyotta.eventstore.EventStoreClient;
import de.qyotta.eventstore.EventStream;
import de.qyotta.eventstore.model.Event;
import static de.qyotta.axonframework.eventstore.utils.EsEventStoreUtils.getStreamName;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.axonframework.domain.DomainEventMessage;
import org.axonframework.domain.DomainEventStream;
import org.axonframework.eventstore.EventStore;
import org.axonframework.eventstore.EventStreamNotFoundException;
import org.axonframework.serializer.Revision;
import com.google.gson.Gson;
package de.qyotta.axonframework.eventstore;






/**
 * @author satan
 *
 */
@SuppressWarnings({ "rawtypes" })
public class EsEventStore implements EventStore {
   private final EventStoreClient client;
   private final Gson gson = new Gson();
   @SuppressWarnings("nls")
   private String prefix = "domain";

   public EsEventStore(final EventStoreClient client) {
      this.client = client;
   }

   @Override
   public void appendEvents(final String type, final DomainEventStream events) {
// Path: esjc-axon-eventstore/lib/src/main/java/de/qyotta/axonframework/eventstore/utils/Constants.java
// @SuppressWarnings("nls")
// public interface Constants {
//    public static final String ES_EVENT_TYPE_STREAM_PREFIX = "$et-";
//    public static final String DOMAIN_EVENT_TYPE = DomainEventMessage.class.getSimpleName();
//    public static final String AGGREGATE_ID_KEY = "AgregateIdentifier";
//    public static final String PAYLOAD_REVISION_KEY = "PayloadRevision";
//    public static final String EVENT_METADATA_KEY = "EventMetaData";
// }
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/EventStoreClient.java
// public class EventStoreClient {
//    private final ESContext context;
// 
//    public EventStoreClient(ESContext context) {
//       this.context = context;
//    }
// 
//    /**
//     * Creates a new {@link EventStreamReaderImpl}. Catch up is scheduled at the given interval. If the given interval is 0 or negative it will not be scheduled but can be invoked manually.
//     *
//     * @param streamName
//     * @param intervalMillis
//     * @param callback
//     * @return
//     */
//    public EventStreamReader newEventStreamReader(final String streamName, final int intervalMillis, final EventStreamReaderCallback callback) {
//       return new EventStreamReaderImpl(streamUrlForName(streamName), context, intervalMillis, callback);
//    }
// 
//    public EventStreamReader newEventStreamReader(final String streamName, final int intervalMillis, final EventStreamReaderCallback callback, final EventStreamReaderImpl.EventStreamReaderErrorCallback errorCallback) {
//       return new EventStreamReaderImpl(streamUrlForName(streamName), context, intervalMillis, callback, errorCallback);
//    }
// 
//    public EventStream readEvents(final String streamName) {
//       return new EventStreamImpl(streamUrlForName(streamName), context);
//    }
// 
//    public void createProjection(String name, final String... includedStreams) {
//       context.getWriter()
//             .createLinkedProjection(context.getSettings()
//                   .getHost(), name, includedStreams);
//    }
// 
//    public void appendEvent(final String streamName, final Event event) {
//       context.getWriter()
//             .appendEvent(streamUrlForName(streamName), event);
//    }
// 
//    public void appendEvents(final String streamName, final Collection<Event> collection) {
//       context.getWriter()
//             .appendEvents(streamUrlForName(streamName), collection);
//    }
// 
//    public void deleteStream(final String streamName, final boolean deletePermanently) {
//       context.getWriter()
//             .deleteStream(streamUrlForName(streamName), deletePermanently);
//    }
// 
//    private String streamUrlForName(final String streamName) {
//       return context.getSettings()
//             .getHost() + STREAMS_PATH + streamName;
//    }
// }
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/EventStream.java
// public interface EventStream {
// 
//    boolean hasNext();
// 
//    EventResponse next();
// 
//    EventResponse peek();
// 
//    void setAfterTimestamp(final Date timestamp);
// 
//    void setAfterTitle(final String eventId);
// 
//    /**
//     * Attempts to load the next event in the stream from the current point. If the next event was already loaded this method does nothing. This method is only useful after hasNext returned false.
//     * After this method has been called use hasNext to check whether a new event arrived.
//     */
//    void loadNext();
// 
// }
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/model/Event.java
// @Getter
// @Setter
// @Builder(toBuilder = true)
// @ToString
// @EqualsAndHashCode
// @NoArgsConstructor(access = AccessLevel.PUBLIC)
// @AllArgsConstructor(access = AccessLevel.PUBLIC)
// public class Event {
//    private String eventId;
//    private String eventType;
//    private Long eventNumber;
//    private String streamId;
//    private Boolean isLinkMetaData;
//    private Long positionEventNumber;
//    private String positionStreamId;
//    private String title;
//    private String id;
//    private String updated;
//    private Author author;
//    private String summary;
// 
//    private String eventStreamId;
//    private String data;
//    private String metadata;
// }
// 
// Path: axon-eventstore/lib/src/main/java/de/qyotta/axonframework/eventstore/utils/EsEventStoreUtils.java
// public static final String getStreamName(final String type, final Object identifier, final String prefix) {
//    return prefix + "-" + type.toLowerCase() + "-" + identifier.toString();
// }


// Path: axon-eventstore/lib/src/main/java/de/qyotta/axonframework/eventstore/EsEventStore.java
import de.qyotta.axonframework.eventstore.utils.Constants;
import de.qyotta.eventstore.EventStoreClient;
import de.qyotta.eventstore.EventStream;
import de.qyotta.eventstore.model.Event;
import static de.qyotta.axonframework.eventstore.utils.EsEventStoreUtils.getStreamName;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.axonframework.domain.DomainEventMessage;
import org.axonframework.domain.DomainEventStream;
import org.axonframework.eventstore.EventStore;
import org.axonframework.eventstore.EventStreamNotFoundException;
import org.axonframework.serializer.Revision;
import com.google.gson.Gson;

package de.qyotta.axonframework.eventstore;






/**
 * @author satan
 *
 */
@SuppressWarnings({ "rawtypes" })
public class EsEventStore implements EventStore {
   private final EventStoreClient client;
   private final Gson gson = new Gson();
   @SuppressWarnings("nls")
   private String prefix = "domain";

   public EsEventStore(final EventStoreClient client) {
      this.client = client;
   }

   @Override
   public void appendEvents(final String type, final DomainEventStream events) {
      final Map<Object, List<Event>> identifierToEventStoreEvents = new HashMap<>();