Index: Dev/branches/rest-dojo-ui/client/rft/pages/questions.html
===================================================================
--- Dev/branches/rest-dojo-ui/client/rft/pages/questions.html	(revision 303)
+++ Dev/branches/rest-dojo-ui/client/rft/pages/questions.html	(revision 305)
@@ -2,5 +2,5 @@
     <h1>Questions</h1>
     <div data-dojo-type="dijit.form.Button" data-rft-attach-event="onClick:onNewQuestion">New question</div>
-    <div data-dojo-type="rft.ui.TitleGroup" data-rft-attach-point="accordion">
+    <div data-rft-attach-point="list">
     </div>
     <div data-dojo-type="dijit.Dialog" title="Question" data-rft-attach-point="questionDialog">
Index: Dev/branches/rest-dojo-ui/client/rft/pages/questions.js
===================================================================
--- Dev/branches/rest-dojo-ui/client/rft/pages/questions.js	(revision 303)
+++ Dev/branches/rest-dojo-ui/client/rft/pages/questions.js	(revision 305)
@@ -1,6 +1,5 @@
-define(['dojo/_base/declare','dojo/_base/lang','dojo/_base/array','dojo/_base/event',
-    'dojo/_base/Deferred','dojo/dom-construct','rft/store','dijit/TitlePane',
-    'rft/ui/_Page','rft/ui/LineWithActionsWidget'],
-    function(declare,lang,array,event,Deferred,domConstruct,store,TitlePane,_Page,LineWithActionsWidget) {
+define(['dojo/_base/declare','dojo/_base/lang','dojo/_base/event',
+    'dojo/_base/Deferred','rft/store','rft/ui/_Page','rft/ui/AccordionList'],
+    function(declare,lang,event,Deferred,store,_Page,AccordionList) {
         return declare('rft.pages.questions',[_Page],{
             constructor: function() {
@@ -9,74 +8,18 @@
             },
             onVisit: function() {
-                this._store = store.getStore('Question');                
-                this._refresh(true);
+                this._store = store.getStore('Question');
+                this._list = new AccordionList({
+                    store: this._store,
+                    actions: {
+                        'Edit': lang.hitch(this,'_editQuestion')
+                    },
+                    categoryProperty: 'category',
+                    titleProperty: 'title'
+                },this.list);
+                this._list.startup();
+                this._refresh();
             },
-            _refresh: function(initial) {
-                Deferred.when( this._store.query() )
-                .then(lang.hitch(this,function(results){
-                    array.forEach(results,lang.hitch(this,'_addQuestion'));
-                    initial && this.accordion.selectChild(true);
-                }));
-            },
-            _addQuestion: function(q) {
-                var uid = q.getUid();
-                var question = this.questions[uid];
-                if ( !question ) {
-                    var qw = new LineWithActionsWidget({
-                        title: q.title,
-                        userObject: q,
-                        actions: {
-                            'Edit': lang.hitch(this,'_editQuestion')
-                        }
-                    });
-                    qw.startup();
-                    question = this.questions[uid] = {
-                        question: q,
-                        widget: qw
-                    }
-                } else {
-                    // update info
-                    question.question = q;
-                    question.widget.title = q.title;
-                    question.widget.userObject = q;
-                    question.widget.refresh();
-                }
-                var container = this._getContainerForQuestion(q);
-                question.widget.placeAt(container.containerNode);
-                this._cleanupEmptyContainers();
-            },
-            _getContainerForQuestion: function(q) {
-                var category = q.category || 'Unsorted';
-                var widgets = this.accordion.getChildren();
-                var containerWidget = null;
-                var placeNode = this.accordion.domNode;
-                var placePos = 'last';
-                array.some(widgets,lang.hitch(this,function(widget) {
-                    if ( widget.title == category ) {
-                        containerWidget = widget;
-                        return true;
-                    } else if ( widget.title > category  ) {
-                        placeNode = widget.domNode;
-                        placePos = "before";
-                        return true;
-                    }
-                    return false;
-                }));
-                if ( !containerWidget ) {
-                    containerWidget = new TitlePane({
-                        title:category
-                    });
-                    containerWidget.startup();
-                    domConstruct.place(containerWidget.domNode,placeNode,placePos);
-                }
-                return containerWidget;
-            },
-            _cleanupEmptyContainers: function() {
-                var widgets = this.accordion.getChildren();
-                array.forEach(widgets,lang.hitch(this,function(widget){
-                    if ( !widget.getChildren().length ) {
-                        this.accordion.removeChild(widget).destroy();
-                    }
-                }));
+            _refresh: function() {
+                this._list.refresh();
             },
             onNewQuestion: function() {
Index: Dev/branches/rest-dojo-ui/client/rft/ui/AccordionList.js
===================================================================
--- Dev/branches/rest-dojo-ui/client/rft/ui/AccordionList.js	(revision 305)
+++ Dev/branches/rest-dojo-ui/client/rft/ui/AccordionList.js	(revision 305)
@@ -0,0 +1,108 @@
+define(['dojo/_base/declare','dojo/_base/lang','dojo/_base/array',
+    'dojo/_base/Deferred','dojo/dom-construct','dijit/_WidgetBase',
+    'dijit/_TemplatedMixin','dijit/_WidgetsInTemplateMixin','dijit/TitlePane',
+    'rft/ui/LineWithActionsWidget','dojo/text!rft/ui/templates/AccordionList.html'],
+    function(declare,lang,array,
+        Deferred,domConstruct,_WidgetBase,
+        _TemplatedMixin,_WidgetsInTemplateMixin,TitlePane,
+        LineWithActionsWidget,template){
+        return declare('rft.ui.AccordionList',[_WidgetBase,_TemplatedMixin,_WidgetsInTemplateMixin],{
+            templateString: template,
+            store: null,
+            idProperty: null,
+            categoryProperty: null,
+            titleProperty: null,
+            actions: null,
+            _widgets: null,
+            constructor: function() {
+                this._widgets = {};
+            },
+            postCreate: function() {
+                this.idProperty = this.idProperty || this.store.idProperty;
+                this.refresh(true);
+            },
+            refresh: function(initial) {
+                Deferred.when( this.store.query() )
+                .then(lang.hitch(this,'_addItems',initial));
+            },
+            _addItems: function(initial,items) {
+                var newWidgets = {};
+                array.forEach(this._widgets,domConstruct.destroy); // get everything out of the dom
+                array.forEach(items,lang.hitch(this,function(item){
+                    var widget = this._getWidgetForItem(item);
+                    var id = this._getItemProperty(this.idProperty,item);
+                    var container = this._getContainerForItem(item);
+                    widget.placeAt(container.containerNode);
+                    newWidgets[id] = widget;
+                }));
+                var oldWidgets = array.filter(this.items,function(widget){
+                    return array.indexOf(newWidgets,widget) < 0;
+                });
+                array.forEach(oldWidgets,function(widget){
+                    widget.destroy();
+                });
+                this._widgets = newWidgets; // overwrite, releasing any non-existing items
+                initial && this.accordion.selectChild(true);
+                this._cleanupEmptyContainers();
+            },
+            _getWidgetForItem: function(item) {
+                var id = this._getItemProperty(this.idProperty,item);
+                var widget = this._widgets[id];
+                if ( !widget ) {
+                    widget = new LineWithActionsWidget({
+                        title: this._getItemProperty(this.titleProperty,item),
+                        userObject: item,
+                        actions: this.actions
+                    });
+                    widget.startup();
+                    this._widgets[id] = widget;
+                } else {
+                    widget.title = this._getItemProperty(this.titleProperty,item);
+                    widget.userObject = item;
+                    widget.refresh();
+                }
+                return widget;
+            },
+            _getContainerForItem: function(item) {
+                var category = this._getItemProperty(this.categoryProperty,item) || 'Unsorted';
+                var widgets = this.accordion.getChildren();
+                var containerWidget = null;
+                var placeNode = this.accordion.domNode;
+                var placePos = 'last';
+                array.some(widgets,lang.hitch(this,function(widget) {
+                    if ( widget.title == category ) {
+                        containerWidget = widget;
+                        return true;
+                    } else if ( widget.title > category  ) {
+                        placeNode = widget.domNode;
+                        placePos = "before";
+                        return true;
+                    }
+                    return false;
+                }));
+                if ( !containerWidget ) {
+                    containerWidget = new TitlePane({
+                        title:category
+                    });
+                    containerWidget.startup();
+                    domConstruct.place(containerWidget.domNode,placeNode,placePos);
+                }
+                return containerWidget;
+            },
+            _cleanupEmptyContainers: function() {
+                var widgets = this.accordion.getChildren();
+                array.forEach(widgets,lang.hitch(this,function(widget){
+                    if ( !widget.getChildren().length ) {
+                        this.accordion.removeChild(widget).destroy();
+                    }
+                }));
+            },
+            _getItemProperty: function(property,item) {
+                if ( lang.isFunction(property) ) {
+                    return property(item);
+                } else {
+                    return item[property];
+                }
+            }
+        });
+    });
Index: Dev/branches/rest-dojo-ui/client/rft/ui/QuestionWidget.js
===================================================================
--- Dev/branches/rest-dojo-ui/client/rft/ui/QuestionWidget.js	(revision 303)
+++ Dev/branches/rest-dojo-ui/client/rft/ui/QuestionWidget.js	(revision 305)
@@ -28,5 +28,5 @@
                 var value = this.ourForm.get('value');
                 lang.mixin(this.value,value);
-                return this._question;
+                return this.value;
             },
             _onTypeChange: function(type) {
Index: Dev/branches/rest-dojo-ui/client/rft/ui/templates/AccordionList.html
===================================================================
--- Dev/branches/rest-dojo-ui/client/rft/ui/templates/AccordionList.html	(revision 305)
+++ Dev/branches/rest-dojo-ui/client/rft/ui/templates/AccordionList.html	(revision 305)
@@ -0,0 +1,4 @@
+<div>
+    <div data-dojo-type="rft.ui.TitleGroup" data-dojo-attach-point="accordion">
+    </div>
+</div>
