diff --git a/src/main/java/org/olat/admin/securitygroup/gui/multi/UsersToGroupWizardStep01.java b/src/main/java/org/olat/admin/securitygroup/gui/multi/UsersToGroupWizardStep01.java
index 043c3033157eb6adaf75d55d424d3825df8c2a1d..3f1eb2fc21f37cab8e780028d1058b02319100eb 100644
--- a/src/main/java/org/olat/admin/securitygroup/gui/multi/UsersToGroupWizardStep01.java
+++ b/src/main/java/org/olat/admin/securitygroup/gui/multi/UsersToGroupWizardStep01.java
@@ -24,6 +24,7 @@ import org.olat.core.gui.components.form.flexible.impl.Form;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.generic.wizard.BasicStep;
 import org.olat.core.gui.control.generic.wizard.PrevNextFinishConfig;
+import org.olat.core.gui.control.generic.wizard.Step;
 import org.olat.core.gui.control.generic.wizard.StepFormController;
 import org.olat.core.gui.control.generic.wizard.StepsRunContext;
 import org.olat.core.util.mail.MailTemplate;
@@ -47,7 +48,7 @@ public class UsersToGroupWizardStep01 extends BasicStep {
 		setI18nTitleAndDescr("import.title.select", null);
 		
 		if(mailDefaultTemplate == null) {
-			setNextStep(BasicStep.NOSTEP);
+			setNextStep(Step.NOSTEP);
 		} else {
 			setNextStep(new UsersToGroupWizardStep02(ureq));
 		}
diff --git a/src/main/java/org/olat/admin/user/UserSearchFlexiController.java b/src/main/java/org/olat/admin/user/UserSearchFlexiController.java
index 10282ff03cc2a4b5358cd407871955ee88a5b3ec..3abdc12164234d998a6798710ae717660940d654 100644
--- a/src/main/java/org/olat/admin/user/UserSearchFlexiController.java
+++ b/src/main/java/org/olat/admin/user/UserSearchFlexiController.java
@@ -102,7 +102,8 @@ public class UserSearchFlexiController extends FlexiAutoCompleterController {
 
 	private static final String usageIdentifyer = UserTableDataModel.class.getCanonicalName();
 	
-	private FormLink backLink, searchButton;
+	private FormLink backLink;
+	private FormLink searchButton;
 	private TextElement loginEl;
 	private Map <String,FormItem>propFormItems;
 	private FlexiTableElement tableEl;
diff --git a/src/main/java/org/olat/basesecurity/BaseSecurity.java b/src/main/java/org/olat/basesecurity/BaseSecurity.java
index e2257501af7bbdf729dc75824f8aa5dbe766dc6b..4cb050a7a4eb5d7153d366dcd98cfa2129068c33 100644
--- a/src/main/java/org/olat/basesecurity/BaseSecurity.java
+++ b/src/main/java/org/olat/basesecurity/BaseSecurity.java
@@ -105,8 +105,8 @@ public interface BaseSecurity {
 	/**
 	 * Specialized method to import identities in courses, groups... The query
 	 * search in the legacy name of identity, in authentication user name,
-	 * concat first and last name and institutional number. It's all case
-	 * insensitive.
+	 * concat first and last name, email, institutional number, institutional
+	 * email. It's all case insensitive.
 	 * 
 	 * @param identityNames A list of names
 	 * @return A list of identities
diff --git a/src/main/java/org/olat/basesecurity/manager/IdentityDAO.java b/src/main/java/org/olat/basesecurity/manager/IdentityDAO.java
index 580ada2aadb3177f662955ffc862085a9f83808f..e428dcd1b8b7aeb1013cee271508ab014c7202a9 100644
--- a/src/main/java/org/olat/basesecurity/manager/IdentityDAO.java
+++ b/src/main/java/org/olat/basesecurity/manager/IdentityDAO.java
@@ -81,6 +81,8 @@ public class IdentityDAO {
 		  .append(" where lower(ident.name) in (:names)")
 		  .append(" or lower(auth.authusername) in (:names)")
 		  .append(" or lower(concat(user.firstName,' ', user.lastName)) in (:names)")
+		  .append(" or lower(user.email) in (:names)")
+		  .append(" or lower(user.institutionalEmail) in (:names)")
 		  .append(" or lower(user.institutionalUserIdentifier) in (:names)");
 
 		List<String> loweredIdentityNames = names.stream()
@@ -131,6 +133,16 @@ public class IdentityDAO {
 		if(names.contains(fullName.toLowerCase())) {
 			namedIdentity.addName(fullName);
 		}
+		
+		if(StringHelper.containsNonWhitespace(user.getEmail())
+				&& names.contains(user.getEmail().toLowerCase())) {
+			namedIdentity.addName(user.getEmail());
+		}
+		
+		if(StringHelper.containsNonWhitespace(user.getInstitutionalEmail())
+				&& names.contains(user.getInstitutionalEmail().toLowerCase())) {
+			namedIdentity.addName(user.getInstitutionalEmail());
+		}
 	}
 	
 	public void setIdentityLastLogin(IdentityRef identity, Date lastLogin) {
diff --git a/src/main/java/org/olat/core/gui/control/generic/wizard/DefaultStepsRunContext.java b/src/main/java/org/olat/core/gui/control/generic/wizard/DefaultStepsRunContext.java
index 335a66ddf5191ae7af87bb884608bf764c490a82..f6261c749305a3f6a3f9c2b929c685acf147afdb 100644
--- a/src/main/java/org/olat/core/gui/control/generic/wizard/DefaultStepsRunContext.java
+++ b/src/main/java/org/olat/core/gui/control/generic/wizard/DefaultStepsRunContext.java
@@ -47,4 +47,8 @@ public class DefaultStepsRunContext implements StepsRunContext {
 		return context.containsKey(key);
 	}
 
+	@Override
+	public void remove(String key) {
+		context.remove(key);
+	}
 }
diff --git a/src/main/java/org/olat/core/gui/control/generic/wizard/StepFormBasicController.java b/src/main/java/org/olat/core/gui/control/generic/wizard/StepFormBasicController.java
index 0da1728bdd6f098ca963e33d7e0546216902b489..60706f06d74c1961084d6eb16e4ca509b8478777 100644
--- a/src/main/java/org/olat/core/gui/control/generic/wizard/StepFormBasicController.java
+++ b/src/main/java/org/olat/core/gui/control/generic/wizard/StepFormBasicController.java
@@ -25,6 +25,8 @@
 */
 package org.olat.core.gui.control.generic.wizard;
 
+import java.util.List;
+
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.form.flexible.FormItem;
@@ -94,15 +96,26 @@ public abstract class StepFormBasicController extends FormBasicController implem
 		runContext = null;
 	}
 
-	protected void addToRunContext(String key, Object value){
+	protected void addToRunContext(String key, Object value) {
 		runContext.put(key, value);
 	}
-	protected boolean containsRunContextKey(String key){
+	
+	protected void removeFromRunContext(String key) {
+		runContext.remove(key);
+	}
+	
+	protected boolean containsRunContextKey(String key) {
 		return runContext.containsKey(key);
 	}
-	protected Object getFromRunContext(String key){
+	
+	protected Object getFromRunContext(String key) {
 		return runContext.get(key);
 	}
+
+	@SuppressWarnings({ "unused", "unchecked" })
+	protected <T> List<T> getListFromRunContext(String key, Class<T> resultClass) {
+		return (List<T>)runContext.get(key);
+	}
 	
 	public void back() {
 		
diff --git a/src/main/java/org/olat/core/gui/control/generic/wizard/StepsRunContext.java b/src/main/java/org/olat/core/gui/control/generic/wizard/StepsRunContext.java
index a1040695c81b9876bbecdc58f79d9f7f9995bcde..3a04b471e10e06e231d3e65d40db87c7f72fe7c4 100644
--- a/src/main/java/org/olat/core/gui/control/generic/wizard/StepsRunContext.java
+++ b/src/main/java/org/olat/core/gui/control/generic/wizard/StepsRunContext.java
@@ -31,23 +31,11 @@ package org.olat.core.gui.control.generic.wizard;
  */
 public interface StepsRunContext {
 	
-	/**
-	 * 
-	 * @param key
-	 * @param value
-	 */
 	public void put(String key, Object value);
-	/**
-	 * 
-	 * @param key
-	 * @return
-	 */
+
 	public Object get(String key);
 	
-	/**
-	 * 
-	 * @param key
-	 * @return
-	 */
 	public boolean containsKey(String key);
+	
+	public void remove(String key);
 }
diff --git a/src/main/java/org/olat/course/member/wizard/ImportMemberByUsernamesController.java b/src/main/java/org/olat/course/member/wizard/ImportMemberByUsernamesController.java
index c23cc7d13d4be9a573a091a2584105592ee246e5..c7a5ef0f8da70cc58a395b3d6686e50f9578da12 100644
--- a/src/main/java/org/olat/course/member/wizard/ImportMemberByUsernamesController.java
+++ b/src/main/java/org/olat/course/member/wizard/ImportMemberByUsernamesController.java
@@ -19,54 +19,254 @@
  */
 package org.olat.course.member.wizard;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.olat.admin.user.UserTableDataModel;
+import org.olat.basesecurity.BaseSecurity;
+import org.olat.basesecurity.BaseSecurityModule;
+import org.olat.basesecurity.OrganisationRoles;
+import org.olat.basesecurity.OrganisationService;
+import org.olat.basesecurity.model.FindNamedIdentity;
 import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.form.flexible.FormItem;
 import org.olat.core.gui.components.form.flexible.FormItemContainer;
+import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement;
+import org.olat.core.gui.components.form.flexible.elements.FormLink;
 import org.olat.core.gui.components.form.flexible.elements.TextElement;
 import org.olat.core.gui.components.form.flexible.impl.Form;
+import org.olat.core.gui.components.form.flexible.impl.FormEvent;
+import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.generic.wizard.StepFormBasicController;
 import org.olat.core.gui.control.generic.wizard.StepsEvent;
 import org.olat.core.gui.control.generic.wizard.StepsRunContext;
+import org.olat.core.id.Identity;
+import org.olat.user.UserManager;
+import org.olat.user.propertyhandlers.UserPropertyHandler;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * 
  * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
  */
 public class ImportMemberByUsernamesController extends StepFormBasicController {
+	
+	private static final String usageIdentifyer = UserTableDataModel.class.getCanonicalName();
 
 	private TextElement idata;
+	private FlexiTableElement tableEl;
+	private ImportMemberOverviewDataModel userTableModel;
+	
+	private FormLink backLink;
+	private FormLayoutContainer inputContainer;
+	private FormLayoutContainer tableContainer;
+
+	private boolean isAdministrativeUser;
+	private final List<Identity> anonymousUsers;
+
+	private List<String> notFoundNames;
+	private List<Identity> identitiesList;
+	
+	@Autowired
+	private UserManager userManager;
+	@Autowired
+	private BaseSecurity securityManager;
+	@Autowired
+	private BaseSecurityModule securityModule;
+	@Autowired
+	private OrganisationService organisationService;
 
 	public ImportMemberByUsernamesController(UserRequest ureq, WindowControl wControl, Form rootForm,
 			StepsRunContext runContext) {
-		super(ureq, wControl, rootForm, runContext, LAYOUT_DEFAULT, null);
+		super(ureq, wControl, rootForm, runContext, LAYOUT_BAREBONE, null);
+		setTranslator(userManager.getPropertyHandlerTranslator(getTranslator()));
+		anonymousUsers = organisationService.getIdentitiesWithRole(OrganisationRoles.guest);
+		isAdministrativeUser = securityModule.isUserAllowedAdminProps(ureq.getUserSession().getRoles());
 		initForm (ureq);
 	}
 
-	public boolean validate() {
-		return !idata.isEmpty("form.legende.mandatory");
+	@Override
+	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		// input field
+		inputContainer = FormLayoutContainer.createDefaultFormLayout("input", getTranslator());
+		formLayout.add(inputContainer);
+		
+		idata = uifactory.addTextAreaElement("addusers", "form.addusers", -1, 15, 40, true, false, " ", inputContainer);
+		idata.setElementCssClass("o_sel_user_import");
+		idata.setExampleKey ("form.names.example", null);
+		
+		// table for duplicates
+		String page = velocity_root + "/warn_duplicates.html";
+		tableContainer = FormLayoutContainer.createCustomFormLayout("table", getTranslator(), page);
+		formLayout.add(tableContainer);
+		tableContainer.setVisible(false);
+		
+		// user search form
+		backLink = uifactory.addFormLink("back", tableContainer);
+		backLink.setIconLeftCSS("o_icon o_icon_back");
+		
+		//add the table
+		FlexiTableColumnModel tableColumnModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();
+		int colIndex = 0;
+		List<UserPropertyHandler> userPropertyHandlers = userManager.getUserPropertyHandlersFor(usageIdentifyer, isAdministrativeUser);
+		List<UserPropertyHandler> resultingPropertyHandlers = new ArrayList<>();
+		// followed by the users fields
+		for (int i = 0; i < userPropertyHandlers.size(); i++) {
+			UserPropertyHandler userPropertyHandler	= userPropertyHandlers.get(i);
+			boolean visible = UserManager.getInstance().isMandatoryUserProperty(usageIdentifyer , userPropertyHandler);
+			if(visible) {
+				resultingPropertyHandlers.add(userPropertyHandler);
+				tableColumnModel.addFlexiColumnModel(new DefaultFlexiColumnModel(userPropertyHandler.i18nColumnDescriptorLabelKey(), colIndex++));
+			}
+		}
+		
+		userTableModel = new ImportMemberOverviewDataModel(resultingPropertyHandlers, getLocale(), tableColumnModel);
+		tableEl = uifactory.addTableElement(getWindowControl(), "users", userTableModel, 100, false, getTranslator(), tableContainer);
+		tableEl.setCustomizeColumns(false);
+		tableEl.setMultiSelect(true);
+		tableEl.setSelectAllEnable(true);
 	}
 
-	public String getLoginsString() {
-		return idata.getValue();
+	@Override
+	protected void doDispose() {
+		//
 	}
-
+	
 	@Override
 	protected void formOK(UserRequest ureq) {
-		String logins = idata.getValue();
-		addToRunContext("logins", logins);
-		fireEvent(ureq, StepsEvent.ACTIVATE_NEXT);
+		//
 	}
 
 	@Override
-	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
-		idata = uifactory.addTextAreaElement("addusers", "form.addusers", -1, 15, 40, true, false, " ", formLayout);
-		idata.setElementCssClass("o_sel_user_import");
-		idata.setExampleKey ("form.names.example", null);
+	protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
+		if(backLink == source) {
+			doBackToInput();
+		}
+		super.formInnerEvent(ureq, source, event);
 	}
 
 	@Override
-	protected void doDispose() {
-		//
+	protected void formNext(UserRequest ureq) {
+		String logins = idata.getValue();
+		if(tableContainer.isVisible()) {
+			selectDuplicates();
+			addToRunContext("keyIdentities", new ArrayList<>(identitiesList));
+			addToRunContext("notFounds", notFoundNames);
+			fireEvent(ureq, StepsEvent.ACTIVATE_NEXT);
+		} else if(processInput(logins)) {
+			tableContainer.setVisible(true);
+			inputContainer.setVisible(false);
+		} else {
+			addToRunContext("keyIdentities", new ArrayList<>(identitiesList));
+			addToRunContext("notFounds", notFoundNames);
+			fireEvent(ureq, StepsEvent.ACTIVATE_NEXT);
+		}
+	}
+
+	private void doBackToInput() {
+		tableContainer.setVisible(false);
+		inputContainer.setVisible(true);
+		identitiesList = null;
+	}
+	
+	private void selectDuplicates() {
+		List<Identity> selectedIdentities = new ArrayList<>();
+		for(Integer index:tableEl.getMultiSelectedIndex()) {
+			Identity identity = userTableModel.getObject(index.intValue());
+			if(identity != null) {
+				selectedIdentities.add(identity);
+			}
+		}
+		identitiesList.addAll(selectedIdentities);
+	}
+
+	/**
+	 * 
+	 * @param inp The text input
+	 * @return true if duplicates found
+	 */
+	private boolean processInput(String inp) {
+		List<String> identList = getLines(inp);
+		Set<String> identListLowercase = identList.stream()
+				.map(String::toLowerCase)
+				.collect(Collectors.toSet());
+
+		notFoundNames = new ArrayList<>();
+		Map<String, Set<Identity>> duplicates = new HashMap<>();
+		Set<Identity> okSet = new HashSet<>();
+
+		// search by names, institutional identifier, first + last names, authentication user names
+		List<FindNamedIdentity> identities = securityManager.findIdentitiesBy(identList);
+		for(FindNamedIdentity identity:identities) {
+			identListLowercase.removeAll(identity.getNamesLowerCase());
+			if(!validIdentity(identity.getIdentity())) {
+				notFoundNames.add(identity.getFirstFoundName());
+			} else if (!okSet.contains(identity.getIdentity())) {
+				okSet.add(identity.getIdentity());
+			}
+			
+			for(String name:identity.getNamesLowerCase()) {
+				Set<Identity> ids = duplicates.computeIfAbsent(name, n -> new HashSet<>());
+				ids.add(identity.getIdentity());
+			}
+		}
+
+		notFoundNames.addAll(identListLowercase);
+		return processDuplicates(okSet, duplicates);
+	}
+	
+	private boolean processDuplicates(Set<Identity> okSet, Map<String, Set<Identity>> duplicates) {
+		Set<Identity> duplicatesSet = new HashSet<>();
+		StringBuilder sb = new StringBuilder();
+		for(Map.Entry<String,Set<Identity>> entry:duplicates.entrySet()) {
+			if(entry.getValue().size() > 1) {
+				if(sb.length() > 0) sb.append(", ");
+				sb.append(entry.getKey());
+				duplicatesSet.addAll(entry.getValue());
+			}	
+		}
+		
+		okSet.removeAll(duplicatesSet);
+		
+		identitiesList = new ArrayList<>(okSet);
+
+		if(sb.length() > 0) {
+			tableContainer.contextPut("duplicatesMsg", translate("warn.duplicates.names", sb.toString()));
+			tableContainer.setVisible(true);
+			inputContainer.setVisible(false);
+			
+			userTableModel.setObjects(new ArrayList<>(duplicatesSet));
+			tableEl.reset(true, true, true);
+			return true;
+		}
+		return false;
+	}
+	
+	private List<String> getLines(String inp) {
+		List<String> identList = new ArrayList<>();
+		String[] lines = inp.split("\r?\n");
+		for (int i = 0; i < lines.length; i++) {
+			String username = lines[i].trim();
+			if(username.length() > 0) {
+				identList.add(username);
+			}
+		}
+		return identList;
+	}
+	
+	private boolean validIdentity(Identity ident) {
+		return ident != null
+				&& ident.getStatus().compareTo(Identity.STATUS_VISIBLE_LIMIT) < 0
+				&& !anonymousUsers.contains(ident);
 	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewDataModel.java b/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewDataModel.java
index bde98ca39aef13e7f251260e50a4a91296c9aea6..b3340ce65bb1dba4fc509bec1adc1b9d74e9a70d 100644
--- a/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewDataModel.java
+++ b/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewDataModel.java
@@ -38,6 +38,11 @@ public class ImportMemberOverviewDataModel extends DefaultTableDataModel<Identit
 	private FlexiTableColumnModel columnModel;
 	private final List<UserPropertyHandler> userPropertyHandlers;
 	
+	public ImportMemberOverviewDataModel(List<UserPropertyHandler> userPropertyHandlers, Locale locale,
+			FlexiTableColumnModel columnModel) {
+		this(new ArrayList<>(), userPropertyHandlers, locale, columnModel);
+	}
+	
 	public ImportMemberOverviewDataModel(List<Identity> identities, List<UserPropertyHandler> userPropertyHandlers,
 			Locale locale, FlexiTableColumnModel columnModel) {
 		super(identities);
diff --git a/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewIdentitiesController.java b/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewIdentitiesController.java
index 7504e49fe0e7d575d6fad4422c7abc87c61774ae..618baa969196a062fa164796aec71bd58e7ce682 100644
--- a/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewIdentitiesController.java
+++ b/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewIdentitiesController.java
@@ -20,19 +20,14 @@
 package org.olat.course.member.wizard;
 
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 import org.olat.admin.user.UserTableDataModel;
-import org.olat.basesecurity.BaseSecurity;
 import org.olat.basesecurity.BaseSecurityModule;
 import org.olat.basesecurity.OrganisationRoles;
 import org.olat.basesecurity.OrganisationService;
-import org.olat.basesecurity.model.FindNamedIdentity;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.form.flexible.FormItemContainer;
 import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement;
@@ -46,9 +41,7 @@ import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.generic.wizard.StepFormBasicController;
 import org.olat.core.gui.control.generic.wizard.StepsEvent;
 import org.olat.core.gui.control.generic.wizard.StepsRunContext;
-import org.olat.core.gui.translator.Translator;
 import org.olat.core.id.Identity;
-import org.olat.core.id.UserConstants;
 import org.olat.user.UserManager;
 import org.olat.user.propertyhandlers.UserPropertyHandler;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -61,44 +54,31 @@ public class ImportMemberOverviewIdentitiesController extends StepFormBasicContr
 	
 	private static final String usageIdentifyer = UserTableDataModel.class.getCanonicalName();
 	
-	private FlexiTableElement tableEl;
-	private ImportMemberOverviewDataModel userTableModel;
-	
 	private List<Identity> oks;
-	private List<String> notfounds;
+	private List<String> notFounds;
 	private boolean isAdministrativeUser;
 	private final List<Identity> anonymousUsers;
-	private Map<String,Set<Identity>> duplicates = new HashMap<>();
-	
 	
 	@Autowired
 	private UserManager userManager;
 	@Autowired
-	private BaseSecurity securityManager;
-	@Autowired
 	private BaseSecurityModule securityModule;
 	@Autowired
 	private OrganisationService organisationService;
 
 	public ImportMemberOverviewIdentitiesController(UserRequest ureq, WindowControl wControl, Form rootForm, StepsRunContext runContext) {
 		super(ureq, wControl, rootForm, runContext, LAYOUT_VERTICAL, null);
-		
+		setTranslator(userManager.getPropertyHandlerTranslator(getTranslator()));
 		anonymousUsers = organisationService.getIdentitiesWithRole(OrganisationRoles.guest);
 		isAdministrativeUser = securityModule.isUserAllowedAdminProps(ureq.getUserSession().getRoles());
 		
 		oks = null;
-		if(containsRunContextKey("logins")) {
-			String logins = (String)runContext.get("logins");
-			loadModel(logins);
-		} else if(containsRunContextKey("keys")) {
-			@SuppressWarnings("unchecked")
-			List<String> keys = (List<String>)runContext.get("keys");
-			loadModel(keys);
-		} else if(containsRunContextKey("keyIdentities")) {
-			@SuppressWarnings("unchecked")
-			List<Identity> keys = (List<Identity>)runContext.get("keyIdentities");
-			loadModelByIdentities(keys);
+		notFounds = getListFromRunContext("notFounds", String.class);
+		if(notFounds == null) {
+			notFounds = new ArrayList<>();
 		}
+		List<Identity> keys = getListFromRunContext("keyIdentities", Identity.class);
+		loadModelByIdentities(keys);
 
 		initForm (ureq);
 	}
@@ -106,14 +86,14 @@ public class ImportMemberOverviewIdentitiesController extends StepFormBasicContr
 	@Override
 	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
 		formLayout.setElementCssClass("o_sel_user_import_overview");
-		if(notfounds != null && !notfounds.isEmpty()) {
+		if(notFounds != null && !notFounds.isEmpty()) {
 			String page = velocity_root + "/warn_notfound.html";
 			FormLayoutContainer warnLayout = FormLayoutContainer.createCustomFormLayout("warnNotFounds", getTranslator(), page);
 			warnLayout.setRootForm(mainForm);
 			formLayout.add(warnLayout);
 			
 			StringBuilder sb = new StringBuilder();
-			for(String notfound:notfounds) {
+			for(String notfound:notFounds) {
 				if(sb.length() > 0) sb.append(", ");
 				sb.append(notfound);
 			}
@@ -122,23 +102,6 @@ public class ImportMemberOverviewIdentitiesController extends StepFormBasicContr
 			warnLayout.contextPut("notFounds", msg);
 		}
 		
-		StringBuilder sb = new StringBuilder();
-		for(Map.Entry<String,Set<Identity>> entry:duplicates.entrySet()) {
-			if(entry.getValue().size() > 1) {
-				if(sb.length() > 0) sb.append(", ");
-				sb.append(entry.getKey());
-			}	
-		}
-		
-		
-		if(sb.length() > 0) {
-			String page = velocity_root + "/warn_duplicates.html";
-			FormLayoutContainer warnLayout = FormLayoutContainer.createCustomFormLayout("warnNotFounds", getTranslator(), page);
-			warnLayout.setRootForm(mainForm);
-			formLayout.add(warnLayout);
-			warnLayout.contextPut("duplicatesMsg", translate("warn.duplicates.names", sb.toString()));
-		}
-		
 		//add the table
 		FlexiTableColumnModel tableColumnModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();
 		int colIndex = 0;
@@ -154,42 +117,18 @@ public class ImportMemberOverviewIdentitiesController extends StepFormBasicContr
 			}
 		}
 		
-		Translator myTrans = userManager.getPropertyHandlerTranslator(getTranslator());
-		userTableModel = new ImportMemberOverviewDataModel(oks, resultingPropertyHandlers, getLocale(), tableColumnModel);
-		tableEl = uifactory.addTableElement(getWindowControl(), "users", userTableModel, myTrans, formLayout);
+		ImportMemberOverviewDataModel userTableModel = new ImportMemberOverviewDataModel(oks, resultingPropertyHandlers, getLocale(), tableColumnModel);
+		FlexiTableElement tableEl = uifactory.addTableElement(getWindowControl(), "users", userTableModel, getTranslator(), formLayout);
 		tableEl.setCustomizeColumns(false);
-		//TODO OO-4545
-		/*
-		tableEl.setMultiSelect(true);
-		tableEl.setSelectAllEnable(true);
-		tableEl.selectAll();
-		*/
-	}
-	
-	private void loadModel(List<String> keys) {
-		notfounds = new ArrayList<>();
-		
-		Set<Identity> okSet = new HashSet<>();
-		for (String identityKey : keys) {
-			Identity ident = securityManager.loadIdentityByKey(Long.parseLong(identityKey));
-			if (!validIdentity(ident)) { // not found, add to not-found-list
-				notfounds.add(identityKey);
-			} else if (!okSet.contains(ident)) {
-				okSet.add(ident);
-			}
-		}
-		oks = new ArrayList<>(okSet);
 	}
 	
-	private void loadModelByIdentities(List<Identity> keys) {
-		notfounds = new ArrayList<>();
-		
+	private void loadModelByIdentities(List<Identity> identities) {
 		Set<Identity> okSet = new HashSet<>();
-		for (Identity ident : keys) {
+		for (Identity ident : identities) {
 			if (!validIdentity(ident)) {
 				String fullname = userManager.getUserDisplayName(ident);
 				if(fullname != null) {
-					notfounds.add(fullname);
+					notFounds.add(fullname);
 				}
 			} else if (!okSet.contains(ident)) {
 				okSet.add(ident);
@@ -198,76 +137,6 @@ public class ImportMemberOverviewIdentitiesController extends StepFormBasicContr
 		oks = new ArrayList<>(okSet);
 	}
 	
-	private void loadModel(String inp) {
-		oks = new ArrayList<>();
-		notfounds = new ArrayList<>();
-		duplicates.clear();
-		
-		Set<Identity> okSet = new HashSet<>();
-		List<String> identList = new ArrayList<>();
-		String[] lines = inp.split("\r?\n");
-		for (int i = 0; i < lines.length; i++) {
-			String username = lines[i].trim();
-			if(username.length() > 0) {
-				identList.add(username);
-			}
-		}
-		
-		// make a lower case copy of identList for processing username and email
-		Collection<String> identListLowercase = new HashSet<>(identList.size());
-		for (String ident:identList) {
-			identListLowercase.add(ident.toLowerCase());
-		}
-		
-		// search by names, institutional identifier, first + last names, authentication user names
-		List<FindNamedIdentity> identities = securityManager.findIdentitiesBy(identList);
-		for(FindNamedIdentity identity:identities) {
-			identListLowercase.removeAll(identity.getNamesLowerCase());
-			if(!validIdentity(identity.getIdentity())) {
-				notfounds.add(identity.getFirstFoundName());
-			} else if (!okSet.contains(identity.getIdentity())) {
-				okSet.add(identity.getIdentity());
-			}
-			
-			for(String name:identity.getNamesLowerCase()) {
-				Set<Identity> ids = duplicates.computeIfAbsent(name, n -> new HashSet<>());
-				ids.add(identity.getIdentity());
-			}
-		}
-		
-		//search by email, case insensitive
-		List<String> emailListLowercase = new ArrayList<>(identList.size());
-		for (String ident:identList) {
-			if(ident.indexOf('@') > 0) {
-				emailListLowercase.add(ident.toLowerCase());
-			}
-		}
-		
-		List<Identity> mailIdentities = userManager.findIdentitiesByEmail(emailListLowercase);
-		for(Identity identity:mailIdentities) {
-			String email = identity.getUser().getProperty(UserConstants.EMAIL, null);
-			if(email != null && identListLowercase.remove(email.toLowerCase())) {
-				duplicates.computeIfAbsent(email.toLowerCase(), n -> new HashSet<>()).add(identity);
-			}
-			String institutEmail = identity.getUser().getProperty(UserConstants.INSTITUTIONALEMAIL, null);
-			if(institutEmail != null && identListLowercase.remove(institutEmail.toLowerCase())) {
-				duplicates.computeIfAbsent(institutEmail.toLowerCase(), n -> new HashSet<>()).add(identity);
-			}
-			if(!validIdentity(identity)) {
-				if(email != null) {
-					notfounds.remove(email);
-				} else if(institutEmail != null) {
-					notfounds.remove(institutEmail);
-				}
-			} else if (!okSet.contains(identity)) {
-				okSet.add(identity);
-			}
-		}
-		
-		notfounds.addAll(identListLowercase);
-		oks = new ArrayList<>(okSet);
-	}
-	
 	private boolean validIdentity(Identity ident) {
 		return ident != null
 				&& ident.getStatus().compareTo(Identity.STATUS_VISIBLE_LIMIT) < 0
@@ -280,17 +149,11 @@ public class ImportMemberOverviewIdentitiesController extends StepFormBasicContr
 	
 	@Override
 	protected void formNext(UserRequest ureq) {
-		//TODO OO-4545
-		/*
-		List<Identity> selectedOks = new ArrayList<>(oks.size());
-		for(Integer index:tableEl.getMultiSelectedIndex()) {
-			Identity selected = userTableModel.getObject(index.intValue());
-			if(selected != null) {
-				selectedOks.add(selected);
-			}
+		if(notFounds == null || notFounds.isEmpty()) {
+			removeFromRunContext("notFounds");
+		} else {
+			addToRunContext("notFounds", notFounds);
 		}
-		addToRunContext("members", selectedOks);
-		*/
 		addToRunContext("members", oks);
 		fireEvent(ureq, StepsEvent.ACTIVATE_NEXT);
 	}
diff --git a/src/main/java/org/olat/course/member/wizard/_content/warn_duplicates.html b/src/main/java/org/olat/course/member/wizard/_content/warn_duplicates.html
index a6722d64934e2845f56e7f7d855b812f7c59d539..c626d072b81d656f7d4d943b127d68f1496f6ffc 100644
--- a/src/main/java/org/olat/course/member/wizard/_content/warn_duplicates.html
+++ b/src/main/java/org/olat/course/member/wizard/_content/warn_duplicates.html
@@ -1,4 +1,6 @@
+<div>$r.render("back")</div>
 <div class="o_warning">
 	$duplicatesMsg<br>
 	$r.translate("warn.duplicates.select")
-</div>
\ No newline at end of file
+</div>
+$r.render("users")
\ No newline at end of file
diff --git a/src/main/java/org/olat/user/UserImpl.java b/src/main/java/org/olat/user/UserImpl.java
index 684883b401f811ae9f55a2cb9e59f845dc835120..8d5f39d8337e049c77172c0ae230546db55d85d8 100644
--- a/src/main/java/org/olat/user/UserImpl.java
+++ b/src/main/java/org/olat/user/UserImpl.java
@@ -74,7 +74,7 @@ import org.olat.user.propertyhandlers.UserPropertyHandler;
  */
 @Entity
 @Table(name="o_user")
-public class UserImpl implements Persistable, User {
+public class UserImpl implements User {
 
 	private static final long serialVersionUID = -2872102058369727753L;
 	private static final Logger log = Tracing.createLoggerFor(UserImpl.class);