Index: src/Libraries/Hyena/Hyena/Tests/StringUtilTests.cs
===================================================================
--- src/Libraries/Hyena/Hyena/Tests/StringUtilTests.cs	(revision 5046)
+++ src/Libraries/Hyena/Hyena/Tests/StringUtilTests.cs	(working copy)
@@ -224,17 +224,6 @@
             AssertSearchKey ("\u00f8", "o");
             AssertSearchKey ("\u0142", "l");
         }
-        
-        // Test that some kinds of punctuation are removed.
-        [Test]
-        public void TestRemovePunctuation ()
-        {
-            AssertSearchKey ("'", "");
-            AssertSearchKey ("\"", "");
-            AssertSearchKey ("!", "");
-            AssertSearchKey ("?", "");
-            AssertSearchKey ("/", "");
-        }
     }
 
     [TestFixture]
Index: src/Libraries/Hyena/Hyena/StringUtil.cs
===================================================================
--- src/Libraries/Hyena/Hyena/StringUtil.cs	(revision 5046)
+++ src/Libraries/Hyena/Hyena/StringUtil.cs	(working copy)
@@ -192,8 +192,6 @@
 
                 if (ignored_special_cases.ContainsKey (c)) {
                     sb.Append (ignored_special_cases[c]);
-                } else if (category == UnicodeCategory.OtherPunctuation) {
-                    // Skip punctuation
                 } else if (!(previous_was_latin && category == UnicodeCategory.NonSpacingMark)) {
                     sb.Append (c);
                 }
Index: src/Libraries/Hyena/Hyena.Query/ExactStringQueryValue.cs
===================================================================
--- src/Libraries/Hyena/Hyena.Query/ExactStringQueryValue.cs	(revision 5046)
+++ src/Libraries/Hyena/Hyena.Query/ExactStringQueryValue.cs	(working copy)
@@ -33,7 +33,7 @@
     {
         public override string ToSql (Operator op)
         {
-            return String.IsNullOrEmpty (value) ? null : value.Replace ("'", "''").ToLower ();
+            return String.IsNullOrEmpty (value) ? null : Escape (op, value).ToLower ();
         }
     }
 }
Index: src/Libraries/Hyena/Hyena.Query/StringQueryValue.cs
===================================================================
--- src/Libraries/Hyena/Hyena.Query/StringQueryValue.cs	(revision 5046)
+++ src/Libraries/Hyena/Hyena.Query/StringQueryValue.cs	(working copy)
@@ -84,25 +84,23 @@
             if (String.IsNullOrEmpty (value))
                 return null;
 
-            string ret = null;
+            return Escape (op, Hyena.StringUtil.SearchKey (value));
+        }
 
-            // SearchKey() removes ' anyway, but it's escaped again so proper
-            // SQL behavior isn't dependent on search behavior.
-            ret = Hyena.StringUtil.SearchKey (value).Replace ("'", "''");
+        protected static string Escape (Operator op, string orig)
+        {
+             return EscapeLike (op, orig.Replace ("'", "''"));
+        }
 
+        private static string EscapeLike (Operator op, string orig)
+        {
             if (op == Contains   || op == DoesNotContain ||
                 op == StartsWith || op == EndsWith) {
-                ret = EscapeLike (ret);
+                return orig.Replace ("\\", "\\\\")
+                           .Replace ("%", "\\%")
+                           .Replace ("_", "\\_");
             }
-
-            return ret;
+            return orig;
         }
-
-        private static string EscapeLike (string orig)
-        {
-            return orig.Replace ("\\", "\\\\")
-                       .Replace ("%", "\\%")
-                       .Replace ("_", "\\_");
-        }
     }
 }
Index: src/Libraries/Hyena/Hyena.Query/Tests/QueryTests.cs
===================================================================
--- src/Libraries/Hyena/Hyena.Query/Tests/QueryTests.cs	(revision 5046)
+++ src/Libraries/Hyena/Hyena.Query/Tests/QueryTests.cs	(working copy)
@@ -153,12 +153,60 @@
             val.ParseUserQuery ("mp3");
     
             Assert.AreEqual (
-                "(CoreTracks.MimeType LIKE '%mp3%' OR CoreTracks.Uri LIKE '%mp3%')",
+                "(CoreTracks.MimeType LIKE '%mp3%' ESCAPE '\\' OR CoreTracks.Uri LIKE '%mp3%' ESCAPE '\\')",
                 MimeTypeField.ToSql (StringQueryValue.Contains, val)
             );
         }
-		
+
         [Test]
+        public void EscapeSingleQuotes ()
+        {
+            QueryValue val = new StringQueryValue ();
+            val.ParseUserQuery ("Kelli O'Hara");
+
+            Assert.AreEqual (
+                "(CoreArtists.NameLowered LIKE '%kelli o''hara%' ESCAPE '\\' AND CoreArtists.NameLowered IS NOT NULL)",
+                ArtistField.ToSql (StringQueryValue.Contains, val)
+            );
+        }
+
+        [Test] // http://bugzilla.gnome.org/show_bug.cgi?id=570312
+        public void EscapeSqliteWildcards1 ()
+        {
+            QueryValue val = new StringQueryValue ();
+            val.ParseUserQuery ("100% Techno");
+
+            Assert.AreEqual (
+                "(CoreAlbums.TitleLowered LIKE '%100\\% techno%' ESCAPE '\\' AND CoreAlbums.TitleLowered IS NOT NULL)",
+                AlbumField.ToSql (StringQueryValue.Contains, val)
+            );
+        }
+
+        [Test] // http://bugzilla.gnome.org/show_bug.cgi?id=570312
+        public void EscapeSqliteWildcards2 ()
+        {
+            QueryValue val = new StringQueryValue ();
+            val.ParseUserQuery ("-_-");
+
+            Assert.AreEqual (
+                "(CoreAlbums.TitleLowered LIKE '%-\\_-%' ESCAPE '\\' AND CoreAlbums.TitleLowered IS NOT NULL)",
+                AlbumField.ToSql (StringQueryValue.Contains, val)
+            );
+        }
+
+        [Test] // http://bugzilla.gnome.org/show_bug.cgi?id=570312
+        public void EscapeSqliteWildcards3 ()
+        {
+            QueryValue val = new StringQueryValue ();
+            val.ParseUserQuery ("Metallic/\\");
+
+            Assert.AreEqual (
+                "(CoreAlbums.TitleLowered LIKE '%metallic/\\\\%' ESCAPE '\\' AND CoreAlbums.TitleLowered IS NOT NULL)",
+                AlbumField.ToSql (StringQueryValue.Contains, val)
+            );
+        }
+
+        [Test]
         // Test behavior issues described in
         // http://bugzilla.gnome.org/show_bug.cgi?id=547078
         public void ParenthesesInQuotes ()
