Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/AbstractDefaultGUIElement.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/AbstractDefaultGUIElement.java	(revision 1115)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/AbstractDefaultGUIElement.java	(revision 1121)
@@ -15,5 +15,4 @@
 package de.ugoe.cs.autoquest.eventcore.guimodel;
 
-import java.util.IdentityHashMap;
 import java.util.LinkedList;
 import java.util.List;
@@ -38,13 +37,4 @@
     /**
      * <p>
-     * The reference to equal GUI element manager (needed to preserve singleton behavior, even
-     * though the objects are not singleton).
-     * </p>
-     */
-    private static final EqualGUIElementManager equalGUIElementManager =
-        new EqualGUIElementManager();
-
-    /**
-     * <p>
      * Specification of the GUI element
      * </p>
@@ -58,4 +48,11 @@
      */
     private final IGUIElement parent;
+    
+    /**
+     * <p>
+     * List of other GUI elements being equal to this
+     * </p>
+     */
+    private List<AbstractDefaultGUIElement> equalGUIElements = null;
     
     /**
@@ -109,5 +106,45 @@
     @Override
     public void addEqualGUIElement(IGUIElement equalElement) {
-        equalGUIElementManager.addEqualGUIElements(this, equalElement);
+        if (!(equalElement instanceof AbstractDefaultGUIElement)) {
+            throw new IllegalArgumentException
+                ("this implementation can only handle other AbstractDefaultGUIElements");
+        }
+        
+        AbstractDefaultGUIElement other = (AbstractDefaultGUIElement) equalElement;
+        
+        synchronized (AbstractDefaultGUIElement.class) {
+            if (this.equalGUIElements == null) {
+                if (other.equalGUIElements == null) {
+                    this.equalGUIElements = new LinkedList<AbstractDefaultGUIElement>();
+                    this.equalGUIElements.add(this);
+                    this.equalGUIElements.add(other);
+                    other.equalGUIElements = this.equalGUIElements;
+                }
+                else {
+                    addIfNotContained(other.equalGUIElements, this);
+                    this.equalGUIElements = other.equalGUIElements;
+                }
+            }
+            else {
+                if (other.equalGUIElements == null) {
+                    addIfNotContained(this.equalGUIElements, other);
+                    other.equalGUIElements = this.equalGUIElements;
+                }
+                else if (this.equalGUIElements != other.equalGUIElements) {
+                    this.equalGUIElements.addAll(other.equalGUIElements);
+
+                    // we also have to set this new list for all other elements for which so
+                    // far list2 was registered
+                    for (AbstractDefaultGUIElement candidate : other.equalGUIElements) {
+                        candidate.equalGUIElements = this.equalGUIElements;
+                    }
+
+                    other.equalGUIElements = this.equalGUIElements;
+                }
+                // else
+                // in this case, both GUI elements should already be registered with the same
+                // lists.
+            }
+        }
     }
 
@@ -140,5 +177,20 @@
         // 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);
+        if (super.equals(other)) {
+            return true;
+        }
+        else if (other instanceof AbstractDefaultGUIElement) {
+            synchronized (AbstractDefaultGUIElement.class) {
+                if (equalGUIElements != null) {
+                    for (IGUIElement candidate : equalGUIElements) {
+                        if (candidate == other) {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
     }
 
@@ -154,161 +206,35 @@
         // 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);
+        synchronized (AbstractDefaultGUIElement.class) {
+            if (this.equalGUIElements == null) {
+                this.equalGUIElements = new LinkedList<AbstractDefaultGUIElement>();
+                this.equalGUIElements.add(this);
+            }
+            
+            return System.identityHashCode(this.equalGUIElements);
+        }
     }
     
     /**
      * <p>
-     * This internal helper class manages equal GUI elements. This is necessary, as we often first
-     * identify many GUI elements as different and later use a heuristic to determine that they are
-     * the same. This class provides the means to preserve the singleton behavior of the GUI
-     * elements after we merge two GUI elements.
-     * </p>
-     * 
-     * @version 1.0
-     * @author Patrick Harms
-     */
-    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>
-         * Adds a new equals relationship between two {@link IGUIElement}s to the equality manager.
-         * </p>
-         * 
-         * @param guiElement1
-         *            first equal GUI element
-         * @param guiElement2
-         *            second equal GUI element
-         */
-        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);
-                    
-                    // we also have to set this new list for all other elements for which so
-                    // far list2 was registered
-                    for (IGUIElement candidate : list2) {
-                        identityHashMap.put(candidate, list1);
-                    }
-                }
-                // else
-                // in this case, both GUI elements should already be registered with the same
-                // lists.
-            }
-        }
-
-        /**
-         * <p>
-         * Returns the object hash of a {@link IGUIElement}.
-         * </p>
-         * 
-         * @param guiElement
-         *            gui element whose object hash is determined
-         * @return the object hash
-         */
-        private synchronized int hashCode(IGUIElement guiElement) {
-            return System.identityHashCode(getEqualElementsList(guiElement));
-        }
-
-        /**
-         * <p>
-         * Determines the equality of two {@link IGUIElement}s based on the information of the
-         * identify manager. Two elements are equal, if they have been added as equal using
-         * {@link #addEqualGUIElements(IGUIElement, IGUIElement)}.
-         * </p>
-         * 
-         * @param guiElement
-         *            GUI element to which the object is compared
-         * @param other
-         *            object that is compared to the GUI element
-         * @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>
-         * Returns the equal {@link IGUIElement} of a given {@link IGUIElement}.
-         * </p>
-         * 
-         * @param guiElement
-         *            GUI element of which the equal elements are returned
-         * @return the equal GUI elements
-         */
-        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>
-         * Adds {@link IGUIElement} as equal to a list of {@link IGUIElement} if and only if it is
-         * not already contained.
-         * </p>
-         * 
-         * @param equalElementsList
-         *            list of {@link IGUIElement} to which the GUI element is added
-         * @param guiElement
-         *            GUI element to be added
-         */
-        private void addIfNotContained(List<IGUIElement> equalElementsList, IGUIElement guiElement)
-        {
-            for (IGUIElement candidate : equalElementsList) {
-                if (candidate == guiElement) {
-                    return;
-                }
-            }
-
-            equalElementsList.add(guiElement);
-        }
-
+     * Adds an {@link AbstractDefaultGUIElement} as equal to a list of
+     * {@link AbstractDefaultGUIElement}s if and only if it is not already contained.
+     * </p>
+     * 
+     * @param equalElementsList
+     *            list of {@link AbstractDefaultGUIElement} to which the GUI element is added
+     * @param guiElement
+     *            GUI element to be added
+     */
+    private void addIfNotContained(List<AbstractDefaultGUIElement> equalElementsList,
+                                   AbstractDefaultGUIElement       guiElement)
+    {
+        for (IGUIElement candidate : equalElementsList) {
+            if (candidate == guiElement) {
+                return;
+            }
+        }
+
+        equalElementsList.add(guiElement);
     }
 
