function userSearchChangeHelper(userId, gg_form) {
	
	// gee_form
	// local because I can't pass it into
	// query call backs. SP sucks
	var gee_form = gg_form;
	var user_id = userId;
	
	function EmpData(usrid) {
		this.EmpName = "";
		this.EmpNumber = "";
		this.EmpType = "";
		this.DefaultDept = "";
		this.DefaultFaculty = "";
		
		try {
			var emp = new GlideRecord('sys_user');
			emp.addQuery('sys_id', usrid);
			emp.query(function(emp){
				if(emp.next()) {
					this.EmpName = emp.first_name + " " + emp.last_name;
					this.EmpNumber = emp.u_pinumber;
					this.EmpType = emp.u_type + "";
					this.DefaultDept = emp.department+"";
					this.DefaultFaculty = emp.u_faculty+"";
					
					console.log("@@@ Emp Data: EmpName["+this.EmpName+"] EmpNumber["+this.EmpNumber+"] EmpType["+this.EmpType+"]");
				} else console.log("@@@ Emp returned NOTHING, for user ["+user_id+"] from param["+userId+"]");
			});
		} catch(err) {
			console.log("@@@ userSearchChangeHelper:: init, record query failed message["+err.message+"]");
		}
		
		console.log("@@@ EmpData:: init called.");
		//
		//  This methods return a 'Yes' if flag is true and 'No' otherwise
		//
		this.YesNo = function(flag) {
			try {
				
				if(flag) return 'Yes';
					return 'No';
				
			} catch(err) {
				console.log("@@@ An exception occurred in userSearchChangeHelper::YesNo, message=" + err.message);
			}
		};
		
		this.isUserTypeGeneric = function() {
			try {
				return this.EmpType == 'generic';
			} catch(err) {
				console.log("@@@ An exception occurred in userSearchChangeHelper::_isUserTypeGeneric, message=" + err.message);
			}
		};
		
		this.isUserTypeStaff = function() {
			try {
				return this.EmpType == 'staff';
			} catch(err) {
				console.log("@@@ An exception occurred in userSearchChangeHelper::_isUserTypeStaff, message=" + err.message);
			}
		};
		
		this.isUserTypeStudent = function() {
			try {
				return (this.EmpType == 'UG' || this.EmpType == 'PGT' || this.EmpType == 'PGR');
			} catch(err) {
				console.log("@@@ An exception occurred in userSearchChangeHelper::_isUserTypeStudent, message=" + err.message);
			}
		};
		
		this.isUserTypeEmpty = function() {
			try {
				var tmp = this.EmpType + "";
				tmp = tmp.trim();
				return tmp == '';
			} catch(err) {
				console.log("@@@ An exception occurred in userSearchChangeHelper::_isUserTypeEmpty, message=" + err.message);
			}
		};
		
	}
	
	this.Employee = new EmpData(user_id);
	
	_initialize = function() {
		
		// does nothing
		
	};
	
	//
	//	role = a record from 'u_employee_post'
	//
	this.updateRoleData = function(role) {
		try {
			// find the manager details for this role
			gee_form.hideFieldMsg('Line_Manager');
			var manager = new GlideRecord('u_employee_post');
			manager.addQuery('sys_id', role.u_manager_post);
			manager.query(function Q(manager) {
				var LM_PostName = 'No data';
				if(manager.next()) {
					LM_PostName = manager.u_short_description;
				}
				gee_form.setValue('LM_PostName' , LM_PostName);
			});
			
			gee_form.setValue('Post_ID' , role.u_number) ;
			gee_form.setValue('Post_Title', role.u_short_description);
			gee_form.setValue('Line_Manager' , role.u_manager) ;
			gee_form.setValue('LineManagerFlag' , 0, 'No');
			if(role.u_line_manager=='true') {
				gee_form.setValue('LineManagerFlag' , 1, 'Yes');
			}
			gee_form.setValue('Career_Path' , role.u_career_path) ;
			
			if(gee_form.getValue('Line_Manager')=="") {
				gee_form.showFieldMsg('Line_Manager',"This request can not be submitted without a valid line Manager. Please report this using the Link below.",'error');
				
				var emsg = '?subject=' + "Auto Generated Email: Missing Line Manager report";
				
				emsg += "&body=Post Number:"+ role.u_number + "%0D%0APost Title:" + role.u_short_description + "%0D%0AHeld by Employee: "+ this.Employee.EmpName + "%0D%0AEmployee Number:"+ this.Employee.EmpNumber;
				emsg += "%0D%0AThis employee and post have no line manager and HR Requests cannot be submitted for this person until this has been corrected. ";
				emsg += "I have provided details below to assist you in correcting this record to allow HR Requests to be submitted for this person: ";
				
				emsg = emsg.replace(" ", "%20"); // replace all spaces
				
				emsg = '<a href="mailto:HumanResources@soton.ac.uk' + emsg; // prefix
				emsg += '">Report missing Line Manager.</a>'; // tail
				//if(document && gel) document.getElementById("LmEmailId").innerHTML = "<p>Use this link to email HR with the missing line manager details: "+emsg+"</p>";
				//else // service portal.
			}
			
			this.updateDeptAndFaculty(role);
		}
		catch (err) {
			console.log("@@@ An exception occurred in userSearchChangeHelper::updateRoleData, message=" + err.message);
		}
		
	};
	
	//
	//	role = a record from 'u_employee_post'
	//
	this.updateRoleDataVisitor = function(role)
	{
		try {
			// find the manager details for this role
			gee_form.hideFieldMsg('vs_Line_Manager');
			var manager = new GlideRecord('u_employee_post');
			manager.addQuery('sys_id', role.u_manager_post);
			manager.query(function Q(manager){
				var LM_PostName = 'No data';
				if(manager.next()) {
					LM_PostName = manager.u_short_description;
				}
				gee_form.setValue('vs_LM_PostName' , LM_PostName);
			});
			gee_form.setValue('vs_Post_ID' , role.u_number) ;
			gee_form.setValue('vs_Post_Title', role.u_short_description);
			gee_form.setValue('vs_Line_Manager' , role.u_manager) ;
			
			this.updateDeptAndFacultyVisitor(role);
			
		}
		catch (err) {
			console.log("@@@ An exception occurred in visitorSearchChangeHelper::updateRoleData, message=" + err.message);
		}
		
	};
	
	//
	//	role = a record from 'u_employee_post'
	//
	this.updateRoleDataIT = function(role)
	{
		try {
			// find the manager details for this role
			gee_form.hideFieldMsg('it_Line_Manager');
			var manager = new GlideRecord('u_employee_post');
			manager.addQuery('sys_id', role.u_manager_post);
			manager.query(function Q(manager){
				var LM_PostName = 'No data';
				if(manager.next()) {
					LM_PostName = manager.u_short_description;
				}
				gee_form.setValue('it_LM_PostName' , LM_PostName);
			});
			gee_form.setValue('it_Post_ID' , role.u_number) ;
			gee_form.setValue('it_Post_Title', role.u_short_description);
			gee_form.setValue('it_Line_Manager' , role.u_manager) ;
			gee_form.setValue('it_LineManagerFlag' , 0, 'No');
			if(role.u_line_manager=='true') {
				gee_form.setValue('it_LineManagerFlag' , 1, 'Yes');
			}
			gee_form.setValue('it_Career_Path' , role.u_career_path) ;
			
			this.updateDeptAndFacultyIT(role);
			
		}
		catch (err) {
			console.log("@@@ An exception occurred in userSearchChangeHandler::updateRoleData, message=" + err.message);
		}
		
	};
	
	//
	//	facultyGUID = parent department to find
	//
	this.updateFaculty = function(facultyGUID) {
		try {
			var faculty = new GlideRecord('cmn_department');
			faculty.addQuery('sys_id', facultyGUID);
			faculty.query(function Q(faculty){
				var theFaculty = "NOT FOUND";
				if(faculty.next()) {
					theFaculty = faculty.name;
				}
				gee_form.setValue('Faculty_PSG', theFaculty);
			});
		} catch(err) {
			console.log("@@@ An exception occurred in userSearchChangeHelper::updateFaculty, message=" + err.message);
		}
	};
	//
	//	dept = cmn_department record
	//
	this.updateDeptAndFaculty = function(role) {
		try {
			var dept = new GlideRecord('cmn_department');
			console.log("@@@ role.u_short_description={"+ role.u_short_description + "}, role.u_department={" + role.u_department + "}");
				dept.addQuery('sys_id', role.u_department);
				dept.query(function Q(dept){
					if (dept.next()) {
						gee_form.setValue('Academic_Unit', dept.name);
						
						var faculty = new GlideRecord('cmn_department');
						faculty.addQuery('sys_id', dept.u_faculty);
						faculty.query(function Q(faculty){
							var theFaculty = "NOT FOUND";
							if(faculty.next()) {
								theFaculty = faculty.name;
							}
							gee_form.setValue('Faculty_PSG', theFaculty);
						});
						
					} else gee_form.setValue('Academic_Unit', 'NO DEPARTMENT FOUND');
				});
			}
			catch (err) {
				console.log("@@@ An exception occurred in userSearchChangeHelper::updateDeptAndFaculty, message=" + err.message);
			}
		};
		
		//
		//	dept = cmn_department record
		//
		this.updateDeptAndFacultyVisitor = function(role)
		{
			try {
				var dept = new GlideRecord('cmn_department');
				console.log("@@@ role.u_short_description={"+ role.u_short_description + "}, role.u_department={" + role.u_department + "}");
					dept.addQuery('sys_id', role.u_department);
					dept.query(function Q(dept){
						if (dept.next()) {
							gee_form.setValue('vs_Academic_Unit', dept.name);
							var faculty = new GlideRecord('cmn_department');
							faculty.addQuery('sys_id', dept.u_faculty);
							faculty.query(function Q(faculty){
								var theFaculty = "NOT FOUND";
								if(faculty.next()) {
									theFaculty = faculty.name;
								}
								gee_form.setValue('vs_Faculty_PSG', theFaculty);
							});
							
						} else gee_form.setValue('vs_Academic_Unit', 'NO DEPARTMENT FOUND');
					});
				}
				catch (err) {
					console.log("@@@ An exception occurred in visitorSearchChangeHelper::updateDeptAndFacultyVisitor, message=" + err.message);
				}
			};
			
			//
			//	dept = cmn_department record
			//
			this.updateDeptAndFacultyIT = function(role)
			{
				try {
					console.log("@@@ DEBUG::userSearchChangeHelper::updateDeptAndFacultyIT. User Type::Staff["
								+this.Employee.YesNo(this.Employee.isUserTypeStaff())+"] Student["
								+this.Employee.YesNo(this.Employee.isUserTypeStudent())+"] Generic["
								+this.Employee.YesNo(this.Employee.isUserTypeGeneric())+"] Empty["
								+this.Employee.YesNo(this.Employee.isUserTypeEmpty())+"]");
					console.log("@@@ DEBUG::userSearchChangeHelper::updateDeptAndFacultyIT EmpName["+this.Employee.EmpName+"] EmpNumber["+this.Employee.EmpNumber+"] EmpType["+this.Employee.EmpType+"]");
					var dep_name = this.DefaultDept; // used for students
					var dept = new GlideRecord('cmn_department');
					if(role!='student' && role!='generic') {
						console.log("@@@ role.u_short_description={"+ role.u_short_description + "}, role.u_department={" + role.u_department + "}");
							dep_name = role.u_department;
						}
						dept.addQuery('sys_id', dep_name);
						dept.query(function Q(dept){
							if (dept.next()) {
								gee_form.setValue('it_Academic_Unit', dept.name);
								var faculty = new GlideRecord('cmn_department');
								faculty.addQuery('sys_id', facultyGUID);
								faculty.query(function Q(faculty){
									var theFaculty = "NOT FOUND";
									if(faculty.next()) {
										theFaculty = faculty.name;
									}
									gee_form.setValue('it_Faculty_PSG', theFaculty);
								});
							} else gee_form.setValue('it_Academic_Unit', 'NO DEPARTMENT FOUND');
						});
					}
					catch (err) {
						console.log("@@@ An exception occurred in userSearchChangeHelper::updateDeptAndFacultyIT, message=" + err.message);
					}
				};
				
				//
				//	Clear the role field values
				//  This is an It user search method
				this.clearRoleDataIT = function()
				{
					try {
						// clear the manager details.
						gee_form.hideFieldMsg('it_Line_Manager');
						gee_form.setValue('it_LM_PostName' , '');
						gee_form.setValue('it_Post_ID' , '') ;
						gee_form.setValue('it_Post_Title', '');
						gee_form.setValue('it_Line_Manager' , '') ;
						gee_form.setValue('it_LineManagerFlag' , 0, 'No');
						gee_form.setValue('it_Career_Path' , '') ;
						if(this.Employee.isUserTypeStudent())
							this.updateDeptAndFacultyIT('student');
						else if(this.Employee.isUserTypeGeneric()) this.updateDeptAndFacultyIT('generic');
							else if(this.Employee.isUserTypeEmpty()) this.updateDeptAndFacultyIT('empty');
						}
					catch (err) {
						console.log("@@@ An exception occurred in userSearchChangeHelper::clearRoleData, message=" + err.message);
					}
					
				};
				
				this.type = 'userSearchChangeHelper';
				_initialize();
			}