class DefaultAccUniformPasswordService extends AbstractEventableDtoService<AccUniformPasswordDto, AccUniformPassword, AccUniformPasswordFilter> implements AccUniformPasswordService {

	@Override
	public List<AccPasswordChangeOptionDto> findOptionsForPasswordChange(IdmIdentityDto identity, BasePermission ...permissions) {
		List<AccPasswordChangeOptionDto> result = Lists.newArrayList();
		
		AccUniformPasswordSystemFilter filter = new AccUniformPasswordSystemFilter();
		filter.setIdentityId(identity.getId());
		filter.setUniformPasswordDisabled(Boolean.FALSE);
		List<AccUniformPasswordSystemDto> uniformPasswordSystems = this.uniformPasswordSystemService.find(filter, null).getContent();

		// Group uniform password system by uniform password definition
		Map<AccUniformPasswordDto, List<AccAccountDto>> accountsForUniformPassword = Maps.newHashMap();

		// Same behavior as previous versions
		AccAccountFilter accountFilter = new AccAccountFilter();
		accountFilter.setOwnership(Boolean.TRUE);
		accountFilter.setSupportChangePassword(Boolean.TRUE);
		accountFilter.setIdentityId(identity.getId());
		accountFilter.setInProtection(Boolean.FALSE);

		// Include given permissions
		List<AccAccountDto> accounts = accountService.find(accountFilter, null, permissions).getContent();
		for (AccAccountDto account : accounts) {

			// One system can be place more than one in uniform password systems
			List<AccUniformPasswordSystemDto> uniformBySystem = uniformPasswordSystems.stream().filter(pfs -> {
				return pfs.getSystem().equals(account.getSystem());
			}).collect(Collectors.toList());

			if (CollectionUtils.isEmpty(uniformBySystem)) {
				// Simple account as option
				AccPasswordChangeOptionDto optionDto = new AccPasswordChangeOptionDto(account);
				optionDto.setNiceLabel(getNiceLabelForOption(account));
				result.add(optionDto);
				continue;
			}

			for (AccUniformPasswordSystemDto uniformPasswordSystemDto : uniformBySystem) {
				AccUniformPasswordDto definition = DtoUtils.getEmbedded(uniformPasswordSystemDto, AccUniformPasswordSystem_.uniformPassword, AccUniformPasswordDto.class, null);
				if (accountsForUniformPassword.containsKey(definition)) {
					accountsForUniformPassword.get(definition).add(account);
				} else {
					accountsForUniformPassword.put(definition, Lists.newArrayList(account));
				}
			}

		}

		// Check if exists account for uniform password and process options for them
		if (!accountsForUniformPassword.isEmpty()) {
			for (Entry<AccUniformPasswordDto, List<AccAccountDto>> entry : accountsForUniformPassword.entrySet()) {
				// There is also needed 
				AccUniformPasswordDto uniformPasswordDto = entry.getKey();
				AccPasswordChangeOptionDto optionDto = new AccPasswordChangeOptionDto(uniformPasswordDto, entry.getValue());
				optionDto.setNiceLabel(getNiceLabelForOption(uniformPasswordDto));
				optionDto.setChangeInIdm(uniformPasswordDto.isChangeInIdm());
				
				result.add(optionDto);
			}
		}

		return result;
	}

	@Autowired public  DefaultAccUniformPasswordService(AccUniformPasswordRepository repository,
			EntityEventManager entityEventManager);

}