Index: /Dev/trunk/src/client/qed-client/css/qed.less
===================================================================
--- /Dev/trunk/src/client/qed-client/css/qed.less	(revision 493)
+++ /Dev/trunk/src/client/qed-client/css/qed.less	(revision 494)
@@ -22,4 +22,5 @@
 @import "ui/MainMenu.less";
 @import "ui/topbar.less";
+@import "ui/LoginDialog.less";
 @import "widgets/MultipleChoiceWidget.less";
 @import "widgets/lists/List.less";
Index: /Dev/trunk/src/client/qed-client/css/ui/LoginDialog.less
===================================================================
--- /Dev/trunk/src/client/qed-client/css/ui/LoginDialog.less	(revision 494)
+++ /Dev/trunk/src/client/qed-client/css/ui/LoginDialog.less	(revision 494)
@@ -0,0 +1,8 @@
+#rft.claro #loginDialog .infoField {
+
+    display: inline-block;
+    padding-top: 1px;
+    vertical-align: middle;
+    color: @disabledtext;
+
+}
Index: /Dev/trunk/src/client/qed-client/model/widgets/SurveyRunWidget.js
===================================================================
--- /Dev/trunk/src/client/qed-client/model/widgets/SurveyRunWidget.js	(revision 493)
+++ /Dev/trunk/src/client/qed-client/model/widgets/SurveyRunWidget.js	(revision 494)
@@ -9,7 +9,7 @@
         postCreate: function() {
             var endDateBox = this.endDateBox;
-            this.startDateBox.on('change', function(value){
+            this.own(this.startDateBox.on('change', function(value){
                 endDateBox.constraints.min  = value;
-            });
+            }));
         },
         _getValueAttr: function() {
Index: /Dev/trunk/src/client/qed-client/model/widgets/questions/MultipleChoiceInputConfigWidget.js
===================================================================
--- /Dev/trunk/src/client/qed-client/model/widgets/questions/MultipleChoiceInputConfigWidget.js	(revision 493)
+++ /Dev/trunk/src/client/qed-client/model/widgets/questions/MultipleChoiceInputConfigWidget.js	(revision 494)
@@ -52,7 +52,11 @@
         _getValueAttr: function() {
             var value = this.inherited(arguments);
+            value.type = this.type;
             value.allowMultiple = value.allowMultiple.length > 0;
-            value.type = this.type;
             return value;
+        },
+        _setValueAttr: function(value) {
+            value.allowMultiple = value.allowMultiple ? ["on"] : [];
+            return this.inherited(arguments);
         },
         onAddItem: function(evt) {
Index: /Dev/trunk/src/client/qed-client/pages/index.js
===================================================================
--- /Dev/trunk/src/client/qed-client/pages/index.js	(revision 493)
+++ /Dev/trunk/src/client/qed-client/pages/index.js	(revision 494)
@@ -15,10 +15,10 @@
             //this.btnContentCreate.on("click",function(){ Router.go("/sessions"); });
             //this.btnContentFacilitate.on("click",function(){ Router.go("/run"); });
-            this.btnSurveys.on("click",function(){
+            this.own(this.btnSurveys.on("click",function(){
                 Router.go(surveys.getCollectionPath());
-            });
-            this.btnQuestions.on("click",function(){
+            }));
+            this.own(this.btnQuestions.on("click",function(){
                 Router.go(questions.getCollectionPath());
-            });
+            }));
             //this.btnApplications.on("click",function(){Router.go("/applications");});
             //this.btnDashboards.on("click",function(){ Router.go("/dashboards"); });
Index: /Dev/trunk/src/client/qed-client/pages/question.js
===================================================================
--- /Dev/trunk/src/client/qed-client/pages/question.js	(revision 493)
+++ /Dev/trunk/src/client/qed-client/pages/question.js	(revision 494)
@@ -19,6 +19,6 @@
             if ( this._started ) { return; }
             this.inherited(arguments);
-            this.propertiesForm.on('change',lang.hitch(this,'_handlePropertiesChange'));
-            this.contentList.on('change',lang.hitch(this,'_handleContentChange'));
+            this.own(this.propertiesForm.on('change',lang.hitch(this,'_handlePropertiesChange')));
+            this.own(this.contentList.on('change',lang.hitch(this,'_handleContentChange')));
             this._load();
         },
@@ -40,11 +40,7 @@
         _updateObject: function() {
             var pValid = this.propertiesForm.validate();
-            if ( pValid ) {
-                lang.mixin(this.object,this.propertiesForm.get('value'));
-            }
+            lang.mixin(this.object,this.propertiesForm.get('value'));
             var cValid = this.contentList.validate();
-            if ( cValid ) {
-                this.object.content = this.contentList.get('value');
-            }
+            this.object.content = this.contentList.get('value');
             this._isValid = pValid && cValid;
             return this._isValid;
Index: /Dev/trunk/src/client/qed-client/pages/survey.js
===================================================================
--- /Dev/trunk/src/client/qed-client/pages/survey.js	(revision 493)
+++ /Dev/trunk/src/client/qed-client/pages/survey.js	(revision 494)
@@ -23,5 +23,5 @@
             this._setupQuestionBrowser();
             this._setupListView();
-            this.questionList.on('change',lang.hitch(this,'_handleQuestionsChange'));
+            this.own(this.questionList.on('change',lang.hitch(this,'_handleQuestionsChange')));
             this._load();
         },
Index: /Dev/trunk/src/client/qed-client/pages/surveyRun.js
===================================================================
--- /Dev/trunk/src/client/qed-client/pages/surveyRun.js	(revision 493)
+++ /Dev/trunk/src/client/qed-client/pages/surveyRun.js	(revision 494)
@@ -26,5 +26,5 @@
             if ( this._started ) { return; }
             this.inherited(arguments);
-            this.surveyRunWidget.on("change",lang.hitch(this,'_onPropChange'));
+            this.own(this.surveyRunWidget.on("change",lang.hitch(this,'_onPropChange')));
             this._load();
         },
@@ -98,7 +98,5 @@
         _updateObject: function() {
             this._isValid = this.surveyRunWidget.validate();
-            if ( this._isValid ) {
-                lang.mixin(this.object,this.surveyRunWidget.get('value'));
-            }
+            lang.mixin(this.object,this.surveyRunWidget.get('value'));
             return this._isValid;
         },
Index: v/trunk/src/client/qed-client/session.coffee
===================================================================
--- /Dev/trunk/src/client/qed-client/session.coffee	(revision 493)
+++ 	(revision )
@@ -1,50 +1,0 @@
-define [
-    "dojo/_base/declare",
-    "dojo/_base/json",
-    "dojo/Deferred",
-    "dojo/Evented",
-    "dojo/request"
-], (declare, json, Deferred, Evented, request) ->
-    Session = declare [Evented],
-        info: null
-
-        get: () ->
-            @info
-
-        restore: () ->
-            request '/api/login',
-                method: "GET"
-                handleAs: "json"
-            .then (res) =>
-                @_set res
-            , () =>
-                new Deferred().reject (@_set null)
-
-        login: (username, password) ->
-            request '/api/login',
-                method: "POST"
-                handleAs: "json"
-                data:
-                    username: username
-                    password: password
-            .then (res) =>
-                @_set res
-            , () =>
-                new Deferred().reject (@_set null)
-
-        logout: () ->
-            request '/api/logout',
-                method: "POST"
-                handleAs: "json"
-            .then (res) =>
-                @_set null
-            , () =>
-                @_set null
-        
-        _set: (newInfo) ->
-            if (newInfo isnt @info)
-                @info = newInfo
-                @emit 'change', @info
-            @info
-
-    new Session()
Index: /Dev/trunk/src/client/qed-client/session.js
===================================================================
--- /Dev/trunk/src/client/qed-client/session.js	(revision 494)
+++ /Dev/trunk/src/client/qed-client/session.js	(revision 494)
@@ -0,0 +1,58 @@
+define([
+    "dojo/Deferred",
+    "dojo/Evented",
+    "dojo/_base/declare",
+    "dojo/_base/json",
+    "dojo/_base/lang",
+    "dojo/request"
+], function(Deferred, Evented, declare, json, lang, request) {
+    var Session = declare([Evented], {
+        info: null,
+        get: function() {
+            return this.info;
+        },
+        restore: function() {
+            return request('/api/login', {
+                method: "GET",
+                handleAs: "json"
+            }).then(lang.hitch(this,function(res) {
+                return this._set(res);
+            }), lang.hitch(this,function() {
+                return new Deferred().reject(this._set(null));
+            }));
+        },
+        login: function(username, password) {
+            return request('/api/login', {
+                method: "POST",
+                handleAs: "json",
+                data: {
+                    username: username,
+                    password: password
+                }
+            }).then(lang.hitch(this,function(res) {
+                return this._set(res);
+            }), lang.hitch(this,function() {
+                return new Deferred().reject(this._set(null));
+            }));
+        },
+        logout: function() {
+            return request('/api/logout', {
+                method: "POST",
+                handleAs: "json"
+            }).then(lang.hitch(this,function(res) {
+                return this._set(null);
+            }), lang.hitch(this,function() {
+                return this._set(null);
+            }));
+        },
+        _set: function(newInfo) {
+            if (newInfo !== this.info) {
+                this.info = newInfo;
+                this.emit('change', this.info);
+            }
+            return this.info;
+        }
+    });
+
+    return new Session();
+});
Index: v/trunk/src/client/qed-client/ui/LoginDialogWrapper.coffee
===================================================================
--- /Dev/trunk/src/client/qed-client/ui/LoginDialogWrapper.coffee	(revision 493)
+++ 	(revision )
@@ -1,43 +1,0 @@
-define [
-    "../session",
-    "dijit/_WidgetBase",
-    "dijit/_TemplatedMixin",
-    "dijit/_WidgetsInTemplateMixin",
-    "dijit/registry",
-    "dojo/_base/declare",
-    "dojo/_base/event",
-    "dojo/_base/lang",
-    "dojo/on",
-    "dojo/when",
-    "dojo/text!./templates/LoginDialogWrapper.html"
-], (session, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin,
-    registry, declare, event, lang, _on, _when, template) ->
-    declare [_WidgetBase,_TemplatedMixin,_WidgetsInTemplateMixin],
-        templateString: template
-        _fx: null
-        startup: () ->
-            if @_started then return
-            @inherited arguments
-            _on session, 'change', (lang.hitch @, 'onUserChange')
-            @onUserChange session.get()
-        onLogin: (evt) ->
-            if @loginForm.validate()
-                value = @loginForm.get 'value'
-                session.login value.username,
-                              value.password
-                .then () =>
-                    @_fx = _when(@_fx)
-                    .then () =>
-                        @loginDialog.hide()
-                , () =>
-                    alert "Login failed!"
-            event.stop evt if evt
-            false
-        onUserChange: (user) ->
-            @_fx = _when(@_fx)
-            .then () =>
-                if user
-                    @loginDialog.hide()
-                else
-                    @loginDialog.show()
-            null
Index: /Dev/trunk/src/client/qed-client/ui/LoginDialogWrapper.js
===================================================================
--- /Dev/trunk/src/client/qed-client/ui/LoginDialogWrapper.js	(revision 494)
+++ /Dev/trunk/src/client/qed-client/ui/LoginDialogWrapper.js	(revision 494)
@@ -0,0 +1,36 @@
+define(["../session", "dijit/_WidgetBase", "dijit/_TemplatedMixin", "dijit/_WidgetsInTemplateMixin", "dijit/registry", "dojo/_base/declare", "dojo/_base/event", "dojo/_base/lang", "dojo/on", "dojo/when", "dojo/text!./templates/LoginDialogWrapper.html"], function(session, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, registry, declare, event, lang, on, when, template) {
+    return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
+        templateString: template,
+        _fx: null,
+        startup: function() {
+            if (this._started) { return; }
+            this.inherited(arguments);
+            this.own(on(session, 'change', lang.hitch(this, 'onUserChange')));
+            this.own(this.loginForm.on('change', lang.hitch(this, '_handleFormChange')));
+            this.onUserChange(session.get());
+        },
+        _handleFormChange: function() {
+            this.infoNode.innerHTML = "";
+        },
+        onLogin: function(evt) {
+            this.infoNode.innerHTML = "";
+            if (this.loginForm.validate()) {
+                var value = this.loginForm.get('value');
+                session.login(value.username, value.password)
+                .then(lang.hitch(this,function() {
+                    this._fx = when(this._fx).then(lang.hitch(this.loginDialog,'hide'));
+                }), lang.hitch(this,function() {
+                    this.infoNode.innerHTML = "Login failed.";
+                }));
+            }
+            if (evt) { event.stop(evt); }
+            return false;
+        },
+        onUserChange: function(user) {
+            this.infoNode.innerHTML = "";
+            this._fx = when(this._fx).then(lang.hitch(this.loginDialog,function() {
+                return user ? this.hide() : this.show();
+            }));
+        }
+    });
+});
Index: v/trunk/src/client/qed-client/ui/SessionMenu.coffee
===================================================================
--- /Dev/trunk/src/client/qed-client/ui/SessionMenu.coffee	(revision 493)
+++ 	(revision )
@@ -1,30 +1,0 @@
-define [
-    "../session",
-    "./LoginDialogWrapper",
-    "dijit/MenuBarItem",
-    "dojo/_base/declare",
-    "dojo/_base/event",
-    "dojo/on"
-], (session, LoginDialogWrapper, MenuBarItem, declare, event, _on) ->
-    declare [MenuBarItem],
-        info: null
-        postCreate: () ->
-            @set 'label', "Login"
-        startup: () ->
-            if @_started then return
-            @inherited arguments
-            @_update session.get()
-            _on session, 'change', (info) => @_update info
-        _update: (info) ->
-            @info = info
-            if info
-                @set 'label', "Logout, "+info.username
-            else
-                @set 'label', "Login"
-        onClick: (evt) ->
-            if @info
-                session.logout()
-            else
-                LoginDialogWrapper.show()
-            event.stop evt if evt
-            false
Index: /Dev/trunk/src/client/qed-client/ui/SessionMenu.js
===================================================================
--- /Dev/trunk/src/client/qed-client/ui/SessionMenu.js	(revision 494)
+++ /Dev/trunk/src/client/qed-client/ui/SessionMenu.js	(revision 494)
@@ -0,0 +1,41 @@
+define([
+    "../session",
+    "./LoginDialogWrapper",
+    "dijit/MenuBarItem",
+    "dojo/_base/declare",
+    "dojo/_base/event",
+    "dojo/_base/lang",
+    "dojo/on"
+], function(session, LoginDialogWrapper, MenuBarItem, declare, event, lang, on) {
+    return declare([MenuBarItem], {
+        info: null,
+        postCreate: function() {
+            return this.set('label', "Login");
+        },
+        startup: function() {
+            if (this._started) { return; }
+            this.inherited(arguments);
+            this._update(session.get());
+            this.own(on(session, 'change', lang.hitch(this,function(info) {
+                return this._update(info);
+            })));
+        },
+        _update: function(info) {
+            this.info = info;
+            if (info) {
+                return this.set('label', "Logout, " + info.username);
+            } else {
+                return this.set('label', "Login");
+            }
+        },
+        onClick: function(evt) {
+            if (this.info) {
+                session.logout();
+            } else {
+                LoginDialogWrapper.show();
+            }
+            if (evt) { event.stop(evt); }
+            return false;
+        }
+    });
+});
Index: /Dev/trunk/src/client/qed-client/ui/templates/LoginDialogWrapper.html
===================================================================
--- /Dev/trunk/src/client/qed-client/ui/templates/LoginDialogWrapper.html	(revision 493)
+++ /Dev/trunk/src/client/qed-client/ui/templates/LoginDialogWrapper.html	(revision 494)
@@ -23,7 +23,11 @@
                    data-dojo-props="required: true"></div>
             </div>
-            <div data-dojo-type="dijit/form/Button"
-                 type="submit"
-                 data-dojo-attach-event="onClick:onLogin">Login</div>
+            <div>
+                <div data-dojo-type="dijit/form/Button"
+                     type="submit"
+                     data-dojo-attach-event="onClick:onLogin">Login</div>
+                <div class="infoField"
+                     data-dojo-attach-point="infoNode"></div>
+            </div>
         </form>
     </div>
Index: /Dev/trunk/src/client/qed-client/widgets/LineWithActionsWidget.js
===================================================================
--- /Dev/trunk/src/client/qed-client/widgets/LineWithActionsWidget.js	(revision 493)
+++ /Dev/trunk/src/client/qed-client/widgets/LineWithActionsWidget.js	(revision 494)
@@ -21,5 +21,5 @@
         postCreate: function() {
             dom.setSelectable(this.domNode, false); // Text selection, has nothing to do with object selection!
-            on(this.domNode,'click',lang.hitch(this,'_onClick'));
+            this.own(on(this.domNode,'click',lang.hitch(this,'_onClick')));
         },
         startup: function() {
Index: /Dev/trunk/src/client/qed-client/widgets/ListWidget.js
===================================================================
--- /Dev/trunk/src/client/qed-client/widgets/ListWidget.js	(revision 493)
+++ /Dev/trunk/src/client/qed-client/widgets/ListWidget.js	(revision 494)
@@ -50,5 +50,5 @@
             });
             this.source = new this.container(this.domNode,sourceParams);
-            this.source.on('Drop',lang.hitch(this,'_handleChange'));
+            this.own(this.source.on('Drop',lang.hitch(this,'_handleChange')));
         },
         creator: function(item, hint) {
@@ -68,5 +68,5 @@
                 }
             }
-            on(nodeOrWidget,'change',lang.hitch(this,'_handleChange'));
+            this.own(on(nodeOrWidget,'change',lang.hitch(this,'_handleChange')));
             var node = nodeOrWidget.domNode ? nodeOrWidget.domNode : nodeOrWidget;
             if ( hint !== "avatar" && node.id !== id ) {
Index: /Dev/trunk/src/client/qed-client/widgets/Selector.js
===================================================================
--- /Dev/trunk/src/client/qed-client/widgets/Selector.js	(revision 493)
+++ /Dev/trunk/src/client/qed-client/widgets/Selector.js	(revision 494)
@@ -105,5 +105,5 @@
             },this.selectedItemNode);
             this._selectorLine.startup();
-            this._selectorLine.on('click',lang.hitch(this, this.onToggle));
+            this.own(this._selectorLine.on('click',lang.hitch(this, 'onToggle')));
         },
         _createSource: function() {
@@ -210,5 +210,5 @@
             });
             w.startup();
-            w.on("click", lang.hitch(this, this._onSelect, item, w));
+            this.own(w.on("click", lang.hitch(this, '_onSelect', item, w)));
             return w.domNode;
         },
Index: v/trunk/src/server/util/couch.coffee
===================================================================
--- /Dev/trunk/src/server/util/couch.coffee	(revision 493)
+++ 	(revision )
@@ -1,81 +1,0 @@
-request = require './q-request'
-_ = require 'underscore'
-Q = require 'q'
-
-class CouchError extends Error
- 
-class CouchDB
-    constructor: (url,db) ->
-        @serverURL = normalizeURL url
-        @db = db
-        if @db
-            @url = "#{@serverURL}/#{@db}"
-        else
-            @url = "#{@serverURL}"
-    get: (id, opts) ->
-        url = "#{@url}/#{id}"
-        couchRequest 'GET', url, null, opts
-    post: (doc, opts) ->
-        url = "#{@url}/"
-        couchRequest 'POST', url, doc, opts
-    put: (id, doc, opts) ->
-        url = "#{@url}/#{id}"
-        couchRequest 'PUT', url, doc, opts
-    delete: (id, opts) ->
-        url = "#{@url}/#{id}"
-        couchRequest 'DELETE', url, null, opts
-    uuids: (opts) ->
-        url = "#{@serverURL}/_uuids"
-        couchRequest 'GET', url, null, opts
-
-normalizeURL = (url) ->
-    url.replace /\/$/, ''
-
-couchRequest = (method, url, body, opts) ->
-    options =
-        method: method,
-        headers:
-            'Content-Type': 'application/json; charset=utf-8'
-            'Accept': 'application/json'
-        body: JSON.stringify (stringifyFunctions (body || {}))
-    if opts
-        options.qs = createQueryObj opts.query if opts.query
-        _.extend options.headers, opts.headers if opts.headers
-    req = request(url, options)
-    res = req.response.then (res) =>
-        req.then (res) =>
-            JSON.parse res
-        , (err) =>
-            Q.reject (JSON.parse err)
-    , (err) =>
-        Q.reject err
-    res.response = req.response.then (res) =>
-        statusCode: res.statusCode
-        headers: res.headers
-        body: JSON.parse res.body
-    , (err) =>
-        Q.reject err
-    res
-
-createQueryObj = (obj) ->
-    newObj = {}
-    _.each obj, (val,key) ->
-        newObj[key] = JSON.stringify val
-    newObj
-        
-stringifyFunctions = (value) ->
-    if value is null
-        null
-    else if _.isArray value
-        value
-    else if _.isFunction value
-        value.toString()
-    else if _.isObject value
-        value = _.clone value
-        _.each value, (propValue, propName) =>
-            value[propName] = stringifyFunctions propValue
-        value
-    else
-        value
-
-exports.CouchDB = CouchDB
Index: /Dev/trunk/src/server/util/couch.js
===================================================================
--- /Dev/trunk/src/server/util/couch.js	(revision 494)
+++ /Dev/trunk/src/server/util/couch.js	(revision 494)
@@ -0,0 +1,110 @@
+var CouchDB, _ref,
+  __hasProp = {}.hasOwnProperty;
+
+var request = require('./q-request')
+  , _ = require('underscore')
+  , Q = require('q');
+
+function CouchDB(url, db) {
+    this.serverURL = normalizeURL(url);
+    this.db = db;
+    if (this.db) {
+        this.url = "" + this.serverURL + "/" + this.db;
+    } else {
+        this.url = "" + this.serverURL;
+    }
+}
+
+CouchDB.prototype.get = function(id, opts) {
+    var url = "" + this.url + "/" + id;
+    return couchRequest('GET', url, null, opts);
+};
+
+CouchDB.prototype.post = function(doc, opts) {
+    var url = "" + this.url + "/";
+    return couchRequest('POST', url, doc, opts);
+};
+
+CouchDB.prototype.put = function(id, doc, opts) {
+    var url = "" + this.url + "/" + id;
+    return couchRequest('PUT', url, doc, opts);
+};
+
+CouchDB.prototype["delete"] = function(id, opts) {
+    var url = "" + this.url + "/" + id;
+    return couchRequest('DELETE', url, null, opts);
+};
+
+CouchDB.prototype.uuids = function(opts) {
+    var url = "" + this.serverURL + "/_uuids";
+    return couchRequest('GET', url, null, opts);
+};
+
+function normalizeURL(url) {
+    return url.replace(/\/$/, '');
+}
+
+function couchRequest (method, url, body, opts) {
+    var options = {
+        method: method,
+        headers: {
+            'Content-Type': 'application/json; charset=utf-8',
+            'Accept': 'application/json'
+        },
+        body: JSON.stringify(stringifyFunctions(body || {}))
+    };
+    if (opts) {
+        if (opts.query) { options.qs = createQueryObj(opts.query); }
+        if (opts.headers) { _.extend(options.headers, opts.headers); }
+    }
+    var req = request(url, options);
+    var res = req.response
+    .then(function(res) {
+        return req.then(function(res) {
+            return JSON.parse(res);
+        }, function(err) {
+            return Q.reject(JSON.parse(err));
+        });
+    }, function(err) {
+        return Q.reject(err);
+    });
+    res.response = req.response
+    .then(function(res) {
+        return {
+            statusCode: res.statusCode,
+            headers: res.headers,
+            body: JSON.parse(res.body)
+        };
+    }, function(err) {
+        return Q.reject(err);
+    });
+    return res;
+}
+
+function createQueryObj (obj) {
+    var newObj = {};
+    _.each(obj, function(val, key) {
+        newObj[key] = JSON.stringify(val);
+    });
+    return newObj;
+}
+
+function stringifyFunctions (value) {
+    if (value === null) {
+        return null;
+    } else if (_.isArray(value)) {
+        return value;
+    } else if (_.isFunction(value)) {
+        return value.toString();
+    } else if (_.isObject(value)) {
+        value = _.clone(value);
+        _.each(value, function(propValue, propName) {
+            value[propName] = stringifyFunctions(propValue);
+        });
+        return value;
+    } else {
+        return value;
+    }
+}
+
+exports.CouchDB = CouchDB;
