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