// Path: cqrs-lib/src/main/java/se/citerus/cqrs/bookstore/event/DomainEvent.java
// public abstract class DomainEvent<T extends GenericId> implements Serializable {
// 
//   public final T aggregateId;
//   public final int version;
//   public final long timestamp;
// 
//   protected DomainEvent(T aggregateId, int version, long timestamp) {
//     this.aggregateId = aggregateId;
//     this.version = version;
//     this.timestamp = timestamp;
//   }
// 
//   @Override
//   public boolean equals(Object o) {
//     return EqualsBuilder.reflectionEquals(this, o);
//   }
// 
//   @Override
//   public int hashCode() {
//     return HashCodeBuilder.reflectionHashCode(this);
//   }
// 
//   @Override
//   public String toString() {
//     return ToStringBuilder.reflectionToString(this, SHORT_PREFIX_STYLE);
//   }
// 
// }
// 
// Path: cqrs-lib/src/main/java/se/citerus/cqrs/bookstore/event/DomainEventBus.java
// public interface DomainEventBus {
// 
//   void publish(List<DomainEvent> events);
// 
//   void republish(List<DomainEvent> events);
// 
//   <T extends DomainEventListener> T register(T listener);
// 
// }
// 
// Path: cqrs-lib/src/main/java/se/citerus/cqrs/bookstore/event/DomainEventListener.java
// public interface DomainEventListener {
// 
//   boolean supportsReplay();
// 
// }


import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.EventBus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import se.citerus.cqrs.bookstore.event.DomainEvent;
import se.citerus.cqrs.bookstore.event.DomainEventBus;
import se.citerus.cqrs.bookstore.event.DomainEventListener;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
package se.citerus.cqrs.bookstore.ordercontext.application.infrastructure;



public class GuavaDomainEventBus implements DomainEventBus {

  private final Logger logger = LoggerFactory.getLogger(getClass());

  private final EventBus eventBus;
  private final EventBus replayBus;

  public GuavaDomainEventBus() {
    ExecutorService executorService = Executors.newFixedThreadPool(1);
    eventBus = new AsyncEventBus("eventbus", executorService);
    replayBus = new AsyncEventBus("replaybus", executorService);
  }

  @Override
  public <T extends DomainEventListener> T register(T listener) {
    if (listener.supportsReplay()) {
      replayBus.register(listener);
    }
    eventBus.register(listener);
    return listener;
  }

  @Override
// Path: cqrs-lib/src/main/java/se/citerus/cqrs/bookstore/event/DomainEvent.java
// public abstract class DomainEvent<T extends GenericId> implements Serializable {
// 
//   public final T aggregateId;
//   public final int version;
//   public final long timestamp;
// 
//   protected DomainEvent(T aggregateId, int version, long timestamp) {
//     this.aggregateId = aggregateId;
//     this.version = version;
//     this.timestamp = timestamp;
//   }
// 
//   @Override
//   public boolean equals(Object o) {
//     return EqualsBuilder.reflectionEquals(this, o);
//   }
// 
//   @Override
//   public int hashCode() {
//     return HashCodeBuilder.reflectionHashCode(this);
//   }
// 
//   @Override
//   public String toString() {
//     return ToStringBuilder.reflectionToString(this, SHORT_PREFIX_STYLE);
//   }
// 
// }
// 
// Path: cqrs-lib/src/main/java/se/citerus/cqrs/bookstore/event/DomainEventBus.java
// public interface DomainEventBus {
// 
//   void publish(List<DomainEvent> events);
// 
//   void republish(List<DomainEvent> events);
// 
//   <T extends DomainEventListener> T register(T listener);
// 
// }
// 
// Path: cqrs-lib/src/main/java/se/citerus/cqrs/bookstore/event/DomainEventListener.java
// public interface DomainEventListener {
// 
//   boolean supportsReplay();
// 
// }


// Path: order-context-parent/order-application/src/main/java/se/citerus/cqrs/bookstore/ordercontext/application/infrastructure/GuavaDomainEventBus.java
import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.EventBus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import se.citerus.cqrs.bookstore.event.DomainEvent;
import se.citerus.cqrs.bookstore.event.DomainEventBus;
import se.citerus.cqrs.bookstore.event.DomainEventListener;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

package se.citerus.cqrs.bookstore.ordercontext.application.infrastructure;



public class GuavaDomainEventBus implements DomainEventBus {

  private final Logger logger = LoggerFactory.getLogger(getClass());

  private final EventBus eventBus;
  private final EventBus replayBus;

  public GuavaDomainEventBus() {
    ExecutorService executorService = Executors.newFixedThreadPool(1);
    eventBus = new AsyncEventBus("eventbus", executorService);
    replayBus = new AsyncEventBus("replaybus", executorService);
  }

  @Override
  public <T extends DomainEventListener> T register(T listener) {
    if (listener.supportsReplay()) {
      replayBus.register(listener);
    }
    eventBus.register(listener);
    return listener;
  }

  @Override
  public void publish(List<DomainEvent> events) {