Index: branches/TaskRewrite/src/grails-app/conf/BootStrap.groovy
===================================================================
--- branches/TaskRewrite/src/grails-app/conf/BootStrap.groovy	(revision 57)
+++ branches/TaskRewrite/src/grails-app/conf/BootStrap.groovy	(revision 58)
@@ -1,7 +1,156 @@
-class BootStrap {
+import grails.util.GrailsUtil
 
-     def init = { servletContext ->
-     }
-     def destroy = {
-     }
-} 
+class BootStrap 
+{
+    //Required to be right here for Acegi plugin.
+    def authenticateService
+    Boolean BootStrapDemoDataSuccessful = true
+
+    def init = { servletContext ->
+
+    println "**** BootStrap GrailsUtil.environment = ${GrailsUtil.environment}"
+    
+        switch (GrailsUtil.environment)
+        {
+            case "development":
+                        bootStrapDemoData()
+                        break
+            case "test":
+                        break
+            case "production":
+                        bootStrapDemoData()
+                        break 
+        }
+    
+    }
+
+    def destroy = {
+    }
+
+    //Insert some demo/startup data.
+    void bootStrapDemoData()
+    {
+        println "BootStrapping demo data..."
+    
+        //TypeOfPersonGroup
+//         new PersonGroupType(name:"Department").save()
+//         new PersonGroupType(name:"Contractor").save()
+//         new PersonGroupType(name:"ProjectTeam").save()
+    
+        //PersonGroup
+//         new PersonGroup(personGroupType:PersonGroupType.findByName("Department"),
+//                         name:"Electrical").save()
+//         new PersonGroup(personGroupType:PersonGroupType.get(2),
+//                         name:"Kewl AirCon Guys").save()
+//         new PersonGroup(personGroupType:PersonGroupType.get(3),
+//                         name:"gnuMims").save()
+
+            
+        //Person
+//         def passwordEncoded = authenticateService.encodePassword("pass")
+
+        def personInstance = new Person(loginName:"admin",
+                                    firstName:"Admin",
+                                    lastName:"Powers",
+                                    password:authenticateService.encodePassword("pass"),
+                                    email:"admin@example.com")
+        BootStrapSaveAndTest(personInstance)
+
+        //Role
+        def authInstance = new Authority(description:"Application Admin",
+                            authority:"ROLE_ADMIN")
+            authInstance.addToPersons(personInstance)
+            authInstance.save()
+
+//         new Person(username:"admin", 
+//             userRealName:"Admin Powers", 
+//             enabled:true,
+//             
+//         new Person(personGroup:PersonGroup.get(3),
+//             firstName:"Admin",
+//             lastName:"Powers",
+//             userId:"admin",
+//             password:"pass").save()
+//         new Person(personGroup:PersonGroup.get(1),
+//             firstName:"Demo",
+//             lastName:"Danza",
+//             userId:"user",
+//             password:"pass").save()
+
+
+//         new Person(personGroup:PersonGroup.get(1),
+//             firstName:"Craig",
+//             lastName:"SuperTech",
+//             userId:"craig",
+//             password:"pass").save()
+//         new Person(personGroup:PersonGroup.get(2),
+//             firstName:"Joe",
+//             lastName:"Samples",
+//             userId:"joe",
+//             password:"pass").save()
+//         new Person(personGroup:PersonGroup.get(1),
+//             firstName:"Production",
+//             lastName:"Mann",
+//             userId:"Mann",
+//             password:"pass").save()
+                
+        //TaskGroup
+//         new TaskGroup(name:"Engineering",
+//                       description:"Engineering task group").save()
+//         new TaskGroup(name:"Production",
+//                       description:"Production task group").save()
+//         new TaskGroup(name:"NewProject(s)",
+//                       description:" ").save()
+                      
+        
+        //Task
+//         new Task(taskGroup:TaskGroup.findByName("Engineering"),
+//                  leadPerson:Person.get(3),
+//                  name:"Check specific level sensor",
+//                  description:"Has been noted as problematic, try recallibrating",
+//                  scheduledDate: new Date(),
+//                  targetDate: new Date() ).save()
+//         new Task(taskGroup:TaskGroup.findByName("Production"),
+//                  leadPerson:Person.get(5),
+//                  name:"Production Report",
+//                  description:"Production report for specific production run or shift",
+//                  scheduledDate: new Date(),
+//                  targetDate: new Date() ).save()
+//         new Task(taskGroup:TaskGroup.findByName("NewProject(s)"),
+//                  leadPerson:Person.get(1),
+//                  name:"Make killer CMMS app",
+//                  description:"Use Grails and get a move on!",
+//                  scheduledDate: new Date(),
+//                  targetDate: new Date() ).save()
+
+        //EntryType
+//         new EntryType(name:"Fault").save()
+//         new EntryType(name:"WorkDone").save()
+//         new EntryType(name:"Production Report").save()
+
+        //ModificationType
+//         new ModificationType(name:"Created").save()
+//         new ModificationType(name:"Completed").save()
+//         new ModificationType(name:"Closed").save()
+//         new ModificationType(name:"Altered").save()
+//         new ModificationType(name:"TargetDateModified").save()
+//         new ModificationType(name:"ScheduledDateModified").save()
+//         new ModificationType(name:"DescriptionModified").save()
+//         new ModificationType(name:"AssignedToModified").save()
+//         new ModificationType(name:"NameModified").save()
+        
+        if(BootStrapDemoDataSuccessful) {
+            println "BootStrapping demo data...successful."
+        }
+        else println "BootStrapping demo data...failed."
+    }
+    
+    void BootStrapSaveAndTest(object) {
+        if(!object.save()) {
+            BootStrapDemoDataSuccessful = false
+            println "'${object}' failed to save!"
+            println object.errors
+
+        }
+    } 
+}
Index: branches/TaskRewrite/src/grails-app/conf/Config.groovy
===================================================================
--- branches/TaskRewrite/src/grails-app/conf/Config.groovy	(revision 57)
+++ branches/TaskRewrite/src/grails-app/conf/Config.groovy	(revision 58)
@@ -69,2 +69,5 @@
 
 
+
+
+//log4j.logger.org.springframework.security='off,stdout'
Index: branches/TaskRewrite/src/grails-app/conf/SecurityConfig.groovy
===================================================================
--- branches/TaskRewrite/src/grails-app/conf/SecurityConfig.groovy	(revision 58)
+++ branches/TaskRewrite/src/grails-app/conf/SecurityConfig.groovy	(revision 58)
@@ -0,0 +1,20 @@
+security {
+
+	// see DefaultSecurityConfig.groovy for all settable/overridable properties
+
+	active = true
+
+	loginUserDomainClass = "Person"
+    userName = 'loginName'
+    password = 'password'
+    enabled = 'isActive'
+
+	authorityDomainClass = "Authority"
+
+    //Required if we want to run "grails generate-manager"
+    //Which recreates the controller and views, so save the views.
+//     requestMapClass = 'Requestmap'
+
+    useRequestMapDomainClass = false
+    useControllerAnnotations = true
+}
Index: branches/TaskRewrite/src/grails-app/controllers/AuthorityController.groovy
===================================================================
--- branches/TaskRewrite/src/grails-app/controllers/AuthorityController.groovy	(revision 58)
+++ branches/TaskRewrite/src/grails-app/controllers/AuthorityController.groovy	(revision 58)
@@ -0,0 +1,123 @@
+
+
+
+/**
+ * Authority Controller.
+ */
+class AuthorityController {
+
+	// the delete, save and update actions only accept POST requests
+	static Map allowedMethods = [delete: 'POST', save: 'POST', update: 'POST']
+
+	def authenticateService
+
+	def index = {
+		redirect action: list, params: params
+	}
+
+	/**
+	 * Display the list authority page.
+	 */
+	def list = {
+		if (!params.max) {
+			params.max = 10
+		}
+		[authorityList: Authority.list(params)]
+	}
+
+	/**
+	 * Display the show authority page.
+	 */
+	def show = {
+		def authority = Authority.get(params.id)
+		if (!authority) {
+			flash.message = "Authority not found with id $params.id"
+			redirect action: list
+			return
+		}
+
+		[authority: authority]
+	}
+
+	/**
+	 * Delete an authority.
+	 */
+	def delete = {
+		def authority = Authority.get(params.id)
+		if (!authority) {
+			flash.message = "Authority not found with id $params.id"
+			redirect action: list
+			return
+		}
+
+		authenticateService.deleteRole(authority)
+
+		flash.message = "Authority $params.id deleted."
+		redirect action: list
+	}
+
+	/**
+	 * Display the edit authority page.
+	 */
+	def edit = {
+		def authority = Authority.get(params.id)
+		if (!authority) {
+			flash.message = "Authority not found with id $params.id"
+			redirect action: list
+			return
+		}
+
+		[authority: authority]
+	}
+
+	/**
+	 * Authority update action.
+	 */
+	def update = {
+
+		def authority = Authority.get(params.id)
+		if (!authority) {
+			flash.message = "Authority not found with id $params.id"
+			redirect action: edit, id: params.id
+			return
+		}
+
+		long version = params.version.toLong()
+		if (authority.version > version) {
+			authority.errors.rejectValue 'version', 'authority.optimistic.locking.failure',
+				'Another user has updated this Authority while you were editing.'
+			render view: 'edit', model: [authority: authority]
+			return
+		}
+
+		if (authenticateService.updateRole(authority, params)) {
+			authenticateService.clearCachedRequestmaps()
+			redirect action: show, id: authority.id
+		}
+		else {
+			render view: 'edit', model: [authority: authority]
+		}
+	}
+
+	/**
+	 * Display the create new authority page.
+	 */
+	def create = {
+		[authority: new Authority()]
+	}
+
+	/**
+	 * Save a new authority.
+	 */
+	def save = {
+
+		def authority = new Authority()
+		authority.properties = params
+		if (authority.save()) {
+			redirect action: show, id: authority.id
+		}
+		else {
+			render view: 'create', model: [authority: authority]
+		}
+	}
+}
Index: branches/TaskRewrite/src/grails-app/controllers/LoginController.groovy
===================================================================
--- branches/TaskRewrite/src/grails-app/controllers/LoginController.groovy	(revision 58)
+++ branches/TaskRewrite/src/grails-app/controllers/LoginController.groovy	(revision 58)
@@ -0,0 +1,179 @@
+import org.codehaus.groovy.grails.plugins.springsecurity.RedirectUtils
+import org.grails.plugins.springsecurity.service.AuthenticateService
+
+import org.springframework.security.AuthenticationTrustResolverImpl
+import org.springframework.security.DisabledException
+import org.springframework.security.context.SecurityContextHolder as SCH
+import org.springframework.security.ui.AbstractProcessingFilter
+import org.springframework.security.ui.webapp.AuthenticationProcessingFilter
+
+/**
+ * Login Controller (Example).
+ */
+class LoginController {
+
+	/**
+	 * Dependency injection for the authentication service.
+	 */
+	def authenticateService
+
+	/**
+	 * Dependency injection for OpenIDConsumer.
+	 */
+	def openIDConsumer
+
+	/**
+	 * Dependency injection for OpenIDAuthenticationProcessingFilter.
+	 */
+	def openIDAuthenticationProcessingFilter
+
+	private final authenticationTrustResolver = new AuthenticationTrustResolverImpl()
+
+	def index = {
+		if (isLoggedIn()) {
+			redirect uri: '/'
+		}
+		else {
+			redirect action: auth, params: params
+		}
+	}
+
+	/**
+	 * Show the login page.
+	 */
+	def auth = {
+
+		nocache response
+
+		if (isLoggedIn()) {
+			redirect uri: '/'
+			return
+		}
+
+		String view
+		String postUrl
+		def config = authenticateService.securityConfig.security
+		if (config.useOpenId) {
+			view = 'openIdAuth'
+			postUrl = "${request.contextPath}/login/openIdAuthenticate"
+		}
+		else if (config.useFacebook) {
+			view = 'facebookAuth'
+			postUrl = "${request.contextPath}${config.facebook.filterProcessesUrl}"
+		}
+		else {
+			view = 'auth'
+			postUrl = "${request.contextPath}${config.filterProcessesUrl}"
+		}
+
+		render view: view, model: [postUrl: postUrl]
+	}
+
+	/**
+	 * Form submit action to start an OpenID authentication.
+	 */
+	def openIdAuthenticate = {
+		String openID = params['j_username']
+		try {
+			String returnToURL = RedirectUtils.buildRedirectUrl(
+					request, response, openIDAuthenticationProcessingFilter.filterProcessesUrl)
+			String redirectUrl = openIDConsumer.beginConsumption(request, openID, returnToURL)
+			redirect url: redirectUrl
+		}
+		catch (org.springframework.security.ui.openid.OpenIDConsumerException e) {
+			log.error "Consumer error: $e.message", e
+			redirect url: openIDAuthenticationProcessingFilter.authenticationFailureUrl
+		}
+	}
+
+	// Login page (function|json) for Ajax access.
+	def authAjax = {
+		nocache(response)
+		//this is example:
+		render """
+		<script type='text/javascript'>
+		(function() {
+			loginForm();
+		})();
+		</script>
+		"""
+	}
+
+	/**
+	 * The Ajax success redirect url.
+	 */
+	def ajaxSuccess = {
+		nocache(response)
+		render '{success: true}'
+	}
+
+	/**
+	 * Show denied page.
+	 */
+	def denied = {
+		if (isLoggedIn() && authenticationTrustResolver.isRememberMe(SCH.context?.authentication)) {
+			// have cookie but the page is guarded with IS_AUTHENTICATED_FULLY
+			redirect action: full, params: params
+		}
+	}
+
+	/**
+	 * Login page for users with a remember-me cookie but accessing a IS_AUTHENTICATED_FULLY page.
+	 */
+	def full = {
+		render view: 'auth', params: params,
+			model: [hasCookie: authenticationTrustResolver.isRememberMe(SCH.context?.authentication)]
+	}
+
+	// Denial page (data|view|json) for Ajax access.
+	def deniedAjax = {
+		//this is example:
+		render "{error: 'access denied'}"
+	}
+
+	/**
+	 * login failed
+	 */
+	def authfail = {
+
+		def username = session[AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
+		def msg = ''
+		def exception = session[AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY]
+		if (exception) {
+			if (exception instanceof DisabledException) {
+				msg = "[$username] is disabled."
+			}
+			else {
+				msg = "[$username] wrong username/password."
+			}
+		}
+
+		if (isAjax()) {
+			render "{error: '${msg}'}"
+		}
+		else {
+			flash.message = msg
+			redirect action: auth, params: params
+		}
+	}
+
+	/**
+	 * Check if logged in.
+	 */
+	private boolean isLoggedIn() {
+		return authenticateService.isLoggedIn()
+	}
+
+	private boolean isAjax() {
+		return authenticateService.isAjax(request)
+	}
+
+	/** cache controls */
+	private void nocache(response) {
+		response.setHeader('Cache-Control', 'no-cache') // HTTP 1.1
+		response.addDateHeader('Expires', 0)
+		response.setDateHeader('max-age', 0)
+		response.setIntHeader ('Expires', -1) //prevents caching at the proxy server
+		response.addHeader('cache-Control', 'private') //IE5.x only
+	}
+}
Index: branches/TaskRewrite/src/grails-app/controllers/LogoutController.groovy
===================================================================
--- branches/TaskRewrite/src/grails-app/controllers/LogoutController.groovy	(revision 58)
+++ branches/TaskRewrite/src/grails-app/controllers/LogoutController.groovy	(revision 58)
@@ -0,0 +1,13 @@
+/**
+ * Logout Controller (Example).
+ */
+class LogoutController {
+
+	/**
+	 * Index action. Redirects to the Spring security logout uri.
+	 */
+	def index = {
+		// TODO  put any pre-logout code here
+		redirect(uri: '/j_spring_security_logout')
+	}
+}
Index: branches/TaskRewrite/src/grails-app/controllers/PersonController.groovy
===================================================================
--- branches/TaskRewrite/src/grails-app/controllers/PersonController.groovy	(revision 58)
+++ branches/TaskRewrite/src/grails-app/controllers/PersonController.groovy	(revision 58)
@@ -0,0 +1,162 @@
+
+
+
+/**
+ * User controller.
+ */
+class PersonController {
+
+	def authenticateService
+
+	// the delete, save and update actions only accept POST requests
+	static Map allowedMethods = [delete: 'POST', save: 'POST', update: 'POST']
+
+	def index = {
+		redirect action: list, params: params
+	}
+
+	def list = {
+		if (!params.max) {
+			params.max = 10
+		}
+		[personList: Person.list(params)]
+	}
+
+	def show = {
+		def person = Person.get(params.id)
+		if (!person) {
+			flash.message = "Person not found with id $params.id"
+			redirect action: list
+			return
+		}
+		List roleNames = []
+		for (role in person.authorities) {
+			roleNames << role.authority
+		}
+		roleNames.sort { n1, n2 ->
+			n1 <=> n2
+		}
+		[person: person, roleNames: roleNames]
+	}
+
+	/**
+	 * Person delete action. Before removing an existing person,
+	 * he should be removed from those authorities which he is involved.
+	 */
+	def delete = {
+
+		def person = Person.get(params.id)
+		if (person) {
+			def authPrincipal = authenticateService.principal()
+			//avoid self-delete if the logged-in user is an admin
+			if (!(authPrincipal instanceof String) && authPrincipal.username == person.loginName) {
+				flash.message = "You can not delete yourself, please login as another admin and try again"
+			}
+			else {
+				//first, delete this person from Persons_Authorities table.
+				Authority.findAll().each { it.removeFromPersons(person) }
+				person.delete()
+				flash.message = "Person $params.id deleted."
+			}
+		}
+		else {
+			flash.message = "Person not found with id $params.id"
+		}
+
+		redirect action: list
+	}
+
+	def edit = {
+
+		def person = Person.get(params.id)
+		if (!person) {
+			flash.message = "Person not found with id $params.id"
+			redirect action: list
+			return
+		}
+
+		return buildPersonModel(person)
+	}
+
+	/**
+	 * 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
+		}
+
+		def oldPassword = person.password
+		person.properties = params
+		if (!params.password.equals(oldPassword)) {
+			person.password = authenticateService.encodePassword(params.password)
+		}
+		if (person.save()) {
+			Authority.findAll().each { it.removeFromPersons(person) }
+			addRoles(person)
+			redirect action: show, id: person.id
+		}
+		else {
+			render view: 'edit', model: buildPersonModel(person)
+		}
+	}
+
+	def create = {
+		[person: new Person(params), authorityList: Authority.list()]
+	}
+
+	/**
+	 * Person save action.
+	 */
+	def save = {
+
+		def person = new Person()
+		person.properties = params
+		person.password = authenticateService.encodePassword(params.password)
+		if (person.save()) {
+			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)) {
+				Authority.findByAuthority(key).addToPersons(person)
+			}
+		}
+	}
+
+	private Map buildPersonModel(person) {
+
+		List roles = Authority.list()
+		roles.sort { r1, r2 ->
+			r1.authority <=> r2.authority
+		}
+		Set userRoleNames = []
+		for (role in person.authorities) {
+			userRoleNames << role.authority
+		}
+		LinkedHashMap<Authority, Boolean> roleMap = [:]
+		for (role in roles) {
+			roleMap[(role)] = userRoleNames.contains(role.authority)
+		}
+
+		return [person: person, roleMap: roleMap]
+	}
+}
Index: branches/TaskRewrite/src/grails-app/domain/Authority.groovy
===================================================================
--- branches/TaskRewrite/src/grails-app/domain/Authority.groovy	(revision 58)
+++ branches/TaskRewrite/src/grails-app/domain/Authority.groovy	(revision 58)
@@ -0,0 +1,14 @@
+class Authority {
+
+	static hasMany = [persons: Person]
+
+	/** description */
+	String description
+	/** ROLE String */
+	String authority
+
+	static constraints = {
+		authority(blank: false, unique: true)
+		description()
+	}
+}
Index: branches/TaskRewrite/src/grails-app/domain/Person.groovy
===================================================================
--- branches/TaskRewrite/src/grails-app/domain/Person.groovy	(revision 58)
+++ branches/TaskRewrite/src/grails-app/domain/Person.groovy	(revision 58)
@@ -0,0 +1,36 @@
+class Person {
+	static transients = ['pass']
+	static hasMany = [authorities: Authority]
+	static belongsTo = Authority
+
+	String loginName
+	String firstName
+    String lastName
+    String employeeID
+
+	/** MD5 Password */
+	String password
+
+	/** enabled */
+	boolean isActive = true
+
+	String email
+	boolean emailShow = true
+
+	/** description */
+	String description = ''
+
+	/** plain password to create a MD5 password */
+	String pass = '[secret]'
+
+	static constraints = {
+		loginName(blank: false, unique: true)
+		firstName(blank: false)
+        lastName(blank: false)
+		password(blank: false)
+        employeeID(blank: true, nullable:true)
+	}
+
+    //Overriding the default toString method
+    String toString() {"${this.firstName} ${this.lastName}"}
+}
