diff -u -r engine.orig/backend.cs engine/backend.cs
--- engine.orig/backend.cs	2003-08-27 15:00:18.000000000 +1200
+++ engine/backend.cs	2003-10-24 13:09:33.000000000 +1300
@@ -45,6 +45,7 @@
 
 		public virtual bool AcceptCluePacket (CluePacket cp)
 		{
+		Console.WriteLine("In AcceptCluePacket");
 			// If the backend hasn't specified the clue_types its
 			// interested in, always accept the CluePacket.
 			if (SubscribedClues == null)
@@ -63,9 +64,9 @@
 					subscription_hash += clue.GetClueHash ();
 			}
 
-			if (subscription_hash != 0 && 
-			    subscription_hash != this.LastSubscriptionHash) {
-				this.LastSubscriptionHash = subscription_hash;
+			if (subscription_hash != 0) {
+			    //subscription_hash != this.LastSubscriptionHash) {
+				//this.LastSubscriptionHash = subscription_hash;
 				Console.WriteLine ("Accepting Packet: '{0}'", this.Name);
 				return true;
 			} else {
diff -u -r engine.orig/clue.cs engine/clue.cs
--- engine.orig/clue.cs	2003-07-29 11:49:38.000000000 +1200
+++ engine/clue.cs	2003-10-24 13:15:16.000000000 +1300
@@ -67,8 +67,8 @@
 			return this.Text.GetHashCode() ^ this.Type.GetHashCode() ^ this.Relevance.GetHashCode();
 		}
 
-		public override bool Equals (object o) {
-			return this.GetHashCode() == o.GetHashCode();
+		public override int GetHashCode() {
+			return this.GetClueHash();
 		}
 
 		public object Clone ()
@@ -77,5 +77,40 @@
 					 this.Text,
 					 this.Relevance);
 		}
+
+		// We state that two Clues are equal iff all fields are the same.
+		// We may want to ignore Relevance, but at this stage I'll keep it.
+		public static bool operator==(Clue c1, Clue c2) {
+			// Check the simple stuff first.
+			if (Object.ReferenceEquals(c1, null) &&
+					Object.ReferenceEquals(c2, null)) {
+				// Well, if they're both null then this is true...
+				return true;
+			} else if (! (Object.ReferenceEquals(c1, null) ||
+					Object.ReferenceEquals(c2, null))) {
+				return (c1.Text == c2.Text && c1.Type == c2.Type &&
+								c1.Relevance == c2.Relevance);
+			} else {
+				return false;
+			}
+		}
+
+		public static bool operator!=(Clue c1, Clue c2) {
+			return ! (c1 == c2);
+		}
+
+		public override bool Equals(object obj) {
+			if (!(obj is Clue)) {
+				return false;
+			}
+
+			return this == (Clue)obj;
+		}
+
+		// Provide an easy way to determine if this Clue contains anything.
+		public bool Exists() {
+		  Console.WriteLine ("Checking a Clue: {0}", this.ToString());
+			return this.Text != "";
+		}
 	}
 }
diff -u -r engine.orig/cluepacket.cs engine/cluepacket.cs
--- engine.orig/cluepacket.cs	2003-08-01 11:55:42.000000000 +1200
+++ engine/cluepacket.cs	2003-10-24 13:19:39.000000000 +1300
@@ -100,5 +100,95 @@
 
 			return copy;
 		}
+
+		// It's going to be useful to be able to check two CluePackets for
+		// equality.
+
+		// I'm not sure where Xid is coming from, or if it is actually			// every set (I'm not convinced that it is).  But we'll check
+		// that as well for equality.
+    public static bool operator==(CluePacket c1, CluePacket c2) {
+
+			// Check the simple stuff first.
+			if (Object.ReferenceEquals(c1, null) &&
+					Object.ReferenceEquals(c2, null)) {
+				// Well, if they're both null then this is true...
+				return true;
+			} else if (! (Object.ReferenceEquals(c1, null) ||
+					Object.ReferenceEquals(c2, null))	 &&
+					c1.Frontend == c2.Frontend && c1.Context == c2.Context &&
+					c1.Focused  == c2.Focused  && c1.Xid     == c2.Xid &&
+					c1.Clues.Count == c2.Clues.Count) {
+				// Both c1 and c2 have to NOT be null.
+
+				// We're guranteed that each Clue in Clues is going to be unique.
+				// And that the arrays are same length.  So, as soon as we find a
+				// Clue in c1 which doesn't exist in c2 they're not equal.  If we
+				// get to the end then they must be the same arrays.
+				foreach (Clue c in c1.Clues) {
+					if (! c2.Clues.Contains(c)) {
+						return false;
+					}
+				}
+
+				return true;
+			}
+
+			return false;
+		}
+
+		public static bool operator!=(CluePacket c1, CluePacket c2) {
+			return ! (c1 == c2);
+		}
+
+		public override bool Equals(object obj) {
+			if (!(obj is CluePacket)) {
+				return false;
+			}
+
+			return this == (CluePacket)obj;
+		}
+
+    public override int GetHashCode() {
+			int hash = this.Frontend.GetHashCode() + this.Context.GetHashCode() +
+				 + this.Xid;
+			
+			if (this.Focused)
+				hash += 1;
+		
+			foreach (Clue c in this.Clues)
+				hash += c.GetHashCode();
+
+			return hash;
+		}
+
+		// Add a clue to the array.  This allows us to enforce having only one
+		// copy of a Clue in a CluePacket.
+		//
+		// Once debugging is complete the redundant return falses, can be
+		// collapsed.
+		public bool AddClue(Clue c) {
+			if (c.Exists()) {
+				if (! this.Clues.Contains(c)) {
+					Console.WriteLine( "Add a Clue to a CluePacket." );
+					this.Clues.Add (c);
+					
+					return true;
+				} else {
+					Console.WriteLine( "Clue already exists in a CluePacket." );
+					
+					return false;
+				}
+			} else {
+				return false;
+			}
+		}
+
+    public bool Exists() {
+			if (this.Frontend == null || this.Frontend != "") {
+				return false;
+			}
+
+			return true;
+		}
 	}
 }	
diff -u -r engine.orig/cluepacket-manager.cs engine/cluepacket-manager.cs
--- engine.orig/cluepacket-manager.cs	2003-08-01 11:55:42.000000000 +1200
+++ engine/cluepacket-manager.cs	2003-10-24 13:18:16.000000000 +1300
@@ -110,6 +110,7 @@
 			// Send the matches to the match filter.
 			if (nmatches > 0) {
 				foreach (Match m in result.Matches) {
+					Console.WriteLine( "Sending matches to the match filter." );
 					match_filter.NotifyMatch (cp, m);
 				}
 			}
@@ -117,11 +118,19 @@
 			// Cluechain.
 			if (nclues > 0) {
 				CluePacket new_cp = new CluePacket (cp);
+				// Have an array of "Text:Type" to track what we've already seen.
+				// Use IndexOf to search it?
 				foreach (Clue new_clue in result.NewClues) {
-					new_cp.Clues.Add (new_clue);
+					new_cp.AddClue (new_clue);
 				}
 
-				RunQuery (new_cp);
+				if (new_cp != cp) {
+					Console.WriteLine( "Have a new CluePacket, time to do more work!");
+					RunQuery (new_cp);
+				} else {
+					Console.WriteLine( "This CluePacket is the same as the last one, why do more work?");
+				}
+				
 			}
 		}
 
diff -u -r engine.orig/gui.cs engine/gui.cs
--- engine.orig/gui.cs	2003-07-31 13:12:37.000000000 +1200
+++ engine/gui.cs	2003-10-15 13:09:28.000000000 +1300
@@ -184,7 +184,7 @@
 			this.ClearAtNextMatch = true;
 		}
 
-		public void Display (Match m)
+		new public void Display (Match m)
 		{
 			lock (this.match_queue) {
 				this.match_queue.Enqueue (m);

