// Path: eventstore-client/src/main/java/de/qyotta/eventstore/model/Entry.java
// @Getter
// @Setter
// @Builder(toBuilder = true)
// @ToString
// @EqualsAndHashCode
// @NoArgsConstructor(access = AccessLevel.PUBLIC)
// @AllArgsConstructor(access = AccessLevel.PUBLIC)
// public class Entry {
//    private String eventId;
//    private String eventType;
//    private Long eventNumber;
//    private String data;
//    private String metaData;
//    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 List<Link> links;
// 
//    private Event content;
// }
// 
// 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: eventstore-client/src/main/java/de/qyotta/eventstore/model/EventResponse.java
// @Getter
// @Setter
// @Builder(toBuilder = true)
// @ToString
// @EqualsAndHashCode
// @NoArgsConstructor(access = AccessLevel.PUBLIC)
// @AllArgsConstructor(access = AccessLevel.PUBLIC)
// public class EventResponse {
//    private String title;
//    private String id;
//    private String updated;
//    private Author author;
//    private String summary;
// 
//    private Event content;
// }
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/utils/DefaultConnectionKeepAliveStrategy.java
// @Immutable
// public class DefaultConnectionKeepAliveStrategy implements ConnectionKeepAliveStrategy {
//    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultConnectionKeepAliveStrategy.class.getName());
// 
//    public static final DefaultConnectionKeepAliveStrategy INSTANCE = new DefaultConnectionKeepAliveStrategy();
// 
//    private static final long DEFAULT_KEEP_ALIVE = 15 * 1000;
// 
//    @Override
//    public long getKeepAliveDuration(final HttpResponse response, final HttpContext context) {
//       Args.notNull(response, "HTTP response");
//       final HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
//       while (it.hasNext()) {
//          final HeaderElement he = it.nextElement();
//          final String param = he.getName();
//          final String value = he.getValue();
//          if (value != null && param.equalsIgnoreCase("timeout")) {
//             try {
//                return Long.parseLong(value) * 1000;
//             } catch (final NumberFormatException ignore) {
//                LOGGER.warn("keep alive timeout could not be parsed: param=" + param + " value:" + value, ignore);
//             }
//          }
//       }
//       return DEFAULT_KEEP_ALIVE;
//    }
// 
// }


import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.GzipDecompressingEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.qyotta.eventstore.model.Entry;
import de.qyotta.eventstore.model.Event;
import de.qyotta.eventstore.model.EventResponse;
import de.qyotta.eventstore.utils.DefaultConnectionKeepAliveStrategy;
import io.prometheus.client.Histogram;
import io.prometheus.client.Histogram.Timer;
      }
      this.open = false;
   }

   public EventResponse readEvent(final String streamName, final int eventNumber) throws ReadFailedException {
      ensureOpen();

      final String msg = "readEvent(" + streamName + ", " + eventNumber + ")";
      try {
         final URI uri = new URIBuilder(url.toURI()).setPath("/streams/" + streamName + "/" + eventNumber)
               .build();
         return readEvent(uri, "");
      } catch (final URISyntaxException ex) {
         throw new ReadFailedException(streamName, msg, ex);
      }
   }

   private void ensureOpen() {
      if (!open) {
         open();
      }
   }

   public EventResponse readLastEvent(final String streamName) throws ReadFailedException {
      ensureOpen();

      final String msg = "readLastEvent(" + streamName + ")";
      try {
         final URI uri = new URIBuilder(url.toURI()).setPath("/streams/" + streamName + "/head/backward/1")
               .build();
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/model/Entry.java
// @Getter
// @Setter
// @Builder(toBuilder = true)
// @ToString
// @EqualsAndHashCode
// @NoArgsConstructor(access = AccessLevel.PUBLIC)
// @AllArgsConstructor(access = AccessLevel.PUBLIC)
// public class Entry {
//    private String eventId;
//    private String eventType;
//    private Long eventNumber;
//    private String data;
//    private String metaData;
//    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 List<Link> links;
// 
//    private Event content;
// }
// 
// 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: eventstore-client/src/main/java/de/qyotta/eventstore/model/EventResponse.java
// @Getter
// @Setter
// @Builder(toBuilder = true)
// @ToString
// @EqualsAndHashCode
// @NoArgsConstructor(access = AccessLevel.PUBLIC)
// @AllArgsConstructor(access = AccessLevel.PUBLIC)
// public class EventResponse {
//    private String title;
//    private String id;
//    private String updated;
//    private Author author;
//    private String summary;
// 
//    private Event content;
// }
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/utils/DefaultConnectionKeepAliveStrategy.java
// @Immutable
// public class DefaultConnectionKeepAliveStrategy implements ConnectionKeepAliveStrategy {
//    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultConnectionKeepAliveStrategy.class.getName());
// 
//    public static final DefaultConnectionKeepAliveStrategy INSTANCE = new DefaultConnectionKeepAliveStrategy();
// 
//    private static final long DEFAULT_KEEP_ALIVE = 15 * 1000;
// 
//    @Override
//    public long getKeepAliveDuration(final HttpResponse response, final HttpContext context) {
//       Args.notNull(response, "HTTP response");
//       final HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
//       while (it.hasNext()) {
//          final HeaderElement he = it.nextElement();
//          final String param = he.getName();
//          final String value = he.getValue();
//          if (value != null && param.equalsIgnoreCase("timeout")) {
//             try {
//                return Long.parseLong(value) * 1000;
//             } catch (final NumberFormatException ignore) {
//                LOGGER.warn("keep alive timeout could not be parsed: param=" + param + " value:" + value, ignore);
//             }
//          }
//       }
//       return DEFAULT_KEEP_ALIVE;
//    }
// 
// }


// Path: eventstore-client/src/main/java/de/qyotta/neweventstore/ESHttpEventStore.java
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.GzipDecompressingEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.qyotta.eventstore.model.Entry;
import de.qyotta.eventstore.model.Event;
import de.qyotta.eventstore.model.EventResponse;
import de.qyotta.eventstore.utils.DefaultConnectionKeepAliveStrategy;
import io.prometheus.client.Histogram;
import io.prometheus.client.Histogram.Timer;

      }
      this.open = false;
   }

   public EventResponse readEvent(final String streamName, final int eventNumber) throws ReadFailedException {
      ensureOpen();

      final String msg = "readEvent(" + streamName + ", " + eventNumber + ")";
      try {
         final URI uri = new URIBuilder(url.toURI()).setPath("/streams/" + streamName + "/" + eventNumber)
               .build();
         return readEvent(uri, "");
      } catch (final URISyntaxException ex) {
         throw new ReadFailedException(streamName, msg, ex);
      }
   }

   private void ensureOpen() {
      if (!open) {
         open();
      }
   }

   public EventResponse readLastEvent(final String streamName) throws ReadFailedException {
      ensureOpen();

      final String msg = "readLastEvent(" + streamName + ")";
      try {
         final URI uri = new URIBuilder(url.toURI()).setPath("/streams/" + streamName + "/head/backward/1")
               .build();
         final List<Entry> entries = readFeed(streamName, uri, msg, "");