diff --git a/IPython/html/static/notebook/js/widgets/widget.js b/IPython/html/static/notebook/js/widgets/widget.js
index 4b3fe06..95fca66 100644
--- a/IPython/html/static/notebook/js/widgets/widget.js
+++ b/IPython/html/static/notebook/js/widgets/widget.js
@@ -226,31 +226,18 @@ function(widget_manager, underscore, backbone){
             // triggered on model change
         },
 
-        child_view: function(child_model, options) {
+        create_child_view: function(child_model, options) {
             // create and return a child view, given a model and (optionally) a view name
             // if the view name is not given, it defaults to the model's default view attribute
             var child_view = this.model.widget_manager.create_view(child_model, options);
             this.child_views[child_model.id] = child_view;
             return child_view;
         },
-        
-        update_child_views: function(old_list, new_list) {
-            // this function takes an old list and new list of models
-            // views in child_views that correspond to deleted ids are deleted
-            // views corresponding to added ids are added child_views
-        
-            // delete old views
-            _.each(_.difference(old_list, new_list), function(element, index, list) {
-                var view = this.child_views[element.id];
-                delete this.child_views[element.id];
-                view.remove();
-            }, this);
-            
-            // add new views
-            _.each(_.difference(new_list, old_list), function(element, index, list) {
-                // this function adds the view to the child_views dictionary
-                this.child_view(element);
-            }, this);
+
+        delete_child_view: function(child_model, options) {
+            var view = this.child_views[child_model.id];
+            delete this.child_views[child_model.id];
+            view.remove();
         },
 
         do_diff: function(old_list, new_list, removed_callback, added_callback) {
diff --git a/IPython/html/static/notebook/js/widgets/widget_container.js b/IPython/html/static/notebook/js/widgets/widget_container.js
index e69ff36..88ad035 100644
--- a/IPython/html/static/notebook/js/widgets/widget_container.js
+++ b/IPython/html/static/notebook/js/widgets/widget_container.js
@@ -29,11 +29,20 @@ define(["notebook/js/widgets/widget"], function(widget_manager) {
         },
         
         update_children: function(old_list, new_list) {
-            this.$el.empty();
-            this.update_child_views(old_list, new_list);
-            _.each(new_list, function(element, index, list) {
-                this.$el.append(this.child_views[element.id].$el);
-            }, this)
+            this.do_diff(old_list, 
+                new_list, 
+                $.proxy(this.remove_child_model, this),
+                $.proxy(this.add_child_model, this));
+        },
+
+        remove_child_model: function(model) {
+            this.child_views[model.id].remove();
+            this.delete_child_view(model);
+        },
+
+        add_child_model: function(model) {
+            var view = this.create_child_view(model);
+            this.$el.append(view.$el);
         },
         
         update: function(){
@@ -188,11 +197,20 @@ define(["notebook/js/widgets/widget"], function(widget_manager) {
         },
         
         update_children: function(old_list, new_list) {
-            this.$el.empty();
-            this.update_child_views(old_list, new_list);
-            _.each(new_list, function(element, index, list) {
-                this.$body.append(this.child_views[element].$el);
-            }, this)
+            this.do_diff(old_list, 
+                new_list, 
+                $.proxy(this.remove_child_model, this),
+                $.proxy(this.add_child_model, this));
+        },
+
+        remove_child_model: function(model) {
+            this.child_views[model.id].remove();
+            this.delete_child_view(model);
+        },
+
+        add_child_model: function(model) {
+            var view = this.create_child_view(model);
+            this.$body.append(view.$el);
         },
         
         update: function(){
diff --git a/IPython/html/static/notebook/js/widgets/widget_selectioncontainer.js b/IPython/html/static/notebook/js/widgets/widget_selectioncontainer.js
index 46dc3e4..e0a4e31 100644
--- a/IPython/html/static/notebook/js/widgets/widget_selectioncontainer.js
+++ b/IPython/html/static/notebook/js/widgets/widget_selectioncontainer.js
@@ -23,24 +23,13 @@ define(["notebook/js/widgets/widget"], function(widget_manager){
                 .attr('id', guid)
                 .addClass('accordion');
             this.containers = [];
+            this.model_containers = {};
             this.update_children([], this.model.get('children'));
             this.model.on('change:children', function(model, value, options) {
                 this.update_children(model.previous('children'), value);
             }, this);
         },
         
-        update_children: function(old_list, new_list) {
-            _.each(this.containers, function(element, index, list) {
-                element.remove();
-            }, this);
-            this.containers = [];
-            this.update_child_views(old_list, new_list);
-            _.each(new_list, function(element, index, list) {
-                this.add_child_view(this.child_views[element]);
-            }, this)
-        },
-        
-
         update: function(options) {
             // Update the contents of this view
             //
@@ -76,9 +65,24 @@ define(["notebook/js/widgets/widget"], function(widget_manager){
             }
             return AccordionView.__super__.update.apply(this);
         },
+        
+        update_children: function(old_list, new_list) {
+            this.do_diff(old_list, 
+                new_list, 
+                $.proxy(this.remove_child_model, this),
+                $.proxy(this.add_child_model, this));
+        },
 
-        add_child_view: function(view) {
+        remove_child_model: function(model) {
+            var accordion_group = this.model_containers[model.id];
+            this.containers.splice(accordion_group.container_index, 1);
+            delete this.model_containers[model.id];
+            accordion_group.remove();
+            this.delete_child_view(model);
+        },
 
+        add_child_model: function(model) {
+            var view = this.create_child_view(model);
             var index = this.containers.length;
             var uuid = IPython.utils.uuid();
             var accordion_group = $('<div />')
@@ -108,7 +112,9 @@ define(["notebook/js/widgets/widget"], function(widget_manager){
             var accordion_inner = $('<div />')
                 .addClass('accordion-inner')
                 .appendTo(accordion_body);
-            this.containers.push(accordion_group);
+            var container_index = this.containers.push(accordion_group) - 1;
+            accordion_group.container_index = container_index;
+            this.model_containers[model.id] = accordion_group;
             accordion_inner.append(view.$el);
 
             this.update();
@@ -157,31 +163,25 @@ define(["notebook/js/widgets/widget"], function(widget_manager){
                 this.add_child_view(this.child_views[element]);
             }, this)
         },
+        
+        update_children: function(old_list, new_list) {
+            this.do_diff(old_list, 
+                new_list, 
+                $.proxy(this.remove_child_model, this),
+                $.proxy(this.add_child_model, this));
+        },
 
-        update: function(options) {
-            // Update the contents of this view
-            //
-            // Called when the model is changed.  The model may have been 
-            // changed by another view or by a state update from the back-end.
-            if (options === undefined || options.updated_view != this) {
-                // Set tab titles
-                var titles = this.model.get('_titles');
-                for (var page_index in titles) {
-                    var tab_text = this.containers[page_index];
-                    if (tab_text !== undefined) {
-                        tab_text.html(titles[page_index]);
-                    }
-                }
-
-                var selected_index = this.model.get('selected_index');
-                if (0 <= selected_index && selected_index < this.containers.length) {
-                    this.select_page(selected_index);
-                }
-            }
-            return TabView.__super__.update.apply(this);
+        remove_child_model: function(model) {
+            var view = this.child_views[model.id];
+            this.containers.splice(view.parent_tab.tab_text_index, 1);
+            view.parent_tab.remove();
+            view.parent_container.remove();
+            view.remove();
+            this.delete_child_view(model);
         },
 
-        add_child_view: function(view) {
+        add_child_model: function(model) {
+            var view = this.create_child_view(model);
             var index = this.containers.length;
             var uuid = IPython.utils.uuid();
 
@@ -189,6 +189,8 @@ define(["notebook/js/widgets/widget"], function(widget_manager){
             var tab = $('<li />')
                 .css('list-style-type', 'none')
                 .appendTo(this.$tabs);
+            view.parent_tab = tab;
+
             var tab_text = $('<a />')
                 .attr('href', '#' + uuid)
                 .attr('data-toggle', 'tab') 
@@ -202,13 +204,37 @@ define(["notebook/js/widgets/widget"], function(widget_manager){
                     that.touch();
                     that.select_page(index);
                 });
-            this.containers.push(tab_text);
+            tab.tab_text_index = this.containers.push(tab_text) - 1;
 
             var contents_div = $('<div />', {id: uuid})
                 .addClass('tab-pane')
                 .addClass('fade')
                 .append(view.$el)
                 .appendTo(this.$tab_contents);
+            view.parent_container = contents_div;
+        },
+
+        update: function(options) {
+            // Update the contents of this view
+            //
+            // Called when the model is changed.  The model may have been 
+            // changed by another view or by a state update from the back-end.
+            if (options === undefined || options.updated_view != this) {
+                // Set tab titles
+                var titles = this.model.get('_titles');
+                for (var page_index in titles) {
+                    var tab_text = this.containers[page_index];
+                    if (tab_text !== undefined) {
+                        tab_text.html(titles[page_index]);
+                    }
+                }
+
+                var selected_index = this.model.get('selected_index');
+                if (0 <= selected_index && selected_index < this.containers.length) {
+                    this.select_page(selected_index);
+                }
+            }
+            return TabView.__super__.update.apply(this);
         },
 
         select_page: function(index) {
diff --git a/IPython/html/widgets/widget_selectioncontainer.py b/IPython/html/widgets/widget_selectioncontainer.py
index 3283e31..d20dcad 100644
--- a/IPython/html/widgets/widget_selectioncontainer.py
+++ b/IPython/html/widgets/widget_selectioncontainer.py
@@ -27,7 +27,7 @@ class AccordionWidget(DOMWidget):
     _titles = Dict(help="Titles of the pages", sync=True)
     selected_index = Int(0, sync=True)
 
-    children = List(Instance(DOMWidget))
+    children = List(Instance(DOMWidget), sync=True)
 
     # Public methods
     def set_title(self, index, title):