diff --git a/examples/Makefile.am b/examples/Makefile.am
index 80602a2f4..b83468b4b 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -1,6 +1,7 @@
 include $(top_srcdir)/build/autotools/Makefile.am.silent
 
 all_examples = \
+	actor-model \
 	basic-actor \
 	box-layout \
 	canvas \
diff --git a/examples/actor-model.c b/examples/actor-model.c
new file mode 100644
index 000000000..f87fc64d9
--- /dev/null
+++ b/examples/actor-model.c
@@ -0,0 +1,442 @@
+#include <glib-object.h>
+#include <gio/gio.h>
+#include <clutter/clutter.h>
+
+/* {{{ MenuItem */
+#define EXAMPLE_TYPE_MENU_ITEM  (example_menu_item_get_type ())
+
+G_DECLARE_FINAL_TYPE (ExampleMenuItem, example_menu_item, EXAMPLE, MENU_ITEM, ClutterText)
+
+struct _ExampleMenuItem
+{
+  ClutterText parent_instance;
+
+  gboolean is_selected;
+};
+
+struct _ExampleMenuItemClass
+{
+  ClutterTextClass parent_class;
+};
+
+G_DEFINE_TYPE (ExampleMenuItem, example_menu_item, CLUTTER_TYPE_TEXT)
+
+enum {
+  MENU_ITEM_PROP_SELECTED = 1,
+  MENU_ITEM_N_PROPS
+};
+
+static GParamSpec *menu_item_props[MENU_ITEM_N_PROPS] = { NULL, };
+
+static void
+example_menu_item_set_selected (ExampleMenuItem *self,
+                                gboolean         selected)
+{
+  selected = !!selected;
+  if (self->is_selected == selected)
+    return;
+
+  self->is_selected = selected;
+
+  if (self->is_selected)
+    clutter_text_set_color (CLUTTER_TEXT (self), CLUTTER_COLOR_LightSkyBlue);
+  else
+    clutter_text_set_color (CLUTTER_TEXT (self), CLUTTER_COLOR_White);
+
+  g_object_notify_by_pspec (G_OBJECT (self), menu_item_props[MENU_ITEM_PROP_SELECTED]);
+}
+
+static void
+example_menu_item_set_property (GObject      *gobject,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+  switch (prop_id)
+    {
+    case MENU_ITEM_PROP_SELECTED:
+      example_menu_item_set_selected (EXAMPLE_MENU_ITEM (gobject),
+                                      g_value_get_boolean (value));
+      break;
+    }
+}
+
+static void
+example_menu_item_get_property (GObject    *gobject,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+  switch (prop_id)
+    {
+    case MENU_ITEM_PROP_SELECTED:
+      g_value_set_boolean (value, EXAMPLE_MENU_ITEM (gobject)->is_selected);
+      break;
+    }
+}
+
+static void
+example_menu_item_class_init (ExampleMenuItemClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->set_property = example_menu_item_set_property;
+  gobject_class->get_property = example_menu_item_get_property;
+
+  menu_item_props[MENU_ITEM_PROP_SELECTED] =
+    g_param_spec_boolean ("selected", NULL, NULL,
+                          FALSE,
+                          G_PARAM_READWRITE |
+                          G_PARAM_STATIC_STRINGS);
+
+  g_object_class_install_properties (gobject_class, MENU_ITEM_N_PROPS, menu_item_props);
+}
+
+static void
+example_menu_item_init (ExampleMenuItem *self)
+{
+  ClutterText *text = CLUTTER_TEXT (self);
+  ClutterActor *actor = CLUTTER_ACTOR (self);
+
+  clutter_text_set_font_name (text, "Sans Bold 24px");
+  clutter_text_set_color (text, CLUTTER_COLOR_White);
+
+  clutter_actor_set_margin_left (actor, 12);
+  clutter_actor_set_margin_right (actor, 12);
+}
+
+/* }}} */
+
+/* {{{ Menu */
+#define EXAMPLE_TYPE_MENU       (example_menu_get_type ())
+
+G_DECLARE_FINAL_TYPE (ExampleMenu, example_menu, EXAMPLE, MENU, ClutterActor)
+
+struct _ExampleMenu
+{
+  ClutterActor parent_instance;
+
+  int current_idx;
+};
+
+struct _ExampleMenuClass
+{
+  ClutterActorClass parent_class;
+};
+
+G_DEFINE_TYPE (ExampleMenu, example_menu, CLUTTER_TYPE_ACTOR)
+
+static void
+example_menu_class_init (ExampleMenuClass *klass)
+{
+}
+
+static void
+example_menu_init (ExampleMenu *self)
+{
+  ClutterActor *actor = CLUTTER_ACTOR (self);
+  ClutterLayoutManager *layout;
+
+  layout = clutter_box_layout_new ();
+  clutter_box_layout_set_orientation (CLUTTER_BOX_LAYOUT (layout), CLUTTER_ORIENTATION_VERTICAL);
+  clutter_box_layout_set_spacing (CLUTTER_BOX_LAYOUT (layout), 12);
+
+  clutter_actor_set_layout_manager (actor, layout);
+  clutter_actor_set_background_color (actor, CLUTTER_COLOR_Black);
+
+  self->current_idx = -1;
+}
+
+static ClutterActor *
+example_menu_select_item (ExampleMenu *self,
+                          int          idx)
+{
+  ClutterActor *item;
+
+  if (idx == self->current_idx)
+    return clutter_actor_get_child_at_index (CLUTTER_ACTOR (self), self->current_idx);
+
+  item = clutter_actor_get_child_at_index (CLUTTER_ACTOR (self), self->current_idx);
+  if (item != NULL)
+    example_menu_item_set_selected ((ExampleMenuItem *) item, FALSE);
+
+  if (idx < 0)
+    idx = clutter_actor_get_n_children (CLUTTER_ACTOR (self)) - 1;
+  else if (idx >= clutter_actor_get_n_children (CLUTTER_ACTOR (self)))
+    idx = 0;
+
+  self->current_idx = idx;
+
+  item = clutter_actor_get_child_at_index (CLUTTER_ACTOR (self), self->current_idx);
+  if (item != NULL)
+    example_menu_item_set_selected ((ExampleMenuItem *) item, TRUE);
+
+  return item;
+}
+
+static ClutterActor *
+example_menu_select_next (ExampleMenu *self)
+{
+  return example_menu_select_item (self, self->current_idx + 1);
+}
+
+static ClutterActor *
+example_menu_select_prev (ExampleMenu *self)
+{
+  return example_menu_select_item (self, self->current_idx - 1);
+}
+
+/* }}} */
+
+/* {{{ MenuItemModel */
+#define EXAMPLE_TYPE_MENU_ITEM_MODEL    (example_menu_item_model_get_type ())
+
+G_DECLARE_FINAL_TYPE (ExampleMenuItemModel, example_menu_item_model, EXAMPLE, MENU_ITEM_MODEL, GObject)
+
+struct _ExampleMenuItemModel
+{
+  GObject parent_instance;
+
+  char *label;
+
+  gboolean selected;
+};
+
+struct _ExampleMenuItemModelClass
+{
+  GObjectClass parent_class;
+};
+
+enum {
+  MENU_ITEM_MODEL_PROP_LABEL = 1,
+  MENU_ITEM_MODEL_PROP_SELECTED,
+  MENU_ITEM_MODEL_N_PROPS
+};
+
+static GParamSpec *menu_item_model_props[MENU_ITEM_MODEL_N_PROPS] = { NULL, };
+
+G_DEFINE_TYPE (ExampleMenuItemModel, example_menu_item_model, G_TYPE_OBJECT)
+
+static void
+example_menu_item_model_finalize (GObject *gobject)
+{
+  ExampleMenuItemModel *self = (ExampleMenuItemModel *) gobject;
+
+  g_free (self->label);
+
+  G_OBJECT_CLASS (example_menu_item_model_parent_class)->finalize (gobject);
+}
+
+static void
+example_menu_item_model_set_property (GObject      *gobject,
+                                      guint         prop_id,
+                                      const GValue *value,
+                                      GParamSpec   *pspec)
+{
+  ExampleMenuItemModel *self = (ExampleMenuItemModel *) gobject;
+
+  switch (prop_id)
+    {
+    case MENU_ITEM_MODEL_PROP_LABEL:
+      g_free (self->label);
+      self->label = g_value_dup_string (value);
+      break;
+
+    case MENU_ITEM_MODEL_PROP_SELECTED:
+      self->selected = g_value_get_boolean (value);
+      break;
+    }
+}
+
+static void
+example_menu_item_model_get_property (GObject    *gobject,
+                                      guint       prop_id,
+                                      GValue     *value,
+                                      GParamSpec *pspec)
+{
+  ExampleMenuItemModel *self = (ExampleMenuItemModel *) gobject;
+
+  switch (prop_id)
+    {
+    case MENU_ITEM_MODEL_PROP_LABEL:
+      g_value_set_string (value, self->label);
+      break;
+
+    case MENU_ITEM_MODEL_PROP_SELECTED:
+      g_value_set_boolean (value, self->selected);
+      break;
+    }
+}
+
+static void
+example_menu_item_model_class_init (ExampleMenuItemModelClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->set_property = example_menu_item_model_set_property;
+  gobject_class->get_property = example_menu_item_model_get_property;
+  gobject_class->finalize = example_menu_item_model_finalize;
+
+  menu_item_model_props[MENU_ITEM_MODEL_PROP_LABEL] =
+    g_param_spec_string ("label", NULL, NULL,
+                         NULL,
+                         G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+  menu_item_model_props[MENU_ITEM_MODEL_PROP_SELECTED] =
+    g_param_spec_boolean ("selected", NULL, NULL,
+                          FALSE,
+                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+  g_object_class_install_properties (gobject_class, MENU_ITEM_MODEL_N_PROPS, menu_item_model_props);
+}
+
+static void
+example_menu_item_model_init (ExampleMenuItemModel *self)
+{
+}
+/* }}} */
+
+/* {{{ main */
+static gboolean
+on_key_press (ClutterActor *stage,
+              ClutterEvent *event)
+{
+  ClutterActor *scroll = clutter_actor_get_first_child (stage);
+  ClutterActor *menu = clutter_actor_get_first_child (scroll);
+  ClutterActor *item = NULL;
+  guint key = clutter_event_get_key_symbol (event);
+  ClutterPoint p;
+
+  switch (key)
+    {
+    case CLUTTER_KEY_q:
+      clutter_main_quit ();
+      break;
+
+    case CLUTTER_KEY_Up:
+      item = example_menu_select_prev ((ExampleMenu *) menu);
+      clutter_actor_get_position (item, &p.x, &p.y);
+      break;
+
+    case CLUTTER_KEY_Down:
+      item = example_menu_select_next ((ExampleMenu *) menu);
+      clutter_actor_get_position (item, &p.x, &p.y);
+      break;
+    }
+
+  if (item != NULL)
+    clutter_scroll_actor_scroll_to_point (CLUTTER_SCROLL_ACTOR (scroll), &p);
+
+  return CLUTTER_EVENT_PROPAGATE;
+}
+
+static void
+on_model_item_selection (GObject    *model_item,
+                         GParamSpec *pspec,
+                         gpointer    data)
+{
+  char *label = NULL;
+  gboolean is_selected = FALSE;
+
+  g_object_get (model_item, "label", &label, "selected", &is_selected, NULL);
+
+  if (is_selected)
+    g_print ("Item '%s' selected!\n", label);
+
+  g_free (label);
+}
+
+static ClutterActor *
+create_menu_item (gpointer item,
+                  gpointer data G_GNUC_UNUSED)
+{
+  ClutterActor *res = g_object_new (EXAMPLE_TYPE_MENU_ITEM, NULL);
+
+  /* The label goes from the model to the view */
+  g_object_bind_property (item, "label",
+                          res, "text",
+                          G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
+
+  /* The selected state goes in either direction */
+  g_object_bind_property (item, "selected",
+                          res, "selected",
+                          G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+
+  g_signal_connect (item, "notify::selected", G_CALLBACK (on_model_item_selection), NULL);
+
+  return res;
+}
+
+static ClutterActor *
+create_menu_actor (void)
+{
+  GListStore *model = g_list_store_new (EXAMPLE_TYPE_MENU_ITEM_MODEL);
+  ClutterActor *menu = g_object_new (EXAMPLE_TYPE_MENU, NULL);
+  int i;
+
+  /* Populate the model */
+  for (i = 0; i < 12; i++)
+    {
+      char *label = g_strdup_printf ("Option %02d", i + 1);
+
+      ExampleMenuItemModel *item = g_object_new (EXAMPLE_TYPE_MENU_ITEM_MODEL,
+                                                 "label", label,
+                                                 NULL);
+
+      g_list_store_append (model, item);
+
+      g_object_unref (item);
+      g_free (label);
+    }
+
+  clutter_actor_bind_model (menu, G_LIST_MODEL (model),
+                            create_menu_item,
+                            NULL, NULL);
+
+  /* The actor owns the model */
+  g_object_unref (model);
+
+  example_menu_select_item ((ExampleMenu *) menu, 0);
+
+  return menu;
+}
+
+static ClutterActor *
+create_scroll_actor (void)
+{
+  ClutterActor *menu = clutter_scroll_actor_new ();
+  clutter_actor_set_name (menu, "scroll");
+  clutter_scroll_actor_set_scroll_mode (CLUTTER_SCROLL_ACTOR (menu),
+                                        CLUTTER_SCROLL_VERTICALLY);
+  clutter_actor_set_easing_duration (menu, 250);
+  clutter_actor_add_child (menu, create_menu_actor ());
+
+  return menu;
+}
+
+int
+main (int argc, char *argv[])
+{
+  ClutterActor *stage, *menu;
+
+  if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
+    return 1;
+
+  stage = clutter_stage_new ();
+  clutter_stage_set_title (CLUTTER_STAGE (stage), "Actor Model");
+  clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
+  g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
+  g_signal_connect (stage, "key-press-event", G_CALLBACK (on_key_press), NULL);
+  clutter_actor_show (stage);
+
+#define PADDING 18.f
+
+  menu = create_scroll_actor ();
+  clutter_actor_set_position (menu, 0, PADDING);
+  clutter_actor_add_constraint (menu, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5));
+  clutter_actor_add_constraint (menu, clutter_bind_constraint_new (stage, CLUTTER_BIND_HEIGHT, -PADDING * 2));
+  clutter_actor_add_child (stage, menu);
+
+  clutter_main ();
+
+  return 0;
+}
+/* }}} */