// Path: esjc-axon-eventstore/lib/src/main/java/de/qyotta/axonframework/eventstore/utils/EsjcEventstoreUtil.java
// public static final String getStreamName(final String type, final Object identifier, final String prefix) {
//    return prefix + "-" + type.toLowerCase() + "-" + identifier.toString();
// }
// 
// 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: esjc-axon-eventstore/lib/src/main/java/de/qyotta/axonframework/eventstore/utils/EsjcEventstoreUtil.java
// @UtilityClass
// @SuppressWarnings("nls")
// public final class EsjcEventstoreUtil {
//    private static final Type METADATA_TYPE = new TypeToken<Map<String, ?>>() {
//       //
//    }.getType();
// 
//    private static final Gson gson = new Gson();
//    private static final Charset UTF_8 = Charset.forName("UTF-8");
// 
//    public static final String getStreamName(final String type, final Object identifier, final String prefix) {
//       return prefix + "-" + type.toLowerCase() + "-" + identifier.toString();
//    }
// 
//    @SuppressWarnings({ "rawtypes", "unchecked" })
//    public static DomainEventMessage domainEventMessageOf(final ResolvedEvent event) {
//       try {
//          final RecordedEvent originalEvent = event.originalEvent();
//          final Class<?> payloadType = Class.forName(originalEvent.eventType);
//          final Object payload = gson.fromJson(new String(originalEvent.data, UTF_8), payloadType);
//          final Map<String, ?> metaData = gson.fromJson(new String(originalEvent.metadata, UTF_8), METADATA_TYPE);
// 
//          final Map<String, ?> eventMetadata = (Map<String, ?>) metaData.get(Constants.EVENT_METADATA_KEY);
//          final long sequenceNumber = originalEvent.eventNumber;
//          final DateTime dateTime = new DateTime(originalEvent.created.toEpochMilli(), DateTimeZone.UTC);
//          final String identifier = String.valueOf(originalEvent.eventId);
//          final Object aggregateIdentifier = metaData.get(Constants.AGGREGATE_ID_KEY);
//          return new GenericDomainEventMessage(identifier, dateTime, aggregateIdentifier, sequenceNumber, payload, new MetaData(eventMetadata));
//       } catch (final ClassNotFoundException e) {
//          throw new RuntimeException(e);
//       }
// 
//    }
// }


import static de.qyotta.axonframework.eventstore.utils.EsjcEventstoreUtil.getStreamName;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import org.axonframework.domain.DomainEventMessage;
import org.axonframework.domain.DomainEventStream;
import org.axonframework.eventstore.EventStore;
import org.axonframework.eventstore.EventStreamNotFoundException;
import org.axonframework.eventstore.PartialStreamSupport;
import org.axonframework.serializer.Revision;
import com.github.msemys.esjc.EventData;
import com.github.msemys.esjc.ExpectedVersion;
import com.google.gson.Gson;
import de.qyotta.axonframework.eventstore.utils.Constants;
import de.qyotta.axonframework.eventstore.utils.EsjcEventstoreUtil;
      try {
         final EsjcEventStreamBackedDomainEventStream eventStream = new EsjcEventStreamBackedDomainEventStream(EsjcEventstoreUtil.getStreamName(type, identifier, prefix), client, firstSequenceNumber);
         if (!eventStream.hasNext()) {
            throw new EventStreamNotFoundException(type, identifier);
         }
         return eventStream;
      } catch (final EventStreamNotFoundException e) {
         throw new EventStreamNotFoundException(String.format(AGGREGATE_OF_TYPE_S_WITH_IDENTIFIER_S_CANNOT_BE_FOUND, type, identifier), e);
      }
   }

   @Override
   public DomainEventStream readEvents(String type, Object identifier, long firstSequenceNumber, long lastSequenceNumber) {
      try {
         final EsjcEventStreamBackedDomainEventStream eventStream = new EsjcEventStreamBackedDomainEventStream(EsjcEventstoreUtil.getStreamName(type, identifier, prefix), client, firstSequenceNumber,
               lastSequenceNumber);
         if (!eventStream.hasNext()) {
            throw new EventStreamNotFoundException(type, identifier);
         }
         return eventStream;
      } catch (final EventStreamNotFoundException e) {
         throw new EventStreamNotFoundException(String.format(AGGREGATE_OF_TYPE_S_WITH_IDENTIFIER_S_CANNOT_BE_FOUND, type, identifier), e);
      }
   }

   private EventData toEvent(final DomainEventMessage message) {
      final HashMap<String, Object> metaData = new HashMap<>();
      final HashMap<String, Object> eventMetaData = new HashMap<>();
      for (final Entry<String, Object> entry : message.getMetaData()
            .entrySet()) {
// Path: esjc-axon-eventstore/lib/src/main/java/de/qyotta/axonframework/eventstore/utils/EsjcEventstoreUtil.java
// public static final String getStreamName(final String type, final Object identifier, final String prefix) {
//    return prefix + "-" + type.toLowerCase() + "-" + identifier.toString();
// }
// 
// 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: esjc-axon-eventstore/lib/src/main/java/de/qyotta/axonframework/eventstore/utils/EsjcEventstoreUtil.java
// @UtilityClass
// @SuppressWarnings("nls")
// public final class EsjcEventstoreUtil {
//    private static final Type METADATA_TYPE = new TypeToken<Map<String, ?>>() {
//       //
//    }.getType();
// 
//    private static final Gson gson = new Gson();
//    private static final Charset UTF_8 = Charset.forName("UTF-8");
// 
//    public static final String getStreamName(final String type, final Object identifier, final String prefix) {
//       return prefix + "-" + type.toLowerCase() + "-" + identifier.toString();
//    }
// 
//    @SuppressWarnings({ "rawtypes", "unchecked" })
//    public static DomainEventMessage domainEventMessageOf(final ResolvedEvent event) {
//       try {
//          final RecordedEvent originalEvent = event.originalEvent();
//          final Class<?> payloadType = Class.forName(originalEvent.eventType);
//          final Object payload = gson.fromJson(new String(originalEvent.data, UTF_8), payloadType);
//          final Map<String, ?> metaData = gson.fromJson(new String(originalEvent.metadata, UTF_8), METADATA_TYPE);
// 
//          final Map<String, ?> eventMetadata = (Map<String, ?>) metaData.get(Constants.EVENT_METADATA_KEY);
//          final long sequenceNumber = originalEvent.eventNumber;
//          final DateTime dateTime = new DateTime(originalEvent.created.toEpochMilli(), DateTimeZone.UTC);
//          final String identifier = String.valueOf(originalEvent.eventId);
//          final Object aggregateIdentifier = metaData.get(Constants.AGGREGATE_ID_KEY);
//          return new GenericDomainEventMessage(identifier, dateTime, aggregateIdentifier, sequenceNumber, payload, new MetaData(eventMetadata));
//       } catch (final ClassNotFoundException e) {
//          throw new RuntimeException(e);
//       }
// 
//    }
// }


// Path: esjc-axon-eventstore/lib/src/main/java/de/qyotta/axonframework/eventstore/EsjcEventStore.java
import static de.qyotta.axonframework.eventstore.utils.EsjcEventstoreUtil.getStreamName;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import org.axonframework.domain.DomainEventMessage;
import org.axonframework.domain.DomainEventStream;
import org.axonframework.eventstore.EventStore;
import org.axonframework.eventstore.EventStreamNotFoundException;
import org.axonframework.eventstore.PartialStreamSupport;
import org.axonframework.serializer.Revision;
import com.github.msemys.esjc.EventData;
import com.github.msemys.esjc.ExpectedVersion;
import com.google.gson.Gson;
import de.qyotta.axonframework.eventstore.utils.Constants;
import de.qyotta.axonframework.eventstore.utils.EsjcEventstoreUtil;

      try {
         final EsjcEventStreamBackedDomainEventStream eventStream = new EsjcEventStreamBackedDomainEventStream(EsjcEventstoreUtil.getStreamName(type, identifier, prefix), client, firstSequenceNumber);
         if (!eventStream.hasNext()) {
            throw new EventStreamNotFoundException(type, identifier);
         }
         return eventStream;
      } catch (final EventStreamNotFoundException e) {
         throw new EventStreamNotFoundException(String.format(AGGREGATE_OF_TYPE_S_WITH_IDENTIFIER_S_CANNOT_BE_FOUND, type, identifier), e);
      }
   }

   @Override
   public DomainEventStream readEvents(String type, Object identifier, long firstSequenceNumber, long lastSequenceNumber) {
      try {
         final EsjcEventStreamBackedDomainEventStream eventStream = new EsjcEventStreamBackedDomainEventStream(EsjcEventstoreUtil.getStreamName(type, identifier, prefix), client, firstSequenceNumber,
               lastSequenceNumber);
         if (!eventStream.hasNext()) {
            throw new EventStreamNotFoundException(type, identifier);
         }
         return eventStream;
      } catch (final EventStreamNotFoundException e) {
         throw new EventStreamNotFoundException(String.format(AGGREGATE_OF_TYPE_S_WITH_IDENTIFIER_S_CANNOT_BE_FOUND, type, identifier), e);
      }
   }

   private EventData toEvent(final DomainEventMessage message) {
      final HashMap<String, Object> metaData = new HashMap<>();
      final HashMap<String, Object> eventMetaData = new HashMap<>();
      for (final Entry<String, Object> entry : message.getMetaData()
            .entrySet()) {
         eventMetaData.put(entry.getKey(), entry.getValue());