Index: trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UnusedGUIElementsRule.java
===================================================================
--- trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UnusedGUIElementsRule.java	(revision 1918)
+++ trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UnusedGUIElementsRule.java	(revision 2042)
@@ -15,4 +15,5 @@
 package de.ugoe.cs.autoquest.usability;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -28,8 +29,10 @@
 import de.ugoe.cs.autoquest.eventcore.guimodel.IComboBox;
 import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement;
+import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIView;
 import de.ugoe.cs.autoquest.eventcore.guimodel.IListBox;
 import de.ugoe.cs.autoquest.eventcore.guimodel.IMenuButton;
 import de.ugoe.cs.autoquest.eventcore.guimodel.ITextArea;
 import de.ugoe.cs.autoquest.eventcore.guimodel.ITextField;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
@@ -37,4 +40,5 @@
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
 
 /**
@@ -54,10 +58,14 @@
     public UsabilityEvaluationResult evaluate(ITaskModel taskModel) {
         UsabilityEvaluationResult results = new UsabilityEvaluationResult(taskModel);
-
-        GUIModel guiModel = getGUIModel(taskModel);
-        Set<IGUIElement> allGUIElements = getAllGUIElements(guiModel);
-        Set<IGUIElement> usedGUIElements = getUsedGUIElements(taskModel);
-        List<IGUIElement> unusedGUIElements = getUnusedGUIElements(usedGUIElements, allGUIElements);
-        handleUnusedGUIElements(unusedGUIElements, allGUIElements, results);
+        
+        Map<IGUIView, List<Set<IGUIElement>>> viewDisplays =
+            getViewDisplays(taskModel.getUserSessions());
+        
+        Map<IGUIView, Set<IGUIElement>> allGUIElements = getAllGUIElements(taskModel);
+        
+        for (Map.Entry<IGUIView, List<Set<IGUIElement>>> viewDisplay : viewDisplays.entrySet()) {
+            handleUnusedGUIElements
+                (allGUIElements, viewDisplay.getKey(), viewDisplay.getValue(), results);
+        }
 
         return results;
@@ -65,41 +73,73 @@
 
     /**
-     * <p>
-     * TODO: comment
-     * </p>
+     * @param results 
      *
-     * @param unusedGUIElements
-     * @param results
-     */
-    private void handleUnusedGUIElements(List<IGUIElement>         unusedGUIElements,
-                                         Set<IGUIElement>          allGUIElements,
-                                         UsabilityEvaluationResult results)
+     */
+    private void handleUnusedGUIElements(Map<IGUIView, Set<IGUIElement>> usedGUIElements,
+                                         IGUIView                        view,
+                                         List<Set<IGUIElement>>          viewUsages,
+                                         UsabilityEvaluationResult       results)
     {
-        int ratio = 1000 * unusedGUIElements.size() / allGUIElements.size();
-        
-        UsabilitySmellIntensity severity = UsabilitySmellIntensity.getIntensity(ratio);
-
-        if (severity != null) {
-            Map<String, Object> parameters = new HashMap<String, Object>();
-
-            parameters.put("ratio", ratio / 10);
-            parameters.put("noOfUnused", unusedGUIElements.size());
-            parameters.put("noOfAll", allGUIElements.size());
-            parameters.put("unusedGuiElements", unusedGUIElements);
-            
-            results.addSmell
-                (severity, UsabilitySmellDescription.UNUSED_GUI_ELEMENTS, parameters);
-        }
-     }
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
+        Set<IGUIElement> allElementsInView = usedGUIElements.get(view);
+        
+        if (allElementsInView == null) {
+            return;
+        }
+        
+        Map<Integer, List<IGUIElement>> usageCounters = new HashMap<>();
+        
+        for (IGUIElement relevantElement : allElementsInView) {
+            int usageCounter = 0;
+            
+            for (Set<IGUIElement> viewUsage : viewUsages) {
+                if (viewUsage.contains(relevantElement)) {
+                    usageCounter++;
+                }
+            }
+            
+            List<IGUIElement> elementsWithSameUsage = usageCounters.get(usageCounter);
+            
+            if (elementsWithSameUsage == null) {
+                elementsWithSameUsage = new LinkedList<>();
+                usageCounters.put(usageCounter, elementsWithSameUsage);
+            }
+            
+            elementsWithSameUsage.add(relevantElement);
+        }
+        
+        int cumulativeGuiElementUsage = 0;
+        for (Set<IGUIElement> viewUsage : viewUsages) {
+            cumulativeGuiElementUsage += viewUsage.size();
+        }
+        
+        List<IGUIElement> unusedElements = usageCounters.get(0);
+        
+        if (unusedElements != null) {
+            int ratio = 1000 * unusedElements.size() / allElementsInView.size();
+
+            UsabilitySmellIntensity severity = UsabilitySmellIntensity.getIntensity
+                (ratio, cumulativeGuiElementUsage, -1);
+
+            if (severity != null) {
+                Map<String, Object> parameters = new HashMap<String, Object>();
+
+                parameters.put("ratio", ratio / 10);
+                parameters.put("allDisplays", viewUsages.size());
+                parameters.put("view", view);
+                parameters.put("unusedGuiElements", unusedElements);
+                parameters.put("allGuiElements", allElementsInView.size());
+
+                results.addSmell
+                    (severity, UsabilitySmellDescription.UNUSED_GUI_ELEMENTS, parameters);
+            }
+        }
+    }
+
+    /**
      *
-     * @param taskModel
-     * @return
-     */
-    private GUIModel getGUIModel(ITaskModel taskModel) {
+     */
+    private Map<IGUIView, Set<IGUIElement>> getAllGUIElements(ITaskModel taskModel) {
+        Map<IGUIView, Set<IGUIElement>> result = new HashMap<>();
+        
         for (ITask task : taskModel.getTasks()) {
             if (task instanceof IEventTask) {
@@ -107,6 +147,17 @@
                     Event event = ((IEventTaskInstance) instance).getEvent();
                     
-                    if (event.getTarget() instanceof IGUIElement) {
-                        return ((IGUIElement) event.getTarget()).getGUIModel();
+                    if ((event.getTarget() instanceof IGUIElement) &&
+                        (isRelevant((IGUIElement) event.getTarget())))
+                    {
+                        IGUIView view = ((IGUIElement) event.getTarget()).getView();
+                        
+                        Set<IGUIElement> elements = result.get(view);
+                        
+                        if (elements == null) {
+                            elements = new HashSet<>();
+                            result.put(view, elements);
+                        }
+                        
+                        elements.add((IGUIElement) event.getTarget());
                     }
                 }
@@ -114,135 +165,129 @@
         }
         
-        return null;
-    }
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @param taskModel
-     */
-    private Set<IGUIElement> getUsedGUIElements(ITaskModel taskModel) {
-        Set<IGUIElement> usedGUIElements = new HashSet<IGUIElement>();
-        
-        for (ITask task : taskModel.getTasks()) {
-            if (task instanceof IEventTask) {
-                for (ITaskInstance instance : task.getInstances()) {
-                    Event event = ((IEventTaskInstance) instance).getEvent();
-                    
-                    if (event.getTarget() instanceof IGUIElement) {
-                        usedGUIElements.add((IGUIElement) event.getTarget());
+        // the problem is, that using the GUI model does not allow to find all in a specific view
+        // as the GUI model may return a merged element instead. But anyway, we can add those, which
+        // are in the GUI model and have the same view.
+        
+        GUIModel model = result.values().iterator().next().iterator().next().getGUIModel();
+        
+        GUIModel.Traverser traverser = model.getTraverser();
+
+        IGUIElement currentGUIElement = null;
+        do {
+            if (traverser.hasFirstChild()) {
+                currentGUIElement = traverser.firstChild();
+            }
+            else if (traverser.hasNextSibling()) {
+                currentGUIElement = traverser.nextSibling();
+            }
+            else {
+                while (currentGUIElement != null) {
+                    currentGUIElement = traverser.parent();
+                    if (traverser.hasNextSibling()) {
+                        currentGUIElement = traverser.nextSibling();
+                        break;
                     }
                 }
             }
-        }
-        
-        return usedGUIElements;
-    }
-    
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @param taskModel
-     */
-    private Set<IGUIElement> getAllGUIElements(GUIModel guiModel) {
-        Set<IGUIElement> allGUIElements = new HashSet<IGUIElement>();
-        
-        if (guiModel != null) {
-            GUIModel.Traverser traverser = guiModel.getTraverser();
-
-            IGUIElement currentGUIElement = null;
-            do {
-                if (traverser.hasFirstChild()) {
-                    currentGUIElement = traverser.firstChild();
-                }
-                else if (traverser.hasNextSibling()) {
-                    currentGUIElement = traverser.nextSibling();
-                }
-                else {
-                    while (currentGUIElement != null) {
-                        currentGUIElement = traverser.parent();
-                        if (traverser.hasNextSibling()) {
-                            currentGUIElement = traverser.nextSibling();
-                            break;
+
+            if (isRelevant(currentGUIElement)) {
+                IGUIView view = currentGUIElement.getView();
+                
+                Set<IGUIElement> elements = result.get(view);
+                
+                if (elements == null) {
+                    elements = new HashSet<>();
+                    result.put(view, elements);
+                }
+                
+                elements.add(currentGUIElement);
+            }
+        }
+        while (currentGUIElement != null);
+        
+        return result;
+    }
+
+    /**
+     * 
+     */
+    private Map<IGUIView, List<Set<IGUIElement>>> getViewDisplays(List<IUserSession> sessions) {
+        final IGUIView[] currentView = new IGUIView[1];
+        final List<IEventTaskInstance> actionInstances = new ArrayList<>();
+        final Map<IGUIView, List<Set<IGUIElement>>> result = new HashMap<>();
+        
+        for (IUserSession session : sessions) {
+            currentView[0] = null;
+            actionInstances.clear();
+            
+            for (final ITaskInstance currentRoot : session) {
+                currentRoot.accept(new DefaultTaskInstanceTraversingVisitor() {
+                    @Override
+                    public void visit(IEventTaskInstance eventTaskInstance) {
+                        if (eventTaskInstance.getEvent().getTarget() instanceof IGUIElement) {
+                            IGUIView view =
+                                ((IGUIElement) eventTaskInstance.getEvent().getTarget()).getView();
+                            
+                            if ((currentView[0] == null) && (view != null)) {
+                                currentView[0] = view;
+                                actionInstances.clear();
+                            }
+                            else if ((currentView[0] != null) && (!currentView[0].equals(view))) {
+                                addRelevantTargets(currentView[0], actionInstances, result);
+                                
+                                currentView[0] = view;
+                                actionInstances.clear();
+                            }
+                        }
+                        
+                        if (eventTaskInstance.getEvent().getTarget() instanceof IGUIElement) {
+                            actionInstances.add(eventTaskInstance);
                         }
                     }
-                }
-
-                if (isRelevant(currentGUIElement)) {
-                    allGUIElements.add(currentGUIElement);
-                }
-            }
-            while (currentGUIElement != null);
-        }
-        
-        return allGUIElements;
-    }
-    
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
+                });
+            }
+            
+            // add the used GUI elements of the last shown view in the session
+            if (currentView[0] != null) {
+                addRelevantTargets(currentView[0], actionInstances, result);
+            }
+        }
+        
+        return result;
+    }
+
+    /**
      *
-     * @param taskModel
-     */
-    private List<IGUIElement> getUnusedGUIElements(Set<IGUIElement> usedGUIElements,
-                                                   Set<IGUIElement> allGUIElements)
+     */
+    private void addRelevantTargets(IGUIView                              view,
+                                    List<IEventTaskInstance>              actionInstances,
+                                    Map<IGUIView, List<Set<IGUIElement>>> result)
     {
-        List<IGUIElement> unusedGUIElements = new LinkedList<IGUIElement>();
-        for (IGUIElement currentGUIElement : allGUIElements) {
-            if (isRelevant(currentGUIElement) &&
-                !belongsToUsedGUIElements(currentGUIElement, usedGUIElements))
-            {
-                unusedGUIElements.add(currentGUIElement);
-            }
-        }
-        
-        return unusedGUIElements;
-    }
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
+        List<Set<IGUIElement>> usedGUIElements = result.get(view);
+        
+        if (usedGUIElements == null) {
+            usedGUIElements = new LinkedList<>();
+            result.put(view, usedGUIElements);
+        }
+        
+        Set<IGUIElement> elementsInViewDisplay = new HashSet<>();
+        
+        for (IEventTaskInstance actionInstance : actionInstances) {
+            IGUIElement element = (IGUIElement) actionInstance.getEvent().getTarget();
+            
+            while (element != null) {
+                if (isRelevant(element)) {
+                    elementsInViewDisplay.add(element);
+                }
+                
+                element = element.getParent();
+            }
+        }
+        
+        usedGUIElements.add(elementsInViewDisplay);
+    }
+
+    /**
      *
-     * @param currentGUIElement
-     * @param usedGUIElements
-     * @return
-     */
-    private boolean belongsToUsedGUIElements(IGUIElement      relevantGUIElement,
-                                             Set<IGUIElement> usedGUIElements)
-    {
-        if (usedGUIElements.contains(relevantGUIElement)) {
-            return true;
-        }
-        else {
-            // in some cases, the events are recorded for the children of the relevant GUI elements
-            // therefore, check the children, as well.
-            List<IGUIElement> children =
-                relevantGUIElement.getGUIModel().getChildren(relevantGUIElement);
-            
-            if (children != null) {
-                for (IGUIElement child : children) {
-                    if (belongsToUsedGUIElements(child, usedGUIElements)) {
-                        return true;
-                    }
-                }
-            }
-        }
-        
-        return false;
-    }
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @param currentGUIElement
-     * @return
      */
     private boolean isRelevant(IGUIElement currentGUIElement) {
