Index: glib/gsequence.c
===================================================================
--- glib/gsequence.c	(revision 7371)
+++ glib/gsequence.c	(working copy)
@@ -63,6 +63,11 @@
 static gint           node_get_pos       (GSequenceNode            *node);
 static GSequenceNode *node_get_by_pos    (GSequenceNode            *node,
                                           gint                      pos);
+static GSequenceNode *node_find          (GSequenceNode            *haystack,
+                                          GSequenceNode            *needle,
+                                          GSequenceNode            *end,
+                                          GSequenceIterCompareFunc  cmp,
+                                          gpointer                  user_data);
 static GSequenceNode *node_find_closest  (GSequenceNode            *haystack,
                                           GSequenceNode            *needle,
                                           GSequenceNode            *end,
@@ -710,6 +715,43 @@
 }
 
 /**
+ * g_sequence_find:
+ * @seq: a #GSequence
+ * @data: data for the new item
+ * @cmp_func: the #GCompareDataFunc used to compare items in the sequence. It
+ *     is called with two items of the @seq and @user_data. It should
+ *     return 0 if the items are equal, a negative value if the first
+ *     item comes before the second, and a positive value if the second
+ *     item comes before the first.
+ * @cmp_data: user data passed to @cmp_func.
+ *
+ * Returns an iterator pointing to the position of @data in @seq.
+ *
+ * Return value: a #GSequenceIter pointing to the position in @seq
+ * which contains @data or NULL if data was not found in @seq.
+ *
+ * Since: 2.18
+ **/
+GSequenceIter *
+g_sequence_find (GSequence        *seq,
+                 gpointer          data,
+                 GCompareDataFunc  cmp_func,
+                 gpointer          cmp_data)
+{
+  SortInfo info;
+
+  g_return_val_if_fail (seq != NULL, NULL);
+  
+  info.cmp_func = cmp_func;
+  info.cmp_data = cmp_data;
+  info.end_node = seq->end_node;
+  check_seq_access (seq);
+  
+  return g_sequence_find_iter (seq, data, iter_compare, &info);
+}
+
+
+/**
  * g_sequence_sort_iter:
  * @seq: a #GSequence
  * @cmp_func: the #GSequenceItercompare used to compare iterators in the
@@ -937,6 +979,58 @@
 }
 
 /**
+ * g_sequence_find_iter:
+ * @seq: a #GSequence
+ * @data: data for the new item
+ * @iter_cmp: the #GSequenceIterCompare function used to compare iterators
+ *     in the sequence. It is called with two iterators pointing into @seq.
+ *     It should return 0 if the iterators are equal, a negative value if the
+ *     first iterator comes before the second, and a positive value if the
+ *     second iterator comes before the first.
+ * @cmp_data: user data passed to @iter_cmp
+ *
+ * Like g_sequence_find(), but uses
+ * a #GSequenceIterCompareFunc instead of a #GCompareDataFunc as
+ * the compare function.
+ * 
+ * Return value: a #GSequenceIter pointing to the position in @seq
+ * which contains @data or NULL if data was not found in @seq.
+ * 
+ * Since: 2.18
+ **/
+GSequenceIter *
+g_sequence_find_iter (GSequence                *seq,
+                      gpointer                  data,
+                      GSequenceIterCompareFunc  iter_cmp,
+                      gpointer                  cmp_data)
+{
+  GSequenceNode *node;
+  GSequenceNode *dummy;
+  GSequence *tmp_seq;
+  
+  g_return_val_if_fail (seq != NULL, NULL);
+  
+  check_seq_access (seq);
+  
+  seq->access_prohibited = TRUE;
+
+  tmp_seq = g_sequence_new (NULL);
+  tmp_seq->real_sequence = seq;
+  
+  dummy = g_sequence_append (tmp_seq, data);
+  
+  node = node_find (seq->end_node, dummy,
+                    seq->end_node, iter_cmp, cmp_data);
+
+  g_sequence_free (tmp_seq);
+  
+  seq->access_prohibited = FALSE;
+  
+  return node;
+}
+
+
+/**
  * g_sequence_iter_get_sequence:
  * @iter: a #GSequenceIter
  * 
@@ -1479,6 +1573,48 @@
 }
 
 static GSequenceNode *
+node_find (GSequenceNode            *haystack,
+           GSequenceNode            *needle,
+           GSequenceNode            *end,
+           GSequenceIterCompareFunc  iter_cmp,
+           gpointer                  cmp_data)
+{
+  GSequenceNode *best;
+  gint c;
+  
+  haystack = find_root (haystack);
+  
+  do
+    {
+      best = haystack;
+      
+      /* iter_cmp can't be passed the end node, since the function may
+       * be user-supplied
+       */
+      if (haystack == end)
+        c = 1;
+      else
+        c = iter_cmp (haystack, needle, cmp_data);
+      
+      /* In the following we don't break even if c == 0. Instaed we go on
+       * searching along the 'bigger' nodes, so that we find the last one
+       * that is equal to the needle.
+       */
+      if (c > 0)
+        haystack = haystack->left;
+      else
+        haystack = haystack->right;
+    }
+  while (haystack != NULL && c != 0);
+
+  /* If it's a match, return it */
+  if (c == 0)
+    return best;
+  else
+    return NULL;
+}
+
+static GSequenceNode *
 node_find_closest (GSequenceNode            *haystack,
                    GSequenceNode            *needle,
                    GSequenceNode            *end,
Index: glib/tests/Makefile.am
===================================================================
--- glib/tests/Makefile.am	(revision 7371)
+++ glib/tests/Makefile.am	(working copy)
@@ -32,6 +32,9 @@
 TEST_PROGS         += array-test
 array_test_LDADD    = $(progs_ldadd)
 
+TEST_PROGS             += gsequence-test
+gsequence_test_LDADD    = $(progs_ldadd)
+
 # some testing of gtester funcitonality
 XMLLINT=xmllint
 gtester-xmllint-check: # check testreport xml with xmllint if present
Index: glib/gsequence.h
===================================================================
--- glib/gsequence.h	(revision 7371)
+++ glib/gsequence.h	(working copy)
@@ -99,8 +99,15 @@
                                               gpointer                  data,
                                               GSequenceIterCompareFunc  iter_cmp,
                                               gpointer                  cmp_data);
+GSequenceIter *g_sequence_find               (GSequence        *seq,
+                                              gpointer          data,
+                                              GCompareDataFunc  cmp_func,
+                                              gpointer          cmp_data);
+GSequenceIter *g_sequence_find_iter          (GSequence                *seq,
+                                              gpointer                  data,
+                                              GSequenceIterCompareFunc  iter_cmp,
+                                              gpointer                  cmp_data);
 
-
 /* Dereferencing */
 gpointer       g_sequence_get                (GSequenceIter            *iter);
 void           g_sequence_set                (GSequenceIter            *iter,
