Index: /trunk/grails-app/controllers/PersonController.groovy
===================================================================
--- /trunk/grails-app/controllers/PersonController.groovy	(revision 293)
+++ /trunk/grails-app/controllers/PersonController.groovy	(revision 294)
@@ -105,73 +105,80 @@
 
     /**
-        * Person update action.
-        */
+    * Person update action.
+    */
     def update = {
-
-        def person = Person.get(params.id)
-        if (!person) {
-            flash.message = "Person not found with id $params.id"
-            redirect action: edit, id: params.id
-            return
-        }
-
-        long version = params.version.toLong()
-        if (person.version > version) {
-            person.errors.rejectValue 'version', "person.optimistic.locking.failure",
-                "Another user has updated this Person while you were editing."
-            render view: 'edit', model: buildPersonModel(person)
-            return
-        }
-
-        person.properties = params
-
-        if(params.pass == "") {
-            person.pass = "InsertNothingToClearValidation"
-        }
-        else {
-            if (person.validate()) {
-                person.password = authenticateService.encodePassword(params.pass)
-            }
-        }
-
-        if (!person.hasErrors() && person.save(flush: true)) {
-            Authority.findAll().each { it.removeFromPersons(person) }
-            addRoles(person)
-            flash.message = "Person '$params.id - $params.loginName' updated."
-            redirect action: show, id: person.id
-        }
-        else {
-            render view: 'edit', model: buildPersonModel(person)
-        }
-
-    }
+        Person.withTransaction { status ->
+
+            def person = Person.get(params.id)
+            if (!person) {
+                flash.message = "Person not found with id $params.id"
+                redirect action: edit, id: params.id
+                return
+            }
+
+            long version = params.version.toLong()
+            if (person.version > version) {
+                person.errors.rejectValue 'version', "person.optimistic.locking.failure",
+                    "Another user has updated this Person while you were editing."
+                render view: 'edit', model: buildPersonModel(person)
+                return
+            }
+
+            person.properties = params
+            person.setPersonGroupsFromCheckBoxList(params.personGroups)
+
+            if(params.pass == "") {
+                person.pass = "InsertNothingToClearValidation"
+            }
+            else {
+                if (person.validate()) {
+                    person.password = authenticateService.encodePassword(params.pass)
+                }
+            }
+
+            if (!person.hasErrors() && person.save(flush: true)) {
+                addRemoveRoles(person)
+                flash.message = "Person '$params.id - $params.loginName' updated."
+                redirect action: show, id: person.id
+            }
+            else {
+                render view: 'edit', model: buildPersonModel(person)
+            }
+
+        } //end withTransaction
+    } // update()
 
     def create = {
         params.message = "To allow login at least the 'ROLE_AppUser' authority must be given."
-        [person: new Person(params), authorityList: Authority.list()]
-    }
-
-    /**
-        * Person save action.
-        */
+        [person: new Person(params), authorityList: getLimitedAuthorityList()]
+    }
+
+    /**
+    * Person save action.
+    */
     def save = {
-
-        def person = new Person()
-        person.properties = params
-        person.password = authenticateService.encodePassword(params.pass)
-        if (person.save(flush: true)) {
-            addRoles(person)
-            redirect action: show, id: person.id
-        }
-        else {
-            render view: 'create', model: [authorityList: Authority.list(), person: person]
-        }
-    }
-
-    private void addRoles(person) {
-        for (String key in params.keySet()) {
-            if (key.contains('ROLE') && 'on' == params.get(key)) {
+        Person.withTransaction { status ->
+
+            def person = new Person()
+            person.properties = params
+            person.password = authenticateService.encodePassword(params.pass)
+            person.setPersonGroupsFromCheckBoxList(params.personGroups)
+            if (person.save(flush: true)) {
+                addRemoveRoles(person)
+                redirect action: show, id: person.id
+            }
+            else {
+                render view: 'create', model: [person: person, authorityList: getLimitedAuthorityList()]
+            }
+
+        } //end withTransaction
+    }
+
+    private void addRemoveRoles(person) {
+        for (key in params.keySet()) {
+            if(key.startsWith("ROLE"))
                 Authority.findByAuthority(key).addToPersons(person)
-            }
+            else if(key.startsWith("_ROLE"))
+                Authority.findByAuthority(key.substring(1)).removeFromPersons(person)
         }
     }
@@ -179,5 +186,5 @@
     private Map buildPersonModel(person) {
 
-        List roles = Authority.list()
+        List roles = getLimitedAuthorityList()
         roles.sort { r1, r2 ->
             r1.authority <=> r2.authority
@@ -194,3 +201,16 @@
         return [person: person, roleMap: roleMap]
     }
+
+    /**
+    * Get the full authorityList if current user is an App Admin else leave that authority off the list.
+    */
+    def getLimitedAuthorityList = {
+        def authorityList = []
+        if(authenticateService.ifAnyGranted('ROLE_AppAdmin'))
+            authorityList = Authority.list().sort { p1, p2 -> p1.authority.compareToIgnoreCase(p2.authority) }
+        else
+            authorityList = Authority.withCriteria { gt("id", 1L) }.sort { p1, p2 -> p1.authority.compareToIgnoreCase(p2.authority) }
+
+        return authorityList
+    }
 }
Index: /trunk/grails-app/domain/Person.groovy
===================================================================
--- /trunk/grails-app/domain/Person.groovy	(revision 293)
+++ /trunk/grails-app/domain/Person.groovy	(revision 294)
@@ -54,3 +54,15 @@
     //Overriding the default toString method
     String toString() {"${this.firstName} ${this.lastName}"}
-}
+
+    //  This additional setter is used to convert the checkBoxList string
+    //  of ids selected to the corresponding domain objects.
+    public void setPersonGroupsFromCheckBoxList(ids) {
+        def idList = []
+        ids.each() {
+            if(it.isInteger())
+                idList << it.toInteger()
+        }
+        this.personGroups = idList.collect { PersonGroup.get( it ) }
+    }
+
+} // end class
Index: /trunk/grails-app/services/CreateDataService.groovy
===================================================================
--- /trunk/grails-app/services/CreateDataService.groovy	(revision 293)
+++ /trunk/grails-app/services/CreateDataService.groovy	(revision 294)
@@ -143,4 +143,5 @@
         def authInstance
 
+        // Authority #1
         authInstance = new Authority(description:"Application Admin, not required for daily use! Grants full admin access to the application.",
                                         authority:"ROLE_AppAdmin")
@@ -152,9 +153,10 @@
         def authInstance
 
+        // Authority #2
         authInstance = new Authority(description:"Business manager, grants full management access.",
                                         authority:"ROLE_Manager")
         saveAndTest(authInstance)
 
-        // #3
+        // Authority #3
         authInstance = new Authority(description:"Application User, all application users need this base role to allow login.",
                                         authority:"ROLE_AppUser")
Index: /trunk/grails-app/views/person/create.gsp
===================================================================
--- /trunk/grails-app/views/person/create.gsp	(revision 293)
+++ /trunk/grails-app/views/person/create.gsp	(revision 294)
@@ -111,9 +111,9 @@
                         </td>
                         <td valign="top" class="value ${hasErrors(bean:person,field:'personGroups','errors')}">
-                            <g:select id="personGroups" name="personGroups"
-                                            from="${PersonGroup.list()}"
-                                            optionKey="id" size="5" multiple="yes"
-                                            value="${person?.personGroups?.id}" noSelection="['':'--None--']"/>
                             <g:helpBalloon class="helpballoon" code="person.personGroups" />
+                            <custom:checkBoxList name="personGroups"
+                                                            from="${PersonGroup.list().sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }}"
+                                                            value="${person?.personGroups?.collect{it.id}}"
+                                                            optionKey="id"/>
                         </td>
                     </tr>
Index: /trunk/grails-app/views/person/edit.gsp
===================================================================
--- /trunk/grails-app/views/person/edit.gsp	(revision 293)
+++ /trunk/grails-app/views/person/edit.gsp	(revision 294)
@@ -118,9 +118,9 @@
                         </td>
                         <td valign="top" class="value ${hasErrors(bean:person,field:'personGroups','errors')}">
-                            <g:select id="personGroups" name="personGroups"
-                                            from="${PersonGroup.list()}"
-                                            optionKey="id" size="10" multiple="yes"
-                                            value="${person?.personGroups.id}" noSelection="['':'--None--']"/>
                             <g:helpBalloon class="helpballoon" code="person.personGroups" />
+                            <custom:checkBoxList name="personGroups"
+                                                            from="${PersonGroup.list().sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }}"
+                                                            value="${person?.personGroups?.collect{it.id}}"
+                                                            optionKey="id"/>
                         </td>
                     </tr>
