View Javadoc

1   /**
2    * Copyright 2005-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kim.service.impl;
17  
18  import org.apache.commons.collections.CollectionUtils;
19  import org.apache.commons.lang.StringUtils;
20  import org.apache.log4j.Logger;
21  import org.joda.time.DateTime;
22  import org.kuali.rice.core.api.config.property.ConfigContext;
23  import org.kuali.rice.core.api.criteria.Predicate;
24  import org.kuali.rice.core.api.criteria.PredicateUtils;
25  import org.kuali.rice.core.api.criteria.QueryByCriteria;
26  import org.kuali.rice.core.api.membership.MemberType;
27  import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
28  import org.kuali.rice.coreservice.api.parameter.Parameter;
29  import org.kuali.rice.core.api.uif.RemotableCheckbox;
30  import org.kuali.rice.core.api.uif.RemotableCheckboxGroup;
31  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
32  import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
33  import org.kuali.rice.kim.api.KimConstants;
34  import org.kuali.rice.kim.api.KimConstants.KimGroupMemberTypes;
35  import org.kuali.rice.kim.api.group.Group;
36  import org.kuali.rice.kim.api.group.GroupMember;
37  import org.kuali.rice.kim.api.group.GroupService;
38  import org.kuali.rice.kim.api.identity.IdentityService;
39  import org.kuali.rice.kim.api.identity.Person;
40  import org.kuali.rice.kim.api.identity.address.EntityAddress;
41  import org.kuali.rice.kim.api.identity.address.EntityAddressContract;
42  import org.kuali.rice.kim.api.identity.affiliation.EntityAffiliation;
43  import org.kuali.rice.kim.api.identity.email.EntityEmail;
44  import org.kuali.rice.kim.api.identity.email.EntityEmailContract;
45  import org.kuali.rice.kim.api.identity.employment.EntityEmployment;
46  import org.kuali.rice.kim.api.identity.entity.Entity;
47  import org.kuali.rice.kim.api.identity.entity.EntityDefault;
48  import org.kuali.rice.kim.api.identity.name.EntityName;
49  import org.kuali.rice.kim.api.identity.phone.EntityPhone;
50  import org.kuali.rice.kim.api.identity.phone.EntityPhoneContract;
51  import org.kuali.rice.kim.api.identity.principal.Principal;
52  import org.kuali.rice.kim.api.identity.privacy.EntityPrivacyPreferences;
53  import org.kuali.rice.kim.api.identity.type.EntityTypeContactInfo;
54  import org.kuali.rice.kim.api.permission.PermissionService;
55  import org.kuali.rice.kim.api.responsibility.ResponsibilityService;
56  import org.kuali.rice.kim.api.role.Role;
57  import org.kuali.rice.kim.api.role.RoleMember;
58  import org.kuali.rice.kim.api.role.RoleService;
59  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
60  import org.kuali.rice.kim.api.type.KimAttributeField;
61  import org.kuali.rice.kim.api.type.KimType;
62  import org.kuali.rice.kim.api.type.KimTypeAttribute;
63  import org.kuali.rice.kim.api.type.KimTypeInfoService;
64  import org.kuali.rice.kim.bo.ui.GroupDocumentMember;
65  import org.kuali.rice.kim.bo.ui.GroupDocumentQualifier;
66  import org.kuali.rice.kim.bo.ui.KimDocumentRoleMember;
67  import org.kuali.rice.kim.bo.ui.KimDocumentRolePermission;
68  import org.kuali.rice.kim.bo.ui.KimDocumentRoleQualifier;
69  import org.kuali.rice.kim.bo.ui.KimDocumentRoleResponsibility;
70  import org.kuali.rice.kim.bo.ui.KimDocumentRoleResponsibilityAction;
71  import org.kuali.rice.kim.bo.ui.PersonDocumentAddress;
72  import org.kuali.rice.kim.bo.ui.PersonDocumentAffiliation;
73  import org.kuali.rice.kim.bo.ui.PersonDocumentEmail;
74  import org.kuali.rice.kim.bo.ui.PersonDocumentEmploymentInfo;
75  import org.kuali.rice.kim.bo.ui.PersonDocumentGroup;
76  import org.kuali.rice.kim.bo.ui.PersonDocumentName;
77  import org.kuali.rice.kim.bo.ui.PersonDocumentPhone;
78  import org.kuali.rice.kim.bo.ui.PersonDocumentPrivacy;
79  import org.kuali.rice.kim.bo.ui.PersonDocumentRole;
80  import org.kuali.rice.kim.bo.ui.RoleDocumentDelegation;
81  import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMember;
82  import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMemberQualifier;
83  import org.kuali.rice.kim.document.IdentityManagementGroupDocument;
84  import org.kuali.rice.kim.document.IdentityManagementPersonDocument;
85  import org.kuali.rice.kim.document.IdentityManagementRoleDocument;
86  import org.kuali.rice.kim.framework.services.KimFrameworkServiceLocator;
87  import org.kuali.rice.kim.framework.type.KimTypeService;
88  import org.kuali.rice.kim.impl.KIMPropertyConstants;
89  import org.kuali.rice.kim.impl.common.attribute.KimAttributeDataBo;
90  import org.kuali.rice.kim.impl.common.delegate.DelegateTypeBo;
91  import org.kuali.rice.kim.impl.common.delegate.DelegateMemberAttributeDataBo;
92  import org.kuali.rice.kim.impl.common.delegate.DelegateMemberBo;
93  import org.kuali.rice.kim.impl.group.GroupAttributeBo;
94  import org.kuali.rice.kim.impl.group.GroupBo;
95  import org.kuali.rice.kim.impl.group.GroupMemberBo;
96  import org.kuali.rice.kim.impl.identity.IdentityArchiveService;
97  import org.kuali.rice.kim.impl.identity.address.EntityAddressBo;
98  import org.kuali.rice.kim.impl.identity.address.EntityAddressTypeBo;
99  import org.kuali.rice.kim.impl.identity.affiliation.EntityAffiliationBo;
100 import org.kuali.rice.kim.impl.identity.affiliation.EntityAffiliationTypeBo;
101 import org.kuali.rice.kim.impl.identity.email.EntityEmailBo;
102 import org.kuali.rice.kim.impl.identity.email.EntityEmailTypeBo;
103 import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentBo;
104 import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentStatusBo;
105 import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentTypeBo;
106 import org.kuali.rice.kim.impl.identity.entity.EntityBo;
107 import org.kuali.rice.kim.impl.identity.name.EntityNameBo;
108 import org.kuali.rice.kim.impl.identity.name.EntityNameTypeBo;
109 import org.kuali.rice.kim.impl.identity.phone.EntityPhoneBo;
110 import org.kuali.rice.kim.impl.identity.phone.EntityPhoneTypeBo;
111 import org.kuali.rice.kim.impl.identity.principal.PrincipalBo;
112 import org.kuali.rice.kim.impl.identity.privacy.EntityPrivacyPreferencesBo;
113 import org.kuali.rice.kim.impl.identity.type.EntityTypeContactInfoBo;
114 import org.kuali.rice.kim.impl.permission.PermissionBo;
115 import org.kuali.rice.kim.impl.responsibility.ResponsibilityInternalService;
116 import org.kuali.rice.kim.impl.role.RoleBo;
117 import org.kuali.rice.kim.impl.role.RoleBoLite;
118 import org.kuali.rice.kim.impl.role.RoleMemberAttributeDataBo;
119 import org.kuali.rice.kim.impl.role.RoleMemberBo;
120 import org.kuali.rice.kim.impl.role.RolePermissionBo;
121 import org.kuali.rice.kim.impl.role.RoleResponsibilityActionBo;
122 import org.kuali.rice.kim.impl.role.RoleResponsibilityBo;
123 import org.kuali.rice.kim.impl.services.KimImplServiceLocator;
124 import org.kuali.rice.kim.impl.type.KimTypeBo;
125 import org.kuali.rice.kim.service.KIMServiceLocatorInternal;
126 import org.kuali.rice.kim.service.UiDocumentService;
127 import org.kuali.rice.kim.service.dao.UiDocumentServiceDAO;
128 import org.kuali.rice.kim.util.KimCommonUtilsInternal;
129 import org.kuali.rice.kns.datadictionary.exporter.AttributesMapBuilder;
130 import org.kuali.rice.kns.kim.type.DataDictionaryTypeServiceHelper;
131 import org.kuali.rice.kns.service.DocumentHelperService;
132 import org.kuali.rice.kns.service.KNSServiceLocator;
133 import org.kuali.rice.krad.bo.BusinessObject;
134 import org.kuali.rice.krad.bo.PersistableBusinessObject;
135 import org.kuali.rice.krad.datadictionary.AttributeDefinition;
136 import org.kuali.rice.krad.datadictionary.exporter.ExportMap;
137 import org.kuali.rice.krad.document.Document;
138 import org.kuali.rice.krad.service.BusinessObjectService;
139 import org.kuali.rice.krad.service.KRADServiceLocator;
140 import org.kuali.rice.krad.util.KRADConstants;
141 import org.kuali.rice.krad.util.ObjectUtils;
142 
143 import java.sql.Timestamp;
144 import java.util.ArrayList;
145 import java.util.Collection;
146 import java.util.Collections;
147 import java.util.Comparator;
148 import java.util.HashMap;
149 import java.util.HashSet;
150 import java.util.List;
151 import java.util.Map;
152 import java.util.Set;
153 
154 /**
155  * This is a description of what this class does - shyu don't forget to fill this in.
156  *
157  * @author Kuali Rice Team (rice.collab@kuali.org)
158  *
159  */
160 public class UiDocumentServiceImpl implements UiDocumentService {
161 	private static final Logger LOG = Logger.getLogger(UiDocumentServiceImpl.class);
162 	private static final String SHOW_BLANK_QUALIFIERS = "kim.show.blank.qualifiers";
163     private static final String KIM_IDENTITY_ARCHIVE_SERVICE = "kimIdentityArchiveService";
164 
165     private IdentityArchiveService identityArchiveService;
166     private RoleService roleService;
167 	private BusinessObjectService businessObjectService;
168 	private IdentityService identityService;
169     private PermissionService permissionService;
170 	private GroupService groupService;
171 	private ResponsibilityService responsibilityService;
172     private ResponsibilityInternalService responsibilityInternalService;
173 	private KimTypeInfoService kimTypeInfoService;
174     private DocumentHelperService documentHelperService;
175     private ParameterService parameterService;
176     private UiDocumentServiceDAO uiDocumentServiceDAO;
177 
178     /**
179 	 * @see org.kuali.rice.kim.service.UiDocumentService#saveEntityPerson(IdentityManagementPersonDocument)
180 	 */
181 	public void saveEntityPerson(
182 	    IdentityManagementPersonDocument identityManagementPersonDocument) {
183 		EntityBo kimEntity = new EntityBo();
184 		EntityBo origEntity = getEntityBo(identityManagementPersonDocument.getEntityId());
185 		boolean creatingNew = true;
186 		if (origEntity == null) {
187 			origEntity = new EntityBo();
188 			kimEntity.setActive(true);
189 		} else {
190 			// TODO : in order to resolve optimistic locking issue. has to get identity and set the version number if identity records matched
191 			// Need to look into this.
192 			//kimEntity = origEntity;
193 			kimEntity.setActive(origEntity.isActive());
194 			kimEntity.setVersionNumber(origEntity.getVersionNumber());
195 			creatingNew = false;
196 		}
197 
198 		kimEntity.setId(identityManagementPersonDocument.getEntityId());
199 		String initiatorPrincipalId = getInitiatorPrincipalId(identityManagementPersonDocument);
200 		boolean inactivatingPrincipal = false;
201 		if(canModifyEntity(initiatorPrincipalId, identityManagementPersonDocument.getPrincipalId())){
202 			inactivatingPrincipal = setupPrincipal(identityManagementPersonDocument, kimEntity, origEntity.getPrincipals());
203 			setupAffiliation(identityManagementPersonDocument, kimEntity, origEntity.getAffiliations(), origEntity.getEmploymentInformation());
204 			setupName(identityManagementPersonDocument, kimEntity, origEntity.getNames());
205 		// entitytype
206 			List<EntityTypeContactInfoBo> entityTypes = new ArrayList<EntityTypeContactInfoBo>();
207 			EntityTypeContactInfoBo entityType = new EntityTypeContactInfoBo();
208 			entityType.setEntityId(identityManagementPersonDocument.getEntityId());
209 			entityType.setEntityTypeCode(KimConstants.EntityTypes.PERSON);
210 			entityType.setActive(true);
211 			entityTypes.add(entityType);
212 			EntityTypeContactInfoBo origEntityType = new EntityTypeContactInfoBo();
213 			for (EntityTypeContactInfoBo type : origEntity.getEntityTypeContactInfos()) {
214 				// should check identity.entitytypeid, but it's not persist in persondoc yet
215 				if (type.getEntityTypeCode()!=null && StringUtils.equals(type.getEntityTypeCode(), entityType.getEntityTypeCode())) {
216 					origEntityType = type;
217 					entityType.setVersionNumber(type.getVersionNumber());
218 					entityType.setActive(type.isActive());
219 				}
220 			}
221 			setupPhone(identityManagementPersonDocument, entityType, origEntityType.getPhoneNumbers());
222 			setupEmail(identityManagementPersonDocument, entityType, origEntityType.getEmailAddresses());
223 			setupAddress(identityManagementPersonDocument, entityType, origEntityType.getAddresses());
224             kimEntity.setEntityTypeContactInfos(entityTypes);
225 		} else{
226 			if(ObjectUtils.isNotNull(origEntity.getExternalIdentifiers())) {
227                 kimEntity.setExternalIdentifiers(origEntity.getExternalIdentifiers());
228             }
229 			if(ObjectUtils.isNotNull(origEntity.getEmploymentInformation())) {
230                 kimEntity.setEmploymentInformation(origEntity.getEmploymentInformation());
231             }
232 			if(ObjectUtils.isNotNull(origEntity.getAffiliations())) {
233                 kimEntity.setAffiliations(origEntity.getAffiliations());
234             }
235 			if(ObjectUtils.isNotNull(origEntity.getNames())) {
236                 kimEntity.setNames(origEntity.getNames());
237             }
238 			if(ObjectUtils.isNotNull(origEntity.getEntityTypeContactInfos())) {
239                 kimEntity.setEntityTypeContactInfos(origEntity.getEntityTypeContactInfos());
240             }
241 		}
242 		if(creatingNew || canOverrideEntityPrivacyPreferences(getInitiatorPrincipalId(identityManagementPersonDocument), identityManagementPersonDocument.getPrincipalId())) {
243 			setupPrivacy(identityManagementPersonDocument, kimEntity, origEntity.getPrivacyPreferences());
244 		} else {
245 			if(ObjectUtils.isNotNull(origEntity.getPrivacyPreferences())) {
246 				kimEntity.setPrivacyPreferences(origEntity.getPrivacyPreferences());
247 			}
248 		}
249 		List <GroupMemberBo>  groupPrincipals = populateGroupMembers(identityManagementPersonDocument);
250 		List <RoleMemberBo>  rolePrincipals = populateRoleMembers(identityManagementPersonDocument);
251 		List <DelegateTypeBo> personDelegations = populateDelegations(identityManagementPersonDocument);
252 		List <PersistableBusinessObject> bos = new ArrayList<PersistableBusinessObject>();
253 		List <RoleResponsibilityActionBo> roleRspActions = populateRoleRspActions(identityManagementPersonDocument);
254 		List <RoleMemberAttributeDataBo> blankRoleMemberAttrs = getBlankRoleMemberAttrs(rolePrincipals);
255 		bos.add(kimEntity);
256 		//if(ObjectUtils.isNotNull(kimEntity.getPrivacyPreferences()))
257 		//	bos.add(kimEntity.getPrivacyPreferences());
258 		bos.addAll(groupPrincipals);
259 		bos.addAll(rolePrincipals);
260 		bos.addAll(roleRspActions);
261 		bos.addAll(personDelegations);
262 		// boservice.save(bos) does not handle deleteawarelist
263 		getBusinessObjectService().save(bos);
264 
265 		if (!blankRoleMemberAttrs.isEmpty()) {
266 			getBusinessObjectService().delete(blankRoleMemberAttrs);
267 		}
268 		if ( inactivatingPrincipal ) {
269 			//when a person is inactivated, inactivate their group, role, and delegation memberships
270 			KimImplServiceLocator.getRoleInternalService().principalInactivated(
271                     identityManagementPersonDocument.getPrincipalId());
272 		}
273 	}
274 
275 	private String getInitiatorPrincipalId(Document document){
276 		try{
277 			return document.getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId();
278 		} catch(Exception ex){
279 			return null;
280 		}
281 	}
282 
283 	public Map<String,Object> getAttributeEntries( List<KimAttributeField> definitions ) {
284 		final Map<String,Object> attributeEntries = new HashMap<String,Object>();
285 		if (definitions != null) {
286 	        for (AttributeDefinition definition : DataDictionaryTypeServiceHelper.toKimAttributeDefinitions(definitions)) {
287 				final AttributesMapBuilder builder = new AttributesMapBuilder();
288                 final ExportMap map = builder.buildAttributeMap(definition, "");
289                 attributeEntries.put(definition.getName(),map.getExportData());
290 			}
291 		}
292         return attributeEntries;
293 	}
294 
295 
296 	/**
297 	 *
298 	 * @see org.kuali.rice.kim.service.UiDocumentService#loadEntityToPersonDoc(IdentityManagementPersonDocument, String)
299 	 */
300 	public void loadEntityToPersonDoc(IdentityManagementPersonDocument identityManagementPersonDocument, String principalId) {
301 		Principal principal = this.getIdentityService().getPrincipal(principalId);
302         Entity kimEntity = null;
303 
304         if(ObjectUtils.isNotNull(principal)) {
305             // If the principal is not null it was found in the identity management service
306             kimEntity = this.getIdentityService().getEntity(principal.getEntityId());
307         }
308 
309         if(ObjectUtils.isNull(principal) || ObjectUtils.isNull(kimEntity)) {
310             // If the principal or entity is null look up the entity in the
311             // archive service, and then get the principal from it
312             IdentityArchiveService identityArchive = getIdentityArchiveService();
313             EntityDefault entityInfo = identityArchive.getEntityDefaultFromArchiveByPrincipalId(principalId);
314             principal = entityInfo.getPrincipals().get(0);
315             Entity.Builder eb  = Entity.Builder.create();
316             eb.setId(entityInfo.getEntityId());
317             kimEntity = eb.build();
318 
319         }
320         if(kimEntity == null) {
321             throw new RuntimeException("Entity does not exist for principal id: " + principalId);
322         }
323         if(principal==null) {
324         	throw new RuntimeException("Principal does not exist for principal id:"+principalId);
325         }
326 
327         identityManagementPersonDocument.setPrincipalId(principal.getPrincipalId());
328         identityManagementPersonDocument.setPrincipalName(principal.getPrincipalName());
329         //identityManagementPersonDocument.setPassword(principal.getPassword());
330         identityManagementPersonDocument.setActive(principal.isActive());
331 		identityManagementPersonDocument.setEntityId(kimEntity.getId());
332 		if ( ObjectUtils.isNotNull( kimEntity.getPrivacyPreferences() ) ) {
333 			identityManagementPersonDocument.setPrivacy(loadPrivacyReferences(kimEntity.getPrivacyPreferences()));
334 		}
335 		//identityManagementPersonDocument.setActive(kimEntity.isActive());
336 		identityManagementPersonDocument.setAffiliations(loadAffiliations(kimEntity.getAffiliations(),kimEntity.getEmploymentInformation()));
337 		identityManagementPersonDocument.setNames(loadNames( identityManagementPersonDocument, principalId, kimEntity.getNames(), identityManagementPersonDocument.getPrivacy().isSuppressName() ));
338 		EntityTypeContactInfo entityType = null;
339 		for (EntityTypeContactInfo type : kimEntity.getEntityTypeContactInfos()) {
340 			if (KimConstants.EntityTypes.PERSON.equals(type.getEntityTypeCode())) {
341 				entityType = EntityTypeContactInfo.Builder.create(type).build();
342 			}
343 		}
344 
345 		if(entityType!=null){
346 			identityManagementPersonDocument.setEmails(loadEmails(identityManagementPersonDocument, principalId, entityType.getEmailAddresses(), identityManagementPersonDocument.getPrivacy().isSuppressEmail()));
347 			identityManagementPersonDocument.setPhones(loadPhones(identityManagementPersonDocument, principalId, entityType.getPhoneNumbers(), identityManagementPersonDocument.getPrivacy().isSuppressPhone()));
348 			identityManagementPersonDocument.setAddrs(loadAddresses(identityManagementPersonDocument, principalId, entityType.getAddresses(), identityManagementPersonDocument.getPrivacy().isSuppressAddress()));
349 		}
350 
351 		List<Group> groups = getGroupService().getGroups(getGroupService().getDirectGroupIdsByPrincipalId(
352                 identityManagementPersonDocument.getPrincipalId()));
353 		loadGroupToPersonDoc(identityManagementPersonDocument, groups);
354 		loadRoleToPersonDoc(identityManagementPersonDocument);
355 		loadDelegationsToPersonDoc(identityManagementPersonDocument);
356 	}
357 
358     @SuppressWarnings("unchecked")
359 	public List<DelegateTypeBo> getPersonDelegations(String principalId){
360 		if(principalId==null) {
361 			return new ArrayList<DelegateTypeBo>();
362         }
363 		Map<String,String> criteria = new HashMap<String,String>(1);
364 		criteria.put(KimConstants.PrimaryKeyConstants.MEMBER_ID, principalId);
365 		criteria.put( KIMPropertyConstants.DelegationMember.MEMBER_TYPE_CODE, MemberType.PRINCIPAL.getCode() );
366 		List<DelegateMemberBo> delegationMembers = (List<DelegateMemberBo>)getBusinessObjectService().findMatching(DelegateMemberBo.class, criteria);
367 		List<DelegateTypeBo> delegations = new ArrayList<DelegateTypeBo>();
368 		List<String> delegationIds = new ArrayList<String>();
369 		if(ObjectUtils.isNotNull(delegationMembers)){
370 			for(DelegateMemberBo delegationMember: delegationMembers){
371 				if(!delegationIds.contains(delegationMember.getDelegationId())){
372 					delegationIds.add(delegationMember.getDelegationId());
373 					criteria = new HashMap<String,String>(1);
374 					criteria.put(KimConstants.PrimaryKeyConstants.DELEGATION_ID, delegationMember.getDelegationId());
375 					delegations.add(getBusinessObjectService().findByPrimaryKey(DelegateTypeBo.class, criteria));
376 				}
377 			}
378 		}
379 		return delegations;
380 	}
381 
382 
383     protected void loadDelegationsToPersonDoc(IdentityManagementPersonDocument identityManagementPersonDocument){
384 		List<RoleDocumentDelegation> delList = new ArrayList<RoleDocumentDelegation>();
385 		RoleDocumentDelegation documentDelegation;
386 		List<DelegateTypeBo> origDelegations = getPersonDelegations(identityManagementPersonDocument.getPrincipalId());
387 		if(ObjectUtils.isNotNull(origDelegations)){
388 			for(DelegateTypeBo del: origDelegations){
389 				if(del.isActive()){
390 					documentDelegation = new RoleDocumentDelegation();
391 					documentDelegation.setActive(del.isActive());
392 					documentDelegation.setDelegationId(del.getDelegationId());
393 					documentDelegation.setDelegationTypeCode(del.getDelegationTypeCode());
394 					documentDelegation.setKimTypeId(del.getKimTypeId());
395 					documentDelegation.setMembers(
396 							loadDelegationMembers(identityManagementPersonDocument,
397 									del.getMembers(), (RoleBo)getMember(MemberType.ROLE, del.getRoleId())));
398 					documentDelegation.setRoleId(del.getRoleId());
399 					documentDelegation.setEdit(true);
400 					delList.add(documentDelegation);
401 				}
402 			}
403 		}
404 		identityManagementPersonDocument.setDelegations(delList);
405 		setDelegationMembersInDocument(identityManagementPersonDocument);
406 	}
407 
408 	public void setDelegationMembersInDocument(IdentityManagementPersonDocument identityManagementPersonDocument){
409 		if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getDelegations())){
410 			for(RoleDocumentDelegation delegation: identityManagementPersonDocument.getDelegations()){
411 				if(CollectionUtils.isNotEmpty(delegation.getMembers())){
412 					for(RoleDocumentDelegationMember member: delegation.getMembers()){
413 						if (StringUtils.equals(member.getMemberId(), identityManagementPersonDocument.getPrincipalId()))
414 						{
415 						    member.setDelegationTypeCode(delegation.getDelegationTypeCode());
416 						    identityManagementPersonDocument.getDelegationMembers().add(member);
417 						}
418 					}
419 				}
420 			}
421 		}
422 	}
423 
424     protected List<RoleDocumentDelegationMember> loadDelegationMembers(
425     		IdentityManagementPersonDocument identityManagementPersonDocument, List<DelegateMemberBo> members, RoleBo roleImpl){
426 		List<RoleDocumentDelegationMember> pndMembers = new ArrayList<RoleDocumentDelegationMember>();
427 		RoleDocumentDelegationMember pndMember;
428 		RoleMemberBo roleMember;
429 		if(ObjectUtils.isNotNull(members)){
430 			for(DelegateMemberBo member: members){
431 				pndMember = new RoleDocumentDelegationMember();
432 				pndMember.setActiveFromDate(member.getActiveFromDateValue());
433 				pndMember.setActiveToDate(member.getActiveToDateValue());
434 				pndMember.setActive(member.isActive(new Timestamp(System.currentTimeMillis())));
435 				pndMember.setRoleBo(roleImpl);
436 				if(pndMember.isActive()){
437                     pndMember.setMemberId(member.getMemberId());
438                     pndMember.setDelegationMemberId(member.getDelegationMemberId());
439                     pndMember.setMemberTypeCode(member.getType().getCode());
440                     pndMember.setDelegationId(member.getDelegationId());
441                     pndMember.setVersionNumber(member.getVersionNumber());
442                     pndMember.setObjectId(member.getObjectId());
443 
444 					pndMember.setRoleMemberId(member.getRoleMemberId());
445 					roleMember = getRoleMemberForRoleMemberId(member.getRoleMemberId());
446 					if(roleMember!=null){
447 						pndMember.setRoleMemberName(getMemberName(roleMember.getType(), roleMember.getMemberId()));
448 						pndMember.setRoleMemberNamespaceCode(getMemberNamespaceCode(roleMember.getType(), roleMember.getMemberId()));
449 					}
450 					pndMember.setMemberNamespaceCode(getMemberNamespaceCode(member.getType(), member.getMemberId()));
451 					pndMember.setMemberName(getMemberName(member.getType(), member.getMemberId()));
452 					pndMember.setEdit(true);
453 					pndMember.setQualifiers(loadDelegationMemberQualifiers(identityManagementPersonDocument, pndMember.getAttributesHelper().getDefinitions(), member.getAttributeDetails()));
454 					pndMembers.add(pndMember);
455 				}
456 			}
457 		}
458 		return pndMembers;
459 	}
460 
461     protected List<RoleDocumentDelegationMemberQualifier> loadDelegationMemberQualifiers(IdentityManagementPersonDocument identityManagementPersonDocument,
462     		List<KimAttributeField> origAttributeDefinitions, List<DelegateMemberAttributeDataBo> attributeDataList){
463 		List<RoleDocumentDelegationMemberQualifier> pndMemberRoleQualifiers = new ArrayList<RoleDocumentDelegationMemberQualifier>();
464 		RoleDocumentDelegationMemberQualifier pndMemberRoleQualifier;
465 		boolean attributePresent = false;
466 		String origAttributeId;
467 		if(origAttributeDefinitions!=null){
468 			for(KimAttributeField key: origAttributeDefinitions) {
469 				origAttributeId = identityManagementPersonDocument.getKimAttributeDefnId(key);
470 				if(ObjectUtils.isNotNull(attributeDataList)){
471 					for(DelegateMemberAttributeDataBo memberRoleQualifier: attributeDataList){
472 						if(StringUtils.equals(origAttributeId, memberRoleQualifier.getKimAttribute().getId())){
473 							pndMemberRoleQualifier = new RoleDocumentDelegationMemberQualifier();
474 							pndMemberRoleQualifier.setAttrDataId(memberRoleQualifier.getId());
475 							pndMemberRoleQualifier.setAttrVal(memberRoleQualifier.getAttributeValue());
476 							pndMemberRoleQualifier.setDelegationMemberId(memberRoleQualifier.getAssignedToId());
477 							pndMemberRoleQualifier.setKimTypId(memberRoleQualifier.getKimTypeId());
478 							pndMemberRoleQualifier.setKimAttrDefnId(memberRoleQualifier.getKimAttributeId());
479 							pndMemberRoleQualifier.setKimAttribute(memberRoleQualifier.getKimAttribute());
480 							pndMemberRoleQualifiers.add(pndMemberRoleQualifier);
481 							attributePresent = true;
482 						}
483 					}
484 				}
485 				if(!attributePresent){
486 					pndMemberRoleQualifier = new RoleDocumentDelegationMemberQualifier();
487 					pndMemberRoleQualifier.setKimAttrDefnId(origAttributeId);
488 					pndMemberRoleQualifiers.add(pndMemberRoleQualifier);
489 				}
490 				attributePresent = false;
491 			}
492 		}
493 		return pndMemberRoleQualifiers;
494 	}
495 
496 	/**
497 	 *
498      * This method loads related group data to pending person document when user initiates the 'edit' or 'inquiry'.
499      *
500 	 * @param identityManagementPersonDocument
501 	 * @param groups
502 	 */
503     protected void loadGroupToPersonDoc(IdentityManagementPersonDocument identityManagementPersonDocument, List<? extends Group> groups) {
504         List <PersonDocumentGroup> docGroups = new ArrayList <PersonDocumentGroup>();
505         if(ObjectUtils.isNotNull(groups)){
506             for (Group group: groups) {
507                 if (getGroupService().isDirectMemberOfGroup(identityManagementPersonDocument.getPrincipalId(), group.getId())) {
508                     PersonDocumentGroup docGroup = new PersonDocumentGroup();
509                     docGroup.setGroupId(group.getId());
510                     docGroup.setGroupName(group.getName());
511                     docGroup.setNamespaceCode(group.getNamespaceCode());
512                     docGroup.setPrincipalId(identityManagementPersonDocument.getPrincipalId());
513                     Collection<GroupMember> groupMemberships = null;
514                     groupMemberships = getGroupService().getMembersOfGroup(group.getId());
515 
516                     if(ObjectUtils.isNotNull(groupMemberships)){
517                         for (GroupMember groupMember: groupMemberships) {
518                             if (StringUtils.equals(groupMember.getMemberId(), identityManagementPersonDocument.getPrincipalId()) &&
519                                     KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE.equals(groupMember.getType())) {
520                                 docGroup.setGroupMemberId(groupMember.getId());
521                                 if (groupMember.getActiveFromDate() != null) {
522                                     docGroup.setActiveFromDate(groupMember.getActiveFromDate() == null ? null : new Timestamp(groupMember.getActiveFromDate().getMillis()));
523                                 }
524                                 if (groupMember.getActiveToDate() != null) {
525                                     docGroup.setActiveToDate(groupMember.getActiveToDate() == null ? null : new Timestamp(groupMember.getActiveToDate().getMillis()));
526                                 }
527                                 continue;
528                             }
529                         }
530                     }
531                     docGroup.setKimTypeId(group.getKimTypeId());
532                     docGroup.setEdit(true);
533                     docGroups.add(docGroup);
534                 }
535             }
536         }
537         identityManagementPersonDocument.setGroups(docGroups);
538     }
539 
540 	/**
541 	 * Used to populate the {@link PersonDocumentRole} ojbects for a {@link IdentityManagementPersonDocument}
542 	 *
543 	 * @param identityManagementPersonDocument {@link IdentityManagementPersonDocument}
544 	 */
545     protected void loadRoleToPersonDoc(IdentityManagementPersonDocument identityManagementPersonDocument) {
546         List <PersonDocumentRole> docRoles = new ArrayList <PersonDocumentRole>();
547         // a list for Id's of the roles added to docRoles
548         List<String> roleIds = new ArrayList<String>();
549 
550         // get the membership objects for the PrincipalId
551         List<RoleMemberBo> roleMembers = getRoleMembersForPrincipal(identityManagementPersonDocument.getPrincipalId());
552 
553         // if the PrincipalId is a member of any roles, add those roles to docRoles
554         if(ObjectUtils.isNotNull(roleMembers)){
555             // for each membership get the role and add it to docRoles
556             for (RoleMemberBo member : roleMembers) {
557                 loadDocRoles(docRoles, roleIds, member);
558             }
559         }
560 
561         // complete the attributes for each role being being returned
562         for (PersonDocumentRole role : docRoles) {
563             role.setDefinitions(getAttributeDefinitionsForRole(role));
564 
565             KimDocumentRoleMember newRolePrncpl = new KimDocumentRoleMember();
566             newRolePrncpl.setMemberTypeCode(MemberType.PRINCIPAL.getCode());
567             newRolePrncpl.setMemberId(identityManagementPersonDocument.getPrincipalId());
568             role.setNewRolePrncpl(newRolePrncpl);
569 
570             if(role.getDefinitions()!=null){
571                 for (KimAttributeField key : role.getDefinitions()) {
572                     KimDocumentRoleQualifier qualifier = new KimDocumentRoleQualifier();
573                     setAttrDefnIdForQualifier(qualifier,key);
574                     role.getNewRolePrncpl().getQualifiers().add(qualifier);
575                 }
576             }
577 
578             // load the role's ResponsibilityActions
579             loadRoleRstAction(role);
580 
581             role.setAttributeEntry( getAttributeEntries( role.getDefinitions() ) );
582         }
583 
584         // add the PersonDocumentRoles to the IdentityManagementPersonDocument
585         identityManagementPersonDocument.setRoles(docRoles);
586     }
587 
588     /**
589      * Selects a {@link RoleBoLite} for passed {@link RoleMemberBo} and adds to List of {@link PersonDocumentRole} objects
590      *
591      * @param docRoles a list of {@link PersonDocumentRole} roles
592      * @param roleIds a list of the Ids of the Roles already added
593      * @param member a {@link RoleMemberBo} of a {@link RoleBoLite}
594      */
595     private void loadDocRoles(List <PersonDocumentRole> docRoles, List<String> roleIds,  RoleMemberBo member) {
596 
597         // get the RoleBoLite object by it's Id from a role membership object
598         RoleBoLite role =  getBusinessObjectService().findBySinglePrimaryKey(RoleBoLite.class, member.getRoleId());
599 
600         // if not already found add role to docRoles
601         if (ObjectUtils.isNotNull(role) && !roleIds.contains(role.getId())) {
602             PersonDocumentRole docRole = new PersonDocumentRole();
603             docRole.setKimTypeId(role.getKimTypeId());
604             docRole.setActive(role.isActive());
605             docRole.setNamespaceCode(role.getNamespaceCode());
606             docRole.setEdit(true);
607             docRole.setRoleId(role.getId());
608             docRole.setRoleName(role.getName());
609             docRole.refreshReferenceObject("assignedResponsibilities");
610             docRoles.add(docRole);
611             roleIds.add(role.getId());
612         }
613     }
614 
615 	protected List<KimAttributeField> getAttributeDefinitionsForRole(PersonDocumentRole role) {
616     	KimTypeService kimTypeService = KimFrameworkServiceLocator.getKimTypeService(KimTypeBo.to(
617                 role.getKimRoleType()));
618     	//it is possible that the the kimTypeService is coming from a remote application
619         // and therefore it can't be guarenteed that it is up and working, so using a try/catch to catch this possibility.
620         try {
621         	if ( kimTypeService != null ) {
622         		return kimTypeService.getAttributeDefinitions(role.getKimTypeId());
623         	}
624         } catch (Exception ex) {
625             LOG.warn("Not able to retrieve KimTypeService from remote system for KIM Role Type: " + role.getKimRoleType(), ex);
626         }
627     	return Collections.emptyList();
628 	}
629 
630 	protected void loadRoleRstAction(PersonDocumentRole role) {
631 		if(role!=null && CollectionUtils.isNotEmpty(role.getRolePrncpls())){
632 			for (KimDocumentRoleMember roleMbr : role.getRolePrncpls()) {
633 				List<RoleResponsibilityActionBo> actions = getRoleRspActions( roleMbr.getRoleMemberId());
634 				if(ObjectUtils.isNotNull(actions)){
635 					for (RoleResponsibilityActionBo entRoleRspAction :actions) {
636 						KimDocumentRoleResponsibilityAction roleRspAction = new KimDocumentRoleResponsibilityAction();
637 						roleRspAction.setRoleResponsibilityActionId(entRoleRspAction.getId());
638                         roleRspAction.setRoleResponsibilityId(entRoleRspAction.getRoleResponsibilityId());
639 						roleRspAction.setActionTypeCode(entRoleRspAction.getActionTypeCode());
640 						roleRspAction.setActionPolicyCode(entRoleRspAction.getActionPolicyCode());
641 						roleRspAction.setPriorityNumber(entRoleRspAction.getPriorityNumber());
642 						roleRspAction.setRoleResponsibilityActionId(entRoleRspAction.getId());
643 						roleRspAction.refreshReferenceObject("roleResponsibility");
644 						roleMbr.getRoleRspActions().add(roleRspAction);
645 					}
646 				}
647 			}
648 		}
649 	}
650 
651 	protected void setAttrDefnIdForQualifier(KimDocumentRoleQualifier qualifier, KimAttributeField definition) {
652     	qualifier.setKimAttrDefnId(getAttributeDefnId(definition));
653     	qualifier.refreshReferenceObject("kimAttribute");
654     }
655 
656 	protected String getAttributeDefnId(KimAttributeField definition) {
657     	return definition.getId();
658     }
659 
660 	private PrincipalBo getPrincipalImpl(String principalId) {
661 		Map<String,String> criteria = new HashMap<String,String>(1);
662         criteria.put(KIMPropertyConstants.Principal.PRINCIPAL_ID, principalId);
663 		return (PrincipalBo)getBusinessObjectService().findByPrimaryKey(PrincipalBo.class, criteria);
664 	}
665 
666 	public List<EntityEmployment> getEntityEmploymentInformationInfo(String entityId) {
667         EntityBo entityImpl = getEntityBo(entityId);
668         List<EntityEmployment> empInfos = new ArrayList<EntityEmployment>();
669         EntityEmployment empInfo;
670         if(ObjectUtils.isNotNull(entityImpl) && CollectionUtils.isNotEmpty(entityImpl.getEmploymentInformation())){
671         	for(EntityEmploymentBo empImpl: entityImpl.getEmploymentInformation()){
672             	empInfos.add(EntityEmploymentBo.to(empImpl));
673         	}
674         }
675         return empInfos;
676 	}
677 
678 	private EntityBo getEntityBo(String entityId) {
679 		EntityBo entityImpl = getBusinessObjectService().findBySinglePrimaryKey(EntityBo.class, entityId);
680         //TODO - remove this hack... This is here because currently jpa only seems to be going 2 levels deep on the eager fetching.
681 		if(entityImpl!=null  && entityImpl.getEntityTypeContactInfos() != null) {
682         	for (EntityTypeContactInfoBo et : entityImpl.getEntityTypeContactInfos()) {
683         		et.refresh();
684         	}
685         }
686 		return entityImpl;
687 	}
688 
689     @SuppressWarnings("unchecked")
690 	protected List<RoleBo> getRolesForPrincipal(String principalId) {
691 		if ( principalId == null ) {
692 			return new ArrayList<RoleBo>();
693 		}
694 		Map<String,String> criteria = new HashMap<String,String>( 2 );
695 		criteria.put("members.memberId", principalId);
696 		criteria.put("members.typeCode", MemberType.PRINCIPAL.getCode());
697 		return (List<RoleBo>)getBusinessObjectService().findMatching(RoleBo.class, criteria);
698 	}
699 
700 	@SuppressWarnings("unchecked")
701 	protected List<RoleMemberBo> getRoleMembersForPrincipal(String principalId) {
702 		if ( principalId == null ) {
703 			return new ArrayList<RoleMemberBo>();
704 		}
705 		Map<String,String> criteria = new HashMap<String,String>( 2 );
706 		criteria.put("memberId", principalId);
707 		criteria.put("typeCode", MemberType.PRINCIPAL.getCode());
708 		return (List<RoleMemberBo>)getBusinessObjectService().findMatching(RoleMemberBo.class, criteria);
709 	}
710 
711 	public RoleMemberBo getRoleMember(String id) {
712 		if ( id == null ) {
713 			return null;
714 		}
715 		Map<String,String> criteria = new HashMap<String,String>( 2 );
716 		criteria.put("id", id);
717 		return getBusinessObjectService().findByPrimaryKey(RoleMemberBo.class, criteria);
718 	}
719 
720     @SuppressWarnings("unchecked")
721 	protected List<RoleResponsibilityActionBo> getRoleRspActions(String roleMemberId) {
722 		Map<String,String> criteria = new HashMap<String,String>( 1 );
723 		criteria.put(KIMPropertyConstants.RoleMember.ROLE_MEMBER_ID, roleMemberId);
724 		return (List<RoleResponsibilityActionBo>)getBusinessObjectService().findMatching(RoleResponsibilityActionBo.class, criteria);
725 	}
726 
727     protected List<KimDocumentRoleMember> populateDocRolePrncpl(String namespaceCode, List <RoleMemberBo> roleMembers, String principalId, List<KimAttributeField> definitions) {
728 		List <KimDocumentRoleMember> docRoleMembers = new ArrayList <KimDocumentRoleMember>();
729 		if(ObjectUtils.isNotNull(roleMembers)){
730 	    	for (RoleMemberBo rolePrincipal : roleMembers) {
731 	    		if (rolePrincipal.isActive(new Timestamp(System.currentTimeMillis())) && MemberType.PRINCIPAL.equals(
732                         rolePrincipal.getType()) &&
733 	    				StringUtils.equals(rolePrincipal.getMemberId(), principalId)) {
734 	        		KimDocumentRoleMember docRolePrncpl = new KimDocumentRoleMember();
735 	        		docRolePrncpl.setMemberId(rolePrincipal.getMemberId());
736 	        		docRolePrncpl.setRoleMemberId(rolePrincipal.getId());
737 	        		docRolePrncpl.setActive(rolePrincipal.isActive(new Timestamp(System.currentTimeMillis())));
738 	        		docRolePrncpl.setRoleId(rolePrincipal.getRoleId());
739 	        		docRolePrncpl.setActiveFromDate(rolePrincipal.getActiveFromDateValue());
740 	        		docRolePrncpl.setActiveToDate(rolePrincipal.getActiveToDateValue());
741 	         		docRolePrncpl.setQualifiers(populateDocRoleQualifier(namespaceCode, rolePrincipal.getAttributeDetails(), definitions));
742 	         		docRolePrncpl.setEdit(true);
743 	        		docRoleMembers.add(docRolePrncpl);
744 	    		 }
745 	    	}
746 		}
747     	return docRoleMembers;
748     }
749 
750     // UI layout for rolequalifier is a little different from kimroleattribute set up.
751     // each principal may have member with same role multiple times with different qualifier, but the role
752     // only displayed once, and the qualifier displayed multiple times.
753     protected List<KimDocumentRoleQualifier> populateDocRoleQualifier(String namespaceCode, List <RoleMemberAttributeDataBo> qualifiers, List<KimAttributeField> definitions) {
754 
755 		List <KimDocumentRoleQualifier> docRoleQualifiers = new ArrayList <KimDocumentRoleQualifier>();
756 		if(definitions!=null){
757 			for (KimAttributeField definition : definitions) {
758 				String attrDefId=definition.getId();
759 				boolean qualifierFound = false;
760 				if(ObjectUtils.isNotNull(qualifiers)){
761 					for (RoleMemberAttributeDataBo qualifier : qualifiers) {
762 						if (attrDefId!=null && StringUtils.equals(attrDefId, qualifier.getKimAttributeId())) {
763 				    		KimDocumentRoleQualifier docRoleQualifier = new KimDocumentRoleQualifier();
764 				    		docRoleQualifier.setAttrDataId(qualifier.getId());
765 				    		docRoleQualifier.setAttrVal(qualifier.getAttributeValue());
766 				    		docRoleQualifier.setKimAttrDefnId(qualifier.getKimAttributeId());
767 				    		docRoleQualifier.setKimAttribute(qualifier.getKimAttribute());
768 				    		docRoleQualifier.setKimTypId(qualifier.getKimTypeId());
769 				    		docRoleQualifier.setRoleMemberId(qualifier.getAssignedToId());
770 				    		docRoleQualifier.setEdit(true);
771 				    		formatAttrValIfNecessary(docRoleQualifier);
772 				    		docRoleQualifiers.add(docRoleQualifier);
773 				    		qualifierFound = true;
774 				    		break;
775 						}
776 					}
777 				}
778 				if (!qualifierFound) {
779 		    		KimDocumentRoleQualifier docRoleQualifier = new KimDocumentRoleQualifier();
780 		    		docRoleQualifier.setAttrVal("");
781 		    		docRoleQualifier.setKimAttrDefnId(attrDefId);
782 		    		docRoleQualifier.refreshReferenceObject("kimAttribute");
783 		    		docRoleQualifiers.add(docRoleQualifier);
784 				}
785 			}
786 			// If all of the qualifiers are empty, return an empty list
787 			// This is to prevent dynamic qualifiers from appearing in the
788 			// person maintenance roles tab.  see KULRICE-3989 for more detail
789 			// and KULRICE-5071 for detail on switching from config value to 
790 			// application-scoped parameter
791 			if (!isBlankRoleQualifierVisible(namespaceCode)) {
792 				int qualCount = 0;
793 				for (KimDocumentRoleQualifier qual : docRoleQualifiers){
794 					if (StringUtils.isEmpty(qual.getAttrVal())){
795 						qualCount++;
796 					}
797 				}
798 				if (qualCount == docRoleQualifiers.size()){
799 					return new ArrayList <KimDocumentRoleQualifier>();
800 				}
801 			}
802 		}
803     	return docRoleQualifiers;
804     }
805 
806     protected List<PersonDocumentName> loadNames( IdentityManagementPersonDocument personDoc, String principalId, List <EntityName> names, boolean suppressDisplay ) {
807 		List<PersonDocumentName> docNames = new ArrayList<PersonDocumentName>();
808 		if(ObjectUtils.isNotNull(names)){
809 			for (EntityName name: names) {
810 				if(name.isActive()){
811 					PersonDocumentName docName = new PersonDocumentName();
812                     if (name.getNameType() != null) {
813 					    docName.setNameCode(name.getNameType().getCode());
814                     }
815 
816 					//We do not need to check the privacy setting here - The UI should care of it
817 					docName.setFirstName(name.getFirstNameUnmasked());
818 					docName.setLastName(name.getLastNameUnmasked());
819 					docName.setMiddleName(name.getMiddleNameUnmasked());
820 					docName.setNamePrefix(name.getNamePrefixUnmasked());
821 					docName.setNameSuffix(name.getNameSuffixUnmasked());
822 
823 					docName.setActive(name.isActive());
824 					docName.setDflt(name.isDefaultValue());
825 					docName.setEdit(true);
826 					docName.setEntityNameId(name.getId());
827 					docNames.add(docName);
828 				}
829 			}
830 		}
831 		return docNames;
832 	}
833 
834 	public boolean canModifyEntity( String currentUserPrincipalId, String toModifyPrincipalId ){
835 		return (StringUtils.isNotBlank(currentUserPrincipalId) && StringUtils.isNotBlank(toModifyPrincipalId) &&
836 				currentUserPrincipalId.equals(toModifyPrincipalId)) ||
837 				getPermissionService().isAuthorized(
838 						currentUserPrincipalId,
839 						KimConstants.NAMESPACE_CODE,
840 						KimConstants.PermissionNames.MODIFY_ENTITY,
841 						Collections.singletonMap(KimConstants.AttributeConstants.PRINCIPAL_ID, currentUserPrincipalId));
842 	}
843 
844 	public boolean canOverrideEntityPrivacyPreferences( String currentUserPrincipalId, String toModifyPrincipalId ){
845 		return (StringUtils.isNotBlank(currentUserPrincipalId) && StringUtils.isNotBlank(toModifyPrincipalId) &&
846 				currentUserPrincipalId.equals(toModifyPrincipalId)) ||
847 				getPermissionService().isAuthorized(
848 						currentUserPrincipalId,
849 						KimConstants.NAMESPACE_CODE,
850 						KimConstants.PermissionNames.OVERRIDE_ENTITY_PRIVACY_PREFERENCES,
851 						Collections.singletonMap(KimConstants.AttributeConstants.PRINCIPAL_ID, currentUserPrincipalId) );
852 	}
853 
854 	protected boolean canAssignToRole(IdentityManagementRoleDocument document, String initiatorPrincipalId){
855         boolean rulePassed = true;
856         Map<String,String> additionalPermissionDetails = new HashMap<String,String>();
857         additionalPermissionDetails.put(KimConstants.AttributeConstants.NAMESPACE_CODE, document.getRoleNamespace());
858         additionalPermissionDetails.put(KimConstants.AttributeConstants.ROLE_NAME, document.getRoleName());
859 		if(!getDocumentHelperService().getDocumentAuthorizer(document).isAuthorizedByTemplate(
860 				document, KimConstants.NAMESPACE_CODE, KimConstants.PermissionTemplateNames.ASSIGN_ROLE,
861 				initiatorPrincipalId, additionalPermissionDetails, null)){
862             rulePassed = false;
863 		}
864 		return rulePassed;
865 	}
866 
867 	protected List<PersonDocumentAffiliation> loadAffiliations(List <EntityAffiliation> affiliations, List<EntityEmployment> empInfos) {
868 		List<PersonDocumentAffiliation> docAffiliations = new ArrayList<PersonDocumentAffiliation>();
869 		if(ObjectUtils.isNotNull(affiliations)){
870 			for (EntityAffiliation affiliation: affiliations) {
871 				if(affiliation.isActive()){
872 					PersonDocumentAffiliation docAffiliation = new PersonDocumentAffiliation();
873 					docAffiliation.setAffiliationTypeCode(affiliation.getAffiliationType().getCode());
874 					docAffiliation.setCampusCode(affiliation.getCampusCode());
875 					docAffiliation.setActive(affiliation.isActive());
876 					docAffiliation.setDflt(affiliation.isDefaultValue());
877 					docAffiliation.setEntityAffiliationId(affiliation.getId());
878 					docAffiliation.refreshReferenceObject("affiliationType");
879 					// EntityAffiliationImpl does not define empinfos as collection
880 					docAffiliations.add(docAffiliation);
881 					docAffiliation.setEdit(true);
882 					// employment informations
883 					List<PersonDocumentEmploymentInfo> docEmploymentInformations = new ArrayList<PersonDocumentEmploymentInfo>();
884 					if(ObjectUtils.isNotNull(empInfos)){
885 						for (EntityEmployment empInfo: empInfos) {
886 							if (empInfo.isActive()
887                                     && StringUtils.equals(docAffiliation.getEntityAffiliationId(),
888                                                           (empInfo.getEntityAffiliation() != null ? empInfo.getEntityAffiliation().getId() : null))) {
889 								PersonDocumentEmploymentInfo docEmpInfo = new PersonDocumentEmploymentInfo();
890 								docEmpInfo.setEntityEmploymentId(empInfo.getEmployeeId());
891 								docEmpInfo.setEmployeeId(empInfo.getEmployeeId());
892 								docEmpInfo.setEmploymentRecordId(empInfo.getEmploymentRecordId());
893 								docEmpInfo.setBaseSalaryAmount(empInfo.getBaseSalaryAmount());
894 								docEmpInfo.setPrimaryDepartmentCode(empInfo.getPrimaryDepartmentCode());
895 								docEmpInfo.setEmploymentStatusCode(empInfo.getEmployeeStatus() != null ? empInfo.getEmployeeStatus().getCode() : null);
896 								docEmpInfo.setEmploymentTypeCode(empInfo.getEmployeeType() != null ? empInfo.getEmployeeType().getCode() : null);
897 								docEmpInfo.setActive(empInfo.isActive());
898 								docEmpInfo.setPrimary(empInfo.isPrimary());
899 								docEmpInfo.setEntityAffiliationId(empInfo.getEntityAffiliation() != null ? empInfo.getEntityAffiliation().getId() : null);
900 								// there is no version number on KimEntityEmploymentInformationInfo
901 								//docEmpInfo.setVersionNumber(empInfo.getVersionNumber());
902 								docEmpInfo.setEdit(true);
903 								docEmpInfo.refreshReferenceObject("employmentType");
904 								docEmploymentInformations.add(docEmpInfo);
905 							}
906 						}
907 					}
908 					docAffiliation.setEmpInfos(docEmploymentInformations);
909 				}
910 			}
911 		}
912 		return docAffiliations;
913 
914 	}
915 
916     protected boolean setupPrincipal(IdentityManagementPersonDocument identityManagementPersonDocument, EntityBo kimEntity, List<PrincipalBo> origPrincipals) {
917     	boolean inactivatingPrincipal = false;
918 		List<PrincipalBo> principals = new ArrayList<PrincipalBo>();
919 		PrincipalBo principal = new PrincipalBo();
920         principal.setPrincipalName(identityManagementPersonDocument.getPrincipalName());
921 		principal.setPrincipalId(identityManagementPersonDocument.getPrincipalId());
922 		principal.setActive(identityManagementPersonDocument.isActive());
923 		principal.setEntityId(identityManagementPersonDocument.getEntityId());
924 		if(ObjectUtils.isNotNull(origPrincipals)){
925 			for (PrincipalBo prncpl : origPrincipals) {
926 				if (prncpl.getPrincipalId()!=null && StringUtils.equals(prncpl.getPrincipalId(), principal.getPrincipalId())) {
927 					principal.setVersionNumber(prncpl.getVersionNumber());
928                     principal.setObjectId(prncpl.getObjectId());
929                     principal.setPassword(prncpl.getPassword());
930 					// check if inactivating the principal
931 					if ( prncpl.isActive() && !principal.isActive() ) {
932 						inactivatingPrincipal = true;
933 					}
934 				}
935 			}
936 		}
937 		principals.add(principal);
938 
939 		kimEntity.setPrincipals(principals);
940 		return inactivatingPrincipal;
941 	}
942 
943     protected void setupPrivacy(IdentityManagementPersonDocument identityManagementPersonDocument, EntityBo kimEntity, EntityPrivacyPreferencesBo origPrivacy) {
944 		EntityPrivacyPreferencesBo privacyPreferences = new EntityPrivacyPreferencesBo();
945 		privacyPreferences.setEntityId(identityManagementPersonDocument.getEntityId());
946 		privacyPreferences.setSuppressAddress(identityManagementPersonDocument.getPrivacy().isSuppressAddress());
947 		privacyPreferences.setSuppressEmail(identityManagementPersonDocument.getPrivacy().isSuppressEmail());
948 		privacyPreferences.setSuppressName(identityManagementPersonDocument.getPrivacy().isSuppressName());
949 		privacyPreferences.setSuppressPhone(identityManagementPersonDocument.getPrivacy().isSuppressPhone());
950 		privacyPreferences.setSuppressPersonal(identityManagementPersonDocument.getPrivacy().isSuppressPersonal());
951 		if (ObjectUtils.isNotNull(origPrivacy)) {
952 			privacyPreferences.setVersionNumber(origPrivacy.getVersionNumber());
953             privacyPreferences.setObjectId(origPrivacy.getObjectId());
954 		}
955 		kimEntity.setPrivacyPreferences(privacyPreferences);
956 	}
957     protected PersonDocumentPrivacy loadPrivacyReferences(EntityPrivacyPreferences privacyPreferences) {
958 		PersonDocumentPrivacy docPrivacy = new PersonDocumentPrivacy();
959 		docPrivacy.setSuppressAddress(privacyPreferences.isSuppressAddress());
960 		docPrivacy.setSuppressEmail(privacyPreferences.isSuppressEmail());
961 		docPrivacy.setSuppressName(privacyPreferences.isSuppressName());
962 		docPrivacy.setSuppressPhone(privacyPreferences.isSuppressPhone());
963 		docPrivacy.setSuppressPersonal(privacyPreferences.isSuppressPersonal());
964 		docPrivacy.setEdit(true);
965 		return docPrivacy;
966 	}
967 
968     protected void setupName(IdentityManagementPersonDocument identityManagementPersonDocument, EntityBo kimEntity, List<EntityNameBo> origNames) {
969     	if ( !identityManagementPersonDocument.getPrivacy().isSuppressName() ||
970     			canOverrideEntityPrivacyPreferences( getInitiatorPrincipalId(identityManagementPersonDocument), identityManagementPersonDocument.getPrincipalId() ) ) {
971 	    	List<EntityNameBo> entityNames = new ArrayList<EntityNameBo>();
972 			if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getNames())){
973 				for (PersonDocumentName name : identityManagementPersonDocument.getNames()) {
974 				    EntityNameBo entityName = new EntityNameBo();
975 					entityName.setNameCode(name.getNameCode());
976                     if (name.getEntityNameType() != null) {
977                         entityName.setNameType(name.getEntityNameType());
978                     } else {
979                         if (StringUtils.isNotEmpty(name.getNameCode())) {
980                             entityName.setNameType(
981                                     EntityNameTypeBo.from(getIdentityService().getNameType(name.getNameCode())));
982                         }
983                     }
984 					entityName.setFirstName(name.getFirstName());
985 					entityName.setLastName(name.getLastName());
986 					entityName.setMiddleName(name.getMiddleName());
987 					entityName.setNamePrefix(name.getNamePrefix());
988 					entityName.setNameSuffix(name.getNameSuffix());
989 					entityName.setActive(name.isActive());
990 					entityName.setDefaultValue(name.isDflt());
991 					entityName.setId(name.getEntityNameId());
992 					entityName.setEntityId(identityManagementPersonDocument.getEntityId());
993 					if(ObjectUtils.isNotNull(origNames)){
994 						for (EntityNameBo origName : origNames) {
995 							if (origName.getId()!=null && StringUtils.equals(origName.getId(), entityName.getId())) {
996 								entityName.setVersionNumber(origName.getVersionNumber());
997 							}
998 
999 						}
1000 					}
1001 					entityNames.add(entityName);
1002 				}
1003 			}
1004 			kimEntity.setNames(entityNames);
1005     	}
1006 	}
1007 
1008     protected void setupAffiliation(IdentityManagementPersonDocument identityManagementPersonDocument, EntityBo kimEntity,List<EntityAffiliationBo> origAffiliations, List<EntityEmploymentBo> origEmpInfos) {
1009 		List<EntityAffiliationBo> entityAffiliations = new ArrayList<EntityAffiliationBo>();
1010 		// employment informations
1011 		List<EntityEmploymentBo> entityEmploymentInformations = new ArrayList<EntityEmploymentBo>();
1012 		if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getAffiliations())){
1013 			for (PersonDocumentAffiliation affiliation : identityManagementPersonDocument.getAffiliations()) {
1014 				EntityAffiliationBo entityAffiliation = new EntityAffiliationBo();
1015 				entityAffiliation.setAffiliationTypeCode(affiliation.getAffiliationTypeCode());
1016                 if (affiliation.getAffiliationType() != null) {
1017                         entityAffiliation.setAffiliationType(affiliation.getAffiliationType());
1018                 } else {
1019                     if (StringUtils.isNotEmpty(affiliation.getAffiliationTypeCode())) {
1020                         entityAffiliation.setAffiliationType(EntityAffiliationTypeBo.from(getIdentityService().getAffiliationType(
1021                                 affiliation.getAffiliationTypeCode())));
1022                     }
1023                 }
1024 				entityAffiliation.setCampusCode(affiliation.getCampusCode());
1025 				entityAffiliation.setActive(affiliation.isActive());
1026 				entityAffiliation.setDefaultValue(affiliation.isDflt());
1027 				entityAffiliation.setEntityId(identityManagementPersonDocument.getEntityId());
1028 				entityAffiliation.setId(affiliation.getEntityAffiliationId());
1029 				if(ObjectUtils.isNotNull(origAffiliations)){
1030 				// EntityAffiliationImpl does not define empinfos as collection
1031 					for (EntityAffiliationBo origAffiliation : origAffiliations) {
1032 						if(isSameAffiliation(origAffiliation, entityAffiliation)){
1033 							entityAffiliation.setId(origAffiliation.getId());
1034 						}
1035 						if (origAffiliation.getId()!=null && StringUtils.equals(origAffiliation.getId(), entityAffiliation.getId())) {
1036 							entityAffiliation.setVersionNumber(origAffiliation.getVersionNumber());
1037 						}
1038 					}
1039 				}
1040 				entityAffiliations.add(entityAffiliation);
1041 				int employeeRecordCounter = origEmpInfos==null?0:origEmpInfos.size();
1042 				if(CollectionUtils.isNotEmpty(affiliation.getEmpInfos())){
1043 					for (PersonDocumentEmploymentInfo empInfo : affiliation.getEmpInfos()) {
1044 						EntityEmploymentBo entityEmpInfo = new EntityEmploymentBo();
1045 						entityEmpInfo.setId(empInfo.getEntityEmploymentId());
1046 						entityEmpInfo.setEmployeeId(empInfo.getEmployeeId());
1047 						entityEmpInfo.setEmploymentRecordId(empInfo.getEmploymentRecordId());
1048 						entityEmpInfo.setBaseSalaryAmount(empInfo.getBaseSalaryAmount());
1049 						entityEmpInfo.setPrimaryDepartmentCode(empInfo.getPrimaryDepartmentCode());
1050 						entityEmpInfo.setEmployeeStatusCode(empInfo.getEmploymentStatusCode());
1051                         if (empInfo.getEmploymentStatus() != null) {
1052                             entityEmpInfo.setEmployeeStatus(empInfo.getEmploymentStatus());
1053                         } else {
1054                             if (StringUtils.isNotEmpty(empInfo.getEmploymentStatusCode())) {
1055                                 entityEmpInfo.setEmployeeStatus(EntityEmploymentStatusBo
1056                                         .from(getIdentityService().getEmploymentStatus(empInfo.getEmploymentStatusCode())));
1057                             }
1058                         }
1059 						entityEmpInfo.setEmployeeTypeCode(empInfo.getEmploymentTypeCode());
1060                         if (empInfo.getEmploymentType() != null) {
1061                             entityEmpInfo.setEmployeeType(empInfo.getEmploymentType());
1062                         } else {
1063                             if (StringUtils.isNotEmpty(empInfo.getEmploymentTypeCode())) {
1064                                 entityEmpInfo.setEmployeeType(EntityEmploymentTypeBo
1065                                         .from(getIdentityService().getEmploymentType(empInfo.getEmploymentTypeCode())));
1066                             }
1067                         }
1068 						entityEmpInfo.setActive(empInfo.isActive());
1069 						entityEmpInfo.setPrimary(empInfo.isPrimary());
1070 						entityEmpInfo.setEntityId(identityManagementPersonDocument.getEntityId());
1071 						entityEmpInfo.setEntityAffiliationId(empInfo.getEntityAffiliationId());
1072 						if(ObjectUtils.isNotNull(origEmpInfos)){
1073 							for (EntityEmploymentBo origEmpInfo : origEmpInfos) {
1074 								if(isSameEmpInfo(origEmpInfo, entityEmpInfo)){
1075 									entityEmpInfo.setId(origEmpInfo.getId());
1076 								}
1077 
1078 								if (origEmpInfo.getId()!=null && StringUtils.equals(origEmpInfo.getId(), entityEmpInfo.getId())) {
1079 									entityEmpInfo.setVersionNumber(origEmpInfo.getVersionNumber());
1080 									entityEmpInfo.setEmploymentRecordId(empInfo.getEmploymentRecordId());
1081 								}
1082 							}
1083 						}
1084 						if(StringUtils.isEmpty(entityEmpInfo.getEmploymentRecordId())){
1085 							employeeRecordCounter++;
1086 							entityEmpInfo.setEmploymentRecordId(employeeRecordCounter+"");
1087 						}
1088 						entityEmploymentInformations.add(entityEmpInfo);
1089 					}
1090 				}
1091 			}
1092 		}
1093 		kimEntity.setEmploymentInformation(entityEmploymentInformations);
1094 		kimEntity.setAffiliations(entityAffiliations);
1095 	}
1096 
1097     /*
1098      * Added to address KULRICE-5071 : "Move the 'show blank qualifier' kim toggle from a Config param to a System param"
1099      * 
1100      * This method first checks for a namespace specific parameter with a detailTypeCode of "All" and parameterName of "KIM_SHOW_BLANK_QUALIFIERS". 
1101      * If no parameter is found, it checks for the config property "kim.show.blank.qualifiers", and defaults to true if no config property exists. 
1102      *
1103      */
1104     private boolean isBlankRoleQualifierVisible(String namespaceCode) {
1105     	boolean showBlankQualifiers = true;
1106 		
1107 		Parameter param = getParameterService().getParameter(namespaceCode, KRADConstants.DetailTypes.ALL_DETAIL_TYPE, KimConstants.ParameterKey.SHOW_BLANK_QUALIFIERS);
1108 	    if (param != null) {
1109 	    	showBlankQualifiers = "Y".equals(param.getValue());
1110 	    } else {
1111 	    	String configProperty = ConfigContext.getCurrentContextConfig().getProperty(SHOW_BLANK_QUALIFIERS);
1112 	    	if (configProperty != null) {
1113 	    		showBlankQualifiers = Boolean.valueOf(configProperty);
1114             }
1115 	    }
1116 	    
1117 	    return showBlankQualifiers;
1118     }
1119     
1120    private boolean isSameAffiliation(EntityAffiliationBo origAffiliation, EntityAffiliationBo entityAffiliation){
1121     	//entityId
1122     	//affiliationTypeCode
1123     	//campusCode
1124     	return (origAffiliation!=null && entityAffiliation!=null) &&
1125     	(StringUtils.isNotEmpty(origAffiliation.getCampusCode()) && StringUtils.equals(origAffiliation.getCampusCode(), entityAffiliation.getCampusCode()))
1126     	&&
1127     	(StringUtils.isNotEmpty(origAffiliation.getAffiliationTypeCode()) && StringUtils.equals(origAffiliation.getAffiliationTypeCode(), entityAffiliation.getAffiliationTypeCode()))
1128  		&&
1129  		(StringUtils.isNotEmpty(origAffiliation.getEntityId()) && StringUtils.equals(origAffiliation.getEntityId(), entityAffiliation.getEntityId()));
1130     }
1131 
1132     private boolean isSameEmpInfo(EntityEmploymentBo origEmpInfo, EntityEmploymentBo entityEmpInfo){
1133     	//emp_info:
1134     		//employmentRecordId
1135     		//entityId
1136     		//These should be unique - add a business rule
1137     	return (origEmpInfo!=null && entityEmpInfo!=null)
1138     			&& (StringUtils.isNotEmpty(origEmpInfo.getEmploymentRecordId())
1139     					&& StringUtils.equals(origEmpInfo.getEmploymentRecordId(), entityEmpInfo.getEmploymentRecordId() )
1140     				)
1141     			&& StringUtils.equals( origEmpInfo.getEntityId(),entityEmpInfo.getEntityId());
1142     }
1143 
1144     protected void setupPhone(IdentityManagementPersonDocument identityManagementPersonDocument, EntityTypeContactInfoBo entityType, List<EntityPhoneBo> origPhones) {
1145     	if ( !identityManagementPersonDocument.getPrivacy().isSuppressPhone() || canOverrideEntityPrivacyPreferences(getInitiatorPrincipalId(identityManagementPersonDocument), identityManagementPersonDocument.getPrincipalId()) ) {
1146 			List<EntityPhoneBo> entityPhones = new ArrayList<EntityPhoneBo>();
1147 			if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getPhones())){
1148 				for (PersonDocumentPhone phone : identityManagementPersonDocument.getPhones()) {
1149 					EntityPhoneBo entityPhone = new EntityPhoneBo();
1150 					entityPhone.setPhoneTypeCode(phone.getPhoneTypeCode());
1151                     if (phone.getPhoneType() != null) {
1152                         entityPhone.setPhoneType(phone.getPhoneType());
1153                     } else {
1154                         if (StringUtils.isNotEmpty(phone.getPhoneTypeCode())) {
1155                             entityPhone.setPhoneType(EntityPhoneTypeBo
1156                                     .from(getIdentityService().getAddressType(phone.getPhoneTypeCode())));
1157                         }
1158                     }
1159 					entityPhone.setEntityId(identityManagementPersonDocument.getEntityId());
1160 					entityPhone.setId(phone.getEntityPhoneId());
1161 					entityPhone.setEntityTypeCode(entityType.getEntityTypeCode());
1162 					entityPhone.setPhoneNumber(phone.getPhoneNumber());
1163 					entityPhone.setCountryCode(phone.getCountryCode());
1164 					entityPhone.setExtension(phone.getExtension());
1165 					entityPhone.setExtensionNumber(phone.getExtensionNumber());
1166 					entityPhone.setActive(phone.isActive());
1167 					entityPhone.setDefaultValue(phone.isDflt());
1168 					if(ObjectUtils.isNotNull(origPhones)){
1169 						for (EntityPhoneContract origPhone : origPhones) {
1170 							if (origPhone.getId()!=null && StringUtils.equals(origPhone.getId(), entityPhone.getId())) {
1171 								entityPhone.setVersionNumber(origPhone.getVersionNumber());
1172 							}
1173 						}
1174 					}
1175 					entityPhone.setId(phone.getEntityPhoneId());
1176 					entityPhones.add(entityPhone);
1177 				}
1178 			}
1179 			entityType.setPhoneNumbers(entityPhones);
1180     	}
1181 	}
1182 
1183     protected List<PersonDocumentPhone> loadPhones(IdentityManagementPersonDocument identityManagementPersonDocument, String principalId, List<EntityPhone> entityPhones, boolean suppressDisplay ) {
1184 		List<PersonDocumentPhone> docPhones = new ArrayList<PersonDocumentPhone>();
1185 		if(ObjectUtils.isNotNull(entityPhones)){
1186 			for (EntityPhone phone: entityPhones) {
1187 				if(phone.isActive()){
1188 					PersonDocumentPhone docPhone = new PersonDocumentPhone();
1189                     if (phone.getPhoneType() != null) {
1190 					    docPhone.setPhoneTypeCode(phone.getPhoneType().getCode());
1191                     }
1192 					//docPhone.setPhoneType(((KimEntityPhoneImpl)phone).getPhoneType());
1193 					docPhone.setEntityTypeCode(phone.getEntityTypeCode());
1194 					//We do not need to check the privacy setting here - The UI should care of it
1195 					docPhone.setPhoneNumber(phone.getPhoneNumberUnmasked());
1196 					docPhone.setCountryCode(phone.getCountryCodeUnmasked());
1197 					docPhone.setExtensionNumber(phone.getExtensionNumberUnmasked());
1198 
1199 					docPhone.setActive(phone.isActive());
1200 					docPhone.setDflt(phone.isDefaultValue());
1201 					docPhone.setEntityPhoneId(phone.getId());
1202 					docPhone.setEdit(true);
1203 					docPhones.add(docPhone);
1204 				}
1205 			}
1206 		}
1207 		return docPhones;
1208 
1209 	}
1210 
1211     protected void setupEmail(
1212 			IdentityManagementPersonDocument identityManagementPersonDocument,
1213 			EntityTypeContactInfoBo entityType, List<EntityEmailBo> origEmails) {
1214     	if ( !identityManagementPersonDocument.getPrivacy().isSuppressEmail() || canOverrideEntityPrivacyPreferences(getInitiatorPrincipalId(identityManagementPersonDocument), identityManagementPersonDocument.getPrincipalId()) ) {
1215 			List<EntityEmailBo> entityEmails = new ArrayList<EntityEmailBo>();
1216 			if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getEmails())){
1217 				for (PersonDocumentEmail email : identityManagementPersonDocument.getEmails()) {
1218 					EntityEmailBo entityEmail = new EntityEmailBo();
1219 					entityEmail.setEntityId(identityManagementPersonDocument.getEntityId());
1220 					entityEmail.setEntityTypeCode(entityType.getEntityTypeCode());
1221                     if (email.getEmailType() != null) {
1222                         entityEmail.setEmailType(email.getEmailType());
1223                     } else {
1224                         if (StringUtils.isNotEmpty(email.getEmailTypeCode())) {
1225                             entityEmail.setEmailType(
1226                                     EntityEmailTypeBo.from(getIdentityService().getEmailType(email.getEmailTypeCode())));
1227                         }
1228                     }
1229 					entityEmail.setEmailTypeCode(email.getEmailTypeCode());
1230 					entityEmail.setEmailAddress(email.getEmailAddress());
1231 					entityEmail.setActive(email.isActive());
1232 					entityEmail.setDefaultValue(email.isDflt());
1233 					entityEmail.setId(email.getEntityEmailId());
1234 					if(ObjectUtils.isNotNull(origEmails)){
1235 						for (EntityEmailContract origEmail : origEmails) {
1236 							if (origEmail.getId()!=null && StringUtils.equals(origEmail.getId(), entityEmail.getId())) {
1237 								entityEmail.setVersionNumber(origEmail.getVersionNumber());
1238 							}
1239 						}
1240 					}
1241 					entityEmails.add(entityEmail);
1242 				}
1243 			}
1244 			entityType.setEmailAddresses(entityEmails);
1245     	}
1246 	}
1247     protected List<PersonDocumentEmail> loadEmails(IdentityManagementPersonDocument identityManagementPersonDocument, String principalId, List<EntityEmail> entityEmails, boolean suppressDisplay ) {
1248 		List<PersonDocumentEmail> emails = new ArrayList<PersonDocumentEmail>();
1249 		if(ObjectUtils.isNotNull(entityEmails)){
1250 			for (EntityEmail email: entityEmails) {
1251 				if(email.isActive()){
1252 					PersonDocumentEmail docEmail = new PersonDocumentEmail();
1253 					//docEmail.setEntityId(email.getEntityId());
1254 					docEmail.setEntityTypeCode(email.getEntityTypeCode());
1255                     if (email.getEmailType() != null) {
1256 					    docEmail.setEmailTypeCode(email.getEmailType().getCode());
1257                     }
1258 					// EmailType not on info object.
1259 					//docEmail.setEmailType(((KimEntityEmailImpl)email).getEmailType());
1260 					//We do not need to check the privacy setting here - The UI should care of it
1261 					docEmail.setEmailAddress(email.getEmailAddressUnmasked());
1262 
1263 					docEmail.setActive(email.isActive());
1264 					docEmail.setDflt(email.isDefaultValue());
1265 					docEmail.setEntityEmailId(email.getId());
1266 					docEmail.setEdit(true);
1267 					emails.add(docEmail);
1268 				}
1269 			}
1270 		}
1271 		return emails;
1272 	}
1273 
1274     protected void setupAddress(
1275 			IdentityManagementPersonDocument identityManagementPersonDocument,
1276 			EntityTypeContactInfoBo entityType, List<EntityAddressBo> origAddresses) {
1277     	if ( !identityManagementPersonDocument.getPrivacy().isSuppressAddress() || canOverrideEntityPrivacyPreferences(getInitiatorPrincipalId(identityManagementPersonDocument), identityManagementPersonDocument.getPrincipalId()) ) {
1278 			List<EntityAddressBo> entityAddresses = new ArrayList<EntityAddressBo>();
1279 			if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getAddrs())){
1280 				for (PersonDocumentAddress address : identityManagementPersonDocument.getAddrs()) {
1281 					EntityAddressBo entityAddress = new EntityAddressBo();
1282 					entityAddress.setEntityId(identityManagementPersonDocument.getEntityId());
1283 					entityAddress.setEntityTypeCode(entityType.getEntityTypeCode());
1284 					entityAddress.setAddressTypeCode(address.getAddressTypeCode());
1285                     if (address.getAddressType() != null) {
1286                         entityAddress.setAddressType(address.getAddressType());
1287                     } else {
1288                         if (StringUtils.isNotEmpty(address.getAddressTypeCode())) {
1289                             entityAddress.setAddressType(EntityAddressTypeBo.from(
1290                                     getIdentityService().getAddressType(address.getAddressTypeCode())));
1291                         }
1292                     }
1293 					entityAddress.setLine1(address.getLine1());
1294 					entityAddress.setLine2(address.getLine2());
1295 					entityAddress.setLine3(address.getLine3());
1296 					entityAddress.setStateProvinceCode(address.getStateProvinceCode());
1297 					entityAddress.setPostalCode(address.getPostalCode());
1298 					entityAddress.setCountryCode(address.getCountryCode());
1299 					entityAddress.setCity(address.getCity());
1300 					entityAddress.setActive(address.isActive());
1301 					entityAddress.setDefaultValue(address.isDflt());
1302 					entityAddress.setId(address.getEntityAddressId());
1303 					if(ObjectUtils.isNotNull(origAddresses)){
1304 						for (EntityAddressContract origAddress : origAddresses) {
1305 							if (origAddress.getId()!=null && StringUtils.equals(origAddress.getId(), entityAddress.getId())) {
1306 								entityAddress.setVersionNumber(origAddress.getVersionNumber());
1307 							}
1308 						}
1309 					}
1310 					entityAddresses.add(entityAddress);
1311 				}
1312 			}
1313 			entityType.setAddresses(entityAddresses);
1314     	}
1315 	}
1316 
1317     protected List<PersonDocumentAddress> loadAddresses(IdentityManagementPersonDocument identityManagementPersonDocument, String principalId, List<EntityAddress> entityAddresses, boolean suppressDisplay ) {
1318 		List<PersonDocumentAddress> docAddresses = new ArrayList<PersonDocumentAddress>();
1319 		if(ObjectUtils.isNotNull(entityAddresses)){
1320 			for (EntityAddress address: entityAddresses) {
1321 				if(address.isActive()){
1322 					PersonDocumentAddress docAddress = new PersonDocumentAddress();
1323 					docAddress.setEntityTypeCode(address.getEntityTypeCode());
1324 					docAddress.setAddressTypeCode(address.getAddressType().getCode());
1325 
1326 					//We do not need to check the privacy setting here - The UI should care of it
1327 					docAddress.setLine1(address.getLine1Unmasked());
1328 					docAddress.setLine2(address.getLine2Unmasked());
1329 					docAddress.setLine3(address.getLine3Unmasked());
1330 					docAddress.setStateProvinceCode(address.getStateProvinceCodeUnmasked());
1331 					docAddress.setPostalCode(address.getPostalCodeUnmasked());
1332 					docAddress.setCountryCode(address.getCountryCodeUnmasked());
1333 					docAddress.setCity(address.getCityUnmasked());
1334 
1335 					docAddress.setActive(address.isActive());
1336 					docAddress.setDflt(address.isDefaultValue());
1337 					docAddress.setEntityAddressId(address.getId());
1338 					docAddress.setEdit(true);
1339 					docAddresses.add(docAddress);
1340 				}
1341 			}
1342 		}
1343 		return docAddresses;
1344 	}
1345 
1346 
1347     protected List <GroupMemberBo> populateGroupMembers(IdentityManagementPersonDocument identityManagementPersonDocument) {
1348 		List <GroupMemberBo>  groupPrincipals = new ArrayList<GroupMemberBo>();
1349 //		List<? extends Group> origGroups = getGroupService().getGroupsByPrincipalId(identityManagementPersonDocument.getPrincipalId());
1350 		if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getGroups())){
1351 			for (PersonDocumentGroup group : identityManagementPersonDocument.getGroups()) {
1352 				GroupMember.Builder groupPrincipalImpl = GroupMember.Builder.create(group.getGroupId(), identityManagementPersonDocument.getPrincipalId(), KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE);
1353 				if (group.getActiveFromDate() != null) {
1354 					groupPrincipalImpl.setActiveFromDate(new DateTime(group.getActiveFromDate().getTime()));
1355 				}
1356 				if (group.getActiveToDate() != null) {
1357 					groupPrincipalImpl.setActiveToDate(new DateTime(group.getActiveToDate().getTime()));
1358 				}
1359 				groupPrincipalImpl.setId(group.getGroupMemberId());
1360 
1361 
1362                 //groupPrincipalImpl.setVersionNumber(group.getVersionNumber());
1363 				// get the ORM-layer optimisic locking value
1364 				// TODO: this should be replaced with the retrieval and storage of that value
1365 				// in the document tables and not re-retrieved here
1366 				Collection<GroupMember> currGroupMembers = getGroupService().getMembers(Collections.singletonList(group.getGroupId()));
1367 				if(ObjectUtils.isNotNull(currGroupMembers)){
1368 					for (GroupMember origGroupMember: currGroupMembers) {
1369                         if (origGroupMember.isActive(new DateTime(System.currentTimeMillis()))
1370                             && KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE.equals(origGroupMember.getType())) {
1371                             if(origGroupMember.getId()!=null && StringUtils.equals(origGroupMember.getId(), group.getGroupMemberId())){
1372                                 groupPrincipalImpl.setObjectId(origGroupMember.getObjectId());
1373                                 groupPrincipalImpl.setVersionNumber(origGroupMember.getVersionNumber());
1374                             }
1375                         }
1376 					}
1377 				}
1378 
1379 				groupPrincipals.add(GroupMemberBo.from(groupPrincipalImpl.build()));
1380 
1381 			}
1382 		}
1383 		return groupPrincipals;
1384 	}
1385 
1386     protected List<RoleMemberBo> populateRoleMembers(IdentityManagementPersonDocument identityManagementPersonDocument) {
1387 		List<RoleBo> origRoles = getRolesForPrincipal(identityManagementPersonDocument.getPrincipalId());
1388 
1389 		List <RoleMemberBo> roleMembers = new ArrayList<RoleMemberBo>();
1390 		if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getRoles())){
1391 			for (PersonDocumentRole role : identityManagementPersonDocument.getRoles()) {
1392 				//if(role.isEditable()){
1393 					List<RoleMemberBo> origRoleMembers = new ArrayList<RoleMemberBo>();
1394 					if(ObjectUtils.isNotNull(origRoles)){
1395 						for (RoleBo origRole : origRoles) {
1396 							if (origRole.getId()!=null && StringUtils.equals(origRole.getId(), role.getRoleId())) {
1397 								origRoleMembers = origRole.getMembers();
1398 								break;
1399 							}
1400 						}
1401 					}
1402 					if (role.getRolePrncpls().isEmpty()) {
1403 						if (!role.getDefinitions().isEmpty()) {
1404 							RoleMemberBo roleMemberImpl = new RoleMemberBo();
1405 							roleMemberImpl.setRoleId(role.getRoleId());
1406 							roleMemberImpl.setMemberId(identityManagementPersonDocument.getPrincipalId());
1407 							roleMemberImpl.setType(MemberType.PRINCIPAL);
1408 							roleMembers.add(roleMemberImpl);
1409 						}
1410 					} else {
1411 						for (KimDocumentRoleMember roleMember : role.getRolePrncpls()) {
1412 							RoleMemberBo roleMemberImpl = new RoleMemberBo();
1413 							roleMemberImpl.setRoleId(role.getRoleId());
1414 							// TODO : principalId is not ready here yet ?
1415 							roleMemberImpl.setMemberId(identityManagementPersonDocument.getPrincipalId());
1416 							roleMemberImpl.setType(MemberType.PRINCIPAL);
1417 							roleMemberImpl.setId(roleMember.getRoleMemberId());
1418 							if (roleMember.getActiveFromDate() != null) {
1419 								roleMemberImpl.setActiveFromDateValue(
1420                                         new java.sql.Timestamp(roleMember.getActiveFromDate().getTime()));
1421 							}
1422 							if (roleMember.getActiveToDate() != null) {
1423 								roleMemberImpl.setActiveToDateValue(
1424                                         new java.sql.Timestamp(roleMember.getActiveToDate().getTime()));
1425 							}
1426 							List<RoleMemberAttributeDataBo> origAttributes = new ArrayList<RoleMemberAttributeDataBo>();
1427 							if(ObjectUtils.isNotNull(origRoleMembers)){
1428 								for (RoleMemberBo origMember : origRoleMembers) {
1429 									if (origMember.getId()!=null && StringUtils.equals(origMember.getId(), roleMember.getRoleMemberId())) {
1430 										origAttributes = origMember.getAttributeDetails();
1431 										roleMemberImpl.setVersionNumber(origMember.getVersionNumber());
1432 									}
1433 								}
1434 							}
1435 							List<RoleMemberAttributeDataBo> attributes = new ArrayList<RoleMemberAttributeDataBo>();
1436 							if(CollectionUtils.isNotEmpty(roleMember.getQualifiers())){
1437 								for (KimDocumentRoleQualifier qualifier : roleMember.getQualifiers()) {
1438 									//if (StringUtils.isNotBlank(qualifier.getAttrVal())) {
1439 										RoleMemberAttributeDataBo attribute = new RoleMemberAttributeDataBo();
1440 										attribute.setId(qualifier.getAttrDataId());
1441 										attribute.setAttributeValue(qualifier.getAttrVal());
1442 										attribute.setKimAttributeId(qualifier.getKimAttrDefnId());
1443 										attribute.setAssignedToId(qualifier.getRoleMemberId());
1444 										attribute.setKimTypeId(qualifier.getKimTypId());
1445 
1446 										updateAttrValIfNecessary(attribute);
1447 
1448 										if(ObjectUtils.isNotNull(origAttributes)){
1449 											for (RoleMemberAttributeDataBo origAttribute : origAttributes) {
1450 												if (origAttribute.getId()!=null && StringUtils.equals(origAttribute.getId(), qualifier.getAttrDataId())) {
1451 													attribute.setVersionNumber(origAttribute.getVersionNumber());
1452 												}
1453 											}
1454 										}
1455 										if (attribute.getVersionNumber() != null || StringUtils.isNotBlank(qualifier.getAttrVal())) {
1456 											attributes.add(attribute);
1457 										}
1458 									//}
1459 								}
1460 							}
1461 							roleMemberImpl.setAttributeDetails(attributes);
1462 							roleMembers.add(roleMemberImpl);
1463 						}
1464 					}
1465 				//}
1466 			}
1467 		}
1468 		return roleMembers;
1469 	}
1470 
1471 	protected List<DelegateTypeBo> populateDelegations(IdentityManagementPersonDocument identityManagementPersonDocument){
1472 		List<DelegateTypeBo> origDelegations = getPersonDelegations(identityManagementPersonDocument.getPrincipalId());
1473 		List<DelegateTypeBo> kimDelegations = new ArrayList<DelegateTypeBo>();
1474 		DelegateTypeBo newKimDelegation;
1475 		DelegateTypeBo origDelegationImplTemp = null;
1476 		List<DelegateMemberBo> origMembers;
1477 		boolean activatingInactive = false;
1478 		String newDelegationIdAssigned = "";
1479 		if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getDelegations())){
1480 			for(RoleDocumentDelegation roleDocumentDelegation: identityManagementPersonDocument.getDelegations()){
1481 				newKimDelegation = new DelegateTypeBo();
1482 				KimCommonUtilsInternal.copyProperties(newKimDelegation, roleDocumentDelegation);
1483 				newKimDelegation.setRoleId(roleDocumentDelegation.getRoleId());
1484 				if(ObjectUtils.isNotNull(origDelegations)){
1485 					for(DelegateTypeBo origDelegationImpl: origDelegations){
1486 						if((origDelegationImpl.getRoleId()!=null && StringUtils.equals(origDelegationImpl.getRoleId(), newKimDelegation.getRoleId())) &&
1487 								(origDelegationImpl.getDelegationId()!=null && StringUtils.equals(origDelegationImpl.getDelegationId(), newKimDelegation.getDelegationId()))){
1488 							//TODO: verify if you want to add  && newRoleMember.isActive() condition to if...
1489 							newDelegationIdAssigned = newKimDelegation.getDelegationId();
1490 							newKimDelegation.setDelegationId(origDelegationImpl.getDelegationId());
1491 							activatingInactive = true;
1492 						}
1493 						if(origDelegationImpl.getDelegationId()!=null && StringUtils.equals(origDelegationImpl.getDelegationId(), newKimDelegation.getDelegationId())){
1494 							newKimDelegation.setVersionNumber(origDelegationImpl.getVersionNumber());
1495 							origDelegationImplTemp = origDelegationImpl;
1496 						}
1497 					}
1498 				}
1499 				origMembers = (origDelegationImplTemp==null || origDelegationImplTemp.getMembers()==null)?
1500 									new ArrayList<DelegateMemberBo>():origDelegationImplTemp.getMembers();
1501 				newKimDelegation.setMembers(getDelegationMembers(roleDocumentDelegation.getMembers(), origMembers, null, activatingInactive, newDelegationIdAssigned));
1502 				kimDelegations.add(newKimDelegation);
1503 				activatingInactive = false;
1504 			}
1505 		}
1506 		return kimDelegations;
1507 	}
1508 
1509     protected List <RoleMemberAttributeDataBo> getBlankRoleMemberAttrs(List <RoleMemberBo> rolePrncpls) {
1510 
1511 		List <RoleMemberAttributeDataBo>  blankRoleMemberAttrs = new ArrayList<RoleMemberAttributeDataBo>();
1512 		if(ObjectUtils.isNotNull(rolePrncpls)){
1513 			for (RoleMemberBo roleMbr : rolePrncpls) {
1514 				List <RoleMemberAttributeDataBo>  roleMemberAttrs = new ArrayList<RoleMemberAttributeDataBo>();
1515 				if (CollectionUtils.isNotEmpty(roleMbr.getAttributeDetails())) {
1516 					for (RoleMemberAttributeDataBo attr : roleMbr.getAttributeDetails()) {
1517 						if (StringUtils.isBlank(attr.getAttributeValue())) {
1518 							roleMemberAttrs.add(attr);
1519 						}
1520 					}
1521 					if (!roleMemberAttrs.isEmpty()) {
1522 						roleMbr.getAttributeDetails().removeAll(roleMemberAttrs);
1523 						blankRoleMemberAttrs.addAll(roleMemberAttrs);
1524 					}
1525 
1526 				}
1527 			}
1528 		}
1529 
1530 		return blankRoleMemberAttrs;
1531 
1532 	}
1533 
1534     protected List <RoleResponsibilityActionBo> populateRoleRspActions(IdentityManagementPersonDocument identityManagementPersonDocument) {
1535 //		List<RoleImpl> origRoles = getRolesForPrincipal(identityManagementPersonDocument.getPrincipalId());
1536 
1537 		List <RoleResponsibilityActionBo>  roleRspActions = new ArrayList<RoleResponsibilityActionBo>();
1538 		if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getRoles())){
1539 			for (PersonDocumentRole role : identityManagementPersonDocument.getRoles()) {
1540 				if(CollectionUtils.isNotEmpty(role.getRolePrncpls())){
1541 					for (KimDocumentRoleMember roleMbr : role.getRolePrncpls()) {
1542 						if(CollectionUtils.isNotEmpty(roleMbr.getRoleRspActions())){
1543 							for (KimDocumentRoleResponsibilityAction roleRspAction : roleMbr.getRoleRspActions()) {
1544 								RoleResponsibilityActionBo entRoleRspAction = new RoleResponsibilityActionBo();
1545 								entRoleRspAction.setId(roleRspAction.getRoleResponsibilityActionId());
1546 								entRoleRspAction.setActionPolicyCode(roleRspAction.getActionPolicyCode());
1547 								entRoleRspAction.setActionTypeCode(roleRspAction.getActionTypeCode());
1548 								entRoleRspAction.setPriorityNumber(roleRspAction.getPriorityNumber());
1549 								entRoleRspAction.setRoleMemberId(roleRspAction.getRoleMemberId());
1550 								entRoleRspAction.setRoleResponsibilityId(roleRspAction.getRoleResponsibilityId());
1551 								List<RoleResponsibilityActionBo> actions = getRoleRspActions( roleMbr.getRoleMemberId());
1552 								if(ObjectUtils.isNotNull(actions)){
1553 									for(RoleResponsibilityActionBo orgRspAction : actions) {
1554 										if (orgRspAction.getId()!=null && StringUtils.equals(orgRspAction.getId(), roleRspAction.getRoleResponsibilityActionId())) {
1555 											entRoleRspAction.setVersionNumber(orgRspAction.getVersionNumber());
1556 										}
1557 									}
1558 								}
1559 								roleRspActions.add(entRoleRspAction);
1560 							}
1561 						}
1562 					}
1563 				}
1564 			}
1565 		}
1566 		return roleRspActions;
1567 
1568 	}
1569 
1570 	protected BusinessObjectService getBusinessObjectService() {
1571 		if ( businessObjectService == null ) {
1572 			businessObjectService = KRADServiceLocator.getBusinessObjectService();
1573 		}
1574 		return businessObjectService;
1575 	}
1576 
1577 	protected IdentityService getIdentityService() {
1578 		if ( identityService == null ) {
1579 			identityService = KimApiServiceLocator.getIdentityService();
1580 		}
1581 		return identityService;
1582 	}
1583 
1584 	protected GroupService getGroupService() {
1585 		if ( groupService == null ) {
1586 			groupService = KimApiServiceLocator.getGroupService();
1587 		}
1588 		return groupService;
1589 	}
1590 
1591 	protected DocumentHelperService getDocumentHelperService() {
1592 	    if ( documentHelperService == null ) {
1593 	        documentHelperService = KNSServiceLocator.getDocumentHelperService();
1594 		}
1595 	    return this.documentHelperService;
1596 	}
1597 
1598 	protected RoleService getRoleService() {
1599 	   	if(roleService == null){
1600 	   		roleService = KimApiServiceLocator.getRoleService();
1601     	}
1602 		return roleService;
1603 	}
1604 
1605 	public void setRoleService(RoleService roleService) {
1606 		this.roleService = roleService;
1607 	}
1608 
1609 	protected ResponsibilityService getResponsibilityService() {
1610 	   	if ( responsibilityService == null ) {
1611     		responsibilityService = KimApiServiceLocator.getResponsibilityService();
1612     	}
1613 		return responsibilityService;
1614 	}
1615 
1616 	public void setResponsibilityService(ResponsibilityService responsibilityService) {
1617 		this.responsibilityService = responsibilityService;
1618 	}
1619 
1620 
1621 	/* Role document methods */
1622 	@SuppressWarnings("unchecked")
1623 	public void loadRoleDoc(IdentityManagementRoleDocument identityManagementRoleDocument, Role role){
1624         Map<String, String> criteria = new HashMap<String, String>();
1625 		criteria.put(KimConstants.PrimaryKeyConstants.ROLE_ID, role.getId());
1626 		RoleBo roleBo = getBusinessObjectService().findByPrimaryKey(RoleBo.class, criteria);
1627 
1628         Map<String, String> subClassCriteria = new HashMap<String, String>();
1629 		subClassCriteria.put(KimConstants.PrimaryKeyConstants.SUB_ROLE_ID, role.getId());
1630 
1631 		identityManagementRoleDocument.setRoleId(roleBo.getId());
1632 		identityManagementRoleDocument.setKimType(KimTypeBo.to(roleBo.getKimRoleType()));
1633 		identityManagementRoleDocument.setRoleTypeName(roleBo.getKimRoleType().getName());
1634 		identityManagementRoleDocument.setRoleTypeId(roleBo.getKimTypeId());
1635 		identityManagementRoleDocument.setRoleName(roleBo.getName());
1636 		identityManagementRoleDocument.setRoleDescription(roleBo.getDescription());
1637 		identityManagementRoleDocument.setActive(roleBo.isActive());
1638 		identityManagementRoleDocument.setRoleNamespace(roleBo.getNamespaceCode());
1639 		identityManagementRoleDocument.setEditing(true);
1640 
1641 		identityManagementRoleDocument.setPermissions(loadPermissions(
1642                 (List<RolePermissionBo>) getBusinessObjectService().findMatching(RolePermissionBo.class,
1643                         subClassCriteria)));
1644         identityManagementRoleDocument.setResponsibilities(loadResponsibilities(
1645                 (List<RoleResponsibilityBo>) getBusinessObjectService().findMatching(RoleResponsibilityBo.class,
1646                         subClassCriteria)));
1647         loadResponsibilityRoleRspActions(identityManagementRoleDocument);
1648         identityManagementRoleDocument.setMembers(loadRoleMembers(identityManagementRoleDocument, roleBo.getMembers()));
1649         loadMemberRoleRspActions(identityManagementRoleDocument);
1650 		identityManagementRoleDocument.setDelegations(loadRoleDocumentDelegations(identityManagementRoleDocument, getRoleDelegations(roleBo.getId())));
1651 		//Since delegation members are flattened out on the UI...
1652 		setDelegationMembersInDocument(identityManagementRoleDocument);
1653 		identityManagementRoleDocument.setKimType(KimTypeBo.to(roleBo.getKimRoleType()));
1654     }
1655 
1656     @SuppressWarnings("unchecked")
1657     public void loadRoleMembersBasedOnSearch(IdentityManagementRoleDocument identityManagementRoleDocument,
1658                                                     String memberSearchValue){
1659 
1660         List<KimDocumentRoleMember> roleMembersRestricted = new ArrayList<KimDocumentRoleMember>();
1661         List<KimDocumentRoleMember> members = identityManagementRoleDocument.getMembers();
1662         for (KimDocumentRoleMember roleMember : members){
1663             String memberName = roleMember.getMemberName().toLowerCase();
1664             if (memberName.startsWith(memberSearchValue.toLowerCase())) {
1665                 roleMembersRestricted.add(roleMember);
1666             }
1667         }
1668 
1669         identityManagementRoleDocument.setSearchResultMembers(roleMembersRestricted);
1670     }
1671 
1672     @SuppressWarnings("unchecked")
1673     public void clearRestrictedRoleMembersSearchResults(IdentityManagementRoleDocument identityManagementRoleDocument) {
1674         List<KimDocumentRoleMember> roleMembersRestricted =  new ArrayList<KimDocumentRoleMember>();
1675         List<KimDocumentRoleMember> members = identityManagementRoleDocument.getMembers();
1676         identityManagementRoleDocument.setSearchResultMembers(roleMembersRestricted);
1677         identityManagementRoleDocument.setMembers(members);
1678     }
1679 
1680     public void setDelegationMembersInDocument(IdentityManagementRoleDocument identityManagementRoleDocument){
1681         if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getDelegations())){
1682             for(RoleDocumentDelegation delegation: identityManagementRoleDocument.getDelegations()){
1683                 if(CollectionUtils.isNotEmpty(delegation.getMembers())){
1684                     RoleMemberBo roleMember;
1685                     for(RoleDocumentDelegationMember member: delegation.getMembers()){
1686                         member.setDelegationTypeCode(delegation.getDelegationTypeCode());
1687                         if (StringUtils.isEmpty(member.getRoleMemberName())) {
1688                             roleMember = getRoleMemberForRoleMemberId(member.getRoleMemberId());
1689                             if(roleMember!=null){
1690                                 member.setRoleMemberName(getMemberName(roleMember.getType(), roleMember.getMemberId()));
1691                                 member.setRoleMemberNamespaceCode(getMemberNamespaceCode(roleMember.getType(), roleMember.getMemberId()));
1692                             }
1693                         }
1694                         member.setEdit(true);
1695                         identityManagementRoleDocument.getDelegationMembers().add(member);
1696                     }
1697                 }
1698             }
1699         }
1700     }
1701 
1702 	protected List<KimDocumentRoleResponsibility> loadResponsibilities(List<RoleResponsibilityBo> roleResponsibilities){
1703 		List<KimDocumentRoleResponsibility> documentRoleResponsibilities = new ArrayList<KimDocumentRoleResponsibility>();
1704 		if(ObjectUtils.isNotNull(roleResponsibilities)){
1705 			for(RoleResponsibilityBo roleResponsibility: roleResponsibilities){
1706 				if(roleResponsibility.isActive()) {
1707 					KimDocumentRoleResponsibility roleResponsibilityCopy = new KimDocumentRoleResponsibility();
1708 					KimCommonUtilsInternal.copyProperties(roleResponsibilityCopy, roleResponsibility);
1709 					roleResponsibilityCopy.setEdit(true);
1710 					documentRoleResponsibilities.add(roleResponsibilityCopy);
1711 				}
1712 			}
1713 		}
1714 		return documentRoleResponsibilities;
1715 	}
1716 
1717 	protected List<KimDocumentRolePermission> loadPermissions(List<RolePermissionBo> rolePermissions){
1718 		List<KimDocumentRolePermission> documentRolePermissions = new ArrayList<KimDocumentRolePermission>();
1719 		KimDocumentRolePermission rolePermissionCopy;
1720 		if(ObjectUtils.isNotNull(rolePermissions)){
1721 			for(RolePermissionBo rolePermission: rolePermissions){
1722 				if ( rolePermission.isActive() ) {
1723 					rolePermissionCopy = new KimDocumentRolePermission();
1724 					rolePermissionCopy.setRolePermissionId(rolePermission.getId());
1725 					rolePermissionCopy.setRoleId(rolePermission.getRoleId());
1726 					rolePermissionCopy.setPermissionId(rolePermission.getPermissionId());
1727 					rolePermissionCopy.setPermission(PermissionBo.to(rolePermission.getPermission()));
1728 					rolePermissionCopy.setEdit(true);
1729 					documentRolePermissions.add(rolePermissionCopy);
1730 				}
1731 			}
1732 		}
1733 		return documentRolePermissions;
1734 	}
1735 
1736     public void setMembersInDocument(IdentityManagementRoleDocument identityManagementRoleDocument){
1737         if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getDelegations())){
1738             Map<String, String> criteria = new HashMap<String, String>();
1739             criteria.put(KimConstants.PrimaryKeyConstants.ROLE_ID, identityManagementRoleDocument.getRoleId());
1740             RoleBo roleBo = getBusinessObjectService().findByPrimaryKey(RoleBo.class, criteria);
1741             List<RoleMemberBo> members = roleBo.getMembers();
1742             List<RoleMemberBo> membersToRemove = new ArrayList<RoleMemberBo>();
1743             boolean found = false;
1744             for(KimDocumentRoleMember modifiedMember : identityManagementRoleDocument.getModifiedMembers() ) {
1745                 for(RoleMemberBo member : members) {
1746                     if (modifiedMember.getRoleMemberId().equals(member.getId())) {
1747                         membersToRemove.add(member);
1748                         found = true;
1749                     }
1750                     if (found) break;
1751                 }
1752             }
1753             for(RoleMemberBo memberToRemove : membersToRemove ) {
1754                 members.remove(memberToRemove);
1755             }
1756 
1757             identityManagementRoleDocument.setMembers(loadRoleMembers(identityManagementRoleDocument, members));
1758             loadMemberRoleRspActions(identityManagementRoleDocument);
1759         }
1760     }
1761 
1762     protected List<KimDocumentRoleMember> loadRoleMembers(
1763             IdentityManagementRoleDocument identityManagementRoleDocument, List<RoleMemberBo> members){
1764         List<KimDocumentRoleMember> pndMembers = new ArrayList<KimDocumentRoleMember>();
1765         KimDocumentRoleMember pndMember;
1766 
1767         Map<String, PrincipalBo> principalsForPrincipalIds = new HashMap<String, PrincipalBo>();
1768         Map<String, EntityName> entityNamesForPrincipals = new HashMap<String,EntityName>();
1769         Map<String, String> principalIdEntityIdMap = new HashMap<String,String>();
1770         List<String> roleMemberPrincipalIds = new ArrayList<String>();
1771 
1772         if(ObjectUtils.isNotNull(members)){
1773             for(RoleMemberBo roleMember : members) {
1774                 if (roleMember.getType().getCode().equals(KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE.getCode())) {
1775                     if ((!roleMemberPrincipalIds.contains(roleMember.getMemberId())) && roleMember.isActive()) {
1776                         roleMemberPrincipalIds.add(roleMember.getMemberId());
1777                     }
1778                 }
1779             }
1780 
1781             Collection<PrincipalBo> principals = findPrincipalsByPrincipalIds(roleMemberPrincipalIds);
1782             if (principals != null) {
1783                 for(PrincipalBo principal : principals) {
1784                     principalsForPrincipalIds.put(principal.getPrincipalId(), principal);
1785                     principalIdEntityIdMap.put(principal.getPrincipalId(), principal.getEntityId());
1786                 }
1787                 entityNamesForPrincipals = getUiDocumentServiceDAO().findEntityNamesForRole(
1788                         identityManagementRoleDocument.getRoleId());
1789             }
1790 
1791             Map<String, Group> roleGroupMembers = getUiDocumentServiceDAO().findGroupsForRole(identityManagementRoleDocument.getRoleId());
1792 
1793             for(RoleMemberBo member: members){
1794                 pndMember = new KimDocumentRoleMember();
1795                 pndMember.setActiveFromDate(member.getActiveFromDateValue());
1796                 pndMember.setActiveToDate(member.getActiveToDateValue());
1797                 pndMember.setActive(member.isActive(new Timestamp(System.currentTimeMillis())));
1798                 if(pndMember.isActive()){
1799                     pndMember.setRoleMemberId(member.getId());
1800                     pndMember.setRoleId(member.getRoleId());
1801                     pndMember.setMemberId(member.getMemberId());
1802                     pndMember.setMemberNamespaceCode(getMemberNamespaceCode(member.getType(), member.getMemberId()));
1803 
1804                     PrincipalBo principal =  principalsForPrincipalIds.get(member.getMemberId());
1805                     Group group =  null;
1806 
1807                     if (principal != null) {
1808                         pndMember.setMemberName(principal.getPrincipalName());
1809                     } else {
1810                         group =  roleGroupMembers.get(member.getMemberId());
1811                         if (group != null) {
1812                             pndMember.setMemberName(group.getName());
1813                             pndMember.setMemberNamespaceCode(group.getNamespaceCode());
1814                         } else {
1815                             pndMember.setMemberName(getMemberName(member.getType(), member.getMemberId()));
1816                         }
1817                     }
1818 
1819                     EntityName entityName =  entityNamesForPrincipals.get(principalIdEntityIdMap.get(member.getMemberId()));
1820                     if (entityName != null) {
1821                         pndMember.setMemberFullName(entityName.getFirstName() + " " + entityName.getLastName());
1822                     } else {
1823                         if (group != null) {
1824                             pndMember.setMemberFullName(group.getName());
1825                         } else {
1826                             pndMember.setMemberFullName(getMemberFullName(member.getType(), member.getMemberId()));
1827                         }
1828                     }
1829                     pndMember.setMemberTypeCode(member.getType().getCode());
1830                     pndMember.setQualifiers(loadRoleMemberQualifiers(identityManagementRoleDocument, member.getAttributeDetails()));
1831                     pndMember.setEdit(true);
1832                     pndMembers.add(pndMember);
1833                 }
1834             }
1835         }
1836         Collections.sort(pndMembers, identityManagementRoleDocument.getMemberMetaDataType());
1837         return pndMembers;
1838     }
1839 
1840     public Collection<PrincipalBo>  findPrincipalsByPrincipalIds(Collection<String> principalIds) {
1841         if (!principalIds.isEmpty()) {
1842             Map<String,Collection> prncplNameSearchCrit = new HashMap<String,Collection>();
1843             prncplNameSearchCrit.put("PRNCPL_ID", principalIds);
1844             return getBusinessObjectService().findMatching(PrincipalBo.class, prncplNameSearchCrit);
1845         } else {
1846             return null;
1847         }
1848     }
1849 
1850     protected void loadResponsibilityRoleRspActions(IdentityManagementRoleDocument identityManagementRoleDocument){
1851 		if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getResponsibilities())){
1852 			for(KimDocumentRoleResponsibility responsibility: identityManagementRoleDocument.getResponsibilities()){
1853 				responsibility.getRoleRspActions().addAll(loadKimDocumentRoleRespActions(
1854 						getRoleResponsibilityActionImpls(responsibility.getRoleResponsibilityId())));
1855 			}
1856 		}
1857 	}
1858 
1859     @SuppressWarnings("unchecked")
1860     protected RoleResponsibilityActionBo getRoleResponsibilityActionImpl(String roleResponsibilityActionId){
1861         Map<String, String> criteria = new HashMap<String, String>();
1862         criteria.put(KimConstants.PrimaryKeyConstants.ID, roleResponsibilityActionId);
1863         return getBusinessObjectService().findByPrimaryKey(RoleResponsibilityActionBo.class, criteria);
1864     }
1865 
1866 	@SuppressWarnings("unchecked")
1867 	protected List<RoleResponsibilityActionBo> getRoleResponsibilityActionImpls(String roleResponsibilityId){
1868 		Map<String, String> criteria = new HashMap<String, String>();
1869 		criteria.put(KimConstants.PrimaryKeyConstants.ROLE_MEMBER_ID, "*");
1870 		criteria.put(KimConstants.PrimaryKeyConstants.ROLE_RESPONSIBILITY_ID, roleResponsibilityId);
1871 		return (List<RoleResponsibilityActionBo>)
1872 			getBusinessObjectService().findMatching(RoleResponsibilityActionBo.class, criteria);
1873 	}
1874 
1875 	@SuppressWarnings("unchecked")
1876 	public List<RoleResponsibilityActionBo> getRoleMemberResponsibilityActionImpls(String roleMemberId){
1877 		Map<String, String> criteria = new HashMap<String, String>(1);
1878 		criteria.put(KimConstants.PrimaryKeyConstants.ROLE_MEMBER_ID, roleMemberId);
1879 		return (List<RoleResponsibilityActionBo>)
1880 			getBusinessObjectService().findMatching(RoleResponsibilityActionBo.class, criteria);
1881 	}
1882 
1883 	protected void loadMemberRoleRspActions(IdentityManagementRoleDocument identityManagementRoleDocument){
1884 		if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getMembers())){
1885 			for(KimDocumentRoleMember member: identityManagementRoleDocument.getMembers()){
1886 				member.getRoleRspActions().addAll(loadKimDocumentRoleRespActions(
1887 						getRoleMemberResponsibilityActionImpls(member.getRoleMemberId()) ) );
1888 			}
1889 		}
1890 	}
1891 
1892 	protected List<KimDocumentRoleResponsibilityAction> loadKimDocumentRoleRespActions(
1893 			List<RoleResponsibilityActionBo> roleRespActionImpls){
1894 		List<KimDocumentRoleResponsibilityAction> documentRoleRespActions = new ArrayList<KimDocumentRoleResponsibilityAction>();
1895 		KimDocumentRoleResponsibilityAction documentRoleRespAction;
1896 		if(ObjectUtils.isNotNull(roleRespActionImpls)){
1897 			for(RoleResponsibilityActionBo roleRespActionImpl: roleRespActionImpls){
1898 				documentRoleRespAction = new KimDocumentRoleResponsibilityAction();
1899 				KimCommonUtilsInternal.copyProperties(documentRoleRespAction, roleRespActionImpl);
1900 
1901                 //primary key has different name in these objects!  we need to make sure to copy it over
1902                 documentRoleRespAction.setRoleResponsibilityActionId(roleRespActionImpl.getId());
1903 
1904 				// handle the roleResponsibility object being null since not all may be defined when ID value is "*"
1905 				if ( ObjectUtils.isNotNull(roleRespActionImpl.getRoleResponsibility()) ) {
1906 					documentRoleRespAction.setKimResponsibility(roleRespActionImpl.getRoleResponsibility().getKimResponsibility());
1907 				}
1908 				documentRoleRespActions.add(documentRoleRespAction);
1909 			}
1910 		}
1911 		return documentRoleRespActions;
1912 	}
1913 
1914     public BusinessObject getMember(MemberType memberType, String memberId){
1915         Class<? extends BusinessObject> roleMemberTypeClass = null;
1916         String roleMemberIdName = "";
1917     	if(MemberType.PRINCIPAL.equals(memberType)) {
1918         	roleMemberTypeClass = PrincipalBo.class;
1919         	roleMemberIdName = KimConstants.PrimaryKeyConstants.PRINCIPAL_ID;
1920         } else if(MemberType.GROUP.equals(memberType)){
1921         	roleMemberTypeClass = GroupBo.class;
1922         	roleMemberIdName = KimConstants.PrimaryKeyConstants.GROUP_ID;
1923         } else if(MemberType.ROLE.equals(memberType)){
1924         	roleMemberTypeClass = RoleBo.class;
1925         	roleMemberIdName = KimConstants.PrimaryKeyConstants.ROLE_ID;
1926         }
1927         Map<String, String> criteria = new HashMap<String, String>();
1928         criteria.put(roleMemberIdName, memberId);
1929         return getBusinessObjectService().findByPrimaryKey(roleMemberTypeClass, criteria);
1930     }
1931 
1932 	public String getMemberName(MemberType memberType, String memberId){
1933 		if (memberType == null || StringUtils.isEmpty(memberId)) { return "";}
1934 		BusinessObject member = getMember(memberType, memberId);
1935 		if (member == null) { //not a REAL principal, try to fake the name
1936 			String fakeName = "";
1937 			Principal kp = KimApiServiceLocator.getIdentityService().getPrincipal(memberId);
1938 			if(kp != null && kp.getPrincipalName() != null && !"".equals(kp.getPrincipalName())){
1939 				fakeName = kp.getPrincipalName();
1940 			}
1941 
1942 			return fakeName;
1943 		}
1944 		return getMemberName(memberType, member);
1945 	}
1946 
1947 	public String getMemberFullName(MemberType memberType, String memberId){
1948 		if(memberType == null || StringUtils.isEmpty(memberId)) {return "";}
1949 	   	String memberFullName = "";
1950         if(MemberType.PRINCIPAL.equals(memberType)){
1951         	Principal principalInfo = null;
1952         	principalInfo = getIdentityService().getPrincipal(memberId);
1953         	if (principalInfo != null) {
1954         		String principalName = principalInfo.getPrincipalName();
1955         		Person psn = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(principalName);
1956         		if (psn != null) {
1957         		    memberFullName = psn.getFirstName() + " " + psn.getLastName();
1958                 }
1959         	}        	        	
1960         } else if(MemberType.GROUP.equals(memberType)){
1961         	Group group = null;
1962         	group = getGroupService().getGroup(memberId);
1963         	if (group != null) {
1964         		memberFullName = group.getName();
1965         	}
1966         	
1967         } else if(MemberType.ROLE.equals(memberType)){
1968         	Role role = getRoleService().getRole(memberId);
1969         	memberFullName = role.getName();
1970         }
1971         return memberFullName;
1972 	}
1973 
1974 	public String getMemberNamespaceCode(MemberType memberType, String memberId){
1975 		if(memberType == null || StringUtils.isEmpty(memberId)) {return "";}
1976     	String roleMemberNamespaceCode = "";
1977         if(MemberType.PRINCIPAL.equals(memberType)){
1978         	roleMemberNamespaceCode = "";
1979         } else if(MemberType.GROUP.equals(memberType)){
1980         	Group groupInfo = getGroupService().getGroup(memberId);
1981         	if (groupInfo!= null) {
1982         		roleMemberNamespaceCode = groupInfo.getNamespaceCode();
1983         	}
1984         } else if(MemberType.ROLE.equals(memberType)){
1985         	Role role = getRoleService().getRole(memberId);
1986         	if (role != null) {
1987         		roleMemberNamespaceCode = role.getNamespaceCode();
1988         	}        	
1989         }
1990         return roleMemberNamespaceCode;
1991 	}
1992 
1993     public String getMemberIdByName(MemberType memberType, String memberNamespaceCode, String memberName){
1994     	String memberId = "";
1995         if(MemberType.PRINCIPAL.equals(memberType)){
1996             Principal principal = getIdentityService().getPrincipalByPrincipalName(memberName);
1997             if(principal!=null) {
1998                 memberId = principal.getPrincipalId();
1999             }
2000 
2001        } else if(MemberType.GROUP.equals(memberType)){
2002         	Group groupInfo = getGroupService().getGroupByNamespaceCodeAndName(memberNamespaceCode, memberName);
2003         	if (groupInfo!=null) {
2004                 memberId = groupInfo.getId();
2005             }
2006 
2007         } else if(MemberType.ROLE.equals(memberType)){
2008         	memberId = getRoleService().getRoleIdByNamespaceCodeAndName(memberNamespaceCode, memberName);
2009         }
2010         return memberId;
2011     }
2012 
2013     public String getMemberName(MemberType memberType, BusinessObject member){
2014     	String roleMemberName = "";
2015         if(MemberType.PRINCIPAL.equals(memberType)){
2016         	roleMemberName = ((PrincipalBo)member).getPrincipalName();
2017         } else if(MemberType.GROUP.equals(memberType)){
2018         	roleMemberName = ((GroupBo)member).getName();
2019         } else if(MemberType.ROLE.equals(memberType)){
2020         	roleMemberName = ((RoleBo)member).getName();
2021         }
2022         return roleMemberName;
2023     }
2024 
2025     public String getMemberNamespaceCode(MemberType memberType, BusinessObject member){
2026     	String roleMemberNamespaceCode = "";
2027         if(MemberType.PRINCIPAL.equals(memberType)){
2028         	roleMemberNamespaceCode = "";
2029         } else if(MemberType.GROUP.equals(memberType)){
2030         	roleMemberNamespaceCode = ((GroupBo)member).getNamespaceCode();
2031         } else if(MemberType.ROLE.equals(memberType)){
2032         	roleMemberNamespaceCode = ((RoleBo)member).getNamespaceCode();
2033         }
2034         return roleMemberNamespaceCode;
2035     }
2036 
2037     protected List<KimDocumentRoleQualifier> loadRoleMemberQualifiers(IdentityManagementRoleDocument identityManagementRoleDocument,
2038 			List<RoleMemberAttributeDataBo> attributeDataList){
2039 		List<KimDocumentRoleQualifier> pndMemberRoleQualifiers = new ArrayList<KimDocumentRoleQualifier>();
2040 		KimDocumentRoleQualifier pndMemberRoleQualifier;
2041 
2042 		// add all attributes from attributeDataList
2043 		if(attributeDataList!=null){
2044 			for(RoleMemberAttributeDataBo memberRoleQualifier: attributeDataList){
2045 				pndMemberRoleQualifier = new KimDocumentRoleQualifier();
2046 				pndMemberRoleQualifier.setAttrDataId(memberRoleQualifier.getId());
2047 				pndMemberRoleQualifier.setAttrVal(memberRoleQualifier.getAttributeValue());
2048 				pndMemberRoleQualifier.setRoleMemberId(memberRoleQualifier.getAssignedToId());
2049 				pndMemberRoleQualifier.setKimTypId(memberRoleQualifier.getKimTypeId());
2050 				pndMemberRoleQualifier.setKimAttrDefnId(memberRoleQualifier.getKimAttributeId());
2051 				pndMemberRoleQualifier.setKimAttribute(memberRoleQualifier.getKimAttribute());
2052 				formatAttrValIfNecessary(pndMemberRoleQualifier);
2053 				pndMemberRoleQualifiers.add(pndMemberRoleQualifier);
2054 			}
2055 		}
2056 		// also add any attributes already in the document that are not in the attributeDataList
2057 		int countOfOriginalAttributesNotPresent = 0;
2058 		List<KimDocumentRoleQualifier> fillerRoleQualifiers = new ArrayList<KimDocumentRoleQualifier>();
2059 
2060 		List<KimAttributeField> origAttributes = identityManagementRoleDocument.getDefinitions();
2061 		if ( origAttributes != null ) {
2062 			for(KimAttributeField key: origAttributes) {
2063 				boolean attributePresent = false;
2064 				String origAttributeId = identityManagementRoleDocument.getKimAttributeDefnId(key);
2065 				if(attributeDataList!=null){
2066 					for(RoleMemberAttributeDataBo memberRoleQualifier: attributeDataList){
2067 						if(origAttributeId!=null && StringUtils.equals(origAttributeId, memberRoleQualifier.getKimAttribute().getId())){
2068 							attributePresent = true;
2069 							break;
2070 						}
2071 					}
2072 				}
2073 				if(!attributePresent){
2074 					countOfOriginalAttributesNotPresent++;
2075 					pndMemberRoleQualifier = new KimDocumentRoleQualifier();
2076 					pndMemberRoleQualifier.setKimAttrDefnId(origAttributeId);
2077 					pndMemberRoleQualifier.refreshReferenceObject("kimAttribute");
2078 					fillerRoleQualifiers.add(pndMemberRoleQualifier);
2079 				}
2080 			}
2081 
2082 			if(countOfOriginalAttributesNotPresent != origAttributes.size()) {
2083 				pndMemberRoleQualifiers.addAll(fillerRoleQualifiers);
2084 			}
2085 		}
2086 		return pndMemberRoleQualifiers;
2087 	}
2088 
2089     @SuppressWarnings("unchecked")
2090 	public List<DelegateTypeBo> getRoleDelegations(String roleId){
2091 		if(roleId==null) {
2092 			return new ArrayList<DelegateTypeBo>();
2093         }
2094 		Map<String,String> criteria = new HashMap<String,String>(1);
2095 		criteria.put("roleId", roleId);
2096 		return (List<DelegateTypeBo>)getBusinessObjectService().findMatching(DelegateTypeBo.class, criteria);
2097 	}
2098 
2099     protected List<RoleDocumentDelegation> loadRoleDocumentDelegations(IdentityManagementRoleDocument identityManagementRoleDocument, List<DelegateTypeBo> delegations){
2100 		List<RoleDocumentDelegation> delList = new ArrayList<RoleDocumentDelegation>();
2101 		RoleDocumentDelegation documentDelegation;
2102 		if(ObjectUtils.isNotNull(delegations)){
2103 			for(DelegateTypeBo del: delegations){
2104 				documentDelegation = new RoleDocumentDelegation();
2105 				documentDelegation.setActive(del.isActive());
2106 				if(documentDelegation.isActive()){
2107 					documentDelegation.setDelegationId(del.getDelegationId());
2108 					documentDelegation.setDelegationTypeCode(del.getDelegationTypeCode());
2109 					documentDelegation.setKimTypeId(del.getKimTypeId());
2110 					documentDelegation.setMembers(loadDelegationMembers(identityManagementRoleDocument, del.getMembers()));
2111 					documentDelegation.setRoleId(del.getRoleId());
2112 					documentDelegation.setEdit(true);
2113 					delList.add(documentDelegation);
2114 				}
2115 			}
2116 		}
2117 		return delList;
2118 	}
2119 
2120     protected List<RoleDocumentDelegationMember> loadDelegationMembers(IdentityManagementRoleDocument identityManagementRoleDocument, List<DelegateMemberBo> members){
2121 		List<RoleDocumentDelegationMember> pndMembers = new ArrayList<RoleDocumentDelegationMember>();
2122 		RoleDocumentDelegationMember pndMember;
2123 		RoleMemberBo roleMember;
2124 		if(ObjectUtils.isNotNull(members)){
2125 			for(DelegateMemberBo member: members){
2126 				pndMember = new RoleDocumentDelegationMember();
2127 				pndMember.setActiveFromDate(member.getActiveFromDateValue());
2128 				pndMember.setActiveToDate(member.getActiveToDateValue());
2129 				pndMember.setActive(member.isActive(new Timestamp(System.currentTimeMillis())));
2130 				if(pndMember.isActive()){
2131 					//KimCommonUtilsInternal.copyProperties(pndMember, member);
2132                     pndMember.setDelegationId(member.getDelegationId());
2133                     pndMember.setDelegationMemberId(member.getDelegationMemberId());
2134                     pndMember.setDelegationTypeCode(member.getType().getCode());
2135                     pndMember.setRoleMemberId(member.getRoleMemberId());
2136                     pndMember.setMemberId(member.getMemberId());
2137                     pndMember.setMemberTypeCode(member.getType().getCode());
2138 
2139 					roleMember = getRoleMemberForRoleMemberId(member.getRoleMemberId());
2140 					if(roleMember!=null){
2141 						pndMember.setRoleMemberName(getMemberName(roleMember.getType(), roleMember.getMemberId()));
2142 						pndMember.setRoleMemberNamespaceCode(getMemberNamespaceCode(roleMember.getType(), roleMember.getMemberId()));
2143 					}
2144 					pndMember.setMemberNamespaceCode(getMemberNamespaceCode(member.getType(), member.getMemberId()));
2145 					pndMember.setMemberName(getMemberName(member.getType(), member.getMemberId()));
2146 					pndMember.setEdit(true);
2147 					pndMember.setQualifiers(loadDelegationMemberQualifiers(identityManagementRoleDocument, member.getAttributeDetails()));
2148 					pndMembers.add(pndMember);
2149 				}
2150 			}
2151 		}
2152 		return pndMembers;
2153 	}
2154 
2155     protected RoleMemberBo getRoleMemberForRoleMemberId(String roleMemberId){
2156 		Map<String,String> criteria = new HashMap<String,String>( 2 );
2157 		criteria.put(KimConstants.PrimaryKeyConstants.ID, roleMemberId);
2158 		return getBusinessObjectService().findByPrimaryKey(RoleMemberBo.class, criteria);
2159     }
2160 
2161     protected List<RoleDocumentDelegationMemberQualifier> loadDelegationMemberQualifiers(IdentityManagementRoleDocument identityManagementRoleDocument,
2162 			List<DelegateMemberAttributeDataBo> attributeDataList){
2163 		List<RoleDocumentDelegationMemberQualifier> pndMemberRoleQualifiers = new ArrayList<RoleDocumentDelegationMemberQualifier>();
2164 		RoleDocumentDelegationMemberQualifier pndMemberRoleQualifier;
2165 		List<KimAttributeField> origAttributes = identityManagementRoleDocument.getDefinitions();
2166 		boolean attributePresent = false;
2167 		String origAttributeId;
2168 		if(origAttributes!=null){
2169 			for(KimAttributeField key: origAttributes) {
2170 				origAttributeId = identityManagementRoleDocument.getKimAttributeDefnId(key);
2171 				if(attributeDataList!=null){
2172 					for(DelegateMemberAttributeDataBo memberRoleQualifier: attributeDataList){
2173 						if(origAttributeId!=null && StringUtils.equals(origAttributeId, memberRoleQualifier.getKimAttribute().getId())){
2174 							pndMemberRoleQualifier = new RoleDocumentDelegationMemberQualifier();
2175 							pndMemberRoleQualifier.setAttrDataId(memberRoleQualifier.getId());
2176 							pndMemberRoleQualifier.setAttrVal(memberRoleQualifier.getAttributeValue());
2177 							pndMemberRoleQualifier.setDelegationMemberId(memberRoleQualifier.getAssignedToId());
2178 							pndMemberRoleQualifier.setKimTypId(memberRoleQualifier.getKimTypeId());
2179 							pndMemberRoleQualifier.setKimAttrDefnId(memberRoleQualifier.getKimAttributeId());
2180 							pndMemberRoleQualifier.setKimAttribute(memberRoleQualifier.getKimAttribute());
2181 							pndMemberRoleQualifiers.add(pndMemberRoleQualifier);
2182 							attributePresent = true;
2183 						}
2184 					}
2185 				}
2186 				if(!attributePresent){
2187 					pndMemberRoleQualifier = new RoleDocumentDelegationMemberQualifier();
2188 					pndMemberRoleQualifier.setKimAttrDefnId(origAttributeId);
2189 					pndMemberRoleQualifier.refreshReferenceObject("kimAttribute");
2190 					pndMemberRoleQualifiers.add(pndMemberRoleQualifier);
2191 				}
2192 				attributePresent = false;
2193 			}
2194 		}
2195 		return pndMemberRoleQualifiers;
2196 	}
2197 
2198 	/**
2199 	 * @see org.kuali.rice.kim.service.UiDocumentService#saveEntityPerson(IdentityManagementPersonDocument)
2200 	 */
2201 	@SuppressWarnings("unchecked")
2202 	public void saveRole(IdentityManagementRoleDocument identityManagementRoleDocument) {
2203         RoleBo roleBo = new RoleBo();
2204 		Map<String, String> criteria = new HashMap<String, String>();
2205 		String roleId = identityManagementRoleDocument.getRoleId();
2206 		criteria.put(KimConstants.PrimaryKeyConstants.ID, roleId);
2207 		RoleBo origRole = getBusinessObjectService().findByPrimaryKey(RoleBo.class, criteria);
2208 
2209 		List<RolePermissionBo> origRolePermissions = new ArrayList<RolePermissionBo>();
2210 		List<RoleResponsibilityBo> origRoleResponsibilities = new ArrayList<RoleResponsibilityBo>();
2211 		List<RoleMemberBo> origRoleMembers = new ArrayList<RoleMemberBo>();
2212         List<DelegateTypeBo> origRoleDelegations = new ArrayList<DelegateTypeBo>();
2213 
2214 		roleBo.setId(identityManagementRoleDocument.getRoleId());
2215 		roleBo.setKimTypeId(identityManagementRoleDocument.getRoleTypeId());
2216 		roleBo.setNamespaceCode(identityManagementRoleDocument.getRoleNamespace());
2217 		roleBo.setName(identityManagementRoleDocument.getRoleName());
2218 		roleBo.setDescription(identityManagementRoleDocument.getRoleDescription());
2219 
2220 		if (origRole == null) {
2221 			origRole = new RoleBo();
2222 			roleBo.setActive(true);
2223 		} else {
2224 			roleBo.setActive(identityManagementRoleDocument.isActive());
2225 			roleBo.setVersionNumber(origRole.getVersionNumber());
2226             Map<String, String> altCriteria = new HashMap<String, String>();
2227             altCriteria.put(KimConstants.PrimaryKeyConstants.SUB_ROLE_ID, roleId);
2228 			origRolePermissions = new ArrayList<RolePermissionBo>(getBusinessObjectService().findMatching(RolePermissionBo.class, altCriteria));
2229             origRoleResponsibilities = (List<RoleResponsibilityBo>)getBusinessObjectService().findMatching(RoleResponsibilityBo.class, altCriteria);
2230             origRoleMembers = (List<RoleMemberBo>)getBusinessObjectService().findMatching(RoleMemberBo.class, altCriteria);
2231             origRoleDelegations = (List<DelegateTypeBo>)getBusinessObjectService().findMatching(DelegateTypeBo.class, altCriteria);
2232 		}
2233 
2234 		if( getKimTypeInfoService().getKimType(identityManagementRoleDocument.getRoleTypeId()) == null ) {
2235 			LOG.error( "Kim type not found for:"+identityManagementRoleDocument.getRoleTypeId(), new Throwable() );
2236 		}
2237 
2238 		List<PersistableBusinessObject> bos = new ArrayList<PersistableBusinessObject>();
2239 
2240         bos.add(roleBo);
2241 		bos.addAll(getRolePermissions(identityManagementRoleDocument, origRolePermissions));
2242 		bos.addAll(getRoleResponsibilities(identityManagementRoleDocument, origRoleResponsibilities));
2243 		bos.addAll(getRoleResponsibilitiesActions(identityManagementRoleDocument));
2244 		String initiatorPrincipalId = getInitiatorPrincipalId(identityManagementRoleDocument);
2245 
2246 		if(canAssignToRole(identityManagementRoleDocument, initiatorPrincipalId)){
2247 			List<RoleMemberBo> newRoleMembersList = getRoleMembers(identityManagementRoleDocument, origRoleMembers);
2248             roleBo.setMembers(newRoleMembersList);
2249 
2250 			bos.addAll(getRoleMemberResponsibilityActions(newRoleMembersList));
2251 			//bos.addAll(getRoleMemberResponsibilityActions(identityManagementRoleDocument));
2252 			bos.addAll(getRoleDelegations(identityManagementRoleDocument, origRoleDelegations));
2253 		}
2254        // bos.add(roleBo);
2255 		getBusinessObjectService().save(bos);
2256 		KimImplServiceLocator.getResponsibilityInternalService().updateActionRequestsForResponsibilityChange(getChangedRoleResponsibilityIds(identityManagementRoleDocument, origRoleResponsibilities));
2257 		if(!roleBo.isActive()){
2258 			// when a role is inactivated, inactivate the memberships of principals, groups, and roles in
2259 			// that role, delegations, and delegation members, and that roles memberships in other roles
2260 			KimImplServiceLocator.getRoleInternalService().roleInactivated(identityManagementRoleDocument.getRoleId());
2261 		}
2262 	}
2263 
2264 	protected List<RolePermissionBo> getRolePermissions(
2265 			IdentityManagementRoleDocument identityManagementRoleDocument, List<RolePermissionBo> origRolePermissions){
2266 		List<RolePermissionBo> rolePermissions = new ArrayList<RolePermissionBo>();
2267 		if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getPermissions())){
2268 			for(KimDocumentRolePermission documentRolePermission: identityManagementRoleDocument.getPermissions()){
2269 				RolePermissionBo newRolePermission = new RolePermissionBo();
2270 				newRolePermission.setId(documentRolePermission.getRolePermissionId());
2271 				newRolePermission.setRoleId(identityManagementRoleDocument.getRoleId());
2272 				newRolePermission.setPermissionId(documentRolePermission.getPermissionId());
2273 				newRolePermission.setActive( documentRolePermission.isActive() );
2274 
2275 				newRolePermission.setActive(documentRolePermission.isActive());
2276 				if (ObjectUtils.isNotNull(origRolePermissions)) {
2277                     for (RolePermissionBo origPermissionImpl : origRolePermissions) {
2278                         if (!StringUtils.equals(origPermissionImpl.getRoleId(), newRolePermission.getRoleId())
2279                                 && StringUtils.equals(origPermissionImpl.getPermissionId(), newRolePermission.getPermissionId())
2280                                 && origPermissionImpl.isActive()
2281                                 && newRolePermission.isActive()) {
2282 							newRolePermission.setId(origPermissionImpl.getId());
2283 						}
2284 						if(origPermissionImpl.getId()!=null && StringUtils.equals(origPermissionImpl.getId(), newRolePermission.getId())){
2285 							newRolePermission.setVersionNumber(origPermissionImpl.getVersionNumber());
2286                             newRolePermission.setObjectId(origPermissionImpl.getObjectId());
2287 						}
2288 					}
2289 				}
2290 				rolePermissions.add(newRolePermission);
2291 			}
2292 		}
2293 		return rolePermissions;
2294 	}
2295 
2296 	protected List<RoleResponsibilityBo> getRoleResponsibilities(
2297 			IdentityManagementRoleDocument identityManagementRoleDocument, List<RoleResponsibilityBo> origRoleResponsibilities){
2298 		List<RoleResponsibilityBo> roleResponsibilities = new ArrayList<RoleResponsibilityBo>();
2299 		RoleResponsibilityBo newRoleResponsibility;
2300 		if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getResponsibilities())){
2301 			for(KimDocumentRoleResponsibility documentRoleResponsibility: identityManagementRoleDocument.getResponsibilities()){
2302 				newRoleResponsibility = new RoleResponsibilityBo();
2303 				KimCommonUtilsInternal.copyProperties(newRoleResponsibility, documentRoleResponsibility);
2304 				newRoleResponsibility.setActive(documentRoleResponsibility.isActive());
2305 				newRoleResponsibility.setRoleId(identityManagementRoleDocument.getRoleId());
2306 				if(ObjectUtils.isNotNull(origRoleResponsibilities)){
2307 					for(RoleResponsibilityBo origResponsibilityImpl: origRoleResponsibilities){
2308 						if(!StringUtils.equals(origResponsibilityImpl.getRoleId(), newRoleResponsibility.getRoleId()) &&
2309 								StringUtils.equals(origResponsibilityImpl.getResponsibilityId(), newRoleResponsibility.getResponsibilityId()) &&
2310 								!origResponsibilityImpl.isActive() && newRoleResponsibility.isActive()){
2311 							newRoleResponsibility.setRoleResponsibilityId(origResponsibilityImpl.getRoleResponsibilityId());
2312 						}
2313 						if(origResponsibilityImpl.getRoleResponsibilityId()!=null && StringUtils.equals(origResponsibilityImpl.getRoleResponsibilityId(), newRoleResponsibility.getRoleResponsibilityId())) {
2314                             newRoleResponsibility.setVersionNumber(origResponsibilityImpl.getVersionNumber());
2315                             newRoleResponsibility.setObjectId(origResponsibilityImpl.getObjectId());
2316                         }
2317 					}
2318 				}
2319 				roleResponsibilities.add(newRoleResponsibility);
2320 			}
2321 		}
2322 		return roleResponsibilities;
2323 	}
2324 
2325 
2326 	protected List <RoleResponsibilityActionBo> getRoleResponsibilitiesActions(
2327 			IdentityManagementRoleDocument identityManagementRoleDocument){
2328 		List <RoleResponsibilityActionBo>  roleRspActions = new ArrayList<RoleResponsibilityActionBo>();
2329 		if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getResponsibilities())){
2330 		// loop over the responsibilities assigned to the role
2331 			for(KimDocumentRoleResponsibility roleResponsibility : identityManagementRoleDocument.getResponsibilities()){
2332 				// only process if the actions are not assigned at the role member level
2333 				if(!getResponsibilityInternalService().areActionsAtAssignmentLevelById(roleResponsibility.getResponsibilityId())){
2334 					List<KimDocumentRoleResponsibilityAction> documentRoleResponsibilityActions = roleResponsibility.getRoleRspActions();
2335 					if( ObjectUtils.isNotNull(documentRoleResponsibilityActions)
2336 							&& !documentRoleResponsibilityActions.isEmpty()
2337 							&& StringUtils.isNotBlank(documentRoleResponsibilityActions.get(0).getRoleResponsibilityActionId() ) ) {
2338 						RoleResponsibilityActionBo roleRspAction = new RoleResponsibilityActionBo();
2339 						roleRspAction.setId(documentRoleResponsibilityActions.get(0).getRoleResponsibilityActionId());
2340 						roleRspAction.setActionPolicyCode(documentRoleResponsibilityActions.get(0).getActionPolicyCode());
2341 						roleRspAction.setActionTypeCode(documentRoleResponsibilityActions.get(0).getActionTypeCode());
2342 						roleRspAction.setPriorityNumber(documentRoleResponsibilityActions.get(0).getPriorityNumber());
2343 						roleRspAction.setForceAction(documentRoleResponsibilityActions.get(0).isForceAction());
2344 						roleRspAction.setRoleMemberId("*");
2345 						roleRspAction.setRoleResponsibilityId(documentRoleResponsibilityActions.get(0).getRoleResponsibilityId());
2346 						updateResponsibilityActionVersionNumber(roleRspAction, getRoleResponsibilityActionImpl(roleRspAction.getId()));
2347 						roleRspActions.add(roleRspAction);
2348 					}
2349 				}
2350 			}
2351 		}
2352 		return roleRspActions;
2353 	}
2354 
2355 	// FIXME: This should be pulling by the PK, not using another method which pulls multiple records and then finds
2356 	// the right one here!
2357 	protected void updateResponsibilityActionVersionNumber(RoleResponsibilityActionBo newRoleRspAction,
2358 			RoleResponsibilityActionBo origRoleRespActionImpl){
2359 		if(ObjectUtils.isNotNull(origRoleRespActionImpl)){
2360             if(origRoleRespActionImpl.getId()!=null && StringUtils.equals(origRoleRespActionImpl.getId(), newRoleRspAction.getId())) {
2361                 newRoleRspAction.setVersionNumber(origRoleRespActionImpl.getVersionNumber());
2362                 newRoleRspAction.setObjectId(origRoleRespActionImpl.getObjectId());
2363             }
2364 		}
2365 	}
2366 
2367 	protected List<RoleResponsibilityActionBo> getRoleMemberResponsibilityActions(List<RoleMemberBo> newRoleMembersList){
2368 		List<RoleResponsibilityActionBo> roleRspActions = new ArrayList<RoleResponsibilityActionBo>();
2369 		if(ObjectUtils.isNotNull(newRoleMembersList)){
2370 			for(RoleMemberBo roleMember: newRoleMembersList){
2371 				roleRspActions.addAll(roleMember.getRoleRspActions());
2372 			}
2373 		}
2374 		return roleRspActions;
2375 	}
2376 
2377 	/*protected List<RoleResponsibilityActionBo> getRoleMemberResponsibilityActions(IdentityManagementRoleDocument identityManagementRoleDocument){
2378 		List<RoleResponsibilityActionBo> roleRspActions = new ArrayList<RoleResponsibilityActionBo>();
2379 		if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getMembers())){
2380 			for(KimDocumentRoleMember roleMember: identityManagementRoleDocument.getMembers()){
2381 				for(KimDocumentRoleResponsibilityAction roleRspAction : roleMember.getRoleRspActions()){
2382 					RoleResponsibilityActionBo entRoleRspAction = new RoleResponsibilityActionBo();
2383 					entRoleRspAction.setId(roleRspAction.getRoleResponsibilityActionId());
2384 					entRoleRspAction.setActionPolicyCode(roleRspAction.getActionPolicyCode());
2385 					entRoleRspAction.setActionTypeCode(roleRspAction.getActionTypeCode());
2386 					entRoleRspAction.setPriorityNumber(roleRspAction.getPriorityNumber());
2387 					entRoleRspAction.setRoleMemberId(roleRspAction.getRoleMemberId());
2388 					entRoleRspAction.setForceAction(roleRspAction.isForceAction());
2389 					entRoleRspAction.setRoleResponsibilityId(roleRspAction.getRoleResponsibilityId());
2390 					List<RoleResponsibilityActionBo> actions = getRoleRspActions(roleMember.getRoleMemberId());
2391 					if(ObjectUtils.isNotNull(actions)){
2392 						for(RoleResponsibilityActionBo orgRspAction : actions) {
2393 							if (orgRspAction.getId()!=null && StringUtils.equals(orgRspAction.getId(), roleRspAction.getRoleResponsibilityActionId())) {
2394 								entRoleRspAction.setVersionNumber(orgRspAction.getVersionNumber());
2395 							}
2396 						}
2397 					}
2398 					roleRspActions.add(entRoleRspAction);
2399 				}
2400 			}
2401 		}
2402 		return roleRspActions;
2403 	}*/
2404 
2405     protected List<RoleMemberBo> getRoleMembers(IdentityManagementRoleDocument identityManagementRoleDocument, List<RoleMemberBo> origRoleMembers){
2406         List<RoleMemberBo> roleMembers = new ArrayList<RoleMemberBo>();
2407         RoleMemberBo newRoleMember;
2408         RoleMemberBo origRoleMemberImplTemp;
2409         List<RoleMemberAttributeDataBo> origAttributes;
2410         boolean activatingInactive = false;
2411         String newRoleMemberIdAssigned = "";
2412 
2413         identityManagementRoleDocument.setKimType(KimApiServiceLocator.getKimTypeInfoService().getKimType(identityManagementRoleDocument.getRoleTypeId()));
2414         KimTypeService kimTypeService = KimFrameworkServiceLocator.getKimTypeService(identityManagementRoleDocument.getKimType());
2415 
2416         if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getModifiedMembers())){
2417             for(KimDocumentRoleMember documentRoleMember: identityManagementRoleDocument.getModifiedMembers()){
2418                 origRoleMemberImplTemp = null;
2419 
2420                 newRoleMember = new RoleMemberBo();
2421                 KimCommonUtilsInternal.copyProperties(newRoleMember, documentRoleMember);
2422                 newRoleMember.setId(documentRoleMember.getRoleMemberId());
2423                 newRoleMember.setRoleId(identityManagementRoleDocument.getRoleId());
2424                 if(ObjectUtils.isNotNull(origRoleMembers)){
2425                     for(RoleMemberBo origRoleMemberImpl: origRoleMembers){
2426                         if((origRoleMemberImpl.getRoleId()!=null && StringUtils.equals(origRoleMemberImpl.getRoleId(), newRoleMember.getRoleId())) &&
2427                             (origRoleMemberImpl.getMemberId()!=null && StringUtils.equals(origRoleMemberImpl.getMemberId(), newRoleMember.getMemberId())) &&
2428                             (origRoleMemberImpl.getType()!=null && org.apache.commons.lang.ObjectUtils.equals(origRoleMemberImpl.getType(), newRoleMember.getType())) &&
2429                             !origRoleMemberImpl.isActive() &&
2430                             !kimTypeService.validateUniqueAttributes(
2431                                     identityManagementRoleDocument.getKimType().getId(),
2432                                     documentRoleMember.getQualifierAsMap(), origRoleMemberImpl.getAttributes()).isEmpty()) {
2433 
2434                             //TODO: verify if you want to add  && newRoleMember.isActive() condition to if...
2435 
2436                             newRoleMemberIdAssigned = newRoleMember.getId();
2437                             newRoleMember.setId(origRoleMemberImpl.getId());
2438                             activatingInactive = true;
2439                         }
2440                         if(origRoleMemberImpl.getId()!=null && StringUtils.equals(origRoleMemberImpl.getId(), newRoleMember.getId())){
2441                             newRoleMember.setVersionNumber(origRoleMemberImpl.getVersionNumber());
2442                             origRoleMemberImplTemp = origRoleMemberImpl;
2443 
2444                             // Obtain role rsp actions from db and assign to origRoleMemberImplTemp
2445                             List<RoleResponsibilityActionBo> roleRespActionBos = getRoleMemberResponsibilityActionImpls(origRoleMemberImplTemp.getId());
2446                             if(ObjectUtils.isNotNull(roleRespActionBos))
2447                                 origRoleMemberImplTemp.setRoleRspActions(roleRespActionBos);
2448                         }
2449                     }
2450                 }
2451                 origAttributes = (origRoleMemberImplTemp==null || origRoleMemberImplTemp.getAttributes()==null)?
2452                                     new ArrayList<RoleMemberAttributeDataBo>():origRoleMemberImplTemp.getAttributeDetails();
2453                 newRoleMember.setActiveFromDateValue(documentRoleMember.getActiveFromDate());
2454                 newRoleMember.setActiveToDateValue(documentRoleMember.getActiveToDate());
2455                 newRoleMember.setAttributeDetails(getRoleMemberAttributeData(documentRoleMember.getQualifiers(), origAttributes, activatingInactive, newRoleMemberIdAssigned));
2456                 newRoleMember.setRoleRspActions(getRoleMemberResponsibilityActions(documentRoleMember, origRoleMemberImplTemp, activatingInactive, newRoleMemberIdAssigned));
2457                 newRoleMember.setType(MemberType.fromCode(documentRoleMember.getMemberTypeCode()));
2458 
2459                 if( (origRoleMemberImplTemp == null) || (!newRoleMember.equals(origRoleMemberImplTemp)) ) {
2460                     roleMembers.add(newRoleMember);
2461                 }
2462                 activatingInactive = false;
2463                 origRoleMemberImplTemp = null;
2464             }
2465         }
2466         return roleMembers;
2467     }
2468 
2469 	protected List<RoleResponsibilityActionBo> getRoleMemberResponsibilityActions(
2470 			KimDocumentRoleMember documentRoleMember, RoleMemberBo origRoleMemberImplTemp, boolean activatingInactive, String newRoleMemberIdAssigned){
2471 		List<RoleResponsibilityActionBo> roleRspActions = new ArrayList<RoleResponsibilityActionBo>();
2472 		List<RoleResponsibilityActionBo> origActions = new ArrayList<RoleResponsibilityActionBo>();
2473 		if(origRoleMemberImplTemp!=null) {
2474 			origActions = getRoleRspActions(origRoleMemberImplTemp.getId());
2475 		}
2476 		if(CollectionUtils.isNotEmpty(documentRoleMember.getRoleRspActions())){
2477 			for(KimDocumentRoleResponsibilityAction roleRspAction : documentRoleMember.getRoleRspActions()){
2478 				RoleResponsibilityActionBo newRoleRspAction = new RoleResponsibilityActionBo();
2479 				newRoleRspAction.setId(roleRspAction.getRoleResponsibilityActionId());
2480 				newRoleRspAction.setActionPolicyCode(roleRspAction.getActionPolicyCode());
2481 				newRoleRspAction.setActionTypeCode(roleRspAction.getActionTypeCode());
2482 				newRoleRspAction.setPriorityNumber(roleRspAction.getPriorityNumber());
2483 				newRoleRspAction.setRoleMemberId(roleRspAction.getRoleMemberId());
2484 				newRoleRspAction.setForceAction(roleRspAction.isForceAction());
2485 				newRoleRspAction.setRoleResponsibilityId("*");
2486 				if(ObjectUtils.isNotNull(origActions)){
2487 					for(RoleResponsibilityActionBo origRspAction: origActions) {
2488 						if(activatingInactive && StringUtils.equals(origRspAction.getRoleResponsibilityId(), newRoleRspAction.getRoleResponsibilityId()) &&
2489 								StringUtils.equals(newRoleRspAction.getRoleMemberId(), newRoleMemberIdAssigned)){
2490 							newRoleRspAction.setRoleMemberId(origRspAction.getRoleMemberId());
2491 							newRoleRspAction.setId(origRspAction.getId());
2492 						}
2493 						if (origRspAction.getId()!=null && StringUtils.equals(origRspAction.getId(), newRoleRspAction.getId())) {
2494 							newRoleRspAction.setVersionNumber(origRspAction.getVersionNumber());
2495                             newRoleRspAction.setObjectId(origRspAction.getObjectId());
2496 
2497                         }
2498 					}
2499 				}
2500 				roleRspActions.add(newRoleRspAction);
2501 			}
2502 		}
2503 		return roleRspActions;
2504 	}
2505 
2506 	protected List<RoleMemberAttributeDataBo> getRoleMemberAttributeData(List<KimDocumentRoleQualifier> qualifiers,
2507 			List<RoleMemberAttributeDataBo> origAttributes, boolean activatingInactive, String newRoleMemberIdAssigned){
2508 		List<RoleMemberAttributeDataBo> roleMemberAttributeDataList = new ArrayList<RoleMemberAttributeDataBo>();
2509 		RoleMemberAttributeDataBo newRoleMemberAttributeData;
2510 		if(CollectionUtils.isNotEmpty(qualifiers)){
2511 			for(KimDocumentRoleQualifier memberRoleQualifier: qualifiers){
2512 				if(StringUtils.isNotBlank(memberRoleQualifier.getAttrVal())){
2513 					newRoleMemberAttributeData = new RoleMemberAttributeDataBo();
2514 					newRoleMemberAttributeData.setId(memberRoleQualifier.getAttrDataId());
2515 					newRoleMemberAttributeData.setAttributeValue(memberRoleQualifier.getAttrVal());
2516 					newRoleMemberAttributeData.setAssignedToId(memberRoleQualifier.getRoleMemberId());
2517 					newRoleMemberAttributeData.setKimTypeId(memberRoleQualifier.getKimTypId());
2518 					newRoleMemberAttributeData.setKimAttributeId(memberRoleQualifier.getKimAttrDefnId());
2519 
2520 					updateAttrValIfNecessary(newRoleMemberAttributeData);
2521 
2522 					if(ObjectUtils.isNotNull(origAttributes)){
2523 						for(RoleMemberAttributeDataBo origAttribute: origAttributes){
2524 							if(activatingInactive && StringUtils.equals(origAttribute.getKimAttributeId(), newRoleMemberAttributeData.getKimAttributeId()) &&
2525 									StringUtils.equals(newRoleMemberAttributeData.getAssignedToId(), newRoleMemberIdAssigned)){
2526 								newRoleMemberAttributeData.setAssignedToId(origAttribute.getAssignedToId());
2527 								newRoleMemberAttributeData.setId(origAttribute.getId());
2528 							}
2529 							if(origAttribute.getId()!=null && StringUtils.equals(origAttribute.getId(), newRoleMemberAttributeData.getId())){
2530 								newRoleMemberAttributeData.setVersionNumber(origAttribute.getVersionNumber());
2531 							}
2532 						}
2533 					}
2534 					roleMemberAttributeDataList.add(newRoleMemberAttributeData);
2535 				}
2536 			}
2537 		}
2538 		return roleMemberAttributeDataList;
2539 	}
2540 
2541 	/**
2542 	 * Determines if the attribute value on the attribute data should be updated; if so, it performs some attribute value formatting.
2543 	 * In the default implementation, this method formats checkbox controls
2544 	 *
2545 	 * @param roleMemberAttributeData a role member qualifier attribute to update
2546 	 */
2547 	protected void updateAttrValIfNecessary(RoleMemberAttributeDataBo roleMemberAttributeData) {
2548 		if (doCheckboxLogic(roleMemberAttributeData.getKimTypeId(), roleMemberAttributeData.getKimAttributeId())) {
2549 			convertCheckboxAttributeData(roleMemberAttributeData);
2550 		}
2551 	}
2552 
2553 	protected void formatAttrValIfNecessary(KimDocumentRoleQualifier roleQualifier) {
2554         if (doCheckboxLogic(roleQualifier.getKimTypId(), roleQualifier.getKimAttrDefnId())) {
2555             formatCheckboxAttributeData(roleQualifier);
2556         }
2557 	}
2558 
2559     private boolean doCheckboxLogic(String kimTypeId, String attrId) {
2560         final KimAttributeField attributeDefinition = getAttributeDefinition(kimTypeId, attrId);
2561         return attributeDefinition != null
2562                 && attributeDefinition.getAttributeField().getControl() != null
2563                 && (attributeDefinition.getAttributeField().getControl() instanceof RemotableCheckboxGroup
2564                         || attributeDefinition.getAttributeField().getControl() instanceof RemotableCheckbox);
2565     }
2566 
2567 	protected void formatCheckboxAttributeData(KimDocumentRoleQualifier roleQualifier) {
2568 		if (roleQualifier.getAttrVal().equals(KimConstants.KIM_ATTRIBUTE_BOOLEAN_TRUE_STR_VALUE)) {
2569 			roleQualifier.setAttrVal(KimConstants.KIM_ATTRIBUTE_BOOLEAN_TRUE_STR_VALUE_DISPLAY);
2570 		} else if (roleQualifier.getAttrVal().equals(KimConstants.KIM_ATTRIBUTE_BOOLEAN_FALSE_STR_VALUE)) {
2571 			roleQualifier.setAttrVal(KimConstants.KIM_ATTRIBUTE_BOOLEAN_FALSE_STR_VALUE_DISPLAY);
2572 		}
2573 	}
2574 
2575 	/**
2576 	 * Finds the KNS attribute used to render the given KimAttributeData
2577 	 *
2578      * @return the KNS attribute used to render that qualifier, or null if the AttributeDefinition cannot be determined
2579 	 */
2580 	protected KimAttributeField getAttributeDefinition(String kimTypId, String attrDefnId) {
2581 		final KimType type = getKimTypeInfoService().getKimType(kimTypId);
2582 		if (type != null) {
2583 			final KimTypeService typeService = (KimTypeService) KimImplServiceLocator.getBean(type.getServiceName());
2584 			if (typeService != null) {
2585 				final KimTypeAttribute attributeInfo = type.getAttributeDefinitionById(attrDefnId);
2586 				if (attributeInfo != null) {
2587 					final List<KimAttributeField> attributeMap = typeService.getAttributeDefinitions(type.getId());
2588 					if (attributeMap != null) {
2589 						return DataDictionaryTypeServiceHelper.findAttributeField(
2590                                 attributeInfo.getKimAttribute().getAttributeName(), attributeMap);
2591 					}
2592 				}
2593 			}
2594 		}
2595 		return null;
2596 	}
2597 
2598 	/**
2599 	 * Formats the attribute value on this checkbox attribute, changing "on" to "Y" and "off" to "N"
2600 	 *
2601 	 * @param roleMemberAttributeData the attribute data to format the attribute value of
2602 	 */
2603 	protected void convertCheckboxAttributeData(RoleMemberAttributeDataBo roleMemberAttributeData) {
2604 		if (roleMemberAttributeData.getAttributeValue().equalsIgnoreCase(KimConstants.KIM_ATTRIBUTE_BOOLEAN_TRUE_STR_VALUE_DISPLAY)) {
2605 			roleMemberAttributeData.setAttributeValue(KimConstants.KIM_ATTRIBUTE_BOOLEAN_TRUE_STR_VALUE);
2606 		} else if (roleMemberAttributeData.getAttributeValue().equalsIgnoreCase(KimConstants.KIM_ATTRIBUTE_BOOLEAN_FALSE_STR_VALUE_DISPLAY)) {
2607 			roleMemberAttributeData.setAttributeValue(KimConstants.KIM_ATTRIBUTE_BOOLEAN_FALSE_STR_VALUE);
2608 		}
2609 	}
2610 
2611 	protected List<DelegateTypeBo> getRoleDelegations(IdentityManagementRoleDocument identityManagementRoleDocument, List<DelegateTypeBo> origDelegations){
2612 		List<DelegateTypeBo> kimDelegations = new ArrayList<DelegateTypeBo>();
2613 		DelegateTypeBo newKimDelegation;
2614 		DelegateTypeBo origDelegationImplTemp = null;
2615 		List<DelegateMemberBo> origMembers;
2616         List<DelegateMemberBo> allOrigMembers = new ArrayList<DelegateMemberBo>();;
2617         boolean activatingInactive = false;
2618 		String newDelegationIdAssigned = "";
2619             if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getDelegations())){
2620 			for(RoleDocumentDelegation roleDocumentDelegation: identityManagementRoleDocument.getDelegations()){
2621 				newKimDelegation = new DelegateTypeBo();
2622 				KimCommonUtilsInternal.copyProperties(newKimDelegation, roleDocumentDelegation);
2623 				newKimDelegation.setRoleId(identityManagementRoleDocument.getRoleId());
2624 				if(ObjectUtils.isNotNull(origDelegations)){
2625 					for(DelegateTypeBo origDelegationImpl: origDelegations){
2626 						if(StringUtils.equals(origDelegationImpl.getRoleId(), newKimDelegation.getRoleId()) &&
2627 								StringUtils.equals(origDelegationImpl.getDelegationId(), newKimDelegation.getDelegationId())){
2628 							//TODO: verify if you want to add  && newRoleMember.isActive() condition to if...
2629 							newDelegationIdAssigned = newKimDelegation.getDelegationId();
2630 							newKimDelegation.setDelegationId(origDelegationImpl.getDelegationId());
2631 							activatingInactive = true;
2632 						}
2633 						if(origDelegationImpl.getDelegationId()!=null && StringUtils.equals(origDelegationImpl.getDelegationId(), newKimDelegation.getDelegationId())){
2634 							newKimDelegation.setVersionNumber(origDelegationImpl.getVersionNumber());
2635                             newKimDelegation.setObjectId(origDelegationImpl.getObjectId());
2636 							origDelegationImplTemp = origDelegationImpl;
2637 						}
2638                         for (DelegateMemberBo delegateMemberBo:origDelegationImpl.getMembers() ) {
2639                             allOrigMembers.add(delegateMemberBo);
2640                         }
2641                     }
2642 				}
2643 				origMembers = (origDelegationImplTemp == null || origDelegationImplTemp.getMembers()==null)?
2644 									new ArrayList<DelegateMemberBo>():origDelegationImplTemp.getMembers();
2645 				newKimDelegation.setMembers(getDelegationMembers(roleDocumentDelegation.getMembers(), origMembers, allOrigMembers, activatingInactive, newDelegationIdAssigned));
2646                 kimDelegations.add(newKimDelegation);
2647 				activatingInactive = false;
2648 			}
2649 		}
2650 		return kimDelegations;
2651 	}
2652 
2653 	protected List<DelegateMemberBo> getDelegationMembers(List<RoleDocumentDelegationMember> delegationMembers,
2654 			List<DelegateMemberBo> origDelegationMembers, List<DelegateMemberBo> allOrigMembers, boolean activatingInactive, String newDelegationIdAssigned){
2655 		List<DelegateMemberBo> delegationsMembersList = new ArrayList<DelegateMemberBo>();
2656 		DelegateMemberBo newDelegationMemberImpl;
2657 		DelegateMemberBo origDelegationMemberImplTemp = null;
2658 		List<DelegateMemberAttributeDataBo> origAttributes;
2659 		String delegationMemberId = "";
2660 		if(CollectionUtils.isNotEmpty(delegationMembers)){
2661 			for(RoleDocumentDelegationMember delegationMember: delegationMembers){
2662 				newDelegationMemberImpl = new DelegateMemberBo();
2663 				KimCommonUtilsInternal.copyProperties(newDelegationMemberImpl, delegationMember);
2664                 newDelegationMemberImpl.setType(MemberType.fromCode(delegationMember.getMemberTypeCode()));
2665 				if(ObjectUtils.isNotNull(origDelegationMembers)){
2666 					for(DelegateMemberBo origDelegationMember: origDelegationMembers){
2667 						if(activatingInactive && StringUtils.equals(origDelegationMember.getMemberId(), newDelegationMemberImpl.getMemberId()) &&
2668 								StringUtils.equals(newDelegationMemberImpl.getDelegationId(), newDelegationIdAssigned) &&
2669 								!origDelegationMember.isActive(new Timestamp(System.currentTimeMillis()))){
2670 							newDelegationMemberImpl.setDelegationId(origDelegationMember.getDelegationId());
2671 							delegationMemberId = newDelegationMemberImpl.getDelegationMemberId();
2672 							newDelegationMemberImpl.setDelegationMemberId(origDelegationMember.getDelegationMemberId());
2673 						}
2674 						if(origDelegationMember.getDelegationMemberId()!=null && StringUtils.equals(origDelegationMember.getDelegationMemberId(), newDelegationMemberImpl.getDelegationMemberId())){
2675 							newDelegationMemberImpl.setVersionNumber(origDelegationMember.getVersionNumber());
2676                             newDelegationMemberImpl.setObjectId(origDelegationMember.getObjectId());
2677                             origDelegationMemberImplTemp = origDelegationMember;
2678 						}
2679 					}
2680 				}
2681                 for (DelegateMemberBo origMember : allOrigMembers) {
2682                     if ((origMember.getDelegationMemberId() != null) &&
2683                         (origMember.getDelegationMemberId().equals(delegationMember.getDelegationMemberId())) &&
2684                         (origMember.getRoleMemberId() != null) &&
2685                         (origMember.getRoleMemberId().equals(delegationMember.getRoleMemberId()))) {
2686                             newDelegationMemberImpl.setVersionNumber(origMember.getVersionNumber());
2687                             newDelegationMemberImpl.setObjectId(origMember.getObjectId());
2688                             origDelegationMemberImplTemp = origMember;
2689                     }
2690                 }
2691 				origAttributes = (origDelegationMemberImplTemp==null || origDelegationMemberImplTemp.getAttributeDetails()==null)?
2692 						new ArrayList<DelegateMemberAttributeDataBo>():origDelegationMemberImplTemp.getAttributeDetails();
2693 				newDelegationMemberImpl.setAttributeDetails(getDelegationMemberAttributeData(delegationMember.getQualifiers(), origAttributes, activatingInactive, delegationMemberId));
2694 				newDelegationMemberImpl.setActiveFromDateValue(delegationMember.getActiveFromDate());
2695                 newDelegationMemberImpl.setActiveToDateValue(delegationMember.getActiveToDate());
2696                 delegationsMembersList.add(newDelegationMemberImpl);
2697 			}
2698 		}
2699 		return delegationsMembersList;
2700 	}
2701 
2702 	//TODO: implement logic same as role members - do not insert qualifiers with blank values
2703 	protected List<DelegateMemberAttributeDataBo> getDelegationMemberAttributeData(
2704 			List<RoleDocumentDelegationMemberQualifier> qualifiers, List<DelegateMemberAttributeDataBo> origAttributes,
2705 			boolean activatingInactive, String delegationMemberId){
2706 		List<DelegateMemberAttributeDataBo> delegationMemberAttributeDataList = new ArrayList<DelegateMemberAttributeDataBo>();
2707 		DelegateMemberAttributeDataBo newDelegationMemberAttributeData;
2708 		if(CollectionUtils.isNotEmpty(qualifiers)){
2709 			for(RoleDocumentDelegationMemberQualifier memberRoleQualifier: qualifiers){
2710 				if(StringUtils.isNotBlank(memberRoleQualifier.getAttrVal())){
2711 					newDelegationMemberAttributeData = new DelegateMemberAttributeDataBo();
2712 					newDelegationMemberAttributeData.setId(memberRoleQualifier.getAttrDataId());
2713 					newDelegationMemberAttributeData.setAttributeValue(memberRoleQualifier.getAttrVal());
2714 					newDelegationMemberAttributeData.setAssignedToId(memberRoleQualifier.getDelegationMemberId());
2715 					newDelegationMemberAttributeData.setKimTypeId(memberRoleQualifier.getKimTypId());
2716 					newDelegationMemberAttributeData.setKimAttributeId(memberRoleQualifier.getKimAttrDefnId());
2717 					if(ObjectUtils.isNotNull(origAttributes)){
2718 						for(DelegateMemberAttributeDataBo origAttribute: origAttributes){
2719 							if(activatingInactive && StringUtils.equals(origAttribute.getKimAttributeId(), newDelegationMemberAttributeData.getKimAttributeId()) &&
2720 									StringUtils.equals(newDelegationMemberAttributeData.getAssignedToId(), delegationMemberId)){
2721 								newDelegationMemberAttributeData.setAssignedToId(origAttribute.getAssignedToId());
2722 								newDelegationMemberAttributeData.setId(origAttribute.getId());
2723 							}
2724 							if(StringUtils.equals(origAttribute.getId(), newDelegationMemberAttributeData.getId())){
2725 								newDelegationMemberAttributeData.setVersionNumber(origAttribute.getVersionNumber());
2726 							}
2727 						}
2728 					}
2729 					delegationMemberAttributeDataList.add(newDelegationMemberAttributeData);
2730 				}
2731 			}
2732 		}
2733 		return delegationMemberAttributeDataList;
2734 	}
2735 
2736 	/* Group document methods */
2737 	public void loadGroupDoc(IdentityManagementGroupDocument identityManagementGroupDocument, Group groupInfo){
2738 		//Map<String, String> criteria = new HashMap<String, String>();
2739 		//criteria.put(KimApiConstants.PrimaryKeyConstants.GROUP_ID, groupInfo.getId());
2740 		//GroupImpl kimGroupImpl = (GroupImpl)
2741 		//	getBusinessObjectService().findByPrimaryKey(GroupImpl.class, criteria);
2742 
2743 		identityManagementGroupDocument.setGroupId(groupInfo.getId());
2744         KimType kimType = KimApiServiceLocator.getKimTypeInfoService().getKimType(groupInfo.getKimTypeId());
2745 		identityManagementGroupDocument.setKimType(kimType);
2746 		identityManagementGroupDocument.setGroupTypeName(kimType.getName());
2747 		identityManagementGroupDocument.setGroupTypeId(kimType.getId());
2748 		identityManagementGroupDocument.setGroupName(groupInfo.getName());
2749 		identityManagementGroupDocument.setGroupDescription(groupInfo.getDescription());
2750 		identityManagementGroupDocument.setActive(groupInfo.isActive());
2751 		identityManagementGroupDocument.setGroupNamespace(groupInfo.getNamespaceCode());
2752 
2753         List<GroupMember> members = new ArrayList(KimApiServiceLocator.getGroupService().getMembersOfGroup(groupInfo.getId()));
2754         identityManagementGroupDocument.setMembers(loadGroupMembers(identityManagementGroupDocument, members));
2755 
2756 
2757 
2758         identityManagementGroupDocument.setQualifiers(loadGroupQualifiers(identityManagementGroupDocument, groupInfo.getAttributes()));
2759 		identityManagementGroupDocument.setEditing(true);
2760 	}
2761 
2762 	protected static class GroupMemberNameComparator implements Comparator<GroupDocumentMember> {
2763 		/**
2764 		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
2765 		 */
2766 		public int compare(GroupDocumentMember m1, GroupDocumentMember m2) {
2767 			return m1.getMemberName().compareToIgnoreCase(m2.getMemberName());
2768 		}
2769 	}
2770 
2771 	protected GroupMemberNameComparator groupMemberNameComparator = new GroupMemberNameComparator();
2772 
2773 	protected List<GroupDocumentMember> loadGroupMembers(
2774 			IdentityManagementGroupDocument identityManagementGroupDocument, List<GroupMember> members){
2775 		List<GroupDocumentMember> pndMembers = new ArrayList<GroupDocumentMember>();
2776 		GroupDocumentMember pndMember = new GroupDocumentMember();
2777 		if(ObjectUtils.isNotNull(members)){
2778 			for(GroupMember member: members){
2779 				pndMember = new GroupDocumentMember();
2780 
2781 				pndMember.setActiveFromDate(member.getActiveFromDate() == null ? null : new Timestamp(member.getActiveFromDate().getMillis()));
2782 				pndMember.setActiveToDate(member.getActiveToDate() == null ? null : new Timestamp(member.getActiveToDate().getMillis()));
2783 				//pndMember.setActive(member.isActive());
2784 				if(pndMember.isActive()){
2785 					pndMember.setGroupMemberId(member.getMemberId());
2786 					pndMember.setGroupId(member.getGroupId());
2787 					pndMember.setMemberId(member.getMemberId());
2788 					pndMember.setMemberName(getMemberName(member.getType(), member.getMemberId()));
2789 					pndMember.setMemberFullName(getMemberFullName(member.getType(), member.getMemberId()));
2790 					pndMember.setMemberTypeCode(member.getType().getCode());
2791 					pndMember.setEdit(true);
2792 					pndMembers.add(pndMember);
2793 				}
2794 			}
2795 		}
2796 		Collections.sort(pndMembers, groupMemberNameComparator);
2797 		return pndMembers;
2798 	}
2799 
2800 	protected List<GroupDocumentQualifier> loadGroupQualifiers(IdentityManagementGroupDocument IdentityManagementGroupDocument,
2801 			Map<String, String> attributes){
2802 		List<GroupDocumentQualifier> pndGroupQualifiers = new ArrayList<GroupDocumentQualifier>();
2803 		GroupDocumentQualifier pndGroupQualifier = new GroupDocumentQualifier();
2804 		List<KimAttributeField> origAttributes = IdentityManagementGroupDocument.getDefinitions();
2805 		boolean attributePresent = false;
2806 		String origAttributeId;
2807 		if(origAttributes!=null){
2808 
2809 			for(KimAttributeField key: origAttributes) {
2810 				origAttributeId = IdentityManagementGroupDocument.getKimAttributeDefnId(key);
2811 				if(!attributes.isEmpty()){
2812 
2813 					for(GroupAttributeBo groupQualifier: KimAttributeDataBo.createFrom(GroupAttributeBo.class, attributes, IdentityManagementGroupDocument.getGroupTypeId())){
2814 						if(origAttributeId!=null && ObjectUtils.isNotNull(groupQualifier.getKimAttribute()) &&
2815 								StringUtils.equals(origAttributeId, groupQualifier.getKimAttribute().getId())){
2816 							pndGroupQualifier = new GroupDocumentQualifier();
2817 							KimCommonUtilsInternal.copyProperties(pndGroupQualifier, groupQualifier);
2818 							pndGroupQualifier.setAttrDataId(groupQualifier.getId());
2819 							pndGroupQualifier.setAttrVal(groupQualifier.getAttributeValue());
2820 							pndGroupQualifier.setKimAttrDefnId(groupQualifier.getKimAttribute().getId());
2821 							pndGroupQualifier.setKimTypId(groupQualifier.getKimType().getId());
2822 							pndGroupQualifier.setGroupId(groupQualifier.getAssignedToId());
2823 							pndGroupQualifiers.add(pndGroupQualifier);
2824 							attributePresent = true;
2825 						}
2826 					}
2827 				}
2828 				if(!attributePresent){
2829 					pndGroupQualifier = new GroupDocumentQualifier();
2830 					pndGroupQualifier.setKimAttrDefnId(origAttributeId);
2831 					pndGroupQualifiers.add(pndGroupQualifier);
2832 				}
2833 				attributePresent = false;
2834 			}
2835 		}
2836 		return pndGroupQualifiers;
2837 	}
2838 
2839 	/**
2840 	 * @see org.kuali.rice.kim.service.UiDocumentService#saveEntityPerson(IdentityManagementPersonDocument)
2841 	 */
2842 	@SuppressWarnings("unchecked")
2843 	public void saveGroup(IdentityManagementGroupDocument identityManagementGroupDocument) {
2844 		GroupBo kimGroup = new GroupBo();
2845 		Map<String, String> criteria = new HashMap<String, String>();
2846 		String groupId = identityManagementGroupDocument.getGroupId();
2847 		criteria.put("groupId", groupId);
2848 		GroupBo origGroup = (GroupBo)getBusinessObjectService().findBySinglePrimaryKey(GroupBo.class, groupId);
2849 		List<GroupMemberBo> origGroupMembers = new ArrayList<GroupMemberBo>();
2850 		if (ObjectUtils.isNull(origGroup)) {
2851 			origGroup = new GroupBo();
2852 			kimGroup.setActive(true);
2853 		} else {
2854 			kimGroup.setVersionNumber(origGroup.getVersionNumber());
2855 			//TODO: when a group is inactivated, inactivate the memberships of principals in that group
2856 			//and the memberships of that group in roles
2857 			kimGroup.setActive(identityManagementGroupDocument.isActive());
2858 			origGroupMembers = (List<GroupMemberBo>)getBusinessObjectService().findMatching(GroupMemberBo.class, criteria);
2859 		}
2860 
2861 		kimGroup.setId(identityManagementGroupDocument.getGroupId());
2862 		KimType kimType = getKimTypeInfoService().getKimType(identityManagementGroupDocument.getGroupTypeId());
2863 		if( kimType == null ) {
2864 			throw new RuntimeException("Kim type not found for:"+identityManagementGroupDocument.getGroupTypeId());
2865 		}
2866 
2867 		kimGroup.setKimTypeId(kimType.getId());
2868 		kimGroup.setNamespaceCode(identityManagementGroupDocument.getGroupNamespace());
2869 		kimGroup.setName(identityManagementGroupDocument.getGroupName());
2870 		kimGroup.setDescription(identityManagementGroupDocument.getGroupDescription());
2871 		kimGroup.setAttributeDetails(getGroupAttributeData(identityManagementGroupDocument, origGroup.getAttributeDetails()));
2872 
2873 		List<String> oldIds;
2874 		List<String> newIds;
2875 		oldIds = getGroupService().getMemberPrincipalIds(kimGroup.getId()); // for the actionList update
2876 
2877 
2878 		List<GroupMemberBo> newGroupMembersList = getGroupMembers(identityManagementGroupDocument, origGroupMembers);
2879 		kimGroup.setMembers(newGroupMembersList);  // add the new, complete list to the group
2880 
2881 		kimGroup = (GroupBo)getBusinessObjectService().save(kimGroup);
2882 
2883 		newIds = kimGroup.getMemberPrincipalIds();
2884 		//newIds = getGroupService().getMemberPrincipalIds(kimGroup.getGroupId()); // for the action list update
2885 
2886 		// Do an async update of the action list for the updated groups
2887 		org.kuali.rice.kim.service.KIMServiceLocatorInternal.getGroupInternalService().updateForWorkgroupChange(kimGroup.getId(), oldIds, newIds);
2888 		if(!kimGroup.isActive()){
2889 			// when a group is inactivated, inactivate the memberships of principals in that group
2890 			// and the memberships of that group in roles
2891 			KimImplServiceLocator.getRoleInternalService().groupInactivated(identityManagementGroupDocument.getGroupId());
2892 		}
2893 
2894 	}
2895 
2896 	protected List<GroupMemberBo> getGroupMembers(IdentityManagementGroupDocument identityManagementGroupDocument, List<GroupMemberBo> origGroupMembers){
2897 		List<GroupMemberBo> groupMembers = new ArrayList<GroupMemberBo>();
2898 		GroupMemberBo newGroupMember;
2899 		if(CollectionUtils.isNotEmpty(identityManagementGroupDocument.getMembers())){
2900 			for(GroupDocumentMember documentGroupMember: identityManagementGroupDocument.getMembers()){
2901 				newGroupMember = new GroupMemberBo();
2902 				//KimCommonUtilsInternalInternal.copyProperties(newGroupMember, documentGroupMember);
2903                 //copy properties manually for now until new BO created for DocumentGroupMember
2904 
2905 				newGroupMember.setGroupId(identityManagementGroupDocument.getGroupId());
2906                 newGroupMember.setActiveFromDateValue(documentGroupMember.getActiveFromDate());
2907                 newGroupMember.setActiveToDateValue(documentGroupMember.getActiveToDate());
2908                 newGroupMember.setMemberId(documentGroupMember.getMemberId());
2909                 newGroupMember.setTypeCode(documentGroupMember.getMemberTypeCode());
2910 				if(ObjectUtils.isNotNull(origGroupMembers)){
2911 					for(GroupMemberBo origGroupMemberImpl: origGroupMembers){
2912 						if(StringUtils.equals(origGroupMemberImpl.getGroupId(), newGroupMember.getGroupId()) &&
2913 								StringUtils.equals(origGroupMemberImpl.getMemberId(), newGroupMember.getMemberId()) &&
2914 								!origGroupMemberImpl.isActive(new Timestamp(System.currentTimeMillis()))){
2915 							//TODO: verify if you want to add  && newGroupMember.isActive() condition to if...
2916 							newGroupMember.setMemberId(origGroupMemberImpl.getMemberId());
2917 						}
2918                         if(StringUtils.equals(origGroupMemberImpl.getGroupId(), newGroupMember.getGroupId()) &&
2919 								StringUtils.equals(origGroupMemberImpl.getMemberId(), newGroupMember.getMemberId()) &&
2920 								origGroupMemberImpl.isActive(new Timestamp(System.currentTimeMillis()))){
2921 							newGroupMember.setId(origGroupMemberImpl.getId());
2922                             newGroupMember.setVersionNumber(origGroupMemberImpl.getVersionNumber());
2923 						}
2924 					}
2925 				}
2926 				groupMembers.add(newGroupMember);
2927 			}
2928 		}
2929 		return groupMembers;
2930 	}
2931 
2932 	protected List<GroupAttributeBo> getGroupAttributeData(IdentityManagementGroupDocument identityManagementGroupDocument,
2933 			List<GroupAttributeBo> origAttributes){
2934 		List<GroupAttributeBo> groupAttributeDataList = new ArrayList<GroupAttributeBo>();
2935 		GroupAttributeBo newGroupAttributeData;
2936 		if(CollectionUtils.isNotEmpty(identityManagementGroupDocument.getQualifiers())){
2937 			for(GroupDocumentQualifier groupQualifier: identityManagementGroupDocument.getQualifiers()){
2938 				if(StringUtils.isNotBlank(groupQualifier.getAttrVal())){
2939 					newGroupAttributeData = new GroupAttributeBo();
2940 					newGroupAttributeData.setId(groupQualifier.getAttrDataId());
2941 					newGroupAttributeData.setAttributeValue(groupQualifier.getAttrVal());
2942 					newGroupAttributeData.setAssignedToId(groupQualifier.getGroupId());
2943 					newGroupAttributeData.setKimTypeId(groupQualifier.getKimTypId());
2944 					newGroupAttributeData.setKimAttributeId(groupQualifier.getKimAttrDefnId());
2945 					if(ObjectUtils.isNotNull(origAttributes)){
2946 						for(GroupAttributeBo origAttribute: origAttributes){
2947 							if(StringUtils.equals(origAttribute.getKimAttributeId(), newGroupAttributeData.getKimAttributeId()) &&
2948 									StringUtils.equals(newGroupAttributeData.getAssignedToId(), origAttribute.getAssignedToId())){
2949 							    newGroupAttributeData.setId(origAttribute.getId());
2950 							}
2951 							if(origAttribute.getId()!=null && StringUtils.equals(origAttribute.getId(), newGroupAttributeData.getId())){
2952 							    newGroupAttributeData.setVersionNumber(origAttribute.getVersionNumber());
2953 							}
2954 						}
2955 					}
2956 					groupAttributeDataList.add(newGroupAttributeData);
2957 				}
2958 			}
2959 		}
2960 		return groupAttributeDataList;
2961 	}
2962 
2963     @SuppressWarnings("unchecked")
2964 	public KimDocumentRoleMember getKimDocumentRoleMember(MemberType memberType, String memberId, String roleId){
2965     	if(memberType == null || StringUtils.isEmpty(memberId) || StringUtils.isEmpty(roleId)) {
2966     		return null;
2967         }
2968     	KimDocumentRoleMember documentRoleMember = new KimDocumentRoleMember();
2969     	documentRoleMember.setRoleId(roleId);
2970     	Map<String, String> criteria = new HashMap<String, String>();
2971     	criteria.put("roleId", roleId);
2972     	criteria.put("mbr_id", memberId);
2973 
2974     	List<RoleMemberBo> matchingRoleMembers = (List<RoleMemberBo>)getBusinessObjectService().findMatching(RoleMemberBo.class, criteria);
2975     	if (matchingRoleMembers==null || matchingRoleMembers.size()<1) { return null; }
2976 
2977     	RoleMemberBo roleMemberImpl = matchingRoleMembers.get(0);
2978     	documentRoleMember.setRoleMemberId(roleMemberImpl.getId());
2979     	if(MemberType.PRINCIPAL.equals(memberType)){
2980     		Principal principal = getIdentityService().getPrincipal(memberId);
2981     		if (principal != null) {
2982     			documentRoleMember.setMemberId(principal.getPrincipalId());
2983         		documentRoleMember.setMemberName(principal.getPrincipalName());
2984         		documentRoleMember.setMemberTypeCode(MemberType.PRINCIPAL.getCode());
2985     		}    		
2986         } else if(MemberType.GROUP.equals(memberType)){
2987         	Group group = getGroupService().getGroup(memberId);
2988         	if (group != null) {
2989         		documentRoleMember.setMemberNamespaceCode(group.getNamespaceCode());
2990         		documentRoleMember.setMemberId(group.getId());
2991         		documentRoleMember.setMemberName(group.getName());
2992         		documentRoleMember.setMemberTypeCode(MemberType.GROUP.getCode());
2993         	}
2994         	
2995         } else if(MemberType.ROLE.equals(memberType)){
2996         	Role role = getRoleService().getRole(memberId);
2997         	if (role != null) {
2998         		documentRoleMember.setMemberNamespaceCode(role.getNamespaceCode());
2999         		documentRoleMember.setMemberId(role.getId());
3000         		documentRoleMember.setMemberName(role.getName());
3001         		documentRoleMember.setMemberTypeCode(MemberType.ROLE.getCode());
3002         	}        	
3003         }
3004     	return documentRoleMember;
3005     }
3006 
3007     protected Set<String> getChangedRoleResponsibilityIds(
3008 			IdentityManagementRoleDocument identityManagementRoleDocument, List<RoleResponsibilityBo> origRoleResponsibilities){
3009 		Set<String> lRet = new HashSet<String>();
3010 		List<String> newResp = new ArrayList<String>();
3011 		List<String> oldResp = new ArrayList<String>();
3012 		if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getResponsibilities())){
3013 			for(KimDocumentRoleResponsibility documentRoleResponsibility: identityManagementRoleDocument.getResponsibilities()){
3014 				newResp.add(documentRoleResponsibility.getResponsibilityId());
3015 			}
3016 		}
3017 		if(ObjectUtils.isNotNull(origRoleResponsibilities)){
3018 			for(RoleResponsibilityBo roleRespBo: origRoleResponsibilities){
3019 				oldResp.add(roleRespBo.getResponsibilityId());
3020 			}
3021 		}
3022 		lRet.addAll(newResp);
3023 		lRet.addAll(oldResp);
3024 
3025 		return lRet;
3026 	}
3027 
3028 	public KimTypeInfoService getKimTypeInfoService() {
3029 		if ( kimTypeInfoService == null ) {
3030 			kimTypeInfoService = KimApiServiceLocator.getKimTypeInfoService();
3031 		}
3032 		return kimTypeInfoService;
3033 	}
3034 
3035     public List<KimDocumentRoleMember> getRoleMembers(Map<String,String> fieldValues) {
3036         List<KimDocumentRoleMember> matchingRoleMembers = new ArrayList<KimDocumentRoleMember>();
3037         //Remove since they are KNS fieldValues and not BO
3038         fieldValues.remove(KRADConstants.BACK_LOCATION);
3039         fieldValues.remove(KRADConstants.DOC_FORM_KEY);
3040         fieldValues.remove(KRADConstants.DOC_NUM);
3041 
3042 
3043 
3044 		List<RoleMember> matchingRoleMembersTemp = getRoleService().findRoleMembers(toQuery(fieldValues)).getResults();
3045 		KimDocumentRoleMember matchingRoleMember;
3046 		BusinessObject roleMemberObject;
3047 		RoleMemberBo roleMemberBo;
3048 		if(CollectionUtils.isNotEmpty(matchingRoleMembersTemp)){
3049 			for(RoleMember roleMember: matchingRoleMembersTemp){
3050 				roleMemberBo = getRoleMember(roleMember.getId());
3051 				roleMemberObject = getMember(roleMemberBo.getType(), roleMemberBo.getMemberId());
3052 				matchingRoleMember = new KimDocumentRoleMember();
3053 				KimCommonUtilsInternal.copyProperties(matchingRoleMember, roleMemberBo);
3054                 matchingRoleMember.setMemberId(roleMemberBo.getMemberId());
3055                 matchingRoleMember.setRoleMemberId(roleMemberBo.getId());
3056 				matchingRoleMember.setMemberName(getMemberName(roleMemberBo.getType(), roleMemberObject));
3057 				matchingRoleMember.setMemberNamespaceCode(getMemberNamespaceCode(roleMemberBo.getType(), roleMemberObject));
3058 				matchingRoleMember.setQualifiers(getQualifiers(roleMemberBo.getAttributeDetails()));
3059 				matchingRoleMembers.add(matchingRoleMember);
3060 			}
3061 		}
3062 		return matchingRoleMembers;
3063     }
3064 
3065    private QueryByCriteria toQuery(Map<String,String> fieldValues) {
3066        String memberTypeCode = fieldValues.get(KIMPropertyConstants.KimMember.MEMBER_TYPE_CODE);
3067        String memberName = fieldValues.get(KimConstants.KimUIConstants.MEMBER_NAME);
3068        String memberNamespaceCode = fieldValues.get(KimConstants.KimUIConstants.MEMBER_NAMESPACE_CODE);
3069 
3070        if(StringUtils.isNotEmpty(memberName) || StringUtils.isNotEmpty(memberNamespaceCode)) {
3071             String memberId  = getMemberIdByName(MemberType.fromCode(memberTypeCode),memberNamespaceCode,memberName)  ;
3072            if(StringUtils.isNotEmpty(memberId)) {
3073                   fieldValues.put(KIMPropertyConstants.KimMember.MEMBER_ID, memberId);
3074            }
3075        }
3076 
3077        List<Predicate> pred = new ArrayList<Predicate>();
3078 
3079        pred.add(PredicateUtils.convertMapToPredicate(fieldValues));
3080        Predicate[] predicates = new Predicate[0];
3081        predicates = pred.toArray(predicates)  ;
3082         return QueryByCriteria.Builder.fromPredicates(predicates);
3083     }
3084 
3085     private List<KimDocumentRoleQualifier> getQualifiers(List<RoleMemberAttributeDataBo> attributes){
3086     	if (attributes==null) {return null;}
3087     	List<KimDocumentRoleQualifier> qualifiers = new ArrayList<KimDocumentRoleQualifier>();
3088     	KimDocumentRoleQualifier qualifier;
3089     	if(ObjectUtils.isNotNull(attributes)){
3090 	    	for(RoleMemberAttributeDataBo attribute: attributes){
3091 		    	qualifier = new KimDocumentRoleQualifier();
3092 				qualifier.setAttrDataId(attribute.getId());
3093 				qualifier.setAttrVal(attribute.getAttributeValue());
3094 				qualifier.setRoleMemberId(attribute.getAssignedToId());
3095 				qualifier.setKimTypId(attribute.getKimTypeId());
3096 				qualifier.setKimAttrDefnId(attribute.getKimAttributeId());
3097 				qualifier.setKimAttribute(attribute.getKimAttribute());
3098 				qualifiers.add(qualifier);
3099 	    	}
3100     	}
3101     	return qualifiers;
3102     }
3103     
3104 	public ResponsibilityInternalService getResponsibilityInternalService() {
3105 		if ( responsibilityInternalService == null ) {
3106 				responsibilityInternalService = KimImplServiceLocator.getResponsibilityInternalService();
3107 		}
3108 		return responsibilityInternalService;
3109 	}
3110 
3111    public PermissionService getPermissionService() {
3112 		if ( permissionService == null ) {
3113 				permissionService = KimApiServiceLocator.getPermissionService();
3114 		}
3115 		return permissionService;
3116 	}
3117 
3118     public ParameterService getParameterService() {
3119     	if ( parameterService == null ) {
3120     		parameterService = CoreFrameworkServiceLocator.getParameterService();
3121     	}
3122     	return parameterService;
3123     }
3124 
3125     public void setParameterService(ParameterService parameterService) {
3126     	this.parameterService = parameterService;
3127     }
3128 
3129     public static IdentityArchiveService getIdentityArchiveService() {
3130         return GlobalResourceLoader.getService(KIM_IDENTITY_ARCHIVE_SERVICE);
3131     }
3132 
3133     public UiDocumentServiceDAO getUiDocumentServiceDAO() {
3134         if ( uiDocumentServiceDAO == null ) {
3135             uiDocumentServiceDAO = KIMServiceLocatorInternal.getUiDocumentServiceDAO();
3136         }
3137         return uiDocumentServiceDAO;
3138     }
3139 
3140     public void setUiDocumentService(UiDocumentServiceDAO uiDocumentServiceDAO) {
3141         this.uiDocumentServiceDAO = uiDocumentServiceDAO;
3142     }
3143 }