Index: /trunk/autoquest-plugin-html-test/src/test/java/de/ugoe/cs/autoquest/plugin/html/commands/CMDcondenseHTMLGUIModelTest.java
===================================================================
--- /trunk/autoquest-plugin-html-test/src/test/java/de/ugoe/cs/autoquest/plugin/html/commands/CMDcondenseHTMLGUIModelTest.java	(revision 1335)
+++ /trunk/autoquest-plugin-html-test/src/test/java/de/ugoe/cs/autoquest/plugin/html/commands/CMDcondenseHTMLGUIModelTest.java	(revision 1336)
@@ -43,8 +43,4 @@
 
 /**
- * <p>
- * TODO comment
- * </p>
- * 
  * @author Patrick Harms
  */
@@ -168,5 +164,5 @@
             
         String[] assertionSpec =
-            { "/server/doc1/html/body/group_common/div",
+            { "/server/doc1/html/body/div",
               "/server/doc1/html/body/group_doc1/div_1",
               "/server/doc1/html/body/group_doc2/div_2" };
@@ -207,13 +203,13 @@
             
         String[] assertionSpec =
-            { "/server/doc1/html/body/div/group_doc1doc2doc3/group_doc1doc2/group_common/div_1",
-              "/server/doc1/html/body/div/group_doc1doc2doc3/group_doc1doc2/group_common/div_2",
+            { "/server/doc1/html/body/div/group_doc1doc2doc3/group_doc1doc2/div_1",
+              "/server/doc1/html/body/div/group_doc1doc2doc3/group_doc1doc2/div_2",
               "/server/doc1/html/body/div/group_doc1doc2doc3/group_doc1doc2/group_doc1/div_3",
               "/server/doc1/html/body/div/group_doc1doc2doc3/group_doc1doc2/group_doc1/div_5",
               "/server/doc1/html/body/div/group_doc1doc2doc3/group_doc1doc2/group_doc2/div_7",
               "/server/doc1/html/body/div/group_doc1doc2doc3/group_doc1doc2/group_doc2/div_8",
-              "/server/doc1/html/body/div/group_doc1doc2doc3/group_common/div_6",
+              "/server/doc1/html/body/div/group_doc1doc2doc3/div_6",
               "/server/doc1/html/body/div/group_doc1doc5/div_4",
-              "/server/doc1/html/body/div/group_doc3doc5/group_common/div_11",
+              "/server/doc1/html/body/div/group_doc3doc5/div_11",
               "/server/doc1/html/body/div/group_doc3doc5/group_doc3/div_9",
               "/server/doc1/html/body/div/group_doc3doc5/group_doc3/div_10",
@@ -221,5 +217,123 @@
               "/server/doc1/html/body/div/group_doc4/div_13" };
         
-        guiModel.dump(System.out, "UTF-8");
+        assertGUIModel(guiModel, assertionSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_condense_07() throws Exception {
+        String[] guiSpec =
+            { "/server/doc1/html/body/div/div_1/div_11",
+              "/server/doc2/html/body/div/div_2/div_21",
+              "/server/doc3/html/body/div/div_1/div_12" };
+                
+        GUIModel guiModel = generateGUIModel(guiSpec);
+        GlobalDataContainer.getInstance().addData("sequences_targets", guiModel);
+                
+        executeCommand();
+            
+        String[] assertionSpec =
+            { "/server/doc1/html/body/div/group_doc1doc3/div_1/group_doc1/div_11",
+              "/server/doc1/html/body/div/group_doc1doc3/div_1/group_doc3/div_12",
+              "/server/doc1/html/body/div/group_doc2/div_2/div_21" };
+        
+        assertGUIModel(guiModel, assertionSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_condense_08() throws Exception {
+        String[] guiSpec =
+            { "/server/doc1/html/body/div/div_1/div_11/div_111",
+              "/server/doc1/html/body/div/div_2/div_21/div_211",
+              "/server/doc1/html/body/div/div_3/div_31",
+              "/server/doc2/html/body/div/div_1/div_11/div_111",
+              "/server/doc2/html/body/div/div_2/div_21/div_211",
+              "/server/doc2/html/body/div/div_3/div_31",
+              "/server/doc2/html/body/div/div_4/div_41",
+              "/server/doc3/html/body/div" };
+                
+        GUIModel guiModel = generateGUIModel(guiSpec);
+        GlobalDataContainer.getInstance().addData("sequences_targets", guiModel);
+                
+        executeCommand();
+            
+        String[] assertionSpec =
+            { "/server/doc1/html/body/div/group_doc1doc2/div_1/div_11/div_111",
+              "/server/doc1/html/body/div/group_doc1doc2/div_2/div_21/div_211",
+              "/server/doc1/html/body/div/group_doc1doc2/div_3/div_31",
+              "/server/doc1/html/body/div/group_doc1doc2/group_doc2/div_4/div_41" };
+        
+        assertGUIModel(guiModel, assertionSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_condense_09() throws Exception {
+        String[] guiSpec =
+            { "/server/doc1/html/body/div/div_1/div_11/div_111",
+              "/server/doc1/html/body/div/div_2/div_21/div_211",
+              "/server/doc1/html/body/div/div_3/div_31",
+              "/server/doc2/html/body/div/div_1/div_12/div_121",
+              "/server/doc2/html/body/div/div_2/div_22/div_221",
+              "/server/doc2/html/body/div/div_3/div_31",
+              "/server/doc2/html/body/div/div_4/div_41",
+              "/server/doc3/html/body/div" };
+                
+        GUIModel guiModel = generateGUIModel(guiSpec);
+        GlobalDataContainer.getInstance().addData("sequences_targets", guiModel);
+                
+        executeCommand();
+            
+        String[] assertionSpec =
+            { "/server/doc1/html/body/div/group_doc1doc2/div_1/group_doc1/div_11/div_111",
+              "/server/doc1/html/body/div/group_doc1doc2/div_1/group_doc2/div_12/div_121",
+              "/server/doc1/html/body/div/group_doc1doc2/div_2/group_doc1/div_21/div_211",
+              "/server/doc1/html/body/div/group_doc1doc2/div_2/group_doc2/div_22/div_221",
+              "/server/doc1/html/body/div/group_doc1doc2/div_3/div_31",
+              "/server/doc1/html/body/div/group_doc1doc2/group_doc2/div_4/div_41" };
+        
+        assertGUIModel(guiModel, assertionSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_condense_10() throws Exception {
+        String[] guiSpec =
+            { "/server/doc1/html/body/div/div_1/div_11/div_111",
+              "/server/doc1/html/body/div/div_2/div_21/div_211",
+              "/server/doc1/html/body/div/div_3/div_31/div_311",
+              "/server/doc1/html/body/div/div_4/div_41/div_411",
+              "/server/doc1/html/body/div/div_5/div_51/div_511",
+              "/server/doc2/html/body/div/div_2/div_21/div_211",
+              "/server/doc2/html/body/div/div_3/div_31/div_311",
+              "/server/doc2/html/body/div/div_4/div_41/div_411",
+              "/server/doc2/html/body/div/div_5/div_51/div_511",
+              "/server/doc3/html/body/div/div_3/div_31/div_311",
+              "/server/doc3/html/body/div/div_4/div_41/div_411",
+              "/server/doc3/html/body/div/div_5/div_51/div_511",
+              "/server/doc4/html/body/div/div_4/div_41/div_411",
+              "/server/doc4/html/body/div/div_5/div_51/div_511" };
+                
+        GUIModel guiModel = generateGUIModel(guiSpec);
+        GlobalDataContainer.getInstance().addData("sequences_targets", guiModel);
+                
+        executeCommand();
+            
+        String[] assertionSpec =
+            { "/server/doc1/html/body/div/div_4/div_41/div_411",
+              "/server/doc1/html/body/div/div_5/div_51/div_511",
+              "/server/doc1/html/body/div/group_doc1doc2doc3/div_3/div_31/div_311",
+              "/server/doc1/html/body/div/group_doc1doc2doc3/group_doc1doc2/div_2/div_21/div_211",
+              "/server/doc1/html/body/div/group_doc1doc2doc3/group_doc1doc2/group_doc1/div_1/div_11/div_111" };
+        
         assertGUIModel(guiModel, assertionSpec);
     }
Index: /trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/commands/CMDcondenseHTMLGUIModel.java
===================================================================
--- /trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/commands/CMDcondenseHTMLGUIModel.java	(revision 1335)
+++ /trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/commands/CMDcondenseHTMLGUIModel.java	(revision 1336)
@@ -15,5 +15,4 @@
 package de.ugoe.cs.autoquest.plugin.html.commands;
 
-import java.io.PrintStream;
 import java.util.Arrays;
 import java.util.Comparator;
@@ -74,9 +73,6 @@
  *         \-- html
  *               \-- body
- *                     |-- group (common)
- *                     |     |-- div (id = menu)
- *                     |     |     \-- ...
- *                     |     \-- div (id = footer)
- *                     |           \-- ...
+ *                     |-- div (id = menu)
+ *                     |     \-- ...
  *                     |-- group (document1)
  *                     |     \-- div (id = textcontent)
@@ -85,4 +81,6 @@
  *                     |     \-- div (id = imagecontent)
  *                     |           \-- ...
+ *                     \-- div (id = footer)
+ *                           \-- ...
  * </pre>
  * This now allows the menu and the footer to be treated as identical over several pages.
@@ -128,5 +126,12 @@
         for (IGUIElement root : model.getRootElements()) {
             if (root instanceof HTMLServer) {
-                mergeServer((HTMLServer) root, model);
+                try {
+                    mergeServer((HTMLServer) root, model);
+                }
+                catch (Exception e) {
+                    Console.printerrln("problems while condensing model of server " + root);
+                    //e.printStackTrace(System.out);
+                    break;
+                }
             }
         }
@@ -148,8 +153,8 @@
         GUIElementsCluster rootCluster = getSimilarElementClusterHierarchy(server, model);
 
-        rootCluster.dump(System.out, "");
-            
-        Console.traceln(Level.FINE, "grouping GUI elements according to clusters");
-        groupGUIElementsAccordingToClusters(rootCluster, model, "");
+        //rootCluster.dump(System.out, "");
+            
+        Console.traceln(Level.FINE, "merging GUI elements in same clusters and creating groups");
+        mergeGUIElementsAccordingToClusters(rootCluster, model, "");
             
         //model.dump(System.out, "UTF-8");
@@ -176,4 +181,5 @@
         
         List<IGUIElement> children = model.getChildren(server);
+
         
         SimilarGUIElements similarGuiElements = new SimilarGUIElements();
@@ -182,4 +188,5 @@
             // when starting with the root, the cluster parent is the child itself, i.e. the
             // document. We expect all documents to be similar.
+
             similarGuiElements.add(new SimilarGUIElement(child, child));
         }
@@ -243,4 +250,22 @@
                 }
             }
+//            else {
+//                // search for a default cluster to add all elements to, which have no children
+//                GUIElementsCluster defaultCluster = null;
+//                
+//                for (GUIElementsCluster candidate : parentCluster.childClusters) {
+//                    if (candidate.similarChildrenGUIElements.size() == 0) {
+//                        defaultCluster = candidate;
+//                        break;
+//                    }
+//                }
+//                
+//                if (defaultCluster == null) {
+//                    defaultCluster = new GUIElementsCluster();
+//                    parentCluster.addChildCluster(defaultCluster);
+//                }
+//                
+//                defaultCluster.clusteredGUIElements.add(similarGuiElement);
+//            }
         }
     }
@@ -354,5 +379,5 @@
                 createClusterHierachies(subClusterToHandle);
                 
-                GUIElementsCluster commonCluster = new GUIElementsCluster();
+                /*GUIElementsCluster commonCluster = new GUIElementsCluster();
                 //commonCluster.setClusteredGUIElements(subClusterToHandle.clusteredGUIElements);
                 commonCluster.similarChildrenGUIElements.addAll
@@ -360,5 +385,41 @@
                 
                 subClusterToHandle.similarChildrenGUIElements.clear();
-                subClusterToHandle.childClusters.add(0, commonCluster);
+                subClusterToHandle.childClusters.add(0, commonCluster);*/
+            }
+        }
+    }
+
+    /**
+     * <p>
+     * called for each cluster to merge similar GUI elements depending on the clusters and to
+     * create GUI element groups if required. Calls itself recursively to be also applied on
+     * child clusters.
+     * </p>
+     *
+     * @param cluster the cluster of which the similar children shall be merged
+     * @param model   the model to be adapted through the merge
+     */
+    private void mergeGUIElementsAccordingToClusters(GUIElementsCluster cluster,
+                                                     GUIModel           model,
+                                                     String             indent)
+    {
+        //System.out.println(indent + "handling " + cluster);
+        
+        for (SimilarGUIElements similarGUIElements : cluster.similarChildrenGUIElements) {
+            mergeGUIElements(similarGUIElements, model, indent + "  ");
+        }
+        
+        if (cluster.childClusters.size() > 0) {
+            //System.out.println(indent + "  handling child clusters");
+            
+            for (GUIElementsCluster childCluster : cluster.childClusters) {
+                if (cluster.isDefault() || cluster.clusterParentsMatch(childCluster)) {
+                    // for default cluster or children not creating subgroups, just traverse the
+                    // cluster hierarchy
+                    mergeGUIElementsAccordingToClusters(childCluster, model, indent + "    ");
+                }
+                else {
+                    createClusterGroup(childCluster, model, indent + "    ");
+                }
             }
         }
@@ -380,6 +441,6 @@
 
         while (similarGUIElements.size() > 1) {
-            System.out.println(indent + "merging " + mergeResult + " and " +
-                               similarGUIElements.get(1).similarGUIElement);
+            //System.out.println(indent + "merging " + mergeResult + " and " +
+            //                   similarGUIElements.get(1).similarGUIElement);
             mergeResult = model.mergeGUIElements
                 (mergeResult, similarGUIElements.remove(1).similarGUIElement, false);
@@ -396,10 +457,7 @@
      * @param model   the model to be used for creating the groups
     */
-    private void groupGUIElementsAccordingToClusters(GUIElementsCluster cluster,
-                                                     GUIModel           model,
-                                                     String             indent)
-    {
-        System.out.println(indent + "handling " + cluster);
-        
+    private void createClusterGroup(GUIElementsCluster cluster, GUIModel model, String indent) {
+        //System.out.println(indent + "creating group for " + cluster);
+
         List<IGUIElement> guiElementsToGroup = new LinkedList<IGUIElement>();
         
@@ -409,46 +467,30 @@
         }
         
-        List<IGUIElement> subgroups = new LinkedList<IGUIElement>();
-
-        
-        System.out.println(indent + "iterating child clusters of " + cluster);
+        //System.out.println(indent + "  iterating child clusters of " + cluster);
         for (GUIElementsCluster childCluster : cluster.childClusters) {
-            groupGUIElementsAccordingToClusters(childCluster, model, indent + "  ");
-            
-            if (cluster.childClusters.size() > 1) {
-                List<IGUIElement> childGuiElemsToGroup = new LinkedList<IGUIElement>();
-                
-                for (SimilarGUIElements similarGUIElems : childCluster.similarChildrenGUIElements) {
-                    childGuiElemsToGroup.addAll(similarGUIElems.toGUIElementList());
-                }
-                
-                for (GUIElementsCluster subsubcluster : childCluster.childClusters) {
-                    if (subsubcluster.getGroup() != null) {
-                        childGuiElemsToGroup.add(subsubcluster.getGroup());
-                    }
-                }
-                
-                if (childGuiElemsToGroup.size() > 0) {
-                    System.out.println(indent + "  grouping: " + childGuiElemsToGroup);
-                    IGUIElement group = model.groupGUIElements
-                        (childGuiElemsToGroup, getGroupName(childCluster));
-                    System.out.println
-                        (indent + "    created group for " + childCluster + ": " + group);
-
-                    if (group != null) {
-                        childCluster.setGroup(group);
-                        if (cluster.isSubCluster(childCluster)) {
-                            subgroups.add(childCluster.getGroup());
-                        }
-                        else {
-                            subgroups.add(childCluster.getGroup().getParent());
-                        }
-                    }
-                }
-            }
-            
-            System.out.println();
-        }
-        
+            if (cluster.isDefault() || cluster.clusterParentsMatch(childCluster)) {
+                // for default cluster or children not creating subgroups, just traverse the
+                // cluster hierarchy
+                mergeGUIElementsAccordingToClusters(childCluster, model, indent + "  ");
+            }
+            else {
+                createClusterGroup(childCluster, model, indent + "  ");
+            }
+            
+            if (childCluster.getGroup() != null) {
+                if (cluster.isSubCluster(childCluster)) {
+                    guiElementsToGroup.add(childCluster.getGroup());
+                }
+                else {
+                    guiElementsToGroup.add(childCluster.getGroup().getParent());
+                }
+            }
+        }
+        
+        //System.out.println(indent + "grouping: " + guiElementsToGroup);
+        IGUIElement group = model.groupGUIElements(guiElementsToGroup, getGroupName(cluster));
+        //System.out.println(indent + "  created group for " + cluster + ": " + group);
+        
+        cluster.setGroup(group);
     }
 
@@ -541,4 +583,42 @@
         public String toString() {
             return getName();
+        }
+
+        /**
+         * <p>
+         * checks, if the main cluster parents, i.e., the documents of this and the provided cluster
+         * match
+         * </p>
+         *
+         * @param other the other cluster of which the main cluster parents shall be compared to
+         *              this
+         *              
+         * @return true if they match, false else
+         */
+        private boolean clusterParentsMatch(GUIElementsCluster other) {
+            // cluster parent may already be merged and therefore equals --> use system identity
+            // hash code for uniqueness
+            Set<Integer> mainClusterParents1 = new HashSet<Integer>();
+            for (SimilarGUIElement clusteredElem1 : clusteredGUIElements) {
+                mainClusterParents1.add(System.identityHashCode(clusteredElem1.mainClusterParent));
+            }
+            
+            Set<Integer> mainClusterParents2 = new HashSet<Integer>();
+            for (SimilarGUIElement clusteredElem2 : other.clusteredGUIElements) {
+                mainClusterParents2.add(System.identityHashCode(clusteredElem2.mainClusterParent));
+            }
+            
+            return mainClusterParents1.equals(mainClusterParents2);
+        }
+
+        /**
+         * <p>
+         * returns true, if this cluster is a default cluster
+         * </p>
+         *
+         * @return
+         */
+        public boolean isDefault() {
+            return clusteredGUIElements.size() <= 0;
         }
 
@@ -688,48 +768,48 @@
          * </p>
          */
-        private void dump(PrintStream out, String indent) {
-            out.print(indent);
-            out.print(getName());
-            out.println(" { ");
-            
-            if (clusteredGUIElements.size() > 0) {
-                out.print(indent);
-                out.println("  clustered GUIElements {");
-
-                for (SimilarGUIElement clusteredGUIElement : clusteredGUIElements) {
-                    clusteredGUIElement.dump(out, indent + "    ");
-                }
-
-                out.print(indent);
-                out.println("  }");
-            }
-
-            if (similarChildrenGUIElements.size() > 0) {
-                out.print(indent);
-                out.println("  similar children {");
-
-                for (SimilarGUIElements similarGuiElements : similarChildrenGUIElements) {
-                    similarGuiElements.dump(out, indent + "    ");
-                }
-
-                out.print(indent);
-                out.println("  }");
-            }
-
-            if (childClusters.size() > 0) {
-                out.print(indent);
-                out.println("  child clusters {");
-
-                for (GUIElementsCluster childCluster : childClusters) {
-                    childCluster.dump(out, indent + "    ");
-                }
-
-                out.print(indent);
-                out.println("  }");
-            }
-            
-            out.print(indent);
-            out.println("}");
-        }
+//        private void dump(PrintStream out, String indent) {
+//            out.print(indent);
+//            out.print(getName());
+//            out.println(" { ");
+//            
+//            if (clusteredGUIElements.size() > 0) {
+//                out.print(indent);
+//                out.println("  clustered GUIElements {");
+//
+//                for (SimilarGUIElement clusteredGUIElement : clusteredGUIElements) {
+//                    clusteredGUIElement.dump(out, indent + "    ");
+//                }
+//
+//                out.print(indent);
+//                out.println("  }");
+//            }
+//
+//            if (similarChildrenGUIElements.size() > 0) {
+//                out.print(indent);
+//                out.println("  similar children {");
+//
+//                for (SimilarGUIElements similarGuiElements : similarChildrenGUIElements) {
+//                    similarGuiElements.dump(out, indent + "    ");
+//                }
+//
+//                out.print(indent);
+//                out.println("  }");
+//            }
+//
+//            if (childClusters.size() > 0) {
+//                out.print(indent);
+//                out.println("  child clusters {");
+//
+//                for (GUIElementsCluster childCluster : childClusters) {
+//                    childCluster.dump(out, indent + "    ");
+//                }
+//
+//                out.print(indent);
+//                out.println("  }");
+//            }
+//            
+//            out.print(indent);
+//            out.println("}");
+//        }
 
     }
@@ -787,17 +867,17 @@
          * </p>
          */
-        private void dump(PrintStream out, String indent) {
-            out.print(indent);
-            out.print("{ ");
-            
-            for (int i = 0; i < super.size(); i++) {
-                if (i > 0) {
-                    out.print(", ");
-                }
-                out.print(super.get(i));
-            }
-            
-            out.println(" }");
-        }
+//        private void dump(PrintStream out, String indent) {
+//            out.print(indent);
+//            out.print("{ ");
+//            
+//            for (int i = 0; i < super.size(); i++) {
+//                if (i > 0) {
+//                    out.print(", ");
+//                }
+//                out.print(super.get(i));
+//            }
+//            
+//            out.println(" }");
+//        }
     }
     
@@ -839,8 +919,8 @@
          * </p>
          */
-        private void dump(PrintStream out, String indent) {
-            out.print(indent);
-            out.println(this);
-        }
+//        private void dump(PrintStream out, String indent) {
+//            out.print(indent);
+//            out.println(this);
+//        }
 
         /* (non-Javadoc)
