Index: docs/reference/gobject/gobject-sections.txt
===================================================================
--- docs/reference/gobject/gobject-sections.txt	(revision 6891)
+++ docs/reference/gobject/gobject-sections.txt	(working copy)
@@ -296,6 +296,18 @@
 </SECTION>
 
 <SECTION>
+<FILE>gobjectbind</FILE>
+<TITLE>Property Binding</TITLE>
+GObjectBindingTransform
+g_object_bind
+g_object_bind_full
+g_object_unbind
+g_object_mutual_bind
+g_object_mutual_bind_full
+g_object_mutual_unbind
+</SECTION>
+
+<SECTION>
 <TITLE>Enumeration and Flag Types</TITLE>
 <FILE>enumerations_flags</FILE>
 GEnumClass
Index: docs/reference/gobject/gobject-docs.sgml
===================================================================
--- docs/reference/gobject/gobject-docs.sgml	(revision 6891)
+++ docs/reference/gobject/gobject-docs.sgml	(working copy)
@@ -5,6 +5,7 @@
 <!ENTITY gobject-GTypePlugin SYSTEM "xml/gtypeplugin.xml">
 <!ENTITY gobject-GTypeModule SYSTEM "xml/gtypemodule.xml">
 <!ENTITY gobject-The-Base-Object-Type SYSTEM "xml/objects.xml">
+<!ENTITY gobject-Property-Binding SYSTEM "xml/gobjectbind.xml">
 <!ENTITY gobject-Enumeration-and-Flag-Types SYSTEM "xml/enumerations_flags.xml">
 <!ENTITY gobject-Boxed-Types SYSTEM "xml/gboxed.xml">
 <!ENTITY gobject-Generic-values SYSTEM "xml/generic_values.xml">
@@ -92,6 +93,7 @@
       &gobject-GTypePlugin;
       &gobject-GTypeModule;
       &gobject-The-Base-Object-Type;
+      &gobject-Property-Binding;
       &gobject-Enumeration-and-Flag-Types;
       &gobject-Boxed-Types;
       &gobject-Generic-values;
Index: gobject/gobjectbind.c
===================================================================
--- gobject/gobjectbind.c	(revision 0)
+++ gobject/gobjectbind.c	(revision 0)
@@ -0,0 +1,627 @@
+/* GObject - GLib Type, Object, Parameter and Signal Library
+ * Copyright (c) 2004 Victor Porton (dead url: http://ex-code.com/~porton/)
+ * Copyright (c) 2004-2006 os-cillation e.K (Benedikt Meurer <benny@xfce.org>).
+ * Copyright (c) 2008 A. Walton <awalton@gnome.org> (GLib port).
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gobject.h"
+#include "gvalue.h"
+#include "gobjectbind.h"
+#include "gobjectalias.h"
+
+/**
+ * SECTION:gobjectbind
+ * @title: Property binding
+ * @short_description: Connects the values of properties together.
+ * 
+ * The purpose of this code is to expedite certain coding tasks, namely those 
+ * related to Model-View-Controller (MVC) programming which is used throughout 
+ * GObject code and higher-level toolkits such as Gtk+. In MVC programming, the model
+ * contains the data, the view displays the data, and the controller negotiates 
+ * between the model and view.
+ * 
+ * In the course of programming code that uses MVC, programmers are faced 
+ * with the task of writing controller code simply to connect one object (the model) 
+ * to another (the view), often simply setting the value of one property to 
+ * the value within another. GObject property binding replaces that process. 
+ * 
+ * Instead of having to manually connect signals and write a callback that 
+ * connects objects, possibly making coding and copy & paste mistakes, 
+ * programmers can use g_object_bind() or g_object_mutual_bind(), 
+ * depending on how the view and the model should interact, where the 
+ * former function creates a one-way binding and the latter creates 
+ * a bidirectional binding.
+ *
+ * A simple example of how this can be useful follows. 
+ * 
+ * |[
+ *   GtkWidget *button;
+ *   GtkWidget *entry;
+ *
+ *   button = gtk_check_button_new_with_label ("Activate");
+ *   entry = gtk_entry_new();
+ *   
+ *   g_object_bind (G_OBJECT (button), "active",
+ *                  G_OBJECT (entry), "sensitive");
+ * ]|
+ *
+ * In the above example, whenever the "active" property of the GtkCheckButton
+ * is changed, the GtkEntry's sensitivity is updated respectively, such that 
+ * when the button is active, the entry is active, and when the button is 
+ * inactive, the entry is likewise inactive. 
+ *
+ * It is not necessary to hold the #GObjectBinding for the link if you 
+ * never need to disconnect it for any reason during the lifetime of your 
+ * program. When one of the bound objects is finalized, the link will automatically
+ * be destroyed. If the link was created with g_object_bind_full() or 
+ * g_object_mutual_bind_full(), the user-provided destroy notify function will 
+ * be called for the link.
+ *
+ * Bindings work by automatically connecting to the "notify" signal on the 
+ * relevant properties. Keep in mind that this means property update propagation
+ * is not instantaneous and may not be thread-safe.
+ *
+ * Mutual binding creates a bidirectional link between two properties, 
+ * such that when either is updated, the other will likewise be updated.
+ * Binding is internally prevented from being recursive between objects, 
+ * so that binding multiple objects and properties in complex ways 
+ * is possible.
+ *
+ * g_object_bind_full() and g_object_mutual_bind_full() allow for more 
+ * complicated binding patterns. These functions allow you to specify 
+ * the transform function used while binding, so that the value can 
+ * be updated beyond that of simply casting one data type to another.
+ * An example of how you can use this to your advantage follows.
+ *
+ * |[
+ * static gboolean 
+ * celsius_to_fahrenheit (const GValue *src, GValue *dest, gpointer user_data)
+ * {
+ *   double celsius, fahrenheit;
+ *   
+ *   g_return_val_if_fail (G_VALUE_HOLDS_DOUBLE (src), FALSE);
+ *   g_return_val_if_fail (G_VALUE_HOLDS_DOUBLE (dest), FALSE);
+ *   
+ *   celsius = g_value_get_double (src);
+ *   fahrenheit = (9 * celsius / 5) + 32.0;
+ *   g_value_set_double (dest, fahrenheit);
+ * 
+ *   return TRUE;
+ * }
+ * 
+ * static gboolean
+ * fahrenheit_to_celsius (const GValue *src, GValue *dest, gpointer user_data)
+ * {
+ *   double celsius, fahrenheit;
+ *   
+ *   g_return_val_if_fail (G_VALUE_HOLDS_DOUBLE (src), FALSE);
+ *   g_return_val_if_fail (G_VALUE_HOLDS_DOUBLE (dest), FALSE);
+ * 
+ *   fahrenheit = g_value_get_double (src);
+ *   celsius = 5 * (fahrenheit - 32.0) / 9;
+ *   g_value_set_double (dest, celsius);
+ * 
+ *   return TRUE;
+ * }
+ * 
+ * /<!-- -->* ... *<!-- -->/
+ *
+ *   c_slider = gtk_hscale_new_with_range (0.0, 100.0, 1.0);
+ *   f_slider = gtk_hscale_new_with_range (32.0, 212.0, 1.0);
+ *
+ *   g_object_mutual_bind_full (G_OBJECT (gtk_range_get_adjustment (GTK_RANGE (c_slider))), "value",
+ *                              G_OBJECT (gtk_range_get_adjustment (GTK_RANGE (f_slider))), "value",
+ *                              (GObjectBindingTransform)celsius_to_fahrenheit,
+ *                              (GObjectBindingTransform)fahrenheit_to_celsius,
+ *                              NULL, NULL);
+ * /<!-- -->* ... *<!-- -->/
+ * ]|
+ * 
+ */
+
+typedef struct _GObjectBindingBase    GObjectBindingBase;
+typedef struct _GObjectBindingLink    GObjectBindingLink;
+
+struct _GObjectBindingBase
+{
+  GDestroyNotify  destroy;
+};
+
+struct _GObjectBindingLink
+{
+  GObject             *dst_object;
+  GParamSpec          *dst_pspec;
+  gulong               dst_handler; /* only set for mutual bindings */
+  gulong               handler;
+  GObjectBindingTransform  transform;
+  gpointer             user_data;
+};
+
+struct _GObjectBinding
+{
+  /*< private >*/
+  GObject         *src_object;
+  GObjectBindingBase   base;
+  GObjectBindingLink   link;
+};
+
+struct _GObjectMutualBinding
+{
+  /*< private >*/
+  GObjectBindingBase  base;
+  GObjectBindingLink  direct;
+  GObjectBindingLink  reverse;
+};
+
+static void
+g_object_bind_properties_transfer (GObject             *src_object,
+                                   GParamSpec          *src_pspec,
+                                   GObject             *dst_object,
+                                   GParamSpec          *dst_pspec,
+                                   GObjectBindingTransform  transform,
+                                   gpointer             user_data)
+{
+  const gchar *src_name;
+  const gchar *dst_name;
+  gboolean     result;
+  GValue       src_value = { 0, };
+  GValue       dst_value = { 0, };
+
+  src_name = g_param_spec_get_name (src_pspec);
+  dst_name = g_param_spec_get_name (dst_pspec);
+
+  g_value_init (&src_value, G_PARAM_SPEC_VALUE_TYPE (src_pspec));
+  g_object_get_property (src_object, src_name, &src_value);
+
+  g_value_init (&dst_value, G_PARAM_SPEC_VALUE_TYPE (dst_pspec));
+  result = (*transform) (&src_value, &dst_value, user_data);
+
+  g_value_unset (&src_value);
+
+  g_return_if_fail (result);
+
+  g_param_value_validate (dst_pspec, &dst_value);
+  g_object_set_property (dst_object, dst_name, &dst_value);
+  g_value_unset (&dst_value);
+}
+
+
+
+static void
+g_object_bind_properties_notify (GObject    *src_object,
+                                 GParamSpec *src_pspec,
+                                 gpointer    data)
+{
+  GObjectBindingLink *link = data;
+
+  /* block the destination handler for mutual bindings,
+   * so we don't recurse here.
+   */
+  if (link->dst_handler != 0)
+    g_signal_handler_block (link->dst_object, link->dst_handler);
+
+  g_object_bind_properties_transfer (src_object,
+                                src_pspec,
+                                link->dst_object,
+                                link->dst_pspec,
+                                link->transform,
+                                link->user_data);
+
+  /* unblock destination handler */
+  if (link->dst_handler != 0)
+    g_signal_handler_unblock (link->dst_object, link->dst_handler);
+}
+
+
+
+static void
+g_object_bind_on_dst_object_destroy (gpointer  data,
+                                     GObject  *object)
+{
+  GObjectBinding *binding = data;
+
+  binding->link.dst_object = NULL;
+
+  /* calls g_object_bind_on_disconnect() */
+  g_signal_handler_disconnect (binding->src_object, binding->link.handler);
+}
+
+
+
+static void
+g_object_bind_on_disconnect (gpointer  data,
+                             GClosure *closure)
+{
+  GObjectBindingLink *link = data;
+  GObjectBinding     *binding;
+
+  binding = (GObjectBinding *) (((gchar *) link) - G_STRUCT_OFFSET (GObjectBinding, link));
+
+  if (binding->base.destroy != NULL)
+    binding->base.destroy (link->user_data);
+
+  if (link->dst_object != NULL)
+    g_object_weak_unref (link->dst_object, g_object_bind_on_dst_object_destroy, binding);
+
+  g_slice_free (GObjectBinding, binding);
+}
+
+
+
+/* recursively calls g_object_mutual_bind_on_disconnect_object2() */
+static void
+g_object_mutual_bind_on_disconnect_object1 (gpointer  data,
+                                            GClosure *closure)
+{
+  GObjectMutualBinding *binding;
+  GObjectBindingLink   *link = data;
+  GObject          *object2;
+
+  binding = (GObjectMutualBinding *) (((gchar *) link) - G_STRUCT_OFFSET (GObjectMutualBinding, direct));
+  binding->reverse.dst_object = NULL;
+
+  object2 = binding->direct.dst_object;
+  if (object2 != NULL)
+    {
+      if (binding->base.destroy != NULL)
+        binding->base.destroy (binding->direct.user_data);
+      binding->direct.dst_object = NULL;
+      g_signal_handler_disconnect (object2, binding->reverse.handler);
+      g_slice_free (GObjectMutualBinding, binding);
+    }
+}
+
+
+
+/* recursively calls g_object_mutual_bind_on_disconnect_object1() */
+static void
+g_object_mutual_bind_on_disconnect_object2 (gpointer  data,
+                                            GClosure *closure)
+{
+  GObjectMutualBinding *binding;
+  GObjectBindingLink   *link = data;
+  GObject          *object1;
+
+  binding = (GObjectMutualBinding *) (((gchar *) link) - G_STRUCT_OFFSET (GObjectMutualBinding, reverse));
+  binding->direct.dst_object = NULL;
+
+  object1 = binding->reverse.dst_object;
+  if (object1 != NULL)
+    {
+      binding->reverse.dst_object = NULL;
+      g_signal_handler_disconnect (object1, binding->direct.handler);
+    }
+}
+
+
+
+static void
+g_object_bind_link_init (GObjectBindingLink     *link,
+                         GObject            *src_object,
+                         const gchar        *src_property,
+                         GObject            *dst_object,
+                         GParamSpec         *dst_pspec,
+                         GObjectBindingTransform transform,
+                         GClosureNotify      destroy_notify,
+                         gpointer            user_data)
+{
+  gchar *signal_name;
+
+  link->dst_object  = dst_object;
+  link->dst_pspec   = dst_pspec;
+  link->dst_handler = 0;
+  link->transform   = transform;
+  link->user_data   = user_data;
+
+  signal_name = g_strconcat ("notify::", src_property, NULL);
+  link->handler = g_signal_connect_data (src_object,
+                                         signal_name,
+                                         G_CALLBACK (g_object_bind_properties_notify),
+                                         link,
+                                         destroy_notify,
+                                         0);
+  g_free (signal_name);
+}
+
+
+
+/**
+ * g_object_bind:
+ * @src_object: The source #GObject.
+ * @src_property: The name of the property to bind from.
+ * @dst_object: The destination #GObject.
+ * @dst_property: The name of the property to bind to.
+ *
+ * One-way binds @src_property in @src_object to @dst_property
+ * in @dst_object.
+ *
+ * Before binding the value of @dst_property is set to the
+ * value of @src_property.
+ *
+ * Returns: The descriptor of the binding. It is automatically
+ *     destroyed if one of the objects is finalized.
+ *
+ * Since: 2.14
+ **/
+GObjectBinding*
+g_object_bind (GObject      *src_object,
+               const gchar  *src_property,
+               GObject      *dst_object,
+               const gchar  *dst_property)
+{
+  return g_object_bind_full (src_object, src_property,
+                             dst_object, dst_property,
+                             NULL, NULL, NULL);
+}
+
+
+
+/**
+ * g_object_bind_full:
+ * @src_object: The source #GObject.
+ * @src_property: The name of the property to bind from.
+ * @dst_object: The destination #GObject.
+ * @dst_property: The name of the property to bind to.
+ * @transform: Transformation function or %NULL.
+ * @destroy_notify: Callback function that is called on
+ *   disconnection with @user_data or %NULL.
+ * @user_data: User data associated with the binding.
+ *
+ * One-way binds @src_property in @src_object to @dst_property
+ * in @dst_object.
+ *
+ * Before binding the value of @dst_property is set to the
+ * value of @src_property. 
+ * 
+ * If the transform function is non-%NULL, the function will be called
+ * to transform the value from one property to the other.  If %NULL, 
+ * the binding transform function will be g_value_transform().
+ *
+ * Returns: The descriptor of the binding. It is automatically
+ *      destroyed if one of the objects is finalized.
+ *
+ * Since: 2.14
+ **/
+GObjectBinding*
+g_object_bind_full (GObject            *src_object,
+                    const gchar        *src_property,
+                    GObject            *dst_object,
+                    const gchar        *dst_property,
+                    GObjectBindingTransform transform,
+                    GDestroyNotify      destroy_notify,
+                    gpointer            user_data)
+{
+  GObjectBinding  *binding;
+  GParamSpec  *src_pspec;
+  GParamSpec  *dst_pspec;
+
+  g_return_val_if_fail (G_IS_OBJECT (src_object), NULL);
+  g_return_val_if_fail (G_IS_OBJECT (dst_object), NULL);
+  g_return_val_if_fail (src_property != NULL, NULL);
+  g_return_val_if_fail (dst_property != NULL, NULL);
+
+  src_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (src_object), src_property);
+  dst_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (dst_object), dst_property);
+
+  if (transform == NULL)
+    transform = (GObjectBindingTransform) g_value_transform;
+
+  g_object_bind_properties_transfer (src_object,
+                                src_pspec,
+                                dst_object,
+                                dst_pspec,
+                                transform,
+                                user_data);
+
+  binding = g_slice_new (GObjectBinding);
+  binding->src_object = src_object;
+  binding->base.destroy = destroy_notify;
+
+  g_object_bind_link_init (&binding->link,
+                         src_object,
+                         src_property,
+                         dst_object,
+                         dst_pspec,
+                         transform,
+                         g_object_bind_on_disconnect,
+                         user_data);
+
+  g_object_weak_ref (dst_object, g_object_bind_on_dst_object_destroy, binding);
+
+  return binding;
+}
+
+/**
+ * g_object_unbind:
+ * @binding: An #GObjectBinding to unbind.
+ *
+ * Disconnects the binding between two properties. Should be
+ * rarely used by applications; the binding will automatically
+ * be destroyed when the objects are destroyed.
+ *
+ * This functions also calls the @destroy_notify function that
+ * was specified when @binding was created.
+ *
+ * Since: 2.14
+ **/
+void
+g_object_unbind (GObjectBinding *binding)
+{
+  g_signal_handler_disconnect (binding->src_object, binding->link.handler);
+}
+
+/**
+ * g_object_mutual_bind:
+ * @object1: The first #GObject.
+ * @property1: The first property to bind.
+ * @object2: The second #GObject.
+ * @property2: The second property to bind.
+ *
+ * Mutually binds values of two properties, i.e. when the value of 
+ * @property1 is changed, @property2 is updated and visa-versa.
+ * The value for both properties will be transformed using 
+ * g_value_transform(). 
+ *
+ * Before binding the value of @property2 is set to the value
+ * of @property1.
+ *
+ * Returns: The descriptor of the binding. It is automatically
+ *     destroyed if one of the objects is finalized.
+ *
+ * Since: 2.14
+ **/
+GObjectMutualBinding*
+g_object_mutual_bind (GObject     *object1,
+                      const gchar *property1,
+                      GObject     *object2,
+                      const gchar *property2)
+{
+  return g_object_mutual_bind_full (object1, property1,
+                                    object2, property2,
+                                    NULL, NULL, NULL, NULL);
+}
+
+/**
+ * g_object_mutual_bind_full:
+ * @object1: The first #GObject.
+ * @property1: The first property to bind.
+ * @object2: The second #GObject.
+ * @property2: The second property to bind.
+ * @transform: Transformation function or %NULL.
+ * @reverse_transform: The inverse transformation function or %NULL.
+ * @destroy_notify: Callback function called on disconnection with
+ *     @user_data as argument or %NULL.
+ * @user_data: User data associated with the binding.
+ *
+ * Mutually binds values of two properties, i.e. when the value of 
+ * @property1 is changed, @property2 is updated and visa-versa. 
+ * The value for @property2 will be set using the @transform 
+ * function, whereas the value for @property1 will be set using 
+ * @reverse_transform. @transform and @reverse_transform should
+ * usually be inverse functions. Keep in mind that the properties
+ * may not be instantaneously updated.
+ *
+ * Before binding, the value of @property2 is set to the value of
+ * @property1.
+ *
+ * Both @transform and @reverse_transform should simultaneously be
+ * %NULL or non-%NULL. If %NULL, both binding transform functions will 
+ * be g_value_transform().
+ *
+ * Returns: The descriptor of the binding. It is automatically
+ *     destroyed if one of the objects is finalized.
+ *
+ * Since: 2.14
+ **/
+GObjectMutualBinding*
+g_object_mutual_bind_full (GObject            *object1,
+                           const gchar        *property1,
+                           GObject            *object2,
+                           const gchar        *property2,
+                           GObjectBindingTransform transform,
+                           GObjectBindingTransform reverse_transform,
+                           GDestroyNotify      destroy_notify,
+                           gpointer            user_data)
+{
+  GObjectMutualBinding  *binding;
+  GParamSpec        *pspec1;
+  GParamSpec        *pspec2;
+
+  g_return_val_if_fail (G_IS_OBJECT (object1), NULL);
+  g_return_val_if_fail (G_IS_OBJECT (object2), NULL);
+  g_return_val_if_fail (property1 != NULL, NULL);
+  g_return_val_if_fail (property2 != NULL, NULL);
+
+  pspec1 = g_object_class_find_property (G_OBJECT_GET_CLASS (object1), property1);
+  pspec2 = g_object_class_find_property (G_OBJECT_GET_CLASS (object2), property2);
+
+  if (G_UNLIKELY (transform != NULL && reverse_transform == NULL))
+    g_warning ("Transform is set, but Reverse Transform is NULL.\n"
+               "This is most likely a coding error.");
+
+  if (G_UNLIKELY (transform == NULL && reverse_transform != NULL))
+    g_warning ("Transform is NULL, but Reverse Transform is set.\n"
+               "This is most likely a coding error.");
+
+  if (transform == NULL)
+    transform = (GObjectBindingTransform) g_value_transform;
+
+  if (reverse_transform == NULL)
+    reverse_transform = (GObjectBindingTransform) g_value_transform;
+
+  g_object_bind_properties_transfer (object1,
+                                pspec1,
+                                object2,
+                                pspec2,
+                                transform,
+                                user_data);
+
+  binding = g_slice_new0 (GObjectMutualBinding);
+  binding->base.destroy = destroy_notify;
+
+  g_object_bind_link_init (&binding->direct,
+                         object1,
+                         property1,
+                         object2,
+                         pspec2,
+                         transform,
+                         g_object_mutual_bind_on_disconnect_object1,
+                         user_data);
+
+  g_object_bind_link_init (&binding->reverse,
+                         object2,
+                         property2,
+                         object1,
+                         pspec1,
+                         reverse_transform,
+                         g_object_mutual_bind_on_disconnect_object2,
+                         user_data);
+
+  /* tell each link about the reverse link for mutual
+   * bindings, to make sure that we do not ever recurse
+   * in notify (yeah, the GObject notify dispatching is
+   * really weird!).
+   */
+  binding->direct.dst_handler = binding->reverse.handler;
+  binding->reverse.dst_handler = binding->direct.handler;
+
+  return binding;
+}
+
+
+/**
+ * g_object_mutual_unbind:
+ * @binding: An #GObjectMutualBinding to unbind.
+ *
+ * Disconnects the binding between two properties. Should be
+ * rarely used by applications; the binding will automatically
+ * be destroyed when either of the objects is destroyed.
+ *
+ * This functions also calls the @destroy_notify function that
+ * was specified when @binding was created.
+ *
+ * Since: 2.14
+ **/
+void
+g_object_mutual_unbind (GObjectMutualBinding *binding)
+{
+  g_signal_handler_disconnect (binding->direct.dst_object, binding->direct.handler);
+}
+
+#define __G_OBJECT_BIND_C__
+#include "gobjectaliasdef.c"
Index: gobject/gobjectbind.h
===================================================================
--- gobject/gobjectbind.h	(revision 0)
+++ gobject/gobjectbind.h	(revision 0)
@@ -0,0 +1,101 @@
+/* GObject - GLib Type, Object, Parameter and Signal Library
+ * Copyright (c) 2004 Victor Porton (dead url: http://ex-code.com/~porton/)
+ * Copyright (c) 2004-2006 os-cillation e.K (Benedikt Meurer <benny@xfce.org>).
+ * Copyright (c) 2008 A. Walton <awalton@gnome.org> (GLib port).
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION)
+#error "Only <glib-object.h> can be included directly."
+#endif
+
+#ifndef __G_OBJECT_BIND_H__
+#define __G_OBJECT_BIND_H__
+
+#include <gobject/gobject.h>
+#include <gobject/gvalue.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GObjectBinding:
+ *
+ * Opaque structure holding a one-way binding. 
+ */
+typedef struct _GObjectBinding        GObjectBinding;
+
+/**
+ * GObjectMutualBinding:
+ * 
+ * Opaque structure holding a bi-directional binding. 
+ */
+typedef struct _GObjectMutualBinding  GObjectMutualBinding;
+
+/**
+ * GObjectBindingTransform:
+ * @src_value: #GValue to transform from.
+ * @dst_value: #GValue to store the transform result in.
+ * @user_data: data passed to the transform function
+ *
+ * Tries to transform the contents of @src_value into a type appropriate to store in 
+ * @dst_value, e.g. to transform a %G_TYPE_INT value into a %G_TYPE_FLOAT value.
+ *
+ * Performing transformations between value types might incur precision lossage. 
+ * Especially transformations into strings might reveal seemingly arbitrary 
+ * results and shouldn't be relied upon for production code 
+ * (such as rcfile value or object property serialization).
+ *
+ * Both @src_value and @dst_value are initialized before this function is called.
+ *
+ * Returns: %TRUE if the transform was successfully applied, %FALSE otherwise.
+ *     Upon failing the @dst_value is left untouched.
+ * Since: 2.14
+ */
+typedef gboolean  (*GObjectBindingTransform)  (const GValue *src_value,
+                                                GValue       *dst_value,
+                                                gpointer      user_data);
+
+GObjectBinding        *g_object_bind                    (GObject            *src_object,
+                                                         const gchar        *src_property,
+                                                         GObject            *dst_object,
+                                                         const gchar        *dst_property);
+GObjectBinding        *g_object_bind_full               (GObject            *src_object,
+                                                         const gchar        *src_property,
+                                                         GObject            *dst_object,
+                                                         const gchar        *dst_property,
+                                                         GObjectBindingTransform transform,
+                                                         GDestroyNotify      destroy_notify,
+                                                         gpointer            user_data);
+void                   g_object_unbind                  (GObjectBinding     *binding);
+
+GObjectMutualBinding  *g_object_mutual_bind             (GObject            *object1,
+                                                         const gchar        *property1,
+                                                         GObject            *object2,
+                                                         const gchar        *property2);
+GObjectMutualBinding  *g_object_mutual_bind_full        (GObject            *object1,
+                                                         const gchar        *property1,
+                                                         GObject            *object2,
+                                                         const gchar        *property2,
+                                                         GObjectBindingTransform transform,
+                                                         GObjectBindingTransform reverse_transform,
+                                                         GDestroyNotify      destroy_notify,
+                                                         gpointer            user_data);
+void                   g_object_mutual_unbind           (GObjectMutualBinding   *binding);
+
+G_END_DECLS
+
+#endif /* !__G_OBJECT_BIND_H__ */
Index: gobject/gobject.symbols
===================================================================
--- gobject/gobject.symbols	(revision 6891)
+++ gobject/gobject.symbols	(working copy)
@@ -428,6 +428,17 @@
 #endif
 #endif
 
+#if IN_HEADER(__G_OBJECT_BIND_H__)
+#if IN_FILE(__G_OBJECT_BIND_C__)
+g_object_bind
+g_object_bind_full
+g_object_unbind
+g_object_mutual_bind
+g_object_mutual_bind_full
+g_object_mutual_unbind
+#endif
+#endif
+
 #ifdef INCLUDE_VARIABLES
 g_param_spec_types
 #endif
Index: gobject/Makefile.am
===================================================================
--- gobject/Makefile.am	(revision 6891)
+++ gobject/Makefile.am	(working copy)
@@ -95,6 +95,7 @@
 	gclosure.h		\
 	genums.h		\
 	gobject.h		\
+	gobjectbind.h 		\
 	gparam.h		\
 	gparamspecs.h		\
 	gsignal.h		\
@@ -117,6 +118,7 @@
 	gclosure.c		\
 	genums.c		\
 	gobject.c		\
+	gobjectbind.c		\
 	gparam.c		\
 	gparamspecs.c		\
 	gsignal.c		\
Index: glib/glib-object.h
===================================================================
--- glib/glib-object.h	(revision 6891)
+++ glib/glib-object.h	(working copy)
@@ -25,6 +25,7 @@
 #include	<gobject/gboxed.h>
 #include	<gobject/genums.h>
 #include	<gobject/gobject.h>
+#include 	<gobject/gobjectbind.h>
 #include	<gobject/gparam.h>
 #include	<gobject/gparamspecs.h>
 #include	<gobject/gsignal.h>
