From a9a4cc63e1b2f8340bcd5670e6b9d60eaae83246 Mon Sep 17 00:00:00 2001
From: Gregor Riegler <gregor.riegler@gmail.com>
Date: Thu, 6 Jun 2013 16:50:18 +0200
Subject: [PATCH] [XVSM] SpaceListener refactoring

---
 .../tuwien/sbc/valesriegler/common/Util.java  |  21 ++-
 .../xvsm/AbstractXVSMConnector.java           |  41 +++--
 .../sbc/valesriegler/xvsm/CookXVSM.java       | 105 ++++++-------
 .../sbc/valesriegler/xvsm/DriverXVSM.java     |  84 -----------
 .../sbc/valesriegler/xvsm/GroupAgentXVSM.java | 141 +++++++++---------
 .../sbc/valesriegler/xvsm/GroupXVSM.java      |   4 +-
 .../valesriegler/xvsm/PizzeriaAgentXVSM.java  |  72 ++++-----
 .../valesriegler/xvsm/SpaceListenerImpl.java  |  45 ------
 .../sbc/valesriegler/xvsm/WaiterXVSM.java     |  66 ++++----
 .../sbc/valesriegler/xvsm/driver/Driver.java  |   2 +-
 .../xvsm/spacehelpers/SpaceAction.java        |  12 ++
 .../{ => spacehelpers}/SpaceListener.java     |  19 +--
 .../xvsm/spacehelpers/SpaceListenerImpl.java  |  41 +++++
 .../SpaceListenerImplBuilder.java             |  57 +++++++
 14 files changed, 315 insertions(+), 395 deletions(-)
 delete mode 100644 src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/SpaceListenerImpl.java
 create mode 100644 src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/spacehelpers/SpaceAction.java
 rename src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/{ => spacehelpers}/SpaceListener.java (83%)
 create mode 100644 src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/spacehelpers/SpaceListenerImpl.java
 create mode 100644 src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/spacehelpers/SpaceListenerImplBuilder.java

diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/common/Util.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/common/Util.java
index 1cecd4d..2c04677 100644
--- a/src/main/java/at/ac/tuwien/sbc/valesriegler/common/Util.java
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/common/Util.java
@@ -1,23 +1,16 @@
 package at.ac.tuwien.sbc.valesriegler.common;
 
-import java.awt.*;
-import java.net.URI;
-import java.util.*;
-import java.util.List;
-
 import at.ac.tuwien.sbc.valesriegler.types.PizzaOrder;
 import at.ac.tuwien.sbc.valesriegler.types.PizzaType;
-import org.mozartspaces.capi3.Coordinator;
-import org.mozartspaces.core.Capi;
-import org.mozartspaces.core.ContainerReference;
-import org.mozartspaces.core.MzsConstants.Container;
-import org.mozartspaces.core.MzsConstants.RequestTimeout;
-import org.mozartspaces.core.MzsCoreException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.swing.*;
 import javax.swing.border.TitledBorder;
+import java.awt.*;
+import java.net.URI;
+import java.util.*;
+import java.util.List;
 
 public abstract class Util {
 	private static final Logger log = LoggerFactory.getLogger(Util.class);
@@ -147,4 +140,10 @@ public abstract class Util {
 
         return sb.toString();
     }
+
+    public static void handleSpaceErrorAndTerminate(Exception e) {
+        log.error(e.getMessage());
+        e.printStackTrace();
+        System.exit(1);
+    }
 }
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/AbstractXVSMConnector.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/AbstractXVSMConnector.java
index 2e3fc81..09cebbd 100644
--- a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/AbstractXVSMConnector.java
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/AbstractXVSMConnector.java
@@ -3,6 +3,7 @@ package at.ac.tuwien.sbc.valesriegler.xvsm;
 import at.ac.tuwien.sbc.valesriegler.common.HasId;
 import at.ac.tuwien.sbc.valesriegler.common.Util;
 import at.ac.tuwien.sbc.valesriegler.types.GroupData;
+import at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers.SpaceListenerImplBuilder;
 import org.mozartspaces.capi3.Coordinator;
 import org.mozartspaces.capi3.CountNotMetException;
 import org.mozartspaces.capi3.FifoCoordinator;
@@ -10,16 +11,12 @@ import org.mozartspaces.capi3.LindaCoordinator;
 import org.mozartspaces.capi3.LindaCoordinator.LindaSelector;
 import org.mozartspaces.core.*;
 import org.mozartspaces.notifications.NotificationManager;
-import org.mozartspaces.notifications.Operation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.Serializable;
 import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
 import java.util.concurrent.atomic.AtomicLong;
 
 public abstract class AbstractXVSMConnector {
@@ -51,6 +48,8 @@ public abstract class AbstractXVSMConnector {
     protected NotificationManager notificationMgr;
     protected int port;
 
+    private HashMap<String, ContainerReference> containers = new HashMap<String, ContainerReference>();
+
     public AbstractXVSMConnector(int port) {
         this.port = port;
         initSpaceCommunication(port);
@@ -65,7 +64,7 @@ public abstract class AbstractXVSMConnector {
             notificationMgr = new NotificationManager(core);
         } catch (Exception e) {
             log.error("Space connection could not be established! Have you started the Space Server?");
-            handleSpaceErrorAndTerminate(e);
+            Util.handleSpaceErrorAndTerminate(e);
         }
     }
 
@@ -74,11 +73,17 @@ public abstract class AbstractXVSMConnector {
     }
 
     protected ContainerReference useContainerOfSpaceWithPort(String containerName, int spacePort) {
+        String key = containerName + port;
+        ContainerReference container = containers.get(key);
+        if(container != null) return container;
+
         try {
             final String address = String.format(Util.SERVER_ADDR, spacePort);
-            return CapiUtil.lookupOrCreateContainer(containerName, URI.create(address), createCoordinators(new FifoCoordinator(), new LindaCoordinator(false)), null, capi);
+            container = CapiUtil.lookupOrCreateContainer(containerName, URI.create(address), createCoordinators(new FifoCoordinator(), new LindaCoordinator(false)), null, capi);
+            containers.put(key, container);
+            return container;
         } catch (MzsCoreException e) {
-            handleSpaceErrorAndTerminate(e);
+            Util.handleSpaceErrorAndTerminate(e);
         }
 
         throw new RuntimeException("Could not Create container " + containerName);
@@ -88,22 +93,6 @@ public abstract class AbstractXVSMConnector {
         return Arrays.asList(coordinator);
     }
 
-    protected void handleSpaceErrorAndTerminate(Exception e) {
-        log.error(e.getMessage());
-        e.printStackTrace();
-        System.exit(1);
-    }
-
-    protected void createNotification(SpaceListener listener,
-                                      ContainerReference cref) {
-        listener.startHandlingAbsenceOfNotifications();
-        try {
-            notificationMgr.createNotification(cref, listener, Operation.WRITE);
-        } catch (Exception e) {
-            handleSpaceErrorAndTerminate(e);
-        }
-    }
-
     protected <T extends Serializable> void sendItemsToContainer(
             List<T> items, ContainerReference cref, long timeout, TransactionReference tx) {
 
@@ -226,4 +215,8 @@ public abstract class AbstractXVSMConnector {
                 Util.SPACE_TRANSACTION_TIMEOUT,
                 URI.create(String.format(Util.SERVER_ADDR, port)));
     }
+
+    protected SpaceListenerImplBuilder getDefaultBuilder() {
+        return new SpaceListenerImplBuilder().setCapi(capi).setNotificationManager(notificationMgr);
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/CookXVSM.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/CookXVSM.java
index 149a14c..25cf111 100644
--- a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/CookXVSM.java
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/CookXVSM.java
@@ -1,51 +1,52 @@
 package at.ac.tuwien.sbc.valesriegler.xvsm;
 
-import java.io.Serializable;
-import java.net.URI;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import at.ac.tuwien.sbc.valesriegler.types.*;
-import org.mozartspaces.capi3.FifoCoordinator;
+import at.ac.tuwien.sbc.valesriegler.common.Util;
+import at.ac.tuwien.sbc.valesriegler.types.Pizza;
+import at.ac.tuwien.sbc.valesriegler.types.PizzaOrder;
+import at.ac.tuwien.sbc.valesriegler.types.PizzaOrderStatus;
+import at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers.SpaceAction;
+import at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers.SpaceListener;
 import org.mozartspaces.core.ContainerReference;
-import org.mozartspaces.core.MzsConstants;
 import org.mozartspaces.core.MzsConstants.RequestTimeout;
 import org.mozartspaces.core.MzsCoreException;
 import org.mozartspaces.core.TransactionReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import at.ac.tuwien.sbc.valesriegler.common.Util;
+import java.io.Serializable;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 
 public class CookXVSM extends AbstractXVSMConnector {
-	private static final Logger log = LoggerFactory.getLogger(CookXVSM.class);
-
-	private int cookId;
-
-	public CookXVSM(int id, int port) {
-		super(port);
-		
-		this.cookId = id;
-		orderTakenContainer = useContainer(Util.ORDER_TAKEN);
-		deliveryOrderTakenContainer = useContainer(Util.DELIVERY_ORDER_TAKEN);
-		preparedPizzasContainer = useContainer(Util.DELIVER_PIZZAS);
-		preparePizzasContainer = useContainer(Util.PREPARE_PIZZAS);
-		prepareDeliveryPizzasContainer = useContainer(Util.PREPARE_DELIVERY_PIZZAS);
-		pizzaInProgressContainer = useContainer(Util.PIZZAS_IN_PROGRESS) ;
+    private static final Logger log = LoggerFactory.getLogger(CookXVSM.class);
+
+    private int cookId;
+
+    public CookXVSM(int id, int port) {
+        super(port);
+
+        this.cookId = id;
+        orderTakenContainer = useContainer(Util.ORDER_TAKEN);
+        deliveryOrderTakenContainer = useContainer(Util.DELIVERY_ORDER_TAKEN);
+        preparedPizzasContainer = useContainer(Util.DELIVER_PIZZAS);
+        preparePizzasContainer = useContainer(Util.PREPARE_PIZZAS);
+        prepareDeliveryPizzasContainer = useContainer(Util.PREPARE_DELIVERY_PIZZAS);
+        pizzaInProgressContainer = useContainer(Util.PIZZAS_IN_PROGRESS);
         preparedDeliveryPizzasContainer = useContainer(Util.DELIVER_DELIVERY_PIZZAS);
-	}
+    }
 
     public void listenForPizzas() {
-        SpaceListener pizzasListener = new SpaceListenerImpl(capi, preparePizzasContainer, 15000) {
+        SpaceListener pizzasListener = getDefaultBuilder().setCref(preparePizzasContainer).setTimeout(15000).setSpaceAction(new SpaceAction() {
 
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries)
+            public void onEntriesWritten(List<? extends Serializable> entries)
                     throws Exception {
 
                 List<PizzaOrder> pizzas = castEntries(entries);
 
-                if(inNotification.get()) Collections.shuffle(pizzas);
+                if (inNotification.get()) Collections.shuffle(pizzas);
 
                 for (PizzaOrder pizzaOrder : pizzas) {
 
@@ -53,7 +54,7 @@ public class CookXVSM extends AbstractXVSMConnector {
                     String pizzaAlreadyCooked = String.format("Pizza with id %d has already been cooked by another cook", pizzaOrder.getId());
 
                     try {
-                        if (! mayPreparePizza(pizzaOrder, tx)) {
+                        if (!mayPreparePizza(pizzaOrder, tx)) {
                             capi.rollbackTransaction(tx);
                             continue;
                         }
@@ -85,15 +86,7 @@ public class CookXVSM extends AbstractXVSMConnector {
 
                 }
             }
-
-            @Override
-            List<? extends Serializable> getEntries() throws Exception {
-                return capi.read(preparePizzasContainer, FifoCoordinator
-                        .newSelector(MzsConstants.Selecting.COUNT_ALL),
-                        RequestTimeout.DEFAULT, null);
-            }
-        };
-        createNotification(pizzasListener, preparePizzasContainer);
+        }).createSpaceListenerImpl();
 
     }
 
@@ -103,26 +96,26 @@ public class CookXVSM extends AbstractXVSMConnector {
      */
     private boolean mayPreparePizza(PizzaOrder pizzaOrder, TransactionReference tx) throws MzsCoreException {
         List<PizzaOrder> deliveryPizzas = readMatchingEntities(new PizzaOrder(), prepareDeliveryPizzasContainer, tx, RequestTimeout.ZERO, "BBBBBB");
-        if (! deliveryPizzas.isEmpty()) {
+        if (!deliveryPizzas.isEmpty()) {
             final PizzaOrder template = new PizzaOrder();
             template.setOrderId(pizzaOrder.getOrderId());
             final List<PizzaOrder> pizzasOfOrderInProgress = readMatchingEntities(template, pizzaInProgressContainer, tx, RequestTimeout.ZERO, "ASDF");
-            if(pizzasOfOrderInProgress.isEmpty()) return false;
+            if (pizzasOfOrderInProgress.isEmpty()) return false;
         }
         return true;
     }
 
 
     public void listenForDeliveryPizzas() {
-        SpaceListener pizzasListener = new SpaceListenerImpl(capi, prepareDeliveryPizzasContainer, 15000) {
+        SpaceListener pizzasListener = getDefaultBuilder().setCref(prepareDeliveryPizzasContainer).setTimeout(15000).setSpaceAction(new SpaceAction() {
 
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries)
+            public void onEntriesWritten(List<? extends Serializable> entries)
                     throws Exception {
 
                 List<PizzaOrder> pizzas = castEntries(entries);
 
-                if(inNotification.get()) Collections.shuffle(pizzas);
+                if (inNotification.get()) Collections.shuffle(pizzas);
 
                 for (PizzaOrder pizzaOrder : pizzas) {
 
@@ -156,25 +149,17 @@ public class CookXVSM extends AbstractXVSMConnector {
 
                 }
             }
-
-            @Override
-            List<? extends Serializable> getEntries() throws Exception {
-                return capi.read(prepareDeliveryPizzasContainer, FifoCoordinator
-                        .newSelector(MzsConstants.Selecting.COUNT_ALL),
-                        RequestTimeout.DEFAULT, null);
-            }
-        };
-        createNotification(pizzasListener, prepareDeliveryPizzasContainer);
+        }).createSpaceListenerImpl();
 
     }
 
-	private PizzaOrder createPizza(PizzaOrder order) throws InterruptedException {
-		long duration = order.getPizzaType().duration;
-		Thread.sleep(duration * 1000);
-		
-		PizzaOrder pizza = Pizza.createPizzaFromPizzaOrder(order, cookId, false);
-		pizza.setStatus(PizzaOrderStatus.DONE);
-		return pizza;
-	}
+    private PizzaOrder createPizza(PizzaOrder order) throws InterruptedException {
+        long duration = order.getPizzaType().duration;
+        Thread.sleep(duration * 1000);
+
+        PizzaOrder pizza = Pizza.createPizzaFromPizzaOrder(order, cookId, false);
+        pizza.setStatus(PizzaOrderStatus.DONE);
+        return pizza;
+    }
 
 }
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/DriverXVSM.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/DriverXVSM.java
index 7289d62..89deb62 100644
--- a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/DriverXVSM.java
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/DriverXVSM.java
@@ -2,18 +2,9 @@ package at.ac.tuwien.sbc.valesriegler.xvsm;
 
 
 import at.ac.tuwien.sbc.valesriegler.common.Util;
-import at.ac.tuwien.sbc.valesriegler.types.DeliveryGroupData;
-import at.ac.tuwien.sbc.valesriegler.types.Order;
-import at.ac.tuwien.sbc.valesriegler.types.Pizza;
-import org.mozartspaces.core.MzsConstants;
-import org.mozartspaces.core.TransactionReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.List;
-
 public class DriverXVSM extends AbstractXVSMConnector {
     private static final Logger log = LoggerFactory.getLogger(DriverXVSM.class);
 
@@ -29,80 +20,5 @@ public class DriverXVSM extends AbstractXVSMConnector {
         this.deliverDeliveryOrder = useContainer(Util.DELIVER_DELIVERY_ORDER);
     }
 
-    public void listenForPreparedPizzas() {
-        /**
-         * A driver gets informed when a new pizza is complete. He takes the
-         * orderId of the pizza and looks up the corresponding order from which
-         * he gets the number of necessary pizzas of the order. He then tries to
-         * fetch all pizzas with the corresponding orderId and compares the
-         * number of those pizzas with the number of necessary pizzas. If all
-         * pizzas of an order are complete he then delivers them!
-         */
-        SpaceListener preparedPizzasListener = new SpaceListenerImpl(capi, preparedDeliveryPizzasContainer, true) {
-
-            @Override
-            void onEntriesWritten(List<? extends Serializable> entries)
-                    throws Exception {
-
-                log.info("HELLLOOOOO");
-
-                List<Pizza> pizzas = castEntries(entries);
-
-                for (Pizza pizza : pizzas) {
-                    int orderId = pizza.getOrderId();
-                    Order order = new Order();
-                    order.setId(orderId);
-
-                    TransactionReference tx = getDefaultTransaction();
-
-                    try {
-                        DeliveryGroupData entity = new DeliveryGroupData();
-                        entity.setDeliveryStatus(null);
-                        entity.setOrder(order);
 
-                        DeliveryGroupData groupData = takeMatchingEntity(entity,
-                                deliveryOrderTakenContainer, tx, MzsConstants.RequestTimeout.DEFAULT,
-                                "Another driver just checks if the delivery order is complete");
-                        int groupId = groupData.getId();
-                        int numberOfPizzas = groupData.getOrder().getNumberOfPizzas();
-
-                        Pizza pizzaTemplate = new Pizza();
-                        pizzaTemplate.setOrderId(orderId);
-
-                        List<Pizza> pizzasOfOrder = takeMatchingEntities(
-                                pizzaTemplate, preparedDeliveryPizzasContainer, tx,
-                                MzsConstants.RequestTimeout.DEFAULT,
-                                "Cannot take the pizzas from the preparedDeliveryPizzasContainer");
-
-                        if (pizzasOfOrder.size() == numberOfPizzas) {
-                            DeliveryGroupData group = new DeliveryGroupData();
-                            group.setDriverId(driverId);
-                            Order completeOrder = new Order();
-                            completeOrder.setId(orderId);
-                            completeOrder.setGroupId(groupId);
-                            group.setOrder(completeOrder);
-                            final List<DeliveryGroupData> groupsWithCompleteOrder = Arrays.asList(group);
-                            sendItemsToContainer(groupsWithCompleteOrder,
-                                    deliverDeliveryOrder, MzsConstants.RequestTimeout.DEFAULT,
-                                    tx);
-
-                            capi.commitTransaction(tx);
-                        } else {
-                            log.info("Not yet all pizzas prepared! Order with id "
-                                    + orderId + " has " + numberOfPizzas
-                                    + " pizzas, but only " + pizzasOfOrder.size()
-                                    + " pizzas are ready by now!");
-                            capi.rollbackTransaction(tx);
-                        }
-                    } catch (NullPointerException e) {
-
-                    } catch (Exception e) {
-                        capi.rollbackTransaction(tx);
-                    }
-                }
-            }
-        };
-
-        createNotification(preparedPizzasListener, preparedDeliveryPizzasContainer);
-    }
 }
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/GroupAgentXVSM.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/GroupAgentXVSM.java
index b19a6bb..cd8cb49 100644
--- a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/GroupAgentXVSM.java
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/GroupAgentXVSM.java
@@ -4,11 +4,10 @@ import at.ac.tuwien.sbc.valesriegler.common.Util;
 import at.ac.tuwien.sbc.valesriegler.group.GroupAgent;
 import at.ac.tuwien.sbc.valesriegler.types.DeliveryGroupData;
 import at.ac.tuwien.sbc.valesriegler.types.GroupData;
-import at.ac.tuwien.sbc.valesriegler.types.PizzaOrder;
 import at.ac.tuwien.sbc.valesriegler.types.Table;
+import at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers.SpaceAction;
+import at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers.SpaceListener;
 import org.mozartspaces.core.MzsConstants.RequestTimeout;
-import org.mozartspaces.core.MzsCoreException;
-import org.mozartspaces.core.TransactionReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -27,107 +26,102 @@ public class GroupAgentXVSM extends AbstractXVSMConnector {
 	}
 	
 	public void listenForDeliveredOrders(int port) {
-		SpaceListener deliveredOrders = new SpaceListenerImpl(capi, orderCompleteContainer, false) {
-			
-			@Override
-			void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
-				GroupData groupData =  getSingleGroup(entries);
-				final int groupId = groupData.getOrder().getId();
-                           
+		SpaceListener deliveredOrders = getDefaultBuilder().setCref(useContainerOfSpaceWithPort(Util.ORDER_COMPLETE, port)).setSpaceAction(new SpaceAction() {
+
+
+            @Override
+            public void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
+                GroupData groupData = getSingleGroup(entries);
+                final int groupId = groupData.getOrder().getId();
+
                 SwingUtilities.invokeLater(new Runnable() {
-					@Override
-					public void run() {
-						GroupAgent.getInstance().getGroupModel().setGroupEating(groupId);
-					}
-				});
+                    @Override
+                    public void run() {
+                        GroupAgent.getInstance().getGroupModel().setGroupEating(groupId);
+                    }
+                });
             }
-        };
-        createNotification(deliveredOrders, useContainerOfSpaceWithPort(Util.ORDER_COMPLETE, port));
+        }).createSpaceListenerImpl();
 
 	}
 
 	public void listenForPaymentRequest(int port) {
-		SpaceListener paymentRequest = new SpaceListenerImpl(capi, paymentRequestContainer, false) {
+		SpaceListener paymentRequest = getDefaultBuilder().setCref(useContainerOfSpaceWithPort(Util.PAYMENT_REQUEST, port)).setSpaceAction(new SpaceAction() {
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
+            public void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
                 final GroupData group = getSingleGroup(entries);
-                           
+
                 SwingUtilities.invokeLater(new Runnable() {
-					@Override
-					public void run() {
-						GroupAgent.getInstance().getGroupModel().setGroupWantsToPay(group.getId());
-					}
-				});
-                
+                    @Override
+                    public void run() {
+                        GroupAgent.getInstance().getGroupModel().setGroupWantsToPay(group.getId());
+                    }
+                });
+
             }
 
-	
-        };
-        createNotification(paymentRequest, useContainerOfSpaceWithPort(Util.PAYMENT_REQUEST, port));
+
+        }).createSpaceListenerImpl();
 	}
 
 	public void listenForPaymentDone(int port) {
-		SpaceListener payment = new SpaceListenerImpl(capi, paymentDoneContainer, false) {
+		SpaceListener payment = getDefaultBuilder().setCref(useContainerOfSpaceWithPort(Util.PAYMENT_DONE, port)).setSpaceAction(new SpaceAction() {
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
-            	
+            public void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
+
                 final GroupData group = getSingleGroup(entries);
-                           
+
                 SwingUtilities.invokeLater(new Runnable() {
-					@Override
-					public void run() {
-						GroupAgent.getInstance().getGroupModel().setGroupHasPaid(group.getId());
-					}
-				});
-                
+                    @Override
+                    public void run() {
+                        GroupAgent.getInstance().getGroupModel().setGroupHasPaid(group.getId());
+                    }
+                });
+
             }
-        };
-        createNotification(payment, useContainerOfSpaceWithPort(Util.PAYMENT_DONE, port));
+        }).createSpaceListenerImpl();
 	}
 
 	public void listenForTableAssigned(int port) {
-		SpaceListener tableAssignmentListener = new SpaceListenerImpl(capi, tableAssignedContainer, false) {
-			
+		SpaceListener tableAssignmentListener = getDefaultBuilder().setCref(useContainerOfSpaceWithPort(Util.TABLE_ASSIGNED, port)).setSpaceAction(new SpaceAction() {
+
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
-				
-				final List<Table> tables = castEntries(entries);
-				
-				SwingUtilities.invokeLater(new Runnable() {
-					@Override
-					public void run() {
-						GroupAgent.getInstance().getGroupModel().setGroupsSitting(tables);
-					}
-				});
+            public void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
+
+                final List<Table> tables = castEntries(entries);
+
+                SwingUtilities.invokeLater(new Runnable() {
+                    @Override
+                    public void run() {
+                        GroupAgent.getInstance().getGroupModel().setGroupsSitting(tables);
+                    }
+                });
             }
-        };
-        createNotification(tableAssignmentListener, useContainerOfSpaceWithPort(Util.TABLE_ASSIGNED, port));
-    
+        }).createSpaceListenerImpl();
 	}
 
 	public void listenForOrdersTaken(int port) {
-		SpaceListener tableAssignmentListener = new SpaceListenerImpl(capi, orderTakenContainer, false) {
+		SpaceListener tableAssignmentListener = getDefaultBuilder().setCref(useContainerOfSpaceWithPort(Util.ORDER_TAKEN, port)).setSpaceAction(new SpaceAction() {
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
-               final GroupData group = getSingleGroup(entries);
-				
-				SwingUtilities.invokeLater(new Runnable() {
-					
-					@Override
-					public void run() {
-						GroupAgent.getInstance().getGroupModel().setOrderTaken(group);
-					}
-				});
+            public void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
+                final GroupData group = getSingleGroup(entries);
+
+                SwingUtilities.invokeLater(new Runnable() {
+
+                    @Override
+                    public void run() {
+                        GroupAgent.getInstance().getGroupModel().setOrderTaken(group);
+                    }
+                });
             }
-        };
-        createNotification(tableAssignmentListener, useContainerOfSpaceWithPort(Util.ORDER_TAKEN, port));
+        }).createSpaceListenerImpl();
 	}
 
     public void listenForNewPizzerias() {
-        SpaceListener newPizzeriaListener = new SpaceListenerImpl(capi, groupAgentInfoContainer, true) {
+        SpaceListener newPizzeriaListener = getDefaultBuilder().setCref(groupAgentInfoContainer).setLookaround(true).setSpaceAction(new SpaceAction() {
 
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
+            public void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
                 final Set<String> pizzeriaIdentifiers = GroupAgent.getInstance().getPizzeriaIdentifiers();
 
                 synchronized (pizzeriaIdentifiers) {
@@ -135,7 +129,7 @@ public class GroupAgentXVSM extends AbstractXVSMConnector {
                     final List<String> pizzeriaIds = new ArrayList<>();
                     for (PizzeriaRegistration registration : pizzeriaRegistrations) {
                         final String pizzeriaId = String.valueOf(registration.pizzeriaSpacePort);
-                        if(! pizzeriaIdentifiers.contains(pizzeriaId)) {
+                        if (!pizzeriaIdentifiers.contains(pizzeriaId)) {
                             pizzeriaIds.add(pizzeriaId);
                             listenToPizzeria(pizzeriaId);
                         }
@@ -149,8 +143,7 @@ public class GroupAgentXVSM extends AbstractXVSMConnector {
                     });
                 }
             }
-        };
-        createNotification(newPizzeriaListener, groupAgentInfoContainer);
+        }).createSpaceListenerImpl();
 
     }
 
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/GroupXVSM.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/GroupXVSM.java
index e1f6001..f8c9842 100644
--- a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/GroupXVSM.java
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/GroupXVSM.java
@@ -29,8 +29,6 @@ public class GroupXVSM extends AbstractXVSMConnector {
 		
 		paymentRequestContainer = useContainerOfSpaceWithPort(Util.PAYMENT_REQUEST, port) ;
 		orderCompleteContainer = useContainerOfSpaceWithPort(Util.ORDER_COMPLETE, port) ;
-//		isEatingContainer = useContainer(Util.IS_EATING) ;
-//		freeTablesContainer = useContainer(Util.FREE_TABLES) ;
 	}
 
 	public void waitForMyOrder() {
@@ -50,7 +48,7 @@ public class GroupXVSM extends AbstractXVSMConnector {
 	  try {
         	notificationMgr.createNotification(orderCompleteContainer, deliveredOrders, Operation.WRITE);
         } catch (Exception e) {
-           handleSpaceErrorAndTerminate(e);
+           Util.handleSpaceErrorAndTerminate(e);
         }
 	}
 	
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/PizzeriaAgentXVSM.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/PizzeriaAgentXVSM.java
index 200ee46..93ded78 100644
--- a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/PizzeriaAgentXVSM.java
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/PizzeriaAgentXVSM.java
@@ -8,11 +8,9 @@ import javax.swing.SwingUtilities;
 
 import at.ac.tuwien.sbc.valesriegler.common.OrderId;
 import at.ac.tuwien.sbc.valesriegler.types.*;
+import at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers.SpaceAction;
+import at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers.SpaceListener;
 import org.mozartspaces.core.MzsConstants.RequestTimeout;
-import org.mozartspaces.core.TransactionReference;
-import org.mozartspaces.notifications.Notification;
-import org.mozartspaces.notifications.NotificationListener;
-import org.mozartspaces.notifications.Operation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -37,9 +35,9 @@ public class PizzeriaAgentXVSM extends AbstractXVSMConnector {
     }
 
 	public void listenForOccupiedTables() {
-		SpaceListener tablesListener = new SpaceListenerImpl(capi, tableAssignedContainer, false) {
+		SpaceListener tablesListener = getDefaultBuilder().setCref(tableAssignedContainer).setSpaceAction(new SpaceAction() {
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
+            public void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
                 log.info("A new group was assigned to a table!");
 
                 final List<Table> tables = castEntries(entries);
@@ -53,15 +51,14 @@ public class PizzeriaAgentXVSM extends AbstractXVSMConnector {
                     }
                 });
             }
-        };
-        createNotification(tablesListener, tableAssignedContainer);
+        }).createSpaceListenerImpl();
 	}
 	
 	public void listenForFreeTables() {
-		SpaceListener tablesListener = new SpaceListenerImpl(capi, freeTablesContainer, false) {
+		SpaceListener tablesListener = getDefaultBuilder().setCref(freeTablesContainer).setSpaceAction(new SpaceAction() {
 
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
+            public void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
                 log.info("A table has become free");
 
                 final List<Table> tables = castEntries(entries);
@@ -81,15 +78,14 @@ public class PizzeriaAgentXVSM extends AbstractXVSMConnector {
                     }
                 });
             }
-        };
-        createNotification(tablesListener, freeTablesContainer);
+        }).createSpaceListenerImpl();
 	}
 
 	public void listenForWaitingGroups() {
 		
-        SpaceListener groupsListener = new SpaceListenerImpl(capi, assignTableContainer, false) {
+        SpaceListener groupsListener = getDefaultBuilder().setCref(assignTableContainer).setSpaceAction(new SpaceAction() {
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
+            public void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
                 final List<GroupData> groups = castEntries(entries);
 
                 SwingUtilities.invokeLater(new Runnable() {
@@ -100,14 +96,13 @@ public class PizzeriaAgentXVSM extends AbstractXVSMConnector {
                 });
 
             }
-        };
-        createNotification(groupsListener, assignTableContainer);
+        }).createSpaceListenerImpl();
 	}
 
     public void listenForTakenDeliveryOrders() {
-        SpaceListener orderTakenListener = new SpaceListenerImpl(capi, deliveryOrderTakenContainer, false) {
+        SpaceListener orderTakenListener = getDefaultBuilder().setCref(deliveryOrderTakenContainer).setSpaceAction(new SpaceAction() {
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
+            public void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
                 final List<DeliveryGroupData> groups = castEntries(entries);
 
                 SwingUtilities.invokeLater(new Runnable() {
@@ -118,15 +113,14 @@ public class PizzeriaAgentXVSM extends AbstractXVSMConnector {
                 });
 
             }
-        };
-        createNotification(orderTakenListener, deliveryOrderTakenContainer);
+        }).createSpaceListenerImpl();
     }
 
 public void listenForTakenOrders() {
 
-        SpaceListener orderTakenListener = new SpaceListenerImpl(capi, orderTakenContainer, false) {
+        SpaceListener orderTakenListener = getDefaultBuilder().setCref(orderTakenContainer).setSpaceAction(new SpaceAction() {
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
+            public void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
                 final List<GroupData> groups = castEntries(entries);
 
                 SwingUtilities.invokeLater(new Runnable() {
@@ -137,15 +131,14 @@ public void listenForTakenOrders() {
                 });
 
             }
-        };
-        createNotification(orderTakenListener, orderTakenContainer);
+        }).createSpaceListenerImpl();
 	}
 
 	public void listenForPizzasInPreparation() {
-		SpaceListener pizzasInProgress = new SpaceListenerImpl(capi, pizzaInProgressContainer, false) {
+		SpaceListener pizzasInProgress = getDefaultBuilder().setCref(pizzaInProgressContainer).setSpaceAction(new SpaceAction() {
 
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
+            public void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
                 final List<Pizza> pizzas = castEntries(entries);
 
                 log.info("{} pizzas in progress changes!", pizzas.size());
@@ -162,14 +155,13 @@ public void listenForTakenOrders() {
                 });
 
             }
-        };
-        createNotification(pizzasInProgress, pizzaInProgressContainer);
+        }).createSpaceListenerImpl();
 	}
 
 	public void listenForDeliveredOrders() {
-		SpaceListener deliveredOrders = new SpaceListenerImpl(capi, orderCompleteContainer, false) {
+		SpaceListener deliveredOrders = getDefaultBuilder().setCref(orderCompleteContainer).setSpaceAction(new SpaceAction() {
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
+            public void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
                 final List<GroupData> groups = castEntries(entries);
 
                 log.info("{} order was delivered!", groups.size());
@@ -181,14 +173,13 @@ public void listenForTakenOrders() {
                     }
                 });
             }
-        };
-        createNotification(deliveredOrders, orderCompleteContainer);
+        }).createSpaceListenerImpl();
 	}
 
 	public void listenForPreparedPizzas() {
-		SpaceListener preparedPizzasListener = new SpaceListenerImpl(capi, preparedPizzasContainer, false) {
+		SpaceListener preparedPizzasListener = getDefaultBuilder().setCref(preparedPizzasContainer).setSpaceAction(new SpaceAction() {
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
+            public void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
                 final List<Pizza> pizzas = castEntries(entries);
 
                 SwingUtilities.invokeLater(new Runnable() {
@@ -200,15 +191,13 @@ public void listenForTakenOrders() {
                 });
 
             }
-        };
-        createNotification(preparedPizzasListener, preparedPizzasContainer);
-
+        }).createSpaceListenerImpl();
 	}
 
 	public void listenForPayment() {
-		SpaceListener isGoneListener = new SpaceListenerImpl(capi, paymentDoneContainer, false) {
+		SpaceListener isGoneListener = getDefaultBuilder().setCref(paymentDoneContainer).setSpaceAction(new SpaceAction() {
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
+            public void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
                 final List<GroupData> groups = castEntries(entries);
 
                 final GroupData group = groups.get(0);
@@ -228,12 +217,11 @@ public void listenForTakenOrders() {
 
                 sendItemsToContainer(Arrays.asList(table), freeTablesContainer, RequestTimeout.DEFAULT, null);
             }
-        };
-        createNotification(isGoneListener, paymentDoneContainer);
+        }).createSpaceListenerImpl();
 	}
 
 
-	public void sendFreeTablesToContainer(List<Table> tables) {
+    public void sendFreeTablesToContainer(List<Table> tables) {
 		sendItemsToContainer(tables, freeTablesContainer, RequestTimeout.DEFAULT, null);
 	}
 
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/SpaceListenerImpl.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/SpaceListenerImpl.java
deleted file mode 100644
index b612fb9..0000000
--- a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/SpaceListenerImpl.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package at.ac.tuwien.sbc.valesriegler.xvsm;
-
-import java.io.Serializable;
-import java.util.List;
-
-import org.mozartspaces.capi3.AnyCoordinator;
-import org.mozartspaces.capi3.FifoCoordinator;
-import org.mozartspaces.core.Capi;
-import org.mozartspaces.core.ContainerReference;
-import org.mozartspaces.core.MzsConstants;
-import org.mozartspaces.core.MzsConstants.RequestTimeout;
-
-/**
- * 
- * @author Gregor Riegler <gregor DOT riegler AT gmail DOT com>
- *
- * @see SpaceListener
- */
-public abstract class SpaceListenerImpl extends SpaceListener {
-
-	private final Capi capi;
-	private final ContainerReference cref;
-
-	public SpaceListenerImpl(Capi core, ContainerReference cref) {
-		this.capi = core;
-		this.cref= cref;
-	}
-	
-	public SpaceListenerImpl(Capi core, ContainerReference cref, boolean lookAround) {
-		this(core, cref);
-		this.lookAround  = lookAround;
-	}
-	
-	public SpaceListenerImpl(Capi core, ContainerReference cref, long milliseconds) {
-		this(core, cref);
-		this.timeout = milliseconds;
-	}
-
-	@Override
-	List<? extends Serializable> getEntries() throws Exception {
-		return capi.read(cref, FifoCoordinator
-				.newSelector(MzsConstants.Selecting.COUNT_MAX),
-				RequestTimeout.DEFAULT, null);
-	}
-}
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/WaiterXVSM.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/WaiterXVSM.java
index b46115b..b358690 100644
--- a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/WaiterXVSM.java
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/WaiterXVSM.java
@@ -3,7 +3,8 @@ package at.ac.tuwien.sbc.valesriegler.xvsm;
 import at.ac.tuwien.sbc.valesriegler.common.OrderId;
 import at.ac.tuwien.sbc.valesriegler.common.Util;
 import at.ac.tuwien.sbc.valesriegler.types.*;
-import org.mozartspaces.core.MzsConstants;
+import at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers.SpaceAction;
+import at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers.SpaceListener;
 import org.mozartspaces.core.MzsConstants.RequestTimeout;
 import org.mozartspaces.core.MzsCoreException;
 import org.mozartspaces.core.TransactionReference;
@@ -42,9 +43,9 @@ public class WaiterXVSM extends AbstractXVSMConnector {
     }
 
     public void listenForPhoneOrders() {
-        SpaceListener phoneListener = new SpaceListenerImpl(capi, phoneCallsContainer, true) {
+        SpaceListener phoneListener = getDefaultBuilder().setCref(phoneCallsContainer).setLookaround(true).setSpaceAction(new SpaceAction() {
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
+            public void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
                 final List<DeliveryGroupData> phoneOrders = castEntries(entries);
 
                 for (DeliveryGroupData phoneOrder : phoneOrders) {
@@ -73,13 +74,10 @@ public class WaiterXVSM extends AbstractXVSMConnector {
                         log.info("Waiter has taken a phone delivery call!");
                     } catch (Exception e) {
                     }
-
-
                 }
 
             }
-        };
-        createNotification(phoneListener, phoneCallsContainer);
+        }).createSpaceListenerImpl();
     }
 
     private void updatePizzeriaOrderNumber(Order order, TransactionReference tx) throws MzsCoreException {
@@ -98,10 +96,10 @@ public class WaiterXVSM extends AbstractXVSMConnector {
 
 
     public void listenForFreeTable() {
-        SpaceListener listener = new SpaceListenerImpl(capi, freeTablesContainer, false) {
+        SpaceListener listener = getDefaultBuilder().setCref(freeTablesContainer).setSpaceAction(new SpaceAction() {
 
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
+            public void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
 
                 List<Table> tables = castEntries(entries);
 
@@ -131,16 +129,14 @@ public class WaiterXVSM extends AbstractXVSMConnector {
                     }
                 }
             }
-        };
-
-        createNotification(listener, freeTablesContainer);
+        }).createSpaceListenerImpl();
     }
 
     public void listenForNewGuests() {
-        SpaceListener listener = new SpaceListenerImpl(capi, assignTableContainer) {
+        SpaceListener listener = getDefaultBuilder().setCref(assignTableContainer).setSpaceAction(new SpaceAction() {
 
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries)
+            public void onEntriesWritten(List<? extends Serializable> entries)
                     throws Exception {
                 log.info("New guest groups have arrived");
 
@@ -171,16 +167,14 @@ public class WaiterXVSM extends AbstractXVSMConnector {
                     }
                 }
             }
-        };
-
-        createNotification(listener, assignTableContainer);
+        }).createSpaceListenerImpl();
     }
 
     public void listenForPaymentRequest() {
-        SpaceListener paymentListener = new SpaceListenerImpl(capi, paymentRequestContainer) {
+        SpaceListener paymentListener = getDefaultBuilder().setCref(paymentRequestContainer).setSpaceAction(new SpaceAction() {
 
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries)
+            public void onEntriesWritten(List<? extends Serializable> entries)
                     throws Exception {
 
                 List<GroupData> groups = castEntries(entries);
@@ -208,16 +202,14 @@ public class WaiterXVSM extends AbstractXVSMConnector {
                     }
                 }
             }
-        };
-
-        createNotification(paymentListener, paymentRequestContainer);
+        }).createSpaceListenerImpl();
     }
 
     public void listenForOrderRequests() {
-        SpaceListener ordersListener = new SpaceListenerImpl(capi, takeOrderContainer) {
+        SpaceListener ordersListener = getDefaultBuilder().setCref(takeOrderContainer).setSpaceAction(new SpaceAction() {
 
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries)
+            public void onEntriesWritten(List<? extends Serializable> entries)
                     throws Exception {
 
                 List<GroupData> groups = castEntries(entries);
@@ -259,9 +251,7 @@ public class WaiterXVSM extends AbstractXVSMConnector {
                     }
                 }
             }
-        };
-
-        createNotification(ordersListener, takeOrderContainer);
+        }).createSpaceListenerImpl();
     }
 
     public void listenForPreparedPizzas() {
@@ -273,10 +263,10 @@ public class WaiterXVSM extends AbstractXVSMConnector {
          * number of those pizzas with the number of necessary pizzas. If all
          * pizzas of an order are complete he then delivers them!
          */
-        SpaceListener preparedPizzasListener = new SpaceListenerImpl(capi, preparedPizzasContainer) {
+        SpaceListener preparedPizzasListener = getDefaultBuilder().setCref(preparedPizzasContainer).setSpaceAction(new SpaceAction() {
 
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries)
+            public void onEntriesWritten(List<? extends Serializable> entries)
                     throws Exception {
 
                 List<Pizza> pizzas = castEntries(entries);
@@ -335,9 +325,7 @@ public class WaiterXVSM extends AbstractXVSMConnector {
                     }
                 }
             }
-        };
-
-        createNotification(preparedPizzasListener, preparedPizzasContainer);
+        }).createSpaceListenerImpl();
     }
 
 
@@ -350,10 +338,10 @@ public class WaiterXVSM extends AbstractXVSMConnector {
          * number of those pizzas with the number of necessary pizzas. If all
          * pizzas of an order are complete he then delivers them!
          */
-        SpaceListener preparedPizzasListener = new SpaceListenerImpl(capi, preparedDeliveryPizzasContainer, true) {
+        SpaceListener preparedPizzasListener = getDefaultBuilder().setCref(preparedDeliveryPizzasContainer).setLookaround(true).setSpaceAction(new SpaceAction() {
 
             @Override
-            void onEntriesWritten(List<? extends Serializable> entries)
+            public void onEntriesWritten(List<? extends Serializable> entries)
                     throws Exception {
 
                 List<Pizza> pizzas = castEntries(entries);
@@ -371,7 +359,7 @@ public class WaiterXVSM extends AbstractXVSMConnector {
                         entity.setOrder(order);
 
                         DeliveryGroupData groupData = takeMatchingEntity(entity,
-                                deliveryOrderTakenContainer, tx, MzsConstants.RequestTimeout.DEFAULT,
+                                deliveryOrderTakenContainer, tx, RequestTimeout.DEFAULT,
                                 "Another driver just checks if the delivery order is complete");
                         int groupId = groupData.getId();
                         int numberOfPizzas = groupData.getOrder().getNumberOfPizzas();
@@ -381,7 +369,7 @@ public class WaiterXVSM extends AbstractXVSMConnector {
 
                         List<Pizza> pizzasOfOrder = takeMatchingEntities(
                                 pizzaTemplate, preparedDeliveryPizzasContainer, tx,
-                                MzsConstants.RequestTimeout.DEFAULT,
+                                RequestTimeout.DEFAULT,
                                 "Cannot take the pizzas from the preparedDeliveryPizzasContainer");
 
                         if (pizzasOfOrder.size() == numberOfPizzas) {
@@ -392,7 +380,7 @@ public class WaiterXVSM extends AbstractXVSMConnector {
                             group.setOrder(completeOrder);
                             final List<DeliveryGroupData> groupsWithCompleteOrder = Arrays.asList(group);
                             sendItemsToContainer(groupsWithCompleteOrder,
-                                    deliverDeliveryOrder, MzsConstants.RequestTimeout.DEFAULT,
+                                    deliverDeliveryOrder, RequestTimeout.DEFAULT,
                                     tx);
 
                             capi.commitTransaction(tx);
@@ -410,9 +398,7 @@ public class WaiterXVSM extends AbstractXVSMConnector {
                     }
                 }
             }
-        };
-
-        createNotification(preparedPizzasListener, preparedDeliveryPizzasContainer);
+        }).createSpaceListenerImpl();
     }
 
     private void assignGroupToTable(GroupData lockedGroup,
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/driver/Driver.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/driver/Driver.java
index 33e6cd5..c58a300 100644
--- a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/driver/Driver.java
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/driver/Driver.java
@@ -24,7 +24,7 @@ public class Driver {
 
     private void start() {
         xvsm = new DriverXVSM(id, port);
-        xvsm.listenForPreparedPizzas();
+//        xvsm.listenForPreparedPizzas();
     }
 
     public Driver(int id, int port) {
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/spacehelpers/SpaceAction.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/spacehelpers/SpaceAction.java
new file mode 100644
index 0000000..9cc0e2a
--- /dev/null
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/spacehelpers/SpaceAction.java
@@ -0,0 +1,12 @@
+package at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers;
+
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public abstract class SpaceAction {
+    protected AtomicBoolean inNotification = new AtomicBoolean(true);
+
+    public abstract void onEntriesWritten(List<? extends Serializable> entries) throws Exception;
+}
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/SpaceListener.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/spacehelpers/SpaceListener.java
similarity index 83%
rename from src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/SpaceListener.java
rename to src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/spacehelpers/SpaceListener.java
index 5716045..f85e000 100644
--- a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/SpaceListener.java
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/spacehelpers/SpaceListener.java
@@ -1,12 +1,12 @@
-package at.ac.tuwien.sbc.valesriegler.xvsm;
+package at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers;
 
 import java.io.Serializable;
 import java.util.Date;
 import java.util.List;
 import java.util.Timer;
 import java.util.TimerTask;
-import java.util.concurrent.atomic.AtomicBoolean;
 
+import at.ac.tuwien.sbc.valesriegler.xvsm.AbstractXVSMConnector;
 import org.mozartspaces.notifications.Notification;
 import org.mozartspaces.notifications.NotificationListener;
 import org.mozartspaces.notifications.Operation;
@@ -20,7 +20,7 @@ import org.slf4j.LoggerFactory;
  * In {@link SpaceListener#getEntries()} a method for reading the entities, that are normally expected from the notification,
  * must be supplied. Thus, it's possible in {@link SpaceListener#startHandlingAbsenceOfNotifications()} to start a timer and to
  * execute the actions, which are normally triggered by the notification, with space objects read from {@link SpaceListener#getEntries()}.
- * If {@link SpaceListener#lookAround} is true the timer periodically checks if the corresponding {@link AbstractXVSMConnector#timeOflastOperation} is old enough (= the agent is idle for some time)
+ * If {@link SpaceListener#lookAround} is true the timer periodically checks if the corresponding {@link at.ac.tuwien.sbc.valesriegler.xvsm.AbstractXVSMConnector#timeOflastOperation} is old enough (= the agent is idle for some time)
  * and possibly executes the action as a result.
  * 
  * @author Gregor Riegler <gregor DOT riegler AT gmail DOT com>
@@ -32,7 +32,7 @@ public abstract class SpaceListener implements NotificationListener {
 	
 	protected boolean lookAround = true;
 	protected long timeout = 3000;
-	protected AtomicBoolean inNotification = new AtomicBoolean(true);
+    protected SpaceAction spaceAction;
 
 	@Override
 	public void entryOperationFinished(Notification arg0, Operation arg1,
@@ -41,8 +41,8 @@ public abstract class SpaceListener implements NotificationListener {
 			AbstractXVSMConnector.timeOflastOperation.set(new Date().getTime());
 			try {
 				log.info("I am running a notification now!");
-				inNotification.set(true);
-				onEntriesWritten(entries);
+				spaceAction.inNotification.set(true);
+				spaceAction.onEntriesWritten(entries);
 			} catch (Exception e) {
 //				e.printStackTrace();
 			}
@@ -52,9 +52,6 @@ public abstract class SpaceListener implements NotificationListener {
 
 	abstract List<? extends Serializable> getEntries() throws Exception;
 
-	abstract void onEntriesWritten(List<? extends Serializable> entries)
-			throws Exception;
-
 	public void startHandlingAbsenceOfNotifications() {
 		if(!lookAround) return;
 		AbstractXVSMConnector.timeOflastOperation.set(new Date().getTime() + 3500);
@@ -79,8 +76,8 @@ public abstract class SpaceListener implements NotificationListener {
 					List<? extends Serializable> entries = getEntries();
 					if(entries.size() != 0) {
 						log.info("{} entries in timer", entries.size());
-						inNotification.set(false);
-						onEntriesWritten(entries);
+						spaceAction.inNotification.set(false);
+						spaceAction.onEntriesWritten(entries);
 					} else {
 						log.info("No entries in timer!");
 					}
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/spacehelpers/SpaceListenerImpl.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/spacehelpers/SpaceListenerImpl.java
new file mode 100644
index 0000000..4b9e97b
--- /dev/null
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/spacehelpers/SpaceListenerImpl.java
@@ -0,0 +1,41 @@
+package at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.mozartspaces.capi3.FifoCoordinator;
+import org.mozartspaces.core.Capi;
+import org.mozartspaces.core.ContainerReference;
+import org.mozartspaces.core.MzsConstants;
+import org.mozartspaces.core.MzsConstants.RequestTimeout;
+import org.mozartspaces.notifications.NotificationManager;
+
+/**
+ * 
+ * @author Gregor Riegler <gregor DOT riegler AT gmail DOT com>
+ *
+ * @see SpaceListener
+ */
+public class SpaceListenerImpl extends SpaceListener {
+
+    public final NotificationManager notificationManager;
+    private Capi capi;
+	private ContainerReference cref;
+
+
+    public SpaceListenerImpl(Capi capi, ContainerReference cref, int timeout, SpaceAction spaceAction, NotificationManager notificationManager, boolean lookaround) {
+        this.capi = capi;
+        this.cref = cref;
+        this.timeout = timeout;
+        this.spaceAction = spaceAction;
+        this.notificationManager = notificationManager;
+        this.lookAround = lookaround;
+    }
+
+    @Override
+	List<? extends Serializable> getEntries() throws Exception {
+		return capi.read(cref, FifoCoordinator
+				.newSelector(MzsConstants.Selecting.COUNT_MAX),
+				RequestTimeout.DEFAULT, null);
+	}
+}
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/spacehelpers/SpaceListenerImplBuilder.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/spacehelpers/SpaceListenerImplBuilder.java
new file mode 100644
index 0000000..02e176e
--- /dev/null
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/spacehelpers/SpaceListenerImplBuilder.java
@@ -0,0 +1,57 @@
+package at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers;
+
+import at.ac.tuwien.sbc.valesriegler.common.Util;
+import org.mozartspaces.core.Capi;
+import org.mozartspaces.core.ContainerReference;
+import org.mozartspaces.notifications.NotificationManager;
+import org.mozartspaces.notifications.Operation;
+
+public class SpaceListenerImplBuilder {
+    private Capi capi;
+    private ContainerReference cref;
+    private int timeout = 3000;
+    private SpaceAction spaceAction;
+    private boolean lookaround = false;
+    private NotificationManager notificationManager;
+
+    public SpaceListenerImplBuilder setCapi(Capi capi) {
+        this.capi = capi;
+        return this;
+    }
+
+    public SpaceListenerImplBuilder setCref(ContainerReference cref) {
+        this.cref = cref;
+        return this;
+    }
+
+    public SpaceListenerImplBuilder setTimeout(int timeout) {
+        this.timeout = timeout;
+        return this;
+    }
+
+    public SpaceListenerImplBuilder setSpaceAction(SpaceAction spaceAction) {
+        this.spaceAction = spaceAction;
+        return this;
+    }
+
+    public SpaceListenerImplBuilder setNotificationManager(NotificationManager mgr) {
+        this.notificationManager = mgr;
+        return this;
+    }
+
+    public SpaceListenerImplBuilder setLookaround(boolean lookaround) {
+        this.lookaround = lookaround;
+        return this;
+    }
+
+    public SpaceListenerImpl createSpaceListenerImpl() {
+        final SpaceListenerImpl spaceListener = new SpaceListenerImpl(capi, cref, timeout, spaceAction, notificationManager, lookaround);
+        spaceListener.startHandlingAbsenceOfNotifications();
+        try {
+           notificationManager.createNotification(cref, spaceListener, Operation.WRITE);
+        } catch (Exception e) {
+            Util.handleSpaceErrorAndTerminate(e);
+        }
+        return spaceListener;
+    }
+}
\ No newline at end of file
-- 
2.43.0