Index: trunk/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/AbstractDefaultGUIElement.java
===================================================================
--- trunk/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/AbstractDefaultGUIElement.java	(revision 604)
+++ trunk/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/AbstractDefaultGUIElement.java	(revision 609)
@@ -6,4 +6,8 @@
 
 package de.ugoe.cs.quest.eventcore.guimodel;
+
+import java.util.IdentityHashMap;
+import java.util.LinkedList;
+import java.util.List;
 
 /**
@@ -18,4 +22,8 @@
     public static final long serialVersionUID = 1L;
 
+    /** the reference to equal GUI element manager (needed to preserve singleton behavior) */
+    private static final EqualGUIElementManager equalGUIElementManager =
+        new EqualGUIElementManager();
+
     /** the specification of the GUI element */
     private IGUIElementSpec specification;
@@ -54,4 +62,13 @@
     }
 
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.quest.eventcore.guimodel.IGUIElement#addEqualGUIElement(IGUIElement)
+     */
+    @Override
+    public void addEqualGUIElement(IGUIElement equalElement)
+    {
+        equalGUIElementManager.addEqualGUIElements(this, equalElement);
+    }
+
     /*
      * (non-Javadoc)
@@ -60,7 +77,7 @@
      */
     public final boolean equals(Object other) {
-        // implement final, as GUI elments are all singletons and the equal only if they are the
-        // same object
-        return super.equals(other);
+        // implement final, as GUI elements are all singletons and they equal only if they are the
+        // same object or if they are in the list of equal GUI elements
+        return super.equals(other) || equalGUIElementManager.equals(this, other);
     }
 
@@ -70,7 +87,145 @@
     @Override
     public final int hashCode() {
-        // implement final, as GUI elments are all singletons and the equal only if they are the
-        // same object
-        return super.hashCode();
+        // implement final, as GUI elements are all singletons and they equal only if they are the
+        // same object. If there are several GUI element objects that represent the same GUI element
+        // then they are stored in the list of equal elements. In this case, the hash code of the
+        // list is unique within the system
+        return equalGUIElementManager.hashCode(this);
+    }
+
+    /**
+     * <p>
+     * TODO comment
+     * </p>
+     * 
+     * @version $Revision: $ $Date: 24.08.2012$
+     * @author 2012, last modified by $Author: pharms$
+     */
+    private static class EqualGUIElementManager {
+
+        /**
+         * <p>
+         * the internal map of GUI elements mapping each registered element to its equal variants.
+         * We use the {@link IdentityHashMap} as a normal hash map would not work because of the
+         * changing of the hash code of GUI elements at runtime.
+         * </p>
+         */
+        private IdentityHashMap<IGUIElement, List<IGUIElement>> identityHashMap =
+            new IdentityHashMap<IGUIElement, List<IGUIElement>>();
+        
+        /**
+         * <p>
+         * TODO: comment
+         * </p>
+         *
+         * @param abstractDefaultGUIElement
+         * @param equalElement
+         */
+        private synchronized void addEqualGUIElements(IGUIElement guiElement1,
+                                                      IGUIElement guiElement2)
+        {
+            List<IGUIElement> list1 = identityHashMap.get(guiElement1);
+            List<IGUIElement> list2 = identityHashMap.get(guiElement2);
+            
+            if (list1 == null) {
+                if (list2 == null) {
+                    list2 = new LinkedList<IGUIElement>();
+                    list2.add(guiElement1);
+                    list2.add(guiElement2);
+                    identityHashMap.put(guiElement1, list2);
+                    identityHashMap.put(guiElement2, list2);
+                }
+                else {
+                    addIfNotContained(list2, guiElement1);
+                    identityHashMap.put(guiElement1, list2);
+                }
+            }
+            else {
+                if (list2 == null) {
+                    addIfNotContained(list1, guiElement2);
+                    identityHashMap.put(guiElement2, list1);
+                }
+                else if (list1 != list2) {
+                    list1.addAll(list2);
+                    identityHashMap.put(guiElement2, list1);
+                }
+                // else
+                //     in this case, both GUI elements should already be registered with the same
+                //     lists.
+            }
+        }
+
+        /**
+         * <p>
+         * TODO: comment
+         * </p>
+         *
+         * @param abstractDefaultGUIElement
+         * @return
+         */
+        private synchronized int hashCode(IGUIElement guiElement) {
+            return System.identityHashCode(getEqualElementsList(guiElement));
+        }
+
+        /**
+         * <p>
+         * TODO: comment
+         * </p>
+         *
+         * @param abstractDefaultGUIElement
+         * @param other
+         * @return
+         */
+        private synchronized boolean equals(IGUIElement guiElement, Object other) {
+            if (other instanceof IGUIElement) {
+                for (IGUIElement candidate : getEqualElementsList(guiElement)) {
+                    if (candidate == other) {
+                        return true;
+                    }
+                }
+            }
+            
+            return false;
+        }
+
+        /**
+         * <p>
+         * TODO: comment
+         * </p>
+         *
+         * @param guiElement
+         * @return
+         */
+        private List<IGUIElement> getEqualElementsList(IGUIElement guiElement) {
+            List<IGUIElement> returnValue = identityHashMap.get(guiElement);
+            
+            if (returnValue == null) {
+                returnValue = new LinkedList<IGUIElement>();
+                returnValue.add(guiElement);
+                identityHashMap.put(guiElement, returnValue);
+            }
+            
+            return returnValue;
+        }
+
+        /**
+         * <p>
+         * TODO: comment
+         * </p>
+         *
+         * @param resultingList
+         * @param guiElement1
+         */
+        private void addIfNotContained(List<IGUIElement> equalElementsList, IGUIElement guiElement)
+        {
+            for (IGUIElement candidate : equalElementsList) {
+                if (candidate == guiElement) {
+                    return;
+                }
+            }
+            
+            equalElementsList.add(guiElement);
+        }
+
     }
 
