diff --git a/src/main/java/de/bps/course/nodes/vc/provider/adobe/AdobeConnectProvider.java b/src/main/java/de/bps/course/nodes/vc/provider/adobe/AdobeConnectProvider.java
index e0441173a2094ce992edca0148bd28fa4210d9ac..0d9f6e37466707670dfdaf22b55decfc52175f49 100644
--- a/src/main/java/de/bps/course/nodes/vc/provider/adobe/AdobeConnectProvider.java
+++ b/src/main/java/de/bps/course/nodes/vc/provider/adobe/AdobeConnectProvider.java
@@ -373,7 +373,7 @@ public class AdobeConnectProvider extends LogDelegator implements VCProvider {
   	parameters.put("first-name", identity.getUser().getProperty(UserConstants.FIRSTNAME, null));
   	parameters.put("last-name", identity.getUser().getProperty(UserConstants.LASTNAME, null));
   	parameters.put("login", PREFIX + identity.getName());
-  	parameters.put("password", Encoder.encrypt(identity.getName() + "@" + Settings.getApplicationName()));
+  	parameters.put("password", Encoder.md5hash(identity.getName() + "@" + Settings.getApplicationName()));
   	parameters.put("type", userType);
   	parameters.put("has-children", "false");
   	Document responseDoc = getResponseDocument(sendRequest(parameters));
@@ -453,7 +453,7 @@ public class AdobeConnectProvider extends LogDelegator implements VCProvider {
     parameters.put("action", "login");
     if(accountId != null) parameters.put("account-id", accountId);
     parameters.put("login", PREFIX + identity.getName());
-    parameters.put("password", Encoder.encrypt(identity.getName() + "@" + Settings.getApplicationName()));
+    parameters.put("password", Encoder.md5hash(identity.getName() + "@" + Settings.getApplicationName()));
     Document responseDoc = getResponseDocument(sendRequest(parameters));
 
     return evaluateOk(responseDoc);
diff --git a/src/main/java/de/bps/course/nodes/vc/provider/wimba/WimbaClassroomProvider.java b/src/main/java/de/bps/course/nodes/vc/provider/wimba/WimbaClassroomProvider.java
index 876ffc61eae374516405dfab0f41c0ad1133d255..2a15adad9256647e358d8e8e61cc9c3b59f80623 100644
--- a/src/main/java/de/bps/course/nodes/vc/provider/wimba/WimbaClassroomProvider.java
+++ b/src/main/java/de/bps/course/nodes/vc/provider/wimba/WimbaClassroomProvider.java
@@ -226,7 +226,7 @@ public class WimbaClassroomProvider extends LogDelegator implements VCProvider {
 		// first delete recordings
 		Map<String, String> mapRecordings = listRecordings(roomId);
 		for(String key : mapRecordings.keySet()) {
-			removeClassroomRecording(key, config);
+			removeClassroomRecording(key);
 		}
 		
 		Map<String, String> parameters = new HashMap<String, String>();
@@ -410,7 +410,7 @@ public class WimbaClassroomProvider extends LogDelegator implements VCProvider {
 		parameters.put("function", "createUser");
 		parameters.put("target", PREFIX + identity.getKey());
 		parameters.put("password_type", "P");// specified password, see Wimba Classroom 6.0 API Guide, page 8
-		parameters.put("password", Encoder.encrypt(identity.getName() + "@" + Settings.getApplicationName()));
+		parameters.put("password", Encoder.md5hash(identity.getName() + "@" + Settings.getApplicationName()));
 		parameters.put("first_name", identity.getUser().getProperty(UserConstants.FIRSTNAME, null));
 		parameters.put("last_name", identity.getUser().getProperty(UserConstants.LASTNAME, null));
 		String raw = sendRequest(parameters);
@@ -519,7 +519,7 @@ public class WimbaClassroomProvider extends LogDelegator implements VCProvider {
 		return mapKeyName;
 	}
 	
-	public URL createClassroomRecordingUrl(String recordingId, Identity identity, VCConfiguration config) {
+	public URL createClassroomRecordingUrl(String recordingId, Identity identity) {
 		URL url = null;
 		/* Notice: This is a very special and wimba specific case, the recordingId must not prefixed! */
 		URI uri = UriBuilder.fromUri(protocol + "://" + baseUrl).port(port)
@@ -533,7 +533,7 @@ public class WimbaClassroomProvider extends LogDelegator implements VCProvider {
 		return url;
 	}
 	
-	public boolean removeClassroomRecording(String recordingId, VCConfiguration config) {
+	public boolean removeClassroomRecording(String recordingId) {
 		if(!loginAdmin()) throw new AssertException("Cannot login to Wimba Classroom. Please check module configuration and Wimba Classroom connectivity");
 		
 		Map<String, String> parameters = new HashMap<String, String>();
diff --git a/src/main/java/de/bps/course/nodes/vc/provider/wimba/WimbaDisplayController.java b/src/main/java/de/bps/course/nodes/vc/provider/wimba/WimbaDisplayController.java
index 303559af35522804cf755727fd7d15ff23bb8064..e50bc9d5c3ef8ceec9f9fb065cdc3c0313754060 100644
--- a/src/main/java/de/bps/course/nodes/vc/provider/wimba/WimbaDisplayController.java
+++ b/src/main/java/de/bps/course/nodes/vc/provider/wimba/WimbaDisplayController.java
@@ -265,7 +265,7 @@ public class WimbaDisplayController extends BasicController {
         String key = (String) recTable.getTableDataModel().getValueAt(row, 0);
         if(action.equals(COMMAND_OPEN_RECORDING)) {
           wimba.login(ureq.getIdentity(), null);
-          URL url = wimba.createClassroomRecordingUrl(key, ureq.getIdentity(), config);
+          URL url = wimba.createClassroomRecordingUrl(key, ureq.getIdentity());
           RedirectMediaResource rmr = new RedirectMediaResource(url.toString());
           ureq.getDispatchResult().setResultingMediaResource(rmr);
           return;
@@ -283,7 +283,7 @@ public class WimbaDisplayController extends BasicController {
         		getWindowControl().setError(translate(text));
         	}
         } else if(action.equals(COMMAND_DELETE_RECORDING)) {
-          if(wimba.removeClassroomRecording(key, config)) {
+          if(wimba.removeClassroomRecording(key)) {
             getWindowControl().setInfo(translate("table.recordings.delete.success"));
             recTableModel.removeRecording(row);
             recTable.modelChanged();
@@ -340,7 +340,7 @@ public class WimbaDisplayController extends BasicController {
 
 }
 
-class RecordingsTableModel implements TableDataModel {
+class RecordingsTableModel implements TableDataModel<Object[]> {
 
   private List<Object[]> recordings = new ArrayList<Object[]>();
   private Translator translator;
@@ -376,12 +376,12 @@ class RecordingsTableModel implements TableDataModel {
   }
 
   @Override
-  public Object getObject(int row) {
+  public Object[] getObject(int row) {
     return recordings.get(row);
   }
 
   @Override
-  public void setObjects(List objects) {
+  public void setObjects(List<Object[]> objects) {
     this.recordings = objects;
   }
 
diff --git a/src/main/java/org/olat/admin/user/SendTokenToUserForm.java b/src/main/java/org/olat/admin/user/SendTokenToUserForm.java
index 1553e266ebc576408ef2c82ce7adbc49abb12635..776364bde82f94043206e1779a983104bc17a2e2 100644
--- a/src/main/java/org/olat/admin/user/SendTokenToUserForm.java
+++ b/src/main/java/org/olat/admin/user/SendTokenToUserForm.java
@@ -119,7 +119,7 @@ public class SendTokenToUserForm extends FormBasicController {
 		Locale locale = I18nManager.getInstance().getLocaleOrDefault(prefs.getLanguage());
 		String emailAdress = user.getUser().getProperty(UserConstants.EMAIL, locale);
 		if (emailAdress != null) {
-			dummyKey = Encoder.encrypt(emailAdress);
+			dummyKey = Encoder.md5hash(emailAdress);
 
 			String serverpath = Settings.getServerContextPathURI();
 			Translator userTrans = Util.createPackageTranslator(RegistrationManager.class, locale) ;
diff --git a/src/main/java/org/olat/admin/user/UserChangePasswordController.java b/src/main/java/org/olat/admin/user/UserChangePasswordController.java
index bdf903a018523e8243dd7d330c192f1012a4fc12..c8b05421334f8b7a72c086f4e42681577db62711 100644
--- a/src/main/java/org/olat/admin/user/UserChangePasswordController.java
+++ b/src/main/java/org/olat/admin/user/UserChangePasswordController.java
@@ -26,8 +26,8 @@
 package org.olat.admin.user;
 
 import org.olat.basesecurity.BaseSecurity;
-import org.olat.basesecurity.BaseSecurityManager;
 import org.olat.basesecurity.Constants;
+import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.velocity.VelocityContainer;
@@ -57,6 +57,8 @@ public class UserChangePasswordController extends BasicController {
 	private SendTokenToUserForm tokenForm;
 	private VelocityContainer mainVC;
 	private Identity user;
+	
+	private final OLATAuthManager olatAuthenticationSpi;
 
 	/**
 	 * @param ureq
@@ -66,7 +68,8 @@ public class UserChangePasswordController extends BasicController {
 	public UserChangePasswordController(UserRequest ureq, WindowControl wControl, Identity changeableUser) { 
 		super(ureq, wControl);
 		
-		BaseSecurity mgr = BaseSecurityManager.getInstance();
+		olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class);
+		BaseSecurity mgr = CoreSpringFactory.getImpl(BaseSecurity.class);
 		if (!mgr.isIdentityPermittedOnResourceable(
 				ureq.getIdentity(), 
 				Constants.PERMISSION_ACCESS, 
@@ -94,7 +97,7 @@ public class UserChangePasswordController extends BasicController {
 	@Override
 	public void event(UserRequest ureq, Controller source, Event event) {
 		if (source == chPwdForm && event.equals(Event.DONE_EVENT)) {
-			if (OLATAuthManager.changePassword(ureq.getIdentity(), user, chPwdForm.getNewPassword())) {
+			if (olatAuthenticationSpi.changePassword(ureq.getIdentity(), user, chPwdForm.getNewPassword())) {
 				showInfo("changeuserpwd.successful");
 				logAudit ("user password changed successfully of " +user.getName(), this.getClass().getName());
 			} else {
diff --git a/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java b/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java
index 05919f373dd464a674f08d17082fbb591270be70..8feea6498fe8dba8dd77dabe789cacc0459a4cec 100644
--- a/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java
+++ b/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java
@@ -483,11 +483,11 @@ public class UsermanagerUserSearchController extends BasicController implements
 									HashMap<String, String> roleChangeMap = (HashMap<String, String>) runContext.get("roleChangeMap");
 									List<Long> ownGroups = (List<Long>) runContext.get("ownerGroups");
 									List<Long> partGroups = (List<Long>) runContext.get("partGroups");
-									List<Long> mailGroups = (List<Long>) runContext.get("mailGroups");
+									//List<Long> mailGroups = (List<Long>) runContext.get("mailGroups");
 									if (attributeChangeMap.size() != 0 || roleChangeMap.size() != 0 || ownGroups.size() != 0 || partGroups.size() != 0){
 										Identity addingIdentity = ureq1.getIdentity();
 										ubcMan.changeSelectedIdentities(selectedIdentities, attributeChangeMap, roleChangeMap, notUpdatedIdentities,
-											isAdministrativeUser, ownGroups, partGroups, mailGroups, getTranslator(), addingIdentity);
+											isAdministrativeUser, ownGroups, partGroups, getTranslator(), addingIdentity);
 										hasChanges = true;
 									}
 								}
diff --git a/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangeManager.java b/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangeManager.java
index 0b774e70714141bb6f67b1482b0a2d42a287a95c..ba7fd1259b6b488407778ac3a42c87b368ef994c 100644
--- a/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangeManager.java
+++ b/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangeManager.java
@@ -100,7 +100,8 @@ public class UserBulkChangeManager extends BasicManager {
 	}
 
 	public void changeSelectedIdentities(List<Identity> selIdentities, HashMap<String, String> attributeChangeMap,
-			HashMap<String, String> roleChangeMap, ArrayList<String> notUpdatedIdentities, boolean isAdministrativeUser, List<Long> ownGroups, List<Long> partGroups, List<Long> mailGroups, Translator trans, Identity addingIdentity) {
+			HashMap<String, String> roleChangeMap, ArrayList<String> notUpdatedIdentities, boolean isAdministrativeUser, List<Long> ownGroups, List<Long> partGroups,
+			Translator trans, Identity addingIdentity) {
 
 		Translator transWithFallback = UserManager.getInstance().getPropertyHandlerTranslator(trans);
 		String usageIdentifyer = UserBulkChangeStep00.class.getCanonicalName();
@@ -129,8 +130,11 @@ public class UserBulkChangeManager extends BasicManager {
 						errorDesc = transWithFallback.translate("error.password");
 						updateError = true;
 					}
-				} else newPwd = null;
-				OLATAuthManager.changePasswordAsAdmin(identity, newPwd);
+				} else {
+					newPwd = null;
+				}
+				OLATAuthManager olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class);
+				olatAuthenticationSpi.changePasswordAsAdmin(identity, newPwd);
 			}
 
 			// set language
diff --git a/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangePasswordController.java b/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangePasswordController.java
index d7d2f131c640afe92741c9577070715395447021..5894a43182777c7cfce75aa60415cf8a20fb1f76 100644
--- a/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangePasswordController.java
+++ b/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangePasswordController.java
@@ -26,6 +26,7 @@ package org.olat.admin.user.bulkChange;
 
 import org.olat.basesecurity.BaseSecurity;
 import org.olat.basesecurity.BaseSecurityManager;
+import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.form.flexible.FormItemContainer;
@@ -60,16 +61,20 @@ import org.olat.user.UserManager;
 public class UserBulkChangePasswordController extends BasicController {
 	
 	private static final OLog log = Tracing.createLoggerFor(UserBulkChangePasswordController.class);
+	
 	private ChangePasswordForm changePasswordForm;
+	private final OLATAuthManager olatAuthenticationSpi;
 
 	public UserBulkChangePasswordController(UserRequest ureq, WindowControl wControl) {
 		super(ureq, wControl);
+		
+		olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class);
 
 		Panel main = new Panel("changePsw");
 		VelocityContainer mainVC = createVelocityContainer("index");
 		
 		changePasswordForm = new ChangePasswordForm(ureq, wControl);
-		this.listenTo(changePasswordForm);
+		listenTo(changePasswordForm);
 		mainVC.put("form", changePasswordForm.getInitialComponent());		
 		
 		main.setContent(mainVC);
@@ -106,7 +111,7 @@ public class UserBulkChangePasswordController extends BasicController {
 					Identity identity = identityManager.findIdentityByName(username);
 					if(identity!=null) {
 						if (password!=null && password.trim().length()>0) {
-							OLATAuthManager.changePassword(ureq.getIdentity(), identity, password);	
+							olatAuthenticationSpi.changePassword(ureq.getIdentity(), identity, password);	
 							log.info("changePassword for username: " + username);
 						}
 						if (autodisc) {
diff --git a/src/main/java/org/olat/basesecurity/AuthHelper.java b/src/main/java/org/olat/basesecurity/AuthHelper.java
index 2c56eae6c0675318f53ddca5c788fbace9186240..81c2efda55a3b5b842a8e784b5d27dc56a23ff56 100644
--- a/src/main/java/org/olat/basesecurity/AuthHelper.java
+++ b/src/main/java/org/olat/basesecurity/AuthHelper.java
@@ -65,7 +65,6 @@ import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.core.logging.activity.OlatLoggingAction;
 import org.olat.core.logging.activity.ThreadLocalUserActivityLogger;
-import org.olat.core.util.Encoder;
 import org.olat.core.util.SessionInfo;
 import org.olat.core.util.UserSession;
 import org.olat.core.util.WebappHelper;
@@ -362,10 +361,10 @@ public class AuthHelper {
 		if (pwd == null) {
 			// when no password is used the provider must be set to null to not generate
 			// an OLAT authentication token. See method doku.
-			ident = BaseSecurityManager.getInstance().createAndPersistIdentityAndUser(loginName, newUser, null, null, null);
+			ident = BaseSecurityManager.getInstance().createAndPersistIdentityAndUser(loginName, newUser, null, null);
  		} else {
 			ident = BaseSecurityManager.getInstance().createAndPersistIdentityAndUser(loginName, newUser,
-			BaseSecurityModule.getDefaultAuthProviderIdentifier(), loginName, Encoder.encrypt(pwd));
+			BaseSecurityModule.getDefaultAuthProviderIdentifier(), loginName, pwd);
 		}
 		// TODO: Tracing message
 		return ident;
diff --git a/src/main/java/org/olat/basesecurity/Authentication.java b/src/main/java/org/olat/basesecurity/Authentication.java
index fa75301ca60a6d2a7af19c3751a75f1ecf049cf4..522ee46ffcc5fafaf674edc44723d2fd2228fb39 100644
--- a/src/main/java/org/olat/basesecurity/Authentication.java
+++ b/src/main/java/org/olat/basesecurity/Authentication.java
@@ -55,6 +55,18 @@ public interface Authentication extends CreateInfo, Persistable {
 	 * @return
 	 */
 	public String getCredential();
+	
+	/**
+	 * Salt used to hash the password
+	 * @return
+	 */
+	public String getSalt();
+	
+	/**
+	 * Algoritm used to hash the password
+	 * @return
+	 */
+	public String getAlgorithm();
 
 	/**
 	 * @param identity
@@ -75,6 +87,18 @@ public interface Authentication extends CreateInfo, Persistable {
 	 * @param credential
 	 */
 	public void setCredential(String credential);
+	
+	/**
+	 * 
+	 * @param salt
+	 */
+	public void setSalt(String salt);
+	
+	/**
+	 * 
+	 * @param algorithm
+	 */
+	public void setAlgorithm(String algorithm);
 
 }
 
diff --git a/src/main/java/org/olat/basesecurity/AuthenticationImpl.hbm.xml b/src/main/java/org/olat/basesecurity/AuthenticationImpl.hbm.xml
index d82b1a094b924ced6ce56bdf7877a55b61476366..be1f99bd0f94bc9827384bbbda57595bef8b731b 100644
--- a/src/main/java/org/olat/basesecurity/AuthenticationImpl.hbm.xml
+++ b/src/main/java/org/olat/basesecurity/AuthenticationImpl.hbm.xml
@@ -26,6 +26,9 @@
 	<property name="credential" type="string" not-null="false">
 		<column name="credential" length="255" index="credential_idx"/>
 	</property>
+	
+	<property name="salt" column="salt" type="string" not-null="false"/>
+	<property name="algorithm" column="hashalgorithm" type="string" not-null="false"/>
 
 	</class>
 </hibernate-mapping>
diff --git a/src/main/java/org/olat/basesecurity/AuthenticationImpl.java b/src/main/java/org/olat/basesecurity/AuthenticationImpl.java
index b9cd42e99b34ae853e1d72ceb67ad238f5d86aaf..2b36aac750f3c66472264e2c110de96651f1f633 100644
--- a/src/main/java/org/olat/basesecurity/AuthenticationImpl.java
+++ b/src/main/java/org/olat/basesecurity/AuthenticationImpl.java
@@ -36,10 +36,13 @@ import org.olat.core.logging.AssertException;
  */
 public class AuthenticationImpl extends PersistentObject implements Authentication {
 
+	private static final long serialVersionUID = 7969409958077836798L;
 	private Identity identity;
 	private String provider;
 	private String authusername;
 	private String credential;
+	private String salt;
+	private String algorithm;
 
 	/**
 	 * for hibernate only
@@ -47,8 +50,22 @@ public class AuthenticationImpl extends PersistentObject implements Authenticati
 	protected AuthenticationImpl() {
 	//  
 	}
+	
+	AuthenticationImpl(Identity identity, String provider, String authusername, String credentials) {
+		
+		if (provider.length() > 8) {
+			// this implementation allows only 8 characters, as defined in hibernate file
+			throw new AssertException("Authentication provider '" + provider + "' to long, only 8 characters supported!");
+		}
+		this.identity = identity;
+		this.provider = provider;
+		this.authusername = authusername;
+		this.credential = credentials;
+	}
 
-	AuthenticationImpl(Identity identity, String provider, String authusername, String credential) {
+	AuthenticationImpl(Identity identity, String provider, String authusername,
+			String credential, String salt, String algorithm) {
+		
 		if (provider.length() > 8) {
 			// this implementation allows only 8 characters, as defined in hibernate file
 			throw new AssertException("Authentication provider '" + provider + "' to long, only 8 characters supported!");
@@ -57,11 +74,14 @@ public class AuthenticationImpl extends PersistentObject implements Authenticati
 		this.provider = provider;
 		this.authusername = authusername;
 		this.credential = credential;
+		this.salt = salt;
+		this.algorithm = algorithm;
 	}
 
 	/**
 	 * @return
 	 */
+	@Override
 	public String getAuthusername() {
 		return authusername;
 	}
@@ -69,6 +89,7 @@ public class AuthenticationImpl extends PersistentObject implements Authenticati
 	/**
 	 * @return
 	 */
+	@Override
 	public String getProvider() {
 		return provider;
 	}
@@ -78,6 +99,7 @@ public class AuthenticationImpl extends PersistentObject implements Authenticati
 	 * 
 	 * @param string
 	 */
+	@Override
 	public void setAuthusername(String string) {
 		authusername = string;
 	}
@@ -87,6 +109,7 @@ public class AuthenticationImpl extends PersistentObject implements Authenticati
 	 * 
 	 * @param string
 	 */
+	@Override
 	public void setProvider(String string) {
 		provider = string;
 	}
@@ -96,6 +119,7 @@ public class AuthenticationImpl extends PersistentObject implements Authenticati
 	 * 
 	 * @return
 	 */
+	@Override
 	public String getCredential() {
 		return credential;
 	}
@@ -103,13 +127,35 @@ public class AuthenticationImpl extends PersistentObject implements Authenticati
 	/**
 	 * @param string
 	 */
+	@Override
 	public void setCredential(String string) {
 		credential = string;
 	}
 
+	@Override
+	public String getSalt() {
+		return salt;
+	}
+
+	@Override
+	public void setSalt(String salt) {
+		this.salt = salt;
+	}
+
+	@Override
+	public String getAlgorithm() {
+		return algorithm;
+	}
+
+	@Override
+	public void setAlgorithm(String algorithm) {
+		this.algorithm = algorithm;
+	}
+
 	/**
 	 * @see java.lang.Object#toString()
 	 */
+	@Override
 	public String toString() {
 		return "auth: provider:" + provider + " ,authusername:" + authusername + ", hashpwd:" + credential + " ," + super.toString();
 	}
@@ -117,6 +163,7 @@ public class AuthenticationImpl extends PersistentObject implements Authenticati
 	/**
 	 * @see org.olat.basesecurity.Authentication#getIdentity()
 	 */
+	@Override
 	public Identity getIdentity() {
 		return identity;
 	}
@@ -124,6 +171,7 @@ public class AuthenticationImpl extends PersistentObject implements Authenticati
 	/**
 	 * @see org.olat.basesecurity.Authentication#setIdentity(org.olat.core.id.Identity)
 	 */
+	@Override
 	public void setIdentity(Identity identity) {
 		this.identity = identity;
 	}
diff --git a/src/main/java/org/olat/basesecurity/BaseSecurity.java b/src/main/java/org/olat/basesecurity/BaseSecurity.java
index fe8c73a75ff6a36678d7c54fbe2e1c967d38b854..9f66ce9d285432fa41a72f64215247ed8099a848 100644
--- a/src/main/java/org/olat/basesecurity/BaseSecurity.java
+++ b/src/main/java/org/olat/basesecurity/BaseSecurity.java
@@ -35,6 +35,7 @@ import org.olat.core.id.Identity;
 import org.olat.core.id.OLATResourceable;
 import org.olat.core.id.Roles;
 import org.olat.core.id.User;
+import org.olat.core.util.Encoder;
 import org.olat.resource.OLATResource;
 
 /**
@@ -272,6 +273,8 @@ public interface BaseSecurity {
 	 * @return nr of members in the securitygroup
 	 */
 	public int countIdentitiesOfSecurityGroup(SecurityGroup secGroup);
+	
+
 
 	/**
 	 * @param username the username
@@ -283,8 +286,8 @@ public interface BaseSecurity {
 	 * @param credential the credentials or null if not used
 	 * @return the new identity
 	 */
-	public Identity createAndPersistIdentity(String username, User user, String provider, String authusername, String credential);
-
+	public Identity createAndPersistIdentity(String username, User user, String provider, String authusername, String password);
+	
 	/**
 	 * @param username the username
 	 * @param user the unpresisted User
@@ -295,7 +298,19 @@ public interface BaseSecurity {
 	 * @param credential the credentials or null if not used
 	 * @return the new identity
 	 */
-	public Identity createAndPersistIdentityAndUser(String username, User user, String provider, String authusername, String credential);
+	public Identity createAndPersistIdentityAndUser(String username, User user, String provider, String authusername);
+
+	/**
+	 * @param username the username
+	 * @param user the unpresisted User
+	 * @param provider the provider of the authentication ("OLAT" or "AAI"). If
+	 *          null, no authentication token is generated.
+	 * @param authusername the username used as authentication credential
+	 *          (=username for provider "OLAT")
+	 * @param password The password which will be used as credentials (not hashed it)
+	 * @return the new identity
+	 */
+	public Identity createAndPersistIdentityAndUser(String username, User user, String provider, String authusername, String password);
 
 	/**
 	 * Return the List of associated Authentications.
@@ -313,32 +328,22 @@ public interface BaseSecurity {
 	 */
 	public Authentication findAuthentication(Identity identity, String provider);
 	
-	/**
-	 * 
-	 * @param identity
-	 * @param creationDate
-	 * @return
-	 */
-	public List<Authentication> findOldAuthentication(String provider, Date creationDate);
 	
 	/**
-	 * 
-	 * @param provider
-	 * @param token
+	 * Find authentication which are older than a specific date.
+	 * @param provider The provider
+	 * @param creationDate The date's limit
 	 * @return
 	 */
-	public List<Authentication> findAuthentication(String provider, String credential);
+	public List<Authentication> findOldAuthentication(String provider, Date creationDate);
 	
 	/**
-	 * Return the credential or null
-	 * @param identity
-	 * @param provider
+	 * Authentication with a security token
+	 * @param provider The provider
+	 * @param securityToken The security token
 	 * @return
 	 */
-	public String findCredentials(Identity identity, String provider);
-
-	//fxdiff: FXOLAT-219 decrease the load for synching groups
-	public boolean hasAuthentication(Long identityKey, String provider);
+	public List<Authentication> findAuthenticationByToken(String provider, String securityToken);
 
 	/**
 	 * @param identity
@@ -347,7 +352,7 @@ public interface BaseSecurity {
 	 * @param credential
 	 * @return an Authentication
 	 */
-	public Authentication createAndPersistAuthentication(Identity identity, String provider, String authUsername, String credential);
+	public Authentication createAndPersistAuthentication(Identity identity, String provider, String authUsername, String password, Encoder.Algorithm algoritm);
 
 	/**
 	 * @param authentication
@@ -359,6 +364,24 @@ public interface BaseSecurity {
 	 * @param authentication
 	 */
 	public Authentication updateAuthentication(Authentication authentication);
+	
+	/**
+	 * 
+	 * @param authentication
+	 * @param password
+	 * @param algorithm
+	 * @return
+	 */
+	public boolean checkCredentials(Authentication authentication, String password);
+	
+	/**
+	 * Updated the hashed password to a new one
+	 * @param authentication
+	 * @param password
+	 * @param algorithm
+	 * @return
+	 */
+	public Authentication updateCredentials(Authentication authentication, String password, Encoder.Algorithm algorithm);
 
 	// --- SecGroup management
 
diff --git a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java
index b12779e93eda0c4f0dbb0452b6fb077d6765e7b4..1c0511cba0630b4d83adbfb84a47413892daab42 100644
--- a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java
+++ b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java
@@ -62,11 +62,13 @@ import org.olat.core.id.User;
 import org.olat.core.id.UserConstants;
 import org.olat.core.logging.AssertException;
 import org.olat.core.manager.BasicManager;
-import org.olat.core.util.StringHelper;
+import org.olat.core.util.Encoder.Algorithm;
+import org.olat.core.util.Encoder;
 import org.olat.core.util.Util;
 import org.olat.core.util.coordinate.CoordinatorManager;
 import org.olat.core.util.coordinate.SyncerCallback;
 import org.olat.core.util.resource.OresHelper;
+import org.olat.login.LoginModule;
 import org.olat.resource.OLATResource;
 import org.olat.resource.OLATResourceImpl;
 import org.olat.resource.OLATResourceManager;
@@ -933,11 +935,31 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity {
 	 * @param credential the credentials or null if not used
 	 * @return Identity
 	 */
+	@Override
 	public Identity createAndPersistIdentity(String username, User user, String provider, String authusername, String credential) {
 		IdentityImpl iimpl = new IdentityImpl(username, user);
 		dbInstance.getCurrentEntityManager().persist(iimpl);
 		if (provider != null) { 
-			createAndPersistAuthentication(iimpl, provider, authusername, credential);
+			createAndPersistAuthentication(iimpl, provider, authusername, credential, LoginModule.getDefaultHashAlgorithm());
+		}
+		notifyNewIdentityCreated(iimpl);
+		return iimpl;
+	}
+
+	/**
+	 * @param username The username
+	 * @param user The unpresisted User
+	 * @param provider The provider of the authentication ("OLAT" or "AAI"). If null, no authentication token is generated.
+	 * @param authusername The username used as authentication credential (=username for provider "OLAT")
+	 * @return Identity
+	 */
+	@Override
+	public Identity createAndPersistIdentityAndUser(String username, User user, String provider, String authusername) {
+		dbInstance.getCurrentEntityManager().persist(user);
+		IdentityImpl iimpl = new IdentityImpl(username, user);
+		dbInstance.getCurrentEntityManager().persist(iimpl);
+		if (provider != null) { 
+			createAndPersistAuthentication(iimpl, provider, authusername, null, null);
 		}
 		notifyNewIdentityCreated(iimpl);
 		return iimpl;
@@ -953,12 +975,13 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity {
 	 * @param credential the credentials or null if not used
 	 * @return Identity
 	 */
+	@Override
 	public Identity createAndPersistIdentityAndUser(String username, User user, String provider, String authusername, String credential) {
 		dbInstance.getCurrentEntityManager().persist(user);
 		IdentityImpl iimpl = new IdentityImpl(username, user);
 		dbInstance.getCurrentEntityManager().persist(iimpl);
 		if (provider != null) { 
-			createAndPersistAuthentication(iimpl, provider, authusername, credential);
+			createAndPersistAuthentication(iimpl, provider, authusername, credential, LoginModule.getDefaultHashAlgorithm());
 		}
 		notifyNewIdentityCreated(iimpl);
 		return iimpl;
@@ -1383,13 +1406,20 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity {
 	 * @see org.olat.basesecurity.Manager#createAndPersistAuthentication(org.olat.core.id.Identity, java.lang.String, java.lang.String, java.lang.String)
 	 */
 	@Override
-	public Authentication createAndPersistAuthentication(final Identity ident, final String provider, final String authUserName, final String credential) {
+	public Authentication createAndPersistAuthentication(final Identity ident, final String provider, final String authUserName,
+			final String credentials, final Encoder.Algorithm algorithm) {
 		OLATResourceable resourceable = OresHelper.createOLATResourceableInstanceWithoutCheck(provider, ident.getKey());
 		return CoordinatorManager.getInstance().getCoordinator().getSyncer().doInSync(resourceable, new SyncerCallback<Authentication>(){
 			public Authentication execute() {
 				Authentication auth = findAuthentication(ident, provider);
 				if(auth == null) {
-					auth = new AuthenticationImpl(ident, provider, authUserName, credential);
+					if(algorithm != null) {
+						String salt = Encoder.getSalt();
+						String hash = Encoder.encrypt(credentials, salt, algorithm);
+						auth = new AuthenticationImpl(ident, provider, authUserName, hash, salt, algorithm.name());
+					} else {
+						auth = new AuthenticationImpl(ident, provider, authUserName, credentials);
+					}
 					dbInstance.getCurrentEntityManager().persist(auth);
 				}
 				return auth;
@@ -1424,8 +1454,8 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity {
 	 * @see org.olat.basesecurity.Manager#findAuthentication(org.olat.core.id.Identity, java.lang.String)
 	 */
 	@Override
-	public List<Authentication> findAuthentication(String provider, String credential) {
-		if (provider==null || credential==null) {
+	public List<Authentication> findAuthenticationByToken(String provider, String securityToken) {
+		if (provider==null || securityToken==null) {
 			throw new IllegalArgumentException("provider and token must not be null");
 		}
 		
@@ -1435,7 +1465,7 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity {
 		
 		List<Authentication> results = dbInstance.getCurrentEntityManager()
 				.createQuery(sb.toString(), Authentication.class)
-				.setParameter("credential", credential)
+				.setParameter("credential", securityToken)
 				.setParameter("provider", provider)
 				.getResultList();
 		return results;
@@ -1460,63 +1490,55 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity {
 	}
 
 	@Override
-	public String findCredentials(Identity identity, String provider) {
-		if (identity==null) {
-			throw new IllegalArgumentException("identity must not be null");
-		}
-		
-		StringBuilder sb = new StringBuilder();
-		sb.append("select auth.credential from ").append(AuthenticationImpl.class.getName())
-		  .append(" as auth where auth.identity.key=:identityKey and auth.provider=:provider");
-		
-		List<String> results = dbInstance.getCurrentEntityManager()
-				.createQuery(sb.toString(), String.class)
-				.setParameter("identityKey", identity.getKey())
-				.setParameter("provider", provider)
-				.getResultList();
-		if (results == null || results.size() == 0) return null;
-		if (results.size() > 1) throw new AssertException("Found more than one Authentication for a given subject and a given provider.");
-		return results.get(0);
+	public Authentication updateAuthentication(Authentication authentication) {
+		return dbInstance.getCurrentEntityManager().merge(authentication);
 	}
 
 	@Override
-	//fxdiff: FXOLAT-219 decrease the load for synching groups
-	public boolean hasAuthentication(Long identityKey, String provider) {
-		if (identityKey == null || !StringHelper.containsNonWhitespace(provider)) return false;
-		
-		String queryStr = "select count(auth) from org.olat.basesecurity.AuthenticationImpl as auth where auth.identity.key=:key and auth.provider=:provider";
-		DBQuery query = DBFactory.getInstance().createQuery(queryStr);
-		query.setLong("key", identityKey);
-		query.setString("provider", provider);
-		
-		Number count = (Number)query.uniqueResult();
-		return count.intValue() > 0;
+	public boolean checkCredentials(Authentication authentication, String password) {
+		Algorithm algorithm = Algorithm.find(authentication.getAlgorithm());
+		String hash = Encoder.encrypt(password, authentication.getSalt(), algorithm);
+		return authentication.getCredential() != null && authentication.getCredential().equals(hash);
 	}
 
 	@Override
-	public Authentication updateAuthentication(Authentication authentication) {
-		return dbInstance.getCurrentEntityManager().merge(authentication);
+	public Authentication updateCredentials(Authentication authentication, String password, Algorithm algorithm) {
+		String salt = Encoder.getSalt();
+		String newCredentials = Encoder.encrypt(password, salt, algorithm);
+		authentication.setSalt(salt);
+		authentication.setCredential(newCredentials);
+		authentication.setAlgorithm(algorithm.name());
+		return updateAuthentication(authentication);
 	}
 
 	/**
 	 * @see org.olat.basesecurity.Manager#deleteAuthentication(org.olat.basesecurity.Authentication)
 	 */
+	@Override
 	public void deleteAuthentication(Authentication auth) {
-		DBFactory.getInstance().deleteObject(auth);
+		dbInstance.getCurrentEntityManager().remove(auth);
 	}
 
 	/**
 	 * @see org.olat.basesecurity.Manager#findAuthenticationByAuthusername(java.lang.String, java.lang.String)
 	 */
+	@Override
 	public Authentication findAuthenticationByAuthusername(String authusername, String provider) {
-		List results = DBFactory.getInstance().find(
-				"from org.olat.basesecurity.AuthenticationImpl as auth where auth.provider = ? and auth.authusername = ?",
-				new Object[] { provider, authusername }, new Type[] { StandardBasicTypes.STRING, StandardBasicTypes.STRING });
+		StringBuilder sb = new StringBuilder();
+		sb.append("select auth from ").append(AuthenticationImpl.class.getName()).append(" as auth")
+		  .append(" inner join fetch auth.identity ident")
+		  .append(" where auth.provider=:provider and auth.authusername=:authusername");
+
+		List<Authentication> results = dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), Authentication.class)
+				.setParameter("provider", provider)
+				.setParameter("authusername", authusername)
+				.getResultList();
 		if (results.size() == 0) return null;
-		if (results.size() != 1) throw new AssertException(
-				"more than one entry for the a given authusername and provider, should never happen (even db has a unique constraint on those columns combined) ");
-		Authentication auth = (Authentication) results.get(0);
-		return auth;
+		if (results.size() != 1) {
+			throw new AssertException("more than one entry for the a given authusername and provider, should never happen (even db has a unique constraint on those columns combined) ");
+		}
+		return results.get(0);
 	}
 
 	/**
diff --git a/src/main/java/org/olat/commons/lifecycle/LifeCycleManager.java b/src/main/java/org/olat/commons/lifecycle/LifeCycleManager.java
index bc266543a6d9f5ab6862c45ac0fe5d789ae9fcb5..fc98cf2bafb94e994881afb542787d949c5e9b38 100644
--- a/src/main/java/org/olat/commons/lifecycle/LifeCycleManager.java
+++ b/src/main/java/org/olat/commons/lifecycle/LifeCycleManager.java
@@ -162,7 +162,7 @@ public class LifeCycleManager extends BasicManager {
 	public static String getShortTypeName(String standardTypeName) {
 		if (standardTypeName.length() > LifeCycleEntry.PERSISTENTTYPENAME_MAXLENGTH) {
 			//encode into an md5 hash with fixed length of 32 characters otherwise the sting may get too long for locks or db fields
-			return Encoder.encrypt(standardTypeName);
+			return Encoder.md5hash(standardTypeName);
 		} else {
 			return standardTypeName;
 		}
diff --git a/src/main/java/org/olat/commons/rss/RSSUtil.java b/src/main/java/org/olat/commons/rss/RSSUtil.java
index d27c14b8e547acb67d583df6346f8a998397d7cf..e8d7b7191c21c52467b929e5f653a65d8a074dea 100644
--- a/src/main/java/org/olat/commons/rss/RSSUtil.java
+++ b/src/main/java/org/olat/commons/rss/RSSUtil.java
@@ -80,7 +80,7 @@ public class RSSUtil {
 		if (auth == null) {
 			// no token found - create one
 			 token = RandomStringUtils.randomAlphanumeric(6);
-			 auth = secManager.createAndPersistAuthentication(identity, RSSUtil.RSS_AUTH_PROVIDER, identity.getName(), token);
+			 auth = secManager.createAndPersistAuthentication(identity, RSSUtil.RSS_AUTH_PROVIDER, identity.getName(), token, null);
 		} else {
 			token = auth.getCredential();
 		}
diff --git a/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java b/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java
index 07707fee3e87b8a288a80d2ec42fc8e2ec42bcae..aefbda2c63c94712c7ffebfc19e0ab77da2a1e9f 100644
--- a/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java
+++ b/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java
@@ -165,7 +165,7 @@ public class HTMLEditorController extends FormBasicController {
 			// OLAT-5066: the use of "fileName" gives users the (false) impression that the file they wish to access
 			// is already locked by someone else. Since the lock token must be smaller than 50 characters we us an 
 			// MD5 hash of the absolute file path which will always be 32 characters long and virtually unique.
-			String lockToken = Encoder.encrypt(getFileDebuggingPath(baseContainer, relFilePath));
+			String lockToken = Encoder.md5hash(getFileDebuggingPath(baseContainer, relFilePath));
 			this.lock = CoordinatorManager.getInstance().getCoordinator().getLocker().acquireLock(lockResourceable, ureq.getIdentity(), lockToken);
 			VelocityContainer vc = (VelocityContainer) flc.getComponent();
 			if (!lock.isSuccess()) {
diff --git a/src/main/java/org/olat/core/commons/services/webdav/DefaultServlet.java b/src/main/java/org/olat/core/commons/services/webdav/DefaultServlet.java
index b9f38d918d6468044301302f48133bc43d990df6..babd1ac6f292bdabe0b8385efc574b962d3589cc 100644
--- a/src/main/java/org/olat/core/commons/services/webdav/DefaultServlet.java
+++ b/src/main/java/org/olat/core/commons/services/webdav/DefaultServlet.java
@@ -125,9 +125,9 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.naming.resources.Resource;
 import org.apache.naming.resources.ResourceAttributes;
 import org.olat.core.helpers.Settings;
+import org.olat.core.util.MD5Encoder;
 import org.olat.core.util.servlets.FastHttpDateFormat;
 import org.olat.core.util.servlets.Globals;
-import org.olat.core.util.servlets.MD5Encoder;
 import org.olat.core.util.servlets.URLEncoder;
 
 
diff --git a/src/main/java/org/olat/core/commons/services/webdav/_spring/webdavContext.xml b/src/main/java/org/olat/core/commons/services/webdav/_spring/webdavContext.xml
index e24e6ea68a60fe384f7f894b7eb5b94953648ffe..bd9493d46b11e0816b3201b4d1ab97a7ed3098dc 100644
--- a/src/main/java/org/olat/core/commons/services/webdav/_spring/webdavContext.xml
+++ b/src/main/java/org/olat/core/commons/services/webdav/_spring/webdavContext.xml
@@ -10,7 +10,13 @@
 		<!-- set to false to disable the WebDAV support and remove the WebDAV Link from the GUI -->
 		<property name="enabled" value="${webdav.links.enabled}" />
 		<property name="sessionManager" ref="userSessionManager" />
-	</bean>  
+		<property name="webDAVAuthManager" ref="webDAVAuthenticationSpi" />
+	</bean>
+	
+	<bean id="webDAVAuthenticationSpi" class="org.olat.core.commons.services.webdav.manager.WebDAVAuthManager" >
+		<property name="securityManager" ref="baseSecurityManager" />
+		<property name="olatAuthenticationSpi" ref="olatAuthenticationSpi" />
+	</bean>
   
 	
 	<!-- WebDAV provider factory -->
diff --git a/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVAuthManager.java b/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVAuthManager.java
index 56db6a7b680efb2e51af94a8aad7b515a2654a99..a9b84b57432de8bc22ee7c80aae7690236b5cb68 100644
--- a/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVAuthManager.java
+++ b/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVAuthManager.java
@@ -22,14 +22,14 @@ package org.olat.core.commons.services.webdav.manager;
 
 import org.olat.basesecurity.Authentication;
 import org.olat.basesecurity.BaseSecurity;
-import org.olat.basesecurity.BaseSecurityManager;
-import org.olat.core.commons.persistence.DBFactory;
 import org.olat.core.id.Identity;
 import org.olat.core.logging.AssertException;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
-import org.olat.core.util.Encoder;
-import org.olat.login.OLATAuthenticationController;
+import org.olat.core.util.Encoder.Algorithm;
+import org.olat.login.LoginModule;
+import org.olat.login.auth.AuthenticationSPI;
+import org.olat.login.auth.OLATAuthManager;
 
 
 /**
@@ -41,68 +41,82 @@ import org.olat.login.OLATAuthenticationController;
  * Initial Date:  13 apr. 2010 <br>
  * @author srosse, stephane.rosse@frentix.com
  */
-public class WebDAVAuthManager {
+public class WebDAVAuthManager implements AuthenticationSPI {
 	
 	public static final String PROVIDER_WEBDAV = "WEBDAV";
 	
 	private static final OLog log = Tracing.createLoggerFor(WebDAVAuthManager.class);
 	
+	private BaseSecurity securityManager;
+	private OLATAuthManager olatAuthenticationSpi;
 	
 	/**
-	 * Change the WEBDAV-Password of an identity
-	 * @param doer Identity who is changing the password
-	 * @param identity Identity who's password is being changed.
-	 * @param newPwd New password.
-	 * @return True upon success.
+	 * [used by Spring]
+	 * @param securityManager
 	 */
-	public static boolean changePassword(Identity doer, Identity identity, String newPwd) {
-		if (doer==null) throw new AssertException("password changing identity cannot be undefined!");
-		
-		if (identity.getKey() == null) throw new AssertException("cannot change password on a nonpersisted identity");
-		// password's length is limited to 128 chars. 
-		// The 128 bit MD5 hash is converted into a 32 character long String
-		String hashedPwd = Encoder.encrypt(newPwd);
-		
-		identity = (Identity) DBFactory.getInstance().loadObject(identity);
-		
-		return changeWebDAVPassword(doer, identity, hashedPwd);
+	public void setSecurityManager(BaseSecurity securityManager) {
+		this.securityManager = securityManager;
 	}
-	
-	private static boolean changeWebDAVPassword(Identity doer, Identity identity, String hashedPwd) {
-		Authentication auth = BaseSecurityManager.getInstance().findAuthentication(identity, PROVIDER_WEBDAV);
-		if (auth == null) { // create new authentication for provider OLAT
-			auth = BaseSecurityManager.getInstance().createAndPersistAuthentication(identity, PROVIDER_WEBDAV, identity.getName(), hashedPwd);
-			log.audit(doer.getName() + " created new WebDAV authenticatin for identity: " + identity.getName());
-		}
 
-		auth.setCredential(hashedPwd);
-		DBFactory.getInstance().updateObject(auth);
-		log.audit(doer.getName() + " set new WebDAV password for identity: " +identity.getName());
-		return true;
-	}
-	
 	/**
-	 * Authenticate against the WEBDAV Authentication provider.
-	 * @param login
-	 * @param pass
-	 * @return Identity if authentication was successful, null otherwise.
+	 * [used by Spring]
+	 * @param olatAuthenticationSpi
 	 */
-	public static Identity authenticate(String login, String pass) {
-		BaseSecurity securityManager = BaseSecurityManager.getInstance();
+	public void setOlatAuthenticationSpi(OLATAuthManager olatAuthenticationSpi) {
+		this.olatAuthenticationSpi = olatAuthenticationSpi;
+	}
+
+	@Override
+	public Identity authenticate(Identity identity, String login, String password) {
+		Authentication authentication = null;
+		if (identity != null) {
+			authentication = securityManager.findAuthentication(identity, PROVIDER_WEBDAV);
+		} else {
+			authentication = securityManager.findAuthenticationByAuthusername(login, PROVIDER_WEBDAV);
+		}
+
+		if(authentication == null) {
+			//fallback to standard OLAT authentication
+			return olatAuthenticationSpi.authenticate(identity, login, password);
+		}
 		
-		Identity ident = securityManager.findIdentityByName(login);
-		if (ident == null) return null;
-		boolean visible = securityManager.isIdentityVisible(ident);
+		Identity authenticatedIdentity = authentication.getIdentity();
+		boolean visible = securityManager.isIdentityVisible(authenticatedIdentity);
 		if (!visible) {
 			return null;
 		}
+		
+		if (securityManager.checkCredentials(authentication, password))	{
+			Algorithm algorithm = Algorithm.find(authentication.getAlgorithm());
+			if(Algorithm.md5.equals(algorithm)) {
+				authentication = securityManager.updateCredentials(authentication, password, LoginModule.getDefaultHashAlgorithm());
+			}
+			return authentication.getIdentity();
+		}
+		return null;
+	}
+
+	/**
+	 * Change the WEBDAV-Password of an identity
+	 * @param doer Identity who is changing the password
+	 * @param identity Identity who's password is being changed.
+	 * @param newPwd New password.
+	 * @return True upon success.
+	 */
+	public boolean changePassword(Identity doer, Identity identity, String newPwd) {
+		if (doer==null) throw new AssertException("password changing identity cannot be undefined!");
+		if (identity == null || identity.getKey() == null)
+			throw new AssertException("cannot change password on a nonpersisted identity");
 
-		//find WEBDAV authentication provider
-		String auth = securityManager.findCredentials(ident, PROVIDER_WEBDAV);
-		if (auth != null && auth.equals(Encoder.encrypt(pass)))	{
-			return ident;
+		Authentication auth = securityManager.findAuthentication(identity, PROVIDER_WEBDAV);
+		if (auth == null) { // create new authentication for provider OLAT
+			Identity reloadedIdentity = securityManager.loadIdentityByKey(identity.getKey());
+			auth = securityManager.createAndPersistAuthentication(reloadedIdentity, PROVIDER_WEBDAV, identity.getName(), newPwd, LoginModule.getDefaultHashAlgorithm());
+			log.audit(doer.getName() + " created new WebDAV authenticatin for identity: " + identity.getName());
+		} else {
+			auth = securityManager.updateCredentials(auth, newPwd, LoginModule.getDefaultHashAlgorithm());
+			log.audit(doer.getName() + " set new WebDAV password for identity: " +identity.getName());
 		}
-		//fallback to OLAT authentication provider 
-		return OLATAuthenticationController.authenticate(ident, login, pass);
+		return true;
 	}
 }
diff --git a/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVManagerImpl.java b/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVManagerImpl.java
index 2544bd64220fe308c12cb9087d5724a167794fa8..cfa2499dba68bb09045b7de795519d085ef53bfe 100644
--- a/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVManagerImpl.java
+++ b/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVManagerImpl.java
@@ -66,6 +66,7 @@ public class WebDAVManagerImpl extends WebDAVManager {
 
 	private CacheWrapper<String,UserSession> timedSessionCache;
 	private UserSessionManager sessionManager;
+	private WebDAVAuthManager webDAVAuthManager;
 
 	/**
 	 * [spring]
@@ -82,6 +83,14 @@ public class WebDAVManagerImpl extends WebDAVManager {
 	public void setSessionManager(UserSessionManager sessionManager) {
 		this.sessionManager = sessionManager;
 	}
+	
+	/**
+	 * [used by Spring]
+	 * @param webDAVAuthManager
+	 */
+	public void setWebDAVAuthManager(WebDAVAuthManager webDAVAuthManager) {
+		this.webDAVAuthManager = webDAVAuthManager;
+	}
 
 	/**
 	 * @see org.olat.core.commons.services.webdav.WebDAVManager#handleAuthentication(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
@@ -171,7 +180,7 @@ public class WebDAVManagerImpl extends WebDAVManager {
 			// and set valid true if valid.
 			// In this example, we simply check
 			// that neither field is blank
-			Identity identity = WebDAVAuthManager.authenticate(userID, password);
+			Identity identity = webDAVAuthManager.authenticate(null, userID, password);
 			if (identity != null) {
 				UserSession usess = sessionManager.getUserSession(request);
 				synchronized(usess) {
diff --git a/src/main/java/org/olat/core/dispatcher/mapper/manager/MapperServiceImpl.java b/src/main/java/org/olat/core/dispatcher/mapper/manager/MapperServiceImpl.java
index b3fe4175171f48794dfca766982f8c7f1d424b3e..4f5746d2c80b254cb44b0af1db911686cc04aea7 100644
--- a/src/main/java/org/olat/core/dispatcher/mapper/manager/MapperServiceImpl.java
+++ b/src/main/java/org/olat/core/dispatcher/mapper/manager/MapperServiceImpl.java
@@ -84,7 +84,7 @@ public class MapperServiceImpl implements MapperService {
 	@Override
 	public String register(UserSession session, Mapper mapper) {
 		String mapid = UUID.randomUUID().toString().replace("-", "");
-		mapid = Encoder.encrypt(mapid);
+		mapid = Encoder.md5hash(mapid);
 		
 		MapperKey mapperKey = new MapperKey(session, mapid);
 		mapperKeyToMapper.put(mapperKey, mapper);
@@ -118,7 +118,7 @@ public class MapperServiceImpl implements MapperService {
 
 	@Override
 	public String register(UserSession session, String mapperId, Mapper mapper, int expirationTime) {
-		String encryptedMapId = Encoder.encrypt(mapperId);
+		String encryptedMapId = Encoder.md5hash(mapperId);
 		MapperKey mapperKey = new MapperKey(session, encryptedMapId);
 		boolean alreadyLoaded = mapperKeyToMapper.containsKey(mapperKey);
 		if(mapper instanceof Serializable) {
diff --git a/src/main/java/org/olat/core/util/Encoder.java b/src/main/java/org/olat/core/util/Encoder.java
index 0114decc1fb3661433001c99c70e6151dcefefbb..e5370a00942cdccb7a1972ac0a675b0cd564d764 100644
--- a/src/main/java/org/olat/core/util/Encoder.java
+++ b/src/main/java/org/olat/core/util/Encoder.java
@@ -26,19 +26,67 @@
 
 package org.olat.core.util;
 
+import java.io.UnsupportedEncodingException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
 
-import org.olat.core.logging.AssertException;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
+
+import com.oreilly.servlet.Base64Encoder;
 
 
 /**
- * Description:
+ * Description: it's our hash factory
+ * 
  * 
  * @author Sabina Jeger
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
  */
 public class Encoder {
-	private static final String HASH_ALGORITHM = "MD5";
+	
+	private static final OLog log = Tracing.createLoggerFor(Encoder.class);
+	
+	public enum Algorithm {
+		md5("MD5", 1),
+		sha1("SHA-1", 100),
+		sha256("SHA-256", 100),
+		sha512("SHA-512", 100),
+		pbkdf2("PBKDF2WithHmacSHA1", 20000);
+
+		private final int iterations;
+		private final String algorithm;
+		
+		private Algorithm(String algorithm, int iterations) {
+			this.algorithm = algorithm;
+			this.iterations = iterations;
+		}
+		
+		public String getAlgorithm() {
+			return algorithm;
+		}
+		
+		public int getIterations() {
+			return iterations;
+		}
+		
+		public static final Algorithm find(String str) {
+			if(StringHelper.containsNonWhitespace(str)) {
+				for(Algorithm value:values()) {
+					if(value.name().equals(str)) {
+						return value;
+					}
+				}
+			}
+			return md5;
+		}
+	}
 
 	/**
 	 * The MD5 helper object for this class.
@@ -51,26 +99,91 @@ public class Encoder {
 	 * @param s
 	 * @return MD5 encrypted string
 	 */
-	public static String encrypt(String s) {
-		byte[] inbytes = s.getBytes();
+	public static String md5hash(String s) {
+		return md5(s, null);
+	}
+	
+	public static String encrypt(String s, String salt, Algorithm algorithm) {
+		switch(algorithm) {
+			case md5: return md5(s, salt);
+			case sha1:
+			case sha256:
+			case sha512:
+				return digest(s, salt, algorithm);
+			case pbkdf2:
+				return secretKey(s, salt, algorithm);
+			default: return md5(s, salt);
+		}
+	}
+
+	protected static String md5(String s, String salt) {
 		try {
-			MessageDigest md5Helper = MessageDigest.getInstance(HASH_ALGORITHM);
-			byte[] outbytes = md5Helper.digest(inbytes);
-			String out = md5Encoder.encode(outbytes);
-			return out;
+			byte[] inbytes = s.getBytes();
+			MessageDigest digest = MessageDigest.getInstance(Algorithm.md5.algorithm);
+			digest.reset();
+			if(salt != null) {
+				digest.update(salt.getBytes());
+			}
+			byte[] outbytes = digest.digest(inbytes);
+			return md5Encoder.encode(outbytes);
 		} catch (NoSuchAlgorithmException e) {
-			throw new AssertException("Cannot load MD5 Message Digest ," + HASH_ALGORITHM + " not supported");
+			log.error("", e);
+			return null;
 		}
 	}
-
-	/**
-	 * encrypt the first argument and show the result on the console
-	 * 
-	 * @param args
-	 */
-	public static void main(String[] args) {
-		String result = encrypt(args[0]);
-		System.out.println("MD5-Hash of " + args[0] + ": " + result);
+	
+	protected static String digest(String password, String salt, Algorithm algorithm) {
+		try {
+			MessageDigest digest = MessageDigest.getInstance(algorithm.getAlgorithm());
+			digest.reset();
+			if(salt != null) {
+				digest.update(salt.getBytes());
+			}
+			byte[] input = password.getBytes("UTF-8");
+			for(int i=algorithm.getIterations(); i-->0; ) {
+				input = digest.digest(input);
+			}
+			return byteToBase64(input);
+		} catch (NoSuchAlgorithmException e) {
+			log.error("", e);
+			return null;
+		} catch (UnsupportedEncodingException e) {
+			log.error("", e);
+			return null;
+		}
+	}
+	
+	protected static String secretKey(String password, String salt, Algorithm algorithm) {
+		try {
+			KeySpec spec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), algorithm.getIterations(), 160);
+			SecretKeyFactory f = SecretKeyFactory.getInstance(algorithm.getAlgorithm());
+			return byteToBase64(f.generateSecret(spec).getEncoded());
+		} catch (NoSuchAlgorithmException e) {
+			log.error("", e);
+			return null;
+		} catch (InvalidKeySpecException e) {
+			log.error("", e);
+			return null;
+		}
+	}
+	
+	public static String getSalt() {
+	    try {
+				//Always use a SecureRandom generator
+				SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
+				//Create array for salt
+				byte[] salt = new byte[16];
+				//Get a random salt
+				sr.nextBytes(salt);
+				//return salt
+				return byteToBase64(salt);
+			} catch (NoSuchAlgorithmException e) {
+				log.error("", e);
+				return null;
+			}
 	}
 
+  public static String byteToBase64(byte[] data){
+  	return Base64Encoder.encode(data);
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/core/util/mail/manager/MailManager.java b/src/main/java/org/olat/core/util/mail/manager/MailManager.java
index e67bea37764d90bbdb64a8a3ef975444039ea498..3980db0290f9207d74576352514176328060f548 100644
--- a/src/main/java/org/olat/core/util/mail/manager/MailManager.java
+++ b/src/main/java/org/olat/core/util/mail/manager/MailManager.java
@@ -225,7 +225,7 @@ public class MailManager extends BasicManager {
 			return hasSibling;
 		}
 		
-		String uuid = Encoder.encrypt(name + checksum);
+		String uuid = Encoder.md5hash(name + checksum);
 		String dir = attachmentStorage.generateDir(uuid, false);
 		VFSContainer container = attachmentStorage.getContainer(dir);
 		String uniqueName = VFSManager.similarButNonExistingName(container, name);
@@ -733,7 +733,7 @@ public class MailManager extends BasicManager {
 				createAddress(toAddress, recipientTo, true, result, true);
 			} 
 			if(makeRealMail && StringHelper.containsNonWhitespace(to)) {
-				createAddress(toAddress, to, result);
+				createAddress(toAddress, to);
 			}
 			
 			if(cc != null) {
@@ -1016,7 +1016,7 @@ public class MailManager extends BasicManager {
 		}
 	}
 	
-	private boolean createAddress(List<Address> addressList, String address, MailerResult result) throws AddressException {
+	private boolean createAddress(List<Address> addressList, String address) throws AddressException {
 		Address add = createAddress(address);
 		if(add != null) {
 			addressList.add(add);
diff --git a/src/main/java/org/olat/core/util/resource/OresHelper.java b/src/main/java/org/olat/core/util/resource/OresHelper.java
index fd45b9cb75286aedea70faf563cab2585277b888..89c6e6efefd0a40b9dee3981b3cb7f42b70eae68 100644
--- a/src/main/java/org/olat/core/util/resource/OresHelper.java
+++ b/src/main/java/org/olat/core/util/resource/OresHelper.java
@@ -99,7 +99,7 @@ public class OresHelper {
 		String resourcableTypeName = ores.getResourceableTypeName();
 		if (resourcableTypeName.length() > 80) {
 			//encode into an md5 hash with fixed length of 32 characters otherwise the sting may get too long for locks or db fields
-			resourcableTypeName = Encoder.encrypt(resourcableTypeName);
+			resourcableTypeName = Encoder.md5hash(resourcableTypeName);
 		}
 		String derivedString = resourcableTypeName+"::"+ores.getResourceableId();
 		if (subKey != null) {
diff --git a/src/main/java/org/olat/core/util/servlets/MD5Encoder.java b/src/main/java/org/olat/core/util/servlets/MD5Encoder.java
deleted file mode 100644
index e376c83290bbdcc23d821b61074f45ed41b47ced..0000000000000000000000000000000000000000
--- a/src/main/java/org/olat/core/util/servlets/MD5Encoder.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
-* OLAT - Online Learning and Training<br>
-* http://www.olat.org
-* <p>
-* Licensed under the Apache License, Version 2.0 (the "License"); <br>
-* you may not use this file except in compliance with the License.<br>
-* You may obtain a copy of the License at
-* <p>
-* http://www.apache.org/licenses/LICENSE-2.0
-* <p>
-* Unless required by applicable law or agreed to in writing,<br>
-* software distributed under the License is distributed on an "AS IS" BASIS, <br>
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
-* See the License for the specific language governing permissions and <br>
-* limitations under the License.
-* <p>
-* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
-* University of Zurich, Switzerland.
-* <hr>
-* <a href="http://www.openolat.org">
-* OpenOLAT - Online Learning and Training</a><br>
-* This file has been modified by the OpenOLAT community. Changes are licensed
-* under the Apache 2.0 license as the original file.
-*/
-package org.olat.core.util.servlets;
-
-
-
-/**
- * Encode an MD5 digest into a String.
- * <p>
- * The 128 bit MD5 hash is converted into a 32 character long String.
- * Each character of the String is the hexadecimal representation of 4 bits
- * of the digest.
- *
- * @author Remy Maucherat
- */
-
-public final class MD5Encoder {
-
-
-    // ----------------------------------------------------- Instance Variables
-
-
-    private static final char[] hexadecimal =
-    {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-     'a', 'b', 'c', 'd', 'e', 'f'};
-
-
-    // --------------------------------------------------------- Public Methods
-
-
-    /**
-     * Encodes the 128 bit (16 bytes) MD5 into a 32 character String.
-     *
-     * @param binaryData Array containing the digest
-     * @return Encoded MD5, or null if encoding failed
-     */
-    public String encode( byte[] binaryData ) {
-
-        if (binaryData.length != 16)
-            return null;
-
-        char[] buffer = new char[32];
-
-        for (int i=0; i<16; i++) {
-            int low = (binaryData[i] & 0x0f);
-            int high = ((binaryData[i] & 0xf0) >> 4);
-            buffer[i*2] = hexadecimal[high];
-            buffer[i*2 + 1] = hexadecimal[low];
-        }
-
-        return new String(buffer);
-
-    }
-
-
-}
-
diff --git a/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java b/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java
index 7f79fd366168fbc300de44e31496f951c72f3b25..5c68c5897b139112cfa9330c99bac4fc1dbdf2ef 100644
--- a/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java
+++ b/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java
@@ -266,7 +266,7 @@ public class LTIRunController extends BasicController {
 			}
 		}
 		if (data.length() > 0) {
-			hash = Encoder.encrypt(data);
+			hash = Encoder.md5hash(data);
 		}
 		if (isLogDebugEnabled()) {
 			logDebug("Create accept hash::" + hash + " for data::" + data, null);
diff --git a/src/main/java/org/olat/course/statistic/export/LogLineConverter.java b/src/main/java/org/olat/course/statistic/export/LogLineConverter.java
index 7fdcad46ac3248bec95dce5afc55a9043961734b..9a5ca06e7d6393084438fdadce4997bcad723dc3 100644
--- a/src/main/java/org/olat/course/statistic/export/LogLineConverter.java
+++ b/src/main/java/org/olat/course/statistic/export/LogLineConverter.java
@@ -172,7 +172,7 @@ public class LogLineConverter {
 	private String makeAnonymous(String s, Long courseResId) {
 		String encodeValue = s + "-" + Long.toString(courseResId);
 		// encode with MD5
-		return Encoder.encrypt(encodeValue);
+		return Encoder.md5hash(encodeValue);
 	}
 
 }
diff --git a/src/main/java/org/olat/dispatcher/RemoteLoginformDispatcher.java b/src/main/java/org/olat/dispatcher/RemoteLoginformDispatcher.java
index cb2c7d666aa2c01f8a097a34b7421e6392943917..b858bd29774a3e866ab08e75cf56e3665cdc8d7e 100644
--- a/src/main/java/org/olat/dispatcher/RemoteLoginformDispatcher.java
+++ b/src/main/java/org/olat/dispatcher/RemoteLoginformDispatcher.java
@@ -28,6 +28,7 @@ import javax.servlet.http.HttpServletResponse;
 import org.olat.admin.user.delete.service.UserDeletionManager;
 import org.olat.basesecurity.AuthHelper;
 import org.olat.basesecurity.BaseSecurityModule;
+import org.olat.core.CoreSpringFactory;
 import org.olat.core.dispatcher.Dispatcher;
 import org.olat.core.dispatcher.DispatcherAction;
 import org.olat.core.gui.UserRequest;
@@ -46,6 +47,7 @@ import org.olat.core.util.StringHelper;
 import org.olat.core.util.UserSession;
 import org.olat.core.util.WebappHelper;
 import org.olat.login.OLATAuthenticationController;
+import org.olat.login.auth.OLATAuthManager;
 
 /**
  * <h3>Description:</h3>
@@ -123,7 +125,8 @@ public class RemoteLoginformDispatcher implements Dispatcher {
 			}
 			
 			// Authenticate user
-			Identity identity = OLATAuthenticationController.authenticate(userName, pwd);
+			OLATAuthManager olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class);
+			Identity identity = olatAuthenticationSpi.authenticate(null, userName, pwd);
 			if (identity == null) {
 				log.info("Could not authenticate user '" + userName + "', wrong password or user name");
 				// redirect to OLAT loginscreen, add error parameter so that the loginform can mark itself as errorfull
diff --git a/src/main/java/org/olat/ims/cp/ContentPackage.java b/src/main/java/org/olat/ims/cp/ContentPackage.java
index 06d52fca68447b0de955cce5f022ef720e2cb3e4..1240bea3c81ac690ef5ac88176c0a5a8e7c902d2 100644
--- a/src/main/java/org/olat/ims/cp/ContentPackage.java
+++ b/src/main/java/org/olat/ims/cp/ContentPackage.java
@@ -210,7 +210,7 @@ public class ContentPackage {
 		String orgaIdentifier = getFirstOrganizationInManifest().getIdentifier();
 		// For the root node id of the ext-js tree we use an md5 hash. This is to
 		// make sure that no unwanted characters are handed over to JS.
-		String rootNodeId = Encoder.encrypt(orgaIdentifier);
+		String rootNodeId = Encoder.md5hash(orgaIdentifier);
 		return new CPTreeDataModel(orgaIdentifier, rootNodeId, this);
 	}
 
diff --git a/src/main/java/org/olat/ims/cp/ui/VFSCPContainer.java b/src/main/java/org/olat/ims/cp/ui/VFSCPContainer.java
index f7b9a4d2f9f27b45f3f3d42babbe32be7c91c168..5fa74059cb652f555009638379655d15a9226b21 100644
--- a/src/main/java/org/olat/ims/cp/ui/VFSCPContainer.java
+++ b/src/main/java/org/olat/ims/cp/ui/VFSCPContainer.java
@@ -64,7 +64,7 @@ public class VFSCPContainer extends AbstractVirtualContainer implements VFSConta
 		super(name);
 		
 		String orgaIdentifier = cp.getFirstOrganizationInManifest().getIdentifier();
-		rootNodeId = Encoder.encrypt(orgaIdentifier);
+		rootNodeId = Encoder.md5hash(orgaIdentifier);
 
 		this.cp = cp;
 		cpMgm = (CPManagerImpl) CPManager.getInstance();
diff --git a/src/main/java/org/olat/ldap/LDAPLoginManagerImpl.java b/src/main/java/org/olat/ldap/LDAPLoginManagerImpl.java
index ae5fbac12d154f7c37b6588ae312e418cac72b28..0fd6bd939e107a3f9a2d360c58d8e2fd72d5c870 100644
--- a/src/main/java/org/olat/ldap/LDAPLoginManagerImpl.java
+++ b/src/main/java/org/olat/ldap/LDAPLoginManagerImpl.java
@@ -544,7 +544,7 @@ public class LDAPLoginManagerImpl extends LDAPLoginManager implements GenericEve
 		}
 
 		// Create Identity
-		Identity identity = securityManager.createAndPersistIdentityAndUser(uid, user, LDAPAuthenticationController.PROVIDER_LDAP, uid, null);
+		Identity identity = securityManager.createAndPersistIdentityAndUser(uid, user, LDAPAuthenticationController.PROVIDER_LDAP, uid);
 		// Add to SecurityGroup LDAP
 		SecurityGroup secGroup = securityManager.findSecurityGroupByName(LDAPConstants.SECURITY_GROUP_LDAP);
 		securityManager.addIdentityToSecurityGroup(identity, secGroup);
@@ -662,14 +662,14 @@ public class LDAPLoginManagerImpl extends LDAPLoginManager implements GenericEve
 				Authentication ldapAuth = securityManager.findAuthentication(identity, LDAPAuthenticationController.PROVIDER_LDAP);
 				if(ldapAuth == null) {
 					//BUG Fixe: update the user and test if it has a ldap provider
-					securityManager.createAndPersistAuthentication(identity, LDAPAuthenticationController.PROVIDER_LDAP, identity.getName(), null);
+					securityManager.createAndPersistAuthentication(identity, LDAPAuthenticationController.PROVIDER_LDAP, identity.getName(), null, null);
 				}
 				return identity;
 			}
 			else {
 				if (LDAPLoginModule.isConvertExistingLocalUsersToLDAPUsers()) {
 					// Add user to LDAP security group and add the ldap provider
-					securityManager.createAndPersistAuthentication(identity, LDAPAuthenticationController.PROVIDER_LDAP, identity.getName(), null);
+					securityManager.createAndPersistAuthentication(identity, LDAPAuthenticationController.PROVIDER_LDAP, identity.getName(), null, null);
 					securityManager.addIdentityToSecurityGroup(identity, ldapGroup);
 					logInfo("Found identity by LDAP username that was not yet in LDAP security group. Converted user::" + uid
 							+ " to be an LDAP managed user");
diff --git a/src/main/java/org/olat/ldap/ui/LDAPAuthenticationController.java b/src/main/java/org/olat/ldap/ui/LDAPAuthenticationController.java
index d251501d7c0d956d77e37eb770cd61d2eb292dd9..637c401a5f9a27352c28bdd0261222efeec30635 100644
--- a/src/main/java/org/olat/ldap/ui/LDAPAuthenticationController.java
+++ b/src/main/java/org/olat/ldap/ui/LDAPAuthenticationController.java
@@ -32,7 +32,6 @@ import org.olat.basesecurity.BaseSecurity;
 import org.olat.basesecurity.BaseSecurityManager;
 import org.olat.basesecurity.BaseSecurityModule;
 import org.olat.core.CoreSpringFactory;
-import org.olat.core.commons.persistence.DBFactory;
 import org.olat.core.dispatcher.DispatcherAction;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
@@ -49,7 +48,6 @@ import org.olat.core.id.context.ContextEntry;
 import org.olat.core.id.context.StateEntry;
 import org.olat.core.logging.OLATRuntimeException;
 import org.olat.core.logging.OLATSecurityException;
-import org.olat.core.util.Encoder;
 import org.olat.core.util.StringHelper;
 import org.olat.core.util.UserSession;
 import org.olat.core.util.Util;
@@ -59,8 +57,8 @@ import org.olat.ldap.LDAPError;
 import org.olat.ldap.LDAPLoginManager;
 import org.olat.ldap.LDAPLoginModule;
 import org.olat.login.LoginModule;
-import org.olat.login.OLATAuthenticationController;
 import org.olat.login.auth.AuthenticationController;
+import org.olat.login.auth.OLATAuthManager;
 import org.olat.login.auth.OLATAuthentcationForm;
 import org.olat.registration.DisclaimerController;
 import org.olat.registration.PwChangeController;
@@ -80,10 +78,14 @@ public class LDAPAuthenticationController extends AuthenticationController imple
 	private String provider = null;
 
 	private CloseableModalController cmc;
+	
+	private final OLATAuthManager olatAuthenticationSpi;
 
 	public LDAPAuthenticationController(UserRequest ureq, WindowControl control) {
 		// use fallback translator to login and registration package
 		super(ureq, control, Util.createPackageTranslator(LoginModule.class, ureq.getLocale(), Util.createPackageTranslator(RegistrationManager.class, ureq.getLocale())));
+
+		olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class);
 		
 		loginComp = createVelocityContainer("ldaplogin");
 		
@@ -173,7 +175,7 @@ protected void event(UserRequest ureq, Component source, Event event) {
 			} else {
 				// try fallback to OLAT provider if configured
 				if (LDAPLoginModule.isCacheLDAPPwdAsOLATPwdOnLogin()) {
-					authenticatedIdentity = OLATAuthenticationController.authenticate(login, pass);
+					authenticatedIdentity = olatAuthenticationSpi.authenticate(null, login, pass);
 				}
 				if (authenticatedIdentity != null) {
 					provider = BaseSecurityModule.getDefaultAuthProviderIdentifier();
@@ -287,15 +289,13 @@ protected void event(UserRequest ureq, Component source, Event event) {
 			}
 			// Add or update an OLAT authentication token for this user if configured in the module
 			if (identity != null && LDAPLoginModule.isCacheLDAPPwdAsOLATPwdOnLogin()) {
-				
 				Authentication auth = secMgr.findAuthentication(identity, BaseSecurityModule.getDefaultAuthProviderIdentifier());
 				if (auth == null) {
 					// Create new authentication token
-					secMgr.createAndPersistAuthentication(identity, BaseSecurityModule.getDefaultAuthProviderIdentifier(), username, Encoder.encrypt(pwd));
+					secMgr.createAndPersistAuthentication(identity, BaseSecurityModule.getDefaultAuthProviderIdentifier(), username, pwd, LoginModule.getDefaultHashAlgorithm());
 				} else {
 					// Reuse existing authentication token
-					auth.setCredential(Encoder.encrypt(pwd));
-					DBFactory.getInstance().updateObject(auth);
+					secMgr.updateCredentials(auth, pwd, LoginModule.getDefaultHashAlgorithm());
 				}				
 			}
 			return identity;
diff --git a/src/main/java/org/olat/login/GuestBFWCParts.java b/src/main/java/org/olat/login/GuestBFWCParts.java
index 13fc7daf0d0d724640f25a3fbadd7b32deceae2c..aba6a98b917ac8ce6471b4aa4d6bc50d45a912c7 100644
--- a/src/main/java/org/olat/login/GuestBFWCParts.java
+++ b/src/main/java/org/olat/login/GuestBFWCParts.java
@@ -123,7 +123,7 @@ public class GuestBFWCParts implements BaseFullWebappControllerParts {
 
 		// let all extensions add sitedefinitions
 		ExtManager extm = ExtManager.getInstance();
-		Class extensionPointSites = DTabs.class;
+		Class<?> extensionPointSites = DTabs.class;
 		int cnt = extm.getExtensionCnt();
 		for (int i = 0; i < cnt; i++) {
 			Extension anExt = extm.getExtension(i);
diff --git a/src/main/java/org/olat/login/LoginAuthprovidersController.java b/src/main/java/org/olat/login/LoginAuthprovidersController.java
index 0d3ccbe2a3808def3caf416b6831489cb74e805c..ce5dbceb5623b1fb3f6dce76fc44f632ba95f989 100644
--- a/src/main/java/org/olat/login/LoginAuthprovidersController.java
+++ b/src/main/java/org/olat/login/LoginAuthprovidersController.java
@@ -145,7 +145,7 @@ public class LoginAuthprovidersController extends MainLayoutBasicController impl
 			showAccessibilityPage();
 			olatMenuTree.setSelectedNodeId(accessibilityNode.getIdent());
 		} else if ("about".equals(type)) {
-			showAboutPage(ureq);
+			showAboutPage();
 			olatMenuTree.setSelectedNodeId(aboutNode.getIdent());
 		} else if ("registration".equals(type)) {
 			// make sure the OLAT authentication controller is activated as only this one can handle registration requests
@@ -272,7 +272,7 @@ public class LoginAuthprovidersController extends MainLayoutBasicController impl
 				} else if (cmd.equals(ACTION_COOKIES)) {
 					dmzPanel.pushContent(createVelocityContainer("cookies"));
 				} else if (cmd.equals(ACTION_ABOUT)) {
-					showAboutPage(ureq);//fxdiff FXOLAT-113: business path in DMZ
+					showAboutPage();//fxdiff FXOLAT-113: business path in DMZ
 				} else if (cmd.equals(ACTION_ACCESSIBILITY)) {
 					showAccessibilityPage();//fxdiff FXOLAT-113: business path in DMZ
 				}
@@ -296,7 +296,7 @@ public class LoginAuthprovidersController extends MainLayoutBasicController impl
 		dmzPanel.pushContent(browserCheck);
 	}
 	//fxdiff FXOLAT-113: business path in DMZ
-	protected void showAboutPage(UserRequest ureq) {
+	protected void showAboutPage() {
 	//fxdiff FXOLAT-139
 		VelocityContainer aboutVC = createVelocityContainer("about");
 		// Add version info and licenses
diff --git a/src/main/java/org/olat/login/LoginModule.java b/src/main/java/org/olat/login/LoginModule.java
index 3e1187e5ffb3d4bab5fd48c0a0b673d519944a9b..65b794d12902ff94e2fd71d6adab028cbd3b94ed 100644
--- a/src/main/java/org/olat/login/LoginModule.java
+++ b/src/main/java/org/olat/login/LoginModule.java
@@ -32,6 +32,7 @@ import java.util.Map;
 import org.olat.core.configuration.AbstractOLATModule;
 import org.olat.core.configuration.PersistedProperties;
 import org.olat.core.logging.StartupException;
+import org.olat.core.util.Encoder;
 import org.olat.core.util.cache.CacheWrapper;
 import org.olat.core.util.coordinate.CoordinatorManager;
 import org.olat.login.auth.AuthenticationProvider;
@@ -124,6 +125,10 @@ public class LoginModule extends AbstractOLATModule {
 		return defaultProviderName;
 	}
 	
+	public static Encoder.Algorithm getDefaultHashAlgorithm() {
+		return Encoder.Algorithm.sha512;
+	}
+	
 	/**
 	 * @param provider
 	 * @return AuthenticationProvider implementation.
diff --git a/src/main/java/org/olat/login/OLATAuthenticationController.java b/src/main/java/org/olat/login/OLATAuthenticationController.java
index 2cc24fa1e6201cb981374dc254fe99f8dde1d5d9..1e0809b32d8368bf6e95e2edaa89055c77580dae 100644
--- a/src/main/java/org/olat/login/OLATAuthenticationController.java
+++ b/src/main/java/org/olat/login/OLATAuthenticationController.java
@@ -25,13 +25,10 @@
 
 package org.olat.login;
 
-import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
 
 import org.olat.basesecurity.AuthHelper;
-import org.olat.basesecurity.BaseSecurityManager;
-import org.olat.basesecurity.BaseSecurityModule;
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
@@ -47,27 +44,21 @@ import org.olat.core.id.Identity;
 import org.olat.core.id.context.ContextEntry;
 import org.olat.core.id.context.StateEntry;
 import org.olat.core.logging.OLATSecurityException;
-import org.olat.core.logging.Tracing;
-import org.olat.core.util.Encoder;
 import org.olat.core.util.StringHelper;
 import org.olat.core.util.UserSession;
 import org.olat.core.util.Util;
 import org.olat.core.util.WebappHelper;
 import org.olat.core.util.i18n.I18nManager;
-import org.olat.core.util.mail.MailHelper;
 import org.olat.login.auth.AuthenticationController;
+import org.olat.login.auth.OLATAuthManager;
 import org.olat.login.auth.OLATAuthentcationForm;
 import org.olat.registration.DisclaimerController;
 import org.olat.registration.PwChangeController;
 import org.olat.registration.RegistrationController;
 import org.olat.registration.RegistrationManager;
 import org.olat.registration.RegistrationModule;
-import org.olat.registration.TemporaryKey;
-import org.olat.user.UserManager;
 import org.olat.user.UserModule;
 
-import com.thoughtworks.xstream.XStream;
-
 /**
  * Initial Date:  04.08.2004
  *
@@ -89,6 +80,8 @@ public class OLATAuthenticationController extends AuthenticationController imple
 	private Link registerLink;
 	private Link anoLink;
 	
+	private final OLATAuthManager olatAuthenticationSpi;
+	
 	/**
 	 * @see org.olat.login.auth.AuthenticationController#init(org.olat.core.gui.UserRequest, org.olat.core.gui.control.WindowControl)
 	 */
@@ -96,6 +89,8 @@ public class OLATAuthenticationController extends AuthenticationController imple
 		// use fallback translator to registration module
 		super(ureq, winControl, Util.createPackageTranslator(RegistrationManager.class, ureq.getLocale()));
 
+		olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class);
+		
 		loginComp = createVelocityContainer("olat_log", "olatlogin");
 		
 		if(UserModule.isPwdchangeallowed(null)) {
@@ -203,7 +198,7 @@ public class OLATAuthenticationController extends AuthenticationController imple
 				getLogger().audit("Login attempt on already blocked login for " + login + ". IP::" + ureq.getHttpReq().getRemoteAddr(), null);
 				return;
 			}
-			authenticatedIdentity = authenticate(login, pass);
+			authenticatedIdentity = olatAuthenticationSpi.authenticate(null, login, pass);
 			if (authenticatedIdentity == null) {
 				if (LoginModule.registerFailedLoginAttempt(login)) {
 					getLogger().audit("Too many failed login attempts for " + login + ". Login blocked. IP::" + ureq.getHttpReq().getRemoteAddr(), null);
@@ -288,19 +283,19 @@ public class OLATAuthenticationController extends AuthenticationController imple
 	 * @param pass
 	 * @return Identity if authentication was successfull, null otherwise.
 	 * @deprecated should not be part of the controller
-	 */
+	 *//*
 	public static Identity authenticate(String login, String pass) {
 		if (pass == null) return null; // do never accept empty passwords
 		Identity ident = BaseSecurityManager.getInstance().findIdentityByName(login);
 		return authenticate(ident, login, pass);
-	}
+	}*/
 	
 	/**
 	 * @param login
 	 * @param pass
 	 * @return Identity if authentication was successfull, null otherwise.
 	 * @deprecated should not be part of the controller
-	 */
+	 *//*
 	public static Identity authenticate(Identity ident, String login, String pass) {
 		// check for email instead of username if ident is null
 		if (ident == null && LoginModule.allowLoginUsingEmail()) {
@@ -342,7 +337,7 @@ public class OLATAuthenticationController extends AuthenticationController imple
 			}
 		}
 		return null;		
-	}
+	}*/
 
 	/**
 	 * @see org.olat.core.gui.control.DefaultController#doDispose(boolean)
diff --git a/src/main/java/org/olat/login/_spring/loginContext.xml b/src/main/java/org/olat/login/_spring/loginContext.xml
index d0b6290d588eae44f85648fa37c4f98ffa2e3db7..0abeac4ddac7d955b71200e1262ecfb6fc9d12b0 100644
--- a/src/main/java/org/olat/login/_spring/loginContext.xml
+++ b/src/main/java/org/olat/login/_spring/loginContext.xml
@@ -3,10 +3,9 @@
 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 	xsi:schemaLocation="
   http://www.springframework.org/schema/beans 
-  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
+  http://www.springframework.org/schema/beans/spring-beans.xsd">
 
 <bean id="loginModule" class="org.olat.login.LoginModule">
-
 	<property name="persistedProperties">
 	  <bean class="org.olat.core.configuration.PersistedProperties" scope="prototype" init-method="init" destroy-method="destroy">
 	    <constructor-arg index="0" ref="coordinatorManager"/>
@@ -88,6 +87,8 @@
 </bean>
 
 <bean id="afterLoginInterceptionManager" class="org.olat.login.AfterLoginInterceptionManager" />
+<bean id="olatAuthenticationSpi" class="org.olat.login.auth.OLATAuthManager" />
+
 
 
 </beans>
\ No newline at end of file
diff --git a/src/main/java/org/olat/login/auth/AuthenticationEvent.java b/src/main/java/org/olat/login/auth/AuthenticationEvent.java
index c57ce4cfaceae2bfda7f3c2a637fcb34ee98ce03..748f8dcfdbfaef93f1cce67c28df40a18709004d 100644
--- a/src/main/java/org/olat/login/auth/AuthenticationEvent.java
+++ b/src/main/java/org/olat/login/auth/AuthenticationEvent.java
@@ -35,6 +35,7 @@ import org.olat.core.id.Identity;
  */
 public class AuthenticationEvent extends Event {
 
+	private static final long serialVersionUID = -5353574564474813721L;
 	Identity identity;
 	
 	/**
@@ -48,5 +49,7 @@ public class AuthenticationEvent extends Event {
 	/**
 	 * @return the identity that was authenticated.
 	 */
-	public Identity getIdentity() { return identity; }
+	public Identity getIdentity() {
+		return identity;
+	}
 }
diff --git a/src/main/java/org/olat/login/auth/AuthenticationProvider.java b/src/main/java/org/olat/login/auth/AuthenticationProvider.java
index 3b3ed83f917593a90e177505b29209198a164080..954c18574d7a27550e6c1a4cd467f5c072fc6ba8 100644
--- a/src/main/java/org/olat/login/auth/AuthenticationProvider.java
+++ b/src/main/java/org/olat/login/auth/AuthenticationProvider.java
@@ -94,7 +94,6 @@ public class AuthenticationProvider implements ControllerCreator{
 	 * @param language
 	 * @return Description text.
 	 */
-	@SuppressWarnings("unchecked")
 	public String getDescription(Locale locale) {
 		Translator trans = getPackageTranslatorForLocale(locale);
 		String desc = trans.translate("authentication.provider.description");
@@ -123,7 +122,7 @@ public class AuthenticationProvider implements ControllerCreator{
 	 * @return a translator for the package matching the authenticationProvider
 	 */
 	private Translator getPackageTranslatorForLocale (Locale locale) {
-		Class authProvClass = null;
+		Class<?> authProvClass = null;
 		try {
 			authProvClass = Class.forName(clazz);
 		} catch (ClassNotFoundException e) {
diff --git a/src/main/java/org/olat/login/auth/AuthenticationSPI.java b/src/main/java/org/olat/login/auth/AuthenticationSPI.java
new file mode 100644
index 0000000000000000000000000000000000000000..2d838872a25704314d9e247ab4f32c72ffbb2f00
--- /dev/null
+++ b/src/main/java/org/olat/login/auth/AuthenticationSPI.java
@@ -0,0 +1,34 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.login.auth;
+
+import org.olat.core.id.Identity;
+
+/**
+ * 
+ * Initial date: 23.08.2013<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public interface AuthenticationSPI {
+	
+	public Identity authenticate(Identity identity, String login, String password);
+
+}
diff --git a/src/main/java/org/olat/login/auth/OLATAuthManager.java b/src/main/java/org/olat/login/auth/OLATAuthManager.java
index 8035f1a465cdb76274d4446d0c0f2f0001fb155e..f34f98f5db25cf199390c4717cc400f5297fba1a 100644
--- a/src/main/java/org/olat/login/auth/OLATAuthManager.java
+++ b/src/main/java/org/olat/login/auth/OLATAuthManager.java
@@ -25,13 +25,14 @@
 package org.olat.login.auth;
 
 import java.util.Collections;
+import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 
 import org.apache.velocity.VelocityContext;
 import org.olat.basesecurity.Authentication;
 import org.olat.basesecurity.BaseSecurity;
 import org.olat.basesecurity.BaseSecurityManager;
-import org.olat.basesecurity.BaseSecurityModule;
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.translator.Translator;
 import org.olat.core.id.Identity;
@@ -42,21 +43,29 @@ import org.olat.core.logging.AssertException;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.core.manager.BasicManager;
-import org.olat.core.util.Encoder;
+import org.olat.core.util.Encoder.Algorithm;
 import org.olat.core.util.Util;
 import org.olat.core.util.WebappHelper;
 import org.olat.core.util.i18n.I18nManager;
 import org.olat.core.util.mail.MailContext;
 import org.olat.core.util.mail.MailContextImpl;
+import org.olat.core.util.mail.MailHelper;
 import org.olat.core.util.mail.MailTemplate;
 import org.olat.core.util.mail.MailerWithTemplate;
 import org.olat.core.util.resource.OresHelper;
+import org.olat.core.util.xml.XStreamHelper;
 import org.olat.ldap.LDAPError;
 import org.olat.ldap.LDAPLoginManager;
 import org.olat.ldap.LDAPLoginModule;
 import org.olat.ldap.ui.LDAPAuthenticationController;
+import org.olat.login.LoginModule;
 import org.olat.login.OLATAuthenticationController;
+import org.olat.registration.RegistrationManager;
+import org.olat.registration.TemporaryKey;
 import org.olat.user.UserManager;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.thoughtworks.xstream.XStream;
 
 /**
  * Description:<br>
@@ -66,10 +75,81 @@ import org.olat.user.UserManager;
  * Initial Date:  26.09.2007 <br>
  * @author Felix Jost, http://www.goodsolutions.ch
  */
-public class OLATAuthManager extends BasicManager {
+public class OLATAuthManager extends BasicManager implements AuthenticationSPI {
 	
 	private static OLog log = Tracing.createLoggerFor(OLATAuthenticationController.class);
 	
+	@Autowired
+	private UserManager userManager;
+	@Autowired
+	private BaseSecurity securityManager;
+	
+	/**
+	 * 
+	 * @param identity
+	 * @param password
+	 * @param provider
+	 * @return
+	 */
+	@Override
+	public Identity authenticate(Identity ident, String login, String password) {
+		Authentication authentication;	
+		if (ident == null) {
+			// check for email instead of username if ident is null
+			if(LoginModule.allowLoginUsingEmail()) {
+				if (MailHelper.isValidEmailAddress(login)){
+	  	 	 	ident = userManager.findIdentityByEmail(login);
+	  	 	 	// check for email changed with verification workflow
+					if (ident == null) {
+						ident = findIdentInChangingEmailWorkflow(login);
+					}
+	  	 	}
+			} 
+			
+			if(ident == null) {
+				authentication = securityManager.findAuthenticationByAuthusername(login, "OLAT");
+			} else {
+				authentication = securityManager.findAuthentication(ident, "OLAT");
+			}
+		} else {
+			authentication = securityManager.findAuthentication(ident,  "OLAT");
+		}
+
+		if (authentication == null) {
+			log.audit("Error authenticating user "+login+" via provider OLAT", OLATAuthenticationController.class.getName());
+			return null;
+		}
+		
+		// find OLAT authentication provider
+		if (securityManager.checkCredentials(authentication, password))	{
+			Algorithm algorithm = Algorithm.find(authentication.getAlgorithm());
+			if(Algorithm.md5.equals(algorithm)) {
+				authentication = securityManager.updateCredentials(authentication, password, LoginModule.getDefaultHashAlgorithm());
+			}
+			return authentication.getIdentity();
+		}
+		log.audit("Error authenticating user "+login+" via provider OLAT", OLATAuthenticationController.class.getName());
+		return null;
+	}
+	
+	private Identity findIdentInChangingEmailWorkflow(String login){
+		XStream xml = XStreamHelper.createXStreamInstance();
+		
+		RegistrationManager rm = RegistrationManager.getInstance();
+		List<TemporaryKey> tk = rm.loadTemporaryKeyByAction(RegistrationManager.EMAIL_CHANGE);
+		if (tk != null) {
+			for (TemporaryKey temporaryKey : tk) {
+				@SuppressWarnings("unchecked")
+				Map<String, String> mails = (Map<String, String>)xml.fromXML(temporaryKey.getEmailAddress());
+				if (login.equals(mails.get("changedEMail"))) {
+					return securityManager.findIdentityByName(mails.get("currentEMail"));
+				}
+			}
+		}
+		return null;		
+	}
+	
+	
 	/**
 	 * Change the password of an identity. if the given identity is a LDAP-User,
 	 * the pw-change is propagated to LDAP (according to config) NOTE: caller of
@@ -85,16 +165,10 @@ public class OLATAuthManager extends BasicManager {
 	 *            New password.
 	 * @return True upon success.
 	 */
-	public static boolean changePassword(Identity doer, Identity identity, String newPwd) {
-		
+	public boolean changePassword(Identity doer, Identity identity, String newPwd) {
 		if (doer==null) throw new AssertException("password changing identity cannot be undefined!");
-		
 		if (identity.getKey() == null) throw new AssertException("cannot change password on a nonpersisted identity");
-		// password's length is limited to 128 chars. 
-		// The 128 bit MD5 hash is converted into a 32 character long String
-		String hashedPwd = Encoder.encrypt(newPwd);
-		BaseSecurity securityManager = BaseSecurityManager.getInstance();
-		
+
 		//o_clusterREVIEW
 		identity = securityManager.loadIdentityByKey(identity.getKey());
 		
@@ -110,21 +184,19 @@ public class OLATAuthManager extends BasicManager {
 				allOk = ldapError.isEmpty();
 
 				if(allOk && LDAPLoginModule.isCacheLDAPPwdAsOLATPwdOnLogin()) {
-					allOk &= changeOlatPassword(doer, identity, hashedPwd);
+					allOk &= changeOlatPassword(doer, identity, newPwd);
 				}
 			}
-		}
-		else {
-			allOk =changeOlatPassword(doer, identity, hashedPwd);
+		} else {
+			allOk = changeOlatPassword(doer, identity, newPwd);
 		}
 		if(allOk) {
 			sendConfirmationEmail(doer, identity);
 		}
-		
 		return allOk;
 	}
 	
-	private static void sendConfirmationEmail(Identity doer, Identity identity) {
+	private void sendConfirmationEmail(Identity doer, Identity identity) {
 		String prefsLanguage = identity.getUser().getPreferences().getLanguage();
 		Locale locale = I18nManager.getInstance().getLocaleOrDefault(prefsLanguage);
 		Translator translator = Util.createPackageTranslator(OLATAuthenticationController.class, locale);
@@ -151,16 +223,15 @@ public class OLATAuthManager extends BasicManager {
 		mailer.sendMailAsSeparateMails(context, Collections.singletonList(identity), null, template, null, null);
 	}
 	
-	private static boolean changeOlatPassword(Identity doer, Identity identity, String hashedPwd) {
-		Authentication auth = BaseSecurityManager.getInstance().findAuthentication(identity, BaseSecurityModule.getDefaultAuthProviderIdentifier());
+	private boolean changeOlatPassword(Identity doer, Identity identity, String newPwd) {
+		Authentication auth = securityManager.findAuthentication(identity, "OLAT");
 		if (auth == null) { // create new authentication for provider OLAT
-			auth = BaseSecurityManager.getInstance().createAndPersistAuthentication(identity, BaseSecurityModule.getDefaultAuthProviderIdentifier(), identity.getName(), hashedPwd);
+			auth = securityManager.createAndPersistAuthentication(identity, "OLAT", identity.getName(), newPwd, LoginModule.getDefaultHashAlgorithm());
 			log.audit(doer.getName() + " created new authenticatin for identity: " + identity.getName());
+		} else {
+			auth = securityManager.updateCredentials(auth, newPwd, LoginModule.getDefaultHashAlgorithm());
+			log.audit(doer.getName() + " set new password for identity: " + identity.getName());
 		}
-
-		auth.setCredential(hashedPwd);
-		auth = BaseSecurityManager.getInstance().updateAuthentication(auth);
-		log.audit(doer.getName() + " set new password for identity: " +identity.getName());
 		return true;
 	}
 
@@ -170,7 +241,7 @@ public class OLATAuthManager extends BasicManager {
 	 * @param newPwd
 	 * @return
 	 */
-	public static boolean changePasswordAsAdmin(Identity identity, String newPwd) {
+	public boolean changePasswordAsAdmin(Identity identity, String newPwd) {
 		Identity adminUserIdentity = BaseSecurityManager.getInstance().findIdentityByName("administrator");
 		return changePassword(adminUserIdentity, identity, newPwd);
 	}
@@ -181,7 +252,7 @@ public class OLATAuthManager extends BasicManager {
 	 * @param newPwd
 	 * @return
 	 */
-	public static boolean changePasswordByPasswordForgottenLink(Identity identity, String newPwd) {
+	public boolean changePasswordByPasswordForgottenLink(Identity identity, String newPwd) {
 		return changePassword(identity, identity, newPwd);
 	}
 	
diff --git a/src/main/java/org/olat/modules/vitero/manager/ViteroManager.java b/src/main/java/org/olat/modules/vitero/manager/ViteroManager.java
index 1d5206635edf6a1b5293278d915c4bfdb510d7b2..a7caaf968fe377c2b2b65abc1be9fd156885f9f0 100644
--- a/src/main/java/org/olat/modules/vitero/manager/ViteroManager.java
+++ b/src/main/java/org/olat/modules/vitero/manager/ViteroManager.java
@@ -484,7 +484,7 @@ public class ViteroManager extends BasicManager implements UserDataDeletable {
 				created = true;
 				userId =  createVmsUser(identity);
 				if(userId > 0) {
-					securityManager.createAndPersistAuthentication(identity, VMS_PROVIDER, Integer.toString(userId), "");
+					securityManager.createAndPersistAuthentication(identity, VMS_PROVIDER, Integer.toString(userId), null, null);
 				}
 			} else {
 				userId = -1;
@@ -1297,7 +1297,7 @@ public class ViteroManager extends BasicManager implements UserDataDeletable {
 						Identity identity = securityManager.findIdentityByName(olatUsername);
 						if(identity != null) {
 							authenticationCreated++;
-							securityManager.createAndPersistAuthentication(identity, VMS_PROVIDER, Integer.toString(user.getId()), "");
+							securityManager.createAndPersistAuthentication(identity, VMS_PROVIDER, Integer.toString(user.getId()), null, null);
 							logInfo("Recreate VMS authentication for: " + identity.getName());
 						}
 					}
diff --git a/src/main/java/org/olat/modules/webFeed/dispatching/Path.java b/src/main/java/org/olat/modules/webFeed/dispatching/Path.java
index fb750a44ef7c00c2825aa87f79493a381b06b47b..833892391ffbf5ea16a16cc9d6c1f1979dcd5b6c 100644
--- a/src/main/java/org/olat/modules/webFeed/dispatching/Path.java
+++ b/src/main/java/org/olat/modules/webFeed/dispatching/Path.java
@@ -513,7 +513,7 @@ public class Path {
 			if (authentication == null) {
 				// Create an authentication
 				String token = RandomStringUtils.randomAlphanumeric(6);
-				authentication = manager.createAndPersistAuthentication(identity, TOKEN_PROVIDER, idKey, token);
+				authentication = manager.createAndPersistAuthentication(identity, TOKEN_PROVIDER, idKey, token, null);
 			}
 			// If the repository entry allows guest access it is public, thus not
 			// private.
diff --git a/src/main/java/org/olat/modules/webFeed/managers/FeedManagerImpl.java b/src/main/java/org/olat/modules/webFeed/managers/FeedManagerImpl.java
index 35d29327b0d6f0a885ceb8532d282a3f0803d504..ede557ea5cd6afcc5f98cc49bd29e17bc7f85aaf 100644
--- a/src/main/java/org/olat/modules/webFeed/managers/FeedManagerImpl.java
+++ b/src/main/java/org/olat/modules/webFeed/managers/FeedManagerImpl.java
@@ -107,7 +107,7 @@ public class FeedManagerImpl extends FeedManager {
 	private final XStream xstream;
 	
 	// Better performance when protected (apparently)
-	protected CacheWrapper feedCache;
+	protected CacheWrapper<String,Feed> feedCache;
 	private OLog log;
 
 
@@ -185,7 +185,7 @@ public class FeedManagerImpl extends FeedManager {
 	 * 
 	 * @return The feed cache
 	 */
-	protected CacheWrapper initFeedCache() {
+	protected CacheWrapper<String,Feed> initFeedCache() {
 		if (feedCache == null) {
 			OLATResourceable ores = OresHelper.createOLATResourceableType(Feed.class);
 			coordinator.getSyncer().doInSync(ores, new SyncerExecutor() {
@@ -521,7 +521,7 @@ public class FeedManagerImpl extends FeedManager {
 		e.setTitle(entry.getTitle());
 		e.setDescription(entry.getDescription() != null ? entry.getDescription().getValue() : null);
 		// Extract content objects from syndication item
-		StringBuffer sb = new StringBuffer();
+		StringBuilder sb = new StringBuilder();
 		for (SyndContent content : (List<SyndContent>) entry.getContents()) {
 			// we don't check for type, assume it is html or txt
 			if (sb.length() > 0) {
@@ -1234,7 +1234,7 @@ public class FeedManagerImpl extends FeedManager {
 	public LockResult acquireLock(OLATResourceable feed, Item item, Identity identity) {
 		String key = itemKey(item, feed);
 		if (key.length() >= OresHelper.ORES_TYPE_LENGTH) {
-			key = Encoder.encrypt(key);
+			key = Encoder.md5hash(key);
 		}
 		OLATResourceable itemResource = OresHelper.createOLATResourceableType(key);
 		LockResult lockResult = coordinator.getLocker().acquireLock(itemResource, identity, key);
diff --git a/src/main/java/org/olat/registration/PwChangeForm.java b/src/main/java/org/olat/registration/PwChangeForm.java
index d403ab5032a6a391114041f6ea2908675d0f53d9..9efcc534637aeaf6cdce9e2decf9a81ed27badb7 100644
--- a/src/main/java/org/olat/registration/PwChangeForm.java
+++ b/src/main/java/org/olat/registration/PwChangeForm.java
@@ -25,6 +25,7 @@
 
 package org.olat.registration;
 
+import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.form.flexible.FormItemContainer;
 import org.olat.core.gui.components.form.flexible.elements.TextElement;
@@ -48,12 +49,17 @@ public class PwChangeForm extends FormBasicController {
 	private TextElement newpass1;
 	private TextElement newpass2; // confirm
 	
+	private final OLATAuthManager olatAuthenticationSpi;
+	
 	/**
 	 * Password change form.
 	 * @param name
 	 */
 	public PwChangeForm(UserRequest ureq, WindowControl wControl) {
 		super(ureq, wControl, null, Util.createPackageTranslator(ChangePasswordForm.class, ureq.getLocale()));
+		
+		olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class);
+		
 		initForm(ureq);
 	}
 
@@ -79,7 +85,7 @@ public class PwChangeForm extends FormBasicController {
 	 * @param s The identity to change the password.
 	 */
 	public boolean saveFormData(Identity s) {
-		return OLATAuthManager.changePasswordByPasswordForgottenLink(s, newpass1.getValue());	
+		return olatAuthenticationSpi.changePasswordByPasswordForgottenLink(s, newpass1.getValue());	
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/registration/RegistrationManager.java b/src/main/java/org/olat/registration/RegistrationManager.java
index 1eb978c9f8a376024e9f17d0b8bceb473e2d0e31..dcbd7a8865ae90365f863ca2a848b1334abd6c43 100644
--- a/src/main/java/org/olat/registration/RegistrationManager.java
+++ b/src/main/java/org/olat/registration/RegistrationManager.java
@@ -305,7 +305,7 @@ public class RegistrationManager extends BasicManager {
 	 */
 	public TemporaryKeyImpl register(String emailaddress, String ipaddress, String action) {
 		String today = new Date().toString();
-		String encryptMe = Encoder.encrypt(emailaddress + ipaddress + today);
+		String encryptMe = Encoder.md5hash(emailaddress + ipaddress + today);
 		TemporaryKeyImpl tk = new TemporaryKeyImpl(emailaddress, ipaddress, encryptMe, action);
 		DBFactory.getInstance().saveObject(tk);
 		return tk;
diff --git a/src/main/java/org/olat/restapi/security/Authentication.java b/src/main/java/org/olat/restapi/security/Authentication.java
index cc2c1850edc23ebc485842171cf44a6e25d0f7f6..1da83467760addd11b675bb9bc5704422d219cd4 100644
--- a/src/main/java/org/olat/restapi/security/Authentication.java
+++ b/src/main/java/org/olat/restapi/security/Authentication.java
@@ -38,7 +38,7 @@ import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.id.Identity;
 import org.olat.core.util.StringHelper;
-import org.olat.login.OLATAuthenticationController;
+import org.olat.login.auth.OLATAuthManager;
 
 /**
  * 
@@ -123,7 +123,8 @@ public class Authentication {
 	
 	private Response loginWithPassword(String username, String password, HttpServletRequest httpRequest) {
 		UserRequest ureq = RestSecurityHelper.getUserRequest(httpRequest);
-		Identity identity = OLATAuthenticationController.authenticate(username, password);
+		OLATAuthManager olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class);
+		Identity identity = olatAuthenticationSpi.authenticate(null, username, password);
 		if(identity == null) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
diff --git a/src/main/java/org/olat/restapi/security/RestApiLoginFilter.java b/src/main/java/org/olat/restapi/security/RestApiLoginFilter.java
index 77b562c1caaacadaea2bad00293dd828f03c857a..aa83547c82b12865cc6937a6255f0abcbccc838c 100644
--- a/src/main/java/org/olat/restapi/security/RestApiLoginFilter.java
+++ b/src/main/java/org/olat/restapi/security/RestApiLoginFilter.java
@@ -55,7 +55,7 @@ import org.olat.core.util.UserSession;
 import org.olat.core.util.WebappHelper;
 import org.olat.core.util.i18n.I18nManager;
 import org.olat.core.util.session.UserSessionManager;
-import org.olat.login.OLATAuthenticationController;
+import org.olat.login.auth.OLATAuthManager;
 import org.olat.restapi.RestModule;
 
 import com.oreilly.servlet.Base64Decoder;
@@ -168,7 +168,9 @@ public class RestApiLoginFilter implements Filter {
 					if (p != -1) {
 						String username = userPass.substring(0, p);
 						String password = userPass.substring(p + 1);
-						Identity identity = OLATAuthenticationController.authenticate(username, password);
+
+						OLATAuthManager olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class);
+						Identity identity = olatAuthenticationSpi.authenticate(null, username, password);
 						if(identity == null) {
 							return false;
 						}
diff --git a/src/main/java/org/olat/restapi/security/RestSecurityBeanImpl.java b/src/main/java/org/olat/restapi/security/RestSecurityBeanImpl.java
index 8688b8305aa9852000c14d1a4e775beb64729ec5..b575790b292be5903ed6b36d7924cd111379a191 100644
--- a/src/main/java/org/olat/restapi/security/RestSecurityBeanImpl.java
+++ b/src/main/java/org/olat/restapi/security/RestSecurityBeanImpl.java
@@ -71,7 +71,7 @@ public class RestSecurityBeanImpl implements RestSecurityBean {
 		
 		Authentication auth = securityManager.findAuthentication(identity, REST_AUTH_PROVIDER);
 		if(auth == null) {
-			auth = securityManager.createAndPersistAuthentication(identity, REST_AUTH_PROVIDER, identity.getName(), token);
+			auth = securityManager.createAndPersistAuthentication(identity, REST_AUTH_PROVIDER, identity.getName(), token, null);
 		} else {
 			auth.setCredential(token);
 			auth = securityManager.updateAuthentication(auth);
@@ -89,7 +89,7 @@ public class RestSecurityBeanImpl implements RestSecurityBean {
 		if(!StringHelper.containsNonWhitespace(token)) return false;
 		boolean registrated = tokenToIdentity.containsKey(token);
 		if(!registrated) {
-			List<Authentication> auths = securityManager.findAuthentication(REST_AUTH_PROVIDER, token);
+			List<Authentication> auths = securityManager.findAuthenticationByToken(REST_AUTH_PROVIDER, token);
 			if(auths.size() == 1) {
 				Authentication auth = auths.get(0);
 				tokenToIdentity.put(token, auth.getIdentity().getKey());
diff --git a/src/main/java/org/olat/shibboleth/ShibbolethMigrationForm.java b/src/main/java/org/olat/shibboleth/ShibbolethMigrationForm.java
index 0030d8ce68270524688f37c9718a55473be1e068..56f8f7cb5ba9767ca42b5da00e0b164d881c835a 100644
--- a/src/main/java/org/olat/shibboleth/ShibbolethMigrationForm.java
+++ b/src/main/java/org/olat/shibboleth/ShibbolethMigrationForm.java
@@ -26,6 +26,8 @@
 package org.olat.shibboleth;
 
 import org.olat.basesecurity.Authentication;
+import org.olat.basesecurity.BaseSecurity;
+import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.form.flexible.FormItemContainer;
 import org.olat.core.gui.components.form.flexible.elements.TextElement;
@@ -36,7 +38,6 @@ import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
-import org.olat.core.util.Encoder;
 import org.olat.login.LoginModule;
 
 /**
@@ -49,24 +50,25 @@ import org.olat.login.LoginModule;
  */
 
 public class ShibbolethMigrationForm extends FormBasicController {
+	private static final OLog log = Tracing.createLoggerFor(ShibbolethMigrationForm.class);
+	
 
-	private Authentication authentication;
+	private final Authentication authentication;
 	private TextElement login;
 	private TextElement password;
-	private OLog log = Tracing.createLoggerFor(this.getClass());
 	
+	private BaseSecurity securityManager;
 	
 	public ShibbolethMigrationForm(UserRequest ureq, WindowControl wControl, Authentication authentication) {
 		super(ureq, wControl);
+		securityManager = CoreSpringFactory.getImpl(BaseSecurity.class);
 		this.authentication = authentication;
 		initForm(ureq);
 	}
 	
 	@Override
 	protected boolean validateFormLogic(UserRequest ureq) {
-		String credential = authentication.getCredential();
-		if (credential == null) return false;
-		if (!credential.equals(Encoder.encrypt(password.getValue()))) {
+		if (!securityManager.checkCredentials(authentication, password.getValue())) {
 			if (LoginModule.registerFailedLoginAttempt(login.getValue())) {
 				password.setErrorKey("smf.error.blocked", null);
 				log.audit("Too many failed login attempts for " + login.getValue() + ". Login blocked.");
@@ -78,7 +80,6 @@ public class ShibbolethMigrationForm extends FormBasicController {
 		}
 		return true;
 	}
-
 	
 	/**
 	 * @return Authentication
diff --git a/src/main/java/org/olat/shibboleth/ShibbolethRegistrationController.java b/src/main/java/org/olat/shibboleth/ShibbolethRegistrationController.java
index 572e754fdf1e749eea97cf96c34a8015702f4a2b..9d7d9c6499b6048020aff966e8cff5961d99ccbb 100644
--- a/src/main/java/org/olat/shibboleth/ShibbolethRegistrationController.java
+++ b/src/main/java/org/olat/shibboleth/ShibbolethRegistrationController.java
@@ -353,7 +353,7 @@ public class ShibbolethRegistrationController extends DefaultController implemen
 						user.setProperty(UserConstants.INSTITUTIONALEMAIL, institutionalEmail);
 					}
 					user.setProperty(UserConstants.INSTITUTIONALUSERIDENTIFIER, shibbolethAttributesMap.get(ShibbolethModule.getInstitutionalUserIdentifier()));
-					identity = secMgr.createAndPersistIdentityAndUser(choosenLogin, user, ShibbolethDispatcher.PROVIDER_SHIB, shibbolethUniqueID, null);
+					identity = secMgr.createAndPersistIdentityAndUser(choosenLogin, user, ShibbolethDispatcher.PROVIDER_SHIB, shibbolethUniqueID);
 					SecurityGroup olatUserGroup = secMgr.findSecurityGroupByName(Constants.GROUP_OLATUSERS);
 					secMgr.addIdentityToSecurityGroup(identity, olatUserGroup);
 					// tell system that this user did accept the disclaimer
@@ -365,7 +365,7 @@ public class ShibbolethRegistrationController extends DefaultController implemen
 					Authentication auth = migrationForm.getAuthentication();
 					Identity authenticationedIdentity = auth.getIdentity();
 					BaseSecurity secMgr = BaseSecurityManager.getInstance();
-					secMgr.createAndPersistAuthentication(authenticationedIdentity, ShibbolethDispatcher.PROVIDER_SHIB, shibbolethUniqueID, null);
+					secMgr.createAndPersistAuthentication(authenticationedIdentity, ShibbolethDispatcher.PROVIDER_SHIB, shibbolethUniqueID, null, null);
 					
 					// update user profile
 					User user = authenticationedIdentity.getUser();
diff --git a/src/main/java/org/olat/user/ChangePasswordController.java b/src/main/java/org/olat/user/ChangePasswordController.java
index 90c5dd32474087f36235951e406f048c25b2c7f9..3d83f89cd72c16deb952f3084ed4b70e25cf1622 100644
--- a/src/main/java/org/olat/user/ChangePasswordController.java
+++ b/src/main/java/org/olat/user/ChangePasswordController.java
@@ -29,10 +29,11 @@ import java.util.Iterator;
 import java.util.List;
 
 import org.olat.basesecurity.Authentication;
-import org.olat.basesecurity.BaseSecurityModule;
-import org.olat.basesecurity.Constants;
 import org.olat.basesecurity.BaseSecurity;
 import org.olat.basesecurity.BaseSecurityManager;
+import org.olat.basesecurity.BaseSecurityModule;
+import org.olat.basesecurity.Constants;
+import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.velocity.VelocityContainer;
@@ -47,7 +48,6 @@ import org.olat.core.util.resource.OresHelper;
 import org.olat.ldap.LDAPError;
 import org.olat.ldap.LDAPLoginModule;
 import org.olat.ldap.ui.LDAPAuthenticationController;
-import org.olat.login.OLATAuthenticationController;
 import org.olat.login.SupportsAfterLoginInterceptor;
 import org.olat.login.auth.OLATAuthManager;
 
@@ -72,6 +72,8 @@ public class ChangePasswordController extends BasicController implements Support
 	
 	private VelocityContainer myContent;
 	private ChangePasswordForm chPwdForm;
+	
+	private final OLATAuthManager olatAuthenticationSpi;
 
 	/**
 	 * @param ureq
@@ -79,6 +81,8 @@ public class ChangePasswordController extends BasicController implements Support
 	 */
 	public ChangePasswordController(UserRequest ureq, WindowControl wControl) {
 		super(ureq, wControl);
+		
+		olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class);
 
 		// if a user is not allowed to change his/her own password, say it here
 		if (!UserModule.isPwdchangeallowed(ureq.getIdentity())) {
@@ -141,14 +145,14 @@ public class ChangePasswordController extends BasicController implements Support
 					//fallback to OLAT if enabled happen automatically in LDAPAuthenticationController
 					provenIdent = LDAPAuthenticationController.authenticate(ureq.getIdentity().getName(), oldPwd, ldapError);
 				} else if(BaseSecurityManager.getInstance().findAuthentication(ureq.getIdentity(), BaseSecurityModule.getDefaultAuthProviderIdentifier()) != null) {
-					provenIdent = OLATAuthenticationController.authenticate(ureq.getIdentity().getName(), oldPwd);
+					provenIdent = olatAuthenticationSpi.authenticate(ureq.getIdentity(), ureq.getIdentity().getName(), oldPwd);
 				}
 
 				if (provenIdent == null) {
 					showError("error.password.noauth");	
 				} else {
 					String newPwd = chPwdForm.getNewPasswordValue();
-					if(OLATAuthManager.changePassword(ureq.getIdentity(), provenIdent, newPwd)) {
+					if(olatAuthenticationSpi.changePassword(ureq.getIdentity(), provenIdent, newPwd)) {
 						//TODO: verify that we are NOT in a transaction (changepwd should be commited immediately)				
 						// fxdiff: we need this event for the afterlogin-controller
 						fireEvent(ureq, Event.DONE_EVENT);
diff --git a/src/main/java/org/olat/user/UserModule.java b/src/main/java/org/olat/user/UserModule.java
index 020a37422ea26bdeabaa02400f9694f52ebffbdd..2d301c45a0242f93cd151891f92a916b38b673dd 100644
--- a/src/main/java/org/olat/user/UserModule.java
+++ b/src/main/java/org/olat/user/UserModule.java
@@ -26,7 +26,6 @@
 package org.olat.user;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
@@ -49,7 +48,6 @@ import org.olat.core.logging.OLATRuntimeException;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.StartupException;
 import org.olat.core.logging.Tracing;
-import org.olat.core.util.Encoder;
 import org.olat.ldap.LDAPLoginManager;
 import org.olat.login.AfterLoginConfig;
 import org.olat.login.AfterLoginInterceptionManager;
@@ -114,8 +112,7 @@ public class UserModule extends AbstractOLATModule {
 	 */
 	public static boolean isLoginOnBlacklist(String login) {
 		login = login.toLowerCase();
-		for (Iterator iter = getLoginBlacklist().iterator(); iter.hasNext();) {
-			String regexp = (String) iter.next();
+		for (String regexp: getLoginBlacklist()) {
 			if (login.matches(regexp)) {
 				log.audit("Blacklist entry match for login '" + login + "' with regexp '" + regexp + "'.");
 				return true;
@@ -142,7 +139,7 @@ public class UserModule extends AbstractOLATModule {
 			count ++;
 		}
 		
-		Tracing.logInfo("Successfully added " + count + " entries to login blacklist.", UserModule.class);
+		logInfo("Successfully added " + count + " entries to login blacklist.");
 		
 
 		// Autogeneration of test users
@@ -159,16 +156,14 @@ public class UserModule extends AbstractOLATModule {
 
 		// read user editable fields configuration
 		if (defaultUsers != null) {
-			for (Iterator iter = defaultUsers.iterator(); iter.hasNext();) {
-				DefaultUser user = (DefaultUser) iter.next();
+			for (DefaultUser user:defaultUsers) {
 				createUser(user);
 			}
 		}
 		if (hasTestUsers) {
 			// read user editable fields configuration
 			if (testUsers != null) {
-				for (Iterator iter = testUsers.iterator(); iter.hasNext();) {
-					DefaultUser user = (DefaultUser) iter.next();
+				for (DefaultUser user :testUsers) {
 					createUser(user);
 				}
 			}
@@ -250,7 +245,7 @@ public class UserModule extends AbstractOLATModule {
 			// Now finally create that user thing on the database with all
 			// credentials, person etc. in one transation context!
 			identity = BaseSecurityManager.getInstance().createAndPersistIdentityAndUser(user.getUserName(), newUser, authenticationProviderConstant,
-					user.getUserName(), Encoder.encrypt(user.getPassword()));
+					user.getUserName(), user.getPassword());
 			if (identity == null) {
 				throw new OLATRuntimeException(this.getClass(), "Error, could not create  user and subject with name " + user.getUserName(), null);
 			} else {
@@ -288,7 +283,7 @@ public class UserModule extends AbstractOLATModule {
 	/**
 	 * @return List of logins on blacklist.
 	 */
-	public static List getLoginBlacklist() {
+	public static List<String> getLoginBlacklist() {
 		return loginBlacklistChecked;
 	}
 
diff --git a/src/main/java/org/olat/user/WebDAVPasswordController.java b/src/main/java/org/olat/user/WebDAVPasswordController.java
index 7e4c3131489797c6f3dc976bf0a4ae135c1af67a..83f517bc7c60c9138b576801361f4d0faa42533c 100644
--- a/src/main/java/org/olat/user/WebDAVPasswordController.java
+++ b/src/main/java/org/olat/user/WebDAVPasswordController.java
@@ -23,8 +23,9 @@ package org.olat.user;
 import java.util.List;
 
 import org.olat.basesecurity.Authentication;
-import org.olat.basesecurity.BaseSecurityManager;
+import org.olat.basesecurity.BaseSecurity;
 import org.olat.basesecurity.BaseSecurityModule;
+import org.olat.core.CoreSpringFactory;
 import org.olat.core.commons.modules.bc.FolderManager;
 import org.olat.core.commons.services.webdav.manager.WebDAVAuthManager;
 import org.olat.core.gui.UserRequest;
@@ -63,8 +64,15 @@ public class WebDAVPasswordController extends FormBasicController {
 	private FormLayoutContainer accessDataFlc;
 	private FormLayoutContainer buttonGroupLayout;
 	
+	private final WebDAVAuthManager webDAVAuthManager;
+	private final BaseSecurity securityManager;
+	
 	public WebDAVPasswordController(UserRequest ureq, WindowControl wControl) {
 		super(ureq,wControl, "pwdav");
+		
+		webDAVAuthManager = CoreSpringFactory.getImpl(WebDAVAuthManager.class);
+		securityManager = CoreSpringFactory.getImpl(BaseSecurity.class);
+		
 		initForm(ureq);
 	}
 	
@@ -82,7 +90,7 @@ public class WebDAVPasswordController extends FormBasicController {
 
 			boolean hasOlatToken = false;
 			boolean hasWebDAVToken = false;
-			List<Authentication> authentications = BaseSecurityManager.getInstance().getAuthentications(ureq.getIdentity());
+			List<Authentication> authentications = securityManager.getAuthentications(ureq.getIdentity());
 			for(Authentication auth : authentications) {
 				if(BaseSecurityModule.getDefaultAuthProviderIdentifier().equals(auth.getProvider())) {
 					hasOlatToken = true;
@@ -161,7 +169,7 @@ public class WebDAVPasswordController extends FormBasicController {
 	protected void formOK(UserRequest ureq) {
 		if(passwordEl != null && passwordEl.isVisible()) {
 			String newPassword = passwordEl.getValue();
-			if(WebDAVAuthManager.changePassword(ureq.getIdentity(), ureq.getIdentity(), newPassword)) {
+			if(webDAVAuthManager.changePassword(ureq.getIdentity(), ureq.getIdentity(), newPassword)) {
 				showInfo("pwdav.password.successful");
 				toogleChangePassword(ureq);
 			} else {
@@ -189,12 +197,14 @@ public class WebDAVPasswordController extends FormBasicController {
 		passwordEl.setVisible(visible);
 		confirmPasswordEl.setVisible(visible);
 		
-		Authentication auth = BaseSecurityManager.getInstance().findAuthentication(ureq.getIdentity(), WebDAVAuthManager.PROVIDER_WEBDAV);
+		Authentication auth = securityManager.findAuthentication(ureq.getIdentity(), WebDAVAuthManager.PROVIDER_WEBDAV);
 		String passwordPlaceholderKey = auth == null ? "pwdav.password.not_set" : "pwdav.password.set";
 		String passwordPlaceholder = getTranslator().translate(passwordPlaceholderKey);
 		passwordStaticEl.setValue(passwordPlaceholder);
 		
 		String buttonPlaceholderKey = auth == null ? "pwdav.password.new" : "pwdav.password.change";
 		newButton.setI18nKey(buttonPlaceholderKey);
+		
+		flc.setDirty(true);
 	}
 }
diff --git a/src/main/java/org/olat/user/restapi/UserAuthenticationWebService.java b/src/main/java/org/olat/user/restapi/UserAuthenticationWebService.java
index 3ee1301ea6b2ea0a9b0f769599d58bb959286806..be1985d3760f6f9c56a8039f2d4cd28ae0ecc4ab 100644
--- a/src/main/java/org/olat/user/restapi/UserAuthenticationWebService.java
+++ b/src/main/java/org/olat/user/restapi/UserAuthenticationWebService.java
@@ -141,7 +141,7 @@ public class UserAuthenticationWebService {
 		String provider = authenticationVO.getProvider();
 		String authUsername = authenticationVO.getAuthUsername();
 		String credentials = authenticationVO.getCredential();
-		Authentication authentication = baseSecurity.createAndPersistAuthentication(identity, provider, authUsername, credentials);
+		Authentication authentication = baseSecurity.createAndPersistAuthentication(identity, provider, authUsername, credentials, null);
 		if(authentication == null) {
 			return Response.serverError().status(Status.NOT_ACCEPTABLE).build();
 		}
diff --git a/src/main/resources/database/mysql/alter_9_0_0_to_9_1_0.sql b/src/main/resources/database/mysql/alter_9_0_0_to_9_1_0.sql
new file mode 100644
index 0000000000000000000000000000000000000000..d20bd44fcbf4f3d04a21bcb56ae34577845dfab0
--- /dev/null
+++ b/src/main/resources/database/mysql/alter_9_0_0_to_9_1_0.sql
@@ -0,0 +1,3 @@
+-- salted password
+alter table o_bs_authentication add column salt varchar(255) default null;
+alter table o_bs_authentication add column hashalgorithm varchar(16) default null;
diff --git a/src/main/resources/database/mysql/setupDatabase.sql b/src/main/resources/database/mysql/setupDatabase.sql
index 5c6caf39f72a1436ac7830ebcb5197285490c8cb..ebf63ab0a24abb80b5dda6863887dfdc7a2548b9 100644
--- a/src/main/resources/database/mysql/setupDatabase.sql
+++ b/src/main/resources/database/mysql/setupDatabase.sql
@@ -78,6 +78,8 @@ create table if not exists o_bs_authentication (
    provider varchar(8),
    authusername varchar(255),
    credential varchar(255),
+   salt varchar(255) default null,
+   hashalgorithm varchar(16) default null,
    primary key (id),
    unique (provider, authusername)
 );
diff --git a/src/main/resources/database/oracle/alter_9_0_0_to_9_1_0.sql b/src/main/resources/database/oracle/alter_9_0_0_to_9_1_0.sql
new file mode 100644
index 0000000000000000000000000000000000000000..3df574818a9baf40033195d1a031a9bd21e65360
--- /dev/null
+++ b/src/main/resources/database/oracle/alter_9_0_0_to_9_1_0.sql
@@ -0,0 +1,3 @@
+-- salted password
+alter table o_bs_authentication add (salt varchar(255));
+alter table o_bs_authentication add (hashalgorithm varchar(16));
diff --git a/src/main/resources/database/oracle/setupDatabase.sql b/src/main/resources/database/oracle/setupDatabase.sql
index 17a7f501a389996bac9ad16532e2b6acf6bac790..db0de6b77b66c472ccf23715a6cab12bd523c08a 100644
--- a/src/main/resources/database/oracle/setupDatabase.sql
+++ b/src/main/resources/database/oracle/setupDatabase.sql
@@ -85,6 +85,8 @@ CREATE TABLE o_bs_authentication (
   provider varchar2(8 char),
   authusername varchar2(255 char),
   credential varchar2(255 char),
+  salt varchar2(255 char),
+  hashalgorithm varchar2(16 char),
   PRIMARY KEY (id),
   CONSTRAINT u_o_bs_authentication UNIQUE (provider, authusername)
 );
diff --git a/src/main/resources/database/postgresql/alter_9_0_0_to_9_1_0.sql b/src/main/resources/database/postgresql/alter_9_0_0_to_9_1_0.sql
new file mode 100644
index 0000000000000000000000000000000000000000..d20bd44fcbf4f3d04a21bcb56ae34577845dfab0
--- /dev/null
+++ b/src/main/resources/database/postgresql/alter_9_0_0_to_9_1_0.sql
@@ -0,0 +1,3 @@
+-- salted password
+alter table o_bs_authentication add column salt varchar(255) default null;
+alter table o_bs_authentication add column hashalgorithm varchar(16) default null;
diff --git a/src/main/resources/database/postgresql/setupDatabase.sql b/src/main/resources/database/postgresql/setupDatabase.sql
index 958f197b43b792834093c8502da5bfd726e3895e..23f1872ffd5ddf0ff9eae715a946ac6b898dd6aa 100644
--- a/src/main/resources/database/postgresql/setupDatabase.sql
+++ b/src/main/resources/database/postgresql/setupDatabase.sql
@@ -76,6 +76,8 @@ create table o_bs_authentication (
    provider varchar(8),
    authusername varchar(255),
    credential varchar(255),
+   salt varchar(255) default null,
+   hashalgorithm varchar(16) default null,
    primary key (id),
    unique (provider, authusername)
 );
diff --git a/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java b/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java
index 479b27c95a0c68d293931e7c5883b230ccd4b450..d538a6d41bc102bcc546a247ce5fb16daa659223 100644
--- a/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java
+++ b/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java
@@ -38,7 +38,6 @@ import org.olat.core.id.Identity;
 import org.olat.core.id.Roles;
 import org.olat.core.id.User;
 import org.olat.core.id.UserConstants;
-import org.olat.core.util.Encoder;
 import org.olat.resource.OLATResource;
 import org.olat.test.JunitTestHelper;
 import org.olat.test.OlatTestCase;
@@ -64,7 +63,7 @@ public class BaseSecurityManagerTest extends OlatTestCase {
 	public void testCreateIdentity() {
 		String name = "createid-" + UUID.randomUUID().toString();
 		User user = userManager.createUser("first" + name, "last" + name, name + "@frentix.com");
-		Identity identity = securityManager.createAndPersistIdentityAndUser(name, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), name, Encoder.encrypt("secret"));
+		Identity identity = securityManager.createAndPersistIdentityAndUser(name, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), name, "secret");
 		dbInstance.commitAndCloseSession();
 		
 		Assert.assertNotNull(identity);
@@ -86,7 +85,7 @@ public class BaseSecurityManagerTest extends OlatTestCase {
 		User user = userManager.createUser("first" + name, "last" + name, name + "@frentix.com");
 		user.setProperty(UserConstants.COUNTRY, "");
 		user.setProperty(UserConstants.CITY, "Basel");
-		Identity identity = securityManager.createAndPersistIdentityAndUser(name, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), name, Encoder.encrypt("secret"));
+		Identity identity = securityManager.createAndPersistIdentityAndUser(name, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), name, "secret");
 		dbInstance.commitAndCloseSession();
 		
 		//reload and update
@@ -836,15 +835,4 @@ public class BaseSecurityManagerTest extends OlatTestCase {
 		Assert.assertTrue(permissions.contains("test.gpor-1_2"));
 		Assert.assertFalse(permissions.contains("test.gpor-1_3"));
 	}
-	
-	@Test
-	public void findCredentials() {
-		//create a user with the default provider
-		Identity id = JunitTestHelper.createAndPersistIdentityAsUser("find-cred-" + UUID.randomUUID().toString());
-		
-		dbInstance.commitAndCloseSession();
-		
-		String credential = securityManager.findCredentials(id, BaseSecurityModule.getDefaultAuthProviderIdentifier());
-		Assert.assertNotNull(credential);	
-	}
 }
diff --git a/src/test/java/org/olat/basesecurity/BaseSecurityTest.java b/src/test/java/org/olat/basesecurity/BaseSecurityTest.java
index 7ee5f0a4faa0206584b8367869e4018e9a62d323..f51fffaab029c42f30d8e0e00e64b3ba6c3a547a 100644
--- a/src/test/java/org/olat/basesecurity/BaseSecurityTest.java
+++ b/src/test/java/org/olat/basesecurity/BaseSecurityTest.java
@@ -46,7 +46,6 @@ import org.olat.core.id.User;
 import org.olat.core.id.UserConstants;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
-import org.olat.core.util.Encoder;
 import org.olat.test.JunitTestHelper;
 import org.olat.test.OlatTestCase;
 import org.olat.user.UserManager;
@@ -482,13 +481,13 @@ public class BaseSecurityTest extends OlatTestCase {
 		try {
 			User onePropUser = UserManager.getInstance().createUser("onepropuser", "onepropuser", "onepropuser@lustig.com");
 			onePropUser.setProperty(UserConstants.FIRSTNAME, "one");		
-			Identity onePropeIdentity = baseSecurityManager.createAndPersistIdentityAndUser("onePropUser", onePropUser, BaseSecurityModule.getDefaultAuthProviderIdentifier(), "onepropuser", Encoder.encrypt("ppp"));
+			Identity onePropeIdentity = baseSecurityManager.createAndPersistIdentityAndUser("onePropUser", onePropUser, BaseSecurityModule.getDefaultAuthProviderIdentifier(), "onepropuser", "ppp");
 			Assert.assertNotNull(onePropeIdentity);
 			
 			User twoPropUser = UserManager.getInstance().createUser("twopropuser", "twopropuser", "twopropuser@lustig.com");
 			twoPropUser.setProperty(UserConstants.FIRSTNAME, "two");
 			twoPropUser.setProperty(UserConstants.LASTNAME, "prop");
-			Identity twoPropeIdentity = baseSecurityManager.createAndPersistIdentityAndUser("twopropuser", twoPropUser, BaseSecurityModule.getDefaultAuthProviderIdentifier(), "twopropuser", Encoder.encrypt("ppp"));
+			Identity twoPropeIdentity = baseSecurityManager.createAndPersistIdentityAndUser("twopropuser", twoPropUser, BaseSecurityModule.getDefaultAuthProviderIdentifier(), "twopropuser", "ppp");
 			Assert.assertNotNull(twoPropeIdentity);
 			// commit
 			DBFactory.getInstance().closeSession();
@@ -575,7 +574,7 @@ public class BaseSecurityTest extends OlatTestCase {
 			multiPropUser.setProperty(UserConstants.INSTITUTIONALEMAIL, "multiinst@lustig.com");		
 			multiPropUser.setProperty(UserConstants.INSTITUTIONALUSERIDENTIFIER, "multiinst");		
 			multiPropUser.setProperty(UserConstants.CITY, "züri");		
-			Identity onePropeIdentity = baseSecurityManager.createAndPersistIdentityAndUser("multiPropUser", multiPropUser, BaseSecurityModule.getDefaultAuthProviderIdentifier(), "multipropuser", Encoder.encrypt("ppp"));
+			Identity onePropeIdentity = baseSecurityManager.createAndPersistIdentityAndUser("multiPropUser", multiPropUser, BaseSecurityModule.getDefaultAuthProviderIdentifier(), "multipropuser", "ppp");
 			Assert.assertNotNull(onePropeIdentity);
 			
 			// commit
@@ -752,7 +751,7 @@ public class BaseSecurityTest extends OlatTestCase {
 			User user = UserManager.getInstance().createUser(name+"_Firstname", name + "_Lastname", name + "@lustig.com");
 			user.setProperty(UserConstants.INSTITUTIONALNAME, "unizh2");
 			user.setProperty(UserConstants.INSTITUTIONALUSERIDENTIFIER, "12-345-678-908");
-			ident = baseSecurityManager.createAndPersistIdentityAndUser(name, user, authProvider, name, Encoder.encrypt("ppp"));
+			ident = baseSecurityManager.createAndPersistIdentityAndUser(name, user, authProvider, name, "ppp");
 			return ident;
 		}
 	}
diff --git a/src/test/java/org/olat/basesecurity/SecurityManagerTest.java b/src/test/java/org/olat/basesecurity/SecurityManagerTest.java
index 0ae7b08444e51c48a51013e2db625f269b52d847..6b36385ecf16e909009080a46716a4009eed7b08 100644
--- a/src/test/java/org/olat/basesecurity/SecurityManagerTest.java
+++ b/src/test/java/org/olat/basesecurity/SecurityManagerTest.java
@@ -50,6 +50,7 @@ import org.olat.core.id.Identity;
 import org.olat.core.id.UserConstants;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
+import org.olat.core.util.Encoder;
 import org.olat.test.JunitTestHelper;
 import org.olat.test.OlatTestCase;
 
@@ -156,7 +157,7 @@ public class SecurityManagerTest extends OlatTestCase {
 		assertEquals(1, userList.size());
 
 		// 3) two fields wheras only one matches to one single user
-		sm.createAndPersistAuthentication(s1, "mytest_p", s1.getName(), "sdf");
+		sm.createAndPersistAuthentication(s1, "mytest_p", s1.getName(), "sdf", Encoder.Algorithm.sha512);
 		String[] myProviders = new String[] {"mytest_p", "non-prov"};
 		for (int i = 0; i < myProviders.length; i++) {
 			assertTrue("Provider name.length must be <= 8", myProviders[i].length() <= 8);
diff --git a/src/test/java/org/olat/core/util/EncoderTest.java b/src/test/java/org/olat/core/util/EncoderTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a31c4745af36dfc546f2765fe3205638515cb8a
--- /dev/null
+++ b/src/test/java/org/olat/core/util/EncoderTest.java
@@ -0,0 +1,87 @@
+package org.olat.core.util;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+import org.olat.core.util.Encoder.Algorithm;
+
+/**
+ * 
+ * Initial date: 23.08.2013<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class EncoderTest {
+	
+	@Test
+	public void testCompatibility() {
+		//the openolat password as saved on our database
+		String openolat = "c14c4d01c090a065eaa619ca92f8cbc0";
+
+		String hashedOpenolat_1 = Encoder.md5("openolat", null);
+		Assert.assertEquals(openolat, hashedOpenolat_1);
+		
+		String encryptedOpenolat_1 = Encoder.md5hash("openolat");
+		Assert.assertEquals(openolat, encryptedOpenolat_1);
+		
+		String encryptedOpenolat_2 = Encoder.encrypt("openolat", null, Algorithm.md5);
+		Assert.assertEquals(openolat, encryptedOpenolat_2);
+	}
+	
+	/**
+	 * Dummy test which check that the salts are not always equals.
+	 */
+	@Test
+	public void testSalt() {
+		Set<String> history = new HashSet<String>();
+		for(int i=0; i<100; i++) {
+			String salt = Encoder.getSalt();
+			Assert.assertFalse(history.contains(salt));
+			history.add(salt);
+		}
+		Assert.assertEquals(100, history.size());
+	}
+
+	@Test
+	public void testSHA1() {
+		String password = "openolat#19";
+		String salt = "FEHq1hZYqd54/iCoboHvBQ==";
+		String hash = "dkpoYSfn3uz6UcwdFhauuOFgX7Q=";
+		
+		String shaOutput = Encoder.encrypt(password, salt, Algorithm.sha1);
+		Assert.assertEquals(hash, shaOutput);
+	}
+			
+	@Test
+	public void testSHA256() {
+		String password = "openolat#19";
+		String salt = "dbStjLmL2av7LObcN/69ww==";
+		String hash = "+iTqibtIuur1t1IBYJ3P1i/iq6Xx2cb38wHc7LXHLHQ=";
+		
+		String shaOutput = Encoder.encrypt(password, salt, Algorithm.sha256);
+		Assert.assertEquals(hash, shaOutput);
+	}
+	
+	@Test
+	public void testSHA512() {
+		String password = "openolat#19";
+		String salt = "Y4nY4VFWaiSnM6qe88ZxbQ==";
+		String hash = "3+OTGOdnladWlLOY71DNnYa1YpaNmrDyefCvp/LM7d417frbjabdJnWkxK6JLOwxzJkpSfyjg3LY\nY8I0Mnq8PA==";
+		
+		String shaOutput = Encoder.encrypt(password, salt, Algorithm.sha512);
+		Assert.assertEquals(hash, shaOutput);
+	}
+	
+	@Test
+	public void testPBKDF2() {
+		String password = "openolat#19";
+		String salt = "lji1/YS8rEwv/ML0JUV2OQ==";
+		String hash = "kUUaki27mueSEkrFeAFQoLfs1k8=";
+
+		String shaOutput = Encoder.encrypt(password, salt, Algorithm.pbkdf2);
+		Assert.assertEquals(hash, shaOutput);
+	}
+}
diff --git a/src/test/java/org/olat/group/test/BusinessGroupServiceTest.java b/src/test/java/org/olat/group/test/BusinessGroupServiceTest.java
index d82d36fd99c7540a5333d4d9ee1c5673cc302e45..9eade2339a36e5cba7ab2586cbc76fbc1dfe5955 100644
--- a/src/test/java/org/olat/group/test/BusinessGroupServiceTest.java
+++ b/src/test/java/org/olat/group/test/BusinessGroupServiceTest.java
@@ -47,7 +47,6 @@ import org.olat.core.id.Roles;
 import org.olat.core.id.User;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
-import org.olat.core.util.Encoder;
 import org.olat.core.util.mail.MailPackage;
 import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupService;
@@ -169,8 +168,8 @@ public class BusinessGroupServiceTest extends OlatTestCase {
 			bgWithWaitingList.setMaxParticipants(new Integer(2));
 			// Identities
 			String suffix = UUID.randomUUID().toString();
-			User UserWg1 = userManager.createAndPersistUser("FirstName_" + suffix, "LastName_" + suffix, suffix + "_junittest@olat.unizh.ch");
-			wg1 = securityManager.createAndPersistIdentity(suffix, UserWg1, BaseSecurityModule.getDefaultAuthProviderIdentifier(), suffix, Encoder.encrypt("wg1"));
+			User userWg1 = userManager.createAndPersistUser("FirstName_" + suffix, "LastName_" + suffix, suffix + "_junittest@olat.unizh.ch");
+			wg1 = securityManager.createAndPersistIdentity(suffix, userWg1, BaseSecurityModule.getDefaultAuthProviderIdentifier(), suffix, "wg1");
 
 			dbInstance.commitAndCloseSession();
 
diff --git a/src/test/java/org/olat/ldap/LDAPLoginTest.java b/src/test/java/org/olat/ldap/LDAPLoginTest.java
index 1dcdb3a2a443902cae623767e8ed05cff6af08ae..d17c341b195fe1d1382ba562a35d2ceffaf392e8 100644
--- a/src/test/java/org/olat/ldap/LDAPLoginTest.java
+++ b/src/test/java/org/olat/ldap/LDAPLoginTest.java
@@ -169,7 +169,7 @@ public class LDAPLoginTest extends OlatTestCase {
 			try {
 				//create user but with different attributes - must fail since user already exists
 				User user = UserManager.getInstance().createUser("klaus", "Meier", "klaus@meier.ch");
-				Identity identity = securityManager.createAndPersistIdentityAndUser("kmeier", user, "LDAP", "kmeier", null);
+				Identity identity = securityManager.createAndPersistIdentityAndUser("kmeier", user, "LDAP", "kmeier");
 				SecurityGroup secGroup = securityManager.findSecurityGroupByName(LDAPConstants.SECURITY_GROUP_LDAP);
 				securityManager.addIdentityToSecurityGroup(identity, secGroup);
 				
@@ -188,7 +188,7 @@ public class LDAPLoginTest extends OlatTestCase {
 		} else {
 			//create user but with different attributes - must fail since user already exists
 			User user = UserManager.getInstance().createUser("klaus", "Meier", "klaus@meier.ch");
-			Identity identity = securityManager.createAndPersistIdentityAndUser("kmeier", user, "LDAP", "kmeier", null);
+			Identity identity = securityManager.createAndPersistIdentityAndUser("kmeier", user, "LDAP", "kmeier");
 			SecurityGroup secGroup = securityManager.findSecurityGroupByName(LDAPConstants.SECURITY_GROUP_LDAP);
 			securityManager.addIdentityToSecurityGroup(identity, secGroup);
 			// simulate closed session (user adding from startup job)
@@ -250,14 +250,14 @@ public class LDAPLoginTest extends OlatTestCase {
 		
 		//create some users in LDAPSecurityGroup
 		User user = UserManager.getInstance().createUser("grollia", "wa", "gorrila@olat.org");
-		Identity identity = securityManager.createAndPersistIdentityAndUser("gorilla", user, "LDAP", "gorrila", null);
+		Identity identity = securityManager.createAndPersistIdentityAndUser("gorilla", user, "LDAP", "gorrila");
 		SecurityGroup secGroup1 = securityManager.findSecurityGroupByName(LDAPConstants.SECURITY_GROUP_LDAP);
 		securityManager.addIdentityToSecurityGroup(identity, secGroup1);
 		user = UserManager.getInstance().createUser("wer", "immer", "immer@olat.org");
-		identity = securityManager.createAndPersistIdentityAndUser("der", user, "LDAP", "der", null);
+		identity = securityManager.createAndPersistIdentityAndUser("der", user, "LDAP", "der");
 		securityManager.addIdentityToSecurityGroup(identity, secGroup1);
 		user = UserManager.getInstance().createUser("die", "da", "chaspi@olat.org");
-		identity = securityManager.createAndPersistIdentityAndUser("das", user, "LDAP", "das", null);
+		identity = securityManager.createAndPersistIdentityAndUser("das", user, "LDAP", "das");
 		securityManager.addIdentityToSecurityGroup(identity, secGroup1);
 		
 		// simulate closed session
@@ -330,11 +330,11 @@ public class LDAPLoginTest extends OlatTestCase {
 
 		//create Users in LDAP Group only existing in OLAT 
 		User user1 = UserManager.getInstance().createUser("hansi", "hürlima", "hansi@hansli.com");
-		Identity identity1 = securityManager.createAndPersistIdentityAndUser("hansi", user1, "LDAP", "hansi", null);
+		Identity identity1 = securityManager.createAndPersistIdentityAndUser("hansi", user1, "LDAP", "hansi");
 		SecurityGroup secGroup1 = securityManager.findSecurityGroupByName(LDAPConstants.SECURITY_GROUP_LDAP);
 		securityManager.addIdentityToSecurityGroup(identity1, secGroup1);
 		user1 = UserManager.getInstance().createUser("chaspi", "meier", "chaspi@hansli.com");
-		identity1 = securityManager.createAndPersistIdentityAndUser("chaspi", user1, "LDAP", "chaspi", null);
+		identity1 = securityManager.createAndPersistIdentityAndUser("chaspi", user1, "LDAP", "chaspi");
 		securityManager.addIdentityToSecurityGroup(identity1, secGroup1);
 
 		//create User to Delete List
diff --git a/src/test/java/org/olat/restapi/UserAuthenticationMgmtTest.java b/src/test/java/org/olat/restapi/UserAuthenticationMgmtTest.java
index 3cb8b5759bb7cb27c3912b8c3c01ef974b2b905a..f204bb3a33685240bb07680b15a6511b6193af67 100644
--- a/src/test/java/org/olat/restapi/UserAuthenticationMgmtTest.java
+++ b/src/test/java/org/olat/restapi/UserAuthenticationMgmtTest.java
@@ -55,6 +55,7 @@ import org.olat.basesecurity.BaseSecurity;
 import org.olat.basesecurity.BaseSecurityManager;
 import org.olat.core.commons.persistence.DBFactory;
 import org.olat.core.id.Identity;
+import org.olat.core.util.Encoder;
 import org.olat.restapi.support.vo.AuthenticationVO;
 import org.olat.test.OlatJerseyTestCase;
 
@@ -155,7 +156,7 @@ public class UserAuthenticationMgmtTest extends OlatJerseyTestCase {
 		//create an authentication token
 		BaseSecurity baseSecurity = BaseSecurityManager.getInstance();
 		Identity adminIdent = baseSecurity.findIdentityByName("administrator");
-		Authentication authentication = baseSecurity.createAndPersistAuthentication(adminIdent, "REST-A-2", "administrator", "credentials");
+		Authentication authentication = baseSecurity.createAndPersistAuthentication(adminIdent, "REST-A-2", "administrator", "credentials", Encoder.Algorithm.sha512);
 		assertTrue(authentication != null && authentication.getKey() != null && authentication.getKey().longValue() > 0);
 		DBFactory.getInstance().intermediateCommit();
 		
diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java
index 56e54c5b1b34d8f19b8d91516c8a747825796e9e..0163194b60c8f52b642c7f25c885bdeb324fa76d 100644
--- a/src/test/java/org/olat/test/AllTestsJunit4.java
+++ b/src/test/java/org/olat/test/AllTestsJunit4.java
@@ -60,6 +60,7 @@ import org.junit.runners.Suite;
 	org.olat.core.util.coordinate.LockEntryTest.class,
 	org.olat.core.util.StringHelperTest.class,
 	org.olat.core.util.FormatterTest.class,
+	org.olat.core.util.EncoderTest.class,
 	org.olat.core.util.mail.manager.MailManagerTest.class,
 	org.olat.core.id.context.BusinessControlFactoryTest.class,
 	org.olat.core.id.context.HistoryManagerTest.class,
@@ -95,6 +96,7 @@ import org.junit.runners.Suite;
 	org.olat.basesecurity.BaseSecurityTest.class,//ok
 	org.olat.basesecurity.BaseSecurityManagerTest.class,//ok
 	org.olat.user.UserManagerTest.class,//ok
+	org.olat.user.UserNameAndPasswordSyntaxCheckerWithRegexpTest.class,//ok
 	org.olat.repository.RepositoryManagerTest.class,//ok
 	org.olat.repository.RepositoryManagerConcurrentTest.class,//ok
 	org.olat.repository.RepositoryManagerQueryTest.class,//ok
diff --git a/src/test/java/org/olat/test/JunitTestHelper.java b/src/test/java/org/olat/test/JunitTestHelper.java
index f3776c42c1c9eee0f5d8503f2dfa704299e8377b..b3ede57d305a089d8c498d985c21bd3d8573a35a 100644
--- a/src/test/java/org/olat/test/JunitTestHelper.java
+++ b/src/test/java/org/olat/test/JunitTestHelper.java
@@ -42,7 +42,6 @@ import org.olat.core.id.OLATResourceable;
 import org.olat.core.id.Roles;
 import org.olat.core.id.User;
 import org.olat.core.util.CodeHelper;
-import org.olat.core.util.Encoder;
 import org.olat.core.util.resource.OresHelper;
 import org.olat.course.CourseFactory;
 import org.olat.course.DeployableCourseExport;
@@ -107,8 +106,7 @@ public class JunitTestHelper {
 		SecurityGroup group = securityManager.findSecurityGroupByName(Constants.GROUP_OLATUSERS);
 		if (group == null) group = securityManager.createAndPersistNamedSecurityGroup(Constants.GROUP_OLATUSERS);
 		User user = UserManager.getInstance().createUser("first" + login, "last" + login, login + "@" + maildomain);
-		identity = securityManager.createAndPersistIdentityAndUser(login, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), login,
-				Encoder.encrypt(PWD));
+		identity = securityManager.createAndPersistIdentityAndUser(login, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), login, PWD);
 		securityManager.addIdentityToSecurityGroup(identity, group);
 		return identity;
 	}
@@ -125,8 +123,7 @@ public class JunitTestHelper {
 		SecurityGroup group = securityManager.findSecurityGroupByName(Constants.GROUP_AUTHORS);
 		if (group == null) group = securityManager.createAndPersistNamedSecurityGroup(Constants.GROUP_AUTHORS);
 		User user = UserManager.getInstance().createUser("first" + login, "last" + login, login + "@" + maildomain);
-		identity = securityManager.createAndPersistIdentityAndUser(login, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), login,
-				Encoder.encrypt(PWD));
+		identity = securityManager.createAndPersistIdentityAndUser(login, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), login, PWD);
 		securityManager.addIdentityToSecurityGroup(identity, group);
 		return identity;
 	}
@@ -143,8 +140,7 @@ public class JunitTestHelper {
 		SecurityGroup group = securityManager.findSecurityGroupByName(Constants.GROUP_ADMIN);
 		if (group == null) group = securityManager.createAndPersistNamedSecurityGroup(Constants.GROUP_ADMIN);
 		User user = UserManager.getInstance().createUser("first" + login, "last" + login, login + "@" + maildomain);
-		identity = securityManager.createAndPersistIdentityAndUser(login, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), login,
-				Encoder.encrypt(PWD));
+		identity = securityManager.createAndPersistIdentityAndUser(login, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), login, PWD);
 		securityManager.addIdentityToSecurityGroup(identity, group);
 		return identity;
 	}
diff --git a/src/test/java/org/olat/test/Selenium2TestsJunit4.java b/src/test/java/org/olat/test/Selenium2TestsJunit4.java
deleted file mode 100644
index 232f4a89706a921b42efcfbf05bbfe35a54aa587..0000000000000000000000000000000000000000
--- a/src/test/java/org/olat/test/Selenium2TestsJunit4.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * <a href="http://www.openolat.org">
- * OpenOLAT - Online Learning and Training</a><br>
- * <p>
- * Licensed under the Apache License, Version 2.0 (the "License"); <br>
- * you may not use this file except in compliance with the License.<br>
- * You may obtain a copy of the License at the
- * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
- * <p>
- * Unless required by applicable law or agreed to in writing,<br>
- * software distributed under the License is distributed on an "AS IS" BASIS, <br>
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
- * See the License for the specific language governing permissions and <br>
- * limitations under the License.
- * <p>
- * Initial code contributed and copyrighted by<br>
- * frentix GmbH, http://www.frentix.com
- * <p>
- */
-package org.olat.test;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-/**
- * Description:<br/>
- * May be deprecated, see pom.xml surefire configuration.
- * 
- * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
- * @author jkraehemann, joel.kraehemann@frentix.com, frentix.com
- */
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
-	org.olat.login.FunctionalLoginTest.class,
-	org.olat.login.FunctionalResumeTest.class,
-	org.olat.portal.FunctionalSettingsTest.class,
-	org.olat.portfolio.FunctionalArtefactTest.class,
-	org.olat.course.FunctionalBackTest.class,
-	org.olat.course.FunctionalCourseTest.class,
-	org.olat.course.nodes.cp.FunctionalCPTest.class,
-	org.olat.course.nodes.feed.FunctionalBlogTest.class,
-	org.olat.course.nodes.feed.FunctionalPodcastTest.class,
-	org.olat.course.nodes.iq.FunctionalIQTestTest.class,
-	org.olat.course.nodes.portfolio.FunctionalPortfolioTest.class,
-	org.olat.course.nodes.wiki.FunctionalWikiTest.class
-})
-public class Selenium2TestsJunit4 {
-	//
-}
\ No newline at end of file
diff --git a/src/test/java/org/olat/user/UserManagerTest.java b/src/test/java/org/olat/user/UserManagerTest.java
index 185861eebee55a4e43576be86198ca76dd5cf859..70a828e06e315027528ebb918b46705c0a38f0a2 100644
--- a/src/test/java/org/olat/user/UserManagerTest.java
+++ b/src/test/java/org/olat/user/UserManagerTest.java
@@ -31,7 +31,6 @@ import org.olat.basesecurity.BaseSecurityModule;
 import org.olat.core.commons.persistence.DB;
 import org.olat.core.id.Identity;
 import org.olat.core.id.User;
-import org.olat.core.util.Encoder;
 import org.olat.test.OlatTestCase;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -57,7 +56,7 @@ public class UserManagerTest extends OlatTestCase {
 		String name = "createid-" + UUID.randomUUID().toString();
 		String email = name + "@frentix.com";
 		User user = userManager.createUser("first" + name, "last" + name, email);
-		Identity identity = securityManager.createAndPersistIdentityAndUser(name, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), name, Encoder.encrypt("secret"));
+		Identity identity = securityManager.createAndPersistIdentityAndUser(name, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), name, "secret");
 		dbInstance.commitAndCloseSession();
 		
 		//get empty (must survive)
diff --git a/src/test/java/org/olat/user/UserNameAndPasswordSyntaxCheckerWithRegexpTest.java b/src/test/java/org/olat/user/UserNameAndPasswordSyntaxCheckerWithRegexpTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..2962496f32d04741715d641e4c1db29c4e4f8388
--- /dev/null
+++ b/src/test/java/org/olat/user/UserNameAndPasswordSyntaxCheckerWithRegexpTest.java
@@ -0,0 +1,45 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.user;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+/**
+ * 
+ * Initial date: 23.08.2013<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class UserNameAndPasswordSyntaxCheckerWithRegexpTest {
+	
+	@Test
+	public void testCustom() {
+		//Min. 7 characters, one uppercase, one lowercase, one number
+		UserNameAndPasswordSyntaxCheckerWithRegexp checker = new UserNameAndPasswordSyntaxCheckerWithRegexp();
+		checker.setPasswordRegExp("(?=^.{7,}$)((?=.*\\d)|(?=.*\\W+))(?![.\\n])(?=.*[A-Z])(?=.*[a-z]).*$");
+		
+		Assert.assertTrue(checker.syntaxCheckOlatPassword("Kanu#01"));
+		Assert.assertTrue(checker.syntaxCheckOlatPassword("Kanuunc1"));
+		Assert.assertFalse(checker.syntaxCheckOlatPassword("Kanu#1"));//less than 7 characters
+		Assert.assertFalse(checker.syntaxCheckOlatPassword("Kanuunch"));//no number
+	}
+}