Index: trunk/quest-plugin-jfc/src/main/java/de/ugoe/cs/quest/plugin/jfc/JFCTraceCorrector.java
===================================================================
--- trunk/quest-plugin-jfc/src/main/java/de/ugoe/cs/quest/plugin/jfc/JFCTraceCorrector.java	(revision 828)
+++ trunk/quest-plugin-jfc/src/main/java/de/ugoe/cs/quest/plugin/jfc/JFCTraceCorrector.java	(revision 829)
@@ -27,10 +27,14 @@
 /**
  * <p>
- * corrects older JFC log files which sometimes do not contain correct source specification for
- * events. It parses the file and adds component specifications to the source, that do not have
- * them. The parent components are reused from the last GUI element the user worked with. The
- * leaf component is parsed from the <code>toString</code> parameter that is provided with the
+ * corrects older JFC log files which sometimes do not contain correct source specifications for
+ * events. It parses the file and adds component specifications to the sources, that do not have
+ * them. For each invalid source it checks, if there is another source with the same
+ * <code>toString</code> parameter but a complete list of components. If one is found, it is reused
+ * as source for the event with the wrong source. If none is found, a new component list is
+ * generated. This contains as parent components the components of the source of the previous event.
+ * The leaf component is parsed from the <code>toString</code> parameter that is provided with the
  * source specifications. The resulting leaf nodes are not fully correct. They may pretend to
- * be equal although they are not. But more correctness is not achievable based on the
+ * be equal although they are not. Furthermore they may resist at a position in the GUI tree where
+ * they are not in reality. But more correctness is not achievable based on the
  * <code>toString</code> parameter. 
  * </p>
@@ -64,8 +68,8 @@
     /**
      * <p>
-     * the source of the last parsed event
-     * </p>
-     */
-    private Source lastSource;
+     * the list of all sources parsed in a file
+     * </p>
+     */
+    private List<Source> allSources = new ArrayList<Source>();
 
     /**
@@ -306,5 +310,5 @@
     public void endElement(String uri, String localName, String qName) throws SAXException {
         if (qName.equals("sessions")) {
-            //harmonizeToStringComponents();
+            correctSources(currentSession);
 
             currentSession.dump(outFile);
@@ -312,5 +316,5 @@
         }
         else if (qName.equals("newsession")) {
-            //harmonizeToStringComponents();
+            correctSources(currentSession);
             
             currentSession.dump(outFile);
@@ -322,9 +326,5 @@
         }
         else if (qName.equals("source")) {
-            if (currentSource.components.size() == 0) {
-                correctEventSource(currentSource);
-            }
-            
-            lastSource = currentSource;
+            rememberSource(currentSource);
             currentEvent.source = currentSource;
             currentSource = null;
@@ -341,117 +341,121 @@
 
     /**
-     * 
-     */
-    /*private void harmonizeToStringComponents() {
-        List<SourceGroup> groups = determineSourceGroups();
-        
-        for (SourceGroup group : groups) {
-            group.dump(System.out);
-        }
-    }*/
-
-    /**
+     * <p>
+     * stores a parsed source for later correction or reuse
+     * </p>
      *
-     */
-    /*private List<SourceGroup> determineSourceGroups() {
-        List<SourceGroup> groups = new ArrayList<SourceGroup>();
-        
-        for (Event event : currentSession.events) {
-            Source source = event.source;
-            Component lastComponent = source.components.get(source.components.size() - 1);
-            if (lastComponent instanceof ComponentFromToString) {
-                SourceGroup group = getSourceGroup(groups, source);
-                List<ComponentFromToString> sourcesWithSameXCoordinate =
-                    group.leafComponents.get(((ComponentFromToString) lastComponent).x);
-                
-                if (sourcesWithSameXCoordinate == null) {
-                    sourcesWithSameXCoordinate = new ArrayList<ComponentFromToString>();
-                    group.leafComponents.put
-                        (((ComponentFromToString) lastComponent).x, sourcesWithSameXCoordinate);
-                }
-                
-                if (!sourcesWithSameXCoordinate.contains(lastComponent)) {
-                    sourcesWithSameXCoordinate.add(((ComponentFromToString) lastComponent));
-                }
-            }
-        }
-        
-        return groups;
-    }*/
-
-    /**
-     * 
-     */
-    /*private SourceGroup getSourceGroup(List<SourceGroup> groups, Source source) {
-        SourceGroup resultingGroup = null;
-        
-        for (SourceGroup candidate : groups) {
-            if (candidate.parentComponents.size() == (source.components.size() - 1)) {
-                boolean allComponentsMatch = true;
-            
-                for (int i = 0; i < candidate.parentComponents.size(); i++) {
-                    if (!candidate.parentComponents.get(i).equals(source.components.get(i))) {
-                        allComponentsMatch = false;
-                        break;
-                    }
-                }
-                
-                if (allComponentsMatch) {
-                    resultingGroup = candidate;
-                    break;
-                }
-            }
-        }
-        
-        if (resultingGroup == null) {
-            resultingGroup = new SourceGroup();
-            
-            for (int i = 0; i < (source.components.size() - 1); i++) {
-                resultingGroup.parentComponents.add(source.components.get(i));
-            }
-            
-            groups.add(resultingGroup);
-        }
-        
-        return resultingGroup;
-    }*/
-
-    /**
-     * <p>
-     * corrects the source of an event. It copies all parameters of the source of the previous
+     * @param source the source to store
+     */
+    private void rememberSource(Source source) {
+        allSources.add(source);
+    }
+
+    /**
+     * <p>
+     * corrects all wrong sources in the events of the session. For each wrong resource, the
+     * {@link #correctEventSource(Event, Source)} method is called.
+     * </p>
+     *
+     * @param session the session of which the events shall be corrected
+     */
+    private void correctSources(Session session) {
+        Source previousSource = null;
+        for (Event event : session.events) {
+            if ((event.source == null) || (event.source.components == null) ||
+                (event.source.components.size() == 0))
+            {
+                correctEventSource(event, previousSource);
+            }
+            
+            previousSource = event.source;
+        }
+    }
+
+    /**
+     * <p>
+     * corrects the source of an event. It first searches for a correct source with an equal
+     * <code>toString</code> parameter. If there is any, this is reused. Otherwise it creates a
+     * new correct source. For this, it copies all parameters of the source of the provided previous
      * event if they are not included in the source already. Furthermore, it adds all components
      * of the source of the previous event. At last, it adds a further component based on the
      * information found in the <code>toString</code> parameter of the source.
      * </p>
+     * 
+     * @param event          the event of which the source must be corrected
+     * @param previousSource the source of the previous event to be potentially reused partially
+     */
+    private void correctEventSource(Event event, Source previousSource) {
+        String toStringValue = null;
+        
+        if ((event.source != null) && (event.source.params != null)) {
+            toStringValue = getToStringParam(event.source);
+        }
+        
+        Source existingSource = null;
+        
+        if (toStringValue != null) {
+            for (Source candidate : allSources) {
+                if (toStringValue.equals(getToStringParam(candidate)) &&
+                    (candidate.components != null) && (candidate.components.size() > 0))
+                {
+                    existingSource = candidate;
+                }
+            }
+        }
+        
+        if (existingSource != null) {
+            event.source = existingSource;
+        }
+        else {
+            if (previousSource != null) {
+                for (String[] parameterOfPreviousSource : previousSource.params) {
+                    boolean foundParameter = false;
+                    for (String[] parameter : event.source.params) {
+                        if (parameter[0].equals(parameterOfPreviousSource[0])) {
+                            foundParameter = true;
+                            break;
+                        }
+                    }
+
+                    if (!foundParameter) {
+                        event.source.params.add(parameterOfPreviousSource);
+                    }
+                }
+    
+                for (Component component : previousSource.components) {
+                    if (!(component instanceof ComponentFromToString)) {
+                        event.source.components.add(component);
+                    }
+                }
+            }
+
+            event.source.components.add(getComponentFromToString(toStringValue));
+        }
+    }
+
+    /**
+     * <p>
+     * retrieves the value of the <code>toString</code> parameter of the provided source.
+     * </p>
      *
-     * @param source the source to be corrected
-     */
-    private void correctEventSource(Source source) {
-        for (String[] parameterOfLastSource : lastSource.params) {
-            boolean foundParameter = false;
-            for (String[] parameter : source.params) {
-                if (parameter[0].equals(parameterOfLastSource[0])) {
-                    foundParameter = true;
-                    break;
-                }
-            }
-            
-            if (!foundParameter) {
-                source.params.add(parameterOfLastSource);
-            }
-        }
-        
-        for (Component component : lastSource.components) {
-            if (!(component instanceof ComponentFromToString)) {
-                source.components.add(component);
-            }
-        }
-        
-        source.components.add(getComponentFromToString(source));
-    }
-
-    /**
-     * <p>
-     * determines a component based on the <code>toString</code> parameter of the provided source.
+     * @param source the source to read the parameter of
+     * @return the value of the parameter
+     */
+    private String getToStringParam(Source source) {
+        String value = null;
+        
+        for (String[] param : source.params) {
+            if (("toString".equals(param[0])) && (param[1] != null) && (!"".equals(param[1]))) {
+                value = param[1];
+                break;
+            }
+        }
+        
+        return value;
+    }
+
+    /**
+     * <p>
+     * determines a component based on the <code>toString</code> parameter of a source.
      * For this, it parses the parameter value and tries to determine several infos such as the
      * type and the name of it. The resulting components are not always distinguishable. This is,
@@ -460,18 +464,9 @@
      * </p>
      * 
-     * @param source the source to extract the <code>toString</code> parameter from
+     * @param toStringValue the <code>toString</code> parameter of a source
      * 
      * @return the component parsed from the <code>toString</code> parameter
      */
-    private Component getComponentFromToString(Source source) {
-        String toStringValue = null;
-        
-        for (String[] parameter : source.params) {
-            if ("toString".equals(parameter[0])) {
-                toStringValue = parameter[1];
-                break;
-            }
-        }
-        
+    private Component getComponentFromToString(String toStringValue) {
         ComponentFromToString component = new ComponentFromToString();
         
@@ -802,27 +797,3 @@
     }
 
-    /**
-     * 
-     */
-    /*private class SourceGroup {
-        protected List<Component> parentComponents = new ArrayList<Component>();
-        protected Map<Integer, List<ComponentFromToString>> leafComponents =
-            new HashMap<Integer, List<ComponentFromToString>>();
-
-        private void dump(PrintStream out) {
-            out.println("source group:");
-            
-            for (Map.Entry<Integer, List<ComponentFromToString>> entry : leafComponents.entrySet())
-            {
-                out.print("    x-coordinate = ");
-                out.println(entry.getKey());
-                for (ComponentFromToString leafComponent : entry.getValue()) {
-                    leafComponent.dump(out);
-                }
-                
-                out.println();
-            }
-        }
-    }*/
-
 }
