Index: demo/mv-demo-grabs.c
===================================================================
--- demo/mv-demo-grabs.c	(revision 27)
+++ demo/mv-demo-grabs.c	(working copy)
@@ -365,21 +365,24 @@ create_canvas (GtkTable *table, gint row
   goo_canvas_set_root_item_model (GOO_CANVAS (canvas), root);
   g_object_unref (root);
 
-  rect = goo_canvas_rect_model_new (root, 0, 0, 200, 100,
+  rect = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                    0, 0, 200, 100,
 				    "stroke-pattern", NULL,
 				    "fill-color", "yellow",
 				    NULL);
   view_id = g_strdup_printf ("%s-yellow", id);
   g_object_set_data_full (G_OBJECT (rect), "id", view_id, g_free);
 
-  rect = goo_canvas_rect_model_new (root, 20, 20, 60, 60,
+  rect = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                    20, 20, 60, 60,
 				    "stroke-pattern", NULL,
 				    "fill-color", "blue",
 				    NULL);
   view_id = g_strdup_printf ("%s-blue", id);
   g_object_set_data_full (G_OBJECT (rect), "id", view_id, g_free);
 
-  rect = goo_canvas_rect_model_new (root, 120, 20, 60, 60,
+  rect = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                    120, 20, 60, 60,
 				    "stroke-pattern", NULL,
 				    "fill-color", "red",
 				    NULL);
Index: demo/demo-focus.c
===================================================================
--- demo/demo-focus.c	(revision 27)
+++ demo/demo-focus.c	(working copy)
@@ -91,7 +91,8 @@ create_focus_box (GtkWidget     *canvas,
   GooCanvasItem *root, *item;
 
   root = goo_canvas_get_root_item (GOO_CANVAS (canvas));
-  item = goo_canvas_rect_new (root, x, y, width, height,
+  item = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root),
+                              x, y, width, height,
 			      "stroke-pattern", NULL,
 			      "fill-color", color,
 			      "line-width", 5.0,
Index: demo/demo-fifteen.c
===================================================================
--- demo/demo-fifteen.c	(revision 27)
+++ demo/demo-fifteen.c	(working copy)
@@ -284,12 +284,14 @@ create_canvas_fifteen (void)
 		y = i / 4;
 		x = i % 4;
 
-		board[i] = goo_canvas_group_new (root, NULL);
+		board[i] = goo_canvas_group_new (GOO_CANVAS_CONTAINER (root),
+		                                 NULL);
 		goo_canvas_item_translate (board[i], x * PIECE_SIZE,
 					   y * PIECE_SIZE);
 		setup_item_signals (board[i]);
 
-		rect = goo_canvas_rect_new (board[i], 0, 0,
+		rect = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (board[i]),
+		                            0, 0,
 					    PIECE_SIZE, PIECE_SIZE,
 					    "fill_color", get_piece_color (i),
 					    "stroke_color", "black",
@@ -298,7 +300,8 @@ create_canvas_fifteen (void)
 
 		sprintf (buf, "%d", i + 1);
 
-		text = goo_canvas_text_new (board[i], buf,
+		text = goo_canvas_text_new (GOO_CANVAS_CONTAINER (board[i]),
+		                            buf,
 					    PIECE_SIZE / 2.0, PIECE_SIZE / 2.0,
 					    -1, GTK_ANCHOR_CENTER,
 					    "font", "Sans bold 24",
Index: demo/mv-demo-events.c
===================================================================
--- demo/mv-demo-events.c	(revision 27)
+++ demo/mv-demo-events.c	(working copy)
@@ -38,10 +38,10 @@ on_item_created (GooCanvas          *vie
 
 
 static void
-create_events_area (GooCanvasItemModel     *root,
-		    gint                    area_num,
-		    GooCanvasPointerEvents  pointer_events,
-		    gchar                  *label)
+create_events_area (GooCanvasContainerModel *root,
+		    gint                     area_num,
+		    GooCanvasPointerEvents   pointer_events,
+		    gchar                   *label)
 {
   gint row = area_num / 3, col = area_num % 3;
   gdouble x = col * 200, y = row * 150;
@@ -164,15 +164,24 @@ create_events_page (void)
   gtk_container_add (GTK_CONTAINER (frame), canvas);
   gtk_widget_show (canvas);
 
-  create_events_area (root, 0, GOO_CANVAS_EVENTS_NONE, "none");
-  create_events_area (root, 1, GOO_CANVAS_EVENTS_VISIBLE_PAINTED, "visible-painted");
-  create_events_area (root, 2, GOO_CANVAS_EVENTS_VISIBLE_FILL, "visible-fill");
-  create_events_area (root, 3, GOO_CANVAS_EVENTS_VISIBLE_STROKE, "visible-stroke");
-  create_events_area (root, 4, GOO_CANVAS_EVENTS_VISIBLE, "visible");
-  create_events_area (root, 5, GOO_CANVAS_EVENTS_PAINTED, "painted");
-  create_events_area (root, 6, GOO_CANVAS_EVENTS_FILL, "fill");
-  create_events_area (root, 7, GOO_CANVAS_EVENTS_STROKE, "stroke");
-  create_events_area (root, 8, GOO_CANVAS_EVENTS_ALL, "all");
+  create_events_area (GOO_CANVAS_CONTAINER_MODEL (root),
+                      0, GOO_CANVAS_EVENTS_NONE, "none");
+  create_events_area (GOO_CANVAS_CONTAINER_MODEL (root),
+                      1, GOO_CANVAS_EVENTS_VISIBLE_PAINTED, "visible-painted");
+  create_events_area (GOO_CANVAS_CONTAINER_MODEL (root),
+                      2, GOO_CANVAS_EVENTS_VISIBLE_FILL, "visible-fill");
+  create_events_area (GOO_CANVAS_CONTAINER_MODEL (root),
+                      3, GOO_CANVAS_EVENTS_VISIBLE_STROKE, "visible-stroke");
+  create_events_area (GOO_CANVAS_CONTAINER_MODEL (root),
+                      4, GOO_CANVAS_EVENTS_VISIBLE, "visible");
+  create_events_area (GOO_CANVAS_CONTAINER_MODEL (root),
+                      5, GOO_CANVAS_EVENTS_PAINTED, "painted");
+  create_events_area (GOO_CANVAS_CONTAINER_MODEL (root),
+                      6, GOO_CANVAS_EVENTS_FILL, "fill");
+  create_events_area (GOO_CANVAS_CONTAINER_MODEL (root),
+                      7, GOO_CANVAS_EVENTS_STROKE, "stroke");
+  create_events_area (GOO_CANVAS_CONTAINER_MODEL (root),
+                      8, GOO_CANVAS_EVENTS_ALL, "all");
 
   goo_canvas_set_root_item_model (GOO_CANVAS (canvas), root);
   g_object_unref (root);
Index: demo/mv-demo-clipping.c
===================================================================
--- demo/mv-demo-clipping.c	(revision 27)
+++ demo/mv-demo-clipping.c	(working copy)
@@ -28,7 +28,8 @@ setup_canvas (GooCanvas *canvas)
   g_object_unref (root);
 
   /* Plain items without clip path. */
-  model = goo_canvas_ellipse_model_new (root, 0, 0, 50, 30,
+  model = goo_canvas_ellipse_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                        0, 0, 50, 30,
 					"fill-color", "blue",
 					NULL);
   goo_canvas_item_model_translate (model, 100, 100);
@@ -37,7 +38,8 @@ setup_canvas (GooCanvas *canvas)
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Blue ellipse (unclipped)");
 
-  model = goo_canvas_rect_model_new (root, 200, 50, 100, 100,
+  model = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                     200, 50, 100, 100,
 				     "fill-color", "red",
 				     "clip-fill-rule", CAIRO_FILL_RULE_EVEN_ODD,
 				     NULL);
@@ -45,14 +47,16 @@ setup_canvas (GooCanvas *canvas)
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Red rectangle (unclipped)");
 
-  model = goo_canvas_rect_model_new (root, 380, 50, 100, 100,
+  model = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                     380, 50, 100, 100,
 				     "fill-color", "yellow",
 				     NULL);
   item = goo_canvas_get_item (canvas, model);
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Yellow rectangle (unclipped)");
 
-  model = goo_canvas_text_model_new (root, "Sample Text", 520, 100, -1, GTK_ANCHOR_NW,
+  model = goo_canvas_text_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                     "Sample Text", 520, 100, -1, GTK_ANCHOR_NW,
 				     NULL);
   item = goo_canvas_get_item (canvas, model);
   g_signal_connect (item, "button_press_event",
@@ -60,7 +64,8 @@ setup_canvas (GooCanvas *canvas)
 
 
   /* Clipped items. */
-  model = goo_canvas_ellipse_model_new (root, 0, 0, 50, 30,
+  model = goo_canvas_ellipse_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                        0, 0, 50, 30,
 					"fill-color", "blue",
 					"clip-path", "M 0 0 h 100 v 100 h -100 Z",
 					NULL);
@@ -70,7 +75,8 @@ setup_canvas (GooCanvas *canvas)
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Blue ellipse");
 
-  model = goo_canvas_rect_model_new (root, 200, 250, 100, 100,
+  model = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                     200, 250, 100, 100,
 				     "fill-color", "red",
 				     "clip-path", "M 250 300 h 100 v 100 h -100 Z",
 				     "clip-fill-rule", CAIRO_FILL_RULE_EVEN_ODD,
@@ -79,7 +85,8 @@ setup_canvas (GooCanvas *canvas)
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Red rectangle");
 
-  model = goo_canvas_rect_model_new (root, 380, 250, 100, 100,
+  model = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                     380, 250, 100, 100,
 				     "fill-color", "yellow",
 				     "clip-path", "M480,230 l40,100 l-80 0 z",
 				     NULL);
@@ -87,7 +94,8 @@ setup_canvas (GooCanvas *canvas)
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Yellow rectangle");
 
-  model = goo_canvas_text_model_new (root, "Sample Text", 520, 300, -1, GTK_ANCHOR_NW,
+  model = goo_canvas_text_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                     "Sample Text", 520, 300, -1, GTK_ANCHOR_NW,
 				     "clip-path", "M535,300 h75 v40 h-75 z",
 				     NULL);
   item = goo_canvas_get_item (canvas, model);
@@ -96,12 +104,13 @@ setup_canvas (GooCanvas *canvas)
 
 
   /* Table with clipped items. */
-  table = goo_canvas_table_model_new (root, NULL);
+  table = goo_canvas_table_model_new (GOO_CANVAS_CONTAINER_MODEL (root), NULL);
 
   goo_canvas_item_model_translate (table, 200, 400);
   goo_canvas_item_model_rotate (table, 30, 0, 0);
 
-  model = goo_canvas_ellipse_model_new (table, 0, 0, 50, 30,
+  model = goo_canvas_ellipse_model_new (GOO_CANVAS_CONTAINER_MODEL (table),
+                                        0, 0, 50, 30,
 					"fill-color", "blue",
 					"clip-path", "M 0 0 h 100 v 100 h -100 Z",
 					NULL);
@@ -111,35 +120,41 @@ setup_canvas (GooCanvas *canvas)
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Blue ellipse");
 
-  model = goo_canvas_rect_model_new (table, 200, 250, 100, 100,
+  model = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (table),
+                                     200, 250, 100, 100,
 				     "fill-color", "red",
 				     "clip-path", "M 250 300 h 100 v 100 h -100 Z",
 				     "clip-fill-rule", CAIRO_FILL_RULE_EVEN_ODD,
 				     NULL);
-  goo_canvas_item_model_set_child_properties (table, model,
-					      "column", 1,
-					      NULL);
+  goo_canvas_container_model_set_child_properties (GOO_CANVAS_CONTAINER_MODEL (table),
+                                                   model,
+					           "column", 1,
+					           NULL);
   item = goo_canvas_get_item (canvas, model);
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Red rectangle");
 
-  model = goo_canvas_rect_model_new (table, 380, 250, 100, 100,
+  model = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (table),
+                                     380, 250, 100, 100,
 				     "fill-color", "yellow",
 				     "clip-path", "M480,230 l40,100 l-80 0 z",
 				     NULL);
-  goo_canvas_item_model_set_child_properties (table, model,
-					      "column", 2,
-					      NULL);
+  goo_canvas_container_model_set_child_properties (GOO_CANVAS_CONTAINER_MODEL (table),
+                                                   model,
+					           "column", 2,
+					           NULL);
   item = goo_canvas_get_item (canvas, model);
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Yellow rectangle");
 
-  model = goo_canvas_text_model_new (table, "Sample Text", 520, 300, -1, GTK_ANCHOR_NW,
+  model = goo_canvas_text_model_new (GOO_CANVAS_CONTAINER_MODEL (table),
+                                     "Sample Text", 520, 300, -1, GTK_ANCHOR_NW,
 				     "clip-path", "M535,300 h75 v40 h-75 z",
 				     NULL);
-  goo_canvas_item_model_set_child_properties (table, model,
-					      "column", 3,
-					      NULL);
+  goo_canvas_container_model_set_child_properties (GOO_CANVAS_CONTAINER_MODEL (table),
+                                                   model,
+					           "column", 3,
+					           NULL);
   item = goo_canvas_get_item (canvas, model);
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Text (unclipped)");
Index: demo/demo-large-rect.c
===================================================================
--- demo/demo-large-rect.c	(revision 27)
+++ demo/demo-large-rect.c	(working copy)
@@ -32,7 +32,7 @@ goo_demo_large_rect_init (GooDemoLargeRe
    parent argument and end with a variable list of object properties to fit
    in with the standard canvas items. */
 GooCanvasItem*
-goo_demo_large_rect_new (GooCanvasItem      *parent,
+goo_demo_large_rect_new (GooCanvasContainer *parent,
 			 gdouble             x,
 			 gdouble             y,
 			 gdouble             width,
@@ -60,7 +60,7 @@ goo_demo_large_rect_new (GooCanvasItem  
 
   if (parent)
     {
-      goo_canvas_item_add_child (parent, item, -1);
+      goo_canvas_container_add_child (parent, item, -1);
       g_object_unref (item);
     }
 
Index: demo/demo-table.c
===================================================================
--- demo/demo-table.c	(revision 27)
+++ demo/demo-table.c	(working copy)
@@ -25,13 +25,13 @@ on_button_press (GooCanvasItem *item,
 
 
 static void
-create_demo_item (GooCanvasItem *table,
-		  gint           demo_item_type,
-		  gint           row,
-		  gint           column,
-		  gint           rows,
-		  gint           columns,
-		  gchar         *text)
+create_demo_item (GooCanvasTable *table,
+		  gint            demo_item_type,
+		  gint            row,
+		  gint            column,
+		  gint            rows,
+		  gint            columns,
+		  gchar          *text)
 {
   GooCanvasItem *item = NULL;
   GtkWidget *widget;
@@ -41,42 +41,49 @@ create_demo_item (GooCanvasItem *table,
   switch (demo_item_type)
     {
     case DEMO_RECT_ITEM:
-      item = goo_canvas_rect_new (table, 0, 0, 38, 19,
+      item = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (table), 0, 0, 38, 19,
 				  "fill-color", "red",
 				  NULL);
       break;
     case DEMO_TEXT_ITEM:
-      item = goo_canvas_text_new (table, text, 0, 0, -1, GTK_ANCHOR_NW, NULL);
+      item = goo_canvas_text_new (GOO_CANVAS_CONTAINER (table),
+                                  text, 0, 0, -1, GTK_ANCHOR_NW, NULL);
       break;
     case DEMO_WIDGET_ITEM:
       widget = gtk_button_new_with_label (text);
-      item = goo_canvas_widget_new (table, widget, 0, 0, -1, -1, NULL);
+      item = goo_canvas_widget_new (GOO_CANVAS_CONTAINER (table),
+                                    widget, 0, 0, -1, -1, NULL);
       break;
     }
 
   g_value_init (&value, G_TYPE_UINT);
   g_value_set_uint (&value, row);
-  goo_canvas_item_set_child_property (table, item, "row", &value);
+  goo_canvas_container_set_child_property (GOO_CANVAS_CONTAINER (table),
+                                           item, "row", &value);
   g_value_set_uint (&value, column);
-  goo_canvas_item_set_child_property (table, item, "column", &value);
+  goo_canvas_container_set_child_property (GOO_CANVAS_CONTAINER (table),
+                                           item, "column", &value);
   g_value_set_uint (&value, rows);
-  goo_canvas_item_set_child_property (table, item, "rows", &value);
+  goo_canvas_container_set_child_property (GOO_CANVAS_CONTAINER (table),
+                                           item, "rows", &value);
   g_value_set_uint (&value, columns);
-  goo_canvas_item_set_child_property (table, item, "columns", &value);
+  goo_canvas_container_set_child_property (GOO_CANVAS_CONTAINER (table),
+                                           item, "columns", &value);
 
   /* Test the get function. */
-  goo_canvas_item_get_child_property (table, item, "row", &value);
+  goo_canvas_container_get_child_property (GOO_CANVAS_CONTAINER (table),
+                                           item, "row", &value);
   new_row = g_value_get_uint (&value);
   if (new_row != row)
     g_warning ("Got bad row setting: %i should be: %i\n", new_row, row);
 
 #if 1
-  goo_canvas_item_set_child_properties (table, item,
-					"x-expand", TRUE,
-					"x-fill", TRUE,
-					"y-expand", TRUE,
-					"y-fill", TRUE,
-					NULL);
+  goo_canvas_container_set_child_properties (GOO_CANVAS_CONTAINER (table), item,
+					     "x-expand", TRUE,
+					     "x-fill", TRUE,
+					     "y-expand", TRUE,
+					     "y-fill", TRUE,
+					     NULL);
 #endif
 
   g_object_set_data (G_OBJECT (item), "id", text);
@@ -86,15 +93,15 @@ create_demo_item (GooCanvasItem *table,
 
 
 static GooCanvasItem*
-create_table (GooCanvasItem *parent,
-	      gint           row,
-	      gint           column,
-	      gint           embedding_level,
-	      gdouble        x,
-	      gdouble        y,
-	      gdouble        rotation,
-	      gdouble        scale,
-	      gint           demo_item_type)
+create_table (GooCanvasContainer *parent,
+	      gint                row,
+	      gint                column,
+	      gint                embedding_level,
+	      gdouble             x,
+	      gdouble             y,
+	      gdouble             rotation,
+	      gdouble             scale,
+	      gint                demo_item_type)
 {
   GooCanvasItem *table;
 
@@ -112,43 +119,61 @@ create_table (GooCanvasItem *parent,
 #endif
 
   if (row != -1)
-    goo_canvas_item_set_child_properties (parent, table,
-					  "row", row,
-					  "column", column,
+    goo_canvas_container_set_child_properties (parent, table,
+					       "row", row,
+					       "column", column,
 #if 1
-					  "x-expand", TRUE,
-					  "x-fill", TRUE,
+					       "x-expand", TRUE,
+					       "x-fill", TRUE,
 #endif
 #if 0
-					  "y-expand", TRUE,
-					  "y-fill", TRUE,
+					       "y-expand", TRUE,
+					       "y-fill", TRUE,
 #endif
-					  NULL);
+					       NULL);
 
   if (embedding_level)
     {
       gint level = embedding_level - 1;
-      create_table (table, 0, 0, level, 50, 50, 0, 0.7, demo_item_type);
-      create_table (table, 0, 1, level, 50, 50, 45, 1.0, demo_item_type);
-      create_table (table, 0, 2, level, 50, 50, 90, 1.0, demo_item_type);
-      create_table (table, 1, 0, level, 50, 50, 135, 1.0, demo_item_type);
-      create_table (table, 1, 1, level, 50, 50, 180, 1.5, demo_item_type);
-      create_table (table, 1, 2, level, 50, 50, 225, 1.0, demo_item_type);
-      create_table (table, 2, 0, level, 50, 50, 270, 1.0, demo_item_type);
-      create_table (table, 2, 1, level, 50, 50, 315, 1.0, demo_item_type);
-      create_table (table, 2, 2, level, 50, 50, 360, 2.0, demo_item_type);
+      create_table (GOO_CANVAS_CONTAINER (table), 0, 0, level,
+                    50, 50, 0, 0.7, demo_item_type);
+      create_table (GOO_CANVAS_CONTAINER (table), 0, 1, level,
+                    50, 50, 45, 1.0, demo_item_type);
+      create_table (GOO_CANVAS_CONTAINER (table), 0, 2, level,
+                    50, 50, 90, 1.0, demo_item_type);
+      create_table (GOO_CANVAS_CONTAINER (table), 1, 0, level,
+                    50, 50, 135, 1.0, demo_item_type);
+      create_table (GOO_CANVAS_CONTAINER (table), 1, 1, level,
+                    50, 50, 180, 1.5, demo_item_type);
+      create_table (GOO_CANVAS_CONTAINER (table), 1, 2, level,
+                    50, 50, 225, 1.0, demo_item_type);
+      create_table (GOO_CANVAS_CONTAINER (table), 2, 0, level,
+                    50, 50, 270, 1.0, demo_item_type);
+      create_table (GOO_CANVAS_CONTAINER (table), 2, 1, level,
+                    50, 50, 315, 1.0, demo_item_type);
+      create_table (GOO_CANVAS_CONTAINER (table), 2, 2, level,
+                    50, 50, 360, 2.0, demo_item_type);
     }
   else
     {
-      create_demo_item (table, demo_item_type, 0, 0, 1, 1, "(0,0)");
-      create_demo_item (table, demo_item_type, 0, 1, 1, 1, "(1,0)");
-      create_demo_item (table, demo_item_type, 0, 2, 1, 1, "(2,0)");
-      create_demo_item (table, demo_item_type, 1, 0, 1, 1, "(0,1)");
-      create_demo_item (table, demo_item_type, 1, 1, 1, 1, "(1,1)");
-      create_demo_item (table, demo_item_type, 1, 2, 1, 1, "(2,1)");
-      create_demo_item (table, demo_item_type, 2, 0, 1, 1, "(0,2)");
-      create_demo_item (table, demo_item_type, 2, 1, 1, 1, "(1,2)");
-      create_demo_item (table, demo_item_type, 2, 2, 1, 1, "(2,2)");
+      create_demo_item (GOO_CANVAS_TABLE (table), demo_item_type,
+                        0, 0, 1, 1, "(0,0)");
+      create_demo_item (GOO_CANVAS_TABLE (table), demo_item_type,
+                        0, 1, 1, 1, "(1,0)");
+      create_demo_item (GOO_CANVAS_TABLE (table), demo_item_type,
+                        0, 2, 1, 1, "(2,0)");
+      create_demo_item (GOO_CANVAS_TABLE (table), demo_item_type,
+                        1, 0, 1, 1, "(0,1)");
+      create_demo_item (GOO_CANVAS_TABLE (table), demo_item_type,
+                        1, 1, 1, 1, "(1,1)");
+      create_demo_item (GOO_CANVAS_TABLE (table), demo_item_type,
+                        1, 2, 1, 1, "(2,1)");
+      create_demo_item (GOO_CANVAS_TABLE (table), demo_item_type,
+                        2, 0, 1, 1, "(0,2)");
+      create_demo_item (GOO_CANVAS_TABLE (table), demo_item_type,
+                        2, 1, 1, 1, "(1,2)");
+      create_demo_item (GOO_CANVAS_TABLE (table), demo_item_type,
+                        2, 2, 1, 1, "(2,2)");
     }
 
   return table;
@@ -156,11 +181,11 @@ create_table (GooCanvasItem *parent,
 
 
 static void
-create_demo_table (GooCanvasItem *root,
-		   gdouble        x,
-		   gdouble        y,
-		   gdouble        width,
-		   gdouble        height)
+create_demo_table (GooCanvasContainer *root,
+		   gdouble             x,
+		   gdouble             y,
+		   gdouble             width,
+		   gdouble             height)
 {
   GooCanvasItem *table, *square, *circle, *triangle;
 
@@ -172,39 +197,44 @@ create_demo_table (GooCanvasItem *root,
                                 NULL);
   goo_canvas_item_translate (table, x, y);
 
-  square = goo_canvas_rect_new (table, 0.0, 0.0, 50.0, 50.0,
+  square = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (table),
+                                0.0, 0.0, 50.0, 50.0,
 				"fill-color", "red",
 				NULL);
-  goo_canvas_item_set_child_properties (table, square,
-					"row", 0,
-					"column", 0,
-					"x-shrink", TRUE,
-					NULL);
+  goo_canvas_container_set_child_properties (GOO_CANVAS_CONTAINER (table),
+                                             square,
+					     "row", 0,
+					     "column", 0,
+					     "x-shrink", TRUE,
+					     NULL);
   g_object_set_data (G_OBJECT (square), "id", "Red square");
   g_signal_connect (square, "button_press_event",
 		    G_CALLBACK (on_button_press), NULL);
 
-  circle = goo_canvas_ellipse_new (table, 0.0, 0.0, 25.0, 25.0,
+  circle = goo_canvas_ellipse_new (GOO_CANVAS_CONTAINER (table),
+                                   0.0, 0.0, 25.0, 25.0,
 				   "fill-color", "blue",
 				   NULL);
-  goo_canvas_item_set_child_properties (table, circle,
-					"row", 0,
-					"column", 1,
-					"x-shrink", TRUE,
-					NULL);
+  goo_canvas_container_set_child_properties (GOO_CANVAS_CONTAINER (table),
+                                             circle,
+					     "row", 0,
+					     "column", 1,
+					     "x-shrink", TRUE,
+					     NULL);
   g_object_set_data (G_OBJECT (circle), "id", "Blue circle");
   g_signal_connect (circle, "button_press_event",
 		    G_CALLBACK (on_button_press), NULL);
 
-  triangle = goo_canvas_polyline_new (table, TRUE, 3,
+  triangle = goo_canvas_polyline_new (GOO_CANVAS_CONTAINER (table), TRUE, 3,
 				      25.0, 0.0, 0.0, 50.0, 50.0, 50.0,
 				      "fill-color", "yellow",
 				      NULL);
-  goo_canvas_item_set_child_properties (table, triangle,
-					"row", 0,
-					"column", 2,
-					"x-shrink", TRUE,
-					NULL);
+  goo_canvas_container_set_child_properties (GOO_CANVAS_CONTAINER (table),
+                                             triangle,
+					     "row", 0,
+					     "column", 2,
+					     "x-shrink", TRUE,
+					     NULL);
   g_object_set_data (G_OBJECT (triangle), "id", "Yellow triangle");
   g_signal_connect (triangle, "button_press_event",
 		    G_CALLBACK (on_button_press), NULL);
@@ -212,12 +242,12 @@ create_demo_table (GooCanvasItem *root,
 
 
 static void
-create_width_for_height_table (GooCanvasItem *root,
-			       gdouble        x,
-			       gdouble        y,
-			       gdouble        width,
-			       gdouble        height,
-			       gdouble        rotation)
+create_width_for_height_table (GooCanvasContainer *root,
+			       gdouble             x,
+			       gdouble             y,
+			       gdouble             width,
+			       gdouble             height,
+			       gdouble             rotation)
 {
   GooCanvasItem *table, *item;
   gchar *text = "This is a long paragraph that will have to be split over a few lines so we can see if its allocated height changes when its allocated width is changed.";
@@ -231,39 +261,45 @@ create_width_for_height_table (GooCanvas
   goo_canvas_item_translate (table, x, y);
   goo_canvas_item_rotate (table, rotation, 0, 0);
 
-  item = goo_canvas_rect_new (table, 0.0, 0.0, width - 2, 10.0,
+  item = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (table),
+                              0.0, 0.0, width - 2, 10.0,
 			      "fill-color", "red",
 			      NULL);
-  goo_canvas_item_set_child_properties (table, item,
-					"row", 0,
-					"column", 0,
-					"x-shrink", TRUE,
-					NULL);
-
-#if 1
-  item = goo_canvas_text_new (table, text, 0, 0, -1, GTK_ANCHOR_NW, NULL);
-  goo_canvas_item_set_child_properties (table, item,
-					"row", 1,
-					"column", 0,
-					"x-expand", TRUE,
-					"x-fill", TRUE,
-					"x-shrink", TRUE,
-					"y-expand", TRUE,
-					"y-fill", TRUE,
-					NULL);
+  goo_canvas_container_set_child_properties (GOO_CANVAS_CONTAINER (table),
+                                             item,
+					     "row", 0,
+					     "column", 0,
+					     "x-shrink", TRUE,
+					     NULL);
+
+#if 1
+  item = goo_canvas_text_new (GOO_CANVAS_CONTAINER (table),
+                              text, 0, 0, -1, GTK_ANCHOR_NW, NULL);
+  goo_canvas_container_set_child_properties (GOO_CANVAS_CONTAINER (table),
+                                             item,
+					     "row", 1,
+					     "column", 0,
+					     "x-expand", TRUE,
+					     "x-fill", TRUE,
+					     "x-shrink", TRUE,
+					     "y-expand", TRUE,
+					     "y-fill", TRUE,
+					     NULL);
   g_object_set_data (G_OBJECT (item), "id", "Text Item");
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), NULL);
 #endif
 
-  item = goo_canvas_rect_new (table, 0.0, 0.0, width - 2, 10.0,
+  item = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (table),
+                              0.0, 0.0, width - 2, 10.0,
 			      "fill-color", "red",
 			      NULL);
-  goo_canvas_item_set_child_properties (table, item,
-					"row", 2,
-					"column", 0,
-					"x-shrink", TRUE,
-					NULL);
+  goo_canvas_container_set_child_properties (GOO_CANVAS_CONTAINER (table),
+                                             item,
+					     "row", 2,
+					     "column", 0,
+					     "x-shrink", TRUE,
+					     NULL);
 }
 
 
@@ -291,37 +327,48 @@ create_table_page (void)
   root = goo_canvas_get_root_item (GOO_CANVAS (canvas));
 
 #if 1
-  create_demo_table (root, 400, 200, -1, -1);
-  create_demo_table (root, 400, 260, 100, -1);
+  create_demo_table (GOO_CANVAS_CONTAINER (root), 400, 200, -1, -1);
+  create_demo_table (GOO_CANVAS_CONTAINER (root), 400, 260, 100, -1);
 #endif
 
 #if 1
-  create_table (root, -1, -1, 0, 10, 10, 0, 1.0, DEMO_TEXT_ITEM);
-  create_table (root, -1, -1, 0, 180, 10, 30, 1.0, DEMO_TEXT_ITEM);
-  create_table (root, -1, -1, 0, 350, 10, 60, 1.0, DEMO_TEXT_ITEM);
-  create_table (root, -1, -1, 0, 500, 10, 90, 1.0, DEMO_TEXT_ITEM);
+  create_table (GOO_CANVAS_CONTAINER (root),
+                -1, -1, 0, 10, 10, 0, 1.0, DEMO_TEXT_ITEM);
+  create_table (GOO_CANVAS_CONTAINER (root),
+                -1, -1, 0, 180, 10, 30, 1.0, DEMO_TEXT_ITEM);
+  create_table (GOO_CANVAS_CONTAINER (root),
+                -1, -1, 0, 350, 10, 60, 1.0, DEMO_TEXT_ITEM);
+  create_table (GOO_CANVAS_CONTAINER (root),
+                -1, -1, 0, 500, 10, 90, 1.0, DEMO_TEXT_ITEM);
 #endif
 
 #if 1
-  table = create_table (root, -1, -1, 0, 30, 150, 0, 1.0, DEMO_TEXT_ITEM);
+  table = create_table (GOO_CANVAS_CONTAINER (root),
+                        -1, -1, 0, 30, 150, 0, 1.0, DEMO_TEXT_ITEM);
   g_object_set (table, "width", 300.0, "height", 100.0, NULL);
 #endif
 
 #if 1
-  create_table (root, -1, -1, 1, 200, 200, 30, 0.8, DEMO_TEXT_ITEM);
+  create_table (GOO_CANVAS_CONTAINER (root),
+                -1, -1, 1, 200, 200, 30, 0.8, DEMO_TEXT_ITEM);
 #endif
 
 #if 1
-  table = create_table (root, -1, -1, 0, 10, 700, 0, 1.0, DEMO_WIDGET_ITEM);
+  table = create_table (GOO_CANVAS_CONTAINER (root),
+                        -1, -1, 0, 10, 700, 0, 1.0, DEMO_WIDGET_ITEM);
   g_object_set (table, "width", 300.0, "height", 200.0, NULL);
 #endif
 
-  create_width_for_height_table (root, 100, 1000, 200, -1, 0);
+  create_width_for_height_table (GOO_CANVAS_CONTAINER (root),
+                                 100, 1000, 200, -1, 0);
 #if 1
-  create_width_for_height_table (root, 100, 1200, 300, -1, 0);
+  create_width_for_height_table (GOO_CANVAS_CONTAINER (root),
+                                 100, 1200, 300, -1, 0);
 
-  create_width_for_height_table (root, 500, 1000, 200, -1, 30);
-  create_width_for_height_table (root, 500, 1200, 300, -1, 30);
+  create_width_for_height_table (GOO_CANVAS_CONTAINER (root),
+                                 500, 1000, 200, -1, 30);
+  create_width_for_height_table (GOO_CANVAS_CONTAINER (root),
+                                 500, 1200, 300, -1, 30);
 #endif
 
   gtk_widget_show (canvas);
Index: demo/simple-demo.c
===================================================================
--- demo/simple-demo.c	(revision 27)
+++ demo/simple-demo.c	(working copy)
@@ -44,7 +44,8 @@ main (int argc, char *argv[])
   root = goo_canvas_get_root_item (GOO_CANVAS (canvas));
 
   /* Add a few simple items. */
-  rect_item = goo_canvas_rect_new (root, 100, 100, 400, 400,
+  rect_item = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root),
+                                   100, 100, 400, 400,
 				   "line-width", 10.0,
 				   "radius-x", 20.0,
 				   "radius-y", 10.0,
@@ -52,7 +53,8 @@ main (int argc, char *argv[])
 				   "fill-color", "red",
 				   NULL);
 
-  text_item = goo_canvas_text_new (root, "Hello World", 300, 300, -1,
+  text_item = goo_canvas_text_new (GOO_CANVAS_CONTAINER (root),
+                                   "Hello World", 300, 300, -1,
 				   GTK_ANCHOR_CENTER,
 				   "font", "Sans 24",
 				   NULL);
Index: demo/demo-large-rect.h
===================================================================
--- demo/demo-large-rect.h	(revision 27)
+++ demo/demo-large-rect.h	(working copy)
@@ -39,7 +39,7 @@ struct _GooDemoLargeRectClass
 
 GType               goo_demo_large_rect_get_type  (void) G_GNUC_CONST;
 
-GooCanvasItem*      goo_demo_large_rect_new       (GooCanvasItem      *parent,
+GooCanvasItem*      goo_demo_large_rect_new       (GooCanvasContainer *parent,
 						   gdouble             x,
 						   gdouble             y,
 						   gdouble             width,
Index: demo/demo-item.c
===================================================================
--- demo/demo-item.c	(revision 27)
+++ demo/demo-item.c	(working copy)
@@ -30,7 +30,7 @@ goo_demo_item_init (GooDemoItem *demo_it
    parent argument and end with a variable list of object properties to fit
    in with the standard canvas items. */
 GooCanvasItem*
-goo_demo_item_new (GooCanvasItem      *parent,
+goo_demo_item_new (GooCanvasContainer *parent,
 		   gdouble             x,
 		   gdouble             y,
 		   gdouble             width,
@@ -58,7 +58,7 @@ goo_demo_item_new (GooCanvasItem      *p
 
   if (parent)
     {
-      goo_canvas_item_add_child (parent, item, -1);
+      goo_canvas_container_add_child (parent, item, -1);
       g_object_unref (item);
     }
 
Index: demo/mv-demo-focus.c
===================================================================
--- demo/mv-demo-focus.c	(revision 27)
+++ demo/mv-demo-focus.c	(working copy)
@@ -111,7 +111,8 @@ create_focus_box (GtkWidget     *canvas,
   GooCanvasItemModel *root, *item;
 
   root = goo_canvas_get_root_item_model (GOO_CANVAS (canvas));
-  item = goo_canvas_rect_model_new (root, x, y, width, height,
+  item = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                    x, y, width, height,
 				    "stroke-pattern", NULL,
 				    "fill-color", color,
 				    "line-width", 5.0,
Index: demo/mv-demo-fifteen.c
===================================================================
--- demo/mv-demo-fifteen.c	(revision 27)
+++ demo/mv-demo-fifteen.c	(working copy)
@@ -294,11 +294,12 @@ create_canvas_fifteen (void)
 		y = i / 4;
 		x = i % 4;
 
-		board[i] = goo_canvas_group_model_new (root, NULL);
+		board[i] = goo_canvas_group_model_new (GOO_CANVAS_CONTAINER_MODEL (root), NULL);
 		goo_canvas_item_model_translate (board[i], x * PIECE_SIZE,
 						 y * PIECE_SIZE);
 
-		rect = goo_canvas_rect_model_new (board[i], 0, 0,
+		rect = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (board[i]),
+		                                  0, 0,
 						  PIECE_SIZE, PIECE_SIZE,
 						  "fill_color", get_piece_color (i),
 						  "stroke_color", "black",
@@ -307,7 +308,8 @@ create_canvas_fifteen (void)
 
 		sprintf (buf, "%d", i + 1);
 
-		text = goo_canvas_text_model_new (board[i], buf,
+		text = goo_canvas_text_model_new (GOO_CANVAS_CONTAINER_MODEL (board[i]),
+		                                  buf,
 						  PIECE_SIZE / 2.0, PIECE_SIZE / 2.0,
 						  -1, GTK_ANCHOR_CENTER,
 						  "font", "Sans bold 24",
Index: demo/demo-scalability.c
===================================================================
--- demo/demo-scalability.c	(revision 27)
+++ demo/demo-scalability.c	(working copy)
@@ -74,12 +74,12 @@ create_canvas_scalability (void)
 	for (i = 0; i < N_COLS; i++) {
 		for (j = 0; j < N_ROWS; j++) {
 #ifdef USE_PIXMAP
-		  item = goo_canvas_image_new (root, pixbuf,
+		  item = goo_canvas_image_new (GOO_CANVAS_CONTAINER (root), pixbuf,
 					       i * (width + PADDING),
 					       j * (height + PADDING),
 					      NULL);
 #else
-		  item = goo_canvas_rect_new (root,
+		  item = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root),
 					      i * (width + PADDING),
 					      j * (height + PADDING),
 					      width, height);
Index: demo/scalability-demo.c
===================================================================
--- demo/scalability-demo.c	(revision 27)
+++ demo/scalability-demo.c	(working copy)
@@ -67,7 +67,7 @@ on_motion_notify (GooCanvasItem *item,
 	  return TRUE;
 	}
 
-      ancestor = goo_canvas_item_get_parent (ancestor);
+      ancestor = GOO_CANVAS_ITEM (goo_canvas_item_get_parent (ancestor));
     }
 
   return TRUE;
@@ -149,7 +149,7 @@ setup_canvas (GtkWidget *canvas)
 	  double group_x = left_offset + (group_i * group_width);
 	  double group_y = top_offset + (group_j * group_height);
 
-	  group = goo_canvas_group_new (root, NULL);
+	  group = goo_canvas_group_new (GOO_CANVAS_CONTAINER (root), NULL);
 	  total_items++;
 	  goo_canvas_item_translate (group, group_x, group_y);
 
@@ -169,13 +169,15 @@ setup_canvas (GtkWidget *canvas)
 			   group_x + item_x, group_y + item_y);
 
 #ifdef USE_PIXMAP
-		  item = goo_canvas_image_new (group, NULL, item_x, item_y,
+		  item = goo_canvas_image_new (GOO_CANVAS_CONTAINER (group),
+		                               NULL, item_x, item_y,
 					       "pattern", pattern,
 					       "width", item_width,
 					       "height", item_height,
 					       NULL);
 #else
-		  item = goo_canvas_rect_new (group, item_x, item_y,
+		  item = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (group),
+		                              item_x, item_y,
 					      item_width, item_height,
 					      NULL);
 #ifdef SET_STYLE
@@ -194,13 +196,15 @@ setup_canvas (GtkWidget *canvas)
 #endif
 
 #ifdef USE_TEXT
-		  item = goo_canvas_text_new (group, ids[id_item_num],
+		  item = goo_canvas_text_new (GOO_CANVAS_CONTAINER (group),
+		                              ids[id_item_num],
 					      item_x + item_width / 2,
 					      item_y + item_height / 2,
 					      -1, GTK_ANCHOR_CENTER,
 					      NULL);
 #else
-		  item = goo_canvas_rect_new (group, item_x + 20, item_y + 4,
+		  item = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (group),
+		                              item_x + 20, item_y + 4,
 					      item_width - 40, item_height - 8,
 					      NULL);
 #endif
Index: demo/units-demo.c
===================================================================
--- demo/units-demo.c	(revision 27)
+++ demo/units-demo.c	(working copy)
@@ -46,14 +46,16 @@ setup_canvas (GtkWidget *canvas,
 
   root = goo_canvas_get_root_item (GOO_CANVAS (canvas));
 
-  item = goo_canvas_rect_new (root, d[0], d[1], d[2], d[3],
+  item = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root),
+                              d[0], d[1], d[2], d[3],
 			      NULL);
   g_signal_connect (item, "motion_notify_event",
 		    G_CALLBACK (on_motion_notify), NULL);
 
   sprintf (buffer, "This box is %gx%g %s", d[2], d[3], units_name);
   sprintf (font_desc, "Sans %gpx", d[4]);
-  item = goo_canvas_text_new (root, buffer, d[0] + d[2] / 2, d[1] + d[3] / 2,
+  item = goo_canvas_text_new (GOO_CANVAS_CONTAINER (root),
+                              buffer, d[0] + d[2] / 2, d[1] + d[3] / 2,
 			      -1, GTK_ANCHOR_CENTER,
 			      "font", font_desc,
 			      NULL);
@@ -61,7 +63,8 @@ setup_canvas (GtkWidget *canvas,
 
   sprintf (buffer, "This font is %g %s high", d[7], units_name);
   sprintf (font_desc, "Sans %gpx", d[7]);
-  item = goo_canvas_text_new (root, buffer, d[5], d[6], -1,
+  item = goo_canvas_text_new (GOO_CANVAS_CONTAINER (root),
+                              buffer, d[5], d[6], -1,
 			      GTK_ANCHOR_CENTER,
 			      "font", font_desc,
 			      NULL);
Index: demo/demo.c
===================================================================
--- demo/demo.c	(revision 27)
+++ demo/demo.c	(working copy)
@@ -396,7 +396,6 @@ on_button_release (GooCanvasItem *item,
 #if 0
   g_print ("received 'button-release' signal\n");
 #endif
-
   canvas = goo_canvas_item_get_canvas (item);
   goo_canvas_pointer_ungrab (canvas, item, event->time);
   dragging = FALSE;
@@ -733,7 +732,7 @@ create_canvas_primitives ()
 
 
 static void
-setup_heading (GooCanvasItem *root, char *text, int pos)
+setup_heading (GooCanvasContainer *root, char *text, int pos)
 {
   double x = (pos % 3) * 200 + 100;
   double y = (pos / 3) * 150 + 5;
@@ -756,43 +755,47 @@ setup_heading (GooCanvasItem *root, char
 
 
 static void
-setup_divisions (GooCanvasItem *root)
+setup_divisions (GooCanvasContainer *root)
 {
   GooCanvasItem *group, *item;
 
   group = goo_canvas_group_new (root, NULL);
   goo_canvas_item_translate (group, 2, 2);
 
-  item = goo_canvas_rect_new (group, 0, 0, 600, 450,
+  item = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (group), 0, 0, 600, 450,
 			      "line-width", 4.0,
 			      NULL);
 
-  item = goo_canvas_polyline_new_line (group, 0, 150, 600, 150,
+  item = goo_canvas_polyline_new_line (GOO_CANVAS_CONTAINER (group),
+                              0, 150, 600, 150,
 			      "line-width", 4.0,
 			      NULL);
 
-  item = goo_canvas_polyline_new_line (group, 0, 300, 600, 300,
+  item = goo_canvas_polyline_new_line (GOO_CANVAS_CONTAINER (group),
+                              0, 300, 600, 300,
 			      "line-width", 4.0,
 			      NULL);
 
-  item = goo_canvas_polyline_new_line (group, 200, 0, 200, 450,
+  item = goo_canvas_polyline_new_line (GOO_CANVAS_CONTAINER (group),
+                              200, 0, 200, 450,
 			      "line-width", 4.0,
 			      NULL);
 
-  item = goo_canvas_polyline_new_line (group, 400, 0, 400, 450,
+  item = goo_canvas_polyline_new_line (GOO_CANVAS_CONTAINER (group),
+                              400, 0, 400, 450,
 			      "line-width", 4.0,
 			      NULL);
 
 #if 1
-  setup_heading (group, "Rectangles", 0);
-  setup_heading (group, "Ellipses", 1);
-  setup_heading (group, "Texts", 2);
-  setup_heading (group, "Images", 3);
-  setup_heading (group, "Lines", 4);
-  /*setup_heading (group, "No Curves", 5);*/
-  /*setup_heading (group, "Arcs", 6);*/
-  setup_heading (group, "Polygons", 7);
-  /*setup_heading (group, "Widgets", 8);*/
+  setup_heading (GOO_CANVAS_CONTAINER (group), "Rectangles", 0);
+  setup_heading (GOO_CANVAS_CONTAINER (group), "Ellipses", 1);
+  setup_heading (GOO_CANVAS_CONTAINER (group), "Texts", 2);
+  setup_heading (GOO_CANVAS_CONTAINER (group), "Images", 3);
+  setup_heading (GOO_CANVAS_CONTAINER (group), "Lines", 4);
+  /*setup_heading (GOO_CANVAS_CONTAINER (group), "No Curves", 5);*/
+  /*setup_heading (GOO_CANVAS_CONTAINER (group), "Arcs", 6);*/
+  setup_heading (GOO_CANVAS_CONTAINER (group), "Polygons", 7);
+  /*setup_heading (GOO_CANVAS_CONTAINER (group), "Widgets", 8);*/
 #endif
 }
 
@@ -820,7 +823,7 @@ create_stipple (const char *color_name, 
 }
 
 static void
-setup_rectangles (GooCanvasItem *root)
+setup_rectangles (GooCanvasContainer *root)
 {
   GooCanvasItem *item;
   cairo_pattern_t *pattern;
@@ -872,7 +875,7 @@ setup_rectangles (GooCanvasItem *root)
 
 
 static void
-setup_ellipses (GooCanvasItem *root)
+setup_ellipses (GooCanvasContainer *root)
 {
   GooCanvasItem *ellipse1, *ellipse3;
   cairo_pattern_t *pattern;
@@ -917,7 +920,7 @@ setup_ellipses (GooCanvasItem *root)
 #define RADIUS 60.0
 
 static void
-polish_diamond (GooCanvasItem *root)
+polish_diamond (GooCanvasContainer *root)
 {
   GooCanvasItem *group, *item;
   int i, j;
@@ -939,7 +942,8 @@ polish_diamond (GooCanvasItem *root)
       a = 2.0 * M_PI * j / VERTICES;
       x2 = RADIUS * cos (a);
       y2 = RADIUS * sin (a);
-      item = goo_canvas_polyline_new_line (group, x1, y1, x2, y2, NULL);
+      item = goo_canvas_polyline_new_line (GOO_CANVAS_CONTAINER (group),
+                                           x1, y1, x2, y2, NULL);
     }
   }
 }
@@ -948,7 +952,7 @@ polish_diamond (GooCanvasItem *root)
 #define SCALE 7.0
 
 static void
-make_hilbert (GooCanvasItem *root)
+make_hilbert (GooCanvasContainer *root)
 {
   char hilbert[] = "urdrrulurulldluuruluurdrurddldrrruluurdrurddldrddlulldrdldrrurd";
   char *c;
@@ -1003,7 +1007,7 @@ make_hilbert (GooCanvasItem *root)
 }
 
 static void
-setup_lines (GooCanvasItem *root)
+setup_lines (GooCanvasContainer *root)
 {
   GooCanvasItem *polyline1, *polyline2, *polyline3, *polyline4, *polyline5;
 
@@ -1069,7 +1073,7 @@ setup_lines (GooCanvasItem *root)
 
 
 static void
-setup_polygons (GooCanvasItem *root)
+setup_polygons (GooCanvasContainer *root)
 {
   GooCanvasItem *polyline1, *polyline2;
   GooCanvasPoints *points;
@@ -1136,8 +1140,8 @@ setup_polygons (GooCanvasItem *root)
 }
 
 
-static GooCanvasItem *
-make_anchor (GooCanvasItem *root, double x, double y)
+static GooCanvasContainer *
+make_anchor (GooCanvasContainer *root, double x, double y)
 {
   GooCanvasItem *group, *item;
   cairo_matrix_t transform = { 0.8, 0.2, -0.3, 0.5, x, y };
@@ -1150,16 +1154,16 @@ make_anchor (GooCanvasItem *root, double
 		NULL);
 #endif
 
-  item = goo_canvas_rect_new (group, -2.5, -2.5, 4, 4,
+  item = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (group), -2.5, -2.5, 4, 4,
 			      "line-width", 1.0,
 			      NULL);
   setup_item_signals (item);
 
-  return group;
+  return GOO_CANVAS_CONTAINER (group);
 }
 
 static void 
-setup_texts (GooCanvasItem *root)
+setup_texts (GooCanvasContainer *root)
 {
   GooCanvasItem *item;
   cairo_pattern_t *pattern;
@@ -1225,7 +1229,7 @@ setup_texts (GooCanvasItem *root)
 
 
 static void
-setup_invisible_texts (GooCanvasItem *root)
+setup_invisible_texts (GooCanvasContainer *root)
 {
   goo_canvas_text_new (root, "Visible above 0.8x", 500, 330, -1,
 		       GTK_ANCHOR_CENTER,
@@ -1273,7 +1277,7 @@ setup_invisible_texts (GooCanvasItem *ro
 
 
 static void
-plant_flower (GooCanvasItem *root, double x, double y, GtkAnchorType anchor)
+plant_flower (GooCanvasContainer *root, double x, double y, GtkAnchorType anchor)
 {
   cairo_pattern_t *pattern;
   cairo_surface_t *surface;
@@ -1297,7 +1301,7 @@ plant_flower (GooCanvasItem *root, doubl
 }
 
 static void
-setup_images (GooCanvasItem *root)
+setup_images (GooCanvasContainer *root)
 {
   GdkPixbuf *im;
   GooCanvasItem *image;
@@ -1333,7 +1337,7 @@ setup_static_items (GooCanvas *canvas)
 
   static_root = goo_canvas_get_static_root_item (canvas);
 
-  item = goo_canvas_polyline_new_line (static_root,
+  item = goo_canvas_polyline_new_line (GOO_CANVAS_CONTAINER (static_root),
 				       40.0, 410.0,
 				       40.0, 330.0,
 				       "stroke-color", "midnightblue",
@@ -1345,7 +1349,7 @@ setup_static_items (GooCanvas *canvas)
 				       NULL);
   setup_item_signals (item);
 
-  item = goo_canvas_polyline_new_line (static_root,
+  item = goo_canvas_polyline_new_line (GOO_CANVAS_CONTAINER (static_root),
 				       32.0, 370.0,
 				       48.0, 370.0,
 				       "stroke-color", "midnightblue",
@@ -1353,7 +1357,8 @@ setup_static_items (GooCanvas *canvas)
 				       NULL);
   setup_item_signals (item);
 
-  item = goo_canvas_text_new (static_root, "N", 40, 320, -1, GTK_ANCHOR_S,
+  item = goo_canvas_text_new (GOO_CANVAS_CONTAINER (static_root),
+                              "N", 40, 320, -1, GTK_ANCHOR_S,
 			      "font", "Sans 12",
 			      NULL);
   setup_item_signals (item);
@@ -1440,7 +1445,7 @@ test_simple_transforms (GooCanvasItem *r
 
 
 static void
-setup_grids (GooCanvasItem *root)
+setup_grids (GooCanvasContainer *root)
 {
   GooCanvasItem *item;
 
@@ -1468,16 +1473,16 @@ setup_canvas (GooCanvas *canvas)
 
   /* Setup canvas items */
 #if 1
-  setup_divisions (root);
-  setup_rectangles (root);
-  setup_ellipses (root);
-  setup_lines (root);
-  setup_polygons (root);
-  setup_texts (root); 
-  setup_images (root);
-  setup_invisible_texts (root);
+  setup_divisions (GOO_CANVAS_CONTAINER (root));
+  setup_rectangles (GOO_CANVAS_CONTAINER (root));
+  setup_ellipses (GOO_CANVAS_CONTAINER (root));
+  setup_lines (GOO_CANVAS_CONTAINER (root));
+  setup_polygons (GOO_CANVAS_CONTAINER (root));
+  setup_texts (GOO_CANVAS_CONTAINER (root)); 
+  setup_images (GOO_CANVAS_CONTAINER (root));
+  setup_invisible_texts (GOO_CANVAS_CONTAINER (root));
   setup_static_items (canvas);
-  setup_grids (root);
+  setup_grids (GOO_CANVAS_CONTAINER (root));
 #endif
 
   test_color_properties (root);
Index: demo/demo-item.h
===================================================================
--- demo/demo-item.h	(revision 27)
+++ demo/demo-item.h	(working copy)
@@ -39,7 +39,7 @@ struct _GooDemoItemClass
 
 GType               goo_demo_item_get_type  (void) G_GNUC_CONST;
 
-GooCanvasItem*      goo_demo_item_new       (GooCanvasItem      *parent,
+GooCanvasItem*      goo_demo_item_new       (GooCanvasContainer *parent,
 					     gdouble             x,
 					     gdouble             y,
 					     gdouble             width,
Index: demo/widgets-demo.c
===================================================================
--- demo/widgets-demo.c	(revision 27)
+++ demo/widgets-demo.c	(working copy)
@@ -19,7 +19,7 @@ add_widget_clicked (GtkWidget *button, g
     widget = gtk_entry_new ();
 
   root = goo_canvas_get_root_item (GOO_CANVAS (canvas));
-  witem = goo_canvas_widget_new (root, widget,
+  witem = goo_canvas_widget_new (GOO_CANVAS_CONTAINER (root), widget,
 				 num_added_widgets * 50,
 				 num_added_widgets * 50,
 				 200, 50, NULL);
@@ -242,7 +242,8 @@ create_focus_box (GtkWidget     *canvas,
   GooCanvasItem *root, *item;
 
   root = goo_canvas_get_root_item (GOO_CANVAS (canvas));
-  item = goo_canvas_rect_new (root, x, y, width, height,
+  item = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root),
+                              x, y, width, height,
 			      "stroke-pattern", NULL,
 			      "fill-color", color,
 			      "line-width", 5.0,
@@ -361,21 +362,25 @@ main (int argc, char *argv[])
 
   /* Add a few simple items. */
   label = gtk_label_new ("Hello World");
-  witem = goo_canvas_widget_new (root, label, 50, 50, 200, 100, NULL);
+  witem = goo_canvas_widget_new (GOO_CANVAS_CONTAINER (root),
+                                 label, 50, 50, 200, 100, NULL);
   g_object_set_data (G_OBJECT (witem), "id", "hello");
 
   entry = gtk_entry_new ();
-  move_item = goo_canvas_widget_new (root, entry, 50, 250, 200, 50, NULL);
+  move_item = goo_canvas_widget_new (GOO_CANVAS_CONTAINER (root),
+                                     entry, 50, 250, 200, 50, NULL);
   g_object_set_data (G_OBJECT (move_item), "id", "entry1");
 
   entry = gtk_entry_new ();
   gtk_entry_set_text (GTK_ENTRY (entry), "Size: -1 x -1");
-  witem = goo_canvas_widget_new (root, entry, 50, 300, -1, -1, NULL);
+  witem = goo_canvas_widget_new (GOO_CANVAS_CONTAINER (root),
+                                 entry, 50, 300, -1, -1, NULL);
   g_object_set_data (G_OBJECT (witem), "id", "entry2");
 
   entry = gtk_entry_new ();
   gtk_entry_set_text (GTK_ENTRY (entry), "Size: 100 x -1");
-  witem = goo_canvas_widget_new (root, entry, 50, 350, 100, -1, NULL);
+  witem = goo_canvas_widget_new (GOO_CANVAS_CONTAINER (root),
+                                 entry, 50, 350, 100, -1, NULL);
   g_object_set_data (G_OBJECT (witem), "id", "entry3");
 
   /* Use a textview so we can see the width & height of the widget. */
@@ -390,7 +395,8 @@ main (int argc, char *argv[])
   gtk_widget_show (textview);
   gtk_container_add (GTK_CONTAINER (scrolled_win), textview);
   gtk_widget_set_size_request (scrolled_win, 160, 50);
-  witem = goo_canvas_widget_new (root, scrolled_win, 50, 400, -1, 100, NULL);
+  witem = goo_canvas_widget_new (GOO_CANVAS_CONTAINER (root),
+                                 scrolled_win, 50, 400, -1, 100, NULL);
   g_object_set_data (G_OBJECT (witem), "id", "scrolledwin");
 
   /* Create a vbox item with several child entry widgets to check focus
@@ -409,7 +415,8 @@ main (int argc, char *argv[])
   gtk_widget_show (entry);
   gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
 
-  witem = goo_canvas_widget_new (root, vbox, 50, 600, -1, -1, NULL);
+  witem = goo_canvas_widget_new (GOO_CANVAS_CONTAINER (root),
+                                 vbox, 50, 600, -1, -1, NULL);
   g_object_set_data (G_OBJECT (witem), "id", "vbox");
 
   /* Create a few normal canvas items that take keyboard focus. */
Index: demo/mv-demo-table.c
===================================================================
--- demo/mv-demo-table.c	(revision 27)
+++ demo/mv-demo-table.c	(working copy)
@@ -41,39 +41,46 @@ create_demo_item (GooCanvasItemModel *ta
   switch (demo_item_type)
     {
     case DEMO_RECT_ITEM:
-      model = goo_canvas_rect_model_new (table, 0, 0, 38, 19,
+      model = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (table),
+                                         0, 0, 38, 19,
 					 "fill-color", "red",
 					 NULL);
       break;
     case DEMO_TEXT_ITEM:
-      model = goo_canvas_text_model_new (table, text, 0, 0, -1, GTK_ANCHOR_NW,
+      model = goo_canvas_text_model_new (GOO_CANVAS_CONTAINER_MODEL (table),
+                                         text, 0, 0, -1, GTK_ANCHOR_NW,
 					 NULL);
       break;
     }
 
   g_value_init (&value, G_TYPE_UINT);
   g_value_set_uint (&value, row);
-  goo_canvas_item_model_set_child_property (table, model, "row", &value);
+  goo_canvas_container_model_set_child_property (GOO_CANVAS_CONTAINER_MODEL (table),
+                                                 model, "row", &value);
   g_value_set_uint (&value, column);
-  goo_canvas_item_model_set_child_property (table, model, "column", &value);
+  goo_canvas_container_model_set_child_property (GOO_CANVAS_CONTAINER_MODEL (table),
+                                                 model, "column", &value);
   g_value_set_uint (&value, rows);
-  goo_canvas_item_model_set_child_property (table, model, "rows", &value);
+  goo_canvas_container_model_set_child_property (GOO_CANVAS_CONTAINER_MODEL (table),
+                                                 model, "rows", &value);
   g_value_set_uint (&value, columns);
-  goo_canvas_item_model_set_child_property (table, model, "columns", &value);
+  goo_canvas_container_model_set_child_property (GOO_CANVAS_CONTAINER_MODEL (table),
+                                                 model, "columns", &value);
 
   /* Test the get function. */
-  goo_canvas_item_model_get_child_property (table, model, "row", &value);
+  goo_canvas_container_model_get_child_property (GOO_CANVAS_CONTAINER_MODEL (table), model, "row", &value);
   new_row = g_value_get_uint (&value);
   if (new_row != row)
     g_warning ("Got bad row setting: %i should be: %i\n", new_row, row);
 
 #if 1
-  goo_canvas_item_model_set_child_properties (table, model,
-					      "x-expand", TRUE,
-					      "x-fill", TRUE,
-					      "y-expand", TRUE,
-					      "y-fill", TRUE,
-					      NULL);
+  goo_canvas_container_model_set_child_properties (GOO_CANVAS_CONTAINER_MODEL (table),
+                                                   model,
+					           "x-expand", TRUE,
+					           "x-fill", TRUE,
+					           "y-expand", TRUE,
+					           "y-fill", TRUE,
+					           NULL);
 #endif
 
   item = goo_canvas_get_item (canvas, model);
@@ -84,7 +91,7 @@ create_demo_item (GooCanvasItemModel *ta
 
 
 static GooCanvasItemModel*
-create_table (GooCanvasItemModel *parent,
+create_table (GooCanvasContainerModel *parent,
 	      gint           row,
 	      gint           column,
 	      gint           embedding_level,
@@ -110,31 +117,31 @@ create_table (GooCanvasItemModel *parent
 #endif
 
   if (row != -1)
-    goo_canvas_item_model_set_child_properties (parent, table,
-						"row", row,
-						"column", column,
+    goo_canvas_container_model_set_child_properties (parent, table,
+						     "row", row,
+						     "column", column,
 #if 1
-						"x-expand", TRUE,
-						"x-fill", TRUE,
+					 	     "x-expand", TRUE,
+		 		 		     "x-fill", TRUE,
 #endif
 #if 0
-						"y-expand", TRUE,
-						"y-fill", TRUE,
+						     "y-expand", TRUE,
+						     "y-fill", TRUE,
 #endif
-					  NULL);
+					             NULL);
 
   if (embedding_level)
     {
       gint level = embedding_level - 1;
-      create_table (table, 0, 0, level, 50, 50, 0, 0.7, demo_item_type);
-      create_table (table, 0, 1, level, 50, 50, 45, 1.0, demo_item_type);
-      create_table (table, 0, 2, level, 50, 50, 90, 1.0, demo_item_type);
-      create_table (table, 1, 0, level, 50, 50, 135, 1.0, demo_item_type);
-      create_table (table, 1, 1, level, 50, 50, 180, 1.5, demo_item_type);
-      create_table (table, 1, 2, level, 50, 50, 225, 1.0, demo_item_type);
-      create_table (table, 2, 0, level, 50, 50, 270, 1.0, demo_item_type);
-      create_table (table, 2, 1, level, 50, 50, 315, 1.0, demo_item_type);
-      create_table (table, 2, 2, level, 50, 50, 360, 2.0, demo_item_type);
+      create_table (GOO_CANVAS_CONTAINER_MODEL (table), 0, 0, level, 50, 50, 0, 0.7, demo_item_type);
+      create_table (GOO_CANVAS_CONTAINER_MODEL (table), 0, 1, level, 50, 50, 45, 1.0, demo_item_type);
+      create_table (GOO_CANVAS_CONTAINER_MODEL (table), 0, 2, level, 50, 50, 90, 1.0, demo_item_type);
+      create_table (GOO_CANVAS_CONTAINER_MODEL (table), 1, 0, level, 50, 50, 135, 1.0, demo_item_type);
+      create_table (GOO_CANVAS_CONTAINER_MODEL (table), 1, 1, level, 50, 50, 180, 1.5, demo_item_type);
+      create_table (GOO_CANVAS_CONTAINER_MODEL (table), 1, 2, level, 50, 50, 225, 1.0, demo_item_type);
+      create_table (GOO_CANVAS_CONTAINER_MODEL (table), 2, 0, level, 50, 50, 270, 1.0, demo_item_type);
+      create_table (GOO_CANVAS_CONTAINER_MODEL (table), 2, 1, level, 50, 50, 315, 1.0, demo_item_type);
+      create_table (GOO_CANVAS_CONTAINER_MODEL (table), 2, 2, level, 50, 50, 360, 2.0, demo_item_type);
     }
   else
     {
@@ -154,11 +161,11 @@ create_table (GooCanvasItemModel *parent
 
 
 static void
-create_demo_table (GooCanvasItemModel *root,
-		   gdouble        x,
-		   gdouble        y,
-		   gdouble        width,
-		   gdouble        height)
+create_demo_table (GooCanvasContainerModel *root,
+		   gdouble                  x,
+		   gdouble                  y,
+		   gdouble                  width,
+		   gdouble                  height)
 {
   GooCanvasItemModel *table, *square, *circle, *triangle;
   GooCanvasItem *item;
@@ -171,41 +178,46 @@ create_demo_table (GooCanvasItemModel *r
 				      NULL);
   goo_canvas_item_model_translate (table, x, y);
 
-  square = goo_canvas_rect_model_new (table, 0.0, 0.0, 50.0, 50.0,
+  square = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (table),
+                                      0.0, 0.0, 50.0, 50.0,
 				      "fill-color", "red",
 				      NULL);
-  goo_canvas_item_model_set_child_properties (table, square,
-					      "row", 0,
-					      "column", 0,
-					      "x-shrink", TRUE,
-					      NULL);
+  goo_canvas_container_model_set_child_properties (GOO_CANVAS_CONTAINER_MODEL (table),
+                                                   square,
+					           "row", 0,
+					           "column", 0,
+					           "x-shrink", TRUE,
+					           NULL);
   item = goo_canvas_get_item (canvas, square);
   g_object_set_data (G_OBJECT (item), "id", "Red square");
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), NULL);
 
-  circle = goo_canvas_ellipse_model_new (table, 0.0, 0.0, 25.0, 25.0,
+  circle = goo_canvas_ellipse_model_new (GOO_CANVAS_CONTAINER_MODEL (table),
+                                         0.0, 0.0, 25.0, 25.0,
 					 "fill-color", "blue",
 					 NULL);
-  goo_canvas_item_model_set_child_properties (table, circle,
-					      "row", 0,
-					      "column", 1,
-					      "x-shrink", TRUE,
-					      NULL);
+  goo_canvas_container_model_set_child_properties (GOO_CANVAS_CONTAINER_MODEL (table), circle,
+					           "row", 0,
+					           "column", 1,
+					           "x-shrink", TRUE,
+					           NULL);
   item = goo_canvas_get_item (canvas, circle);
   g_object_set_data (G_OBJECT (item), "id", "Blue circle");
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), NULL);
 
-  triangle = goo_canvas_polyline_model_new (table, TRUE, 3,
+  triangle = goo_canvas_polyline_model_new (GOO_CANVAS_CONTAINER_MODEL (table),
+                                            TRUE, 3,
 					    25.0, 0.0, 0.0, 50.0, 50.0, 50.0,
 					    "fill-color", "yellow",
 					    NULL);
-  goo_canvas_item_model_set_child_properties (table, triangle,
-					      "row", 0,
-					      "column", 2,
-					      "x-shrink", TRUE,
-					      NULL);
+  goo_canvas_container_model_set_child_properties (GOO_CANVAS_CONTAINER_MODEL (table),
+                                                   triangle,
+					           "row", 0,
+					           "column", 2,
+					           "x-shrink", TRUE,
+					           NULL);
   item = goo_canvas_get_item (canvas, triangle);
   g_object_set_data (G_OBJECT (item), "id", "Yellow triangle");
   g_signal_connect (item, "button_press_event",
@@ -214,12 +226,12 @@ create_demo_table (GooCanvasItemModel *r
 
 
 static void
-create_width_for_height_table (GooCanvasItemModel *root,
-			       gdouble        x,
-			       gdouble        y,
-			       gdouble        width,
-			       gdouble        height,
-			       gdouble        rotation)
+create_width_for_height_table (GooCanvasContainerModel *root,
+			       gdouble                  x,
+			       gdouble                  y,
+			       gdouble                  width,
+			       gdouble                  height,
+			       gdouble                  rotation)
 {
   GooCanvasItemModel *table, *model;
   GooCanvasItem *item;
@@ -234,40 +246,46 @@ create_width_for_height_table (GooCanvas
   goo_canvas_item_model_translate (table, x, y);
   goo_canvas_item_model_rotate (table, rotation, 0, 0);
 
-  model = goo_canvas_rect_model_new (table, 0.0, 0.0, width - 2, 10.0,
+  model = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (table),
+                                     0.0, 0.0, width - 2, 10.0,
 				     "fill-color", "red",
 				     NULL);
-  goo_canvas_item_model_set_child_properties (table, model,
-					      "row", 0,
-					      "column", 0,
-					      "x-shrink", TRUE,
-					      NULL);
-
-#if 1
-  model = goo_canvas_text_model_new (table, text, 0, 0, -1, GTK_ANCHOR_NW, NULL);
-  goo_canvas_item_model_set_child_properties (table, model,
-					      "row", 1,
-					      "column", 0,
-					      "x-expand", TRUE,
-					      "x-fill", TRUE,
-					      "x-shrink", TRUE,
-					      "y-expand", TRUE,
-					      "y-fill", TRUE,
-					      NULL);
+  goo_canvas_container_model_set_child_properties (GOO_CANVAS_CONTAINER_MODEL (table),
+                                                   model,
+					           "row", 0,
+					           "column", 0,
+					           "x-shrink", TRUE,
+					           NULL);
+
+#if 1
+  model = goo_canvas_text_model_new (GOO_CANVAS_CONTAINER_MODEL (table),
+                                     text, 0, 0, -1, GTK_ANCHOR_NW, NULL);
+  goo_canvas_container_model_set_child_properties (GOO_CANVAS_CONTAINER_MODEL (table),
+                                                   model,
+					           "row", 1,
+					           "column", 0,
+					           "x-expand", TRUE,
+					           "x-fill", TRUE,
+					           "x-shrink", TRUE,
+				 	           "y-expand", TRUE,
+			 		           "y-fill", TRUE,
+					           NULL);
   item = goo_canvas_get_item (canvas, model);
   g_object_set_data (G_OBJECT (item), "id", "Text Item");
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), NULL);
 #endif
 
-  model = goo_canvas_rect_model_new (table, 0.0, 0.0, width - 2, 10.0,
+  model = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (table),
+                                     0.0, 0.0, width - 2, 10.0,
 				     "fill-color", "red",
 				     NULL);
-  goo_canvas_item_model_set_child_properties (table, model,
-					      "row", 2,
-					      "column", 0,
-					      "x-shrink", TRUE,
-					      NULL);
+  goo_canvas_container_model_set_child_properties (GOO_CANVAS_CONTAINER_MODEL (table),
+                                                   model,
+					           "row", 2,
+					           "column", 0,
+					           "x-shrink", TRUE,
+					           NULL);
 }
 
 
@@ -297,37 +315,48 @@ create_table_page (void)
   g_object_unref (root);
 
 #if 1
-  create_demo_table (root, 400, 200, -1, -1);
-  create_demo_table (root, 400, 260, 100, -1);
+  create_demo_table (GOO_CANVAS_CONTAINER_MODEL (root), 400, 200, -1, -1);
+  create_demo_table (GOO_CANVAS_CONTAINER_MODEL (root), 400, 260, 100, -1);
 #endif
 
 #if 1
-  create_table (root, -1, -1, 0, 10, 10, 0, 1.0, DEMO_TEXT_ITEM);
-  create_table (root, -1, -1, 0, 180, 10, 30, 1.0, DEMO_TEXT_ITEM);
-  create_table (root, -1, -1, 0, 350, 10, 60, 1.0, DEMO_TEXT_ITEM);
-  create_table (root, -1, -1, 0, 500, 10, 90, 1.0, DEMO_TEXT_ITEM);
+  create_table (GOO_CANVAS_CONTAINER_MODEL (root),
+                -1, -1, 0, 10, 10, 0, 1.0, DEMO_TEXT_ITEM);
+  create_table (GOO_CANVAS_CONTAINER_MODEL (root),
+                -1, -1, 0, 180, 10, 30, 1.0, DEMO_TEXT_ITEM);
+  create_table (GOO_CANVAS_CONTAINER_MODEL (root),
+                -1, -1, 0, 350, 10, 60, 1.0, DEMO_TEXT_ITEM);
+  create_table (GOO_CANVAS_CONTAINER_MODEL (root),
+                -1, -1, 0, 500, 10, 90, 1.0, DEMO_TEXT_ITEM);
 #endif
 
 #if 1
-  table = create_table (root, -1, -1, 0, 30, 150, 0, 1.0, DEMO_TEXT_ITEM);
+  table = create_table (GOO_CANVAS_CONTAINER_MODEL (root),
+                        -1, -1, 0, 30, 150, 0, 1.0, DEMO_TEXT_ITEM);
   g_object_set (table, "width", 300.0, "height", 100.0, NULL);
 #endif
 
 #if 1
-  create_table (root, -1, -1, 1, 200, 200, 30, 0.8, DEMO_TEXT_ITEM);
+  create_table (GOO_CANVAS_CONTAINER_MODEL (root),
+                -1, -1, 1, 200, 200, 30, 0.8, DEMO_TEXT_ITEM);
 #endif
 
 #if 0
-  table = create_table (root, -1, -1, 0, 10, 700, 0, 1.0, DEMO_WIDGET_ITEM);
+  table = create_table (GOO_CANVAS_CONTAINER_MODEL (root),
+                        -1, -1, 0, 10, 700, 0, 1.0, DEMO_WIDGET_ITEM);
   g_object_set (table, "width", 300.0, "height", 200.0, NULL);
 #endif
 
-  create_width_for_height_table (root, 100, 1000, 200, -1, 0);
+  create_width_for_height_table (GOO_CANVAS_CONTAINER_MODEL (root),
+                                 100, 1000, 200, -1, 0);
 #if 1
-  create_width_for_height_table (root, 100, 1200, 300, -1, 0);
+  create_width_for_height_table (GOO_CANVAS_CONTAINER_MODEL (root),
+                                 100, 1200, 300, -1, 0);
 
-  create_width_for_height_table (root, 500, 1000, 200, -1, 30);
-  create_width_for_height_table (root, 500, 1200, 300, -1, 30);
+  create_width_for_height_table (GOO_CANVAS_CONTAINER_MODEL (root),
+                                 500, 1000, 200, -1, 30);
+  create_width_for_height_table (GOO_CANVAS_CONTAINER_MODEL (root),
+                                 500, 1200, 300, -1, 30);
 #endif
 
   gtk_widget_show ((GtkWidget*) canvas);
Index: demo/mv-simple-demo.c
===================================================================
--- demo/mv-simple-demo.c	(revision 27)
+++ demo/mv-simple-demo.c	(working copy)
@@ -45,7 +45,8 @@ main (int argc, char *argv[])
   root = goo_canvas_group_model_new (NULL, NULL);
 
   /* Add a few simple items. */
-  rect_model = goo_canvas_rect_model_new (root, 100, 100, 400, 400,
+  rect_model = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                          100, 100, 400, 400,
 					  "line-width", 10.0,
 					  "radius-x", 20.0,
 					  "radius-y", 10.0,
@@ -53,7 +54,8 @@ main (int argc, char *argv[])
 					  "fill-color", "red",
 					  NULL);
 
-  text_model = goo_canvas_text_model_new (root, "Hello World", 300, 300, -1,
+  text_model = goo_canvas_text_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                          "Hello World", 300, 300, -1,
 					  GTK_ANCHOR_CENTER,
 					  "font", "Sans 24",
 					  NULL);
Index: demo/demo-arrowhead.c
===================================================================
--- demo/demo-arrowhead.c	(revision 27)
+++ demo/demo-arrowhead.c	(working copy)
@@ -189,7 +189,7 @@ set_arrow_shape (GooCanvas *canvas)
 
 static void
 create_dimension (GtkWidget *canvas,
-		  GooCanvasItem *root,
+		  GooCanvasContainer *root,
 		  char *arrow_name,
 		  char *text_name,
 		  GtkAnchorType anchor)
@@ -212,7 +212,7 @@ create_dimension (GtkWidget *canvas,
 
 static void
 create_info (GtkWidget *canvas,
-	     GooCanvasItem *root,
+	     GooCanvasContainer *root,
 	     char *info_name,
 	     double x,
 	     double y)
@@ -228,7 +228,7 @@ create_info (GtkWidget *canvas,
 
 static void
 create_sample_arrow (GtkWidget *canvas,
-		     GooCanvasItem *root,
+		     GooCanvasContainer *root,
 		     char *sample_name,
 		     double x1,
 		     double y1,
@@ -372,7 +372,7 @@ on_motion (GooCanvasItem *item,
 
 static void
 create_drag_box (GtkWidget *canvas,
-		 GooCanvasItem *root,
+		 GooCanvasContainer *root,
 		 char *box_name)
 {
   GooCanvasItem *item;
@@ -450,7 +450,7 @@ create_canvas_arrowhead (void)
 
 	/* Big arrow */
 
-	item = goo_canvas_polyline_new_line (root,
+	item = goo_canvas_polyline_new_line (GOO_CANVAS_CONTAINER (root),
 					     LEFT, MIDDLE, RIGHT, MIDDLE,
 					     "stroke_color", "mediumseagreen",
 					     "end-arrow", TRUE,
@@ -459,7 +459,7 @@ create_canvas_arrowhead (void)
 
 	/* Arrow outline */
 
-	item = goo_canvas_polyline_new (root, TRUE, 0,
+	item = goo_canvas_polyline_new (GOO_CANVAS_CONTAINER (root), TRUE, 0,
 					"stroke_color", "black",
 					"line-width", 2.0,
 					"line-cap", CAIRO_LINE_CAP_ROUND,
@@ -469,38 +469,39 @@ create_canvas_arrowhead (void)
 
 	/* Drag boxes */
 
-	create_drag_box (canvas, root, "width_drag_box");
-	create_drag_box (canvas, root, "shape_a_drag_box");
-	create_drag_box (canvas, root, "shape_b_c_drag_box");
+	create_drag_box (canvas, GOO_CANVAS_CONTAINER (root), "width_drag_box");
+	create_drag_box (canvas, GOO_CANVAS_CONTAINER (root), "shape_a_drag_box");
+	create_drag_box (canvas, GOO_CANVAS_CONTAINER (root), "shape_b_c_drag_box");
 
 	/* Dimensions */
 
-	create_dimension (canvas, root, "width_arrow", "width_text", GTK_ANCHOR_E);
-	create_dimension (canvas, root, "shape_a_arrow", "shape_a_text", GTK_ANCHOR_N);
-	create_dimension (canvas, root, "shape_b_arrow", "shape_b_text", GTK_ANCHOR_N);
-	create_dimension (canvas, root, "shape_c_arrow", "shape_c_text", GTK_ANCHOR_W);
+	create_dimension (canvas, GOO_CANVAS_CONTAINER (root), "width_arrow", "width_text", GTK_ANCHOR_E);
+	create_dimension (canvas, GOO_CANVAS_CONTAINER (root), "shape_a_arrow", "shape_a_text", GTK_ANCHOR_N);
+	create_dimension (canvas, GOO_CANVAS_CONTAINER (root), "shape_b_arrow", "shape_b_text", GTK_ANCHOR_N);
+	create_dimension (canvas, GOO_CANVAS_CONTAINER (root), "shape_c_arrow", "shape_c_text", GTK_ANCHOR_W);
 
 	/* Info */
 
-	create_info (canvas, root, "width_info", LEFT, 260);
-	create_info (canvas, root, "shape_a_info", LEFT, 280);
-	create_info (canvas, root, "shape_b_info", LEFT, 300);
-	create_info (canvas, root, "shape_c_info", LEFT, 320);
+	create_info (canvas, GOO_CANVAS_CONTAINER (root), "width_info", LEFT, 260);
+	create_info (canvas, GOO_CANVAS_CONTAINER (root), "shape_a_info", LEFT, 280);
+	create_info (canvas, GOO_CANVAS_CONTAINER (root), "shape_b_info", LEFT, 300);
+	create_info (canvas, GOO_CANVAS_CONTAINER (root), "shape_c_info", LEFT, 320);
 
 	/* Division line */
 
-	goo_canvas_polyline_new_line (root, RIGHT + 50, 0, RIGHT + 50, 1000,
+	goo_canvas_polyline_new_line (GOO_CANVAS_CONTAINER (root),
+	                              RIGHT + 50, 0, RIGHT + 50, 1000,
 				      "fill_color", "black",
 				      "line-width", 2.0,
 				      NULL);
 
 	/* Sample arrows */
 
-	create_sample_arrow (canvas, root, "sample_1",
+	create_sample_arrow (canvas, GOO_CANVAS_CONTAINER (root), "sample_1",
 			     RIGHT + 100, 30, RIGHT + 100, MIDDLE - 30);
-	create_sample_arrow (canvas, root, "sample_2",
+	create_sample_arrow (canvas, GOO_CANVAS_CONTAINER (root), "sample_2",
 			     RIGHT + 70, MIDDLE, RIGHT + 130, MIDDLE);
-	create_sample_arrow (canvas, root, "sample_3",
+	create_sample_arrow (canvas, GOO_CANVAS_CONTAINER (root), "sample_3",
 			     RIGHT + 70, MIDDLE + 30, RIGHT + 130, MIDDLE + 120);
 
 	/* Done! */
Index: demo/demo-features.c
===================================================================
--- demo/demo-features.c	(revision 27)
+++ demo/demo-features.c	(working copy)
@@ -16,7 +16,7 @@ on_button_press (GooCanvasItem *item,
 		 GdkEventButton *event,
 		 gpointer data)
 {
-  GooCanvasItem *parent1, *parent2, *parent;
+  GooCanvasContainer *parent1, *parent2, *parent;
 
   if (event->button != 1 || event->type != GDK_BUTTON_PRESS)
     return FALSE;
@@ -30,9 +30,9 @@ on_button_press (GooCanvasItem *item,
   g_object_ref (item);
   goo_canvas_item_remove (item);
   if (parent == parent1)
-    goo_canvas_item_add_child (parent2, item, -1);
+    goo_canvas_container_add_child (parent2, item, -1);
   else
-    goo_canvas_item_add_child (parent1, item, -1);
+    goo_canvas_container_add_child (parent1, item, -1);
   g_object_unref (item);
 
   return TRUE;
@@ -47,7 +47,8 @@ create_canvas_features (void)
 	GtkWidget *alignment;
 	GtkWidget *frame;
 	GtkWidget *canvas;
-	GooCanvasItem *root, *item;
+	GooCanvasItem *root;
+	GooCanvasItem *item;
 	GooCanvasItem *parent1;
 	GooCanvasItem *parent2;
 	GooCanvasItem *group;
@@ -83,24 +84,24 @@ create_canvas_features (void)
 
 	/* First parent and box */
 
-	parent1 = goo_canvas_group_new (root, NULL);
+	parent1 = goo_canvas_group_new (GOO_CANVAS_CONTAINER (root), NULL);
 
-	goo_canvas_rect_new (parent1, 0, 0, 200, 200,
+	goo_canvas_rect_new (GOO_CANVAS_CONTAINER (parent1), 0, 0, 200, 200,
 			     "fill_color", "tan",
 			     NULL);
 
 	/* Second parent and box */
 
-	parent2 = goo_canvas_group_new (root, NULL);
+	parent2 = goo_canvas_group_new (GOO_CANVAS_CONTAINER (root), NULL);
 	goo_canvas_item_translate (parent2, 200, 0);
 
-	goo_canvas_rect_new (parent2, 0, 0, 200, 200,
+	goo_canvas_rect_new (GOO_CANVAS_CONTAINER (parent2), 0, 0, 200, 200,
 			     "fill_color", "#204060",
 			     NULL);
 
 	/* Big circle to be reparented */
 
-	item = goo_canvas_ellipse_new (parent1, 100, 100, 90, 90,
+	item = goo_canvas_ellipse_new (GOO_CANVAS_CONTAINER (parent1), 100, 100, 90, 90,
 				       "stroke_color", "black",
 				       "fill_color", "mediumseagreen",
 				       "line-width", 3.0,
@@ -112,15 +113,15 @@ create_canvas_features (void)
 
 	/* A group to be reparented */
 
-	group = goo_canvas_group_new (parent2, NULL);
+	group = goo_canvas_group_new (GOO_CANVAS_CONTAINER (parent2), NULL);
 	goo_canvas_item_translate (group, 100, 100);
 
-	goo_canvas_ellipse_new (group, 0, 0, 50, 50,
+	goo_canvas_ellipse_new (GOO_CANVAS_CONTAINER (group), 0, 0, 50, 50,
 				"stroke_color", "black",
 				"fill_color", "wheat",
 				"line_width", 3.0,
 				NULL);
-	goo_canvas_ellipse_new (group, 0, 0, 25, 25,
+	goo_canvas_ellipse_new (GOO_CANVAS_CONTAINER (group), 0, 0, 25, 25,
 				"fill_color", "steelblue",
 				NULL);
 
Index: demo/demo-large-line.c
===================================================================
--- demo/demo-large-line.c	(revision 27)
+++ demo/demo-large-line.c	(working copy)
@@ -32,7 +32,7 @@ goo_demo_large_line_init (GooDemoLargeLi
    parent argument and end with a variable list of object properties to fit
    in with the standard canvas items. */
 GooCanvasItem*
-goo_demo_large_line_new (GooCanvasItem      *parent,
+goo_demo_large_line_new (GooCanvasContainer *parent,
 			 gdouble             x1,
 			 gdouble             y1,
 			 gdouble             x2,
@@ -60,7 +60,7 @@ goo_demo_large_line_new (GooCanvasItem  
 
   if (parent)
     {
-      goo_canvas_item_add_child (parent, item, -1);
+      goo_canvas_container_add_child (parent, item, -1);
       g_object_unref (item);
     }
 
Index: demo/demo-animation.c
===================================================================
--- demo/demo-animation.c	(revision 27)
+++ demo/demo-animation.c	(working copy)
@@ -67,35 +67,35 @@ setup_canvas (GtkWidget *canvas)
   root = goo_canvas_get_root_item (GOO_CANVAS (canvas));
 
   /* Absolute. */
-  ellipse1 = goo_canvas_ellipse_new (root, 0, 0, 25, 15,
+  ellipse1 = goo_canvas_ellipse_new (GOO_CANVAS_CONTAINER (root), 0, 0, 25, 15,
 				     "fill-color", "blue",
 				     NULL);
   goo_canvas_item_translate (ellipse1, 100, 100);
   g_signal_connect (ellipse1, "animation_finished",
 		    G_CALLBACK (on_animation_finished), NULL);
 
-  rect1 = goo_canvas_rect_new (root, -10, -10, 20, 20,
+  rect1 = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root), -10, -10, 20, 20,
 			       "fill-color", "blue",
 			       NULL);
   goo_canvas_item_translate (rect1, 100, 200);
 
-  rect3 = goo_canvas_rect_new (root, -10, -10, 20, 20,
+  rect3 = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root), -10, -10, 20, 20,
 			       "fill-color", "blue",
 			       NULL);
   goo_canvas_item_translate (rect3, 200, 200);
 
   /* Relative. */
-  ellipse2 = goo_canvas_ellipse_new (root, 0, 0, 25, 15,
+  ellipse2 = goo_canvas_ellipse_new (GOO_CANVAS_CONTAINER (root), 0, 0, 25, 15,
 				     "fill-color", "red",
 				     NULL);
   goo_canvas_item_translate (ellipse2, 100, 400);
 
-  rect2 = goo_canvas_rect_new (root, -10, -10, 20, 20,
+  rect2 = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root), -10, -10, 20, 20,
 			       "fill-color", "red",
 			       NULL);
   goo_canvas_item_translate (rect2, 100, 500);
 
-  rect4 = goo_canvas_rect_new (root, -10, -10, 20, 20,
+  rect4 = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root), -10, -10, 20, 20,
 			       "fill-color", "red",
 			       NULL);
   goo_canvas_item_translate (rect4, 200, 500);
Index: demo/demo-paths.c
===================================================================
--- demo/demo-paths.c	(revision 27)
+++ demo/demo-paths.c	(working copy)
@@ -38,58 +38,66 @@ setup_canvas (GtkWidget *canvas)
 		    G_CALLBACK (on_background_button_press), NULL);
 
   /* Test the simple commands like moveto and lineto: MmZzLlHhVv. */
-  path1 = goo_canvas_path_new (root, "M 20 20 L 40 40", NULL);
-  path = goo_canvas_path_new (root, "M30 20 l20, 20", NULL);
-  path = goo_canvas_path_new (root, "M 60 20 H 80", NULL);
-  path = goo_canvas_path_new (root, "M60 40 h20", NULL);
-  path = goo_canvas_path_new (root, "M 100,20 V 40", NULL);
-  path = goo_canvas_path_new (root, "M 120 20 v 20", NULL);
-  path = goo_canvas_path_new (root, "M 140 20 h20 v20 h-20 z", NULL);
-  path = goo_canvas_path_new (root,
+  path1 = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
+                               "M 20 20 L 40 40", NULL);
+  path = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
+                              "M30 20 l20, 20", NULL);
+  path = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
+                              "M 60 20 H 80", NULL);
+  path = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
+                              "M60 40 h20", NULL);
+  path = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
+                              "M 100,20 V 40", NULL);
+  path = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
+                              "M 120 20 v 20", NULL);
+  path = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
+                              "M 140 20 h20 v20 h-20 z", NULL);
+  path = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
 			      "M 180 20 h20 v20 h-20 z m 5,5 h10 v10 h-10 z",
 			      "fill-color", "red",
 			      "fill-rule", CAIRO_FILL_RULE_EVEN_ODD,
 			      NULL);
 
-  path = goo_canvas_path_new (root, "M 220 20 L 260 20 L 240 40 z",
+  path = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
+                              "M 220 20 L 260 20 L 240 40 z",
 			      "fill-color", "red",
 			      "stroke-color", "blue",
 			      "line-width", 3.0,
 			      NULL);
 
   /* Test the bezier curve commands: CcSsQqTt. */
-  path = goo_canvas_path_new (root,
+  path = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
 			      "M20,100 C20,50 100,50 100,100 S180,150 180,100",
 			      NULL);
 
-  path = goo_canvas_path_new (root,
+  path = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
 			      "M220,100 c0,-50 80,-50 80,0 s80,50 80,0",
 			      NULL);
 
-  path = goo_canvas_path_new (root,
+  path = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
 			      "M20,200 Q60,130 100,200 T180,200",
 			      NULL);
 
-  path = goo_canvas_path_new (root,
+  path = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
 			      "M220,200 q40,-70 80,0 t80,0",
 			      NULL);
 
   /* Test the elliptical arc commands: Aa. */
-  path = goo_canvas_path_new (root,
+  path = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
 			      "M200,500 h-150 a150,150 0 1,0 150,-150 z",
 			      "fill-color", "red",
 			      "stroke-color", "blue",
 			      "line-width", 5.0,
 			      NULL);
 
-  path = goo_canvas_path_new (root,
+  path = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
 			      "M175,475 v-150 a150,150 0 0,0 -150,150 z",
 			      "fill-color", "yellow",
 			      "stroke-color", "blue",
 			      "line-width", 5.0,
 			      NULL);
 
-  path = goo_canvas_path_new (root,
+  path = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
 			      "M400,600 l 50,-25 "
 			      "a25,25 -30 0,1 50,-25 l 50,-25 "
 			      "a25,50 -30 0,1 50,-25 l 50,-25 "
@@ -99,22 +107,22 @@ setup_canvas (GtkWidget *canvas)
 			      "line-width", 5.0,
 			      NULL);
 
-  path = goo_canvas_path_new (root,
+  path = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
 			      "M 525,75 a100,50 0 0,0 100,50",
 			      "stroke-color", "red",
 			      "line-width", 5.0,
 			      NULL);
-  path = goo_canvas_path_new (root,
+  path = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
 			      "M 725,75 a100,50 0 0,1 100,50",
 			      "stroke-color", "red",
 			      "line-width", 5.0,
 			      NULL);
-  path = goo_canvas_path_new (root,
+  path = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
 			      "M 525,200 a100,50 0 1,0 100,50",
 			      "stroke-color", "red",
 			      "line-width", 5.0,
 			      NULL);
-  path = goo_canvas_path_new (root,
+  path = goo_canvas_path_new (GOO_CANVAS_CONTAINER (root),
 			      "M 725,200 a100,50 0 1,1 100,50",
 			      "stroke-color", "red",
 			      "line-width", 5.0,
Index: demo/mv-scalability-demo.c
===================================================================
--- demo/mv-scalability-demo.c	(revision 27)
+++ demo/mv-scalability-demo.c	(working copy)
@@ -63,7 +63,7 @@ on_motion_notify (GooCanvasItem *item,
 	  return TRUE;
 	}
 
-      ancestor = goo_canvas_item_get_parent (ancestor);
+      ancestor = GOO_CANVAS_ITEM (goo_canvas_item_get_parent (ancestor));
     }
 
   return TRUE;
@@ -147,7 +147,8 @@ setup_canvas (GtkWidget *canvas)
 	  double group_x = left_offset + (group_i * group_width);
 	  double group_y = top_offset + (group_j * group_height);
 
-	  group = goo_canvas_group_model_new (root, NULL);
+	  group = goo_canvas_group_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+	                                      NULL);
 	  total_items++;
 	  goo_canvas_item_model_translate (group, group_x, group_y);
 
@@ -167,14 +168,16 @@ setup_canvas (GtkWidget *canvas)
 			   group_x + item_x, group_y + item_y);
 
 #ifdef USE_PIXMAP
-		  model = goo_canvas_image_model_new (group, NULL,
+		  model = goo_canvas_image_model_new (GOO_CANVAS_CONTAINER_MODEL (group),
+		                                      NULL,
 						      item_x, item_y,
 						      "pattern", pattern,
 						      "width", item_width,
 						      "height", item_height,
 						      NULL);
 #else
-		  model = goo_canvas_rect_model_new (group, item_x, item_y,
+		  model = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (group),
+		                                     item_x, item_y,
 						     item_width, item_height,
 						     NULL);
 #ifdef SET_STYLE
@@ -195,13 +198,14 @@ setup_canvas (GtkWidget *canvas)
 #endif
 
 #ifdef USE_TEXT
-		  model = goo_canvas_text_model_new (group, ids[id_item_num],
+		  model = goo_canvas_text_model_new (GOO_CANVAS_CONTAINER_MODEL (group),
+		                                     ids[id_item_num],
 						     item_x + item_width / 2,
 						     item_y + item_height / 2,
 						     -1, GTK_ANCHOR_CENTER,
 						     NULL);
 #else
-		  model = goo_canvas_rect_model_new (group,
+		  model = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (group),
 						     item_x + 20,
 						     item_y + 4,
 						     item_width - 40,
Index: demo/mv-demo-scalability.c
===================================================================
--- demo/mv-demo-scalability.c	(revision 27)
+++ demo/mv-demo-scalability.c	(working copy)
@@ -75,12 +75,13 @@ create_canvas_scalability (void)
 	for (i = 0; i < N_COLS; i++) {
 		for (j = 0; j < N_ROWS; j++) {
 #ifdef USE_PIXMAP
-		  item = goo_canvas_image_model_new (root, pixbuf,
+		  item = goo_canvas_image_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+		                                     pixbuf,
 						     i * (width + PADDING),
 						     j * (height + PADDING),
 						     NULL);
 #else
-		  item = goo_canvas_rect_model_new (root,
+		  item = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
 						    i * (width + PADDING),
 						    j * (height + PADDING),
 						    width, height);
Index: demo/mv-demo.c
===================================================================
--- demo/mv-demo.c	(revision 27)
+++ demo/mv-demo.c	(working copy)
@@ -648,7 +648,7 @@ create_canvas_primitives (GooCanvasItemM
 
 
 static void
-setup_heading (GooCanvasItemModel *root, char *text, int pos)
+setup_heading (GooCanvasContainerModel *root, char *text, int pos)
 {
   double x = (pos % 3) * 200 + 100;
   double y = (pos / 3) * 150 + 5;
@@ -663,48 +663,53 @@ setup_heading (GooCanvasItemModel *root,
 
 
 static void
-setup_divisions (GooCanvasItemModel *root)
+setup_divisions (GooCanvasContainerModel *root)
 {
   GooCanvasItemModel *group, *item;
 
   group = goo_canvas_group_model_new (root, NULL);
   goo_canvas_item_model_translate (group, 2, 2);
 
-  item = goo_canvas_rect_model_new (group, 0, 0, 600, 450,
+  item = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (group),
+                                    0, 0, 600, 450,
 				    "line-width", 4.0,
 				    NULL);
   g_object_set_data (G_OBJECT (item), "skip-signal-connection", "TRUE");
 
-  item = goo_canvas_polyline_model_new_line (group, 0, 150, 600, 150,
+  item = goo_canvas_polyline_model_new_line (GOO_CANVAS_CONTAINER_MODEL (group),
+                                             0, 150, 600, 150,
 					     "line-width", 4.0,
 					     NULL);
   g_object_set_data (G_OBJECT (item), "skip-signal-connection", "TRUE");
 
-  item = goo_canvas_polyline_model_new_line (group, 0, 300, 600, 300,
+  item = goo_canvas_polyline_model_new_line (GOO_CANVAS_CONTAINER_MODEL (group),
+                                             0, 300, 600, 300,
 					     "line-width", 4.0,
 					     NULL);
   g_object_set_data (G_OBJECT (item), "skip-signal-connection", "TRUE");
 
-  item = goo_canvas_polyline_model_new_line (group, 200, 0, 200, 450,
+  item = goo_canvas_polyline_model_new_line (GOO_CANVAS_CONTAINER_MODEL (group),
+                                             200, 0, 200, 450,
 					     "line-width", 4.0,
 					     NULL);
   g_object_set_data (G_OBJECT (item), "skip-signal-connection", "TRUE");
 
-  item = goo_canvas_polyline_model_new_line (group, 400, 0, 400, 450,
+  item = goo_canvas_polyline_model_new_line (GOO_CANVAS_CONTAINER_MODEL (group),
+                                             400, 0, 400, 450,
 					     "line-width", 4.0,
 					     NULL);
   g_object_set_data (G_OBJECT (item), "skip-signal-connection", "TRUE");
 
 #if 1
-  setup_heading (group, "Rectangles", 0);
-  setup_heading (group, "Ellipses", 1);
-  setup_heading (group, "Texts", 2);
-  setup_heading (group, "Images", 3);
-  setup_heading (group, "Lines", 4);
-  /*setup_heading (group, "No Curves", 5);*/
-  /*setup_heading (group, "Arcs", 6);*/
-  setup_heading (group, "Polygons", 7);
-  /*setup_heading (group, "Widgets", 8);*/
+  setup_heading (GOO_CANVAS_CONTAINER_MODEL (group), "Rectangles", 0);
+  setup_heading (GOO_CANVAS_CONTAINER_MODEL (group), "Ellipses", 1);
+  setup_heading (GOO_CANVAS_CONTAINER_MODEL (group), "Texts", 2);
+  setup_heading (GOO_CANVAS_CONTAINER_MODEL (group), "Images", 3);
+  setup_heading (GOO_CANVAS_CONTAINER_MODEL (group), "Lines", 4);
+  /*setup_heading (GOO_CANVAS_CONTAINER_MODEL (group), "No Curves", 5);*/
+  /*setup_heading (GOO_CANVAS_CONTAINER_MODEL (group), "Arcs", 6);*/
+  setup_heading (GOO_CANVAS_CONTAINER_MODEL (group), "Polygons", 7);
+  /*setup_heading (GOO_CANVAS_CONTAINER_MODEL (group), "Widgets", 8);*/
 #endif
 }
 
@@ -732,7 +737,7 @@ create_stipple (const char *color_name, 
 }
 
 static void
-setup_rectangles (GooCanvasItemModel *root)
+setup_rectangles (GooCanvasContainerModel *root)
 {
   GooCanvasItemModel *item;
   cairo_pattern_t *pattern;
@@ -773,7 +778,7 @@ setup_rectangles (GooCanvasItemModel *ro
 
 
 static void
-setup_ellipses (GooCanvasItemModel *root)
+setup_ellipses (GooCanvasContainerModel *root)
 {
   GooCanvasItemModel *ellipse1, *ellipse3;
   cairo_pattern_t *pattern;
@@ -820,7 +825,7 @@ setup_ellipses (GooCanvasItemModel *root
 #define RADIUS 60.0
 
 static void
-polish_diamond (GooCanvasItemModel *root)
+polish_diamond (GooCanvasContainerModel *root)
 {
   GooCanvasItemModel *group, *item;
   int i, j;
@@ -841,7 +846,8 @@ polish_diamond (GooCanvasItemModel *root
       a = 2.0 * M_PI * j / VERTICES;
       x2 = RADIUS * cos (a);
       y2 = RADIUS * sin (a);
-      item = goo_canvas_polyline_model_new_line (group, x1, y1, x2, y2, NULL);
+      item = goo_canvas_polyline_model_new_line (GOO_CANVAS_CONTAINER_MODEL (group),
+                                                 x1, y1, x2, y2, NULL);
       g_object_set_data (G_OBJECT (item), "skip-signal-connection", "TRUE");
     }
   }
@@ -851,7 +857,7 @@ polish_diamond (GooCanvasItemModel *root
 #define SCALE 7.0
 
 static void
-make_hilbert (GooCanvasItemModel *root)
+make_hilbert (GooCanvasContainerModel *root)
 {
   char hilbert[] = "urdrrulurulldluuruluurdrurddldrrruluurdrurddldrddlulldrdldrrurd";
   char *c;
@@ -905,7 +911,7 @@ make_hilbert (GooCanvasItemModel *root)
 }
 
 static void
-setup_lines (GooCanvasItemModel *root)
+setup_lines (GooCanvasContainerModel *root)
 {
   GooCanvasItemModel *polyline1, *polyline2, *polyline3, *polyline4, *polyline5;
 
@@ -966,7 +972,7 @@ setup_lines (GooCanvasItemModel *root)
 
 
 static void
-setup_polygons (GooCanvasItemModel *root)
+setup_polygons (GooCanvasContainerModel *root)
 {
   GooCanvasItemModel *polyline1, *polyline2;
   GooCanvasPoints *points;
@@ -1031,8 +1037,8 @@ setup_polygons (GooCanvasItemModel *root
 }
 
 
-static GooCanvasItemModel *
-make_anchor (GooCanvasItemModel *root, double x, double y)
+static GooCanvasContainerModel *
+make_anchor (GooCanvasContainerModel *root, double x, double y)
 {
   GooCanvasItemModel *group, *item;
   cairo_matrix_t transform = { 0.8, 0.2, -0.3, 0.5, x, y };
@@ -1045,15 +1051,16 @@ make_anchor (GooCanvasItemModel *root, d
 		NULL);
 #endif
 
-  item = goo_canvas_rect_model_new (group, -2.5, -2.5, 4, 4,
+  item = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (group),
+                                    -2.5, -2.5, 4, 4,
 				    "line-width", 1.0,
 				    NULL);
 
-  return group;
+  return GOO_CANVAS_CONTAINER_MODEL (group);
 }
 
 static void 
-setup_texts (GooCanvasItemModel *root)
+setup_texts (GooCanvasContainerModel *root)
 {
   cairo_pattern_t *pattern;
   static guchar stipple_data[16] = {
@@ -1113,7 +1120,7 @@ setup_texts (GooCanvasItemModel *root)
 
 
 static void
-setup_invisible_texts (GooCanvasItemModel *root)
+setup_invisible_texts (GooCanvasContainerModel *root)
 {
   goo_canvas_text_model_new (root, "Visible above 0.8x", 500, 330, -1,
 			     GTK_ANCHOR_CENTER,
@@ -1161,7 +1168,7 @@ setup_invisible_texts (GooCanvasItemMode
 
 
 static void
-plant_flower (GooCanvasItemModel *root,
+plant_flower (GooCanvasContainerModel *root,
 	      double x, double y,
 	      GtkAnchorType anchor)
 {
@@ -1186,7 +1193,7 @@ plant_flower (GooCanvasItemModel *root,
 }
 
 static void
-setup_images (GooCanvasItemModel *root)
+setup_images (GooCanvasContainerModel *root)
 {
   GdkPixbuf *im;
   GooCanvasItemModel *image;
@@ -1221,7 +1228,7 @@ create_static_model ()
 
   static_root = goo_canvas_group_model_new (NULL, NULL);
 
-  item = goo_canvas_polyline_model_new_line (static_root,
+  item = goo_canvas_polyline_model_new_line (GOO_CANVAS_CONTAINER_MODEL (static_root),
 					     40.0, 410.0,
 					     40.0, 330.0,
 					     "stroke-color", "midnightblue",
@@ -1232,14 +1239,15 @@ create_static_model ()
 					     "arrow-width", 3.5,
 					     NULL);
 
-  item = goo_canvas_polyline_model_new_line (static_root,
+  item = goo_canvas_polyline_model_new_line (GOO_CANVAS_CONTAINER_MODEL (static_root),
 					     32.0, 370.0,
 					     48.0, 370.0,
 					     "stroke-color", "midnightblue",
 					     "line-width", 3.0,
 					     NULL);
 
-  item = goo_canvas_text_model_new (static_root, "N", 40, 320, -1, GTK_ANCHOR_S,
+  item = goo_canvas_text_model_new (GOO_CANVAS_CONTAINER_MODEL (static_root),
+                                    "N", 40, 320, -1, GTK_ANCHOR_S,
 				    "font", "Sans 12",
 				    NULL);
 
@@ -1293,7 +1301,7 @@ test_simple_transforms (GooCanvasItemMod
 
 
 static void
-setup_grids (GooCanvasItemModel *root)
+setup_grids (GooCanvasContainerModel *root)
 {
   GooCanvasItemModel *item;
 
@@ -1319,18 +1327,18 @@ create_model (void)
 
   /* Setup canvas items */
 #if 1
-  setup_divisions (root);
-  setup_rectangles (root);
-  setup_ellipses (root);
-  setup_lines (root);
-  setup_polygons (root);
-  setup_texts (root); 
-  setup_images (root);
-  setup_invisible_texts (root);
-  setup_grids (root);
+  setup_divisions (GOO_CANVAS_CONTAINER_MODEL (root));
+  setup_rectangles (GOO_CANVAS_CONTAINER_MODEL (root));
+  setup_ellipses (GOO_CANVAS_CONTAINER_MODEL (root));
+  setup_lines (GOO_CANVAS_CONTAINER_MODEL (root));
+  setup_polygons (GOO_CANVAS_CONTAINER_MODEL (root));
+  setup_texts (GOO_CANVAS_CONTAINER_MODEL (root));
+  setup_images (GOO_CANVAS_CONTAINER_MODEL (root));
+  setup_invisible_texts (GOO_CANVAS_CONTAINER_MODEL (root));
+  setup_grids (GOO_CANVAS_CONTAINER_MODEL (root));
 #endif
 #if 0
-  setup_widgets (root);
+  setup_widgets (GOO_CANVAS_ITEM_MODEL (root));
 #endif
 
   test_simple_transforms (root);
Index: demo/demo-large-line.h
===================================================================
--- demo/demo-large-line.h	(revision 27)
+++ demo/demo-large-line.h	(working copy)
@@ -40,7 +40,7 @@ struct _GooDemoLargeLineClass
 
 GType               goo_demo_large_line_get_type  (void) G_GNUC_CONST;
 
-GooCanvasItem*      goo_demo_large_line_new       (GooCanvasItem      *parent,
+GooCanvasItem*      goo_demo_large_line_new       (GooCanvasContainer *parent,
 						   gdouble             x1,
 						   gdouble             y1,
 						   gdouble             x2,
Index: demo/table-demo.c
===================================================================
--- demo/table-demo.c	(revision 27)
+++ demo/table-demo.c	(working copy)
@@ -28,35 +28,37 @@ create_item (GooCanvasItem *table,
 {
   GooCanvasItem *item;
 
-  item = goo_canvas_rect_new (table, 0, 0, width, height,
+  item = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (table),
+                              0, 0, width, height,
 			      "stroke-color", "black",
 			      "fill-color", "red",
 			      NULL);
 
-  goo_canvas_item_set_child_properties (table, item,
-					"row", row,
-					"column", column,
-					"rows", rows,
-					"columns", columns,
-					"x-expand", x_expand,
-					"x-fill", x_fill,
-					"x-shrink", x_shrink,
-					"y-expand", y_expand,
-					"y-fill", y_fill,
-					"y-shrink", y_shrink,
-					NULL);
+  goo_canvas_container_set_child_properties (GOO_CANVAS_CONTAINER (table),
+                                             item,
+					     "row", row,
+					     "column", column,
+					     "rows", rows,
+					     "columns", columns,
+					     "x-expand", x_expand,
+					     "x-fill", x_fill,
+					     "x-shrink", x_shrink,
+					     "y-expand", y_expand,
+					     "y-fill", y_fill,
+					     "y-shrink", y_shrink,
+					     NULL);
 
   return item;
 }
 
 
 void
-create_table1 (GooCanvasItem *parent,
-	       gdouble        x,
-	       gdouble        y,
-	       gdouble        width,
-	       gdouble        height,
-	       gboolean       with_grid_lines)
+create_table1 (GooCanvasContainer *parent,
+	       gdouble             x,
+	       gdouble             y,
+	       gdouble             width,
+	       gdouble             height,
+	       gboolean            with_grid_lines)
 {
   GooCanvasItem *table, *items[9];
   GooCanvasBounds bounds;
@@ -114,12 +116,12 @@ create_table1 (GooCanvasItem *parent,
 
 /* Creates a table with items spanning multiple cells */
 void
-create_table2 (GooCanvasItem *parent,
-	       gdouble        x,
-	       gdouble        y,
-	       gdouble        width,
-	       gdouble        height,
-	       gboolean       with_grid_lines)
+create_table2 (GooCanvasContainer *parent,
+	       gdouble             x,
+	       gdouble             y,
+	       gdouble             width,
+	       gdouble             height,
+	       gboolean            with_grid_lines)
 {
   GooCanvasItem *table, *items[9];
   GooCanvasBounds bounds;
@@ -181,31 +183,31 @@ setup_canvas (GtkWidget *canvas)
   root = goo_canvas_get_root_item (GOO_CANVAS (canvas));
 
   g_print ("\nTable at default size...\n");
-  create_table1 (root, 50, 50, -1, -1, FALSE);
+  create_table1 (GOO_CANVAS_CONTAINER (root), 50, 50, -1, -1, FALSE);
 
   g_print ("\nTable at reduced size...\n");
-  create_table1 (root, 250, 50, 30, 30, FALSE);
+  create_table1 (GOO_CANVAS_CONTAINER (root), 250, 50, 30, 30, FALSE);
 
   g_print ("\nTable at enlarged size...\n");
-  create_table1 (root, 450, 50, 100, 100, FALSE);
+  create_table1 (GOO_CANVAS_CONTAINER (root), 450, 50, 100, 100, FALSE);
 
   g_print ("\nTable with grid lines at default size...\n");
-  create_table1 (root, 50, 250, -1, -1, TRUE);
+  create_table1 (GOO_CANVAS_CONTAINER (root), 50, 250, -1, -1, TRUE);
 
   g_print ("\nTable with grid lines at reduced size...\n");
-  create_table1 (root, 250, 250, 30, 30, TRUE);
+  create_table1 (GOO_CANVAS_CONTAINER (root), 250, 250, 30, 30, TRUE);
 
   g_print ("\nTable with grid lines at enlarged size...\n");
-  create_table1 (root, 450, 250, 150, 150, TRUE);
+  create_table1 (GOO_CANVAS_CONTAINER (root), 450, 250, 150, 150, TRUE);
 
   g_print ("Multispanning table with grid lines at default size...\n");
-  create_table2 (root, 50, 450, -1, -1, TRUE);
+  create_table2 (GOO_CANVAS_CONTAINER (root), 50, 450, -1, -1, TRUE);
 
   g_print ("Multispanning table with grid lines at reduced size...\n");
-  create_table2 (root, 250, 450, 30, 30, TRUE);
+  create_table2 (GOO_CANVAS_CONTAINER (root), 250, 450, 30, 30, TRUE);
 
   g_print ("Multispanning table with grid lines at enlarged size...\n");
-  create_table2 (root, 450, 450, 150, 150, TRUE);
+  create_table2 (GOO_CANVAS_CONTAINER (root), 450, 450, 150, 150, TRUE);
 }
 
 
Index: demo/mv-demo-arrowhead.c
===================================================================
--- demo/mv-demo-arrowhead.c	(revision 27)
+++ demo/mv-demo-arrowhead.c	(working copy)
@@ -188,7 +188,7 @@ set_arrow_shape (GooCanvas *canvas)
 
 static void
 create_drag_box (GtkWidget *canvas,
-		 GooCanvasItemModel *root,
+		 GooCanvasContainerModel *root,
 		 char *box_name)
 {
 	GooCanvasItemModel *box;
@@ -204,7 +204,7 @@ create_drag_box (GtkWidget *canvas,
 
 static void
 create_dimension (GtkWidget *canvas,
-		  GooCanvasItemModel *root,
+		  GooCanvasContainerModel *root,
 		  char *arrow_name,
 		  char *text_name,
 		  GtkAnchorType anchor)
@@ -227,7 +227,7 @@ create_dimension (GtkWidget *canvas,
 
 static void
 create_info (GtkWidget *canvas,
-	     GooCanvasItemModel *root,
+	     GooCanvasContainerModel *root,
 	     char *info_name,
 	     double x,
 	     double y)
@@ -243,7 +243,7 @@ create_info (GtkWidget *canvas,
 
 static void
 create_sample_arrow (GtkWidget *canvas,
-		     GooCanvasItemModel *root,
+		     GooCanvasContainerModel *root,
 		     char *sample_name,
 		     double x1,
 		     double y1,
@@ -471,7 +471,7 @@ create_canvas_arrowhead (void)
 
 	/* Big arrow */
 
-	item = goo_canvas_polyline_model_new_line (root,
+	item = goo_canvas_polyline_model_new_line (GOO_CANVAS_CONTAINER_MODEL (root),
 						   LEFT, MIDDLE, RIGHT, MIDDLE,
 						   "stroke_color", "mediumseagreen",
 						   "end-arrow", TRUE,
@@ -480,7 +480,8 @@ create_canvas_arrowhead (void)
 
 	/* Arrow outline */
 
-	item = goo_canvas_polyline_model_new (root, TRUE, 0,
+	item = goo_canvas_polyline_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+	                                      TRUE, 0,
 					      "stroke_color", "black",
 					      "line-width", 2.0,
 					      "line-cap", CAIRO_LINE_CAP_ROUND,
@@ -490,38 +491,53 @@ create_canvas_arrowhead (void)
 
 	/* Drag boxes */
 
-	create_drag_box (canvas, root, "width_drag_box");
-	create_drag_box (canvas, root, "shape_a_drag_box");
-	create_drag_box (canvas, root, "shape_b_c_drag_box");
+	create_drag_box (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+	                 "width_drag_box");
+	create_drag_box (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+	                 "shape_a_drag_box");
+	create_drag_box (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+	                 "shape_b_c_drag_box");
 
 	/* Dimensions */
 
-	create_dimension (canvas, root, "width_arrow", "width_text", GTK_ANCHOR_E);
-	create_dimension (canvas, root, "shape_a_arrow", "shape_a_text", GTK_ANCHOR_N);
-	create_dimension (canvas, root, "shape_b_arrow", "shape_b_text", GTK_ANCHOR_N);
-	create_dimension (canvas, root, "shape_c_arrow", "shape_c_text", GTK_ANCHOR_W);
+	create_dimension (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+	                  "width_arrow", "width_text", GTK_ANCHOR_E);
+	create_dimension (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+	                  "shape_a_arrow", "shape_a_text", GTK_ANCHOR_N);
+	create_dimension (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+	                  "shape_b_arrow", "shape_b_text", GTK_ANCHOR_N);
+	create_dimension (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+	                  "shape_c_arrow", "shape_c_text", GTK_ANCHOR_W);
 
 	/* Info */
 
-	create_info (canvas, root, "width_info", LEFT, 260);
-	create_info (canvas, root, "shape_a_info", LEFT, 280);
-	create_info (canvas, root, "shape_b_info", LEFT, 300);
-	create_info (canvas, root, "shape_c_info", LEFT, 320);
+	create_info (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+	             "width_info", LEFT, 260);
+	create_info (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+	             "shape_a_info", LEFT, 280);
+	create_info (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+	             "shape_b_info", LEFT, 300);
+	create_info (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+	             "shape_c_info", LEFT, 320);
 
 	/* Division line */
 
-	goo_canvas_polyline_model_new_line (root, RIGHT + 50, 0, RIGHT + 50, 1000,
+	goo_canvas_polyline_model_new_line (GOO_CANVAS_CONTAINER_MODEL (root),
+	                                    RIGHT + 50, 0, RIGHT + 50, 1000,
 					    "fill_color", "black",
 					    "line-width", 2.0,
 					    NULL);
 
 	/* Sample arrows */
 
-	create_sample_arrow (canvas, root, "sample_1",
+	create_sample_arrow (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+	                     "sample_1",
 			     RIGHT + 100, 30, RIGHT + 100, MIDDLE - 30);
-	create_sample_arrow (canvas, root, "sample_2",
+	create_sample_arrow (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+	                    "sample_2",
 			     RIGHT + 70, MIDDLE, RIGHT + 130, MIDDLE);
-	create_sample_arrow (canvas, root, "sample_3",
+	create_sample_arrow (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+	                     "sample_3",
 			     RIGHT + 70, MIDDLE + 30, RIGHT + 130, MIDDLE + 120);
 
 	/* Done! */
Index: demo/mv-demo-features.c
===================================================================
--- demo/mv-demo-features.c	(revision 27)
+++ demo/mv-demo-features.c	(working copy)
@@ -11,7 +11,7 @@ on_button_press (GooCanvasItem *item,
 		 gpointer data)
 {
   GooCanvasItemModel *model = goo_canvas_item_get_model (item);
-  GooCanvasItemModel *parent1, *parent2, *parent;
+  GooCanvasContainerModel *parent1, *parent2, *parent;
 
   if (event->button != 1 || event->type != GDK_BUTTON_PRESS)
     return FALSE;
@@ -23,9 +23,9 @@ on_button_press (GooCanvasItem *item,
   g_object_ref (model);
   goo_canvas_item_model_remove (model);
   if (parent == parent1)
-    goo_canvas_item_model_add_child (parent2, model, -1);
+    goo_canvas_container_model_add_child (parent2, model, -1);
   else
-    goo_canvas_item_model_add_child (parent1, model, -1);
+    goo_canvas_container_model_add_child (parent1, model, -1);
   g_object_unref (model);
 
   return TRUE;
@@ -94,24 +94,29 @@ create_canvas_features (void)
 
 	/* First parent and box */
 
-	parent1 = goo_canvas_group_model_new (root, NULL);
+	parent1 = goo_canvas_group_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+	                                      NULL);
 
-	goo_canvas_rect_model_new (parent1, 0, 0, 200, 200,
+	goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (parent1),
+	                           0, 0, 200, 200,
 				   "fill_color", "tan",
 				   NULL);
 
 	/* Second parent and box */
 
-	parent2 = goo_canvas_group_model_new (root, NULL);
+	parent2 = goo_canvas_group_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+	                                      NULL);
 	goo_canvas_item_model_translate (parent2, 200, 0);
 
-	goo_canvas_rect_model_new (parent2, 0, 0, 200, 200,
+	goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (parent2),
+	                           0, 0, 200, 200,
 				   "fill_color", "#204060",
 				   NULL);
 
 	/* Big circle to be reparented */
 
-	item = goo_canvas_ellipse_model_new (parent1, 100, 100, 90, 90,
+	item = goo_canvas_ellipse_model_new (GOO_CANVAS_CONTAINER_MODEL (parent1),
+	                                     100, 100, 90, 90,
 					     "stroke_color", "black",
 					     "fill_color", "mediumseagreen",
 					     "line-width", 3.0,
@@ -126,15 +131,18 @@ create_canvas_features (void)
 
 	/* A group to be reparented */
 
-	group = goo_canvas_group_model_new (parent2, NULL);
+	group = goo_canvas_group_model_new (GOO_CANVAS_CONTAINER_MODEL (parent2),
+	                                    NULL);
 	goo_canvas_item_model_translate (group, 100, 100);
 
-	goo_canvas_ellipse_model_new (group, 0, 0, 50, 50,
+	goo_canvas_ellipse_model_new (GOO_CANVAS_CONTAINER_MODEL (group),
+	                              0, 0, 50, 50,
 				      "stroke_color", "black",
 				      "fill_color", "wheat",
 				      "line_width", 3.0,
 				      NULL);
-	goo_canvas_ellipse_model_new (group, 0, 0, 25, 25,
+	goo_canvas_ellipse_model_new (GOO_CANVAS_CONTAINER_MODEL (group),
+	                              0, 0, 25, 25,
 				      "fill_color", "steelblue",
 				      NULL);
 
Index: demo/demo-grabs.c
===================================================================
--- demo/demo-grabs.c	(revision 27)
+++ demo/demo-grabs.c	(working copy)
@@ -348,7 +348,7 @@ create_canvas (GtkTable *table, gint row
 
   root = goo_canvas_get_root_item (GOO_CANVAS (canvas));
 
-  rect = goo_canvas_rect_new (root, 0, 0, 200, 100,
+  rect = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root), 0, 0, 200, 100,
 			      "stroke-pattern", NULL,
 			      "fill-color", "yellow",
 			      NULL);
@@ -356,7 +356,7 @@ create_canvas (GtkTable *table, gint row
   g_object_set_data_full (G_OBJECT (rect), "id", view_id, g_free);
   setup_item_signals (rect);
 
-  rect = goo_canvas_rect_new (root, 20, 20, 60, 60,
+  rect = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root), 20, 20, 60, 60,
 			      "stroke-pattern", NULL,
 			      "fill-color", "blue",
 			      NULL);
@@ -364,7 +364,7 @@ create_canvas (GtkTable *table, gint row
   g_object_set_data_full (G_OBJECT (rect), "id", view_id, g_free);
   setup_item_signals (rect);
 
-  rect = goo_canvas_rect_new (root, 120, 20, 60, 60,
+  rect = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root), 120, 20, 60, 60,
 			      "stroke-pattern", NULL,
 			      "fill-color", "red",
 			      NULL);
Index: demo/mv-demo-paths.c
===================================================================
--- demo/mv-demo-paths.c	(revision 27)
+++ demo/mv-demo-paths.c	(working copy)
@@ -14,58 +14,66 @@ create_canvas_model (void)
   root = goo_canvas_group_model_new (NULL, NULL);
 
   /* Test the simple commands like moveto and lineto: MmZzLlHhVv. */
-  path1 = goo_canvas_path_model_new (root, "M 20 20 L 40 40", NULL);
-  path = goo_canvas_path_model_new (root, "M30 20 l20, 20", NULL);
-  path = goo_canvas_path_model_new (root, "M 60 20 H 80", NULL);
-  path = goo_canvas_path_model_new (root, "M60 40 h20", NULL);
-  path = goo_canvas_path_model_new (root, "M 100,20 V 40", NULL);
-  path = goo_canvas_path_model_new (root, "M 120 20 v 20", NULL);
-  path = goo_canvas_path_model_new (root, "M 140 20 h20 v20 h-20 z", NULL);
-  path = goo_canvas_path_model_new (root,
+  path1 = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                    "M 20 20 L 40 40", NULL);
+  path = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                    "M30 20 l20, 20", NULL);
+  path = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                    "M 60 20 H 80", NULL);
+  path = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                    "M60 40 h20", NULL);
+  path = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                    "M 100,20 V 40", NULL);
+  path = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                    "M 120 20 v 20", NULL);
+  path = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                    "M 140 20 h20 v20 h-20 z", NULL);
+  path = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
 				    "M 180 20 h20 v20 h-20 z m 5,5 h10 v10 h-10 z",
 				    "fill-color", "red",
 				    "fill-rule", CAIRO_FILL_RULE_EVEN_ODD,
 				    NULL);
 
-  path = goo_canvas_path_model_new (root, "M 220 20 L 260 20 L 240 40 z",
+  path = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                    "M 220 20 L 260 20 L 240 40 z",
 				    "fill-color", "red",
 				    "stroke-color", "blue",
 				    "line-width", 3.0,
 				    NULL);
 
   /* Test the bezier curve commands: CcSsQqTt. */
-  path = goo_canvas_path_model_new (root,
+  path = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
 				    "M20,100 C20,50 100,50 100,100 S180,150 180,100",
 				    NULL);
 
-  path = goo_canvas_path_model_new (root,
+  path = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
 				    "M220,100 c0,-50 80,-50 80,0 s80,50 80,0",
 				    NULL);
 
-  path = goo_canvas_path_model_new (root,
+  path = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
 				    "M20,200 Q60,130 100,200 T180,200",
 				    NULL);
 
-  path = goo_canvas_path_model_new (root,
+  path = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
 				    "M220,200 q40,-70 80,0 t80,0",
 				    NULL);
 
   /* Test the elliptical arc commands: Aa. */
-  path = goo_canvas_path_model_new (root,
+  path = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
 				    "M200,500 h-150 a150,150 0 1,0 150,-150 z",
 				    "fill-color", "red",
 				    "stroke-color", "blue",
 				    "line-width", 5.0,
 				    NULL);
 
-  path = goo_canvas_path_model_new (root,
+  path = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
 				    "M175,475 v-150 a150,150 0 0,0 -150,150 z",
 				    "fill-color", "yellow",
 				    "stroke-color", "blue",
 				    "line-width", 5.0,
 				    NULL);
 
-  path = goo_canvas_path_model_new (root,
+  path = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
 				    "M400,600 l 50,-25 "
 				    "a25,25 -30 0,1 50,-25 l 50,-25 "
 				    "a25,50 -30 0,1 50,-25 l 50,-25 "
@@ -75,22 +83,22 @@ create_canvas_model (void)
 				    "line-width", 5.0,
 				    NULL);
 
-  path = goo_canvas_path_model_new (root,
+  path = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
 				    "M 525,75 a100,50 0 0,0 100,50",
 				    "stroke-color", "red",
 				    "line-width", 5.0,
 				    NULL);
-  path = goo_canvas_path_model_new (root,
+  path = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
 				    "M 725,75 a100,50 0 0,1 100,50",
 				    "stroke-color", "red",
 				    "line-width", 5.0,
 				    NULL);
-  path = goo_canvas_path_model_new (root,
+  path = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
 				    "M 525,200 a100,50 0 1,0 100,50",
 				    "stroke-color", "red",
 				    "line-width", 5.0,
 				    NULL);
-  path = goo_canvas_path_model_new (root,
+  path = goo_canvas_path_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
 				    "M 725,200 a100,50 0 1,1 100,50",
 				    "stroke-color", "red",
 				    "line-width", 5.0,
Index: demo/mv-demo-animation.c
===================================================================
--- demo/mv-demo-animation.c	(revision 27)
+++ demo/mv-demo-animation.c	(working copy)
@@ -69,35 +69,41 @@ create_canvas_model (void)
   root = goo_canvas_group_model_new (NULL, NULL);
 
   /* Absolute. */
-  ellipse1 = goo_canvas_ellipse_model_new (root, 0, 0, 25, 15,
+  ellipse1 = goo_canvas_ellipse_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                           0, 0, 25, 15,
 					   "fill-color", "blue",
 					   NULL);
   goo_canvas_item_model_translate (ellipse1, 100, 100);
   g_signal_connect (ellipse1, "animation_finished",
 		    G_CALLBACK (on_animation_finished), NULL);
 
-  rect1 = goo_canvas_rect_model_new (root, -10, -10, 20, 20,
+  rect1 = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                     -10, -10, 20, 20,
 				     "fill-color", "blue",
 				     NULL);
   goo_canvas_item_model_translate (rect1, 100, 200);
 
-  rect3 = goo_canvas_rect_model_new (root, -10, -10, 20, 20,
+  rect3 = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                     -10, -10, 20, 20,
 				     "fill-color", "blue",
 				     NULL);
   goo_canvas_item_model_translate (rect3, 200, 200);
 
   /* Relative. */
-  ellipse2 = goo_canvas_ellipse_model_new (root, 0, 0, 25, 15,
+  ellipse2 = goo_canvas_ellipse_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                           0, 0, 25, 15,
 					   "fill-color", "red",
 					   NULL);
   goo_canvas_item_model_translate (ellipse2, 100, 400);
 
-  rect2 = goo_canvas_rect_model_new (root, -10, -10, 20, 20,
+  rect2 = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                     -10, -10, 20, 20,
 				     "fill-color", "red",
 				     NULL);
   goo_canvas_item_model_translate (rect2, 100, 500);
 
-  rect4 = goo_canvas_rect_model_new (root, -10, -10, 20, 20,
+  rect4 = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (root),
+                                     -10, -10, 20, 20,
 				     "fill-color", "red",
 				     NULL);
   goo_canvas_item_model_translate (rect4, 200, 500);
Index: demo/demo-events.c
===================================================================
--- demo/demo-events.c	(revision 27)
+++ demo/demo-events.c	(working copy)
@@ -47,7 +47,8 @@ create_events_area (GtkWidget           
   dash = goo_canvas_line_dash_new (2, 5.0, 5.0);
 
   /* Create invisible item. */
-  rect = goo_canvas_rect_new (root, x + 45, y + 35, 30, 30,
+  rect = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root),
+                              x + 45, y + 35, 30, 30,
 			      "fill-color", "red",
 			      "visibility", GOO_CANVAS_ITEM_INVISIBLE,
 			      "line-width", 5.0,
@@ -59,7 +60,8 @@ create_events_area (GtkWidget           
 
   /* Display a thin rect around it to indicate it is there. */
 #if 1
-  rect = goo_canvas_rect_new (root, x + 42.5, y + 32.5, 36, 36,
+  rect = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root),
+                              x + 42.5, y + 32.5, 36, 36,
 			      "line-dash", dash,
 			      "line-width", 1.0,
 			      "stroke-color", "gray",
@@ -67,7 +69,8 @@ create_events_area (GtkWidget           
 #endif
 
   /* Create unpainted item. */
-  rect = goo_canvas_rect_new (root, x + 85, y + 35, 30, 30,
+  rect = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root),
+                              x + 85, y + 35, 30, 30,
 			      "stroke-pattern", NULL,
 			      "line-width", 5.0,
 			      "pointer-events", pointer_events,
@@ -78,7 +81,8 @@ create_events_area (GtkWidget           
 
   /* Display a thin rect around it to indicate it is there. */
 #if 1
-  rect = goo_canvas_rect_new (root, x + 82.5, y + 32.5, 36, 36,
+  rect = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root),
+                              x + 82.5, y + 32.5, 36, 36,
 			      "line-dash", dash,
 			      "line-width", 1.0,
 			      "stroke-color", "gray",
@@ -86,7 +90,8 @@ create_events_area (GtkWidget           
 #endif
 
   /* Create stroked item. */
-  rect = goo_canvas_rect_new (root, x + 125, y + 35, 30, 30,
+  rect = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root),
+                              x + 125, y + 35, 30, 30,
 			      "line-width", 5.0,
 			      "pointer-events", pointer_events,
 			      NULL);
@@ -95,7 +100,8 @@ create_events_area (GtkWidget           
   setup_item_signals (rect);
 
   /* Create filled item. */
-  rect = goo_canvas_rect_new (root, x + 60, y + 75, 30, 30,
+  rect = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root),
+                              x + 60, y + 75, 30, 30,
 			      "fill-color", "red",
 			      "stroke-pattern", NULL,
 			      "line-width", 5.0,
@@ -106,7 +112,8 @@ create_events_area (GtkWidget           
   setup_item_signals (rect);
 
   /* Create stroked & filled item. */
-  rect = goo_canvas_rect_new (root, x + 100, y + 75, 30, 30,
+  rect = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root),
+                              x + 100, y + 75, 30, 30,
 			      "fill-color", "red",
 			      "line-width", 5.0,
 			      "pointer-events", pointer_events,
@@ -115,7 +122,8 @@ create_events_area (GtkWidget           
   g_object_set_data_full (G_OBJECT (rect), "id", view_id, g_free);
   setup_item_signals (rect);
 
-  goo_canvas_text_new (root, label, x + 100, y + 130, -1, GTK_ANCHOR_CENTER,
+  goo_canvas_text_new (GOO_CANVAS_CONTAINER (root),
+                       label, x + 100, y + 130, -1, GTK_ANCHOR_CENTER,
 		       "font", "Sans 12",
 		       "fill-color", "blue",
 		       NULL);
Index: demo/demo-clipping.c
===================================================================
--- demo/demo-clipping.c	(revision 27)
+++ demo/demo-clipping.c	(working copy)
@@ -25,7 +25,7 @@ setup_canvas (GtkWidget *canvas)
   root = goo_canvas_get_root_item (GOO_CANVAS (canvas));
 
   /* Plain items without clip path. */
-  item = goo_canvas_ellipse_new (root, 0, 0, 50, 30,
+  item = goo_canvas_ellipse_new (GOO_CANVAS_CONTAINER (root), 0, 0, 50, 30,
 				 "fill-color", "blue",
 				 NULL);
   goo_canvas_item_translate (item, 100, 100);
@@ -33,20 +33,21 @@ setup_canvas (GtkWidget *canvas)
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Blue ellipse (unclipped)");
 
-  item = goo_canvas_rect_new (root, 200, 50, 100, 100,
+  item = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root), 200, 50, 100, 100,
 			      "fill-color", "red",
 			      "clip-fill-rule", CAIRO_FILL_RULE_EVEN_ODD,
 			      NULL);
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Red rectangle (unclipped)");
 
-  item = goo_canvas_rect_new (root, 380, 50, 100, 100,
+  item = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root), 380, 50, 100, 100,
 			      "fill-color", "yellow",
 			      NULL);
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Yellow rectangle (unclipped)");
 
-  item = goo_canvas_text_new (root, "Sample Text", 520, 100, -1, GTK_ANCHOR_NW,
+  item = goo_canvas_text_new (GOO_CANVAS_CONTAINER (root),
+                              "Sample Text", 520, 100, -1, GTK_ANCHOR_NW,
 			      NULL);
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Text (unclipped)");
@@ -54,7 +55,7 @@ setup_canvas (GtkWidget *canvas)
 
 
   /* Clipped items. */
-  item = goo_canvas_ellipse_new (root, 0, 0, 50, 30,
+  item = goo_canvas_ellipse_new (GOO_CANVAS_CONTAINER(root), 0, 0, 50, 30,
 				 "fill-color", "blue",
 				 "clip-path", "M 0 0 h 100 v 100 h -100 Z",
 				 NULL);
@@ -63,7 +64,7 @@ setup_canvas (GtkWidget *canvas)
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Blue ellipse");
 
-  item = goo_canvas_rect_new (root, 200, 250, 100, 100,
+  item = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root), 200, 250, 100, 100,
 			      "fill-color", "red",
 			      "clip-path", "M 250 300 h 100 v 100 h -100 Z",
 			      "clip-fill-rule", CAIRO_FILL_RULE_EVEN_ODD,
@@ -71,14 +72,15 @@ setup_canvas (GtkWidget *canvas)
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Red rectangle");
 
-  item = goo_canvas_rect_new (root, 380, 250, 100, 100,
+  item = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (root), 380, 250, 100, 100,
 			      "fill-color", "yellow",
 			      "clip-path", "M480,230 l40,100 l-80 0 z",
 			      NULL);
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Yellow rectangle");
 
-  item = goo_canvas_text_new (root, "Sample Text", 520, 300, -1, GTK_ANCHOR_NW,
+  item = goo_canvas_text_new (GOO_CANVAS_CONTAINER (root),
+                              "Sample Text", 520, 300, -1, GTK_ANCHOR_NW,
 			      "clip-path", "M535,300 h75 v40 h-75 z",
 			      NULL);
   g_signal_connect (item, "button_press_event",
@@ -86,11 +88,11 @@ setup_canvas (GtkWidget *canvas)
 
 
   /* Table with clipped items. */
-  table = goo_canvas_table_new (root, NULL);
+  table = goo_canvas_table_new (GOO_CANVAS_CONTAINER (root), NULL);
   goo_canvas_item_translate (table, 200, 400);
   goo_canvas_item_rotate (table, 30, 0, 0);
 
-  item = goo_canvas_ellipse_new (table, 0, 0, 50, 30,
+  item = goo_canvas_ellipse_new (GOO_CANVAS_CONTAINER (table), 0, 0, 50, 30,
 				 "fill-color", "blue",
 				 "clip-path", "M 0 0 h 100 v 100 h -100 Z",
 				 NULL);
@@ -99,34 +101,35 @@ setup_canvas (GtkWidget *canvas)
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Blue ellipse");
 
-  item = goo_canvas_rect_new (table, 200, 250, 100, 100,
+  item = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (table), 200, 250, 100, 100,
 			      "fill-color", "red",
 			      "clip-path", "M 250 300 h 100 v 100 h -100 Z",
 			      "clip-fill-rule", CAIRO_FILL_RULE_EVEN_ODD,
 			      NULL);
-  goo_canvas_item_set_child_properties (table, item,
-					"column", 1,
-					NULL);
+  goo_canvas_container_set_child_properties (GOO_CANVAS_CONTAINER (table), item,
+		 			     "column", 1,
+					     NULL);
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Red rectangle");
 
-  item = goo_canvas_rect_new (table, 380, 250, 100, 100,
+  item = goo_canvas_rect_new (GOO_CANVAS_CONTAINER (table), 380, 250, 100, 100,
 			      "fill-color", "yellow",
 			      "clip-path", "M480,230 l40,100 l-80 0 z",
 			      NULL);
-  goo_canvas_item_set_child_properties (table, item,
-					"column", 2,
-					NULL);
+  goo_canvas_container_set_child_properties (GOO_CANVAS_CONTAINER (table), item,
+					     "column", 2,
+					     NULL);
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Yellow rectangle");
 
-  item = goo_canvas_text_new (table, "Sample Text", 520, 300, -1,
+  item = goo_canvas_text_new (GOO_CANVAS_CONTAINER (table), "Sample Text",
+                              520, 300, -1,
 			      GTK_ANCHOR_NW,
 			      "clip-path", "M535,300 h75 v40 h-75 z",
 			      NULL);
-  goo_canvas_item_set_child_properties (table, item,
-					"column", 3,
-					NULL);
+  goo_canvas_container_set_child_properties (GOO_CANVAS_CONTAINER (table), item,
+					    "column", 3,
+					    NULL);
   g_signal_connect (item, "button_press_event",
 		    G_CALLBACK (on_button_press), "Text");
 }
Index: demo/Makefile.am
===================================================================
--- demo/Makefile.am	(revision 27)
+++ demo/Makefile.am	(working copy)
@@ -32,6 +32,11 @@ table_demo_SOURCES = \
 
 table_demo_LDADD = $(top_builddir)/src/libgoocanvas.la @PACKAGE_LIBS@ $(INTLLIBS)
 
+generic_position_demo_SOURCES = \
+	generic-position-demo.c
+
+generic_position_demo_LDADD = $(top_builddir)/src/libgoocanvas.la @PACKAGE_LIBS@ $(INTLLIBS)
+
 mv_table_demo_SOURCES = \
 	mv-table-demo.c
 
Index: demo/mv-table-demo.c
===================================================================
--- demo/mv-table-demo.c	(revision 27)
+++ demo/mv-table-demo.c	(working copy)
@@ -28,42 +28,44 @@ create_item (GooCanvasItemModel *table,
 {
   GooCanvasItemModel *model;
 
-  model = goo_canvas_rect_model_new (table, 0, 0, width, height,
+  model = goo_canvas_rect_model_new (GOO_CANVAS_CONTAINER_MODEL (table),
+                                     0, 0, width, height,
 				     "fill-color", "red",
 				     NULL);
 
-  goo_canvas_item_model_set_child_properties (table, model,
-					      "row", row,
-					      "column", column,
-					      "rows", rows,
-					      "columns", columns,
-					      "x-expand", x_expand,
-					      "x-fill", x_fill,
-					      "x-shrink", x_shrink,
-					      "y-expand", y_expand,
-					      "y-fill", y_fill,
-					      "y-shrink", y_shrink,
-					      NULL);
+  goo_canvas_container_model_set_child_properties (GOO_CANVAS_CONTAINER_MODEL (table),
+                                                   model,
+					          "row", row,
+					          "column", column,
+					          "rows", rows,
+					          "columns", columns,
+					          "x-expand", x_expand,
+					          "x-fill", x_fill,
+					          "x-shrink", x_shrink,
+					          "y-expand", y_expand,
+					          "y-fill", y_fill,
+					          "y-shrink", y_shrink,
+					          NULL);
 
   return model;
 }
 
 
 void
-create_table1 (GtkWidget          *canvas,
-	       GooCanvasItemModel *parent,
-	       gdouble             x,
-	       gdouble             y,
-	       gdouble             width,
-	       gdouble             height,
-	       gboolean            with_grid_lines)
+create_table1 (GtkWidget               *canvas,
+	       GooCanvasContainerModel *parent,
+	       gdouble                  x,
+	       gdouble                  y,
+	       gdouble                  width,
+	       gdouble                  height,
+	       gboolean                 with_grid_lines)
 {
   GooCanvasItemModel *table, *items[9];
   GooCanvasItem *item;
   GooCanvasBounds bounds;
   gint i = 0;
 
-  table = goo_canvas_table_model_new (parent,
+  table = goo_canvas_table_model_new (GOO_CANVAS_CONTAINER_MODEL (parent),
 				      "width", width,
 				      "height", height,
 				      NULL);
@@ -115,13 +117,13 @@ create_table1 (GtkWidget          *canva
 
 /* Creates a table with items spanning multiple cells */
 void
-create_table2 (GtkWidget          *canvas,
-	       GooCanvasItemModel *parent,
-	       gdouble             x,
-	       gdouble             y,
-	       gdouble             width,
-	       gdouble             height,
-	       gboolean            with_grid_lines)
+create_table2 (GtkWidget               *canvas,
+	       GooCanvasContainerModel *parent,
+	       gdouble                  x,
+	       gdouble                  y,
+	       gdouble                  width,
+	       gdouble                  height,
+	       gboolean                 with_grid_lines)
 {
   GooCanvasItemModel *table, *items[9];
   GooCanvasItem *item;
@@ -186,31 +188,40 @@ setup_canvas (GtkWidget *canvas)
   goo_canvas_set_root_item_model (GOO_CANVAS (canvas), root);
 
   g_print ("\nTable at default size...\n");
-  create_table1 (canvas, root, 50, 50, -1, -1, FALSE);
+  create_table1 (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+                 50, 50, -1, -1, FALSE);
 
   g_print ("\nTable at reduced size...\n");
-  create_table1 (canvas, root, 250, 50, 30, 30, FALSE);
+  create_table1 (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+                 250, 50, 30, 30, FALSE);
 
   g_print ("\nTable at enlarged size...\n");
-  create_table1 (canvas, root, 450, 50, 100, 100, FALSE);
+  create_table1 (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+                 450, 50, 100, 100, FALSE);
 
   g_print ("\nTable with grid lines at default size...\n");
-  create_table1 (canvas, root, 50, 250, -1, -1, TRUE);
+  create_table1 (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+                 50, 250, -1, -1, TRUE);
 
   g_print ("\nTable with grid lines at reduced size...\n");
-  create_table1 (canvas, root, 250, 250, 30, 30, TRUE);
+  create_table1 (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+                 250, 250, 30, 30, TRUE);
 
   g_print ("\nTable with grid lines at enlarged size...\n");
-  create_table1 (canvas, root, 450, 250, 150, 150, TRUE);
+  create_table1 (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+                 450, 250, 150, 150, TRUE);
 
   g_print ("Multispanning table with grid lines at default size...\n");
-  create_table2 (canvas, root, 50, 450, -1, -1, TRUE);
+  create_table2 (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+                 50, 450, -1, -1, TRUE);
 
   g_print ("Multispanning table with grid lines at reduced size...\n");
-  create_table2 (canvas, root, 250, 450, 30, 30, TRUE);
+  create_table2 (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+                 250, 450, 30, 30, TRUE);
 
   g_print ("Multispanning table with grid lines at enlarged size...\n");
-  create_table2 (canvas, root, 450, 450, 150, 150, TRUE);
+  create_table2 (canvas, GOO_CANVAS_CONTAINER_MODEL (root),
+                 450, 450, 150, 150, TRUE);
 }
 
 
Index: demo/demo-large-items.c
===================================================================
--- demo/demo-large-items.c	(revision 27)
+++ demo/demo-large-items.c	(working copy)
@@ -44,7 +44,7 @@ on_motion_notify (GooCanvasItem *item,
 	  return TRUE;
 	}
 
-      ancestor = goo_canvas_item_get_parent (ancestor);
+      ancestor = GOO_CANVAS_ITEM (goo_canvas_item_get_parent (ancestor));
     }
 
   return TRUE;
@@ -99,7 +99,8 @@ create_large_items_page (void)
 		    G_CALLBACK (on_motion_notify), NULL);
 
 #if 1
-  item = goo_demo_large_rect_new (root, CANVAS_LEFT + 10, CANVAS_TOP + 10,
+  item = goo_demo_large_rect_new (GOO_CANVAS_CONTAINER (root),
+                                  CANVAS_LEFT + 10, CANVAS_TOP + 10,
 				  CANVAS_RIGHT - CANVAS_LEFT - 20,
 				  CANVAS_BOTTOM - CANVAS_TOP - 20,
 				  "fill-color", "yellow",
@@ -108,7 +109,8 @@ create_large_items_page (void)
 #endif
 
 #if 1
-  item = goo_demo_large_rect_new (root, CANVAS_LEFT + 100, CANVAS_TOP + 100,
+  item = goo_demo_large_rect_new (GOO_CANVAS_CONTAINER (root),
+                                  CANVAS_LEFT + 100, CANVAS_TOP + 100,
 				  CANVAS_RIGHT - CANVAS_LEFT - 200, 50,
 				  "fill-color", "orange",
 				  NULL);
@@ -116,7 +118,8 @@ create_large_items_page (void)
 #endif
 
 #if 1
-  item = goo_demo_large_line_new (root, CANVAS_LEFT + 100, CANVAS_TOP + 200,
+  item = goo_demo_large_line_new (GOO_CANVAS_CONTAINER (root),
+                                  CANVAS_LEFT + 100, CANVAS_TOP + 200,
 				  CANVAS_RIGHT - 100, CANVAS_TOP + 200,
 				  "stroke-color", "purple",
 				  "line-width", 10.0,
@@ -125,7 +128,8 @@ create_large_items_page (void)
 #endif
 
 #if 1
-  item = goo_demo_large_line_new (root, CANVAS_LEFT + 100, CANVAS_TOP + 300,
+  item = goo_demo_large_line_new (GOO_CANVAS_CONTAINER (root),
+                                  CANVAS_LEFT + 100, CANVAS_TOP + 300,
 				  CANVAS_RIGHT - 100, CANVAS_BOTTOM - 100,
 				  "stroke-color", "blue",
 				  "line-width", 10.0,
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 27)
+++ ChangeLog	(working copy)
@@ -1,3 +1,89 @@
+2008-11-05  Armin Burgmeier  <armin@openismus.com>
+
+	* src/goocanvascontainer.h:
+	* src/goocanvascontainer.c:
+	* src/goocanvascontainermodel.h:
+	* src/goocanvascontainermodel.c: Moved all the child API from
+	GooCanvasItem to a new interface, GooCanvasContainer.
+
+	* src/Makefile.am: Added the new files to the build.
+
+	* src/goocanvasitem.h: 
+	* src/goocanvasitem.c: Removed the corresponding functionality from
+	GooCanvasItem.
+
+	* src/goocanvasgroup.h:
+	* src/goocanvasgroup.c: Implement the container interface.
+
+	* src/goocanvasrect.c:
+	* src/goocanvasellipse.c:
+	* src/goocanvasutils.c:
+	* src/goocanvasrect.h:
+	* src/goocanvasellipse.h:
+	* src/goocanvasatk.c:
+	* src/goocanvasimage.c:
+	* src/goocanvasgrid.c:
+	* src/goocanvasimage.h:
+	* src/goocanvasgrid.h:
+	* src/goocanvaspolyline.c:
+	* src/goocanvaspath.c:
+	* src/goocanvaspolyline.h:
+	* src/goocanvaspath.h:
+	* src/goocanvasitemsimple.c:
+	* src/goocanvasitemsimple.h:
+	* src/goocanvas.c:
+	* src/goocanvasitemmodel.c:
+	* src/goocanvaswidget.c:
+	* src/goocanvasitemmodel.h:
+	* src/goocanvastext.c:
+	* src/goocanvastable.c:
+	* src/goocanvaswidget.h:
+	* src/goocanvastext.h:
+	* src/goocanvastable.h: Adapt other files for API changes, changed the
+	*_new functions to take a GooCanvasContainer as parent item.
+
+	* demo/mv-demo-grabs.c:
+	* demo/demo-focus.c:
+	* demo/demo-fifteen.c:
+	* demo/mv-demo-events.c:
+	* demo/mv-demo-clipping.c:
+	* demo/demo-large-rect.c:
+	* demo/demo-table.c:
+	* demo/simple-demo.c:
+	* demo/demo-large-rect.h:
+	* demo/demo-item.c:
+	* demo/mv-demo-focus.c:
+	* demo/mv-demo-fifteen.c:
+	* demo/demo-scalability.c:
+	* demo/scalability-demo.c:
+	* demo/units-demo.c:
+	* demo/demo.c:
+	* demo/demo-item.h:
+	* demo/widgets-demo.c:
+	* demo/mv-demo-table.c:
+	* demo/mv-simple-demo.c:
+	* demo/demo-arrowhead.c:
+	* demo/demo-features.c:
+	* demo/demo-large-line.c:
+	* demo/demo-animation.c:
+	* demo/demo-paths.c:
+	* demo/mv-scalability-demo.c:
+	* demo/mv-demo-scalability.c:
+	* demo/mv-demo.c:
+	* demo/demo-large-line.h:
+	* demo/table-demo.c:
+	* demo/mv-demo-arrowhead.c:
+	* demo/mv-demo-features.c:
+	* demo/demo-grabs.c:
+	* demo/mv-demo-paths.c:
+	* demo/mv-demo-animation.c:
+	* demo/demo-events.c:
+	* demo/demo-clipping.c:
+	* demo/Makefile.am:
+	* demo/mv-table-demo.c:
+	* demo/demo-large-items.c: Adapt for API changes, mostly casting
+	things to GooCanvasContainer(Model).
+
 2008-11-04  Damon Chaplin  <damon@gnome.org>
 
 	* src/goocanvasutils.h: added typedefs for wrappers of cairo types
Index: src/goocanvasrect.c
===================================================================
--- src/goocanvasrect.c	(revision 27)
+++ src/goocanvasrect.c	(working copy)
@@ -137,11 +137,11 @@ goo_canvas_rect_init (GooCanvasRect *rec
  * Returns: a new rectangle item.
  **/
 GooCanvasItem*
-goo_canvas_rect_new (GooCanvasItem *parent,
-		     gdouble        x,
-		     gdouble        y,
-		     gdouble        width,
-		     gdouble        height,
+goo_canvas_rect_new (GooCanvasContainer *parent,
+		     gdouble             x,
+		     gdouble             y,
+		     gdouble             width,
+		     gdouble             height,
 		     ...)
 {
   GooCanvasItem *item;
@@ -169,7 +169,7 @@ goo_canvas_rect_new (GooCanvasItem *pare
 
   if (parent)
     {
-      goo_canvas_item_add_child (parent, item, -1);
+      goo_canvas_container_add_child (parent, item, -1);
       g_object_unref (item);
     }
 
@@ -516,11 +516,11 @@ goo_canvas_rect_model_init (GooCanvasRec
  * Returns: a new rectangle model.
  **/
 GooCanvasItemModel*
-goo_canvas_rect_model_new (GooCanvasItemModel *parent,
-			   gdouble             x,
-			   gdouble             y,
-			   gdouble             width,
-			   gdouble             height,
+goo_canvas_rect_model_new (GooCanvasContainerModel *parent,
+			   gdouble                  x,
+			   gdouble                  y,
+			   gdouble                  width,
+			   gdouble                  height,
 			   ...)
 {
   GooCanvasItemModel *model;
@@ -548,7 +548,7 @@ goo_canvas_rect_model_new (GooCanvasItem
 
   if (parent)
     {
-      goo_canvas_item_model_add_child (parent, model, -1);
+      goo_canvas_container_model_add_child (parent, model, -1);
       g_object_unref (model);
     }
 
Index: src/goocanvasellipse.c
===================================================================
--- src/goocanvasellipse.c	(revision 27)
+++ src/goocanvasellipse.c	(working copy)
@@ -149,11 +149,11 @@ goo_canvas_ellipse_init (GooCanvasEllips
  * Returns: a new ellipse item.
  **/
 GooCanvasItem*
-goo_canvas_ellipse_new (GooCanvasItem *parent,
-			gdouble        center_x,
-			gdouble        center_y,
-			gdouble        radius_x,
-			gdouble        radius_y,
+goo_canvas_ellipse_new (GooCanvasContainer *parent,
+			gdouble             center_x,
+			gdouble             center_y,
+			gdouble             radius_x,
+			gdouble             radius_y,
 			...)
 {
   GooCanvasItem *item;
@@ -179,7 +179,7 @@ goo_canvas_ellipse_new (GooCanvasItem *p
 
   if (parent)
     {
-      goo_canvas_item_add_child (parent, item, -1);
+      goo_canvas_container_add_child (parent, item, -1);
       g_object_unref (item);
     }
 
@@ -429,11 +429,11 @@ goo_canvas_ellipse_model_init (GooCanvas
  * Returns: a new ellipse model.
  **/
 GooCanvasItemModel*
-goo_canvas_ellipse_model_new (GooCanvasItemModel *parent,
-			      gdouble             center_x,
-			      gdouble             center_y,
-			      gdouble             radius_x,
-			      gdouble             radius_y,
+goo_canvas_ellipse_model_new (GooCanvasContainerModel *parent,
+			      gdouble                  center_x,
+			      gdouble                  center_y,
+			      gdouble                  radius_x,
+			      gdouble                  radius_y,
 			      ...)
 {
   GooCanvasItemModel *model;
@@ -459,7 +459,7 @@ goo_canvas_ellipse_model_new (GooCanvasI
 
   if (parent)
     {
-      goo_canvas_item_model_add_child (parent, model, -1);
+      goo_canvas_container_model_add_child (parent, model, -1);
       g_object_unref (model);
     }
 
Index: src/goocanvasutils.c
===================================================================
--- src/goocanvasutils.c	(revision 27)
+++ src/goocanvasutils.c	(working copy)
@@ -479,13 +479,13 @@ goo_canvas_query_child_properties (gpoin
   if (!G_TYPE_IS_CLASSED (G_TYPE_FROM_CLASS (class)))
     return NULL;
 
-  if (g_type_interface_peek (class, GOO_TYPE_CANVAS_ITEM))
-    return goo_canvas_item_class_list_child_properties (class,
-							n_properties);
-
-  if (g_type_interface_peek (class, GOO_TYPE_CANVAS_ITEM_MODEL))
-    return goo_canvas_item_model_class_list_child_properties (class,
-							      n_properties);
+  if (g_type_interface_peek (class, GOO_TYPE_CANVAS_CONTAINER))
+    return goo_canvas_container_class_list_child_properties (class,
+							     n_properties);
+
+  if (g_type_interface_peek (class, GOO_TYPE_CANVAS_CONTAINER_MODEL))
+    return goo_canvas_container_model_class_list_child_properties (class,
+							           n_properties);
 
   return NULL;
 }
Index: src/goocanvasrect.h
===================================================================
--- src/goocanvasrect.h	(revision 27)
+++ src/goocanvasrect.h	(working copy)
@@ -60,7 +60,7 @@ struct _GooCanvasRectClass
 
 GType               goo_canvas_rect_get_type  (void) G_GNUC_CONST;
 
-GooCanvasItem*      goo_canvas_rect_new       (GooCanvasItem      *parent,
+GooCanvasItem*      goo_canvas_rect_new       (GooCanvasContainer *parent,
 					       gdouble             x,
 					       gdouble             y,
 					       gdouble             width,
@@ -108,11 +108,11 @@ struct _GooCanvasRectModelClass
 
 GType               goo_canvas_rect_model_get_type  (void) G_GNUC_CONST;
 
-GooCanvasItemModel* goo_canvas_rect_model_new (GooCanvasItemModel *parent,
-					       gdouble             x,
-					       gdouble             y,
-					       gdouble             width,
-					       gdouble             height,
+GooCanvasItemModel* goo_canvas_rect_model_new (GooCanvasContainerModel *parent,
+					       gdouble                  x,
+					       gdouble                  y,
+					       gdouble                  width,
+					       gdouble                  height,
 					       ...);
 
 
Index: src/goocanvasellipse.h
===================================================================
--- src/goocanvasellipse.h	(revision 27)
+++ src/goocanvasellipse.h	(working copy)
@@ -60,7 +60,7 @@ struct _GooCanvasEllipseClass
 
 GType               goo_canvas_ellipse_get_type  (void) G_GNUC_CONST;
 
-GooCanvasItem*      goo_canvas_ellipse_new	 (GooCanvasItem      *parent,
+GooCanvasItem*      goo_canvas_ellipse_new	 (GooCanvasContainer *parent,
 						  gdouble             center_x,
 						  gdouble             center_y,
 						  gdouble             radius_x,
@@ -108,11 +108,11 @@ struct _GooCanvasEllipseModelClass
 
 GType               goo_canvas_ellipse_model_get_type  (void) G_GNUC_CONST;
 
-GooCanvasItemModel* goo_canvas_ellipse_model_new (GooCanvasItemModel *parent,
-						  gdouble             center_x,
-						  gdouble             center_y,
-						  gdouble             radius_x,
-						  gdouble             radius_y,
+GooCanvasItemModel* goo_canvas_ellipse_model_new (GooCanvasContainerModel *parent,
+						  gdouble                  center_x,
+						  gdouble                  center_y,
+						  gdouble                  radius_x,
+						  gdouble                  radius_y,
 						  ...);
 
 G_END_DECLS
Index: src/goocanvascontainermodel.c
===================================================================
--- src/goocanvascontainermodel.c	(revision 0)
+++ src/goocanvascontainermodel.c	(revision 0)
@@ -0,0 +1,529 @@
+/*
+ * GooCanvas. Copyright (C) 2005 Damon Chaplin.
+ * Released under the GNU LGPL license. See COPYING for details.
+ *
+ * goocanvascontainer.c - interface for canvas containers & groups.
+ */
+
+/**
+ * SECTION:goocanvascontainermodel
+ * @Title: GooCanvasContainerModel
+ * @Short_Description: the interface for canvas container models.
+ *
+ * #GooCanvasContainerModel defines the interface that models for canvas containers must
+ * implement, and contains methods for operating on canvas container models.
+ */
+#include <config.h>
+#include <glib/gi18n-lib.h>
+#include <gobject/gobjectnotifyqueue.c>
+#include <gobject/gvaluecollector.h>
+#include <gtk/gtk.h>
+#include "goocanvasprivate.h"
+#include <goocanvasenumtypes.h>
+#include "goocanvascontainermodel.h"
+#include "goocanvasutils.h"
+#include "goocanvasmarshal.h"
+
+
+static GParamSpecPool       *_goo_canvas_container_model_child_property_pool = NULL;
+static GObjectNotifyContext *_goo_canvas_container_model_child_property_notify_context = NULL;
+
+static guint canvas_container_model_child_notify_signal = 0;
+
+enum {
+  CHILD_ADDED,
+  CHILD_MOVED,
+  CHILD_REMOVED,
+
+  LAST_SIGNAL
+};
+
+static guint container_model_signals[LAST_SIGNAL] = { 0 };
+
+static void goo_canvas_container_model_base_init (gpointer g_class);
+
+GType
+goo_canvas_container_model_get_type (void)
+{
+  static GType container_model_type = 0;
+
+  if (!container_model_type)
+    {
+      static const GTypeInfo container_model_info =
+      {
+        sizeof (GooCanvasContainerModelIface),  /* class_size */
+	goo_canvas_container_model_base_init,   /* base_init */
+	NULL,			                /* base_finalize */
+      };
+
+      container_model_type = g_type_register_static (G_TYPE_INTERFACE,
+						     "GooCanvasContainerModel",
+						     &container_model_info, 0);
+
+      g_type_interface_add_prerequisite (container_model_type, G_TYPE_OBJECT);
+      g_type_interface_add_prerequisite (container_model_type, GOO_TYPE_CANVAS_ITEM_MODEL);
+    }
+
+  return container_model_type;
+}
+
+
+
+static void
+child_property_notify_dispatcher (GObject     *object,
+				  guint        n_pspecs,
+				  GParamSpec **pspecs)
+{
+  guint i;
+
+  for (i = 0; i < n_pspecs; i++)
+    g_signal_emit (object, canvas_container_model_child_notify_signal,
+		   g_quark_from_string (pspecs[i]->name), pspecs[i]);
+}
+
+
+static void
+goo_canvas_container_model_base_init (gpointer g_iface)
+{
+  static GObjectNotifyContext cpn_context = { 0, NULL, NULL };
+  static gboolean initialized = FALSE;
+  
+  if (!initialized)
+    {
+      canvas_container_model_child_notify_signal = g_signal_lookup ("child-notify", GOO_TYPE_CANVAS_ITEM_MODEL);
+      GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
+
+      _goo_canvas_container_model_child_property_pool = g_param_spec_pool_new (TRUE);
+
+      cpn_context.quark_notify_queue = g_quark_from_static_string ("GooCanvasContainerModel-child-property-notify-queue");
+      cpn_context.dispatcher = child_property_notify_dispatcher;
+      _goo_canvas_container_model_child_property_notify_context = &cpn_context;
+
+      /**
+       * GooCanvasContainerModel::child-added
+       * @model: the container model that received the signal.
+       * @child_num: the index of the new child.
+       *
+       * Emitted when a child has been added.
+       */
+      container_model_signals[CHILD_ADDED] =
+	g_signal_new ("child-added",
+		      iface_type,
+		      G_SIGNAL_RUN_LAST,
+		      G_STRUCT_OFFSET (GooCanvasContainerModelIface, child_added),
+		      NULL, NULL,
+		      goo_canvas_marshal_VOID__INT,
+		      G_TYPE_NONE, 1,
+		      G_TYPE_INT);
+
+      /**
+       * GooCanvasContainerModel::child-moved
+       * @model: the container model that received the signal.
+       * @old_child_num: the old index of the child.
+       * @new_child_num: the new index of the child.
+       *
+       * Emitted when a child has been moved in the stacking order.
+       */
+      container_model_signals[CHILD_MOVED] =
+	g_signal_new ("child-moved",
+		      iface_type,
+		      G_SIGNAL_RUN_LAST,
+		      G_STRUCT_OFFSET (GooCanvasContainerModelIface, child_moved),
+		      NULL, NULL,
+		      goo_canvas_marshal_VOID__INT_INT,
+		      G_TYPE_NONE, 2,
+		      G_TYPE_INT, G_TYPE_INT);
+
+      /**
+       * GooCanvasContainerModel::child-removed
+       * @model: the container model that received the signal.
+       * @child_num: the index of the child that was removed.
+       *
+       * Emitted when a child has been removed.
+       */
+      container_model_signals[CHILD_REMOVED] =
+	g_signal_new ("child-removed",
+		      iface_type,
+		      G_SIGNAL_RUN_LAST,
+		      G_STRUCT_OFFSET (GooCanvasContainerModelIface, child_removed),
+		      NULL, NULL,
+		      goo_canvas_marshal_VOID__INT,
+		      G_TYPE_NONE, 1,
+		      G_TYPE_INT);
+
+      initialized = TRUE;
+    }
+}
+
+
+/**
+ * goo_canvas_container_model_add_child:
+ * @model: a container model.
+ * @child: the child to add.
+ * @position: the position of the child, or -1 to place it last (at the top of
+ *  the stacking order).
+ * 
+ * Adds a child at the given stack position.
+ **/
+void
+goo_canvas_container_model_add_child      (GooCanvasContainerModel  *model,
+				           GooCanvasItemModel       *child,
+				           gint                      position)
+{
+  GooCanvasContainerModelIface *iface = GOO_CANVAS_CONTAINER_MODEL_GET_IFACE (model);
+
+  g_return_if_fail (iface->add_child != NULL);
+  g_return_if_fail (GOO_CANVAS_ITEM_MODEL (model) != child);
+
+  iface->add_child (model, child, position);
+}
+
+
+/**
+ * goo_canvas_container_model_move_child:
+ * @model: a container model.
+ * @old_position: the current position of the child.
+ * @new_position: the new position of the child.
+ * 
+ * Moves a child to a new stack position.
+ **/
+void
+goo_canvas_container_model_move_child     (GooCanvasContainerModel  *model,
+				           gint                      old_position,
+				           gint                      new_position)
+{
+  GooCanvasContainerModelIface *iface = GOO_CANVAS_CONTAINER_MODEL_GET_IFACE (model);
+
+  g_return_if_fail (iface->move_child != NULL);
+
+  iface->move_child (model, old_position, new_position);
+}
+
+
+/**
+ * goo_canvas_container_model_remove_child:
+ * @model: n container model.
+ * @child_num: the position of the child to remove.
+ * 
+ * Removes the child at the given position.
+ **/
+void
+goo_canvas_container_model_remove_child   (GooCanvasContainerModel  *model,
+				           gint                      child_num)
+{
+  GooCanvasContainerModelIface *iface = GOO_CANVAS_CONTAINER_MODEL_GET_IFACE (model);
+
+  g_return_if_fail (iface->remove_child != NULL);
+
+  iface->remove_child (model, child_num);
+}
+
+
+/**
+ * goo_canvas_container_model_find_child:
+ * @model: a container model.
+ * @child: the child to find.
+ * 
+ * Attempts to find the given child with the container's stack.
+ * 
+ * Returns: the position of the given @child, or -1 if it isn't found.
+ **/
+gint
+goo_canvas_container_model_find_child     (GooCanvasContainerModel *model,
+				           GooCanvasItemModel      *child)
+{
+  GooCanvasItemModel *item;
+  int n_children, i;
+
+  /* Find the current position of container and above. */
+  n_children = goo_canvas_container_model_get_n_children (model);
+  for (i = 0; i < n_children; i++)
+    {
+      item = goo_canvas_container_model_get_child (model, i);
+      if (child == item)
+	return i;
+    }
+  return -1;
+}
+
+
+/**
+ * goo_canvas_container_model_get_n_children:
+ * @model: a container model.
+ * 
+ * Gets the number of children of the container.
+ * 
+ * Returns: the number of children.
+ **/
+gint
+goo_canvas_container_model_get_n_children (GooCanvasContainerModel       *model)
+{
+  GooCanvasContainerModelIface *iface = GOO_CANVAS_CONTAINER_MODEL_GET_IFACE (model);
+
+  return iface->get_n_children ? iface->get_n_children (model) : 0;
+}
+
+
+/**
+ * goo_canvas_container_model_get_child:
+ * @model: a container model.
+ * @child_num: the position of a child in the container's stack.
+ * 
+ * Gets the child at the given stack position.
+ * 
+ * Returns: the child at the given stack position, or %NULL if @child_num
+ * is out of range.
+ **/
+GooCanvasItemModel*
+goo_canvas_container_model_get_child (GooCanvasContainerModel  *model,
+				      gint                      child_num)
+{
+  GooCanvasContainerModelIface *iface = GOO_CANVAS_CONTAINER_MODEL_GET_IFACE (model);
+
+  return iface->get_child ? iface->get_child (model, child_num) : NULL;
+}
+
+/*
+ * Child Properties.
+ */
+
+extern void _goo_canvas_container_get_child_property_internal (GObject *object, GObject *child, const gchar *property_name, GValue *value, GParamSpecPool *property_pool, gboolean is_model);
+
+extern void _goo_canvas_container_set_child_property_internal (GObject *object, GObject *child, const gchar *property_name, const GValue *value, GParamSpecPool *property_pool, GObjectNotifyContext *notify_context, gboolean is_model);
+
+extern void _goo_canvas_container_get_child_properties_internal (GObject *object, GObject *child, va_list var_args, GParamSpecPool *property_pool, GObjectNotifyContext *notify_context, gboolean is_model);
+
+extern void _goo_canvas_container_set_child_properties_internal (GObject *object, GObject *child, va_list var_args, GParamSpecPool *property_pool, GObjectNotifyContext *notify_context, gboolean is_model);
+
+/**
+ * goo_canvas_container_model_get_child_property:
+ * @model: a #GooCanvasContainerModel.
+ * @child: a child #GooCanvasItemModel.
+ * @property_name: the name of the child property to get.
+ * @value: a location to return the value.
+ * 
+ * Gets a child property of @child.
+ **/
+void
+goo_canvas_container_model_get_child_property (GooCanvasContainerModel *model,
+					       GooCanvasItemModel      *child,
+					       const gchar             *property_name,
+					       GValue                  *value)
+{
+  g_return_if_fail (GOO_IS_CANVAS_CONTAINER_MODEL (model));
+  g_return_if_fail (GOO_IS_CANVAS_ITEM_MODEL (child));
+  g_return_if_fail (property_name != NULL);
+  g_return_if_fail (G_IS_VALUE (value));
+
+  _goo_canvas_container_get_child_property_internal ((GObject*) model, (GObject*) child, property_name, value, _goo_canvas_container_model_child_property_pool, TRUE);
+}
+
+
+/**
+ * goo_canvas_container_model_set_child_property:
+ * @model: a #GooCanvasContainerModel.
+ * @child: a child #GooCanvasItemModel.
+ * @property_name: the name of the child property to set.
+ * @value: the value to set the property to.
+ * 
+ * Sets a child property of @child.
+ **/
+void
+goo_canvas_container_model_set_child_property (GooCanvasContainerModel *model,
+					       GooCanvasItemModel      *child,
+					       const gchar             *property_name,
+					       const GValue            *value)
+{
+  g_return_if_fail (GOO_IS_CANVAS_CONTAINER_MODEL (model));
+  g_return_if_fail (GOO_IS_CANVAS_ITEM_MODEL (child));
+  g_return_if_fail (property_name != NULL);
+  g_return_if_fail (G_IS_VALUE (value));
+
+  _goo_canvas_container_set_child_property_internal ((GObject*) model, (GObject*) child, property_name, value, _goo_canvas_container_model_child_property_pool, _goo_canvas_container_model_child_property_notify_context, TRUE);
+}
+
+
+/**
+ * goo_canvas_container_model_get_child_properties_valist:
+ * @model: a #GooCanvasContainerModel.
+ * @child: a child #GooCanvasItemModel.
+ * @var_args: pairs of property names and value pointers, and a terminating
+ *  %NULL.
+ * 
+ * Gets the values of one or more child properties of @child.
+ **/
+void
+goo_canvas_container_model_get_child_properties_valist (GooCanvasContainerModel *model,
+						        GooCanvasItemModel      *child,
+						        va_list                  var_args)
+{
+  g_return_if_fail (GOO_IS_CANVAS_CONTAINER_MODEL (model));
+  g_return_if_fail (GOO_IS_CANVAS_ITEM_MODEL (child));
+
+  _goo_canvas_container_get_child_properties_internal ((GObject*) model, (GObject*) child, var_args, _goo_canvas_container_model_child_property_pool, _goo_canvas_container_model_child_property_notify_context, TRUE);
+}
+
+
+/**
+ * goo_canvas_container_model_set_child_properties_valist:
+ * @model: a #GooCanvasContainerModel.
+ * @child: a child #GooCanvasItemModel.
+ * @var_args: pairs of property names and values, and a terminating %NULL.
+ * 
+ * Sets the values of one or more child properties of @child.
+ **/
+void
+goo_canvas_container_model_set_child_properties_valist (GooCanvasContainerModel *model,
+						        GooCanvasItemModel      *child,
+						        va_list	                 var_args)
+{
+  g_return_if_fail (GOO_IS_CANVAS_CONTAINER_MODEL (model));
+  g_return_if_fail (GOO_IS_CANVAS_ITEM_MODEL (child));
+
+  _goo_canvas_container_set_child_properties_internal ((GObject*) model, (GObject*) child, var_args, _goo_canvas_container_model_child_property_pool, _goo_canvas_container_model_child_property_notify_context, TRUE);
+}
+
+
+/**
+ * goo_canvas_container_model_get_child_properties:
+ * @model: a #GooCanvasContainerModel.
+ * @child: a child #GooCanvasItemModel.
+ * @...: pairs of property names and value pointers, and a terminating %NULL.
+ * 
+ * Gets the values of one or more child properties of @child.
+ **/
+void
+goo_canvas_container_model_get_child_properties  (GooCanvasContainerModel   *model,
+					          GooCanvasItemModel        *child,
+					          ...)
+{
+  va_list var_args;
+  
+  va_start (var_args, child);
+  goo_canvas_container_model_get_child_properties_valist (model, child, var_args);
+  va_end (var_args);
+}
+
+
+/**
+ * goo_canvas_container_model_set_child_properties:
+ * @model: a #GooCanvasContainerModel.
+ * @child: a child #GooCanvasItemModel.
+ * @...: pairs of property names and values, and a terminating %NULL.
+ * 
+ * Sets the values of one or more child properties of @child.
+ **/
+void
+goo_canvas_container_model_set_child_properties  (GooCanvasContainerModel   *model,
+					          GooCanvasItemModel        *child,
+					          ...)
+{
+  va_list var_args;
+  
+  va_start (var_args, child);
+  goo_canvas_container_model_set_child_properties_valist (model, child, var_args);
+  va_end (var_args);
+}
+
+
+
+/**
+ * goo_canvas_container_model_class_install_child_property:
+ * @mclass: a #GObjectClass
+ * @property_id: the id for the property
+ * @pspec: the #GParamSpec for the property
+ * 
+ * This function is only intended to be used when implementing new canvas
+ * container models, specifically layout container models such as
+ * #GooCanvasTableModel.
+ *
+ * It installs a child property on a canvas container class. 
+ **/
+void
+goo_canvas_container_model_class_install_child_property (GObjectClass *mclass,
+						         guint         property_id,
+						         GParamSpec   *pspec)
+{
+  g_return_if_fail (G_IS_OBJECT_CLASS (mclass));
+  g_return_if_fail (G_IS_PARAM_SPEC (pspec));
+  g_return_if_fail (property_id > 0);
+
+  if (g_param_spec_pool_lookup (_goo_canvas_container_model_child_property_pool,
+				pspec->name, G_OBJECT_CLASS_TYPE (mclass),
+				FALSE))
+    {
+      g_warning (G_STRLOC ": class `%s' already contains a child property named `%s'",
+		 G_OBJECT_CLASS_NAME (mclass), pspec->name);
+      return;
+    }
+  g_param_spec_ref (pspec);
+  g_param_spec_sink (pspec);
+  pspec->param_id = property_id;
+  g_param_spec_pool_insert (_goo_canvas_container_model_child_property_pool, pspec,
+			    G_OBJECT_CLASS_TYPE (mclass));
+}
+
+/**
+ * goo_canvas_container_model_class_find_child_property:
+ * @mclass: a #GObjectClass
+ * @property_name: the name of the child property to find
+ * @returns: the #GParamSpec of the child property or %NULL if @class has no
+ *   child property with that name.
+ *
+ * This function is only intended to be used when implementing new canvas
+ * container models, specifically layout container container models such as
+ * #GooCanvasTableModel.
+ *
+ * It finds a child property of a canvas container class by name.
+ */
+GParamSpec*
+goo_canvas_container_model_class_find_child_property (GObjectClass *mclass,
+						      const gchar  *property_name)
+{
+  g_return_val_if_fail (G_IS_OBJECT_CLASS (mclass), NULL);
+  g_return_val_if_fail (property_name != NULL, NULL);
+
+  return g_param_spec_pool_lookup (_goo_canvas_container_model_child_property_pool,
+				   property_name, G_OBJECT_CLASS_TYPE (mclass),
+				   TRUE);
+}
+
+/**
+ * goo_canvas_container_model_class_list_child_properties:
+ * @mclass: a #GObjectClass
+ * @n_properties: location to return the number of child properties found
+ * @returns: a newly allocated array of #GParamSpec*. The array must be 
+ *           freed with g_free().
+ *
+ * This function is only intended to be used when implementing new canvas
+ * container models, specifically layout container container models such as
+ * #GooCanvasTableModel.
+ *
+ * It returns all child properties of a canvas container class.
+ */
+GParamSpec**
+goo_canvas_container_model_class_list_child_properties (GObjectClass *mclass,
+						        guint        *n_properties)
+{
+  GParamSpec **pspecs;
+  guint n;
+
+  g_return_val_if_fail (G_IS_OBJECT_CLASS (mclass), NULL);
+
+  pspecs = g_param_spec_pool_list (_goo_canvas_container_model_child_property_pool,
+				   G_OBJECT_CLASS_TYPE (mclass), &n);
+  if (n_properties)
+    *n_properties = n;
+
+  return pspecs;
+}
+
+
+void
+_goo_canvas_container_model_emit_child_added (GooCanvasContainerModel *model,
+					      gint                     position)
+{
+  g_signal_emit (model, container_model_signals[CHILD_ADDED], 0, position);
+}
+
+
Index: src/goocanvascontainermodel.h
===================================================================
--- src/goocanvascontainermodel.h	(revision 0)
+++ src/goocanvascontainermodel.h	(revision 0)
@@ -0,0 +1,170 @@
+/*
+ * GooCanvas. Copyright (C) 2005 Damon Chaplin.
+ * Released under the GNU LGPL license. See COPYING for details.
+ *
+ * goocanvascontainermodel.h - interface for canvas container models.
+ */
+#ifndef __GOO_CANVAS_CONTAINER_MODEL_H__
+#define __GOO_CANVAS_CONTAINER_MODEL_H__
+
+#include <gtk/gtk.h>
+#include "goocanvasitem.h"
+#include "goocanvasitemmodel.h"
+#include "goocanvascontainer.h"
+
+G_BEGIN_DECLS
+
+
+#define GOO_TYPE_CANVAS_CONTAINER_MODEL            (goo_canvas_container_model_get_type ())
+#define GOO_CANVAS_CONTAINER_MODEL(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_CONTAINER_MODEL, GooCanvasContainerModel))
+#define GOO_IS_CANVAS_CONTAINER_MODEL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_CONTAINER_MODEL))
+#define GOO_CANVAS_CONTAINER_MODEL_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GOO_TYPE_CANVAS_CONTAINER_MODEL, GooCanvasContainerModelIface))
+
+
+/**
+ * GooCanvasContainerModel
+ *
+ * #GooCanvasContainerModel is a typedef used for objects that implement the
+ * #GooCanvasContainerModel interface.
+ *
+ * (There is no actual #GooCanvasContainerModel struct, since it is only an interface.
+ * But using '#GooCanvasContainerModel' is more helpful than using '#GObject'.)
+ */
+/* The typedef is in goocanvasitem.h */
+/*typedef struct _GooCanvasContainerModel       GooCanvasContainerModel;*/
+
+
+/**
+ * GooCanvasContainerModelIface
+ * @get_n_children: returns the number of children of the model.
+ * @get_child: returns the child at the given index.
+ * @add_child: adds a child.
+ * @move_child: moves a child up or down the stacking order.
+ * @remove_child: removes a child.
+ * @get_child_property: gets a child property of a given child model,
+ *  e.g. the "row" or "column" property of a model in a #GooCanvasTableModel.
+ * @set_child_property: sets a child property for a given child model.
+ * @child_added: signal emitted when a child is added.
+ * @child_moved: signal emitted when a child is moved in the stacking order.
+ * @child_removed: signal emitted when a child is removed.
+ *
+ * #GooCanvasContainerModelIface holds the virtual methods that make up the
+ * #GooCanvasContainerModel interface.
+ *
+ * Containers must implement get_n_children() and get_child().
+ * Containers that support dynamic changes to their children should implement
+ * add_child(), move_child() and remove_child().
+ * Layout containers like #GooCanvasTable may implement
+ * get_child_property() and set_child_property().
+ */
+typedef struct _GooCanvasContainerModelIface  GooCanvasContainerModelIface;
+
+struct _GooCanvasContainerModelIface
+{
+  /*< private >*/
+  GTypeInterface base_iface;
+
+  /*< public >*/
+  /* Virtual methods that group models must implement. */
+  gint		       (* get_n_children)		(GooCanvasContainerModel	*model);
+  GooCanvasItemModel*  (* get_child)			(GooCanvasContainerModel	*model,
+							 gint			         child_num);
+
+  /* Virtual methods that group models may implement. */
+  void                 (* add_child)			(GooCanvasContainerModel	*model,
+							 GooCanvasItemModel	        *child,
+							 gint			         position);
+  void                 (* move_child)			(GooCanvasContainerModel	*model,
+							 gint			 old_position,
+							 gint			 new_position);
+  void                 (* remove_child)			(GooCanvasContainerModel	*model,
+							 gint			 child_num);
+  void                 (* get_child_property)		(GooCanvasContainerModel	*model,
+							 GooCanvasItemModel	        *child,
+							 guint			         property_id,
+							 GValue			        *value,
+							 GParamSpec		        *pspec);
+  void                 (* set_child_property)		(GooCanvasContainerModel	*container,
+							 GooCanvasItemModel	        *child,
+							 guint			         property_id,
+							 const GValue		        *value,
+							 GParamSpec		        *pspec);
+
+  /* Signals. */
+  void                 (* child_added)			(GooCanvasContainerModel	*model,
+							 gint			 child_num);
+  void                 (* child_moved)			(GooCanvasContainerModel	*model,
+							 gint			 old_child_num,
+							 gint			 new_child_num);
+  void                 (* child_removed)		(GooCanvasContainerModel	*model,
+							 gint			 child_num);
+
+  /*< private >*/
+
+  /* Padding for future expansion */
+  void (*_goo_canvas_reserved1) (void);
+  void (*_goo_canvas_reserved2) (void);
+  void (*_goo_canvas_reserved3) (void);
+  void (*_goo_canvas_reserved4) (void);
+  void (*_goo_canvas_reserved5) (void);
+  void (*_goo_canvas_reserved6) (void);
+  void (*_goo_canvas_reserved7) (void);
+  void (*_goo_canvas_reserved8) (void);
+};
+
+
+GType               goo_canvas_container_model_get_type       (void) G_GNUC_CONST;
+
+
+gint                goo_canvas_container_model_get_n_children (GooCanvasContainerModel *model);
+GooCanvasItemModel* goo_canvas_container_model_get_child      (GooCanvasContainerModel *model,
+							       gint                     child_num);
+void                goo_canvas_container_model_add_child      (GooCanvasContainerModel *model,
+							       GooCanvasItemModel      *child,
+							       gint                     position);
+void                goo_canvas_container_model_move_child     (GooCanvasContainerModel *model,
+							       gint                     old_position,
+							       gint                     new_position);
+void                goo_canvas_container_model_remove_child   (GooCanvasContainerModel *model,
+							       gint                     child_num);
+gint                goo_canvas_container_model_find_child     (GooCanvasContainerModel *model,
+							       GooCanvasItemModel      *child);
+
+void     goo_canvas_container_model_get_child_property	 (GooCanvasContainerModel   *model,
+							  GooCanvasItemModel        *child,
+							  const gchar               *property_name,
+							  GValue                    *value);
+void     goo_canvas_container_model_set_child_property	 (GooCanvasContainerModel   *model,
+							  GooCanvasItemModel        *child,
+							  const gchar               *property_name,
+							  const GValue              *value);
+void     goo_canvas_container_model_get_child_properties (GooCanvasContainerModel   *model,
+							  GooCanvasItemModel        *child,
+							  ...) G_GNUC_NULL_TERMINATED;
+void     goo_canvas_container_model_set_child_properties (GooCanvasContainerModel   *model,
+							  GooCanvasItemModel        *child,
+							  ...) G_GNUC_NULL_TERMINATED;
+void     goo_canvas_container_model_get_child_properties_valist (GooCanvasContainerModel   *model,
+							         GooCanvasItemModel        *child,
+							         va_list	            var_args);
+void     goo_canvas_container_model_set_child_properties_valist (GooCanvasContainerModel   *model,
+							         GooCanvasItemModel        *child,
+							         va_list	            var_args);
+
+
+/*
+ * Functions to support child properties when implementing new canvas containers.
+ */
+void         goo_canvas_container_model_class_install_child_property (GObjectClass *mclass,
+								      guint	    property_id,
+								      GParamSpec   *pspec);
+GParamSpec*  goo_canvas_container_model_class_find_child_property    (GObjectClass	*mclass,
+								      const gchar	*property_name);
+GParamSpec** goo_canvas_container_model_class_list_child_properties  (GObjectClass	*mclass,
+								      guint	        *n_properties);
+
+
+
+G_END_DECLS
+
+#endif /* __GOO_CANVAS_CONTAINER_MODEL_H__ */
Index: src/goocanvasatk.c
===================================================================
--- src/goocanvasatk.c	(revision 27)
+++ src/goocanvasatk.c	(working copy)
@@ -257,7 +257,8 @@ goo_canvas_item_accessible_initialize (A
 static AtkObject*
 goo_canvas_item_accessible_get_parent (AtkObject *accessible)
 {
-  GooCanvasItem *item, *parent;
+  GooCanvasItem *item;
+  GooCanvasContainer *parent;
   GooCanvas *canvas;
   GObject *object;
 
@@ -287,7 +288,8 @@ goo_canvas_item_accessible_get_parent (A
 static gint
 goo_canvas_item_accessible_get_index_in_parent (AtkObject *accessible)
 {
-  GooCanvasItem *item, *parent;
+  GooCanvasItem *item;
+  GooCanvasContainer *parent;
   GooCanvas *canvas;
   GObject *object;
 
@@ -322,7 +324,7 @@ goo_canvas_item_accessible_get_index_in_
   parent = goo_canvas_item_get_parent (item);
 
   if (parent)
-    return goo_canvas_item_find_child (parent, item);
+    return goo_canvas_container_find_child (parent, item);
 
   canvas = goo_canvas_item_get_canvas (item);
   if (canvas)
@@ -335,18 +337,18 @@ goo_canvas_item_accessible_get_index_in_
 static gint
 goo_canvas_item_accessible_get_n_children (AtkObject *accessible)
 {
-  GooCanvasItem *item;
+  GooCanvasContainer *container;
   GObject *object;
 
   g_return_val_if_fail (GOO_IS_CANVAS_ITEM_ACCESSIBLE (accessible), 0);
 
   object = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible));
-  if (object == NULL)
+  if (object == NULL || !GOO_IS_CANVAS_CONTAINER (object))
     return 0;
 
-  item = GOO_CANVAS_ITEM (object);
+  container = GOO_CANVAS_CONTAINER (object);
 
-  return goo_canvas_item_get_n_children (item);
+  return goo_canvas_container_get_n_children (container);
 }
 
 
@@ -354,19 +356,20 @@ static AtkObject*
 goo_canvas_item_accessible_ref_child (AtkObject *accessible,
 				      gint       child_num)
 {
-  GooCanvasItem *item, *child;
+  GooCanvasContainer *container;
+  GooCanvasItem *child;
   AtkObject *atk_object;
   GObject *object;
 
   g_return_val_if_fail (GOO_IS_CANVAS_ITEM_ACCESSIBLE (accessible), NULL);
 
   object = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible));
-  if (object == NULL)
+  if (object == NULL || !GOO_IS_CANVAS_CONTAINER (object))
     return NULL;
 
-  item = GOO_CANVAS_ITEM (object);
+  container = GOO_CANVAS_CONTAINER (object);
 
-  child = goo_canvas_item_get_child (item, child_num);
+  child = goo_canvas_container_get_child (container, child_num);
   if (!child)
     return NULL;
 
Index: src/goocanvasimage.c
===================================================================
--- src/goocanvasimage.c	(revision 27)
+++ src/goocanvasimage.c	(working copy)
@@ -145,10 +145,10 @@ goo_canvas_image_init (GooCanvasImage *i
  * Returns: a new image item.
  **/
 GooCanvasItem*
-goo_canvas_image_new (GooCanvasItem *parent,
-		      GdkPixbuf     *pixbuf,
-		      gdouble        x,
-		      gdouble        y,
+goo_canvas_image_new (GooCanvasContainer *parent,
+		      GdkPixbuf          *pixbuf,
+		      gdouble             x,
+		      gdouble             y,
 		      ...)
 {
   GooCanvasItem *item;
@@ -179,7 +179,7 @@ goo_canvas_image_new (GooCanvasItem *par
 
   if (parent)
     {
-      goo_canvas_item_add_child (parent, item, -1);
+      goo_canvas_container_add_child (parent, item, -1);
       g_object_unref (item);
     }
 
@@ -530,10 +530,10 @@ goo_canvas_image_model_init (GooCanvasIm
  * Returns: a new image model.
  **/
 GooCanvasItemModel*
-goo_canvas_image_model_new (GooCanvasItemModel *parent,
-			    GdkPixbuf          *pixbuf,
-			    gdouble             x,
-			    gdouble             y,
+goo_canvas_image_model_new (GooCanvasContainerModel *parent,
+			    GdkPixbuf               *pixbuf,
+			    gdouble                  x,
+			    gdouble                  y,
 			    ...)
 {
   GooCanvasItemModel *model;
@@ -564,7 +564,7 @@ goo_canvas_image_model_new (GooCanvasIte
 
   if (parent)
     {
-      goo_canvas_item_model_add_child (parent, model, -1);
+      goo_canvas_container_model_add_child (parent, model, -1);
       g_object_unref (model);
     }
 
Index: src/goocanvasgrid.c
===================================================================
--- src/goocanvasgrid.c	(revision 27)
+++ src/goocanvasgrid.c	(working copy)
@@ -329,7 +329,7 @@ goo_canvas_grid_init (GooCanvasGrid *gri
  * Returns: a new grid item.
  **/
 GooCanvasItem*
-goo_canvas_grid_new (GooCanvasItem      *parent,
+goo_canvas_grid_new (GooCanvasContainer *parent,
 		     gdouble             x,
 		     gdouble             y,
 		     gdouble             width,
@@ -367,7 +367,7 @@ goo_canvas_grid_new (GooCanvasItem      
 
   if (parent)
     {
-      goo_canvas_item_add_child (parent, item, -1);
+      goo_canvas_container_add_child (parent, item, -1);
       g_object_unref (item);
     }
 
@@ -953,15 +953,15 @@ goo_canvas_grid_model_init (GooCanvasGri
  * Returns: a new grid model.
  **/
 GooCanvasItemModel*
-goo_canvas_grid_model_new (GooCanvasItemModel *parent,
-			   gdouble             x,
-			   gdouble             y,
-			   gdouble             width,
-			   gdouble             height,
-			   gdouble             x_step,
-			   gdouble             y_step,
-			   gdouble             x_offset,
-			   gdouble             y_offset,
+goo_canvas_grid_model_new (GooCanvasContainerModel *parent,
+			   gdouble                  x,
+			   gdouble                  y,
+			   gdouble                  width,
+			   gdouble                  height,
+			   gdouble                  x_step,
+			   gdouble                  y_step,
+			   gdouble                  x_offset,
+			   gdouble                  y_offset,
 			   ...)
 {
   GooCanvasItemModel *model;
@@ -991,7 +991,7 @@ goo_canvas_grid_model_new (GooCanvasItem
 
   if (parent)
     {
-      goo_canvas_item_model_add_child (parent, model, -1);
+      goo_canvas_container_model_add_child (parent, model, -1);
       g_object_unref (model);
     }
 
Index: src/goocanvasimage.h
===================================================================
--- src/goocanvasimage.h	(revision 27)
+++ src/goocanvasimage.h	(working copy)
@@ -62,7 +62,7 @@ struct _GooCanvasImageClass
 
 GType               goo_canvas_image_get_type  (void) G_GNUC_CONST;
 
-GooCanvasItem*      goo_canvas_image_new       (GooCanvasItem      *parent,
+GooCanvasItem*      goo_canvas_image_new       (GooCanvasContainer *parent,
 						GdkPixbuf          *pixbuf,
 						gdouble             x,
 						gdouble             y,
@@ -109,10 +109,10 @@ struct _GooCanvasImageModelClass
 
 GType               goo_canvas_image_model_get_type  (void) G_GNUC_CONST;
 
-GooCanvasItemModel* goo_canvas_image_model_new (GooCanvasItemModel *parent,
-						GdkPixbuf          *pixbuf,
-						gdouble             x,
-						gdouble             y,
+GooCanvasItemModel* goo_canvas_image_model_new (GooCanvasContainerModel *parent,
+						GdkPixbuf               *pixbuf,
+						gdouble                  x,
+						gdouble                  y,
 						...);
 
 
Index: src/goocanvasgrid.h
===================================================================
--- src/goocanvasgrid.h	(revision 27)
+++ src/goocanvasgrid.h	(working copy)
@@ -81,7 +81,7 @@ struct _GooCanvasGridClass
 
 
 GType          goo_canvas_grid_get_type      (void) G_GNUC_CONST;
-GooCanvasItem* goo_canvas_grid_new           (GooCanvasItem      *parent,
+GooCanvasItem* goo_canvas_grid_new           (GooCanvasContainer *parent,
 					      gdouble             x,
 					      gdouble             y,
 					      gdouble             width,
@@ -132,15 +132,15 @@ struct _GooCanvasGridModelClass
 
 
 GType               goo_canvas_grid_model_get_type (void) G_GNUC_CONST;
-GooCanvasItemModel* goo_canvas_grid_model_new      (GooCanvasItemModel *parent,
-						    gdouble             x,
-						    gdouble             y,
-						    gdouble             width,
-						    gdouble             height,
-						    gdouble             x_step,
-						    gdouble             y_step,
-						    gdouble             x_offset,
-						    gdouble             y_offset,
+GooCanvasItemModel* goo_canvas_grid_model_new      (GooCanvasContainerModel *parent,
+						    gdouble                  x,
+						    gdouble                  y,
+						    gdouble                  width,
+						    gdouble                  height,
+						    gdouble                  x_step,
+						    gdouble                  y_step,
+						    gdouble                  x_offset,
+						    gdouble                  y_offset,
 						    ...);
 
 
Index: src/goocanvaspolyline.c
===================================================================
--- src/goocanvaspolyline.c	(revision 27)
+++ src/goocanvaspolyline.c	(working copy)
@@ -539,9 +539,9 @@ goo_canvas_polyline_set_property (GObjec
  * Returns: a new polyline item.
  **/
 GooCanvasItem*
-goo_canvas_polyline_new               (GooCanvasItem *parent,
-				       gboolean       close_path,
-				       gint           num_points,
+goo_canvas_polyline_new               (GooCanvasContainer *parent,
+				       gboolean            close_path,
+				       gint                num_points,
 				       ...)
 {
   GooCanvasItem *item;
@@ -571,7 +571,7 @@ goo_canvas_polyline_new               (G
 
   if (parent)
     {
-      goo_canvas_item_add_child (parent, item, -1);
+      goo_canvas_container_add_child (parent, item, -1);
       g_object_unref (item);
     }
 
@@ -606,11 +606,11 @@ goo_canvas_polyline_new               (G
  * Returns: a new polyline item.
  **/
 GooCanvasItem*
-goo_canvas_polyline_new_line          (GooCanvasItem *parent,
-				       gdouble        x1,
-				       gdouble        y1,
-				       gdouble        x2,
-				       gdouble        y2,
+goo_canvas_polyline_new_line          (GooCanvasContainer *parent,
+				       gdouble             x1,
+				       gdouble             y1,
+				       gdouble             x2,
+				       gdouble             y2,
 				       ...)
 {
   GooCanvasItem *item;
@@ -639,7 +639,7 @@ goo_canvas_polyline_new_line          (G
 
   if (parent)
     {
-      goo_canvas_item_add_child (parent, item, -1);
+      goo_canvas_container_add_child (parent, item, -1);
       g_object_unref (item);
     }
 
@@ -1049,9 +1049,9 @@ goo_canvas_polyline_model_init (GooCanva
  * Returns: a new polyline model.
  **/
 GooCanvasItemModel*
-goo_canvas_polyline_model_new (GooCanvasItemModel *parent,
-			       gboolean            close_path,
-			       gint                num_points,
+goo_canvas_polyline_model_new (GooCanvasContainerModel *parent,
+			       gboolean                 close_path,
+			       gint                     num_points,
 			       ...)
 {
   GooCanvasItemModel *model;
@@ -1081,7 +1081,7 @@ goo_canvas_polyline_model_new (GooCanvas
 
   if (parent)
     {
-      goo_canvas_item_model_add_child (parent, model, -1);
+      goo_canvas_container_model_add_child (parent, model, -1);
       g_object_unref (model);
     }
 
@@ -1116,11 +1116,11 @@ goo_canvas_polyline_model_new (GooCanvas
  * Returns: a new polyline model.
  **/
 GooCanvasItemModel*
-goo_canvas_polyline_model_new_line (GooCanvasItemModel *parent,
-				    gdouble             x1,
-				    gdouble             y1,
-				    gdouble             x2,
-				    gdouble             y2,
+goo_canvas_polyline_model_new_line (GooCanvasContainerModel *parent,
+				    gdouble                  x1,
+				    gdouble                  y1,
+				    gdouble                  x2,
+				    gdouble                  y2,
 				    ...)
 {
   GooCanvasItemModel *model;
@@ -1149,7 +1149,7 @@ goo_canvas_polyline_model_new_line (GooC
 
   if (parent)
     {
-      goo_canvas_item_model_add_child (parent, model, -1);
+      goo_canvas_container_model_add_child (parent, model, -1);
       g_object_unref (model);
     }
 
Index: src/goocanvaspath.c
===================================================================
--- src/goocanvaspath.c	(revision 27)
+++ src/goocanvaspath.c	(working copy)
@@ -123,8 +123,8 @@ goo_canvas_path_init (GooCanvasPath *pat
  * Returns: a new path item.
  **/
 GooCanvasItem*
-goo_canvas_path_new               (GooCanvasItem *parent,
-				   const gchar   *path_data,
+goo_canvas_path_new               (GooCanvasContainer *parent,
+				   const gchar        *path_data,
 				   ...)
 {
   GooCanvasItem *item;
@@ -145,7 +145,7 @@ goo_canvas_path_new               (GooCa
 
   if (parent)
     {
-      goo_canvas_item_add_child (parent, item, -1);
+      goo_canvas_container_add_child (parent, item, -1);
       g_object_unref (item);
     }
 
@@ -198,7 +198,7 @@ goo_canvas_path_get_property (GObject   
   GooCanvasPath *path = (GooCanvasPath*) object;
 
   goo_canvas_path_get_common_property (object, path->path_data, prop_id,
-				       value, pspec);
+                                       value, pspec);
 }
 
 
@@ -239,7 +239,7 @@ goo_canvas_path_set_property (GObject   
     }
 
   goo_canvas_path_set_common_property (object, path->path_data, prop_id,
-				       value, pspec);
+                                       value, pspec);
   goo_canvas_item_simple_changed (simple, TRUE);
 }
 
@@ -446,8 +446,8 @@ goo_canvas_path_model_init (GooCanvasPat
  * Returns: a new path model.
  **/
 GooCanvasItemModel*
-goo_canvas_path_model_new (GooCanvasItemModel *parent,
-			   const gchar        *path_data,
+goo_canvas_path_model_new (GooCanvasContainerModel *parent,
+			   const gchar             *path_data,
 			   ...)
 {
   GooCanvasItemModel *model;
@@ -468,7 +468,7 @@ goo_canvas_path_model_new (GooCanvasItem
 
   if (parent)
     {
-      goo_canvas_item_model_add_child (parent, model, -1);
+      goo_canvas_container_model_add_child (parent, model, -1);
       g_object_unref (model);
     }
 
@@ -497,7 +497,7 @@ goo_canvas_path_model_get_property (GObj
   GooCanvasPathModel *pmodel = (GooCanvasPathModel*) object;
 
   goo_canvas_path_get_common_property (object, &pmodel->path_data, prop_id,
-				       value, pspec);
+                                       value, pspec);
 }
 
 
@@ -510,7 +510,7 @@ goo_canvas_path_model_set_property (GObj
   GooCanvasPathModel *pmodel = (GooCanvasPathModel*) object;
 
   goo_canvas_path_set_common_property (object, &pmodel->path_data, prop_id,
-				       value, pspec);
+                                       value, pspec);
   g_signal_emit_by_name (pmodel, "changed", TRUE);
 }
 
Index: src/goocanvasgroup.c
===================================================================
--- src/goocanvasgroup.c	(revision 27)
+++ src/goocanvasgroup.c	(working copy)
@@ -25,6 +25,11 @@
  * goo_canvas_item_rotate(), and the properties such as "visibility" and
  * "pointer-events".
  *
+ * The group's children items are clipped to the region specified by the
+ * #GooCanvasItem:x, #GooCanvasItem:y, #GooCanvasItem:width and
+ * #GooCanvasItem:height properties unless width or height are -1, in which
+ * case the clipping is deactivated.
+ *
  * To create a #GooCanvasGroup use goo_canvas_group_new().
  *
  * To get or set the properties of an existing #GooCanvasGroup, use
@@ -32,24 +37,33 @@
  */
 #include <config.h>
 #include <glib/gi18n-lib.h>
+#include <math.h> /* for fabs() */
 #include <gtk/gtk.h>
 #include "goocanvasprivate.h"
+#include "goocanvascontainer.h"
+#include "goocanvascontainermodel.h"
 #include "goocanvasgroup.h"
 #include "goocanvasitemmodel.h"
 #include "goocanvas.h"
 #include "goocanvasmarshal.h"
 #include "goocanvasatk.h"
 
-
 static void goo_canvas_group_dispose	  (GObject            *object);
 static void goo_canvas_group_finalize     (GObject            *object);
+
 static void canvas_item_interface_init    (GooCanvasItemIface *iface);
+static void canvas_container_interface_init (GooCanvasContainerIface *iface);
 
 G_DEFINE_TYPE_WITH_CODE (GooCanvasGroup, goo_canvas_group,
 			 GOO_TYPE_CANVAS_ITEM_SIMPLE,
 			 G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM,
-						canvas_item_interface_init))
+						canvas_item_interface_init)
+                         G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_CONTAINER,
+                                                canvas_container_interface_init))
 
+/*
+ * GooCanvasGroup.
+ */
 
 static void
 goo_canvas_group_class_init (GooCanvasGroupClass *klass)
@@ -88,7 +102,7 @@ goo_canvas_group_init (GooCanvasGroup *g
  * Return value: a new group item.
  **/
 GooCanvasItem*
-goo_canvas_group_new (GooCanvasItem *parent,
+goo_canvas_group_new (GooCanvasContainer *parent,
 		      ...)
 {
   GooCanvasItem *item;
@@ -107,7 +121,7 @@ goo_canvas_group_new (GooCanvasItem *par
 
   if (parent)
     {
-      goo_canvas_item_add_child (parent, item, -1);
+      goo_canvas_container_add_child (parent, item, -1);
       g_object_unref (item);
     }
 
@@ -145,14 +159,14 @@ goo_canvas_group_finalize (GObject *obje
   G_OBJECT_CLASS (goo_canvas_group_parent_class)->finalize (object);
 }
 
-
 static void
-goo_canvas_group_add_child     (GooCanvasItem  *item,
-				GooCanvasItem  *child,
-				gint            position)
+goo_canvas_group_add_child     (GooCanvasContainer *container,
+				GooCanvasItem      *child,
+				gint                position)
 {
-  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
-  GooCanvasGroup *group = (GooCanvasGroup*) item;
+  GooCanvasGroup *group = GOO_CANVAS_GROUP (container);
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) container;
+
   AtkObject *atk_obj, *child_atk_obj;
 
   g_object_ref (child);
@@ -167,11 +181,11 @@ goo_canvas_group_add_child     (GooCanva
       g_ptr_array_add (group->items, child);
     }
 
-  goo_canvas_item_set_parent (child, item);
+  goo_canvas_item_set_parent (child, container);
   goo_canvas_item_set_is_static (child, simple->simple_data->is_static);
 
   /* Emit the "children_changed" ATK signal, if ATK is enabled. */
-  atk_obj = atk_gobject_accessible_for_object (G_OBJECT (item));
+  atk_obj = atk_gobject_accessible_for_object (G_OBJECT (group));
   if (!ATK_IS_NO_OP_OBJECT (atk_obj))
     {
       child_atk_obj = atk_gobject_accessible_for_object (G_OBJECT (child));
@@ -179,17 +193,17 @@ goo_canvas_group_add_child     (GooCanva
 			     position, child_atk_obj);
     }
 
-  goo_canvas_item_request_update (item);
+  goo_canvas_item_request_update (GOO_CANVAS_ITEM (group));
 }
 
 
 static void
-goo_canvas_group_move_child    (GooCanvasItem  *item,
-				gint	        old_position,
-				gint            new_position)
+goo_canvas_group_move_child    (GooCanvasContainer  *container,
+			        gint	             old_position,
+			        gint                 new_position)
 {
-  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
-  GooCanvasGroup *group = (GooCanvasGroup*) item;
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) container;
+  GooCanvasGroup *group = GOO_CANVAS_GROUP (container);
   GooCanvasItem *child;
   GooCanvasBounds bounds;
 
@@ -204,16 +218,16 @@ goo_canvas_group_move_child    (GooCanva
 
   goo_canvas_util_ptr_array_move (group->items, old_position, new_position);
 
-  goo_canvas_item_request_update (item);
+  goo_canvas_item_request_update (GOO_CANVAS_ITEM (group));
 }
 
 
 static void
-goo_canvas_group_remove_child  (GooCanvasItem  *item,
-				gint            child_num)
+goo_canvas_group_remove_child  (GooCanvasContainer *container,
+			        gint                child_num)
 {
-  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
-  GooCanvasGroup *group = (GooCanvasGroup*) item;
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) container;
+  GooCanvasGroup *group = GOO_CANVAS_GROUP (container);
   GooCanvasItem *child;
   GooCanvasBounds bounds;
   AtkObject *atk_obj, *child_atk_obj;
@@ -230,7 +244,7 @@ goo_canvas_group_remove_child  (GooCanva
     }
 
   /* Emit the "children_changed" ATK signal, if ATK is enabled. */
-  atk_obj = atk_gobject_accessible_for_object (G_OBJECT (item));
+  atk_obj = atk_gobject_accessible_for_object (G_OBJECT (group));
   if (!ATK_IS_NO_OP_OBJECT (atk_obj))
     {
       child_atk_obj = atk_gobject_accessible_for_object (G_OBJECT (child));
@@ -238,30 +252,28 @@ goo_canvas_group_remove_child  (GooCanva
 			     child_num, child_atk_obj);
     }
 
+  g_ptr_array_remove_index (group->items, child_num);
+
   goo_canvas_item_set_parent (child, NULL);
   g_object_unref (child);
 
-  g_ptr_array_remove_index (group->items, child_num);
-
-  goo_canvas_item_request_update (item);
+  goo_canvas_item_request_update (GOO_CANVAS_ITEM (group));
 }
 
 
 static gint
-goo_canvas_group_get_n_children (GooCanvasItem  *item)
+goo_canvas_group_get_n_children (GooCanvasContainer  *container)
 {
-  GooCanvasGroup *group = (GooCanvasGroup*) item;
-
+  GooCanvasGroup *group = GOO_CANVAS_GROUP (container);
   return group->items->len;
 }
 
 
 static GooCanvasItem*
-goo_canvas_group_get_child   (GooCanvasItem       *item,
-			      gint                 child_num)
+goo_canvas_group_get_child   (GooCanvasContainer      *container,
+		              gint                     child_num)
 {
-  GooCanvasGroup *group = (GooCanvasGroup*) item;
-
+  GooCanvasGroup *group = GOO_CANVAS_GROUP (container);
   if (child_num < group->items->len)
     return group->items->pdata[child_num];
   return NULL;
@@ -271,11 +283,11 @@ goo_canvas_group_get_child   (GooCanvasI
 /* This is only used to set the canvas of the root group. It isn't normally
    needed by apps. */
 static void
-goo_canvas_group_set_canvas  (GooCanvasItem *item,
-			      GooCanvas     *canvas)
+goo_canvas_group_set_canvas  (GooCanvasItem  *item,
+		              GooCanvas      *canvas)
 {
-  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
-  GooCanvasGroup *group = (GooCanvasGroup*) item;
+  GooCanvasGroup *group = (GooCanvasGroup*)item;
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) group;
   gint i;
 
   if (simple->canvas == canvas)
@@ -321,15 +333,14 @@ on_model_child_added (GooCanvasGroupMode
 		      GooCanvasGroup      *group)
 {
   GooCanvasItemSimple *simple = (GooCanvasItemSimple*) group;
-  GooCanvasItem *item = (GooCanvasItem*) group;
   GooCanvasItemModel *child_model;
   GooCanvasItem *child;
 
   /* Create a canvas item for the model. */
-  child_model = goo_canvas_item_model_get_child ((GooCanvasItemModel*) model,
-						 position);
+  child_model = goo_canvas_container_model_get_child (GOO_CANVAS_CONTAINER_MODEL (model),
+						      position);
   child = goo_canvas_create_item (simple->canvas, child_model);
-  goo_canvas_item_add_child (item, child, position);
+  goo_canvas_container_add_child (GOO_CANVAS_CONTAINER (group), child, position);
   g_object_unref (child);
 }
 
@@ -340,8 +351,7 @@ on_model_child_moved (GooCanvasGroupMode
 		      gint                 new_position,
 		      GooCanvasGroup      *group)
 {
-  goo_canvas_item_move_child ((GooCanvasItem*) group, old_position,
-			       new_position);
+  goo_canvas_container_move_child (GOO_CANVAS_CONTAINER (group), old_position, new_position);
 }
 
 
@@ -350,7 +360,7 @@ on_model_child_removed (GooCanvasGroupMo
 			gint                 child_num,
 			GooCanvasGroup      *group)
 {
-  goo_canvas_item_remove_child ((GooCanvasItem*) group, child_num);
+  goo_canvas_container_remove_child (GOO_CANVAS_CONTAINER (group), child_num);
 }
 
 
@@ -374,7 +384,7 @@ goo_canvas_group_set_model (GooCanvasIte
 		    G_CALLBACK (on_model_child_removed), group);
 
   /* Recursively create child items for any children. */
-  n_children = goo_canvas_item_model_get_n_children (model);
+  n_children = goo_canvas_container_model_get_n_children (GOO_CANVAS_CONTAINER_MODEL (model));
   for (i = 0; i < n_children; i++)
     on_model_child_added ((GooCanvasGroupModel*) simple->model, i, group);
 }
@@ -390,7 +400,7 @@ goo_canvas_group_request_update  (GooCan
       simple->need_update = TRUE;
 
       if (simple->parent)
-	goo_canvas_item_request_update (simple->parent);
+	goo_canvas_item_request_update (GOO_CANVAS_ITEM (simple->parent));
       else if (simple->canvas)
 	goo_canvas_request_update (simple->canvas);
     }
@@ -424,35 +434,36 @@ goo_canvas_group_update  (GooCanvasItem 
 
       cairo_save (cr);
       if (simple->simple_data->transform)
-	cairo_transform (cr, simple->simple_data->transform);
+        cairo_transform (cr, simple->simple_data->transform);
 
       for (i = 0; i < group->items->len; i++)
-	{
-	  GooCanvasItem *child = group->items->pdata[i];
+        {
+          GooCanvasItem *child = group->items->pdata[i];
+
+          goo_canvas_item_update (child, entire_tree, cr, &child_bounds);
+          
+          /* If the child has non-empty bounds, compute the union. */
+          if (child_bounds.x1 < child_bounds.x2
+              && child_bounds.y1 < child_bounds.y2)
+            {
+              if (initial_bounds)
+                {
+                  simple->bounds.x1 = child_bounds.x1;
+                  simple->bounds.y1 = child_bounds.y1;
+                  simple->bounds.x2 = child_bounds.x2;
+                  simple->bounds.y2 = child_bounds.y2;
+                  initial_bounds = FALSE;
+                }
+              else
+                {
+                  simple->bounds.x1 = MIN (simple->bounds.x1, child_bounds.x1);
+                  simple->bounds.y1 = MIN (simple->bounds.y1, child_bounds.y1);
+                  simple->bounds.x2 = MAX (simple->bounds.x2, child_bounds.x2);
+                  simple->bounds.y2 = MAX (simple->bounds.y2, child_bounds.y2);
+                }
+            }
+        }
 
-	  goo_canvas_item_update (child, entire_tree, cr, &child_bounds);
-	  
-	  /* If the child has non-empty bounds, compute the union. */
-	  if (child_bounds.x1 < child_bounds.x2
-	      && child_bounds.y1 < child_bounds.y2)
-	    {
-	      if (initial_bounds)
-		{
-		  simple->bounds.x1 = child_bounds.x1;
-		  simple->bounds.y1 = child_bounds.y1;
-		  simple->bounds.x2 = child_bounds.x2;
-		  simple->bounds.y2 = child_bounds.y2;
-		  initial_bounds = FALSE;
-		}
-	      else
-		{
-		  simple->bounds.x1 = MIN (simple->bounds.x1, child_bounds.x1);
-		  simple->bounds.y1 = MIN (simple->bounds.y1, child_bounds.y1);
-		  simple->bounds.x2 = MAX (simple->bounds.x2, child_bounds.x2);
-		  simple->bounds.y2 = MAX (simple->bounds.y2, child_bounds.y2);
-		}
-	    }
-	}
       cairo_restore (cr);
     }
 
@@ -578,14 +589,8 @@ static void
 canvas_item_interface_init (GooCanvasItemIface *iface)
 {
   iface->set_canvas     = goo_canvas_group_set_canvas;
-  iface->get_n_children = goo_canvas_group_get_n_children;
-  iface->get_child      = goo_canvas_group_get_child;
   iface->request_update = goo_canvas_group_request_update;
 
-  iface->add_child      = goo_canvas_group_add_child;
-  iface->move_child     = goo_canvas_group_move_child;
-  iface->remove_child   = goo_canvas_group_remove_child;
-
   iface->get_items_at	= goo_canvas_group_get_items_at;
   iface->update         = goo_canvas_group_update;
   iface->paint          = goo_canvas_group_paint;
@@ -594,6 +599,19 @@ canvas_item_interface_init (GooCanvasIte
   iface->set_is_static  = goo_canvas_group_set_is_static;
 }
 
+static void
+canvas_container_interface_init (GooCanvasContainerIface *iface)
+{
+  iface->get_n_children = goo_canvas_group_get_n_children;
+  iface->get_child      = goo_canvas_group_get_child;
+  iface->add_child      = goo_canvas_group_add_child;
+  iface->move_child     = goo_canvas_group_move_child;
+  iface->remove_child   = goo_canvas_group_remove_child;
+}
+
+/*
+ * GooCanvasGroupModel.
+ */
 
 /**
  * SECTION:goocanvasgroupmodel
@@ -624,14 +642,17 @@ canvas_item_interface_init (GooCanvasIte
  * to the signal handlers of the corresponding #GooCanvasGroup objects.
  * (See goo_canvas_get_item() and #GooCanvas::item-created.)
  */
-static void item_model_interface_init (GooCanvasItemModelIface *iface);
+static void item_model_interface_init      (GooCanvasItemModelIface      *iface);
+static void container_model_interface_init (GooCanvasContainerModelIface *iface);
 static void goo_canvas_group_model_dispose      (GObject            *object);
 static void goo_canvas_group_model_finalize     (GObject            *object);
 
 G_DEFINE_TYPE_WITH_CODE (GooCanvasGroupModel, goo_canvas_group_model,
 			 GOO_TYPE_CANVAS_ITEM_MODEL_SIMPLE,
 			 G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM_MODEL,
-						item_model_interface_init))
+						item_model_interface_init)
+                         G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_CONTAINER_MODEL,
+                                                container_model_interface_init))
 
 
 static void
@@ -663,7 +684,7 @@ goo_canvas_group_model_init (GooCanvasGr
  * Return value: a new group model.
  **/
 GooCanvasItemModel*
-goo_canvas_group_model_new (GooCanvasItemModel *parent,
+goo_canvas_group_model_new (GooCanvasContainerModel *parent,
 			    ...)
 {
   GooCanvasItemModel *model;
@@ -682,7 +703,7 @@ goo_canvas_group_model_new (GooCanvasIte
 
   if (parent)
     {
-      goo_canvas_item_model_add_child (parent, model, -1);
+      goo_canvas_container_model_add_child (parent, model, -1);
       g_object_unref (model);
     }
 
@@ -720,14 +741,13 @@ goo_canvas_group_model_finalize (GObject
   G_OBJECT_CLASS (goo_canvas_group_model_parent_class)->finalize (object);
 }
 
-
-extern void _goo_canvas_item_model_emit_child_added (GooCanvasItemModel *model,
-						     gint                position);
+extern void _goo_canvas_container_model_emit_child_added (GooCanvasContainerModel *model,
+						          gint                     position);
 
 static void
-goo_canvas_group_model_add_child     (GooCanvasItemModel *model,
-				      GooCanvasItemModel *child,
-				      gint                position)
+goo_canvas_group_model_add_child     (GooCanvasContainerModel *model,
+				      GooCanvasItemModel      *child,
+				      gint                     position)
 {
   GooCanvasGroupModel *gmodel = (GooCanvasGroupModel*) model;
 
@@ -745,14 +765,14 @@ goo_canvas_group_model_add_child     (Go
 
   goo_canvas_item_model_set_parent (child, model);
 
-  _goo_canvas_item_model_emit_child_added (model, position);
+  _goo_canvas_container_model_emit_child_added (model, position);
 }
 
 
 static void
-goo_canvas_group_model_move_child    (GooCanvasItemModel *model,
-				      gint	          old_position,
-				      gint                new_position)
+goo_canvas_group_model_move_child    (GooCanvasContainerModel *model,
+				      gint	               old_position,
+				      gint                     new_position)
 {
   GooCanvasGroupModel *gmodel = (GooCanvasGroupModel*) model;
 
@@ -764,24 +784,25 @@ goo_canvas_group_model_move_child    (Go
 
 
 static void
-goo_canvas_group_model_remove_child  (GooCanvasItemModel *model,
-				      gint                child_num)
+goo_canvas_group_model_remove_child  (GooCanvasContainerModel *model,
+				      gint                     child_num)
 {
   GooCanvasGroupModel *gmodel = (GooCanvasGroupModel*) model;
   GooCanvasItemModel *child;
 
   child = gmodel->children->pdata[child_num];
   goo_canvas_item_model_set_parent (child, NULL);
-  g_object_unref (child);
 
   g_ptr_array_remove_index (gmodel->children, child_num);
 
   g_signal_emit_by_name (gmodel, "child-removed", child_num);
+
+  g_object_unref (child);
 }
 
 
 static gint
-goo_canvas_group_model_get_n_children (GooCanvasItemModel  *model)
+goo_canvas_group_model_get_n_children (GooCanvasContainerModel  *model)
 {
   GooCanvasGroupModel *gmodel = (GooCanvasGroupModel*) model;
 
@@ -790,8 +811,8 @@ goo_canvas_group_model_get_n_children (G
 
 
 static GooCanvasItemModel*
-goo_canvas_group_model_get_child   (GooCanvasItemModel  *model,
-				    gint                 child_num)
+goo_canvas_group_model_get_child   (GooCanvasContainerModel  *model,
+				    gint                      child_num)
 {
   GooCanvasGroupModel *gmodel = (GooCanvasGroupModel*) model;
 
@@ -820,13 +841,16 @@ goo_canvas_group_model_create_item (GooC
 static void
 item_model_interface_init (GooCanvasItemModelIface *iface)
 {
+  iface->create_item    = goo_canvas_group_model_create_item;
+}
+
+static void
+container_model_interface_init (GooCanvasContainerModelIface *iface)
+{
   iface->add_child      = goo_canvas_group_model_add_child;
   iface->move_child     = goo_canvas_group_model_move_child;
   iface->remove_child   = goo_canvas_group_model_remove_child;
   iface->get_n_children = goo_canvas_group_model_get_n_children;
   iface->get_child      = goo_canvas_group_model_get_child;
 
-  iface->create_item    = goo_canvas_group_model_create_item;
 }
-
-
Index: src/goocanvasitem.c
===================================================================
--- src/goocanvasitem.c	(revision 27)
+++ src/goocanvasitem.c	(working copy)
@@ -16,8 +16,6 @@
 #include <config.h>
 #include <math.h>
 #include <glib/gi18n-lib.h>
-#include <gobject/gobjectnotifyqueue.c>
-#include <gobject/gvaluecollector.h>
 #include <gtk/gtk.h>
 #include "goocanvasprivate.h"
 #include "goocanvasitem.h"
@@ -25,9 +23,6 @@
 #include "goocanvasutils.h"
 #include "goocanvasmarshal.h"
 
-
-static GParamSpecPool       *_goo_canvas_item_child_property_pool = NULL;
-static GObjectNotifyContext *_goo_canvas_item_child_property_notify_context = NULL;
 static const char *animation_key = "GooCanvasItemAnimation";
 
 enum {
@@ -82,36 +77,15 @@ goo_canvas_item_get_type (void)
   return canvas_item_type;
 }
 
-
-static void
-child_property_notify_dispatcher (GObject     *object,
-				  guint        n_pspecs,
-				  GParamSpec **pspecs)
-{
-  guint i;
-
-  for (i = 0; i < n_pspecs; i++)
-    g_signal_emit (object, canvas_item_signals[CHILD_NOTIFY],
-		   g_quark_from_string (pspecs[i]->name), pspecs[i]);
-}
-
-
 static void
 goo_canvas_item_base_init (gpointer g_iface)
 {
-  static GObjectNotifyContext cpn_context = { 0, NULL, NULL };
   static gboolean initialized = FALSE;
   
   if (!initialized)
     {
       GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
 
-      _goo_canvas_item_child_property_pool = g_param_spec_pool_new (TRUE);
-
-      cpn_context.quark_notify_queue = g_quark_from_static_string ("GooCanvasItem-child-property-notify-queue");
-      cpn_context.dispatcher = child_property_notify_dispatcher;
-      _goo_canvas_item_child_property_notify_context = &cpn_context;
-
       /* Mouse events. */
 
       /**
@@ -396,7 +370,7 @@ goo_canvas_item_base_init (gpointer g_if
 					   g_param_spec_object ("parent",
 								_("Parent"),
 								_("The parent item"),
-								GOO_TYPE_CANVAS_ITEM,
+								GOO_TYPE_CANVAS_CONTAINER,
 								G_PARAM_READWRITE));
 
       g_object_interface_install_property (g_iface,
@@ -478,10 +452,10 @@ goo_canvas_item_get_canvas (GooCanvasIte
     }
   else
     {
-      GooCanvasItem *parent = iface->get_parent (item);
+      GooCanvasContainer *parent = iface->get_parent (item);
 
       if (parent)
-	return goo_canvas_item_get_canvas (parent);
+	return goo_canvas_item_get_canvas (GOO_CANVAS_ITEM (parent));
       return NULL;
     }
 }
@@ -509,151 +483,6 @@ goo_canvas_item_set_canvas     (GooCanva
 
 
 /**
- * goo_canvas_item_add_child:
- * @item: the container to add the item to.
- * @child: the item to add.
- * @position: the position of the item, or -1 to place it last (at the top of
- *  the stacking order).
- * 
- * Adds a child item to a container item at the given stack position.
- **/
-void
-goo_canvas_item_add_child      (GooCanvasItem       *item,
-				GooCanvasItem       *child,
-				gint                 position)
-{
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
-
-  g_return_if_fail (iface->add_child != NULL);
-  g_return_if_fail (item != child);
-
-  iface->add_child (item, child, position);
-}
-
-
-/**
- * goo_canvas_item_move_child:
- * @item: a container item.
- * @old_position: the current position of the child item.
- * @new_position: the new position of the child item.
- * 
- * Moves a child item to a new stack position within the container.
- **/
-void
-goo_canvas_item_move_child     (GooCanvasItem       *item,
-				gint                 old_position,
-				gint                 new_position)
-{
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
-
-  g_return_if_fail (iface->move_child != NULL);
-
-  iface->move_child (item, old_position, new_position);
-}
-
-
-/**
- * goo_canvas_item_remove_child:
- * @item: a container item.
- * @child_num: the position of the child item to remove.
- * 
- * Removes the child item at the given position.
- **/
-void
-goo_canvas_item_remove_child   (GooCanvasItem       *item,
-				gint                 child_num)
-{
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
-
-  g_return_if_fail (iface->remove_child != NULL);
-
-  iface->remove_child (item, child_num);
-}
-
-
-/**
- * goo_canvas_item_find_child:
- * @item: a container item.
- * @child: the child item to find.
- * 
- * Attempts to find the given child item with the container's stack.
- * 
- * Returns: the position of the given @child item, or -1 if it isn't found.
- **/
-gint
-goo_canvas_item_find_child     (GooCanvasItem *item,
-				GooCanvasItem *child)
-{
-  GooCanvasItem *tmp;
-  int n_children, i;
-
-  /* Find the current position of item and above. */
-  n_children = goo_canvas_item_get_n_children (item);
-  for (i = 0; i < n_children; i++)
-    {
-      tmp = goo_canvas_item_get_child (item, i);
-      if (child == tmp)
-	return i;
-    }
-  return -1;
-}
-
-
-/**
- * goo_canvas_item_is_container:
- * @item: an item.
- * 
- * Tests to see if the given item is a container.
- * 
- * Returns: %TRUE if the item is a container.
- **/
-gboolean
-goo_canvas_item_is_container (GooCanvasItem       *item)
-{
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
-
-  return iface->get_n_children ? TRUE : FALSE;
-}
-
-
-/**
- * goo_canvas_item_get_n_children:
- * @item: a container item.
- * 
- * Gets the number of children of the container.
- * 
- * Returns: the number of children.
- **/
-gint
-goo_canvas_item_get_n_children (GooCanvasItem       *item)
-{
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
-
-  return iface->get_n_children ? iface->get_n_children (item) : 0;
-}
-
-
-/**
- * goo_canvas_item_get_child:
- * @item: a container item.
- * @child_num: the position of a child in the container's stack.
- * 
- * Gets the child item at the given stack position.
- * 
- * Returns: the child item at the given stack position, or %NULL if @child_num
- * is out of range.
- **/
-GooCanvasItem*
-goo_canvas_item_get_child (GooCanvasItem       *item,
-			   gint                 child_num)
-{
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
-
-  return iface->get_child ? iface->get_child (item, child_num) : NULL;
-}
-
-
-/**
  * goo_canvas_item_get_parent:
  * @item: an item.
  * 
@@ -661,7 +490,7 @@ goo_canvas_item_get_child (GooCanvasItem
  * 
  * Returns: the parent item, or %NULL if the item has no parent.
  **/
-GooCanvasItem*
+GooCanvasContainer*
 goo_canvas_item_get_parent  (GooCanvasItem *item)
 {
   g_return_val_if_fail (GOO_IS_CANVAS_ITEM (item), NULL);
@@ -673,7 +502,7 @@ goo_canvas_item_get_parent  (GooCanvasIt
 /**
  * goo_canvas_item_set_parent:
  * @item: an item.
- * @parent: the new parent item.
+ * @parent: the new parent container.
  * 
  * This function is only intended to be used when implementing new canvas
  * items (specifically container items such as #GooCanvasGroup).
@@ -686,8 +515,8 @@ goo_canvas_item_get_parent  (GooCanvasIt
  * </para></note>
  **/
 void
-goo_canvas_item_set_parent (GooCanvasItem *item,
-			    GooCanvasItem *parent)
+goo_canvas_item_set_parent (GooCanvasItem      *item,
+			    GooCanvasContainer *parent)
 {
   GOO_CANVAS_ITEM_GET_IFACE (item)->set_parent (item, parent);
 }
@@ -748,18 +577,18 @@ goo_canvas_item_set_is_static	(GooCanvas
 void
 goo_canvas_item_remove (GooCanvasItem *item)
 {
-  GooCanvasItem *parent;
+  GooCanvasContainer *parent;
   gint child_num;
 
   parent = goo_canvas_item_get_parent (item);
   if (!parent)
     return;
 
-  child_num = goo_canvas_item_find_child (parent, item);
+  child_num = goo_canvas_container_find_child (parent, item);
   if (child_num == -1)
     return;
 
-  goo_canvas_item_remove_child (parent, child_num);
+  goo_canvas_container_remove_child (parent, child_num);
 }
 
 
@@ -775,7 +604,8 @@ void
 goo_canvas_item_raise          (GooCanvasItem *item,
 				GooCanvasItem *above)
 {
-  GooCanvasItem *parent, *child;
+  GooCanvasContainer *parent;
+  GooCanvasItem *child;
   int n_children, i, item_pos = -1, above_pos = -1;
 
   parent = goo_canvas_item_get_parent (item);
@@ -783,10 +613,10 @@ goo_canvas_item_raise          (GooCanva
     return;
 
   /* Find the current position of item and above. */
-  n_children = goo_canvas_item_get_n_children (parent);
+  n_children = goo_canvas_container_get_n_children (parent);
   for (i = 0; i < n_children; i++)
     {
-      child = goo_canvas_item_get_child (parent, i);
+      child = goo_canvas_container_get_child (parent, i);
       if (child == item)
 	item_pos = i;
       if (child == above)
@@ -802,7 +632,7 @@ goo_canvas_item_raise          (GooCanva
 
   /* Only move the item if the new position is higher in the stack. */
   if (above_pos > item_pos)
-    goo_canvas_item_move_child (parent, item_pos, above_pos);
+    goo_canvas_container_move_child (parent, item_pos, above_pos);
 }
 
 
@@ -818,7 +648,8 @@ void
 goo_canvas_item_lower          (GooCanvasItem *item,
 				GooCanvasItem *below)
 {
-  GooCanvasItem *parent, *child;
+  GooCanvasContainer *parent;
+  GooCanvasItem *child;
   int n_children, i, item_pos = -1, below_pos = -1;
 
   parent = goo_canvas_item_get_parent (item);
@@ -826,10 +657,10 @@ goo_canvas_item_lower          (GooCanva
     return;
 
   /* Find the current position of item and below. */
-  n_children = goo_canvas_item_get_n_children (parent);
+  n_children = goo_canvas_container_get_n_children (parent);
   for (i = 0; i < n_children; i++)
     {
-      child = goo_canvas_item_get_child (parent, i);
+      child = goo_canvas_container_get_child (parent, i);
       if (child == item)
 	item_pos = i;
       if (child == below)
@@ -845,7 +676,7 @@ goo_canvas_item_lower          (GooCanva
 
   /* Only move the item if the new position is lower in the stack. */
   if (below_pos < item_pos)
-    goo_canvas_item_move_child (parent, item_pos, below_pos);
+    goo_canvas_container_move_child (parent, item_pos, below_pos);
 }
 
 
@@ -869,36 +700,6 @@ goo_canvas_item_get_transform  (GooCanva
 
 
 /**
- * goo_canvas_item_get_transform_for_child:
- * @item: an item.
- * @child: a child of @item.
- * @transform: the place to store the transform.
- * 
- * Gets the transformation matrix of an item combined with any special
- * transform needed for the given child. These special transforms are used
- * by layout items such as #GooCanvasTable.
- * 
- * Returns: %TRUE if a transform is set.
- **/
-gboolean
-goo_canvas_item_get_transform_for_child  (GooCanvasItem  *item,
-					  GooCanvasItem  *child,
-					  cairo_matrix_t *transform)
-{
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
-
-  if (child && iface->get_transform_for_child)
-    return iface->get_transform_for_child (item, child, transform);
-
-  /* We fallback to the standard get_transform method. */
-  if (iface->get_transform)
-    return iface->get_transform (item, transform);
-
-  return FALSE;
-}
-
-
-/**
  * goo_canvas_item_set_transform:
  * @item: an item.
  * @transform: the new transformation matrix, or %NULL to reset the
@@ -1443,7 +1244,7 @@ goo_canvas_item_request_update  (GooCanv
   if (iface->request_update)
     iface->request_update (item);
   else
-    goo_canvas_item_request_update (iface->get_parent (item));
+    goo_canvas_item_request_update (GOO_CANVAS_ITEM (iface->get_parent (item)));
 }
 
 
@@ -1524,7 +1325,7 @@ gboolean
 goo_canvas_item_is_visible  (GooCanvasItem   *item)
 {
   GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
-  GooCanvasItem *parent;
+  GooCanvasContainer *parent;
 
   if (iface->is_visible)
     return iface->is_visible (item);
@@ -1533,7 +1334,7 @@ goo_canvas_item_is_visible  (GooCanvasIt
      visible and check its ancestors. */
   parent = goo_canvas_item_get_parent (item);
   if (parent)
-    return goo_canvas_item_is_visible (parent);
+    return goo_canvas_item_is_visible (GOO_CANVAS_ITEM (parent));
 
   return TRUE;
 }
@@ -1743,531 +1544,3 @@ goo_canvas_item_allocate_area      (GooC
 			x_offset, y_offset);
 }
 
-
-/*
- * Child Properties.
- */
-static inline void
-item_get_child_property (GObject      *object,
-			 GObject      *child,
-			 GParamSpec   *pspec,
-			 GValue       *value,
-			 gboolean      is_model)
-{
-  GObjectClass *class;
-
-  class = g_type_class_peek (pspec->owner_type);
-
-  if (is_model)
-    {
-      GooCanvasItemModelIface *iface;
-
-      iface = g_type_interface_peek (class, GOO_TYPE_CANVAS_ITEM_MODEL);
-      iface->get_child_property ((GooCanvasItemModel*) object,
-				 (GooCanvasItemModel*) child,
-				 pspec->param_id, value, pspec);
-    }
-  else
-    {
-      GooCanvasItemIface *iface;
-
-      iface = g_type_interface_peek (class, GOO_TYPE_CANVAS_ITEM);
-      iface->get_child_property ((GooCanvasItem*) object,
-				 (GooCanvasItem*) child,
-				 pspec->param_id, value, pspec);
-    }
-}
-
-
-void
-_goo_canvas_item_get_child_property_internal (GObject              *object,
-					      GObject              *child,
-					      const gchar          *property_name,
-					      GValue               *value,
-					      GParamSpecPool       *property_pool,
-					      gboolean              is_model)
-{
-  GParamSpec *pspec;
-
-  g_object_ref (object);
-  g_object_ref (child);
-  pspec = g_param_spec_pool_lookup (property_pool, property_name,
-				    G_OBJECT_TYPE (object), TRUE);
-  if (!pspec)
-    g_warning ("%s: class `%s' has no child property named `%s'",
-	       G_STRLOC,
-	       G_OBJECT_TYPE_NAME (object),
-	       property_name);
-  else if (!(pspec->flags & G_PARAM_READABLE))
-    g_warning ("%s: child property `%s' of class `%s' is not readable",
-	       G_STRLOC,
-	       pspec->name,
-	       G_OBJECT_TYPE_NAME (object));
-  else
-    {
-      GValue *prop_value, tmp_value = { 0, };
-
-      /* auto-conversion of the callers value type
-       */
-      if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
-	{
-	  g_value_reset (value);
-	  prop_value = value;
-	}
-      else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
-	{
-	  g_warning ("can't retrieve child property `%s' of type `%s' as value of type `%s'",
-		     pspec->name,
-		     g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
-		     G_VALUE_TYPE_NAME (value));
-	  g_object_unref (child);
-	  g_object_unref (object);
-	  return;
-	}
-      else
-	{
-	  g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
-	  prop_value = &tmp_value;
-	}
-      item_get_child_property (object, child, pspec, prop_value, is_model);
-      if (prop_value != value)
-	{
-	  g_value_transform (prop_value, value);
-	  g_value_unset (&tmp_value);
-	}
-    }
-  g_object_unref (child);
-  g_object_unref (object);
-}
-
-
-void
-_goo_canvas_item_get_child_properties_internal (GObject              *object,
-						GObject              *child,
-						va_list	              var_args,
-						GParamSpecPool       *property_pool,
-						GObjectNotifyContext *notify_context,
-						gboolean              is_model)
-{
-  g_object_ref (object);
-  g_object_ref (child);
-
-  for (;;)
-    {
-      GValue value = { 0, };
-      GParamSpec *pspec;
-      gchar *name, *error = NULL;
-
-      name = va_arg (var_args, gchar*);
-      if (!name)
-	break;
-
-      pspec = g_param_spec_pool_lookup (property_pool, name,
-					G_OBJECT_TYPE (object), TRUE);
-      if (!pspec)
-	{
-	  g_warning ("%s: class `%s' has no child property named `%s'",
-		     G_STRLOC, G_OBJECT_TYPE_NAME (object), name);
-	  break;
-	}
-      if (!(pspec->flags & G_PARAM_READABLE))
-	{
-	  g_warning ("%s: child property `%s' of class `%s' is not readable",
-		     G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (object));
-	  break;
-	}
-      g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
-      item_get_child_property (object, child, pspec, &value, is_model);
-      G_VALUE_LCOPY (&value, var_args, 0, &error);
-      if (error)
-	{
-	  g_warning ("%s: %s", G_STRLOC, error);
-	  g_free (error);
-	  g_value_unset (&value);
-	  break;
-	}
-      g_value_unset (&value);
-    }
-
-  g_object_unref (child);
-  g_object_unref (object);
-}
-
-
-static inline void
-canvas_item_set_child_property (GObject            *object,
-				GObject            *child,
-				GParamSpec         *pspec,
-				const GValue       *value,
-				GObjectNotifyQueue *nqueue,
-				gboolean            is_model)
-{
-  GValue tmp_value = { 0, };
-
-  /* provide a copy to work from, convert (if necessary) and validate */
-  g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
-  if (!g_value_transform (value, &tmp_value))
-    g_warning ("unable to set child property `%s' of type `%s' from value of type `%s'",
-	       pspec->name,
-	       g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
-	       G_VALUE_TYPE_NAME (value));
-  else if (g_param_value_validate (pspec, &tmp_value) && !(pspec->flags & G_PARAM_LAX_VALIDATION))
-    {
-      gchar *contents = g_strdup_value_contents (value);
-
-      g_warning ("value \"%s\" of type `%s' is invalid for property `%s' of type `%s'",
-		 contents,
-		 G_VALUE_TYPE_NAME (value),
-		 pspec->name,
-		 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
-      g_free (contents);
-    }
-  else
-    {
-      GObjectClass *class = g_type_class_peek (pspec->owner_type);
-
-      if (is_model)
-	{
-	  GooCanvasItemModelIface *iface;
-
-	  iface = g_type_interface_peek (class, GOO_TYPE_CANVAS_ITEM_MODEL);
-	  iface->set_child_property ((GooCanvasItemModel*) object,
-				     (GooCanvasItemModel*) child,
-				     pspec->param_id, &tmp_value, pspec);
-	}
-      else
-	{
-	  GooCanvasItemIface *iface;
-
-	  iface = g_type_interface_peek (class, GOO_TYPE_CANVAS_ITEM);
-	  iface->set_child_property ((GooCanvasItem*) object,
-				     (GooCanvasItem*) child,
-				     pspec->param_id, &tmp_value, pspec);
-	}
-
-      g_object_notify_queue_add (G_OBJECT (child), nqueue, pspec);
-    }
-  g_value_unset (&tmp_value);
-}
-
-
-void
-_goo_canvas_item_set_child_property_internal (GObject              *object,
-					      GObject              *child,
-					      const gchar          *property_name,
-					      const GValue         *value,
-					      GParamSpecPool       *property_pool,
-					      GObjectNotifyContext *notify_context,
-					      gboolean              is_model)
-{
-  GObjectNotifyQueue *nqueue;
-  GParamSpec *pspec;
-
-  g_object_ref (object);
-  g_object_ref (child);
-
-  nqueue = g_object_notify_queue_freeze (child, notify_context);
-  pspec = g_param_spec_pool_lookup (property_pool, property_name,
-				    G_OBJECT_TYPE (object), TRUE);
-  if (!pspec)
-    g_warning ("%s: class `%s' has no child property named `%s'",
-	       G_STRLOC,
-	       G_OBJECT_TYPE_NAME (object),
-	       property_name);
-  else if (!(pspec->flags & G_PARAM_WRITABLE))
-    g_warning ("%s: child property `%s' of class `%s' is not writable",
-	       G_STRLOC,
-	       pspec->name,
-	       G_OBJECT_TYPE_NAME (object));
-  else
-    {
-      canvas_item_set_child_property (object, child, pspec,
-				      value, nqueue, is_model);
-    }
-  g_object_notify_queue_thaw (child, nqueue);
-  g_object_unref (object);
-  g_object_unref (child);
-}
-
-
-void
-_goo_canvas_item_set_child_properties_internal (GObject              *object,
-						GObject              *child,
-						va_list	              var_args,
-						GParamSpecPool       *property_pool,
-						GObjectNotifyContext *notify_context,
-						gboolean              is_model)
-{
-  GObjectNotifyQueue *nqueue;
-
-  g_object_ref (object);
-  g_object_ref (child);
-
-  nqueue = g_object_notify_queue_freeze (child, notify_context);
-
-  for (;;)
-    {
-      GValue value = { 0, };
-      GParamSpec *pspec;
-      gchar *name, *error = NULL;
-
-      name = va_arg (var_args, gchar*);
-      if (!name)
-	break;
-
-      pspec = g_param_spec_pool_lookup (property_pool, name,
-					G_OBJECT_TYPE (object), TRUE);
-      if (!pspec)
-	{
-	  g_warning ("%s: class `%s' has no child property named `%s'",
-		     G_STRLOC, G_OBJECT_TYPE_NAME (object), name);
-	  break;
-	}
-      if (!(pspec->flags & G_PARAM_WRITABLE))
-	{
-	  g_warning ("%s: child property `%s' of class `%s' is not writable",
-		     G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (object));
-	  break;
-	}
-      g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
-      G_VALUE_COLLECT (&value, var_args, 0, &error);
-      if (error)
-	{
-	  g_warning ("%s: %s", G_STRLOC, error);
-	  g_free (error);
-
-	  /* we purposely leak the value here, it might not be
-	   * in a sane state if an error condition occoured
-	   */
-	  break;
-	}
-      canvas_item_set_child_property (object, child, pspec, &value, nqueue,
-				      is_model);
-      g_value_unset (&value);
-    }
-  g_object_notify_queue_thaw (G_OBJECT (child), nqueue);
-
-  g_object_unref (object);
-  g_object_unref (child);
-}
-
-
-/**
- * goo_canvas_item_get_child_property:
- * @item: a #GooCanvasItem.
- * @child: a child #GooCanvasItem.
- * @property_name: the name of the child property to get.
- * @value: a location to return the value.
- * 
- * Gets a child property of @child.
- **/
-void
-goo_canvas_item_get_child_property (GooCanvasItem *item,
-				    GooCanvasItem *child,
-				    const gchar   *property_name,
-				    GValue        *value)
-{
-  g_return_if_fail (GOO_IS_CANVAS_ITEM (item));
-  g_return_if_fail (GOO_IS_CANVAS_ITEM (child));
-  g_return_if_fail (property_name != NULL);
-  g_return_if_fail (G_IS_VALUE (value));
-
-  _goo_canvas_item_get_child_property_internal ((GObject*) item, (GObject*) child, property_name, value, _goo_canvas_item_child_property_pool, FALSE);
-}
-
-
-/**
- * goo_canvas_item_set_child_property:
- * @item: a #GooCanvasItem.
- * @child: a child #GooCanvasItem.
- * @property_name: the name of the child property to set.
- * @value: the value to set the property to.
- * 
- * Sets a child property of @child.
- **/
-void
-goo_canvas_item_set_child_property (GooCanvasItem   *item,
-				    GooCanvasItem   *child,
-				    const gchar     *property_name,
-				    const GValue    *value)
-{
-  g_return_if_fail (GOO_IS_CANVAS_ITEM (item));
-  g_return_if_fail (GOO_IS_CANVAS_ITEM (child));
-  g_return_if_fail (property_name != NULL);
-  g_return_if_fail (G_IS_VALUE (value));
-
-  _goo_canvas_item_set_child_property_internal ((GObject*) item, (GObject*) child, property_name, value, _goo_canvas_item_child_property_pool, _goo_canvas_item_child_property_notify_context, FALSE);
-}
-
-
-/**
- * goo_canvas_item_get_child_properties_valist:
- * @item: a #GooCanvasItem.
- * @child: a child #GooCanvasItem.
- * @var_args: pairs of property names and value pointers, and a terminating
- *  %NULL.
- * 
- * Gets the values of one or more child properties of @child.
- **/
-void
-goo_canvas_item_get_child_properties_valist (GooCanvasItem   *item,
-					     GooCanvasItem   *child,
-					     va_list	      var_args)
-{
-  g_return_if_fail (GOO_IS_CANVAS_ITEM (item));
-  g_return_if_fail (GOO_IS_CANVAS_ITEM (child));
-
-  _goo_canvas_item_get_child_properties_internal ((GObject*) item, (GObject*) child, var_args, _goo_canvas_item_child_property_pool, _goo_canvas_item_child_property_notify_context, FALSE);
-}
-
-
-/**
- * goo_canvas_item_set_child_properties_valist:
- * @item: a #GooCanvasItem.
- * @child: a child #GooCanvasItem.
- * @var_args: pairs of property names and values, and a terminating %NULL.
- * 
- * Sets the values of one or more child properties of @child.
- **/
-void
-goo_canvas_item_set_child_properties_valist (GooCanvasItem   *item,
-					     GooCanvasItem   *child,
-					     va_list	      var_args)
-{
-  g_return_if_fail (GOO_IS_CANVAS_ITEM (item));
-  g_return_if_fail (GOO_IS_CANVAS_ITEM (child));
-
-  _goo_canvas_item_set_child_properties_internal ((GObject*) item, (GObject*) child, var_args, _goo_canvas_item_child_property_pool, _goo_canvas_item_child_property_notify_context, FALSE);
-}
-
-
-/**
- * goo_canvas_item_get_child_properties:
- * @item: a #GooCanvasItem.
- * @child: a child #GooCanvasItem.
- * @...: pairs of property names and value pointers, and a terminating %NULL.
- * 
- * Gets the values of one or more child properties of @child.
- **/
-void
-goo_canvas_item_get_child_properties        (GooCanvasItem   *item,
-					     GooCanvasItem   *child,
-					     ...)
-{
-  va_list var_args;
-  
-  va_start (var_args, child);
-  goo_canvas_item_get_child_properties_valist (item, child, var_args);
-  va_end (var_args);
-}
-
-
-/**
- * goo_canvas_item_set_child_properties:
- * @item: a #GooCanvasItem.
- * @child: a child #GooCanvasItem.
- * @...: pairs of property names and values, and a terminating %NULL.
- * 
- * Sets the values of one or more child properties of @child.
- **/
-void
-goo_canvas_item_set_child_properties        (GooCanvasItem   *item,
-					     GooCanvasItem   *child,
-					     ...)
-{
-  va_list var_args;
-  
-  va_start (var_args, child);
-  goo_canvas_item_set_child_properties_valist (item, child, var_args);
-  va_end (var_args);
-}
-
-
-
-/**
- * goo_canvas_item_class_install_child_property:
- * @iclass: a #GObjectClass
- * @property_id: the id for the property
- * @pspec: the #GParamSpec for the property
- * 
- * This function is only intended to be used when implementing new canvas
- * items, specifically layout container items such as #GooCanvasTable.
- *
- * It installs a child property on a canvas item class. 
- **/
-void
-goo_canvas_item_class_install_child_property (GObjectClass *iclass,
-					      guint         property_id,
-					      GParamSpec   *pspec)
-{
-  g_return_if_fail (G_IS_OBJECT_CLASS (iclass));
-  g_return_if_fail (G_IS_PARAM_SPEC (pspec));
-  g_return_if_fail (property_id > 0);
-
-  if (g_param_spec_pool_lookup (_goo_canvas_item_child_property_pool,
-				pspec->name, G_OBJECT_CLASS_TYPE (iclass),
-				FALSE))
-    {
-      g_warning (G_STRLOC ": class `%s' already contains a child property named `%s'",
-		 G_OBJECT_CLASS_NAME (iclass), pspec->name);
-      return;
-    }
-  g_param_spec_ref (pspec);
-  g_param_spec_sink (pspec);
-  pspec->param_id = property_id;
-  g_param_spec_pool_insert (_goo_canvas_item_child_property_pool, pspec,
-			    G_OBJECT_CLASS_TYPE (iclass));
-}
-
-/**
- * goo_canvas_item_class_find_child_property:
- * @iclass: a #GObjectClass
- * @property_name: the name of the child property to find
- * @returns: the #GParamSpec of the child property or %NULL if @class has no
- *   child property with that name.
- *
- * This function is only intended to be used when implementing new canvas
- * items, specifically layout container items such as #GooCanvasTable.
- *
- * It finds a child property of a canvas item class by name.
- */
-GParamSpec*
-goo_canvas_item_class_find_child_property (GObjectClass *iclass,
-					   const gchar  *property_name)
-{
-  g_return_val_if_fail (G_IS_OBJECT_CLASS (iclass), NULL);
-  g_return_val_if_fail (property_name != NULL, NULL);
-
-  return g_param_spec_pool_lookup (_goo_canvas_item_child_property_pool,
-				   property_name, G_OBJECT_CLASS_TYPE (iclass),
-				   TRUE);
-}
-
-/**
- * goo_canvas_item_class_list_child_properties:
- * @iclass: a #GObjectClass
- * @n_properties: location to return the number of child properties found
- * @returns: a newly allocated array of #GParamSpec*. The array must be 
- *           freed with g_free().
- *
- * This function is only intended to be used when implementing new canvas
- * items, specifically layout container items such as #GooCanvasTable.
- *
- * It returns all child properties of a canvas item class.
- */
-GParamSpec**
-goo_canvas_item_class_list_child_properties (GObjectClass *iclass,
-					     guint        *n_properties)
-{
-  GParamSpec **pspecs;
-  guint n;
-
-  g_return_val_if_fail (G_IS_OBJECT_CLASS (iclass), NULL);
-
-  pspecs = g_param_spec_pool_list (_goo_canvas_item_child_property_pool,
-				   G_OBJECT_CLASS_TYPE (iclass), &n);
-  if (n_properties)
-    *n_properties = n;
-
-  return pspecs;
-}
Index: src/goocanvaspolyline.h
===================================================================
--- src/goocanvaspolyline.h	(revision 27)
+++ src/goocanvaspolyline.h	(working copy)
@@ -106,12 +106,12 @@ struct _GooCanvasPolylineClass
 
 GType               goo_canvas_polyline_get_type       (void) G_GNUC_CONST;
 
-GooCanvasItem*      goo_canvas_polyline_new            (GooCanvasItem      *parent,
+GooCanvasItem*      goo_canvas_polyline_new            (GooCanvasContainer *parent,
 							gboolean            close_path,
 							gint                num_points,
 							...);
 
-GooCanvasItem*      goo_canvas_polyline_new_line       (GooCanvasItem      *parent,
+GooCanvasItem*      goo_canvas_polyline_new_line       (GooCanvasContainer *parent,
 							gdouble             x1,
 							gdouble             y1,
 							gdouble             x2,
@@ -159,16 +159,16 @@ struct _GooCanvasPolylineModelClass
 
 GType               goo_canvas_polyline_model_get_type  (void) G_GNUC_CONST;
 
-GooCanvasItemModel* goo_canvas_polyline_model_new      (GooCanvasItemModel *parent,
-							gboolean            close_path,
-							gint                num_points,
+GooCanvasItemModel* goo_canvas_polyline_model_new      (GooCanvasContainerModel *parent,
+							gboolean                 close_path,
+							gint                     num_points,
 							...);
 
-GooCanvasItemModel* goo_canvas_polyline_model_new_line (GooCanvasItemModel *parent,
-							gdouble             x1,
-							gdouble             y1,
-							gdouble             x2,
-							gdouble             y2,
+GooCanvasItemModel* goo_canvas_polyline_model_new_line (GooCanvasContainerModel *parent,
+							gdouble                  x1,
+							gdouble                  y1,
+							gdouble                  x2,
+							gdouble                  y2,
 							...);
 
 G_END_DECLS
Index: src/goocanvaspath.h
===================================================================
--- src/goocanvaspath.h	(revision 27)
+++ src/goocanvaspath.h	(working copy)
@@ -61,7 +61,7 @@ struct _GooCanvasPathClass
 
 GType               goo_canvas_path_get_type  (void) G_GNUC_CONST;
 
-GooCanvasItem*      goo_canvas_path_new       (GooCanvasItem      *parent,
+GooCanvasItem*      goo_canvas_path_new       (GooCanvasContainer *parent,
 					       const gchar        *path_data,
 					       ...);
 
@@ -106,8 +106,8 @@ struct _GooCanvasPathModelClass
 
 GType               goo_canvas_path_model_get_type  (void) G_GNUC_CONST;
 
-GooCanvasItemModel* goo_canvas_path_model_new (GooCanvasItemModel *parent,
-					       const gchar        *path_data,
+GooCanvasItemModel* goo_canvas_path_model_new (GooCanvasContainerModel *parent,
+					       const gchar             *path_data,
 					       ...);
 
 
Index: src/goocanvasgroup.h
===================================================================
--- src/goocanvasgroup.h	(revision 27)
+++ src/goocanvasgroup.h	(working copy)
@@ -8,7 +8,9 @@
 #define __GOO_CANVAS_GROUP_H__
 
 #include <gtk/gtk.h>
+#include "goocanvasitem.h"
 #include "goocanvasitemsimple.h"
+#include "goocanvascontainer.h"
 #include "goocanvasutils.h"
 
 G_BEGIN_DECLS
@@ -22,7 +24,6 @@ G_BEGIN_DECLS
 #define GOO_CANVAS_GROUP_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS_GROUP, GooCanvasGroupClass))
 
 
-typedef struct _GooCanvasGroup            GooCanvasGroup;
 typedef struct _GooCanvasGroupClass       GooCanvasGroupClass;
 
 typedef struct _GooCanvasGroupModel       GooCanvasGroupModel;
@@ -33,6 +34,7 @@ typedef struct _GooCanvasGroupModelClass
  *
  * The #GooCanvasGroup-struct struct contains private data only.
  */
+typedef struct _GooCanvasGroup GooCanvasGroup;
 struct _GooCanvasGroup
 {
   GooCanvasItemSimple parent_object;
@@ -57,11 +59,9 @@ struct _GooCanvasGroupClass
 
 
 GType          goo_canvas_group_get_type    (void) G_GNUC_CONST;
-GooCanvasItem* goo_canvas_group_new         (GooCanvasItem  *parent,
+GooCanvasItem* goo_canvas_group_new         (GooCanvasContainer *parent,
 					     ...);
 
-
-
 #define GOO_TYPE_CANVAS_GROUP_MODEL            (goo_canvas_group_model_get_type ())
 #define GOO_CANVAS_GROUP_MODEL(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_GROUP_MODEL, GooCanvasGroupModel))
 #define GOO_CANVAS_GROUP_MODEL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_GROUP_MODEL, GooCanvasGroupModelClass))
@@ -100,7 +100,7 @@ struct _GooCanvasGroupModelClass
 
 
 GType               goo_canvas_group_model_get_type (void) G_GNUC_CONST;
-GooCanvasItemModel* goo_canvas_group_model_new      (GooCanvasItemModel  *parent,
+GooCanvasItemModel* goo_canvas_group_model_new      (GooCanvasContainerModel  *parent,
 						     ...);
 
 
Index: src/goocanvasitem.h
===================================================================
--- src/goocanvasitem.h	(revision 27)
+++ src/goocanvasitem.h	(working copy)
@@ -60,8 +60,10 @@ GType goo_canvas_bounds_get_type (void) 
 
 
 /* Workaround for circular dependencies. Include this file first. */
-typedef struct _GooCanvas           GooCanvas;
-typedef struct _GooCanvasItemModel  GooCanvasItemModel;
+typedef struct _GooCanvas                GooCanvas;
+typedef struct _GooCanvasContainer       GooCanvasContainer;
+typedef struct _GooCanvasItemModel       GooCanvasItemModel;
+typedef struct _GooCanvasContainerModel  GooCanvasContainerModel;
 
 
 /**
@@ -80,16 +82,7 @@ typedef struct _GooCanvasItem       GooC
  * GooCanvasItemIface
  * @get_canvas: returns the canvas the item is in.
  * @set_canvas: sets the canvas the item is in.
- * @get_n_children: returns the number of children of the item.
- * @get_child: returns the child at the given index.
  * @request_update: requests that an update is scheduled.
- * @add_child: adds a child.
- * @move_child: moves a child up or down the stacking order.
- * @remove_child: removes a child.
- * @get_child_property: gets a child property of a given child item,
- *  e.g. the "row" or "column" property of an item in a #GooCanvasTable.
- * @set_child_property: sets a child property for a given child item.
- * @get_transform_for_child: gets the transform used to lay out a given child.
  * @get_parent: gets the item's parent.
  * @set_parent: sets the item's parent.
  * @get_bounds: gets the bounds of the item.
@@ -140,13 +133,6 @@ typedef struct _GooCanvasItem       GooC
  * Items that support transforms should also implement get_transform() and
  * set_transform(). Items that support styles should implement get_style()
  * and set_style().
- *
- * Container items must implement get_canvas(), set_canvas(),
- * get_n_children(), get_child() and request_update(). Containers that support
- * dynamic changes to their children should implement add_child(),
- * move_child() and remove_child(). Layout containers like #GooCanvasTable
- * may implement get_child_property(), set_child_property() and
- * get_transform_for_child().
  */
 typedef struct _GooCanvasItemIface  GooCanvasItemIface;
 
@@ -156,42 +142,15 @@ struct _GooCanvasItemIface
   GTypeInterface base_iface;
 
   /*< public >*/
-  /* Virtual methods that group items must implement. */
   GooCanvas*		(* get_canvas)			(GooCanvasItem		*item);
   void			(* set_canvas)			(GooCanvasItem		*item,
 							 GooCanvas		*canvas);
-  gint			(* get_n_children)		(GooCanvasItem		*item);
-  GooCanvasItem*	(* get_child)			(GooCanvasItem		*item,
-							 gint			 child_num);
   void			(* request_update)		(GooCanvasItem		*item);
 
-  /* Virtual methods that group items may implement. */
-  void			(* add_child)			(GooCanvasItem		*item,
-							 GooCanvasItem		*child,
-							 gint			 position);
-  void			(* move_child)			(GooCanvasItem		*item,
-							 gint			 old_position,
-							 gint			 new_position);
-  void			(* remove_child)		(GooCanvasItem		*item,
-							 gint			 child_num);
-  void			(* get_child_property)		(GooCanvasItem		*item,
-							 GooCanvasItem		*child,
-							 guint			 property_id,
-							 GValue			*value,
-							 GParamSpec		*pspec);
-  void			(* set_child_property)		(GooCanvasItem		*item,
-							 GooCanvasItem		*child,
-							 guint			 property_id,
-							 const GValue		*value,
-							 GParamSpec		*pspec);
-  gboolean		(* get_transform_for_child)	(GooCanvasItem		*item,
-							 GooCanvasItem		*child,
-							 cairo_matrix_t		*transform);
-
   /* Virtual methods that all canvas items must implement. */
-  GooCanvasItem*	(* get_parent)			(GooCanvasItem		*item);
+  GooCanvasContainer*	(* get_parent)			(GooCanvasItem		*item);
   void			(* set_parent)			(GooCanvasItem		*item,
-							 GooCanvasItem		*parent);
+							 GooCanvasContainer	*parent);
   void			(* get_bounds)			(GooCanvasItem		*item,
 							 GooCanvasBounds	*bounds);
   GList*		(* get_items_at)		(GooCanvasItem		*item,
@@ -305,69 +264,24 @@ struct _GooCanvasItemIface
 
 GType              goo_canvas_item_get_type       (void) G_GNUC_CONST;
 
-
-/*
- * Group functions - these should only be called on container items.
- */
-gint               goo_canvas_item_get_n_children (GooCanvasItem   *item);
-GooCanvasItem*     goo_canvas_item_get_child      (GooCanvasItem   *item,
-						   gint             child_num);
-gint               goo_canvas_item_find_child     (GooCanvasItem   *item,
-						   GooCanvasItem   *child);
-void               goo_canvas_item_add_child      (GooCanvasItem   *item,
-						   GooCanvasItem   *child,
-						   gint             position);
-void               goo_canvas_item_move_child     (GooCanvasItem   *item,
-						   gint             old_position,
-						   gint             new_position);
-void               goo_canvas_item_remove_child   (GooCanvasItem   *item,
-						   gint             child_num);
-
-void  goo_canvas_item_get_child_property	  (GooCanvasItem   *item,
-						   GooCanvasItem   *child,
-						   const gchar     *property_name,
-						   GValue          *value);
-void  goo_canvas_item_set_child_property	  (GooCanvasItem   *item,
-						   GooCanvasItem   *child,
-						   const gchar     *property_name,
-						   const GValue    *value);
-void  goo_canvas_item_get_child_properties        (GooCanvasItem   *item,
-						   GooCanvasItem   *child,
-						   ...) G_GNUC_NULL_TERMINATED;
-void  goo_canvas_item_set_child_properties        (GooCanvasItem   *item,
-						   GooCanvasItem   *child,
-						   ...) G_GNUC_NULL_TERMINATED;
-void  goo_canvas_item_get_child_properties_valist (GooCanvasItem   *item,
-						   GooCanvasItem   *child,
-						   va_list	    var_args);
-void  goo_canvas_item_set_child_properties_valist (GooCanvasItem   *item,
-						   GooCanvasItem   *child,
-						   va_list	    var_args);
-
-gboolean goo_canvas_item_get_transform_for_child  (GooCanvasItem   *item,
-						   GooCanvasItem   *child,
-						   cairo_matrix_t  *transform);
-
-
 /*
  * Item functions - these are safe to call on all items.
  */
-GooCanvas*         goo_canvas_item_get_canvas     (GooCanvasItem   *item);
-void               goo_canvas_item_set_canvas     (GooCanvasItem   *item,
-						   GooCanvas       *canvas);
-GooCanvasItem*     goo_canvas_item_get_parent     (GooCanvasItem   *item);
-void               goo_canvas_item_set_parent	  (GooCanvasItem   *item,
-						   GooCanvasItem   *parent);
-void               goo_canvas_item_remove         (GooCanvasItem   *item);
-gboolean           goo_canvas_item_is_container   (GooCanvasItem   *item);
-
-void               goo_canvas_item_raise          (GooCanvasItem   *item,
-						   GooCanvasItem   *above);
-void               goo_canvas_item_lower          (GooCanvasItem   *item,
-						   GooCanvasItem   *below);
+GooCanvas*         goo_canvas_item_get_canvas     (GooCanvasItem       *item);
+void               goo_canvas_item_set_canvas     (GooCanvasItem      *item,
+						   GooCanvas          *canvas);
+GooCanvasContainer*goo_canvas_item_get_parent     (GooCanvasItem      *item);
+void               goo_canvas_item_set_parent	  (GooCanvasItem      *item,
+						   GooCanvasContainer *parent);
+void               goo_canvas_item_remove         (GooCanvasItem      *item);
+
+void               goo_canvas_item_raise          (GooCanvasItem      *item,
+						   GooCanvasItem      *above);
+void               goo_canvas_item_lower          (GooCanvasItem      *item,
+						   GooCanvasItem      *below);
 
-gboolean           goo_canvas_item_get_transform  (GooCanvasItem   *item,
-						   cairo_matrix_t  *transform);
+gboolean           goo_canvas_item_get_transform  (GooCanvasItem      *item,
+						   cairo_matrix_t     *transform);
 void               goo_canvas_item_set_transform  (GooCanvasItem         *item,
 						   const cairo_matrix_t  *transform);
 gboolean	   goo_canvas_item_get_simple_transform (GooCanvasItem   *item,
@@ -460,21 +374,6 @@ gboolean	   goo_canvas_item_get_is_stati
 void		   goo_canvas_item_set_is_static	(GooCanvasItem		*item,
 							 gboolean		 is_static);
 
-
-/*
- * Functions to support child properties when implementing new canvas items.
- */
-void         goo_canvas_item_class_install_child_property (GObjectClass *iclass,
-							   guint	 property_id,
-							   GParamSpec	*pspec);
-GParamSpec*  goo_canvas_item_class_find_child_property	  (GObjectClass	*iclass,
-							   const gchar	*property_name);
-GParamSpec** goo_canvas_item_class_list_child_properties  (GObjectClass	*iclass,
-							   guint	*n_properties);
-
-
-
-
 G_END_DECLS
 
 #endif /* __GOO_CANVAS_ITEM_H__ */
Index: src/goocanvasitemsimple.c
===================================================================
--- src/goocanvasitemsimple.c	(revision 27)
+++ src/goocanvasitemsimple.c	(working copy)
@@ -78,6 +78,7 @@ enum {
   PROP_TITLE,
   PROP_DESCRIPTION,
   PROP_CAN_FOCUS,
+
   PROP_CLIP_PATH,
   PROP_CLIP_FILL_RULE
 };
@@ -113,7 +114,7 @@ static gboolean goo_canvas_item_simple_d
 G_DEFINE_TYPE_WITH_CODE (GooCanvasItemSimple, goo_canvas_item_simple,
 			 G_TYPE_OBJECT,
 			 G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM,
-						canvas_item_interface_init))
+					        canvas_item_interface_init))
 
 
 static void
@@ -752,7 +753,7 @@ goo_canvas_item_simple_set_property (GOb
   GooCanvasItem *item = (GooCanvasItem*) object;
   GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
   GooCanvasItemSimpleData *simple_data = simple->simple_data;
-  GooCanvasItem *parent;
+  GooCanvasContainer *parent;
   AtkObject *accessible;
   gboolean recompute_bounds;
 
@@ -767,7 +768,7 @@ goo_canvas_item_simple_set_property (GOb
     case PROP_PARENT:
       parent = g_value_get_object (value);
       goo_canvas_item_remove (item);
-      goo_canvas_item_add_child (parent, item, -1);
+      goo_canvas_container_add_child (parent, item, -1);
       break;
     case PROP_TITLE:
       accessible = atk_gobject_accessible_for_object (object);
@@ -806,7 +807,7 @@ goo_canvas_item_simple_set_canvas  (GooC
 }
 
 
-static GooCanvasItem*
+static GooCanvasContainer*
 goo_canvas_item_simple_get_parent (GooCanvasItem   *item)
 {
   GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
@@ -815,14 +816,14 @@ goo_canvas_item_simple_get_parent (GooCa
 
 
 static void
-goo_canvas_item_simple_set_parent (GooCanvasItem  *item,
-				   GooCanvasItem  *parent)
+goo_canvas_item_simple_set_parent (GooCanvasItem      *item,
+				   GooCanvasContainer *parent)
 {
   GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
   GooCanvas *canvas;
 
   simple->parent = parent;
-  canvas = parent ? goo_canvas_item_get_canvas (parent) : NULL;
+  canvas = parent ? goo_canvas_item_get_canvas (GOO_CANVAS_ITEM (parent)) : NULL;
   goo_canvas_item_set_canvas (item, canvas);
   simple->need_update = TRUE;
   simple->need_entire_subtree_update = TRUE;
@@ -1061,7 +1062,7 @@ goo_canvas_item_simple_is_visible  (GooC
     return FALSE;
 
   if (simple->parent)
-    return goo_canvas_item_is_visible (simple->parent);
+    return goo_canvas_item_is_visible (GOO_CANVAS_ITEM (simple->parent));
 
   return TRUE;
 }
@@ -1106,7 +1107,7 @@ goo_canvas_item_simple_check_style (GooC
   GooCanvasStyle *parent_style = NULL;
 
   if (item->parent)
-    parent_style = goo_canvas_item_get_style (item->parent);
+    parent_style = goo_canvas_item_get_style (GOO_CANVAS_ITEM(item->parent));
 
   if (simple_data->own_style)
     {
@@ -1931,7 +1932,7 @@ goo_canvas_item_model_simple_set_propert
   GooCanvasItemModel *model = (GooCanvasItemModel*) object;
   GooCanvasItemModelSimple *smodel = (GooCanvasItemModelSimple*) object;
   GooCanvasItemSimpleData *simple_data = &smodel->simple_data;
-  GooCanvasItemModel *parent;
+  GooCanvasContainerModel *parent;
   gboolean recompute_bounds;
 
   switch (prop_id)
@@ -1939,7 +1940,7 @@ goo_canvas_item_model_simple_set_propert
     case PROP_PARENT:
       parent = g_value_get_object (value);
       goo_canvas_item_model_remove (model);
-      goo_canvas_item_model_add_child (parent, model, -1);
+      goo_canvas_container_model_add_child (parent, model, -1);
       break;
     case PROP_TITLE:
       g_free (smodel->title);
@@ -1961,7 +1962,7 @@ goo_canvas_item_model_simple_set_propert
 }
 
 
-static GooCanvasItemModel*
+static GooCanvasContainerModel*
 goo_canvas_item_model_simple_get_parent (GooCanvasItemModel   *model)
 {
   GooCanvasItemModelSimple *smodel = (GooCanvasItemModelSimple*) model;
@@ -1970,8 +1971,8 @@ goo_canvas_item_model_simple_get_parent 
 
 
 static void
-goo_canvas_item_model_simple_set_parent (GooCanvasItemModel   *model,
-					 GooCanvasItemModel   *parent)
+goo_canvas_item_model_simple_set_parent (GooCanvasItemModel        *model,
+					 GooCanvasContainerModel   *parent)
 {
   GooCanvasItemModelSimple *smodel = (GooCanvasItemModelSimple*) model;
   smodel->parent = parent;
Index: src/goocanvasitemsimple.h
===================================================================
--- src/goocanvasitemsimple.h	(revision 27)
+++ src/goocanvasitemsimple.h	(working copy)
@@ -9,7 +9,9 @@
 
 #include <gtk/gtk.h>
 #include "goocanvasitem.h"
+#include "goocanvascontainer.h"
 #include "goocanvasitemmodel.h"
+#include "goocanvascontainermodel.h"
 #include "goocanvasstyle.h"
 #include "goocanvasutils.h"
 
@@ -100,7 +102,7 @@ struct _GooCanvasItemSimple
 
   /* <public> */
   GooCanvas *canvas;
-  GooCanvasItem *parent;
+  GooCanvasContainer *parent;
   GooCanvasItemModelSimple *model;
   GooCanvasItemSimpleData *simple_data;
   GooCanvasBounds bounds;
@@ -216,7 +218,7 @@ struct _GooCanvasItemModelSimple
   GObject parent_object;
 
   /*< public >*/
-  GooCanvasItemModel *parent;
+  GooCanvasContainerModel *parent;
   GooCanvasItemSimpleData simple_data;
 
   /*< private >*/
Index: src/goocanvas.c
===================================================================
--- src/goocanvas.c	(revision 27)
+++ src/goocanvas.c	(working copy)
@@ -1288,11 +1288,12 @@ goo_canvas_get_items_in_area_recurse (Go
   gboolean completely_inside = FALSE, completely_outside = FALSE;
   gboolean is_container, add_item = FALSE;
   gint n_children, i;
+  GooCanvasContainer *container;
 
   /* First check the item/container itself. */
   goo_canvas_item_get_bounds (item, &bounds);
 
-  is_container = goo_canvas_item_is_container (item);
+  is_container = GOO_IS_CANVAS_CONTAINER (item);
 
   if (bounds.x1 >= area->x1 && bounds.x2 <= area->x2
       && bounds.y1 >= area->y1 && bounds.y2 <= area->y2)
@@ -1319,13 +1320,14 @@ goo_canvas_get_items_in_area_recurse (Go
     found_items = g_list_prepend (found_items, item);
 
   /* Now check any children, if appropriate. */
-  if ((inside_area && !completely_outside)
-      || (!inside_area && !completely_inside))
+  if (((inside_area && !completely_outside)
+      || (!inside_area && !completely_inside)) && is_container)
     {
-      n_children = goo_canvas_item_get_n_children (item);
+      container = GOO_CANVAS_CONTAINER (item);
+      n_children = goo_canvas_container_get_n_children (container);
       for (i = 0; i < n_children; i++)
 	{
-	  GooCanvasItem *child = goo_canvas_item_get_child (item, i);
+	  GooCanvasItem *child = goo_canvas_container_get_child (container, i);
 	  found_items = goo_canvas_get_items_in_area_recurse (canvas, child,
 							      area,
 							      inside_area,
@@ -2791,7 +2793,7 @@ propagate_event (GooCanvas     *canvas,
       if (stop_emission || !valid)
 	break;
 
-      ancestor = goo_canvas_item_get_parent (ancestor);
+      ancestor = GOO_CANVAS_ITEM (goo_canvas_item_get_parent (ancestor));
     }
 
   if (item)
@@ -3507,7 +3509,7 @@ get_transform_to_item_space (GooCanvasIt
   while (tmp)
     {
       list = g_list_prepend (list, tmp);
-      tmp = goo_canvas_item_get_parent (tmp);
+      tmp = GOO_CANVAS_ITEM (goo_canvas_item_get_parent (tmp));
     }
 
   /* Now step down applying the inverse of each item's transformation. */
@@ -3515,13 +3517,23 @@ get_transform_to_item_space (GooCanvasIt
     {
       parent = (GooCanvasItem*) l->data;
       child = l->next ? (GooCanvasItem*) l->next->data : NULL;
-      has_transform = goo_canvas_item_get_transform_for_child (parent, child,
-							       &item_transform);
+
+      if (child)
+        {
+          has_transform = goo_canvas_container_get_transform_for_child (GOO_CANVAS_CONTAINER (parent),
+                                                                        child,
+							                &item_transform);
+        }
+      else
+        {
+          has_transform = goo_canvas_item_get_transform (parent, &item_transform);
+        }
+
       if (has_transform)
-	{
-	  cairo_matrix_invert (&item_transform);
-	  cairo_matrix_multiply (&inverse, &inverse, &item_transform);
-	}
+        {
+          cairo_matrix_invert (&item_transform);
+          cairo_matrix_multiply (&inverse, &inverse, &item_transform);
+        }
     }
   g_list_free (list);
 
@@ -3579,7 +3591,7 @@ goo_canvas_convert_from_item_space (GooC
   while (tmp)
     {
       list = g_list_prepend (list, tmp);
-      tmp = goo_canvas_item_get_parent (tmp);
+      tmp = GOO_CANVAS_ITEM (goo_canvas_item_get_parent (tmp));
     }
 
   /* Now step down applying each item's transformation. */
@@ -3587,12 +3599,21 @@ goo_canvas_convert_from_item_space (GooC
     {
       parent = (GooCanvasItem*) l->data;
       child = l->next ? (GooCanvasItem*) l->next->data : NULL;
-      has_transform = goo_canvas_item_get_transform_for_child (parent, child,
-							       &item_transform);
+
+      if (child)
+        {
+          has_transform = goo_canvas_container_get_transform_for_child (GOO_CANVAS_CONTAINER(parent), child,
+							                &item_transform);
+        }
+      else
+        {
+          has_transform = goo_canvas_item_get_transform (parent, &item_transform);
+        }
+
       if (has_transform)
-	{
-	  cairo_matrix_multiply (&transform, &transform, &item_transform);
-	}
+        {
+          cairo_matrix_multiply (&transform, &transform, &item_transform);
+        }
     }
   g_list_free (list);
 
@@ -3981,9 +4002,9 @@ goo_canvas_focus_recurse (GooCanvas     
     }
 
   /* If the item is a container, check the children recursively. */
-  n_children = goo_canvas_item_get_n_children (item);
-  if (n_children)
+  if (GOO_IS_CANVAS_CONTAINER (item))
     {
+      n_children = goo_canvas_container_get_n_children (GOO_CANVAS_CONTAINER (item));
       /* Check if we can skip the entire group. */
       switch (data->direction)
 	{
@@ -4017,7 +4038,7 @@ goo_canvas_focus_recurse (GooCanvas     
 
       for (i = 0; i < n_children; i++)
 	{
-	  child = goo_canvas_item_get_child (item, i);
+	  child = goo_canvas_container_get_child (GOO_CANVAS_CONTAINER (item), i);
 	  goo_canvas_focus_recurse (canvas, child, data);
 	}
     }
@@ -4194,7 +4215,7 @@ goo_canvas_remove (GtkContainer *contain
   GooCanvas *canvas;
   GList *tmp_list;
   GooCanvasWidget *witem;
-  GooCanvasItem *parent;
+  GooCanvasContainer *parent;
   gint child_num;
   
   g_return_if_fail (GOO_IS_CANVAS (container));
@@ -4210,9 +4231,9 @@ goo_canvas_remove (GtkContainer *contain
       if (witem->widget == widget)
 	{
 	  parent = goo_canvas_item_get_parent ((GooCanvasItem*) witem);
-	  child_num = goo_canvas_item_find_child (parent,
-						  (GooCanvasItem*) witem);
-	  goo_canvas_item_remove_child (parent, child_num);
+	  child_num = goo_canvas_container_find_child (parent,
+						       (GooCanvasItem*) witem);
+	  goo_canvas_container_remove_child (parent, child_num);
 
 	  break;
 	}
Index: src/goocanvasitemmodel.c
===================================================================
--- src/goocanvasitemmodel.c	(revision 27)
+++ src/goocanvasitemmodel.c	(working copy)
@@ -22,18 +22,13 @@
 #include "goocanvasprivate.h"
 #include <goocanvasenumtypes.h>
 #include "goocanvasitemmodel.h"
+#include "goocanvascontainermodel.h"
 #include "goocanvasutils.h"
 #include "goocanvasmarshal.h"
 
-
-static GParamSpecPool       *_goo_canvas_item_model_child_property_pool = NULL;
-static GObjectNotifyContext *_goo_canvas_item_model_child_property_notify_context = NULL;
 static const char *animation_key = "GooCanvasItemAnimation";
 
 enum {
-  CHILD_ADDED,
-  CHILD_MOVED,
-  CHILD_REMOVED,
   CHANGED,
 
   CHILD_NOTIFY,
@@ -46,13 +41,6 @@ static guint item_model_signals[LAST_SIG
 
 static void goo_canvas_item_model_base_init (gpointer g_class);
 extern void _goo_canvas_style_init (void);
-extern void _goo_canvas_item_get_child_property_internal (GObject              *object,
-							  GObject              *child,
-							  const gchar          *property_name,
-							  GValue               *value,
-							  GParamSpecPool       *property_pool,
-							  gboolean              is_model);
-
 
 GType
 goo_canvas_item_model_get_type (void)
@@ -78,89 +66,15 @@ goo_canvas_item_model_get_type (void)
   return item_model_type;
 }
 
-
-
-static void
-child_property_notify_dispatcher (GObject     *object,
-				  guint        n_pspecs,
-				  GParamSpec **pspecs)
-{
-  guint i;
-
-  for (i = 0; i < n_pspecs; i++)
-    g_signal_emit (object, item_model_signals[CHILD_NOTIFY],
-		   g_quark_from_string (pspecs[i]->name), pspecs[i]);
-}
-
-
 static void
 goo_canvas_item_model_base_init (gpointer g_iface)
 {
-  static GObjectNotifyContext cpn_context = { 0, NULL, NULL };
   static gboolean initialized = FALSE;
   
   if (!initialized)
     {
       GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
 
-      _goo_canvas_item_model_child_property_pool = g_param_spec_pool_new (TRUE);
-
-      cpn_context.quark_notify_queue = g_quark_from_static_string ("GooCanvasItemModel-child-property-notify-queue");
-      cpn_context.dispatcher = child_property_notify_dispatcher;
-      _goo_canvas_item_model_child_property_notify_context = &cpn_context;
-
-      /**
-       * GooCanvasItemModel::child-added
-       * @model: the item model that received the signal.
-       * @child_num: the index of the new child.
-       *
-       * Emitted when a child has been added.
-       */
-      item_model_signals[CHILD_ADDED] =
-	g_signal_new ("child-added",
-		      iface_type,
-		      G_SIGNAL_RUN_LAST,
-		      G_STRUCT_OFFSET (GooCanvasItemModelIface, child_added),
-		      NULL, NULL,
-		      goo_canvas_marshal_VOID__INT,
-		      G_TYPE_NONE, 1,
-		      G_TYPE_INT);
-
-      /**
-       * GooCanvasItemModel::child-moved
-       * @model: the item model that received the signal.
-       * @old_child_num: the old index of the child.
-       * @new_child_num: the new index of the child.
-       *
-       * Emitted when a child has been moved in the stacking order.
-       */
-      item_model_signals[CHILD_MOVED] =
-	g_signal_new ("child-moved",
-		      iface_type,
-		      G_SIGNAL_RUN_LAST,
-		      G_STRUCT_OFFSET (GooCanvasItemModelIface, child_moved),
-		      NULL, NULL,
-		      goo_canvas_marshal_VOID__INT_INT,
-		      G_TYPE_NONE, 2,
-		      G_TYPE_INT, G_TYPE_INT);
-
-      /**
-       * GooCanvasItemModel::child-removed
-       * @model: the item model that received the signal.
-       * @child_num: the index of the child that was removed.
-       *
-       * Emitted when a child has been removed.
-       */
-      item_model_signals[CHILD_REMOVED] =
-	g_signal_new ("child-removed",
-		      iface_type,
-		      G_SIGNAL_RUN_LAST,
-		      G_STRUCT_OFFSET (GooCanvasItemModelIface, child_removed),
-		      NULL, NULL,
-		      goo_canvas_marshal_VOID__INT,
-		      G_TYPE_NONE, 1,
-		      G_TYPE_INT);
-
       /**
        * GooCanvasItemModel::changed
        * @model: the item model that received the signal.
@@ -218,7 +132,7 @@ goo_canvas_item_model_base_init (gpointe
 					   g_param_spec_object ("parent",
 								_("Parent"),
 								_("The parent item model"),
-								GOO_TYPE_CANVAS_ITEM_MODEL,
+								GOO_TYPE_CANVAS_CONTAINER_MODEL,
 								G_PARAM_READWRITE));
 
       g_object_interface_install_property (g_iface,
@@ -282,151 +196,6 @@ goo_canvas_item_model_base_init (gpointe
 
 
 /**
- * goo_canvas_item_model_add_child:
- * @model: an item model.
- * @child: the child to add.
- * @position: the position of the child, or -1 to place it last (at the top of
- *  the stacking order).
- * 
- * Adds a child at the given stack position.
- **/
-void
-goo_canvas_item_model_add_child      (GooCanvasItemModel  *model,
-				      GooCanvasItemModel  *child,
-				      gint                 position)
-{
-  GooCanvasItemModelIface *iface = GOO_CANVAS_ITEM_MODEL_GET_IFACE (model);
-
-  g_return_if_fail (iface->add_child != NULL);
-  g_return_if_fail (model != child);
-
-  iface->add_child (model, child, position);
-}
-
-
-/**
- * goo_canvas_item_model_move_child:
- * @model: an item model.
- * @old_position: the current position of the child.
- * @new_position: the new position of the child.
- * 
- * Moves a child to a new stack position.
- **/
-void
-goo_canvas_item_model_move_child     (GooCanvasItemModel  *model,
-				      gint                 old_position,
-				      gint                 new_position)
-{
-  GooCanvasItemModelIface *iface = GOO_CANVAS_ITEM_MODEL_GET_IFACE (model);
-
-  g_return_if_fail (iface->move_child != NULL);
-
-  iface->move_child (model, old_position, new_position);
-}
-
-
-/**
- * goo_canvas_item_model_remove_child:
- * @model: an item model.
- * @child_num: the position of the child to remove.
- * 
- * Removes the child at the given position.
- **/
-void
-goo_canvas_item_model_remove_child   (GooCanvasItemModel  *model,
-				      gint                 child_num)
-{
-  GooCanvasItemModelIface *iface = GOO_CANVAS_ITEM_MODEL_GET_IFACE (model);
-
-  g_return_if_fail (iface->remove_child != NULL);
-
-  iface->remove_child (model, child_num);
-}
-
-
-/**
- * goo_canvas_item_model_find_child:
- * @model: an item model.
- * @child: the child to find.
- * 
- * Attempts to find the given child with the container's stack.
- * 
- * Returns: the position of the given @child, or -1 if it isn't found.
- **/
-gint
-goo_canvas_item_model_find_child     (GooCanvasItemModel *model,
-				      GooCanvasItemModel *child)
-{
-  GooCanvasItemModel *item;
-  int n_children, i;
-
-  /* Find the current position of item and above. */
-  n_children = goo_canvas_item_model_get_n_children (model);
-  for (i = 0; i < n_children; i++)
-    {
-      item = goo_canvas_item_model_get_child (model, i);
-      if (child == item)
-	return i;
-    }
-  return -1;
-}
-
-
-/**
- * goo_canvas_item_model_is_container:
- * @model: an item model.
- * 
- * Tests to see if the given item model is a container.
- * 
- * Returns: %TRUE if the item model is a container.
- **/
-gboolean
-goo_canvas_item_model_is_container (GooCanvasItemModel       *model)
-{
-  GooCanvasItemModelIface *iface = GOO_CANVAS_ITEM_MODEL_GET_IFACE (model);
-
-  return iface->get_n_children ? TRUE : FALSE;
-}
-
-
-/**
- * goo_canvas_item_model_get_n_children:
- * @model: an item model.
- * 
- * Gets the number of children of the container.
- * 
- * Returns: the number of children.
- **/
-gint
-goo_canvas_item_model_get_n_children (GooCanvasItemModel       *model)
-{
-  GooCanvasItemModelIface *iface = GOO_CANVAS_ITEM_MODEL_GET_IFACE (model);
-
-  return iface->get_n_children ? iface->get_n_children (model) : 0;
-}
-
-
-/**
- * goo_canvas_item_model_get_child:
- * @model: an item model.
- * @child_num: the position of a child in the container's stack.
- * 
- * Gets the child at the given stack position.
- * 
- * Returns: the child at the given stack position, or %NULL if @child_num
- * is out of range.
- **/
-GooCanvasItemModel*
-goo_canvas_item_model_get_child (GooCanvasItemModel  *model,
-				 gint                 child_num)
-{
-  GooCanvasItemModelIface *iface = GOO_CANVAS_ITEM_MODEL_GET_IFACE (model);
-
-  return iface->get_child ? iface->get_child (model, child_num) : NULL;
-}
-
-
-/**
  * goo_canvas_item_model_get_parent:
  * @model: an item model.
  * 
@@ -434,7 +203,7 @@ goo_canvas_item_model_get_child (GooCanv
  * 
  * Returns: the parent model, or %NULL if the model has no parent.
  **/
-GooCanvasItemModel*
+GooCanvasContainerModel*
 goo_canvas_item_model_get_parent  (GooCanvasItemModel *model)
 {
   return GOO_CANVAS_ITEM_MODEL_GET_IFACE (model)->get_parent (model);
@@ -458,7 +227,7 @@ goo_canvas_item_model_get_parent  (GooCa
  **/
 void
 goo_canvas_item_model_set_parent (GooCanvasItemModel *model,
-				  GooCanvasItemModel *parent)
+				  GooCanvasContainerModel *parent)
 {
   GOO_CANVAS_ITEM_MODEL_GET_IFACE (model)->set_parent (model, parent);
 }
@@ -476,18 +245,18 @@ goo_canvas_item_model_set_parent (GooCan
 void
 goo_canvas_item_model_remove         (GooCanvasItemModel *model)
 {
-  GooCanvasItemModel *parent;
+  GooCanvasContainerModel *parent;
   gint child_num;
 
   parent = goo_canvas_item_model_get_parent (model);
   if (!parent)
     return;
 
-  child_num = goo_canvas_item_model_find_child (parent, model);
+  child_num = goo_canvas_container_model_find_child (parent, model);
   if (child_num == -1)
     return;
 
-  goo_canvas_item_model_remove_child (parent, child_num);
+  goo_canvas_container_model_remove_child (parent, child_num);
 }
 
 
@@ -503,7 +272,8 @@ void
 goo_canvas_item_model_raise          (GooCanvasItemModel *model,
 				      GooCanvasItemModel *above)
 {
-  GooCanvasItemModel *parent, *child;
+  GooCanvasContainerModel *parent;
+  GooCanvasItemModel      *child;
   int n_children, i, model_pos = -1, above_pos = -1;
 
   parent = goo_canvas_item_model_get_parent (model);
@@ -511,10 +281,10 @@ goo_canvas_item_model_raise          (Go
     return;
 
   /* Find the current position of model and above. */
-  n_children = goo_canvas_item_model_get_n_children (parent);
+  n_children = goo_canvas_container_model_get_n_children (parent);
   for (i = 0; i < n_children; i++)
     {
-      child = goo_canvas_item_model_get_child (parent, i);
+      child = goo_canvas_container_model_get_child (parent, i);
       if (child == model)
 	model_pos = i;
       if (child == above)
@@ -530,7 +300,7 @@ goo_canvas_item_model_raise          (Go
 
   /* Only move the model if the new position is higher in the stack. */
   if (above_pos > model_pos)
-    goo_canvas_item_model_move_child (parent, model_pos, above_pos);
+    goo_canvas_container_model_move_child (parent, model_pos, above_pos);
 }
 
 
@@ -546,7 +316,8 @@ void
 goo_canvas_item_model_lower          (GooCanvasItemModel *model,
 				      GooCanvasItemModel *below)
 {
-  GooCanvasItemModel *parent, *child;
+  GooCanvasContainerModel *parent;
+  GooCanvasItemModel      *child;
   int n_children, i, model_pos = -1, below_pos = -1;
 
   parent = goo_canvas_item_model_get_parent (model);
@@ -554,10 +325,10 @@ goo_canvas_item_model_lower          (Go
     return;
 
   /* Find the current position of model and below. */
-  n_children = goo_canvas_item_model_get_n_children (parent);
+  n_children = goo_canvas_container_model_get_n_children (parent);
   for (i = 0; i < n_children; i++)
     {
-      child = goo_canvas_item_model_get_child (parent, i);
+      child = goo_canvas_container_model_get_child (parent, i);
       if (child == model)
 	model_pos = i;
       if (child == below)
@@ -573,7 +344,7 @@ goo_canvas_item_model_lower          (Go
 
   /* Only move the model if the new position is lower in the stack. */
   if (below_pos < model_pos)
-    goo_canvas_item_model_move_child (parent, model_pos, below_pos);
+    goo_canvas_container_model_move_child (parent, model_pos, below_pos);
 }
 
 
@@ -923,253 +694,9 @@ goo_canvas_item_model_stop_animation (Go
   g_object_set_data (G_OBJECT (model), animation_key, NULL);
 }
 
-
-
-/*
- * Child Properties.
- */
-extern void _goo_canvas_item_set_child_property_internal (GObject *object, GObject *child, const gchar *property_name, const GValue *value, GParamSpecPool *property_pool, GObjectNotifyContext *notify_context, gboolean is_model);
-
-extern void _goo_canvas_item_get_child_properties_internal (GObject *object, GObject *child, va_list var_args, GParamSpecPool *property_pool, GObjectNotifyContext *notify_context, gboolean is_model);
-
-extern void _goo_canvas_item_set_child_properties_internal (GObject *object, GObject *child, va_list var_args, GParamSpecPool *property_pool, GObjectNotifyContext *notify_context, gboolean is_model);
-
-
-/**
- * goo_canvas_item_model_get_child_property:
- * @model: a #GooCanvasItemModel.
- * @child: a child #GooCanvasItemModel.
- * @property_name: the name of the child property to get.
- * @value: a location to return the value.
- * 
- * Gets a child property of @child.
- **/
-void
-goo_canvas_item_model_get_child_property (GooCanvasItemModel *model,
-					  GooCanvasItemModel *child,
-					  const gchar        *property_name,
-					  GValue             *value)
-{
-  g_return_if_fail (GOO_IS_CANVAS_ITEM_MODEL (model));
-  g_return_if_fail (GOO_IS_CANVAS_ITEM_MODEL (child));
-  g_return_if_fail (property_name != NULL);
-  g_return_if_fail (G_IS_VALUE (value));
-
-  _goo_canvas_item_get_child_property_internal ((GObject*) model, (GObject*) child, property_name, value, _goo_canvas_item_model_child_property_pool, TRUE);
-}
-
-
-/**
- * goo_canvas_item_model_set_child_property:
- * @model: a #GooCanvasItemModel.
- * @child: a child #GooCanvasItemModel.
- * @property_name: the name of the child property to set.
- * @value: the value to set the property to.
- * 
- * Sets a child property of @child.
- **/
-void
-goo_canvas_item_model_set_child_property (GooCanvasItemModel *model,
-					  GooCanvasItemModel *child,
-					  const gchar        *property_name,
-					  const GValue       *value)
-{
-  g_return_if_fail (GOO_IS_CANVAS_ITEM_MODEL (model));
-  g_return_if_fail (GOO_IS_CANVAS_ITEM_MODEL (child));
-  g_return_if_fail (property_name != NULL);
-  g_return_if_fail (G_IS_VALUE (value));
-
-  _goo_canvas_item_set_child_property_internal ((GObject*) model, (GObject*) child, property_name, value, _goo_canvas_item_model_child_property_pool, _goo_canvas_item_model_child_property_notify_context, TRUE);
-}
-
-
-/**
- * goo_canvas_item_model_get_child_properties_valist:
- * @model: a #GooCanvasItemModel.
- * @child: a child #GooCanvasItemModel.
- * @var_args: pairs of property names and value pointers, and a terminating
- *  %NULL.
- * 
- * Gets the values of one or more child properties of @child.
- **/
-void
-goo_canvas_item_model_get_child_properties_valist (GooCanvasItemModel *model,
-						   GooCanvasItemModel *child,
-						   va_list	       var_args)
-{
-  g_return_if_fail (GOO_IS_CANVAS_ITEM_MODEL (model));
-  g_return_if_fail (GOO_IS_CANVAS_ITEM_MODEL (child));
-
-  _goo_canvas_item_get_child_properties_internal ((GObject*) model, (GObject*) child, var_args, _goo_canvas_item_model_child_property_pool, _goo_canvas_item_model_child_property_notify_context, TRUE);
-}
-
-
-/**
- * goo_canvas_item_model_set_child_properties_valist:
- * @model: a #GooCanvasItemModel.
- * @child: a child #GooCanvasItemModel.
- * @var_args: pairs of property names and values, and a terminating %NULL.
- * 
- * Sets the values of one or more child properties of @child.
- **/
-void
-goo_canvas_item_model_set_child_properties_valist (GooCanvasItemModel *model,
-						   GooCanvasItemModel *child,
-						   va_list	       var_args)
-{
-  g_return_if_fail (GOO_IS_CANVAS_ITEM_MODEL (model));
-  g_return_if_fail (GOO_IS_CANVAS_ITEM_MODEL (child));
-
-  _goo_canvas_item_set_child_properties_internal ((GObject*) model, (GObject*) child, var_args, _goo_canvas_item_model_child_property_pool, _goo_canvas_item_model_child_property_notify_context, TRUE);
-}
-
-
-/**
- * goo_canvas_item_model_get_child_properties:
- * @model: a #GooCanvasItemModel.
- * @child: a child #GooCanvasItemModel.
- * @...: pairs of property names and value pointers, and a terminating %NULL.
- * 
- * Gets the values of one or more child properties of @child.
- **/
-void
-goo_canvas_item_model_get_child_properties  (GooCanvasItemModel   *model,
-					     GooCanvasItemModel   *child,
-					     ...)
-{
-  va_list var_args;
-  
-  va_start (var_args, child);
-  goo_canvas_item_model_get_child_properties_valist (model, child, var_args);
-  va_end (var_args);
-}
-
-
-/**
- * goo_canvas_item_model_set_child_properties:
- * @model: a #GooCanvasItemModel.
- * @child: a child #GooCanvasItemModel.
- * @...: pairs of property names and values, and a terminating %NULL.
- * 
- * Sets the values of one or more child properties of @child.
- **/
-void
-goo_canvas_item_model_set_child_properties  (GooCanvasItemModel   *model,
-					     GooCanvasItemModel   *child,
-					     ...)
-{
-  va_list var_args;
-  
-  va_start (var_args, child);
-  goo_canvas_item_model_set_child_properties_valist (model, child, var_args);
-  va_end (var_args);
-}
-
-
-
-/**
- * goo_canvas_item_model_class_install_child_property:
- * @mclass: a #GObjectClass
- * @property_id: the id for the property
- * @pspec: the #GParamSpec for the property
- * 
- * This function is only intended to be used when implementing new canvas
- * item models, specifically layout container item models such as
- * #GooCanvasTableModel.
- *
- * It installs a child property on a canvas item class. 
- **/
-void
-goo_canvas_item_model_class_install_child_property (GObjectClass *mclass,
-						    guint         property_id,
-						    GParamSpec   *pspec)
-{
-  g_return_if_fail (G_IS_OBJECT_CLASS (mclass));
-  g_return_if_fail (G_IS_PARAM_SPEC (pspec));
-  g_return_if_fail (property_id > 0);
-
-  if (g_param_spec_pool_lookup (_goo_canvas_item_model_child_property_pool,
-				pspec->name, G_OBJECT_CLASS_TYPE (mclass),
-				FALSE))
-    {
-      g_warning (G_STRLOC ": class `%s' already contains a child property named `%s'",
-		 G_OBJECT_CLASS_NAME (mclass), pspec->name);
-      return;
-    }
-  g_param_spec_ref (pspec);
-  g_param_spec_sink (pspec);
-  pspec->param_id = property_id;
-  g_param_spec_pool_insert (_goo_canvas_item_model_child_property_pool, pspec,
-			    G_OBJECT_CLASS_TYPE (mclass));
-}
-
-/**
- * goo_canvas_item_model_class_find_child_property:
- * @mclass: a #GObjectClass
- * @property_name: the name of the child property to find
- * @returns: the #GParamSpec of the child property or %NULL if @class has no
- *   child property with that name.
- *
- * This function is only intended to be used when implementing new canvas
- * item models, specifically layout container item models such as
- * #GooCanvasTableModel.
- *
- * It finds a child property of a canvas item class by name.
- */
-GParamSpec*
-goo_canvas_item_model_class_find_child_property (GObjectClass *mclass,
-						 const gchar  *property_name)
-{
-  g_return_val_if_fail (G_IS_OBJECT_CLASS (mclass), NULL);
-  g_return_val_if_fail (property_name != NULL, NULL);
-
-  return g_param_spec_pool_lookup (_goo_canvas_item_model_child_property_pool,
-				   property_name, G_OBJECT_CLASS_TYPE (mclass),
-				   TRUE);
-}
-
-/**
- * goo_canvas_item_model_class_list_child_properties:
- * @mclass: a #GObjectClass
- * @n_properties: location to return the number of child properties found
- * @returns: a newly allocated array of #GParamSpec*. The array must be 
- *           freed with g_free().
- *
- * This function is only intended to be used when implementing new canvas
- * item models, specifically layout container item models such as
- * #GooCanvasTableModel.
- *
- * It returns all child properties of a canvas item class.
- */
-GParamSpec**
-goo_canvas_item_model_class_list_child_properties (GObjectClass *mclass,
-						   guint        *n_properties)
-{
-  GParamSpec **pspecs;
-  guint n;
-
-  g_return_val_if_fail (G_IS_OBJECT_CLASS (mclass), NULL);
-
-  pspecs = g_param_spec_pool_list (_goo_canvas_item_model_child_property_pool,
-				   G_OBJECT_CLASS_TYPE (mclass), &n);
-  if (n_properties)
-    *n_properties = n;
-
-  return pspecs;
-}
-
-
-void
-_goo_canvas_item_model_emit_child_added (GooCanvasItemModel *model,
-					 gint                position)
-{
-  g_signal_emit (model, item_model_signals[CHILD_ADDED], 0, position);
-}
-
-
 void
-_goo_canvas_item_model_emit_changed (GooCanvasItemModel *model,
-				     gboolean            recompute_bounds)
+_goo_canvas_item_model_emit_changed (GooCanvasItemModel      *model,
+		 	             gboolean                 recompute_bounds)
 {
   g_signal_emit (model, item_model_signals[CHANGED], 0, recompute_bounds);
 }
Index: src/goocanvascontainer.c
===================================================================
--- src/goocanvascontainer.c	(revision 0)
+++ src/goocanvascontainer.c	(revision 0)
@@ -0,0 +1,772 @@
+/*
+ * GooCanvas. Copyright (C) 2005 Damon Chaplin.
+ * Released under the GNU LGPL license. See COPYING for details.
+ *
+ * goocanvascontainer.c - interface for canvas containers.
+ */
+
+/**
+ * SECTION:goocanvascontainer
+ * @Title: GooCanvasContainer
+ * @Short_Description: the interface for canvas containers.
+ *
+ * #GooCanvasContainer defines the interface that canvas containers must implement,
+ * and contains methods for operating on canvas containers.
+ */
+#include <config.h>
+#include <glib/gi18n-lib.h>
+#include <gobject/gobjectnotifyqueue.c>
+#include <gobject/gvaluecollector.h>
+#include <gtk/gtk.h>
+#include "goocanvasprivate.h"
+#include "goocanvascontainer.h"
+#include "goocanvascontainermodel.h"
+#include "goocanvasmarshal.h"
+
+static GParamSpecPool       *_goo_canvas_container_child_property_pool = NULL;
+static GObjectNotifyContext *_goo_canvas_container_child_property_notify_context = NULL;
+
+static guint canvas_container_child_notify_signal = 0;
+
+static void goo_canvas_container_base_init (gpointer g_class);
+
+GType
+goo_canvas_container_get_type (void)
+{
+  static GType canvas_container_type = 0;
+
+  if (!canvas_container_type)
+    {
+      static const GTypeInfo canvas_container_info =
+      {
+        sizeof (GooCanvasContainerIface), /* class_size */
+	goo_canvas_container_base_init,   /* base_init */
+	NULL,			          /* base_finalize */
+      };
+
+      canvas_container_type = g_type_register_static (G_TYPE_INTERFACE,
+						      "GooCanvasContainer",
+						      &canvas_container_info, 0);
+
+      g_type_interface_add_prerequisite (canvas_container_type, G_TYPE_OBJECT);
+      g_type_interface_add_prerequisite (canvas_container_type, GOO_TYPE_CANVAS_ITEM);
+    }
+
+  return canvas_container_type;
+}
+
+static void
+child_property_notify_dispatcher (GObject     *object,
+				  guint        n_pspecs,
+				  GParamSpec **pspecs)
+{
+  guint i;
+
+  for (i = 0; i < n_pspecs; i++)
+    g_signal_emit (object, canvas_container_child_notify_signal,
+		   g_quark_from_string (pspecs[i]->name), pspecs[i]);
+}
+
+static void
+goo_canvas_container_base_init (gpointer g_iface)
+{
+  static GObjectNotifyContext cpn_context = { 0, NULL, NULL };
+  static gboolean initialized = FALSE;
+  
+  if (!initialized)
+    {
+      canvas_container_child_notify_signal = g_signal_lookup ("child-notify", GOO_TYPE_CANVAS_ITEM);
+
+      _goo_canvas_container_child_property_pool = g_param_spec_pool_new (TRUE);
+
+      cpn_context.quark_notify_queue = g_quark_from_static_string ("GooCanvasContainer-child-property-notify-queue");
+      cpn_context.dispatcher = child_property_notify_dispatcher;
+      _goo_canvas_container_child_property_notify_context = &cpn_context;
+
+      initialized = TRUE;
+    }
+}
+
+
+/**
+ * goo_canvas_container_add_child:
+ * @container: the container to add the child to.
+ * @child: the item to add.
+ * @position: the position of the item, or -1 to place it last (at the top of
+ *  the stacking order).
+ * 
+ * Adds a child item to a container at the given stack position.
+ **/
+void
+goo_canvas_container_add_child      (GooCanvasContainer       *container,
+				     GooCanvasItem            *child,
+				     gint                      position)
+{
+  GooCanvasContainerIface *iface = GOO_CANVAS_CONTAINER_GET_IFACE (container);
+
+  g_return_if_fail (iface->add_child != NULL);
+  g_return_if_fail (GOO_CANVAS_ITEM (container) != child);
+
+  iface->add_child (container, child, position);
+}
+
+
+/**
+ * goo_canvas_container_move_child:
+ * @container: a container item.
+ * @old_position: the current position of the child item.
+ * @new_position: the new position of the child item.
+ * 
+ * Moves a child item to a new stack position within the container.
+ **/
+void
+goo_canvas_container_move_child     (GooCanvasContainer       *container,
+				     gint                      old_position,
+				     gint                      new_position)
+{
+  GooCanvasContainerIface *iface = GOO_CANVAS_CONTAINER_GET_IFACE (container);
+
+  g_return_if_fail (iface->move_child != NULL);
+
+  iface->move_child (container, old_position, new_position);
+}
+
+
+/**
+ * goo_canvas_container_remove_child:
+ * @container: a container item.
+ * @child_num: the position of the child item to remove.
+ * 
+ * Removes the child item at the given position.
+ **/
+void
+goo_canvas_container_remove_child   (GooCanvasContainer       *container,
+			             gint                      child_num)
+{
+  GooCanvasContainerIface *iface = GOO_CANVAS_CONTAINER_GET_IFACE (container);
+
+  g_return_if_fail (iface->remove_child != NULL);
+
+  iface->remove_child (container, child_num);
+}
+
+
+/**
+ * goo_canvas_container_find_child:
+ * @container: a container item.
+ * @child: the child item to find.
+ * 
+ * Attempts to find the given child item with the container's stack.
+ * 
+ * Returns: the position of the given @child item, or -1 if it isn't found.
+ **/
+gint
+goo_canvas_container_find_child     (GooCanvasContainer *container,
+				     GooCanvasItem      *child)
+{
+  GooCanvasItem *tmp;
+  int n_children, i;
+
+  /* Find the current position of container and above. */
+  n_children = goo_canvas_container_get_n_children (container);
+  for (i = 0; i < n_children; i++)
+    {
+      tmp = goo_canvas_container_get_child (container, i);
+      if (child == tmp)
+	return i;
+    }
+  return -1;
+}
+
+/**
+ * goo_canvas_container_get_n_children:
+ * @container: a container item.
+ * 
+ * Gets the number of children of the container.
+ * 
+ * Returns: the number of children.
+ **/
+gint
+goo_canvas_container_get_n_children (GooCanvasContainer       *container)
+{
+  GooCanvasContainerIface *iface = GOO_CANVAS_CONTAINER_GET_IFACE (container);
+
+  return iface->get_n_children ? iface->get_n_children (container) : 0;
+}
+
+
+/**
+ * goo_canvas_container_get_child:
+ * @container: a container item.
+ * @child_num: the position of a child in the container's stack.
+ * 
+ * Gets the child item at the given stack position.
+ * 
+ * Returns: the child item at the given stack position, or %NULL if @child_num
+ * is out of range.
+ **/
+GooCanvasItem*
+goo_canvas_container_get_child (GooCanvasContainer       *container,
+			        gint                      child_num)
+{
+  GooCanvasContainerIface *iface = GOO_CANVAS_CONTAINER_GET_IFACE (container);
+
+  return iface->get_child ? iface->get_child (container, child_num) : NULL;
+}
+
+/**
+ * goo_canvas_container_get_transform_for_child:
+ * @container: a container.
+ * @child: a child of @container.
+ * @transform: the place to store the transform.
+ * 
+ * Gets the transformation matrix of a container combined with any special
+ * transform needed for the given child. These special transforms are used
+ * by layout containers such as #GooCanvasTable.
+ * 
+ * Returns: %TRUE if a transform is set.
+ **/
+gboolean
+goo_canvas_container_get_transform_for_child  (GooCanvasContainer  *container,
+					       GooCanvasItem       *child,
+					       cairo_matrix_t      *transform)
+{
+  GooCanvasContainerIface *iface = GOO_CANVAS_CONTAINER_GET_IFACE (container);
+  GooCanvasItemIface *item_iface = GOO_CANVAS_ITEM_GET_IFACE (container);
+
+  if (child && iface->get_transform_for_child)
+    return iface->get_transform_for_child (container, child, transform);
+
+  /* We fallback to the standard get_transform method. */
+  if (item_iface->get_transform)
+    return item_iface->get_transform (GOO_CANVAS_ITEM (container), transform);
+
+  return FALSE;
+}
+
+/*
+ * Child Properties.
+ */
+static inline void
+container_get_child_property (GObject      *object,
+			      GObject      *child,
+			      GParamSpec   *pspec,
+			      GValue       *value,
+			      gboolean      is_model)
+{
+  GObjectClass *class;
+
+  class = g_type_class_peek (pspec->owner_type);
+  if (is_model)
+    {
+      GooCanvasContainerModelIface *iface;
+
+      iface = g_type_interface_peek (class, GOO_TYPE_CANVAS_CONTAINER_MODEL);
+      iface->get_child_property ((GooCanvasContainerModel*) object,
+				 (GooCanvasItemModel*) child,
+				 pspec->param_id, value, pspec);
+    }
+  else
+    {
+      GooCanvasContainerIface *iface;
+
+      iface = g_type_interface_peek (class, GOO_TYPE_CANVAS_CONTAINER);
+      iface->get_child_property ((GooCanvasContainer*) object,
+				 (GooCanvasItem*) child,
+				 pspec->param_id, value, pspec);
+    }
+}
+
+
+void
+_goo_canvas_container_get_child_property_internal (GObject              *object,
+					           GObject              *child,
+					           const gchar          *property_name,
+					           GValue               *value,
+					           GParamSpecPool       *property_pool,
+					           gboolean              is_model)
+{
+  GParamSpec *pspec;
+
+  g_object_ref (object);
+  g_object_ref (child);
+  pspec = g_param_spec_pool_lookup (property_pool, property_name,
+				    G_OBJECT_TYPE (object), TRUE);
+  if (!pspec)
+    g_warning ("%s: class `%s' has no child property named `%s'",
+	       G_STRLOC,
+	       G_OBJECT_TYPE_NAME (object),
+	       property_name);
+  else if (!(pspec->flags & G_PARAM_READABLE))
+    g_warning ("%s: child property `%s' of class `%s' is not readable",
+	       G_STRLOC,
+	       pspec->name,
+	       G_OBJECT_TYPE_NAME (object));
+  else
+    {
+      GValue *prop_value, tmp_value = { 0, };
+
+      /* auto-conversion of the callers value type
+       */
+      if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
+	{
+	  g_value_reset (value);
+	  prop_value = value;
+	}
+      else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
+	{
+	  g_warning ("can't retrieve child property `%s' of type `%s' as value of type `%s'",
+		     pspec->name,
+		     g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
+		     G_VALUE_TYPE_NAME (value));
+	  g_object_unref (child);
+	  g_object_unref (object);
+	  return;
+	}
+      else
+	{
+	  g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+	  prop_value = &tmp_value;
+	}
+      container_get_child_property (object, child, pspec, prop_value, is_model);
+      if (prop_value != value)
+	{
+	  g_value_transform (prop_value, value);
+	  g_value_unset (&tmp_value);
+	}
+    }
+  g_object_unref (child);
+  g_object_unref (object);
+}
+
+
+void
+_goo_canvas_container_get_child_properties_internal (GObject              *object,
+						     GObject              *child,
+						     va_list	           var_args,
+						     GParamSpecPool       *property_pool,
+						     GObjectNotifyContext *notify_context,
+						     gboolean              is_model)
+{
+  g_object_ref (object);
+  g_object_ref (child);
+
+  for (;;)
+    {
+      GValue value = { 0, };
+      GParamSpec *pspec;
+      gchar *name, *error = NULL;
+
+      name = va_arg (var_args, gchar*);
+      if (!name)
+	break;
+
+      pspec = g_param_spec_pool_lookup (property_pool, name,
+					G_OBJECT_TYPE (object), TRUE);
+      if (!pspec)
+	{
+	  g_warning ("%s: class `%s' has no child property named `%s'",
+		     G_STRLOC, G_OBJECT_TYPE_NAME (object), name);
+	  break;
+	}
+      if (!(pspec->flags & G_PARAM_READABLE))
+	{
+	  g_warning ("%s: child property `%s' of class `%s' is not readable",
+		     G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (object));
+	  break;
+	}
+      g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+      container_get_child_property (object, child, pspec, &value, is_model);
+      G_VALUE_LCOPY (&value, var_args, 0, &error);
+      if (error)
+	{
+	  g_warning ("%s: %s", G_STRLOC, error);
+	  g_free (error);
+	  g_value_unset (&value);
+	  break;
+	}
+      g_value_unset (&value);
+    }
+
+  g_object_unref (child);
+  g_object_unref (object);
+}
+
+
+static inline void
+canvas_container_set_child_property (GObject            *object,
+				     GObject            *child,
+				     GParamSpec         *pspec,
+				     const GValue       *value,
+				     GObjectNotifyQueue *nqueue,
+				     gboolean            is_model)
+{
+  GValue tmp_value = { 0, };
+
+  /* provide a copy to work from, convert (if necessary) and validate */
+  g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+  if (!g_value_transform (value, &tmp_value))
+    g_warning ("unable to set child property `%s' of type `%s' from value of type `%s'",
+	       pspec->name,
+	       g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
+	       G_VALUE_TYPE_NAME (value));
+  else if (g_param_value_validate (pspec, &tmp_value) && !(pspec->flags & G_PARAM_LAX_VALIDATION))
+    {
+      gchar *contents = g_strdup_value_contents (value);
+
+      g_warning ("value \"%s\" of type `%s' is invalid for property `%s' of type `%s'",
+		 contents,
+		 G_VALUE_TYPE_NAME (value),
+		 pspec->name,
+		 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
+      g_free (contents);
+    }
+  else
+    {
+      GObjectClass *class = g_type_class_peek (pspec->owner_type);
+
+      if (is_model)
+	{
+	  GooCanvasContainerModelIface *iface;
+
+	  iface = g_type_interface_peek (class, GOO_TYPE_CANVAS_CONTAINER_MODEL);
+	  iface->set_child_property ((GooCanvasContainerModel*) object,
+				     (GooCanvasItemModel*) child,
+				     pspec->param_id, &tmp_value, pspec);
+	}
+      else
+	{
+	  GooCanvasContainerIface *iface;
+
+	  iface = g_type_interface_peek (class, GOO_TYPE_CANVAS_CONTAINER);
+	  iface->set_child_property ((GooCanvasContainer*) object,
+				     (GooCanvasItem*) child,
+				     pspec->param_id, &tmp_value, pspec);
+	}
+
+      g_object_notify_queue_add (G_OBJECT (child), nqueue, pspec);
+    }
+  g_value_unset (&tmp_value);
+}
+
+
+void
+_goo_canvas_container_set_child_property_internal (GObject              *object,
+					           GObject              *child,
+					           const gchar          *property_name,
+					           const GValue         *value,
+					           GParamSpecPool       *property_pool,
+					           GObjectNotifyContext *notify_context,
+					           gboolean              is_model)
+{
+  GObjectNotifyQueue *nqueue;
+  GParamSpec *pspec;
+
+  g_object_ref (object);
+  g_object_ref (child);
+
+  nqueue = g_object_notify_queue_freeze (child, notify_context);
+  pspec = g_param_spec_pool_lookup (property_pool, property_name,
+				    G_OBJECT_TYPE (object), TRUE);
+  if (!pspec)
+    g_warning ("%s: class `%s' has no child property named `%s'",
+	       G_STRLOC,
+	       G_OBJECT_TYPE_NAME (object),
+	       property_name);
+  else if (!(pspec->flags & G_PARAM_WRITABLE))
+    g_warning ("%s: child property `%s' of class `%s' is not writable",
+	       G_STRLOC,
+	       pspec->name,
+	       G_OBJECT_TYPE_NAME (object));
+  else
+    {
+      canvas_container_set_child_property (object, child, pspec,
+				      value, nqueue, is_model);
+    }
+  g_object_notify_queue_thaw (child, nqueue);
+  g_object_unref (object);
+  g_object_unref (child);
+}
+
+
+void
+_goo_canvas_container_set_child_properties_internal (GObject              *object,
+						     GObject              *child,
+						     va_list	           var_args,
+						     GParamSpecPool       *property_pool,
+						     GObjectNotifyContext *notify_context,
+						     gboolean              is_model)
+{
+  GObjectNotifyQueue *nqueue;
+
+  g_object_ref (object);
+  g_object_ref (child);
+
+  nqueue = g_object_notify_queue_freeze (child, notify_context);
+
+  for (;;)
+    {
+      GValue value = { 0, };
+      GParamSpec *pspec;
+      gchar *name, *error = NULL;
+
+      name = va_arg (var_args, gchar*);
+      if (!name)
+	break;
+
+      pspec = g_param_spec_pool_lookup (property_pool, name,
+					G_OBJECT_TYPE (object), TRUE);
+      if (!pspec)
+	{
+	  g_warning ("%s: class `%s' has no child property named `%s'",
+		     G_STRLOC, G_OBJECT_TYPE_NAME (object), name);
+	  break;
+	}
+      if (!(pspec->flags & G_PARAM_WRITABLE))
+	{
+	  g_warning ("%s: child property `%s' of class `%s' is not writable",
+		     G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (object));
+	  break;
+	}
+      g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+      G_VALUE_COLLECT (&value, var_args, 0, &error);
+      if (error)
+	{
+	  g_warning ("%s: %s", G_STRLOC, error);
+	  g_free (error);
+
+	  /* we purposely leak the value here, it might not be
+	   * in a sane state if an error condition occoured
+	   */
+	  break;
+	}
+      canvas_container_set_child_property (object, child, pspec, &value, nqueue,
+				      is_model);
+      g_value_unset (&value);
+    }
+  g_object_notify_queue_thaw (G_OBJECT (child), nqueue);
+
+  g_object_unref (object);
+  g_object_unref (child);
+}
+
+
+/**
+ * goo_canvas_container_get_child_property:
+ * @container: a #GooCanvasContainer.
+ * @child: a child #GooCanvasItem.
+ * @property_name: the name of the child property to get.
+ * @value: a location to return the value.
+ * 
+ * Gets a child property of @child.
+ **/
+void
+goo_canvas_container_get_child_property (GooCanvasContainer *container,
+				         GooCanvasItem      *child,
+				         const gchar        *property_name,
+				         GValue             *value)
+{
+  g_return_if_fail (GOO_IS_CANVAS_CONTAINER (container));
+  g_return_if_fail (GOO_IS_CANVAS_ITEM (child));
+  g_return_if_fail (property_name != NULL);
+  g_return_if_fail (G_IS_VALUE (value));
+
+  _goo_canvas_container_get_child_property_internal ((GObject*) container, (GObject*) child, property_name, value, _goo_canvas_container_child_property_pool, FALSE);
+}
+
+
+/**
+ * goo_canvas_container_set_child_property:
+ * @container: a #GooCanvasContainer.
+ * @child: a child #GooCanvasItem.
+ * @property_name: the name of the child property to set.
+ * @value: the value to set the property to.
+ * 
+ * Sets a child property of @child.
+ **/
+void
+goo_canvas_container_set_child_property (GooCanvasContainer   *container,
+				         GooCanvasItem        *child,
+				         const gchar          *property_name,
+				         const GValue         *value)
+{
+  g_return_if_fail (GOO_IS_CANVAS_CONTAINER (container));
+  g_return_if_fail (GOO_IS_CANVAS_ITEM (child));
+  g_return_if_fail (property_name != NULL);
+  g_return_if_fail (G_IS_VALUE (value));
+
+  _goo_canvas_container_set_child_property_internal ((GObject*) container, (GObject*) child, property_name, value, _goo_canvas_container_child_property_pool, _goo_canvas_container_child_property_notify_context, FALSE);
+}
+
+
+/**
+ * goo_canvas_container_get_child_properties_valist:
+ * @container: a #GooCanvasContainer.
+ * @child: a child #GooCanvasItem.
+ * @var_args: pairs of property names and value pointers, and a terminating
+ *  %NULL.
+ * 
+ * Gets the values of one or more child properties of @child.
+ **/
+void
+goo_canvas_container_get_child_properties_valist (GooCanvasContainer   *container,
+					          GooCanvasItem        *child,
+					          va_list	        var_args)
+{
+  g_return_if_fail (GOO_IS_CANVAS_CONTAINER (container));
+  g_return_if_fail (GOO_IS_CANVAS_ITEM (child));
+
+  _goo_canvas_container_get_child_properties_internal ((GObject*) container, (GObject*) child, var_args, _goo_canvas_container_child_property_pool, _goo_canvas_container_child_property_notify_context, FALSE);
+}
+
+
+/**
+ * goo_canvas_container_set_child_properties_valist:
+ * @container: a #GooCanvasContainer.
+ * @child: a child #GooCanvasItem.
+ * @var_args: pairs of property names and values, and a terminating %NULL.
+ * 
+ * Sets the values of one or more child properties of @child.
+ **/
+void
+goo_canvas_container_set_child_properties_valist (GooCanvasContainer   *container,
+					          GooCanvasItem        *child,
+					          va_list	        var_args)
+{
+  g_return_if_fail (GOO_IS_CANVAS_CONTAINER (container));
+  g_return_if_fail (GOO_IS_CANVAS_ITEM (child));
+
+  _goo_canvas_container_set_child_properties_internal ((GObject*) container, (GObject*) child, var_args, _goo_canvas_container_child_property_pool, _goo_canvas_container_child_property_notify_context, FALSE);
+}
+
+
+/**
+ * goo_canvas_container_get_child_properties:
+ * @container: a #GooCanvasContainer.
+ * @child: a child #GooCanvasItem.
+ * @...: pairs of property names and value pointers, and a terminating %NULL.
+ * 
+ * Gets the values of one or more child properties of @child.
+ **/
+void
+goo_canvas_container_get_child_properties   (GooCanvasContainer   *container,
+					     GooCanvasItem        *child,
+					     ...)
+{
+  va_list var_args;
+  
+  va_start (var_args, child);
+  goo_canvas_container_get_child_properties_valist (container, child, var_args);
+  va_end (var_args);
+}
+
+
+/**
+ * goo_canvas_container_set_child_properties:
+ * @container: a #GooCanvasContainer.
+ * @child: a child #GooCanvasItem.
+ * @...: pairs of property names and values, and a terminating %NULL.
+ * 
+ * Sets the values of one or more child properties of @child.
+ **/
+void
+goo_canvas_container_set_child_properties   (GooCanvasContainer   *container,
+					     GooCanvasItem   *child,
+					     ...)
+{
+  va_list var_args;
+  
+  va_start (var_args, child);
+  goo_canvas_container_set_child_properties_valist (container, child, var_args);
+  va_end (var_args);
+}
+
+
+
+/**
+ * goo_canvas_container_class_install_child_property:
+ * @cclass: a #GObjectClass
+ * @property_id: the id for the property
+ * @pspec: the #GParamSpec for the property
+ * 
+ * This function is only intended to be used when implementing new canvas
+ * containers, specifically layout container containers such as #GooCanvasTable.
+ *
+ * It installs a child property on a canvas container class. 
+ **/
+void
+goo_canvas_container_class_install_child_property (GObjectClass *cclass,
+					           guint         property_id,
+					           GParamSpec   *pspec)
+{
+  g_return_if_fail (G_IS_OBJECT_CLASS (cclass));
+  g_return_if_fail (G_IS_PARAM_SPEC (pspec));
+  g_return_if_fail (property_id > 0);
+
+  if (g_param_spec_pool_lookup (_goo_canvas_container_child_property_pool,
+				pspec->name, G_OBJECT_CLASS_TYPE (cclass),
+				FALSE))
+    {
+      g_warning (G_STRLOC ": class `%s' already contains a child property named `%s'",
+		 G_OBJECT_CLASS_NAME (cclass), pspec->name);
+      return;
+    }
+  g_param_spec_ref (pspec);
+  g_param_spec_sink (pspec);
+  pspec->param_id = property_id;
+  g_param_spec_pool_insert (_goo_canvas_container_child_property_pool, pspec,
+			    G_OBJECT_CLASS_TYPE (cclass));
+}
+
+/**
+ * goo_canvas_container_class_find_child_property:
+ * @cclass: a #GObjectClass
+ * @property_name: the name of the child property to find
+ * @returns: the #GParamSpec of the child property or %NULL if @class has no
+ *   child property with that name.
+ *
+ * This function is only intended to be used when implementing new canvas
+ * containers, specifically layout container containers such as #GooCanvasTable.
+ *
+ * It finds a child property of a canvas container class by name.
+ */
+GParamSpec*
+goo_canvas_container_class_find_child_property (GObjectClass *cclass,
+					        const gchar  *property_name)
+{
+  g_return_val_if_fail (G_IS_OBJECT_CLASS (cclass), NULL);
+  g_return_val_if_fail (property_name != NULL, NULL);
+
+  return g_param_spec_pool_lookup (_goo_canvas_container_child_property_pool,
+				   property_name, G_OBJECT_CLASS_TYPE (cclass),
+				   TRUE);
+}
+
+/**
+ * goo_canvas_container_class_list_child_properties:
+ * @cclass: a #GObjectClass
+ * @n_properties: location to return the number of child properties found
+ * @returns: a newly allocated array of #GParamSpec*. The array must be 
+ *           freed with g_free().
+ *
+ * This function is only intended to be used when implementing new canvas
+ * containers, specifically layout container containers such as #GooCanvasTable.
+ *
+ * It returns all child properties of a canvas container class.
+ */
+GParamSpec**
+goo_canvas_container_class_list_child_properties (GObjectClass *cclass,
+					          guint        *n_properties)
+{
+  GParamSpec **pspecs;
+  guint n;
+
+  g_return_val_if_fail (G_IS_OBJECT_CLASS (cclass), NULL);
+
+  pspecs = g_param_spec_pool_list (_goo_canvas_container_child_property_pool,
+				   G_OBJECT_CLASS_TYPE (cclass), &n);
+  if (n_properties)
+    *n_properties = n;
+
+  return pspecs;
+}
Index: src/goocanvaswidget.c
===================================================================
--- src/goocanvaswidget.c	(revision 27)
+++ src/goocanvaswidget.c	(working copy)
@@ -109,7 +109,7 @@ goo_canvas_widget_init (GooCanvasWidget 
  * Returns: a new widget item.
  **/
 GooCanvasItem*
-goo_canvas_widget_new               (GooCanvasItem    *parent,
+goo_canvas_widget_new               (GooCanvasContainer   *parent,
 				     GtkWidget        *widget,
 				     gdouble           x,
 				     gdouble           y,
@@ -147,14 +147,13 @@ goo_canvas_widget_new               (Goo
 
   if (parent)
     {
-      goo_canvas_item_add_child (parent, item, -1);
+      goo_canvas_container_add_child (parent, item, -1);
       g_object_unref (item);
     }
 
   return item;
 }
 
-
 static void
 goo_canvas_widget_set_widget (GooCanvasWidget *witem,
 			      GtkWidget       *widget)
@@ -216,6 +215,8 @@ goo_canvas_widget_get_property  (GObject
   GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
   GooCanvasWidget *witem = (GooCanvasWidget*) object;
 
+  gdouble width, height;
+
   switch (prop_id)
     {
     case PROP_WIDGET:
@@ -329,8 +330,8 @@ goo_canvas_widget_set_canvas  (GooCanvas
 
 
 static void
-goo_canvas_widget_set_parent (GooCanvasItem  *item,
-			      GooCanvasItem  *parent)
+goo_canvas_widget_set_parent (GooCanvasItem      *item,
+			      GooCanvasContainer *parent)
 {
   GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
   GooCanvas *canvas;
@@ -339,7 +340,7 @@ goo_canvas_widget_set_parent (GooCanvasI
   simple->need_update = TRUE;
   simple->need_entire_subtree_update = TRUE;
 
-  canvas = parent ? goo_canvas_item_get_canvas (parent) : NULL;
+  canvas = parent ? goo_canvas_item_get_canvas (GOO_CANVAS_ITEM (parent)) : NULL;
   goo_canvas_widget_set_canvas (item, canvas);
 }
 
@@ -362,6 +363,7 @@ goo_canvas_widget_update  (GooCanvasItem
 
       simple->bounds.x1 = witem->x;
       simple->bounds.y1 = witem->y;
+
       width = witem->width < 0 ? requisition.width : witem->width;
       height = witem->height < 0 ? requisition.height : witem->height;
 
@@ -380,7 +382,7 @@ goo_canvas_widget_update  (GooCanvasItem
 	default:
 	  break;
 	}
-
+ 
       switch (witem->anchor)
 	{
 	case GTK_ANCHOR_W:
Index: src/goocanvasitemmodel.h
===================================================================
--- src/goocanvasitemmodel.h	(revision 27)
+++ src/goocanvasitemmodel.h	(working copy)
@@ -34,14 +34,6 @@ G_BEGIN_DECLS
 
 /**
  * GooCanvasItemModelIface
- * @get_n_children: returns the number of children of the model.
- * @get_child: returns the child at the given index.
- * @add_child: adds a child.
- * @move_child: moves a child up or down the stacking order.
- * @remove_child: removes a child.
- * @get_child_property: gets a child property of a given child model,
- *  e.g. the "row" or "column" property of a model in a #GooCanvasTableModel.
- * @set_child_property: sets a child property for a given child model.
  * @get_parent: gets the model's parent.
  * @set_parent: sets the model's parent.
  * @create_item: creates a default canvas item to view the model.
@@ -49,9 +41,6 @@ G_BEGIN_DECLS
  * @set_transform: sets the model's transformation matrix.
  * @get_style: gets the model's style.
  * @set_style: sets the model's style.
- * @child_added: signal emitted when a child is added.
- * @child_moved: signal emitted when a child is moved in the stacking order.
- * @child_removed: signal emitted when a child is removed.
  * @changed: signal emitted when the model has changed.
  * @child_notify: signal emitted when a child property has changed.
  * @animation_finished: signal emitted when the model's animation has finished.
@@ -65,12 +54,6 @@ G_BEGIN_DECLS
  * Items that support transforms should also implement get_transform() and
  * set_transform(). Items that support styles should implement get_style()
  * and set_style().
- *
- * Container items must implement get_n_children() and get_child().
- * Containers that support dynamic changes to their children should implement
- * add_child(), move_child() and remove_child().
- * Layout containers like #GooCanvasTable may implement
- * get_child_property() and set_child_property().
  */
 typedef struct _GooCanvasItemModelIface  GooCanvasItemModelIface;
 
@@ -80,38 +63,14 @@ struct _GooCanvasItemModelIface
   GTypeInterface base_iface;
 
   /*< public >*/
-  /* Virtual methods that group models must implement. */
-  gint		       (* get_n_children)		(GooCanvasItemModel	*model);
-  GooCanvasItemModel*  (* get_child)			(GooCanvasItemModel	*model,
-							 gint			 child_num);
-
-  /* Virtual methods that group models may implement. */
-  void                 (* add_child)			(GooCanvasItemModel	*model,
-							 GooCanvasItemModel	*child,
-							 gint			 position);
-  void                 (* move_child)			(GooCanvasItemModel	*model,
-							 gint			 old_position,
-							 gint			 new_position);
-  void                 (* remove_child)			(GooCanvasItemModel	*model,
-							 gint			 child_num);
-  void                 (* get_child_property)		(GooCanvasItemModel	*model,
-							 GooCanvasItemModel	*child,
-							 guint			 property_id,
-							 GValue			*value,
-							 GParamSpec		*pspec);
-  void                 (* set_child_property)		(GooCanvasItemModel	*item,
-							 GooCanvasItemModel	*child,
-							 guint			 property_id,
-							 const GValue		*value,
-							 GParamSpec		*pspec);
 
   /* Virtual methods that all item models must implement. */
-  GooCanvasItemModel*  (* get_parent)			(GooCanvasItemModel	*model);
-  void                 (* set_parent)			(GooCanvasItemModel	*model,
-							 GooCanvasItemModel	*parent);
+  GooCanvasContainerModel*  (* get_parent)			(GooCanvasItemModel		*model);
+  void                      (* set_parent)			(GooCanvasItemModel		*model,
+								 GooCanvasContainerModel	*parent);
 
-  GooCanvasItem*       (* create_item)			(GooCanvasItemModel	*model,
-							 GooCanvas		*canvas);
+  GooCanvasItem*       (* create_item)			(GooCanvasItemModel			*model,
+							 GooCanvas				*canvas);
 
   /* Virtual methods that all item models may implement. */
   gboolean             (* get_transform)		(GooCanvasItemModel	*model,
@@ -123,13 +82,6 @@ struct _GooCanvasItemModelIface
 							 GooCanvasStyle		*style);
 
   /* Signals. */
-  void                 (* child_added)			(GooCanvasItemModel	*model,
-							 gint			 child_num);
-  void                 (* child_moved)			(GooCanvasItemModel	*model,
-							 gint			 old_child_num,
-							 gint			 new_child_num);
-  void                 (* child_removed)		(GooCanvasItemModel	*model,
-							 gint			 child_num);
   void                 (* changed)			(GooCanvasItemModel	*model,
 							 gboolean		 recompute_bounds);
   void                 (* child_notify)			(GooCanvasItemModel	*model,
@@ -155,52 +107,13 @@ GType               goo_canvas_item_mode
 
 
 /*
- * Group functions - these should only be called on container models.
- */
-gint                goo_canvas_item_model_get_n_children (GooCanvasItemModel *model);
-GooCanvasItemModel* goo_canvas_item_model_get_child      (GooCanvasItemModel *model,
-							  gint                child_num);
-void                goo_canvas_item_model_add_child      (GooCanvasItemModel *model,
-							  GooCanvasItemModel *child,
-							  gint                position);
-void                goo_canvas_item_model_move_child     (GooCanvasItemModel *model,
-							  gint                old_position,
-							  gint                new_position);
-void                goo_canvas_item_model_remove_child   (GooCanvasItemModel *model,
-							  gint                child_num);
-gint                goo_canvas_item_model_find_child     (GooCanvasItemModel *model,
-							  GooCanvasItemModel *child);
-
-void     goo_canvas_item_model_get_child_property	 (GooCanvasItemModel   *model,
-							  GooCanvasItemModel   *child,
-							  const gchar          *property_name,
-							  GValue               *value);
-void     goo_canvas_item_model_set_child_property	 (GooCanvasItemModel   *model,
-							  GooCanvasItemModel   *child,
-							  const gchar          *property_name,
-							  const GValue         *value);
-void     goo_canvas_item_model_get_child_properties	 (GooCanvasItemModel   *model,
-							  GooCanvasItemModel   *child,
-							  ...) G_GNUC_NULL_TERMINATED;
-void     goo_canvas_item_model_set_child_properties	 (GooCanvasItemModel   *model,
-							  GooCanvasItemModel   *child,
-							  ...) G_GNUC_NULL_TERMINATED;
-void     goo_canvas_item_model_get_child_properties_valist (GooCanvasItemModel   *model,
-							    GooCanvasItemModel   *child,
-							    va_list	         var_args);
-void     goo_canvas_item_model_set_child_properties_valist (GooCanvasItemModel   *model,
-							    GooCanvasItemModel   *child,
-							    va_list	         var_args);
-
-
-/*
  * Model functions - these are safe to call on all models.
  */
-GooCanvasItemModel* goo_canvas_item_model_get_parent     (GooCanvasItemModel *model);
-void                goo_canvas_item_model_set_parent	 (GooCanvasItemModel *model,
-							  GooCanvasItemModel *parent);
+GooCanvasContainerModel* goo_canvas_item_model_get_parent     (GooCanvasItemModel      *model);
+void                     goo_canvas_item_model_set_parent     (GooCanvasItemModel      *model,
+							       GooCanvasContainerModel *parent);
+
 void                goo_canvas_item_model_remove         (GooCanvasItemModel *model);
-gboolean            goo_canvas_item_model_is_container   (GooCanvasItemModel *model);
 
 void                goo_canvas_item_model_raise          (GooCanvasItemModel *model,
 							  GooCanvasItemModel *above);
@@ -257,19 +170,6 @@ void                goo_canvas_item_mode
 void                goo_canvas_item_model_stop_animation (GooCanvasItemModel *model);
 
 
-/*
- * Functions to support child properties when implementing new canvas items.
- */
-void         goo_canvas_item_model_class_install_child_property (GObjectClass *mclass,
-								 guint	 property_id,
-								 GParamSpec	*pspec);
-GParamSpec*  goo_canvas_item_model_class_find_child_property	(GObjectClass	*mclass,
-								 const gchar	*property_name);
-GParamSpec** goo_canvas_item_model_class_list_child_properties  (GObjectClass	*mclass,
-								 guint	*n_properties);
-
-
-
 G_END_DECLS
 
 #endif /* __GOO_CANVAS_ITEM_MODEL_H__ */
Index: src/goocanvastext.c
===================================================================
--- src/goocanvastext.c	(revision 27)
+++ src/goocanvastext.c	(working copy)
@@ -184,12 +184,12 @@ goo_canvas_text_init (GooCanvasText *tex
  * Returns: a new text item.
  **/
 GooCanvasItem*
-goo_canvas_text_new (GooCanvasItem *parent,
-		     const char    *string,
-		     gdouble        x,
-		     gdouble        y,
-		     gdouble        width,
-		     GtkAnchorType  anchor,
+goo_canvas_text_new (GooCanvasContainer *parent,
+		     const char         *string,
+		     gdouble             x,
+		     gdouble             y,
+		     gdouble             width,
+		     GtkAnchorType       anchor,
 		     ...)
 {
   GooCanvasItem *item;
@@ -216,7 +216,7 @@ goo_canvas_text_new (GooCanvasItem *pare
 
   if (parent)
     {
-      goo_canvas_item_add_child (parent, item, -1);
+      goo_canvas_container_add_child (parent, item, -1);
       g_object_unref (item);
     }
 
@@ -295,7 +295,7 @@ goo_canvas_text_get_property (GObject   
   GooCanvasText *text = (GooCanvasText*) object;
 
   goo_canvas_text_get_common_property (object, text->text_data, prop_id,
-				       value, pspec);
+                                       value, pspec);
 }
 
 
@@ -660,6 +660,7 @@ goo_canvas_text_paint (GooCanvasItemSimp
 					  &origin_x, &origin_y);
   cairo_move_to (cr, origin_x, origin_y);
   pango_cairo_show_layout (cr, layout);
+
   g_object_unref (layout);
 }
 
@@ -694,7 +695,7 @@ goo_canvas_text_get_requested_height (Go
 
   /* Create layout with given width. */
   layout = goo_canvas_text_create_layout (simple_data, text->text_data,
-					  text->layout_width, cr,
+			                  text->layout_width, cr,
 					  &simple->bounds, NULL, NULL);
   g_object_unref (layout);
 
@@ -893,12 +894,12 @@ goo_canvas_text_model_init (GooCanvasTex
  * Returns: a new text model.
  **/
 GooCanvasItemModel*
-goo_canvas_text_model_new (GooCanvasItemModel *parent,
-			   const char         *string,
-			   gdouble             x,
-			   gdouble             y,
-			   gdouble             width,
-			   GtkAnchorType       anchor,
+goo_canvas_text_model_new (GooCanvasContainerModel *parent,
+			   const char              *string,
+			   gdouble                  x,
+			   gdouble                  y,
+			   gdouble                  width,
+			   GtkAnchorType            anchor,
 			   ...)
 {
   GooCanvasItemModel *model;
@@ -925,7 +926,7 @@ goo_canvas_text_model_new (GooCanvasItem
 
   if (parent)
     {
-      goo_canvas_item_model_add_child (parent, model, -1);
+      goo_canvas_container_model_add_child (parent, model, -1);
       g_object_unref (model);
     }
 
Index: src/goocanvastable.c
===================================================================
--- src/goocanvastable.c	(revision 27)
+++ src/goocanvastable.c	(working copy)
@@ -192,9 +192,11 @@ struct _GooCanvasTableLayoutData
   gdouble last_width;
 };
 
-static GooCanvasItemIface *goo_canvas_table_parent_iface;
+static GooCanvasItemIface *goo_canvas_table_parent_item_iface;
+static GooCanvasContainerIface *goo_canvas_table_parent_container_iface;
 
-static void item_interface_init           (GooCanvasItemIface *iface);
+static void item_interface_init           (GooCanvasItemIface      *iface);
+static void container_interface_init      (GooCanvasContainerIface *iface);
 static void goo_canvas_table_finalize     (GObject            *object);
 static void goo_canvas_table_get_property (GObject            *object,
 					   guint               param_id,
@@ -205,13 +207,43 @@ static void goo_canvas_table_set_propert
 					   const GValue       *value,
 					   GParamSpec         *pspec);
 
+static void
+goo_canvas_table_add_child                (GooCanvasContainer  *container,
+				           GooCanvasItem       *child,
+				           gint                 position);
+static void
+goo_canvas_table_move_child               (GooCanvasContainer  *container,
+				           gint	                old_position,
+				           gint                 new_position);
+static void
+goo_canvas_table_remove_child             (GooCanvasContainer  *container,
+		                           gint                 child_num);
+static void
+goo_canvas_table_get_child_property       (GooCanvasContainer  *container,
+				           GooCanvasItem       *child,
+				           guint                property_id,
+				           GValue              *value,
+				           GParamSpec          *pspec);
+static void
+goo_canvas_table_set_child_property       (GooCanvasContainer  *container,
+				           GooCanvasItem       *child,
+				           guint                property_id,
+				           const GValue        *value,
+				           GParamSpec          *pspec);
+gboolean
+goo_canvas_table_get_transform_for_child  (GooCanvasContainer  *container,
+					   GooCanvasItem       *child,
+					   cairo_matrix_t      *transform);
+
 static void goo_canvas_table_init_layout_data (GooCanvasTable *table);
 static void goo_canvas_table_free_layout_data (GooCanvasTableData *table_data);
 
 G_DEFINE_TYPE_WITH_CODE (GooCanvasTable, goo_canvas_table,
 			 GOO_TYPE_CANVAS_GROUP,
 			 G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM,
-						item_interface_init))
+						item_interface_init)
+                         G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_CONTAINER,
+                                                container_interface_init))
 
 typedef void (*InstallChildPropertyFunc) (GObjectClass*, guint, GParamSpec*);
 
@@ -398,13 +430,14 @@ goo_canvas_table_class_init (GooCanvasTa
 {
   GObjectClass *gobject_class = (GObjectClass*) klass;
 
-  goo_canvas_table_parent_iface = g_type_interface_peek (goo_canvas_table_parent_class, GOO_TYPE_CANVAS_ITEM);
+  goo_canvas_table_parent_item_iface = g_type_interface_peek (goo_canvas_table_parent_class, GOO_TYPE_CANVAS_ITEM);
+  goo_canvas_table_parent_container_iface = g_type_interface_peek (goo_canvas_table_parent_class, GOO_TYPE_CANVAS_CONTAINER);
 
   gobject_class->finalize = goo_canvas_table_finalize;
   gobject_class->get_property = goo_canvas_table_get_property;
   gobject_class->set_property = goo_canvas_table_set_property;
 
-  goo_canvas_table_install_common_properties (gobject_class, goo_canvas_item_class_install_child_property);
+  goo_canvas_table_install_common_properties (gobject_class, goo_canvas_container_class_install_child_property);
 }
 
 
@@ -430,6 +463,7 @@ goo_canvas_table_init_data (GooCanvasTab
   table_data->children = g_array_new (0, 0, sizeof (GooCanvasTableChild));
 
   table_data->layout_data = g_slice_new (GooCanvasTableLayoutData);
+
   table_data->layout_data->children = NULL;
   for (d = 0; d < 2; d++)
     {
@@ -482,44 +516,45 @@ goo_canvas_table_init (GooCanvasTable *t
  * a triangle in it:
  *
  * <informalexample><programlisting>
- *  GooCanvasItem *table, *square, *circle, *triangle;
+ *  GooCanvasGroup *table;
+ *  GooCanvasItem  *square, *circle, *triangle;
  *  
- *  table = goo_canvas_table_new (root,
- *                                "row-spacing", 4.0,
- *                                "column-spacing", 4.0,
- *                                NULL);
+ *  table = GOO_CANVAS_GROUP(goo_canvas_table_new (root,
+ *                                                 "row-spacing", 4.0,
+ *                                                 "column-spacing", 4.0,
+ *                                                 NULL));
  *  goo_canvas_item_translate (table, 400, 200);
  *  
  *  square = goo_canvas_rect_new (table, 0.0, 0.0, 50.0, 50.0,
  *                                "fill-color", "red",
  *                                NULL);
- *  goo_canvas_item_set_child_properties (table, square,
- *                                        "row", 0,
- *                                        "column", 0,
- *                                        NULL);
+ *  goo_canvas_group_set_child_properties (table, square,
+ *                                         "row", 0,
+ *                                         "column", 0,
+ *                                         NULL);
  *  
  *  circle = goo_canvas_ellipse_new (table, 0.0, 0.0, 25.0, 25.0,
  *                                   "fill-color", "blue",
  *                                   NULL);
- *  goo_canvas_item_set_child_properties (table, circle,
- *                                        "row", 0,
- *                                        "column", 1,
- *                                        NULL);
+ *  goo_canvas_group_set_child_properties (table, circle,
+ *                                         "row", 0,
+ *                                         "column", 1,
+ *                                         NULL);
  *  
  *  triangle = goo_canvas_polyline_new (table, TRUE, 3,
  *                                      25.0, 0.0, 0.0, 50.0, 50.0, 50.0,
  *                                      "fill-color", "yellow",
  *                                      NULL);
- *  goo_canvas_item_set_child_properties (table, triangle,
- *                                        "row", 0,
- *                                        "column", 2,
- *                                        NULL);
+ *  goo_canvas_group_set_child_properties (table, triangle,
+ *                                         "row", 0,
+ *                                         "column", 2,
+ *                                         NULL);
  * </programlisting></informalexample>
  * 
  * Returns: a new table item.
  **/
 GooCanvasItem*
-goo_canvas_table_new (GooCanvasItem  *parent,
+goo_canvas_table_new (GooCanvasContainer  *parent,
 		      ...)
 {
   GooCanvasItem *item;
@@ -536,7 +571,7 @@ goo_canvas_table_new (GooCanvasItem  *pa
 
   if (parent)
     {
-      goo_canvas_item_add_child (parent, item, -1);
+      goo_canvas_container_add_child (parent, item, -1);
       g_object_unref (item);
     }
 
@@ -618,7 +653,7 @@ goo_canvas_table_get_property (GObject  
   GooCanvasTable *table = (GooCanvasTable*) object;
 
   goo_canvas_table_get_common_property (object, table->table_data,
-					prop_id, value, pspec);
+                                        prop_id, value, pspec);
 }
 
 
@@ -814,18 +849,18 @@ goo_canvas_table_add_child_internal (Goo
 
 
 static void
-goo_canvas_table_add_child     (GooCanvasItem  *item,
-				GooCanvasItem  *child,
-				gint            position)
+goo_canvas_table_add_child     (GooCanvasContainer *container,
+				GooCanvasItem      *child,
+				gint                position)
 {
-  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
-  GooCanvasTable *table = (GooCanvasTable*) item;
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) container;
+  GooCanvasTable *table = (GooCanvasTable*) container;
 
   if (!simple->model)
     goo_canvas_table_add_child_internal (table->table_data, position);
 
   /* Let the parent GooCanvasGroup code do the rest. */
-  goo_canvas_table_parent_iface->add_child (item, child, position);
+  goo_canvas_table_parent_container_iface->add_child (container, child, position);
 }
 
 
@@ -868,37 +903,36 @@ goo_canvas_table_move_child_internal    
 
 
 static void
-goo_canvas_table_move_child    (GooCanvasItem  *item,
-				gint	        old_position,
-				gint            new_position)
+goo_canvas_table_move_child    (GooCanvasContainer *container,
+				gint	            old_position,
+				gint                new_position)
 {
-  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
-  GooCanvasTable *table = (GooCanvasTable*) item;
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) container;
+  GooCanvasTable *table = (GooCanvasTable*) container;
 
   if (!simple->model)
     goo_canvas_table_move_child_internal (table->table_data, old_position,
 					  new_position);
 
   /* Let the parent GooCanvasGroup code do the rest. */
-  goo_canvas_table_parent_iface->move_child (item, old_position, new_position);
+  goo_canvas_table_parent_container_iface->move_child (container, old_position, new_position);
 }
 
 
 static void
-goo_canvas_table_remove_child  (GooCanvasItem  *item,
-				gint            child_num)
+goo_canvas_table_remove_child  (GooCanvasContainer *container,
+				gint                child_num)
 {
-  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
-  GooCanvasGroup *group = (GooCanvasGroup*) item;
-  GooCanvasTable *table = (GooCanvasTable*) item;
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) container;
+  GooCanvasTable *table = (GooCanvasTable*) container;
 
-  g_return_if_fail (child_num < group->items->len);
+  g_return_if_fail (child_num < GOO_CANVAS_GROUP (container)->items->len);
 
   if (!simple->model)
     g_array_remove_index (table->table_data->children, child_num);
 
   /* Let the parent GooCanvasGroup code do the rest. */
-  goo_canvas_table_parent_iface->remove_child (item, child_num);
+  goo_canvas_table_parent_container_iface->remove_child (container, child_num);
 }
 
 
@@ -968,14 +1002,14 @@ goo_canvas_table_get_common_child_proper
 
 
 static void
-goo_canvas_table_get_child_property (GooCanvasItem     *item,
-				     GooCanvasItem     *child,
-				     guint              property_id,
-				     GValue            *value,
-				     GParamSpec        *pspec)
+goo_canvas_table_get_child_property (GooCanvasContainer    *container,
+				     GooCanvasItem         *child,
+				     guint                  property_id,
+				     GValue                *value,
+				     GParamSpec            *pspec)
 {
-  GooCanvasGroup *group = (GooCanvasGroup*) item;
-  GooCanvasTable *table = (GooCanvasTable*) item;
+  GooCanvasTable *table = (GooCanvasTable*) container;
+  GooCanvasGroup *group = GOO_CANVAS_GROUP (container);
   GooCanvasTableChild *table_child;
   gint child_num;
 
@@ -1085,15 +1119,15 @@ goo_canvas_table_set_common_child_proper
 
 
 static void
-goo_canvas_table_set_child_property (GooCanvasItem     *item,
-				     GooCanvasItem     *child,
-				     guint              property_id,
-				     const GValue      *value,
-				     GParamSpec        *pspec)
-{
-  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
-  GooCanvasGroup *group = (GooCanvasGroup*) item;
-  GooCanvasTable *table = (GooCanvasTable*) item;
+goo_canvas_table_set_child_property (GooCanvasContainer    *container,
+				     GooCanvasItem         *child,
+				     guint                  property_id,
+				     const GValue          *value,
+				     GParamSpec            *pspec)
+{
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) container;
+  GooCanvasTable *table = (GooCanvasTable*) container;
+  GooCanvasGroup *group = GOO_CANVAS_GROUP (container);
   GooCanvasTableChild *table_child;
   gint child_num;
 
@@ -1135,7 +1169,7 @@ goo_canvas_table_set_model    (GooCanvas
   table->table_data = &tmodel->table_data;
 
   /* Let the parent GooCanvasGroup code do the rest. */
-  goo_canvas_table_parent_iface->set_model (item, model);
+  goo_canvas_table_parent_item_iface->set_model (item, model);
 }
 
 
@@ -1929,7 +1963,7 @@ goo_canvas_table_get_requested_area (Goo
   GooCanvasItemSimpleData *simple_data = simple->simple_data;
   GooCanvasTable *table = (GooCanvasTable*) item;
   GooCanvasTableData *table_data = table->table_data;
-  GooCanvasTableLayoutData *layout_data;
+  GooCanvasTableLayoutData *layout_data = table_data->layout_data;
   GooCanvasTableDimensionLayoutData *rows, *columns;
   gdouble width = 0.0, height = 0.0;
   gint row, column, end;
@@ -1964,7 +1998,6 @@ goo_canvas_table_get_requested_area (Goo
   goo_canvas_table_size_request_pass3 (table, HORZ);
   goo_canvas_table_size_request_pass2 (table, HORZ);
 
-  layout_data = table_data->layout_data;
   rows = layout_data->dldata[VERT];
   columns = layout_data->dldata[HORZ];
 
@@ -2132,6 +2165,7 @@ goo_canvas_table_allocate_area (GooCanva
 		   -(allocated_area->y1 - requested_area->y1));
   if (simple_data->transform)
     cairo_transform (cr, simple_data->transform);
+
   goo_canvas_table_update_requested_heights (item, cr);
   cairo_restore (cr);
 
@@ -2610,13 +2644,13 @@ goo_canvas_table_get_items_at (GooCanvas
 
 
 gboolean
-goo_canvas_table_get_transform_for_child  (GooCanvasItem  *item,
-					   GooCanvasItem  *child,
-					   cairo_matrix_t *transform)
-{
-  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
-  GooCanvasGroup *group = (GooCanvasGroup*) item;
-  GooCanvasTable *table = (GooCanvasTable*) item;
+goo_canvas_table_get_transform_for_child  (GooCanvasContainer *container,
+					   GooCanvasItem      *child,
+					   cairo_matrix_t     *transform)
+{
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) container;
+  GooCanvasTable *table = (GooCanvasTable*) container;
+  GooCanvasGroup *group = GOO_CANVAS_GROUP (container);
   GooCanvasTableChild *table_child;
   gboolean has_transform = FALSE;
   gint child_num;
@@ -2652,13 +2686,6 @@ goo_canvas_table_get_transform_for_child
 static void
 item_interface_init (GooCanvasItemIface *iface)
 {
-  iface->add_child               = goo_canvas_table_add_child;
-  iface->move_child              = goo_canvas_table_move_child;
-  iface->remove_child            = goo_canvas_table_remove_child;
-  iface->get_child_property      = goo_canvas_table_get_child_property;
-  iface->set_child_property      = goo_canvas_table_set_child_property;
-  iface->get_transform_for_child = goo_canvas_table_get_transform_for_child;
-
   iface->update                  = goo_canvas_table_update;
   iface->get_requested_area      = goo_canvas_table_get_requested_area;
   iface->get_requested_height    = goo_canvas_table_get_requested_height;
@@ -2669,6 +2696,18 @@ item_interface_init (GooCanvasItemIface 
   iface->set_model               = goo_canvas_table_set_model;
 }
 
+static void
+container_interface_init (GooCanvasContainerIface *iface)
+{
+  iface->add_child               = goo_canvas_table_add_child;
+  iface->move_child              = goo_canvas_table_move_child;
+  iface->remove_child            = goo_canvas_table_remove_child;
+  iface->get_child_property      = goo_canvas_table_get_child_property;
+  iface->set_child_property      = goo_canvas_table_set_child_property;
+  iface->get_transform_for_child = goo_canvas_table_get_transform_for_child;
+
+}
+
 
 
 /**
@@ -2703,9 +2742,11 @@ item_interface_init (GooCanvasItemIface 
  * g_object_get() and g_object_set().
  */
 
-static GooCanvasItemModelIface *goo_canvas_table_model_parent_iface;
+static GooCanvasItemModelIface *goo_canvas_table_model_item_parent_iface;
+static GooCanvasContainerModelIface *goo_canvas_table_model_container_parent_iface;
 
-static void item_model_interface_init (GooCanvasItemModelIface *iface);
+static void item_model_interface_init      (GooCanvasItemModelIface      *iface);
+static void container_model_interface_init (GooCanvasContainerModelIface *iface);
 static void goo_canvas_table_model_finalize (GObject *object);
 static void goo_canvas_table_model_get_property (GObject            *object,
 						 guint               param_id,
@@ -2719,7 +2760,9 @@ static void goo_canvas_table_model_set_p
 G_DEFINE_TYPE_WITH_CODE (GooCanvasTableModel, goo_canvas_table_model,
 			 GOO_TYPE_CANVAS_GROUP_MODEL,
 			 G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM_MODEL,
-						item_model_interface_init))
+						item_model_interface_init)
+                         G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_CONTAINER_MODEL,
+			                        container_model_interface_init))
 
 
 static void
@@ -2727,14 +2770,15 @@ goo_canvas_table_model_class_init (GooCa
 {
   GObjectClass *gobject_class = (GObjectClass*) klass;
 
-  goo_canvas_table_model_parent_iface = g_type_interface_peek (goo_canvas_table_model_parent_class, GOO_TYPE_CANVAS_ITEM_MODEL);
+  goo_canvas_table_model_item_parent_iface = g_type_interface_peek (goo_canvas_table_model_parent_class, GOO_TYPE_CANVAS_ITEM_MODEL);
+  goo_canvas_table_model_container_parent_iface = g_type_interface_peek (goo_canvas_table_model_parent_class, GOO_TYPE_CANVAS_CONTAINER_MODEL);
 
   gobject_class->finalize = goo_canvas_table_model_finalize;
 
   gobject_class->get_property = goo_canvas_table_model_get_property;
   gobject_class->set_property = goo_canvas_table_model_set_property;
 
-  goo_canvas_table_install_common_properties (gobject_class, goo_canvas_item_model_class_install_child_property);
+  goo_canvas_table_install_common_properties (gobject_class, goo_canvas_container_model_class_install_child_property);
 }
 
 
@@ -2797,7 +2841,7 @@ goo_canvas_table_model_init (GooCanvasTa
  * Returns: a new table model.
  **/
 GooCanvasItemModel*
-goo_canvas_table_model_new (GooCanvasItemModel *parent,
+goo_canvas_table_model_new (GooCanvasContainerModel *parent,
 			    ...)
 {
   GooCanvasItemModel *model;
@@ -2814,7 +2858,7 @@ goo_canvas_table_model_new (GooCanvasIte
 
   if (parent)
     {
-      goo_canvas_item_model_add_child (parent, model, -1);
+      goo_canvas_container_model_add_child (parent, model, -1);
       g_object_unref (model);
     }
 
@@ -2864,23 +2908,23 @@ goo_canvas_table_model_set_property (GOb
 
 
 static void
-goo_canvas_table_model_add_child     (GooCanvasItemModel *model,
-				      GooCanvasItemModel *child,
-				      gint                position)
+goo_canvas_table_model_add_child     (GooCanvasContainerModel *model,
+				      GooCanvasItemModel      *child,
+				      gint                     position)
 {
   GooCanvasTableModel *tmodel = (GooCanvasTableModel*) model;
 
   goo_canvas_table_add_child_internal (&tmodel->table_data, position);
 
   /* Let the parent GooCanvasGroupModel code do the rest. */
-  goo_canvas_table_model_parent_iface->add_child (model, child, position);
+  goo_canvas_table_model_container_parent_iface->add_child (model, child, position);
 }
 
 
 static void
-goo_canvas_table_model_move_child    (GooCanvasItemModel *model,
-				      gint	          old_position,
-				      gint                new_position)
+goo_canvas_table_model_move_child    (GooCanvasContainerModel *model,
+				      gint	               old_position,
+				      gint                     new_position)
 {
   GooCanvasTableModel *tmodel = (GooCanvasTableModel*) model;
 
@@ -2888,30 +2932,30 @@ goo_canvas_table_model_move_child    (Go
 					new_position);
 
   /* Let the parent GooCanvasGroupModel code do the rest. */
-  goo_canvas_table_model_parent_iface->move_child (model, old_position,
-						   new_position);
+  goo_canvas_table_model_container_parent_iface->move_child (model, old_position,
+						             new_position);
 }
 
 
 static void
-goo_canvas_table_model_remove_child  (GooCanvasItemModel *model,
-				      gint                child_num)
+goo_canvas_table_model_remove_child  (GooCanvasContainerModel *model,
+				      gint                     child_num)
 {
   GooCanvasTableModel *tmodel = (GooCanvasTableModel*) model;
 
   g_array_remove_index (tmodel->table_data.children, child_num);
 
   /* Let the parent GooCanvasGroupModel code do the rest. */
-  goo_canvas_table_model_parent_iface->remove_child (model, child_num);
+  goo_canvas_table_model_container_parent_iface->remove_child (model, child_num);
 }
 
 
 static void
-goo_canvas_table_model_get_child_property (GooCanvasItemModel *model,
-					   GooCanvasItemModel *child,
-					   guint               property_id,
-					   GValue             *value,
-					   GParamSpec         *pspec)
+goo_canvas_table_model_get_child_property (GooCanvasContainerModel *model,
+					   GooCanvasItemModel      *child,
+					   guint                    property_id,
+					   GValue                  *value,
+					   GParamSpec              *pspec)
 {
   GooCanvasGroupModel *gmodel = (GooCanvasGroupModel*) model;
   GooCanvasTableModel *tmodel = (GooCanvasTableModel*) model;
@@ -2935,11 +2979,11 @@ goo_canvas_table_model_get_child_propert
 
 
 static void
-goo_canvas_table_model_set_child_property (GooCanvasItemModel *model,
-					   GooCanvasItemModel *child,
-					   guint               property_id,
-					   const GValue       *value,
-					   GParamSpec         *pspec)
+goo_canvas_table_model_set_child_property (GooCanvasContainerModel *model,
+					   GooCanvasItemModel      *child,
+					   guint                    property_id,
+					   const GValue            *value,
+					   GParamSpec              *pspec)
 {
   GooCanvasGroupModel *gmodel = (GooCanvasGroupModel*) model;
   GooCanvasTableModel *tmodel = (GooCanvasTableModel*) model;
@@ -2984,11 +3028,15 @@ goo_canvas_table_model_create_item (GooC
 static void
 item_model_interface_init (GooCanvasItemModelIface *iface)
 {
+  iface->create_item        = goo_canvas_table_model_create_item;
+}
+
+static void
+container_model_interface_init (GooCanvasContainerModelIface *iface)
+{
   iface->add_child          = goo_canvas_table_model_add_child;
   iface->move_child         = goo_canvas_table_model_move_child;
   iface->remove_child       = goo_canvas_table_model_remove_child;
   iface->get_child_property = goo_canvas_table_model_get_child_property;
   iface->set_child_property = goo_canvas_table_model_set_child_property;
-
-  iface->create_item        = goo_canvas_table_model_create_item;
 }
Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revision 27)
+++ src/Makefile.am	(working copy)
@@ -28,6 +28,8 @@ libgoocanvas_la_LDFLAGS = $(libtool_opts
 libgoocanvasincludedir = $(includedir)/goocanvas-1.0
 
 libgoocanvas_public_headers =		\
+	goocanvascontainer.h		\
+	goocanvascontainermodel.h	\
 	goocanvasellipse.h		\
 	goocanvasgrid.h			\
 	goocanvasgroup.h		\
@@ -48,6 +50,8 @@ libgoocanvas_public_headers =		\
 libgoocanvas_la_SOURCES =		\
 	goocanvasatk.h			\
 	goocanvasatk.c			\
+	goocanvascontainer.c		\
+	goocanvascontainermodel.c	\
 	goocanvasellipse.c		\
 	goocanvasenumtypes.c		\
 	goocanvasgrid.c			\
Index: src/goocanvascontainer.h
===================================================================
--- src/goocanvascontainer.h	(revision 0)
+++ src/goocanvascontainer.h	(revision 0)
@@ -0,0 +1,159 @@
+/*
+ * GooCanvas. Copyright (C) 2005 Damon Chaplin.
+ * Released under the GNU LGPL license. See COPYING for details.
+ *
+ * goocanvascontainer.h - interface for canvas containers.
+ */
+#ifndef __GOO_CANVAS_CONTAINER_H__
+#define __GOO_CANVAS_CONTAINER_H__
+
+#include <gtk/gtk.h>
+#include "goocanvasitem.h"
+
+G_BEGIN_DECLS
+
+#define GOO_TYPE_CANVAS_CONTAINER            (goo_canvas_container_get_type ())
+#define GOO_CANVAS_CONTAINER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_CONTAINER, GooCanvasContainer))
+#define GOO_IS_CANVAS_CONTAINER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_CONTAINER))
+#define GOO_CANVAS_CONTAINER_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GOO_TYPE_CANVAS_CONTAINER, GooCanvasContainerIface))
+
+
+/**
+ * GooCanvasContainer
+ *
+ * #GooCanvasContainer is a typedef used for objects that implement the
+ * #GooCanvasContainer interface.
+ *
+ * (There is no actual #GooCanvasContainer struct, since it is only an interface.
+ * But using '#GooCanvasContainer' is more helpful than using '#GObject'.)
+ */
+
+
+/**
+ * GooCanvasContainerIface
+ * @get_n_children: returns the number of children of the group.
+ * @get_child: returns the child at the given index.
+ * @add_child: adds a child.
+ * @move_child: moves a child up or down the stacking order.
+ * @remove_child: removes a child.
+ * @get_child_property: gets a child property of a given child item,
+ * e.g. the "row" or "column" property of an item in a #GooCanvasTable.
+ * @set_child_property: sets a child property for a given child item.
+ * @get_transform_for_child: gets the transform used to lay out a given child.
+ *
+ * #GooCanvasContainerIface holds the virtual methods for containers.
+ *
+ * Containers must implement get_canvas(), set_canvas(), get_n_children(),
+ * get_child() and request_update(). Containers that support dynamic changes
+ * to their children should implement add_child(), move_child() and
+ * remove_child(). Layout containers like #GooCanvasTable may implement
+ * get_child_property(), set_child_property() and get_transform_for_child().
+ */
+typedef struct _GooCanvasContainerIface  GooCanvasContainerIface;
+
+struct _GooCanvasContainerIface
+{
+  /*< private >*/
+  GTypeInterface base_iface;
+
+  /*< public >*/
+  /* Virtual methods that containers must implement. */
+  gint			(* get_n_children)		(GooCanvasContainer	*container);
+  GooCanvasItem*	(* get_child)			(GooCanvasContainer	*container,
+							 gint			 child_num);
+
+  /* Virtual methods that containers may implement. */
+  void			(* add_child)			(GooCanvasContainer	*container,
+							 GooCanvasItem		*child,
+							 gint			 position);
+  void			(* move_child)			(GooCanvasContainer	*container,
+							 gint			 old_position,
+							 gint			 new_position);
+  void			(* remove_child)		(GooCanvasContainer	*container,
+							 gint			 child_num);
+  void			(* get_child_property)		(GooCanvasContainer	*container,
+							 GooCanvasItem		*child,
+							 guint			 property_id,
+							 GValue			*value,
+							 GParamSpec		*pspec);
+  void			(* set_child_property)		(GooCanvasContainer	*container,
+							 GooCanvasItem		*child,
+							 guint			 property_id,
+							 const GValue		*value,
+							 GParamSpec		*pspec);
+  gboolean		(* get_transform_for_child)	(GooCanvasContainer	*container,
+							 GooCanvasItem		*child,
+							 cairo_matrix_t		*transform);
+
+  /*< private >*/
+
+  /* Padding for future expansion */
+  void (*_goo_canvas_reserved1) (void);
+  void (*_goo_canvas_reserved2) (void);
+  void (*_goo_canvas_reserved3) (void);
+  void (*_goo_canvas_reserved4) (void);
+  void (*_goo_canvas_reserved5) (void);
+  void (*_goo_canvas_reserved6) (void);
+  void (*_goo_canvas_reserved7) (void);
+  void (*_goo_canvas_reserved8) (void);
+};
+
+
+GType              goo_canvas_container_get_type       (void) G_GNUC_CONST;
+
+/*
+ * Group functions - these should only be called on container containers.
+ */
+gint               goo_canvas_container_get_n_children (GooCanvasContainer   *container);
+GooCanvasItem*     goo_canvas_container_get_child      (GooCanvasContainer   *container,
+						        gint                  child_num);
+gint               goo_canvas_container_find_child     (GooCanvasContainer   *container,
+						        GooCanvasItem        *child);
+void               goo_canvas_container_add_child      (GooCanvasContainer   *container,
+						        GooCanvasItem        *child,
+						        gint                  position);
+void               goo_canvas_container_move_child     (GooCanvasContainer   *container,
+						        gint                  old_position,
+						        gint                  new_position);
+void               goo_canvas_container_remove_child   (GooCanvasContainer   *container,
+						        gint                  child_num);
+
+void  goo_canvas_container_get_child_property	  (GooCanvasContainer   *container,
+						   GooCanvasItem        *child,
+						   const gchar     *property_name,
+						   GValue          *value);
+void  goo_canvas_container_set_child_property	  (GooCanvasContainer   *container,
+						   GooCanvasItem        *child,
+						   const gchar     *property_name,
+						   const GValue    *value);
+void  goo_canvas_container_get_child_properties   (GooCanvasContainer   *container,
+						   GooCanvasItem        *child,
+						   ...) G_GNUC_NULL_TERMINATED;
+void  goo_canvas_container_set_child_properties   (GooCanvasContainer   *container,
+						   GooCanvasItem        *child,
+						   ...) G_GNUC_NULL_TERMINATED;
+void  goo_canvas_container_get_child_properties_valist (GooCanvasContainer   *container,
+						        GooCanvasItem        *child,
+						        va_list	    var_args);
+void  goo_canvas_container_set_child_properties_valist (GooCanvasContainer   *container,
+						        GooCanvasItem        *child,
+						        va_list	              var_args);
+
+gboolean goo_canvas_container_get_transform_for_child  (GooCanvasContainer   *container,
+						        GooCanvasItem        *child,
+						        cairo_matrix_t       *transform);
+
+/*
+ * Functions to support child properties when implementing new canvas containers.
+ */
+void         goo_canvas_container_class_install_child_property (GObjectClass    *cclass,
+							        guint   	 property_id,
+							        GParamSpec	*pspec);
+GParamSpec*  goo_canvas_container_class_find_child_property    (GObjectClass	*cclass,
+							        const gchar	*property_name);
+GParamSpec** goo_canvas_container_class_list_child_properties  (GObjectClass	*cclass,
+							        guint	        *n_properties);
+
+G_END_DECLS
+
+#endif /* __GOO_CANVAS_CONTAINER_H__ */
Index: src/goocanvaswidget.h
===================================================================
--- src/goocanvaswidget.h	(revision 27)
+++ src/goocanvaswidget.h	(working copy)
@@ -53,12 +53,12 @@ struct _GooCanvasWidgetClass
 
 
 GType          goo_canvas_widget_get_type          (void) G_GNUC_CONST;
-GooCanvasItem* goo_canvas_widget_new               (GooCanvasItem    *parent,
-						    GtkWidget        *widget,
-						    gdouble           x,
-						    gdouble           y,
-						    gdouble           width,
-						    gdouble           height,
+GooCanvasItem* goo_canvas_widget_new               (GooCanvasContainer *parent,
+						    GtkWidget          *widget,
+						    gdouble             x,
+						    gdouble             y,
+						    gdouble             width,
+						    gdouble             height,
 						    ...);
 
 G_END_DECLS
Index: src/goocanvastext.h
===================================================================
--- src/goocanvastext.h	(revision 27)
+++ src/goocanvastext.h	(working copy)
@@ -67,7 +67,7 @@ struct _GooCanvasTextClass
 
 GType               goo_canvas_text_get_type  (void) G_GNUC_CONST;
 
-GooCanvasItem*      goo_canvas_text_new       (GooCanvasItem      *parent,
+GooCanvasItem*      goo_canvas_text_new       (GooCanvasContainer *parent,
 					       const char         *string,
 					       gdouble             x,
 					       gdouble             y,
@@ -119,12 +119,12 @@ struct _GooCanvasTextModelClass
 
 GType               goo_canvas_text_model_get_type  (void) G_GNUC_CONST;
 
-GooCanvasItemModel* goo_canvas_text_model_new (GooCanvasItemModel *parent,
-					       const char         *string,
-					       gdouble             x,
-					       gdouble             y,
-					       gdouble             width,
-					       GtkAnchorType       anchor,
+GooCanvasItemModel* goo_canvas_text_model_new (GooCanvasContainerModel *parent,
+					       const char              *string,
+					       gdouble                  x,
+					       gdouble                  y,
+					       gdouble                  width,
+					       GtkAnchorType            anchor,
 					       ...);
 
 
Index: src/goocanvastable.h
===================================================================
--- src/goocanvastable.h	(revision 27)
+++ src/goocanvastable.h	(working copy)
@@ -86,7 +86,7 @@ struct _GooCanvasTableClass
 
 
 GType          goo_canvas_table_get_type    (void) G_GNUC_CONST;
-GooCanvasItem* goo_canvas_table_new         (GooCanvasItem  *parent,
+GooCanvasItem* goo_canvas_table_new         (GooCanvasContainer *parent,
 					     ...);
 
 
@@ -130,7 +130,7 @@ struct _GooCanvasTableModelClass
 
 
 GType               goo_canvas_table_model_get_type (void) G_GNUC_CONST;
-GooCanvasItemModel* goo_canvas_table_model_new      (GooCanvasItemModel *parent,
+GooCanvasItemModel* goo_canvas_table_model_new      (GooCanvasContainerModel *parent,
 						     ...);
 
 
Index: docs/goocanvas-sections.txt
===================================================================
--- docs/goocanvas-sections.txt	(revision 27)
+++ docs/goocanvas-sections.txt	(working copy)
@@ -122,16 +122,6 @@ goo_canvas_item_get_model
 goo_canvas_item_set_model
 
 <SUBSECTION>
-goo_canvas_item_is_container
-goo_canvas_item_get_n_children
-goo_canvas_item_get_child
-goo_canvas_item_find_child
-goo_canvas_item_add_child
-goo_canvas_item_move_child
-goo_canvas_item_remove_child
-goo_canvas_item_get_transform_for_child
-
-<SUBSECTION>
 goo_canvas_item_get_style
 goo_canvas_item_set_style
 
@@ -145,17 +135,6 @@ goo_canvas_item_allocate_area
 goo_canvas_item_get_items_at
 goo_canvas_item_paint
 
-<SUBSECTION>
-goo_canvas_item_class_install_child_property
-goo_canvas_item_class_list_child_properties
-goo_canvas_item_class_find_child_property
-goo_canvas_item_get_child_property
-goo_canvas_item_set_child_property
-goo_canvas_item_get_child_properties
-goo_canvas_item_get_child_properties_valist
-goo_canvas_item_set_child_properties
-goo_canvas_item_set_child_properties_valist
-
 <SUBSECTION Standard>
 GOO_CANVAS_ITEM
 GOO_IS_CANVAS_ITEM
@@ -165,6 +144,39 @@ GOO_CANVAS_ITEM_GET_IFACE
 </SECTION>
 
 <SECTION>
+<FILE>goocanvascontainer</FILE>
+GooCanvasContainer
+GooCanvasContainerIface
+
+<SUBSECTION>
+goo_canvas_container_get_n_children
+goo_canvas_container_get_child
+goo_canvas_container_find_child
+goo_canvas_container_add_child
+goo_canvas_container_move_child
+goo_canvas_container_remove_child
+goo_canvas_container_get_transform_for_child
+
+<SUBSECTION>
+goo_canvas_container_class_install_child_property
+goo_canvas_container_class_list_child_properties
+goo_canvas_container_class_find_child_property
+goo_canvas_container_get_child_property
+goo_canvas_container_set_child_property
+goo_canvas_container_get_child_properties
+goo_canvas_container_get_child_properties_valist
+goo_canvas_container_set_child_properties
+goo_canvas_container_set_child_properties_valist
+
+<SUBSECTION Standard>
+GOO_CANVAS_CONTAINER
+GOO_IS_CANVAS_CONTAINER
+GOO_TYPE_CANVAS_CONTAINER
+goo_canvas_container_get_type
+GOO_CANVAS_CONTAINER_GET_IFACE
+</SECTION>
+
+<SECTION>
 <FILE>goocanvasitemmodel</FILE>
 GooCanvasItemModel
 GooCanvasItemModelIface
@@ -196,29 +208,9 @@ goo_canvas_item_model_get_parent
 goo_canvas_item_model_set_parent
 
 <SUBSECTION>
-goo_canvas_item_model_is_container
-goo_canvas_item_model_get_n_children
-goo_canvas_item_model_get_child
-goo_canvas_item_model_add_child
-goo_canvas_item_model_move_child
-goo_canvas_item_model_remove_child
-goo_canvas_item_model_find_child
-
-<SUBSECTION>
 goo_canvas_item_model_get_style
 goo_canvas_item_model_set_style
 
-<SUBSECTION>
-goo_canvas_item_model_class_install_child_property
-goo_canvas_item_model_class_list_child_properties
-goo_canvas_item_model_class_find_child_property
-goo_canvas_item_model_get_child_property
-goo_canvas_item_model_set_child_property
-goo_canvas_item_model_get_child_properties
-goo_canvas_item_model_get_child_properties_valist
-goo_canvas_item_model_set_child_properties
-goo_canvas_item_model_set_child_properties_valist
-
 <SUBSECTION Standard>
 GOO_CANVAS_ITEM_MODEL
 GOO_IS_CANVAS_ITEM_MODEL
@@ -228,6 +220,39 @@ GOO_CANVAS_ITEM_MODEL_GET_IFACE
 </SECTION>
 
 <SECTION>
+<FILE>goocanvascontainermodel</FILE>
+GooCanvasContainerModel
+GooCanvasContainerModelIface
+
+<SUBSECTION>
+goo_canvas_container_model_get_n_children
+goo_canvas_container_model_get_child
+goo_canvas_container_model_add_child
+goo_canvas_container_model_move_child
+goo_canvas_container_model_remove_child
+goo_canvas_container_model_find_child
+
+<SUBSECTION>
+goo_canvas_container_model_class_install_child_property
+goo_canvas_container_model_class_list_child_properties
+goo_canvas_container_model_class_find_child_property
+goo_canvas_container_model_get_child_property
+goo_canvas_container_model_set_child_property
+goo_canvas_container_model_get_child_properties
+goo_canvas_container_model_get_child_properties_valist
+goo_canvas_container_model_set_child_properties
+goo_canvas_container_model_set_child_properties_valist
+
+<SUBSECTION Standard>
+GOO_CANVAS_CONTAINER_MODEL
+GOO_IS_CANVAS_CONTAINER_MODEL
+GOO_TYPE_CANVAS_CONTAINER_MODEL
+goo_canvas_container_model_get_type
+GOO_CANVAS_CONTAINER_MODEL_GET_IFACE
+</SECTION>
+
+
+<SECTION>
 <FILE>goocanvasgroup</FILE>
 <TITLE>GooCanvasGroup</TITLE>
 GooCanvasGroup
Index: docs/goocanvas-docs.sgml
===================================================================
--- docs/goocanvas-docs.sgml	(revision 27)
+++ docs/goocanvas-docs.sgml	(working copy)
@@ -22,6 +22,8 @@
     <xi:include href="xml/goocanvas.xml"/>
     <xi:include href="xml/goocanvasitem.xml"/>
     <xi:include href="xml/goocanvasitemmodel.xml"/>
+    <xi:include href="xml/goocanvascontainer.xml"/>
+    <xi:include href="xml/goocanvascontainermodel.xml"/>
     <xi:include href="xml/goocanvasitemsimple.xml"/>
     <xi:include href="xml/goocanvasitemmodelsimple.xml"/>
     <xi:include href="xml/goocanvasstyle.xml"/>
