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