From ae666ca32a4de375f1684aed522f715feb7677ff Mon Sep 17 00:00:00 2001
From: Gregor Riegler <gregor.riegler@gmail.com>
Date: Thu, 9 May 2013 00:12:37 +0200
Subject: [PATCH] Show table and waiting group changes according to
 notifications in pizzeriaGUI and groupGUI

---
 README.md                                     |   2 +-
 .../tuwien/sbc/valesriegler/group/Group.java  |  16 +-
 .../sbc/valesriegler/group/GroupAgent.java    |  20 +-
 .../group/gui/GroupOverviewModel.java         |   5 +-
 .../valesriegler/pizzeria/PizzeriaAgent.java  |  42 +--
 .../gui/tablemodels/GroupsOverviewModel.java  |  18 +-
 .../xvsm/AbstractXVSMConnector.java           | 155 +++++++++
 .../sbc/valesriegler/xvsm/GroupXVSM.java      |  56 ++++
 .../sbc/valesriegler/xvsm/PizzeriaXVSM.java   |  83 +++++
 .../xvsm/WaiterXVSMConnector.java             | 184 ++++++++++
 .../sbc/valesriegler/xvsm/XVSMConnector.java  | 313 +-----------------
 .../sbc/valesriegler/xvsm/cook/Cook.java      |   3 +-
 .../sbc/valesriegler/xvsm/waiter/Waiter.java  |  11 +-
 13 files changed, 539 insertions(+), 369 deletions(-)
 create mode 100644 src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/AbstractXVSMConnector.java
 create mode 100644 src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/GroupXVSM.java
 create mode 100644 src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/PizzeriaXVSM.java
 create mode 100644 src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/WaiterXVSMConnector.java

diff --git a/README.md b/README.md
index 5f077b4..c26b67b 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 Space Based Computing SS 2013
 ==================
 ### How to start the Group GUI
-		mvn exec:java -Dexec.mainClass="at.ac.tuwien.sbc.valesriegler.group.GroupAgent" 
+		mvn exec:java -Dexec.mainClass="at.ac.tuwien.sbc.valesriegler.group.GroupAgent" -Dmozartspaces.configurationFile="mozartspaces-client.xml"
 		
 ### How to start the JMS Pizzeria GUI
 		mvn exec:java -Dexec.mainClass="at.ac.tuwien.sbc.valesriegler.pizzeria.PizzeriaAgent" -Dexec.args="JMS"
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/group/Group.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/group/Group.java
index 816b280..d078c82 100644
--- a/src/main/java/at/ac/tuwien/sbc/valesriegler/group/Group.java
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/group/Group.java
@@ -25,11 +25,8 @@ public class Group implements Runnable, HasId {
 	private static final Logger log = LoggerFactory.getLogger(Group.class);
 	private static int idNext = -1; // TODO: set to 0 after debugging!
 
-	final private GroupData groupData;
+	private GroupData groupData;
 
-	public GroupData getGroupData() {
-		return groupData;
-	}
 
 	public Group() {
 		groupData = new GroupData(++idNext);
@@ -38,6 +35,8 @@ public class Group implements Runnable, HasId {
 	public Group(Integer id) {
 		groupData = new GroupData(id);
 	}
+	
+	
 
 	@Override
 	public void run() {
@@ -77,6 +76,15 @@ public class Group implements Runnable, HasId {
 			e.printStackTrace();
 		}
 	}
+	
+
+	public void setGroupData(GroupData groupData) {
+		this.groupData = groupData;
+	}
+
+	public GroupData getGroupData() {
+		return groupData;
+	}
 
 	// lets go to the pizzaria.
 	public void goGrabSomeFood() {
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/group/GroupAgent.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/group/GroupAgent.java
index 08b4cfc..6ae4181 100644
--- a/src/main/java/at/ac/tuwien/sbc/valesriegler/group/GroupAgent.java
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/group/GroupAgent.java
@@ -11,11 +11,15 @@ import javax.swing.SwingUtilities;
 
 import org.mozartspaces.core.CapiUtil;
 import org.mozartspaces.core.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import at.ac.tuwien.sbc.valesriegler.common.Util;
 import at.ac.tuwien.sbc.valesriegler.group.gui.GroupOverviewModel;
 import at.ac.tuwien.sbc.valesriegler.group.jms.JMSGroupConnector;
 import at.ac.tuwien.sbc.valesriegler.types.GroupData;
+import at.ac.tuwien.sbc.valesriegler.xvsm.AbstractXVSMConnector;
+import at.ac.tuwien.sbc.valesriegler.xvsm.GroupXVSM;
 import at.ac.tuwien.sbc.valesriegler.xvsm.XVSMConnector;
 
 /**
@@ -29,11 +33,12 @@ import at.ac.tuwien.sbc.valesriegler.xvsm.XVSMConnector;
  */
 public class GroupAgent {
 	
-	
-	public static GroupAgent groupAgent;
+	private static final Logger log = LoggerFactory.getLogger(GroupAgent.class);
 	private GroupOverviewModel groupModel;
 	private AbstractGroupConnector groupconn;
-	private XVSMConnector xvsm;
+	private GroupXVSM xvsm;
+	
+	public static GroupAgent groupAgent;
 
 	public static void main(String[] args) {
 		// TODO: use jms and xvsm manager here.
@@ -49,10 +54,9 @@ public class GroupAgent {
 			groupconn.init();
 		}
 		else {
-			xvsm = new XVSMConnector();
-			xvsm.initSpaceCommunication();
-			xvsm.useGroupsContainer();
+			xvsm = new GroupXVSM();
 
+			xvsm.listenForGroupDataChanges();
 		}
 	}
 
@@ -75,7 +79,9 @@ public class GroupAgent {
 			for (Group group : newGroups) {
 				groupData.add(group.getGroupData());
 			}
-			xvsm.sendGroupsToSpace(groupData);
+			xvsm.sendNewGroupsToSpace(groupData);
+			
+			log.info("New Groups were sent to the space");
 		}
 
 	}
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/group/gui/GroupOverviewModel.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/group/gui/GroupOverviewModel.java
index 6933822..adf9167 100644
--- a/src/main/java/at/ac/tuwien/sbc/valesriegler/group/gui/GroupOverviewModel.java
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/group/gui/GroupOverviewModel.java
@@ -54,11 +54,11 @@ public class GroupOverviewModel extends TableModel<Group> {
 		switch (wantedColumn) {
 		case ID:
 			int groupId = group.getGroupData().getId();
-			log.info("This is the group id : {}", groupId);
+//			log.info("This is the group id : {}", groupId);
 			return groupId;
 		case SIZE:
 			int groupSize = group.getGroupData().getSize();
-			log.info("This is the size : {}", groupSize);
+//			log.info("This is the size : {}", groupSize);
 			return groupSize;
 		case PIZZAS:
 			if (group.getGroupData().getOrder() == null)
@@ -124,6 +124,7 @@ public class GroupOverviewModel extends TableModel<Group> {
 		List<Group> groups = new ArrayList<>();
 		for (GroupData groupData : newItems) {
 			Group group = items.get(groupData.getId());
+			group.setGroupData(groupData);
 			groups.add(group);
 		}
 		super.addItems(groups);
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/pizzeria/PizzeriaAgent.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/pizzeria/PizzeriaAgent.java
index 76d73aa..f6be717 100644
--- a/src/main/java/at/ac/tuwien/sbc/valesriegler/pizzeria/PizzeriaAgent.java
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/pizzeria/PizzeriaAgent.java
@@ -22,7 +22,7 @@ import at.ac.tuwien.sbc.valesriegler.pizzeria.gui.tablemodels.TablesOverviewMode
 import at.ac.tuwien.sbc.valesriegler.pizzeria.gui.tablemodels.WaitersOfOrderModel;
 import at.ac.tuwien.sbc.valesriegler.types.GroupData;
 import at.ac.tuwien.sbc.valesriegler.types.Table;
-import at.ac.tuwien.sbc.valesriegler.xvsm.XVSMConnector;
+import at.ac.tuwien.sbc.valesriegler.xvsm.PizzeriaXVSM;
 
 /**
  * The Main class of the Pizzeria compoment.
@@ -45,7 +45,7 @@ public class PizzeriaAgent {
 	private WaitersOfOrderModel waitersModel;
 	private PizzasOfOrderModel pizzasModel;
 
-	private XVSMConnector xvsm;
+	private PizzeriaXVSM xvsm;
 
 	public static void main(String[] args) {// TODO: remove hardcoding of JMS.
 		// if (args.length != 1) {
@@ -78,40 +78,10 @@ public class PizzeriaAgent {
 	}
 
 	private void initXVSM() {
-			xvsm = new XVSMConnector();
-			xvsm.initSpaceCommunication();
-			xvsm.useTablesContainer();
-			xvsm.useGroupsContainer();
-			xvsm.useFreeTablesContainer();
-			
-			NotificationListener tablesListener = new NotificationListener() {
-	            @Override
-	            public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
-	                log.info("Tables Change notified");
-	            	
-	            	final List<Table> tables = new ArrayList<>();
-	            	List<Entry> entryList = (List<Entry>) entries;
-	            	for (Entry entry : entryList) {
-						tables.add((Table) entry.getValue());
-					}
-	                SwingUtilities.invokeLater(new Runnable() {
-						@Override
-						public void run() {
-							PizzeriaAgent.getInstance().getTablesModel().addItems(tables);
-						}
-					});
-	            }
-	        };
-	        
-	        NotificationListener groupsListener = new NotificationListener() {
-	            @Override
-	            public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
-	                List<GroupData> groups = (List<GroupData>) entries;
-	                PizzeriaAgent.getInstance().getGroupModel().addItems(groups);
-	            }
-	        };
-//			xvsm.initTablesNotifications(tablesListener);
-			xvsm.initGroupNotifications(groupsListener);
+			xvsm = new PizzeriaXVSM();
+						
+			xvsm.listenForTables();
+			xvsm.listenForGroups();
 	}
 
 	private void initGUI() {
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/pizzeria/gui/tablemodels/GroupsOverviewModel.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/pizzeria/gui/tablemodels/GroupsOverviewModel.java
index 69ea92f..966cf22 100644
--- a/src/main/java/at/ac/tuwien/sbc/valesriegler/pizzeria/gui/tablemodels/GroupsOverviewModel.java
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/pizzeria/gui/tablemodels/GroupsOverviewModel.java
@@ -18,6 +18,22 @@ public class GroupsOverviewModel extends TableModel<GroupData> {
 	protected String[] getColumns() {
 		return COLUMNS;
 	}
+	
+	@Override
+	public int getRowCount() {
+		List<GroupData> values = new ArrayList<>(items.values());
+		Iterator<GroupData> it = values.iterator();
+		while (it.hasNext()) {
+			GroupData groupData = it.next();
+			// Show only the waiting groups!
+			// TODO what is the GroupState.NEW? 
+			if(!(groupData.getState() == GroupState.NEW || groupData.getState() == GroupState.WAITING)) {
+				it.remove();
+			}
+		}
+		
+		return values.size();
+	}
 
 	@Override
 	public Object getValueAt(int rowIndex, int columnIndex) {
@@ -26,7 +42,7 @@ public class GroupsOverviewModel extends TableModel<GroupData> {
 		while (it.hasNext()) {
 			GroupData groupData = it.next();
 			// Show only the waiting groups!
-			if(groupData.getState() != GroupState.WAITING) {
+			if(groupData.getState() != GroupState.NEW) {
 				it.remove();
 			}
 		}
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
new file mode 100644
index 0000000..e317610
--- /dev/null
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/AbstractXVSMConnector.java
@@ -0,0 +1,155 @@
+package at.ac.tuwien.sbc.valesriegler.xvsm;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.mozartspaces.capi3.AnyCoordinator;
+import org.mozartspaces.capi3.Coordinator;
+import org.mozartspaces.capi3.CountNotMetException;
+import org.mozartspaces.capi3.LindaCoordinator;
+import org.mozartspaces.capi3.LindaCoordinator.LindaSelector;
+import org.mozartspaces.core.Capi;
+import org.mozartspaces.core.CapiUtil;
+import org.mozartspaces.core.ContainerReference;
+import org.mozartspaces.core.DefaultMzsCore;
+import org.mozartspaces.core.Entry;
+import org.mozartspaces.core.MzsConstants.RequestTimeout;
+import org.mozartspaces.core.MzsCore;
+import org.mozartspaces.core.MzsCoreException;
+import org.mozartspaces.core.TransactionReference;
+import org.mozartspaces.notifications.NotificationManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.ac.tuwien.sbc.valesriegler.common.Util;
+import at.ac.tuwien.sbc.valesriegler.types.GroupData;
+import at.ac.tuwien.sbc.valesriegler.types.Table;
+
+public abstract class AbstractXVSMConnector {
+	private static final Logger log = LoggerFactory.getLogger(AbstractXVSMConnector.class);
+
+	protected ContainerReference tablesContainer;
+	protected ContainerReference groupsContainer;
+	protected ContainerReference assignTableContainer;
+	protected ContainerReference takeOrderContainer;
+	private ContainerReference deliverPizzasContainer;
+	private ContainerReference paymentContainer;
+	protected ContainerReference freeTablesContainer;
+	protected Capi capi;
+	protected NotificationManager notificationMgr;
+
+	public AbstractXVSMConnector() {
+		initSpaceCommunication();
+	}
+
+	public void initSpaceCommunication() {
+		try {
+			MzsCore core = DefaultMzsCore.newInstanceWithoutSpace();
+			capi = new Capi(core);
+			notificationMgr = new NotificationManager(core);
+		} catch (Exception e) {
+			log.error("Space connection could not be established! Have you started the Space Server?");
+			handleSpaceErrorAndTerminate(e);
+		}
+	}
+
+	public void useTablesContainer() {
+		tablesContainer = useContainer(Util.TABLES_CONTAINER, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))) ;
+	}
+
+	public void useTakeOrderContainer() {
+		takeOrderContainer = useContainer(Util.TAKE_ORDER, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))) ;
+	}
+
+	public void useGroupsContainer() {
+		groupsContainer = useContainer(Util.GROUPS_CONTAINER, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))) ;
+	}
+
+	public void useAssignTableContainer() {
+		assignTableContainer = useContainer(Util.ASSIGN_TABLE, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))) ;
+	}
+
+	public void useFreeTablesContainer() {
+		freeTablesContainer = useContainer(Util.FREE_TABLES, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false)));
+	}
+
+	private ContainerReference useContainer(String containerName, List<Coordinator> coordinators) {
+		try {
+			return Util.getOrCreateNamedContainer(Util.SERVER_ADDR, containerName, capi, coordinators);
+		} catch (MzsCoreException e) {
+			handleSpaceErrorAndTerminate(e);
+		}
+		
+		return null;
+	}
+
+	private List<Coordinator> createCoordinators(Coordinator... coordinator) {
+		return Arrays.asList(coordinator);
+	}
+
+	protected void handleSpaceErrorAndTerminate(Exception e) {
+		log.error(e.getMessage());
+		e.printStackTrace();
+		System.exit(1);
+	}
+
+	protected <T extends Serializable> void sendItemsToContainer(
+			List<T> items, ContainerReference cref) {
+				
+				try {
+					List<Entry> entries = new ArrayList<>();
+					for (Serializable item : items) {
+						entries.add(new Entry(item));
+					}
+					capi.write(entries, cref);
+				} catch (Exception e) {
+					log.info(e.getMessage());
+					e.printStackTrace();
+				}
+			}
+
+	@SuppressWarnings("unchecked")
+	protected <T extends Serializable> T takeEntityByTemplateFromContainer(
+			T entity, ContainerReference ref, TransactionReference tx, long timeout, String errorMsg)
+			throws MzsCoreException {
+				try {
+					LindaSelector sel = LindaCoordinator.newSelector(entity, 1);
+					T singleEntity = null;
+					
+					ArrayList<Serializable> entities = capi.take(ref,  sel, RequestTimeout.DEFAULT, tx);
+					
+					return (T) CapiUtil.getSingleEntry(entities);
+				} catch (CountNotMetException e) {
+					log.info(errorMsg);
+					capi.rollbackTransaction(tx);
+					
+					throw new EntityNotFoundByTemplate(errorMsg);
+				}
+			}
+
+	protected <T extends Serializable> List<T> castEntries(List<? extends Serializable> entries) {
+		List<T> newList = new ArrayList<T>();
+		List<Entry> newEntries = (List<Entry>) entries;
+		for (Entry entry : newEntries) {
+			newList.add((T) entry.getValue());
+		}
+		return newList;
+	}
+
+	public void sendTablesToSpace(List<Table> tables) {
+		sendItemsToContainer(tables, tablesContainer);
+	}
+
+	public void sendFreeTablesToSpace(List<Table> tables) {
+		sendItemsToContainer(tables, freeTablesContainer);
+		sendTablesToSpace(tables);
+	}
+
+	public void sendNewGroupsToSpace(List<GroupData> newGroups) {
+		sendItemsToContainer(newGroups, groupsContainer);
+		sendItemsToContainer(newGroups, assignTableContainer);
+	}
+
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..634619b
--- /dev/null
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/GroupXVSM.java
@@ -0,0 +1,56 @@
+package at.ac.tuwien.sbc.valesriegler.xvsm;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.swing.SwingUtilities;
+
+import org.mozartspaces.core.MzsCoreException;
+import org.mozartspaces.notifications.Notification;
+import org.mozartspaces.notifications.NotificationListener;
+import org.mozartspaces.notifications.Operation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.ac.tuwien.sbc.valesriegler.group.GroupAgent;
+import at.ac.tuwien.sbc.valesriegler.types.GroupData;
+
+public class GroupXVSM extends AbstractXVSMConnector {
+	private static final Logger log = LoggerFactory.getLogger(GroupXVSM.class);
+	
+	public GroupXVSM() {
+		super();
+		useGroupsContainer();
+		useAssignTableContainer();
+	}
+
+	public void listenForGroupDataChanges() {
+		NotificationListener groupDataListener = new NotificationListener() {
+            @Override
+            public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
+               
+				log.info("{} groups have changed", entries.size());
+				
+				final List<GroupData> groups = castEntries(entries);
+				
+				SwingUtilities.invokeLater(new Runnable() {
+					
+					@Override
+					public void run() {
+						GroupAgent.getInstance().getGroupModel().addGroupData(groups);
+					}
+				});
+            }
+        };
+        try {
+			notificationMgr.createNotification(groupsContainer, groupDataListener, Operation.WRITE);
+			log.info("Created groupsContainer notification for a waiter");
+		} catch (MzsCoreException e) {
+			e.printStackTrace();
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+			
+	}
+
+}
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/PizzeriaXVSM.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/PizzeriaXVSM.java
new file mode 100644
index 0000000..4e48b4b
--- /dev/null
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/PizzeriaXVSM.java
@@ -0,0 +1,83 @@
+package at.ac.tuwien.sbc.valesriegler.xvsm;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.SwingUtilities;
+
+import org.mozartspaces.core.Entry;
+import org.mozartspaces.notifications.Notification;
+import org.mozartspaces.notifications.NotificationListener;
+import org.mozartspaces.notifications.Operation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.ac.tuwien.sbc.valesriegler.pizzeria.PizzeriaAgent;
+import at.ac.tuwien.sbc.valesriegler.types.GroupData;
+import at.ac.tuwien.sbc.valesriegler.types.Table;
+
+public class PizzeriaXVSM extends AbstractXVSMConnector {
+	private static final Logger log = LoggerFactory.getLogger(PizzeriaXVSM.class);
+	
+	public PizzeriaXVSM() {
+		super();
+		useTablesContainer();
+		useGroupsContainer();
+		useFreeTablesContainer();
+	}
+
+	public void listenForTables() {
+		NotificationListener tablesListener = new NotificationListener() {
+            @Override
+            public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
+                log.info("Tables Change notified");
+            	
+            	final List<Table> tables = castEntries(entries);
+        
+                SwingUtilities.invokeLater(new Runnable() {
+					@Override
+					public void run() {
+						PizzeriaAgent.getInstance().getTablesModel().addItems(tables);
+					}
+				});
+            }
+        };
+        try {
+        	notificationMgr.createNotification(tablesContainer, tablesListener, Operation.WRITE);
+        } catch (Exception e) {
+            handleSpaceErrorAndTerminate(e);
+        }
+	}
+
+	public void listenForGroups() {
+		
+        NotificationListener groupsListener = new NotificationListener() {
+            @Override
+            public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
+                final List<GroupData> groups = castEntries(entries);
+                
+                log.info("{} group changes!", groups.size());
+                for (GroupData groupData : groups) {
+                	log.info(groupData.toString());
+					
+				}
+                
+                SwingUtilities.invokeLater(new Runnable() {
+					@Override
+					public void run() {
+						PizzeriaAgent.getInstance().getGroupModel().addItems(groups);
+					}
+				});
+                
+            }
+        };
+	  try {
+        	notificationMgr.createNotification(groupsContainer, groupsListener, Operation.WRITE);
+        } catch (Exception e) {
+           handleSpaceErrorAndTerminate(e);
+        }
+	}
+
+
+}
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/WaiterXVSMConnector.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/WaiterXVSMConnector.java
new file mode 100644
index 0000000..8c91546
--- /dev/null
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/WaiterXVSMConnector.java
@@ -0,0 +1,184 @@
+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 org.mozartspaces.capi3.CountNotMetException;
+import org.mozartspaces.core.MzsCoreException;
+import org.mozartspaces.core.TransactionReference;
+import org.mozartspaces.core.MzsConstants.RequestTimeout;
+import org.mozartspaces.notifications.Notification;
+import org.mozartspaces.notifications.NotificationListener;
+import org.mozartspaces.notifications.Operation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.ac.tuwien.sbc.valesriegler.common.Util;
+import at.ac.tuwien.sbc.valesriegler.types.GroupData;
+import at.ac.tuwien.sbc.valesriegler.types.GroupState;
+import at.ac.tuwien.sbc.valesriegler.types.Table;
+
+public class WaiterXVSMConnector extends AbstractXVSMConnector {
+	private static final Logger log = LoggerFactory.getLogger(WaiterXVSMConnector.class);
+	
+	public WaiterXVSMConnector() {
+		super();
+		useFreeTablesContainer();
+		useAssignTableContainer();
+		useTablesContainer();
+		useTakeOrderContainer();
+		useGroupsContainer();
+	}
+	
+	public void listenForFreeTable() {
+			
+		NotificationListener freeTableListener = new NotificationListener() {
+            @Override
+            public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
+               
+				log.info("{} tables have become free", entries.size());
+				
+				List<Table> tables = castEntries(entries);
+				Collections.shuffle(tables);
+				
+				for (Table table : tables) {
+					try {
+						TransactionReference tx = capi.createTransaction(RequestTimeout.INFINITE, URI.create(Util.SERVER_ADDR));
+						
+						try {
+							// Acquire a lock for the free table in the FreeTableContainer
+							int id = table.getId();
+							log.info("Try to find the table with id {}", id);
+						
+							Table lockedFreeTable = takeEntityByTemplateFromContainer(new Table(id), freeTablesContainer, tx, 1000, String.format("There was no free table found with id %d", id));
+							
+							log.info("Table with id {} was found", id);
+							GroupData lockedGroup = takeEntityByTemplateFromContainer(new GroupData(), assignTableContainer, tx, 1000, "There is no group waiting for a table at the moment");
+					
+							// The new group sits down at the table
+							lockedFreeTable.setGroupId(lockedGroup.getId());
+							lockedGroup.setTable(lockedFreeTable);
+							
+							// The new group now wants to order
+							lockedGroup.setState(GroupState.ORDER_PENDING);
+							
+							sendItemsToContainer(Arrays.asList(lockedFreeTable), tablesContainer);
+							sendItemsToContainer(Arrays.asList(lockedGroup), groupsContainer);
+							sendItemsToContainer(Arrays.asList(lockedGroup), takeOrderContainer);
+							
+							log.info("Assigned Table to group with groupId {}", lockedGroup.getId());
+							capi.commitTransaction(tx);
+							
+						} catch (IllegalArgumentException e) {
+							log.error("SHOULD NEVER HAPPEN!");
+							System.exit(1);
+						}	catch (CountNotMetException e) {
+							log.error("SHOULD NEVER HAPPEN!");
+							System.exit(1);
+							log.info(e.getMessage());
+						} catch (EntityNotFoundByTemplate e) {
+							// TODO check why another exception is thrown
+//							capi.rollbackTransaction(tx);
+						} catch (Exception e) {
+							log.error("SHOULD NEVER HAPPEN!");
+							e.printStackTrace();
+							log.info(e.getMessage());
+							
+							capi.rollbackTransaction(tx);
+						}
+					} catch (Exception e) {
+						log.error("SHOULD NEVER HAPPEN!");
+						
+						e.printStackTrace();
+					}
+					
+				}
+            }
+        };
+        try {
+			notificationMgr.createNotification(freeTablesContainer, freeTableListener, Operation.WRITE);
+			log.info("Created freeTablesContainer notification for a waiter");
+		} catch (MzsCoreException e) {
+			e.printStackTrace();
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+			
+	}
+		
+	
+	
+	public void listenForNewGuests() {
+		NotificationListener newGroupsListener = new NotificationListener() {
+            @Override
+            public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
+               
+				log.info("New guest groups have arrived");
+				
+				List<GroupData> groups = castEntries(entries);
+				Collections.shuffle(groups);
+				
+				for (GroupData group : groups) {
+					try {
+						TransactionReference tx = capi.createTransaction(1500, URI.create(Util.SERVER_ADDR));
+						
+						try {
+							// Acquire a lock for the group in the AssignTableContainer
+							String groupNotFound = String.format("Group with id %d was already assigned a table by another waiter!", group.getId());
+							GroupData lockedGroup = takeEntityByTemplateFromContainer(new GroupData(group.getId()), assignTableContainer, tx, 1000, groupNotFound);
+							// Acquire a lock for one free table in the TablesContainer
+							Table lockedFreeTable = takeEntityByTemplateFromContainer(new Table(), freeTablesContainer, tx, 1000, String.format("No free table for group with id %d could be found", group.getId()));
+							
+							// The new group sits down at the table
+							lockedFreeTable.setGroupId(lockedGroup.getId());
+							lockedGroup.setTable(lockedFreeTable);
+							
+							// The new group now wants to order
+							lockedGroup.setState(GroupState.ORDER_PENDING);
+							
+							sendItemsToContainer(Arrays.asList(lockedFreeTable), tablesContainer);
+							sendItemsToContainer(Arrays.asList(lockedGroup), groupsContainer);
+							sendItemsToContainer(Arrays.asList(lockedGroup), takeOrderContainer);
+							
+							log.info("Assigned Table to group with groupId {}", lockedGroup.getId());
+							capi.commitTransaction(tx);
+							
+						} catch (IllegalArgumentException e) {
+							log.error("SHOULD NEVER HAPPEN!");
+							System.exit(1);
+						}	catch (CountNotMetException e) {
+							log.error("SHOULD NEVER HAPPEN!");
+							System.exit(1);
+							log.info(e.getMessage());
+						} catch (EntityNotFoundByTemplate e) {
+//							capi.rollbackTransaction(tx);
+						} catch (Exception e) {
+							log.error("SHOULD NEVER HAPPEN!");
+							e.printStackTrace();
+							log.info(e.getMessage());
+							
+							capi.rollbackTransaction(tx);
+						}
+					} catch (Exception e) {
+						log.error("SHOULD NEVER HAPPEN!");
+						
+						e.printStackTrace();
+					}
+					
+				}
+            }
+        };
+        try {
+			notificationMgr.createNotification(assignTableContainer, newGroupsListener, Operation.WRITE);
+			log.info("Created assingTableContainer notification for a waiter");
+		} catch (MzsCoreException e) {
+			e.printStackTrace();
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+	}
+
+}
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/XVSMConnector.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/XVSMConnector.java
index df53848..2214022 100644
--- a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/XVSMConnector.java
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/XVSMConnector.java
@@ -8,25 +8,17 @@ import java.util.Collections;
 import java.util.List;
 
 import org.bouncycastle.crypto.RuntimeCryptoException;
-import org.mozartspaces.capi3.AnyCoordinator;
 import org.mozartspaces.capi3.AnyCoordinator.AnySelector;
-import org.mozartspaces.capi3.Coordinator;
 import org.mozartspaces.capi3.CountNotMetException;
 import org.mozartspaces.capi3.FifoCoordinator;
 import org.mozartspaces.capi3.LindaCoordinator;
 import org.mozartspaces.capi3.LindaCoordinator.LindaSelector;
-import org.mozartspaces.core.Capi;
-import org.mozartspaces.core.CapiUtil;
-import org.mozartspaces.core.ContainerReference;
-import org.mozartspaces.core.DefaultMzsCore;
 import org.mozartspaces.core.Entry;
 import org.mozartspaces.core.MzsConstants.RequestTimeout;
-import org.mozartspaces.core.MzsCore;
 import org.mozartspaces.core.MzsCoreException;
 import org.mozartspaces.core.TransactionReference;
 import org.mozartspaces.notifications.Notification;
 import org.mozartspaces.notifications.NotificationListener;
-import org.mozartspaces.notifications.NotificationManager;
 import org.mozartspaces.notifications.Operation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -43,80 +35,10 @@ import at.ac.tuwien.sbc.valesriegler.types.Table;
  * @author Gregor Riegler <gregor DOT riegler AT gmail DOT com>
  * 
  */
-public class XVSMConnector {
-	private static final Logger log = LoggerFactory.getLogger(XVSMConnector.class);
-
-	private ContainerReference tablesContainer;
-	private ContainerReference groupsContainer;
-	private ContainerReference assignTableContainer;
-	private ContainerReference takeOrderContainer;
-	private ContainerReference deliverPizzasContainer;
-	private ContainerReference paymentContainer;
-	private ContainerReference freeTablesContainer;
-//	private ContainerReference notificationContainer;
-	private Capi capi;
-	private NotificationManager notificationMgr;
-
-
-	
-	public void initSpaceCommunication()  {
-		try {
-			MzsCore core = DefaultMzsCore.newInstanceWithoutSpace();
-			capi = new Capi(core);
-			notificationMgr = new NotificationManager(core);
-		} catch (Exception e) {
-			log.error("Space connection could not be established! Have you started the Space Server?");
-			handleSpaceErrorAndTerminate(e);
-		}
-	}
-	
-	public void useTablesContainer() {
-		tablesContainer = useContainer(Util.TABLES_CONTAINER, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))) ;
-	}
-	
-	public void useTakeOrderContainer() {
-		takeOrderContainer = useContainer(Util.TAKE_ORDER, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))) ;
-	}
-	
-	public void useGroupsContainer() {
-		groupsContainer = useContainer(Util.GROUPS_CONTAINER, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))) ;
-	}
-	
-	public void useAssignTableContainer() {
-		assignTableContainer = useContainer(Util.ASSIGN_TABLE, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))) ;
-	}
-	
-	public void useFreeTablesContainer() {
-		freeTablesContainer = useContainer(Util.FREE_TABLES, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false)));
-	}
-	
-	
-	
-	private ContainerReference useContainer(String containerName, List<Coordinator> coordinators) {
-		try {
-			return Util.getOrCreateNamedContainer(Util.SERVER_ADDR, containerName, capi, coordinators);
-		} catch (MzsCoreException e) {
-			handleSpaceErrorAndTerminate(e);
-		}
-		
-		return null;
-	}
-
-	
-	public void sendTablesToSpace(List<Table> tables) {
-		sendItemsToContainer(tables, tablesContainer);
-	}
-	
-	public void sendFreeTablesToSpace(List<Table> tables) {
-		sendItemsToContainer(tables, freeTablesContainer);
-		sendTablesToSpace(tables);
-	}
-
-
-	public void sendGroupsToSpace(List<GroupData> newGroups) {
-		sendItemsToContainer(newGroups, groupsContainer);
-	}
+public class XVSMConnector extends AbstractXVSMConnector {
+	static final Logger log = LoggerFactory.getLogger(XVSMConnector.class);
 
+	@Deprecated
 	public void handleWaitingGroup(int id) {
 
 		try {
@@ -171,6 +93,7 @@ public class XVSMConnector {
 		}
 	}
 
+	@Deprecated
 	public void handleOrderRequest(int id) {
 		try {
 			TransactionReference tx = capi.createTransaction(RequestTimeout.INFINITE, URI.create(Util.SERVER_ADDR));
@@ -222,235 +145,7 @@ public class XVSMConnector {
            handleSpaceErrorAndTerminate(e);
         }
 	}
-
-	public void handlePaymentRequest() {
-	}
-
-	public void handlePizzaDistribution() {
-	}
-	
-	
-	private List<Coordinator> createCoordinators(Coordinator... coordinator) {
-		return Arrays.asList(coordinator);
-	}
-	
-	private void handleSpaceErrorAndTerminate(Exception e) {
-		log.error(e.getMessage());
-		e.printStackTrace();
-		System.exit(1);
-	}
-	
-	
-	private <T extends Serializable> void sendItemsToContainer(List<T> items, ContainerReference cref) {
-		
-		try {
-			List<Entry> entries = new ArrayList<>();
-			for (Serializable item : items) {
-				entries.add(new Entry(item));
-			}
-			capi.write(entries, cref);
-		} catch (Exception e) {
-			log.info(e.getMessage());
-			e.printStackTrace();
-		}
-	}
 	
-	public void listenForFreeTable() {
-		
-		NotificationListener freeTableListener = new NotificationListener() {
-            @Override
-            public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
-               
-				log.info("{} tables have become free", entries.size());
-				
-				List<Table> tables = castEntries(entries);
-				Collections.shuffle(tables);
-				
-				for (Table table : tables) {
-					try {
-						TransactionReference tx = capi.createTransaction(RequestTimeout.INFINITE, URI.create(Util.SERVER_ADDR));
-						
-						try {
-							// Acquire a lock for the free table in the FreeTableContainer
-							int id = table.getId();
-							log.info("Try to find the table with id {}", id);
-						
-							Table lockedFreeTable = takeEntityByTemplateFromContainer(new Table(id), freeTablesContainer, tx, 1000, String.format("There was no free table found with id %d", id));
-							
-							log.info("Table with id {} was found", id);
-							GroupData lockedGroup = takeEntityByTemplateFromContainer(new GroupData(), assignTableContainer, tx, 1000, "There is no group waiting for a table at the moment");
-					
-							// The new group sits down at the table
-							lockedFreeTable.setGroupId(lockedGroup.getId());
-							lockedGroup.setTable(lockedFreeTable);
-							
-							// The new group now wants to order
-							lockedGroup.setState(GroupState.ORDER_PENDING);
-							
-							sendItemsToContainer(Arrays.asList(lockedFreeTable), tablesContainer);
-							sendItemsToContainer(Arrays.asList(lockedGroup), groupsContainer);
-							sendItemsToContainer(Arrays.asList(lockedGroup), takeOrderContainer);
-							
-							log.info("Assigned Table to group with groupId {}", lockedGroup.getId());
-							capi.commitTransaction(tx);
-							
-						} catch (IllegalArgumentException e) {
-							log.error("SHOULD NEVER HAPPEN!");
-							System.exit(1);
-						}	catch (CountNotMetException e) {
-							log.error("SHOULD NEVER HAPPEN!");
-							System.exit(1);
-							log.info(e.getMessage());
-						} catch (EntityNotFoundByTemplate e) {
-							// TODO check why another exception is thrown
-//							capi.rollbackTransaction(tx);
-						} catch (Exception e) {
-							log.error("SHOULD NEVER HAPPEN!");
-							e.printStackTrace();
-							log.info(e.getMessage());
-							
-							capi.rollbackTransaction(tx);
-						}
-					} catch (Exception e) {
-						log.error("SHOULD NEVER HAPPEN!");
-						
-						e.printStackTrace();
-					}
-					
-				}
-            }
-        };
-        try {
-			notificationMgr.createNotification(freeTablesContainer, freeTableListener, Operation.WRITE);
-			log.info("Created freeTablesContainer notification for a waiter");
-		} catch (MzsCoreException e) {
-			e.printStackTrace();
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-		}
-		
-	}
 	
-
-
-	public void listenForNewGuests() {
-		NotificationListener newGroupsListener = new NotificationListener() {
-            @Override
-            public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
-               
-				log.info("New guest groups have arrived");
-				
-				List<GroupData> groups = castEntries(entries);
-				Collections.shuffle(groups);
-				
-				for (GroupData group : groups) {
-					try {
-						TransactionReference tx = capi.createTransaction(1500, URI.create(Util.SERVER_ADDR));
-						
-						try {
-							// Acquire a lock for the group in the AssignTableContainer
-							String groupNotFound = String.format("Group with id %d was already assigned a table by another waiter!", group.getId());
-							GroupData lockedGroup = takeEntityByTemplateFromContainer(new GroupData(group.getId()), assignTableContainer, tx, 1000, groupNotFound);
-							// Acquire a lock for one free table in the TablesContainer
-							Table lockedFreeTable = takeEntityByTemplateFromContainer(new Table(), freeTablesContainer, tx, 1000, String.format("No free table for group with id %d could be found", group.getId()));
-							
-							// The new group sits down at the table
-							lockedFreeTable.setGroupId(lockedGroup.getId());
-							lockedGroup.setTable(lockedFreeTable);
-							
-							// The new group now wants to order
-							lockedGroup.setState(GroupState.ORDER_PENDING);
-							
-							sendItemsToContainer(Arrays.asList(lockedFreeTable), tablesContainer);
-							sendItemsToContainer(Arrays.asList(lockedGroup), groupsContainer);
-							sendItemsToContainer(Arrays.asList(lockedGroup), takeOrderContainer);
-							
-							log.info("Assigned Table to group with groupId {}", lockedGroup.getId());
-							capi.commitTransaction(tx);
-							
-						} catch (IllegalArgumentException e) {
-							log.error("SHOULD NEVER HAPPEN!");
-							System.exit(1);
-						}	catch (CountNotMetException e) {
-							log.error("SHOULD NEVER HAPPEN!");
-							System.exit(1);
-							log.info(e.getMessage());
-						} catch (EntityNotFoundByTemplate e) {
-//							capi.rollbackTransaction(tx);
-						} catch (Exception e) {
-							log.error("SHOULD NEVER HAPPEN!");
-							e.printStackTrace();
-							log.info(e.getMessage());
-							
-							capi.rollbackTransaction(tx);
-						}
-					} catch (Exception e) {
-						log.error("SHOULD NEVER HAPPEN!");
-						
-						e.printStackTrace();
-					}
-					
-				}
-            }
-        };
-        try {
-			notificationMgr.createNotification(assignTableContainer, newGroupsListener, Operation.WRITE);
-			log.info("Created assingTableContainer notification for a waiter");
-		} catch (MzsCoreException e) {
-			e.printStackTrace();
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-		}
-	}
 	
-	private GroupData getGroupWaitingForTable(GroupData group,
-			TransactionReference tx) throws MzsCoreException {
-
-
-	    GroupData singleGroup = takeEntityByTemplateFromContainer(new GroupData(group.getId()), assignTableContainer, tx, 1000, String.format("Group with id %d was already assigned a table by another waiter!", group.getId()));
-		
-		
-		return singleGroup;
-		
-	}
-	
-	private Table getFreeTableForGroup(GroupData group,
-			TransactionReference tx) throws MzsCoreException {
-		
-		return	 takeEntityByTemplateFromContainer(new Table(), freeTablesContainer, tx, 1000, String.format("No free table for group with id %d could be found", group.getId()));
-	
-		
-	}
-	
-	@SuppressWarnings("unchecked")
-	private <T extends Serializable> T takeEntityByTemplateFromContainer(T entity, ContainerReference ref, TransactionReference tx, long timeout, String errorMsg) throws MzsCoreException {
-		try {
-			LindaSelector sel = LindaCoordinator.newSelector(entity, 1);
-			T singleEntity = null;
-			
-			ArrayList<Serializable> entities = capi.take(ref,  sel, RequestTimeout.DEFAULT, tx);
-			log.info("Returned {} entities", entities.size());
-			
-			return (T) CapiUtil.getSingleEntry(entities);
-		} catch (CountNotMetException e) {
-			log.info(errorMsg);
-			capi.rollbackTransaction(tx);
-			
-			throw new EntityNotFoundByTemplate(errorMsg);
-		}
-	}
-	
-
-	
-	private <T extends Serializable> List<T> castEntries(List<? extends Serializable> entries) {
-		List<T> newList = new ArrayList<T>();
-		List<Entry> newEntries = (List<Entry>) entries;
-		for (Entry entry : newEntries) {
-			newList.add((T) entry.getValue());
-		}
-		return newList;
-	}
-	
-
-
 }
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/cook/Cook.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/cook/Cook.java
index 59f7308..75e7264 100644
--- a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/cook/Cook.java
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/cook/Cook.java
@@ -3,6 +3,7 @@ package at.ac.tuwien.sbc.valesriegler.xvsm.cook;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import at.ac.tuwien.sbc.valesriegler.xvsm.AbstractXVSMConnector;
 import at.ac.tuwien.sbc.valesriegler.xvsm.XVSMConnector;
 
 public class Cook {
@@ -10,7 +11,7 @@ public class Cook {
 	private static final Logger log = LoggerFactory.getLogger(Cook.class);
 	
 	private int id;
-	private XVSMConnector xvsm;
+	private AbstractXVSMConnector xvsm;
 
 	public static void main(String[] args) {
 		if(args.length != 1) {
diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/waiter/Waiter.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/waiter/Waiter.java
index 8942ea7..36bedce 100644
--- a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/waiter/Waiter.java
+++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/waiter/Waiter.java
@@ -16,6 +16,7 @@ import org.slf4j.LoggerFactory;
 import at.ac.tuwien.sbc.valesriegler.pizzeria.PizzeriaAgent;
 import at.ac.tuwien.sbc.valesriegler.types.GroupData;
 import at.ac.tuwien.sbc.valesriegler.types.Table;
+import at.ac.tuwien.sbc.valesriegler.xvsm.WaiterXVSMConnector;
 import at.ac.tuwien.sbc.valesriegler.xvsm.XVSMConnector;
 
 /**
@@ -29,7 +30,7 @@ public class Waiter implements Serializable {
 	private static final Logger log = LoggerFactory.getLogger(Waiter.class);
 
 	private int id;
-	private XVSMConnector xvsm;
+	private WaiterXVSMConnector xvsm;
 
 	public static void main(String[] args) {
 		if (args.length != 1) {
@@ -49,13 +50,7 @@ public class Waiter implements Serializable {
 	}
 
 	private void start() {
-		xvsm = new XVSMConnector();
-		xvsm.initSpaceCommunication();
-		
-		xvsm.useFreeTablesContainer();
-		xvsm.useAssignTableContainer();
-		xvsm.useTablesContainer();
-		xvsm.useTakeOrderContainer();
+		xvsm = new WaiterXVSMConnector();
 		
 		// when new guests arrive the waiter should try to assign a table to them
 		xvsm.listenForNewGuests();
-- 
2.43.0