// Path: eventstore-client/src/main/java/de/qyotta/eventstore/model/Link.java
// public static final String EDIT = "edit";
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/model/Link.java
// public static final String NEXT = "next";
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/model/Link.java
// public static final String PREVIOUS = "previous";
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/model/Link.java
// public static final String SELF = "self";
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/communication/ESContext.java
// public interface ESContext {
// 
//    ESReader getReader();
// 
//    EventStoreSettings getSettings();
// 
//    ESWriter getWriter();
// 
// }
// 
// 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/EventDeletedException.java
// public class EventDeletedException extends RuntimeException {
//    private static final long serialVersionUID = 1L;
// }
// 
// 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/model/EventStreamFeed.java
// @Getter
// @Setter
// @Builder(toBuilder = true)
// @ToString
// @EqualsAndHashCode
// @NoArgsConstructor(access = AccessLevel.PUBLIC)
// @AllArgsConstructor(access = AccessLevel.PUBLIC)
// public class EventStreamFeed {
//    private String title;
//    private String id;
//    private String updated;
//    private Author author;
//    boolean headOfStream;
//    private List<Link> links;
//    private List<Entry> entries;
// 
// }
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/model/Link.java
// @Getter
// @Setter
// @Builder(toBuilder = true)
// @ToString
// @EqualsAndHashCode
// @NoArgsConstructor(access = AccessLevel.PUBLIC)
// @AllArgsConstructor(access = AccessLevel.PUBLIC)
// @SuppressWarnings("nls")
// public class Link {
//    public static final String SELF = "self";
//    public static final String LAST = "last";
//    public static final String PREVIOUS = "previous";
//    public static final String NEXT = "next";
//    public static final String EDIT = "edit";
//    private String uri;
//    private String relation;
// }
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/utils/EsUtils.java
// @UtilityClass
// @SuppressWarnings("nls")
// public class EsUtils {
//    private static final String SEQUENCE_NUMBER_TITLE_SEPERATOR = "@";
// 
//    public static long getEventNumber(final Entry entry) {
//       final String title = entry.getTitle();
//       final String subsequenceNumber = title.substring(0, title.indexOf(SEQUENCE_NUMBER_TITLE_SEPERATOR));
//       return Long.valueOf(subsequenceNumber);
//    }
// 
//    public static Date timestampOf(final Entry entry) {
//       return Date.from(Instant.parse(entry.getUpdated()));
//    }
// 
//    public static Date timestampOf(final EventResponse entry) {
//       return Date.from(Instant.parse(entry.getUpdated()));
//    }
// 
// }


import static de.qyotta.eventstore.model.Link.EDIT;
import static de.qyotta.eventstore.model.Link.NEXT;
import static de.qyotta.eventstore.model.Link.PREVIOUS;
import static de.qyotta.eventstore.model.Link.SELF;
import java.util.Date;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.qyotta.eventstore.communication.ESContext;
import de.qyotta.eventstore.model.Entry;
import de.qyotta.eventstore.model.EventDeletedException;
import de.qyotta.eventstore.model.EventResponse;
import de.qyotta.eventstore.model.EventStreamFeed;
import de.qyotta.eventstore.model.Link;
import de.qyotta.eventstore.utils.EsUtils;
         return;
      }
      // if the last event in the stream is the previous event there can be no new events
      if (previous.getTitle()
            .equals(currentEntries.peekFirst()
                  .getTitle())) {
         return;
      }

      if (previous == null) {
         // If previous is null this is the first event
         next = readEvent(currentEntries.pollLast());
         return;
      }
      findNext();

   }

   private void findNext() {
      while (!currentEntries.isEmpty()) {
         final Entry current = currentEntries.pollLast();
         final String currentTitle = current.getTitle();
         final String previousTitle = previous.getTitle();
         if (currentTitle.equals(previousTitle) && !currentEntries.isEmpty()) {
            // load the next one or not =)
            next = readEvent(currentEntries.pollLast());
            LOGGER.info("Found new event:" + next);
            return;
         }
      }
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/model/Link.java
// public static final String EDIT = "edit";
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/model/Link.java
// public static final String NEXT = "next";
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/model/Link.java
// public static final String PREVIOUS = "previous";
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/model/Link.java
// public static final String SELF = "self";
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/communication/ESContext.java
// public interface ESContext {
// 
//    ESReader getReader();
// 
//    EventStoreSettings getSettings();
// 
//    ESWriter getWriter();
// 
// }
// 
// 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/EventDeletedException.java
// public class EventDeletedException extends RuntimeException {
//    private static final long serialVersionUID = 1L;
// }
// 
// 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/model/EventStreamFeed.java
// @Getter
// @Setter
// @Builder(toBuilder = true)
// @ToString
// @EqualsAndHashCode
// @NoArgsConstructor(access = AccessLevel.PUBLIC)
// @AllArgsConstructor(access = AccessLevel.PUBLIC)
// public class EventStreamFeed {
//    private String title;
//    private String id;
//    private String updated;
//    private Author author;
//    boolean headOfStream;
//    private List<Link> links;
//    private List<Entry> entries;
// 
// }
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/model/Link.java
// @Getter
// @Setter
// @Builder(toBuilder = true)
// @ToString
// @EqualsAndHashCode
// @NoArgsConstructor(access = AccessLevel.PUBLIC)
// @AllArgsConstructor(access = AccessLevel.PUBLIC)
// @SuppressWarnings("nls")
// public class Link {
//    public static final String SELF = "self";
//    public static final String LAST = "last";
//    public static final String PREVIOUS = "previous";
//    public static final String NEXT = "next";
//    public static final String EDIT = "edit";
//    private String uri;
//    private String relation;
// }
// 
// Path: eventstore-client/src/main/java/de/qyotta/eventstore/utils/EsUtils.java
// @UtilityClass
// @SuppressWarnings("nls")
// public class EsUtils {
//    private static final String SEQUENCE_NUMBER_TITLE_SEPERATOR = "@";
// 
//    public static long getEventNumber(final Entry entry) {
//       final String title = entry.getTitle();
//       final String subsequenceNumber = title.substring(0, title.indexOf(SEQUENCE_NUMBER_TITLE_SEPERATOR));
//       return Long.valueOf(subsequenceNumber);
//    }
// 
//    public static Date timestampOf(final Entry entry) {
//       return Date.from(Instant.parse(entry.getUpdated()));
//    }
// 
//    public static Date timestampOf(final EventResponse entry) {
//       return Date.from(Instant.parse(entry.getUpdated()));
//    }
// 
// }


// Path: eventstore-client/src/main/java/de/qyotta/eventstore/EventStreamImpl.java
import static de.qyotta.eventstore.model.Link.EDIT;
import static de.qyotta.eventstore.model.Link.NEXT;
import static de.qyotta.eventstore.model.Link.PREVIOUS;
import static de.qyotta.eventstore.model.Link.SELF;
import java.util.Date;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.qyotta.eventstore.communication.ESContext;
import de.qyotta.eventstore.model.Entry;
import de.qyotta.eventstore.model.EventDeletedException;
import de.qyotta.eventstore.model.EventResponse;
import de.qyotta.eventstore.model.EventStreamFeed;
import de.qyotta.eventstore.model.Link;
import de.qyotta.eventstore.utils.EsUtils;

         return;
      }
      // if the last event in the stream is the previous event there can be no new events
      if (previous.getTitle()
            .equals(currentEntries.peekFirst()
                  .getTitle())) {
         return;
      }

      if (previous == null) {
         // If previous is null this is the first event
         next = readEvent(currentEntries.pollLast());
         return;
      }
      findNext();

   }

   private void findNext() {
      while (!currentEntries.isEmpty()) {
         final Entry current = currentEntries.pollLast();
         final String currentTitle = current.getTitle();
         final String previousTitle = previous.getTitle();
         if (currentTitle.equals(previousTitle) && !currentEntries.isEmpty()) {
            // load the next one or not =)
            next = readEvent(currentEntries.pollLast());
            LOGGER.info("Found new event:" + next);
            return;
         }
      }
      loadFeed(find(NEXT, currentLinks).getUri());