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