Index: trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/jfc/data/JFCEvent.java
===================================================================
--- trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/jfc/data/JFCEvent.java	(revision 369)
+++ trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/jfc/data/JFCEvent.java	(revision 376)
@@ -160,32 +160,94 @@
 	}
 
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see de.ugoe.cs.eventbench.data.ReplayableEvent#equals(java.lang.Object)
+	/**
+	 * <p>
+	 * This method implements the comparison between two targets of JFCEvents.
+	 * The targets are equal, if they have the same placement in the widget
+	 * hierarchy, i.e., the target strings describe the same widgets, according
+	 * to the implementation of widget equality provided by
+	 * {@link #compareWidgets(String, String)}.
+	 * </p>
+	 * 
+	 * @see de.ugoe.cs.eventbench.data.Event#targetEquals(java.lang.String)
 	 */
 	@Override
-	public boolean equals(Object other) {
-		if (other == this) {
-			return true;
-		}
-		if (other instanceof JFCEvent) {
-			return super.equals(other)
-					&& parameters.equals(((JFCEvent) other).parameters);
-		}
-		return false;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see de.ugoe.cs.eventbench.data.ReplayableEvent#hashCode()
-	 */
+	protected boolean targetEquals(String otherTarget) {
+		if( target==null || otherTarget==null ) {
+			return target==otherTarget; 
+		}
+		String[] targetParts = target.split("\\]\\.\\[");
+		String[] otherParts = otherTarget.split("\\]\\.\\[");
+		if (targetParts.length != otherParts.length) {
+			return false;
+		}
+		
+		boolean retVal;
+		if (targetParts.length == 0) {
+			retVal = compareWidgets(target, otherTarget);
+		} else {
+			retVal = true;
+			for (int i = 0; retVal && i < targetParts.length; i++) {
+				retVal &= compareWidgets(targetParts[i], otherParts[i]);
+			}
+		}
+		return retVal;
+	}
+
+	/**
+	 * <p>
+	 * Compares two widget strings of the form
+	 * {@code ['title','class','index','text','hashCode']}.
+	 * </p>
+	 * 
+	 * @param widget1
+	 * @param widget2
+	 * @return
+	 */
+	private boolean compareWidgets(String widget1, String widget2) {
+		String[] widgetInfo1 = widget1.split("','");
+		String[] widgetInfo2 = widget2.split("','");
+		// ensure size is equal
+		if (widgetInfo1.length != 5 || widgetInfo2.length != 5) {
+			return false;
+		}
+		// ensure that class [1], index [2], and text [3] are equal
+		// and title [0] or hashCode [4] are equal
+		return (widgetInfo1[1].equals(widgetInfo2[1])
+				&& widgetInfo1[2].equals(widgetInfo2[2]) && widgetInfo1[3]
+					.equals(widgetInfo2[3]))
+				&& (widgetInfo1[0].equals(widgetInfo2[0]) || widgetInfo1[4]
+						.equals(widgetInfo2[4]));
+
+	}
+	
 	@Override
-	public int hashCode() {
-		int hashCode = super.hashCode();
-		hashCode *= parameters.hashCode();
+	protected int targetHashCode() {
+		int hashCode = 0;
+		int multiplier = 29;
+		if( target!=null ) {
+			String[] targetParts = target.split("\\[\\.\\[");
+			if( targetParts.length==0 ) {
+				hashCode = widgetHashCode(target);
+			} else {
+				for( String widgetString : targetParts ) {
+					hashCode = hashCode * multiplier + widgetHashCode(widgetString);
+				}
+			}
+		}
+		
 		return hashCode;
 	}
+	
+	private int widgetHashCode(String widget) {
+		int hashCode = 0;
+		int multiplier = 37;
+		String[] widgetInfo = widget.split("','");
+		if( widgetInfo.length==5 ) {
+			hashCode = hashCode * multiplier + widgetInfo[1].hashCode();
+			hashCode = hashCode * multiplier + widgetInfo[2].hashCode();
+			hashCode = hashCode * multiplier + widgetInfo[3].hashCode();
+		}
+		return hashCode;
+	}
 
 }
