diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/elements/FlexiTableElement.java b/src/main/java/org/olat/core/gui/components/form/flexible/elements/FlexiTableElement.java
index 928a01f8782d1d6592ba45a2f4cfdb3103bcf7b6..3effb3229dbbf754b054edbf8dbe042b1a2cf953 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/elements/FlexiTableElement.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/elements/FlexiTableElement.java
@@ -159,11 +159,17 @@ public interface FlexiTableElement extends FormItem {
 	public void setSelectAllEnable(boolean enable);
 	
 	/**
-	 * Set all selecteds rows
+	 * Return all selected rows
 	 * @return
 	 */
 	public Set<Integer> getMultiSelectedIndex();
 	
+	/**
+	 * Set a list of selected index (don't sort after this point)
+	 * @param set
+	 */
+	public void setMultiSelectedIndex(Set<Integer> set);
+	
 	/**
 	 * 
 	 * @param index
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/FlexiTableElementImpl.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/FlexiTableElementImpl.java
index 6c39caea27a1e4d979ed857d3132ec730727703b..65d673186829ff23ffe855579389f58d4c550e3d 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/FlexiTableElementImpl.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/FlexiTableElementImpl.java
@@ -1149,6 +1149,14 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 		return multiSelectedIndex == null ? Collections.<Integer>emptySet() : multiSelectedIndex;
 	}
 
+	@Override
+	public void setMultiSelectedIndex(Set<Integer> set) {
+		if(multiSelectedIndex == null) {
+			multiSelectedIndex = new HashSet<Integer>();
+		}
+		multiSelectedIndex.addAll(set);
+	}
+
 	@Override
 	public boolean isMultiSelectedIndex(int index) {
 		return multiSelectedIndex != null && multiSelectedIndex.contains(new Integer(index));
diff --git a/src/main/java/org/olat/course/assessment/AssessedIdentitiesTableDataModel.java b/src/main/java/org/olat/course/assessment/AssessedIdentitiesTableDataModel.java
index 598271d4292a7cd8793b452af768253e36490be4..2c9f1a478949a13e55d211d728c877fa2da568db 100644
--- a/src/main/java/org/olat/course/assessment/AssessedIdentitiesTableDataModel.java
+++ b/src/main/java/org/olat/course/assessment/AssessedIdentitiesTableDataModel.java
@@ -78,7 +78,7 @@ public class AssessedIdentitiesTableDataModel extends DefaultTableDataModel<Asse
 	private List<String> userPropertyNameList;
 	private final boolean isAdministrativeUser;
 	private final List<UserPropertyHandler> userPropertyHandlers;
-	private static final String usageIdentifyer = AssessedIdentitiesTableDataModel.class.getCanonicalName();
+	public static final String usageIdentifyer = AssessedIdentitiesTableDataModel.class.getCanonicalName();
 	private final Translator translator;
 	
 	private Map<Long, CertificateLight> certificates;
diff --git a/src/main/java/org/olat/course/assessment/AssessmentMainController.java b/src/main/java/org/olat/course/assessment/AssessmentMainController.java
index a04d7cfe7278a175cdbb39d05fb2a4b59b2ce4e2..447930a9282625bb59b02b38fc9d8476dbb33eaa 100644
--- a/src/main/java/org/olat/course/assessment/AssessmentMainController.java
+++ b/src/main/java/org/olat/course/assessment/AssessmentMainController.java
@@ -26,7 +26,6 @@
 package org.olat.course.assessment;
 
 import java.util.ArrayList;
-import java.util.BitSet;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
@@ -66,7 +65,6 @@ import org.olat.core.gui.components.table.TableController;
 import org.olat.core.gui.components.table.TableDataModel;
 import org.olat.core.gui.components.table.TableEvent;
 import org.olat.core.gui.components.table.TableGuiConfiguration;
-import org.olat.core.gui.components.table.TableMultiSelectEvent;
 import org.olat.core.gui.components.tree.GenericTreeModel;
 import org.olat.core.gui.components.tree.GenericTreeNode;
 import org.olat.core.gui.components.tree.MenuTree;
@@ -79,8 +77,6 @@ import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.controller.MainLayoutBasicController;
 import org.olat.core.gui.control.generic.dtabs.Activateable2;
 import org.olat.core.gui.control.generic.messages.MessageUIFactory;
-import org.olat.core.gui.control.generic.modal.DialogBoxController;
-import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory;
 import org.olat.core.gui.translator.Translator;
 import org.olat.core.id.Identity;
 import org.olat.core.id.IdentityEnvironment;
@@ -94,7 +90,6 @@ import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.core.logging.activity.ActionType;
 import org.olat.core.util.event.GenericEventListener;
-import org.olat.core.util.mail.MailerResult;
 import org.olat.core.util.resource.OresHelper;
 import org.olat.core.util.tree.TreeHelper;
 import org.olat.course.CourseFactory;
@@ -103,9 +98,8 @@ import org.olat.course.assessment.NodeTableDataModel.Cols;
 import org.olat.course.assessment.bulk.BulkAssessmentOverviewController;
 import org.olat.course.assessment.manager.UserCourseInformationsManager;
 import org.olat.course.certificate.CertificateLight;
-import org.olat.course.certificate.CertificateTemplate;
 import org.olat.course.certificate.CertificatesManager;
-import org.olat.course.certificate.model.CertificateInfos;
+import org.olat.course.certificate.ui.CertificatesWizardController;
 import org.olat.course.condition.Condition;
 import org.olat.course.condition.interpreter.ConditionExpression;
 import org.olat.course.condition.interpreter.OnlyGroupConditionInterpreter;
@@ -119,7 +113,6 @@ import org.olat.course.nodes.ProjectBrokerCourseNode;
 import org.olat.course.nodes.STCourseNode;
 import org.olat.course.properties.CoursePropertyManager;
 import org.olat.course.run.environment.CourseEnvironment;
-import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironmentImpl;
 import org.olat.group.BusinessGroup;
@@ -186,6 +179,7 @@ public class AssessmentMainController extends MainLayoutBasicController implemen
 	// Course assessment notification support fields	
 	private Controller csc;
 	private Controller certificateSubscriptionCtrl;
+	private CertificatesWizardController certificateWizardCtrl;
 	
 	// Hash map to keep references to already created user course environments
 	// Serves as a local cache to reduce database access - not shared by multiple threads
@@ -221,13 +215,13 @@ public class AssessmentMainController extends MainLayoutBasicController implemen
 	private Link showAllCourseNodesButton;
 	private Link filterCourseNodesButton;
 
-	private DialogBoxController confirmCertificateCtrl;
 	private EfficiencyStatementAssessmentController esac;
 	private BulkAssessmentOverviewController bulkAssOverviewCtrl;
 	private final TooledStackedPanel stackPanel;
 
 	private RepositoryEntry re;
 	private OLATResourceable ores;
+	private final boolean hasAssessableNodes;
 	
 	@Autowired
 	private OnyxModule onyxModule;
@@ -273,7 +267,7 @@ public class AssessmentMainController extends MainLayoutBasicController implemen
 		
 		Identity focusOnIdentity = null;
 		ICourse course = CourseFactory.loadCourse(ores);
-		boolean hasAssessableNodes = course.hasAssessableNodes();
+		hasAssessableNodes = course.hasAssessableNodes();
 		boolean hasCertificates = course.getCourseConfig().isAutomaticCertificationEnabled()
 				|| course.getCourseConfig().isManualCertificationEnabled();
 		
@@ -560,27 +554,6 @@ public class AssessmentMainController extends MainLayoutBasicController implemen
 					currentCourseNode = null;
 				}
 				doUserChooseWithData(ureq, identitiesList, currentGroup, currentCourseNode);
-			} else if (event instanceof  TableMultiSelectEvent) {
-				TableMultiSelectEvent tms = (TableMultiSelectEvent)event;
-				BitSet selectedUsers = tms.getSelection();
-				if(selectedUsers.isEmpty()) {
-					showWarning("select.one.user.warning");
-				} else {
-					ICourse course = CourseFactory.loadCourse(ores);
-					CourseNode rootNode = course.getRunStructure().getRootNode();
-					List<CertificateInfos> futureCertififedList = new ArrayList<>();
-					for (int i=selectedUsers.nextSetBit(0); i >= 0; i=selectedUsers.nextSetBit(i+1)) {
-						Object row = userListCtr.getTableDataModel().getObject(i);
-						if(row instanceof AssessedIdentityWrapper) {
-							AssessedIdentityWrapper wrapper = (AssessedIdentityWrapper)row;
-							ScoreEvaluation scoreEval = wrapper.getUserCourseEnvironment().getScoreAccounting().getScoreEvaluation(rootNode);
-							Float score = scoreEval == null ? null : scoreEval.getScore();
-							Boolean passed = scoreEval == null ? null : scoreEval.getPassed();
-							futureCertififedList.add(new CertificateInfos(wrapper.getIdentity(), score, passed));
-						}
-					}
-					doGenerateCertificate(ureq, futureCertififedList);
-				}
 			}
 		}
 		else if (source == nodeListCtr) {
@@ -643,14 +616,13 @@ public class AssessmentMainController extends MainLayoutBasicController implemen
 			if (event.equals(Event.CANCELLED_EVENT)) {
 				setContent(userChoose);
 			}
-		} else if(source == confirmCertificateCtrl) {
-			if(DialogBoxUIFactory.isYesEvent(event)) {
-				@SuppressWarnings("unchecked")
-				List<CertificateInfos> assessedIdentitiesInfos = (List<CertificateInfos>)confirmCertificateCtrl.getUserObject();
-				doGenerateCertificates(assessedIdentitiesInfos);
-				Map<Long, CertificateLight> certificates = getCertificates(CourseFactory.loadCourse(ores));
-				((AssessedIdentitiesTableDataModel)userListCtr.getTableDataModel()).setCertificates(certificates);
-				userListCtr.modelChanged();
+		} else if(source == certificateWizardCtrl) {
+			if(event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) {
+				if(userListCtr != null) {
+					Map<Long, CertificateLight> certificates = getCertificates(CourseFactory.loadCourse(ores));
+					((AssessedIdentitiesTableDataModel)userListCtr.getTableDataModel()).setCertificates(certificates);
+					userListCtr.modelChanged();
+				}
 			}
 		}
 	}
@@ -920,6 +892,7 @@ public class AssessmentMainController extends MainLayoutBasicController implemen
 		tdm.addColumnDescriptors(userListCtr, CMD_CHOOSE_USER, mode == MODE_NODEFOCUS || mode == MODE_GROUPFOCUS || mode == MODE_USERFOCUS, showCertificate);
 		userListCtr.setTableDataModel(tdm);
 		
+		int count = 0;
 		List<String> toolCmpNames = new ArrayList<>(3);
 		if(courseNode != null) {
 			CourseEnvironment courseEnv = course.getCourseEnvironment();
@@ -931,7 +904,7 @@ public class AssessmentMainController extends MainLayoutBasicController implemen
 				options.setGroup(group);
 			}
 			List<Controller> tools = courseNode.createAssessmentTools(ureq, getWindowControl(), stackPanel, courseEnv, options);
-			int count = 0;
+			
 			for(Controller tool:tools) {
 				listenTo(tool);
 				String toolCmpName = "ctrl_" + (count++);
@@ -944,8 +917,13 @@ public class AssessmentMainController extends MainLayoutBasicController implemen
 		}
 		if(courseConfig.isManualCertificationEnabled()) {
 			if(courseNode == null || courseNode == course.getRunStructure().getRootNode()) {
-				userListCtr.addMultiSelectAction("create.certificate", "create.certificate");
-				userListCtr.setMultiSelect(true);
+				removeAsListenerAndDispose(certificateWizardCtrl);
+				certificateWizardCtrl = new CertificatesWizardController(ureq, getWindowControl(), tdm, ores, hasAssessableNodes);
+				listenTo(certificateWizardCtrl);
+
+				String toolCmpName = "ctrl_" + (count++);
+				userChoose.put(toolCmpName, certificateWizardCtrl.getInitialComponent());
+				toolCmpNames.add(toolCmpName);
 			}
 		}
 		userChoose.contextPut("toolCmpNames", toolCmpNames);
@@ -1074,52 +1052,6 @@ public class AssessmentMainController extends MainLayoutBasicController implemen
 		listenTo(esac);
 		main.setContent(esac.getInitialComponent());
 	}
-	
-	private void doGenerateCertificates(List<CertificateInfos> assessedIdentitiesInfos) {
-		ICourse course = CourseFactory.loadCourse(ores);
-		RepositoryEntry resource = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
-		Long templateKey = course.getCourseConfig().getCertificateTemplate();
-		CertificateTemplate template = null;
-		if(templateKey != null) {
-			template = certificatesManager.getTemplateById(templateKey);
-		}
-		
-		MailerResult result = new MailerResult();
-		certificatesManager.generateCertificates(assessedIdentitiesInfos, resource, template, result);
-	}
-	
-	private void doGenerateCertificate(UserRequest ureq, List<CertificateInfos> assessedIdentitiesInfos) {
-		StringBuilder sb = new StringBuilder();
-		for(CertificateInfos infos:assessedIdentitiesInfos) {
-			String name = userManager.getUserDisplayName(infos.getAssessedIdentity());
-			if(sb.length() > 0) sb.append(", ");
-			sb.append(name);
-		}
-		
-		boolean recertificationAllowed = true;
-		StringBuilder sbConfirm = new StringBuilder();
-		ICourse course = CourseFactory.loadCourse(ores);
-		RepositoryEntry resource = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
-		for(CertificateInfos infos:assessedIdentitiesInfos) {
-			boolean allowed = certificatesManager.isRecertificationAllowed(infos.getAssessedIdentity(), resource);
-			recertificationAllowed &= allowed;
-			if(!allowed) {
-				String name = userManager.getUserDisplayName(infos.getAssessedIdentity());
-				if(sbConfirm.length() > 0) sbConfirm.append(", ");
-				sbConfirm.append(name);
-			}
-		}
-		
-		String title = translate("confirm.certificate.title");
-		String text;
-		if(recertificationAllowed) {
-			text = translate("confirm.certificate.description", new String[]{ sb.toString() });
-		} else {
-			text = translate("confirm.certificate.description.warning", new String[]{ sb.toString(), sbConfirm.toString() });
-		}
-		confirmCertificateCtrl = activateYesNoDialog(ureq, title, text, confirmCertificateCtrl);
-		confirmCertificateCtrl.setUserObject(assessedIdentitiesInfos);
-	}
 
 	/**
 	 * Recursive method that adds assessable nodes and all its parents to a list
diff --git a/src/main/java/org/olat/course/certificate/manager/CertificatesManagerImpl.java b/src/main/java/org/olat/course/certificate/manager/CertificatesManagerImpl.java
index 0d5b88187ff1dc57487100e964731e32f6ac6d1a..8df555be92f0a505c08b78b8bfd9507ec90dceec 100644
--- a/src/main/java/org/olat/course/certificate/manager/CertificatesManagerImpl.java
+++ b/src/main/java/org/olat/course/certificate/manager/CertificatesManagerImpl.java
@@ -432,8 +432,7 @@ public class CertificatesManagerImpl implements CertificatesManager, Initializin
 			}
 			
 			dbInstance.getCurrentEntityManager().persist(certificate);
-			
-			
+
 			MailerResult newResult = sendCertificate(identity, entry, certificateFile);
 			if(result != null) {
 				result.append(newResult);
diff --git a/src/main/java/org/olat/course/certificate/ui/AssessedIdentityCertificatesController.java b/src/main/java/org/olat/course/certificate/ui/AssessedIdentityCertificatesController.java
index 9e75a7d3cd208387e86a393fc061cdbd9c2922aa..9fc8945d33ee6b3e03da80c45101b4ace6e77566 100644
--- a/src/main/java/org/olat/course/certificate/ui/AssessedIdentityCertificatesController.java
+++ b/src/main/java/org/olat/course/certificate/ui/AssessedIdentityCertificatesController.java
@@ -135,8 +135,8 @@ public class AssessedIdentityCertificatesController extends BasicController {
 
 	private void doDownload(UserRequest ureq, Certificate certificate) {
 		VFSLeaf certificateLeaf = certificatesManager.getCertificateLeaf(certificate);
-		MediaResource resource = new VFSMediaResource(certificateLeaf);
-		ureq.getDispatchResult().setResultingMediaResource(resource);
+		MediaResource certificateResource = new VFSMediaResource(certificateLeaf);
+		ureq.getDispatchResult().setResultingMediaResource(certificateResource);
 	}
 	
 	private void doConfirmGenerateCertificate(UserRequest ureq) {
diff --git a/src/main/java/org/olat/course/certificate/ui/CertificateAndEfficiencyStatementController.java b/src/main/java/org/olat/course/certificate/ui/CertificateAndEfficiencyStatementController.java
index 5a669b7584f3fb3cf114fb073f80cf0bbf7d2930..cf4d9ae17234aed11fbf07e3dee722148e688e92 100644
--- a/src/main/java/org/olat/course/certificate/ui/CertificateAndEfficiencyStatementController.java
+++ b/src/main/java/org/olat/course/certificate/ui/CertificateAndEfficiencyStatementController.java
@@ -157,7 +157,7 @@ public class CertificateAndEfficiencyStatementController extends BasicController
 		certificate = certificatesManager.getLastCertificate(statementOwner, resourceKey);
 		
 		mainVC = createVelocityContainer("certificate_efficiencystatement");
-		populateAssessedIdentityInfos(ureq, statementOwner, courseRepo, businessGroup, links);
+		populateAssessedIdentityInfos(ureq, courseRepo, businessGroup, links);
 		
 		if(efficiencyStatement != null && certificate != null) {
 			segmentView = SegmentViewFactory.createSegmentView("segments", mainVC, this);
@@ -195,7 +195,7 @@ public class CertificateAndEfficiencyStatementController extends BasicController
 		//
 	}
 
-	private void populateAssessedIdentityInfos(UserRequest ureq, Identity statementOwner, RepositoryEntry courseRepo, BusinessGroup group, boolean links) { 
+	private void populateAssessedIdentityInfos(UserRequest ureq, RepositoryEntry courseRepo, BusinessGroup group, boolean links) { 
 		if(efficiencyStatement != null) {
 			mainVC.contextPut("courseTitle", StringHelper.escapeHtml(efficiencyStatement.getCourseTitle()));
 			mainVC.contextPut("date", StringHelper.formatLocaleDateTime(efficiencyStatement.getLastUpdated(), ureq.getLocale()));
diff --git a/src/main/java/org/olat/course/certificate/ui/CertificatesSelectionController.java b/src/main/java/org/olat/course/certificate/ui/CertificatesSelectionController.java
new file mode 100644
index 0000000000000000000000000000000000000000..23ecc6e314d193f180920239f45aaff651e35f8c
--- /dev/null
+++ b/src/main/java/org/olat/course/certificate/ui/CertificatesSelectionController.java
@@ -0,0 +1,164 @@
+/**
+ * <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.course.certificate.ui;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.olat.basesecurity.BaseSecurityModule;
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.form.flexible.FormItemContainer;
+import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement;
+import org.olat.core.gui.components.form.flexible.impl.Form;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory;
+import org.olat.core.gui.control.Controller;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.core.gui.control.generic.wizard.StepFormBasicController;
+import org.olat.core.gui.control.generic.wizard.StepsEvent;
+import org.olat.core.gui.control.generic.wizard.StepsRunContext;
+import org.olat.core.id.Identity;
+import org.olat.core.id.OLATResourceable;
+import org.olat.core.id.Roles;
+import org.olat.core.util.Util;
+import org.olat.course.CourseFactory;
+import org.olat.course.ICourse;
+import org.olat.course.assessment.AssessedIdentitiesTableDataModel;
+import org.olat.course.assessment.AssessedIdentityWrapper;
+import org.olat.course.assessment.AssessmentMainController;
+import org.olat.course.assessment.bulk.PassedCellRenderer;
+import org.olat.course.certificate.model.CertificateInfos;
+import org.olat.course.nodes.CourseNode;
+import org.olat.course.run.scoring.ScoreEvaluation;
+import org.olat.user.UserManager;
+import org.olat.user.propertyhandlers.UserPropertyHandler;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * 
+ * Initial date: 28.10.2014<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class CertificatesSelectionController extends StepFormBasicController {
+	
+	private FlexiTableElement tableEl;
+	private CertificatesSelectionDataModel tableModel;
+	
+	private final boolean hasAssessableNodes;
+	private final OLATResourceable courseOres;
+	private final boolean isAdministrativeUser;
+	private final List<AssessedIdentityWrapper> datas;
+	
+	@Autowired
+	private UserManager userManager;
+	@Autowired
+	private BaseSecurityModule securityModule;
+	
+	public CertificatesSelectionController(UserRequest ureq, WindowControl wControl,
+			Form rootForm, StepsRunContext runContext, OLATResourceable courseOres,
+			List<AssessedIdentityWrapper> datas, boolean hasAssessableNodes) {
+		super(ureq, wControl, rootForm, runContext, LAYOUT_BAREBONE, null);
+		setTranslator(Util.createPackageTranslator(UserPropertyHandler.class, getLocale(), getTranslator()));
+		setTranslator(Util.createPackageTranslator(AssessmentMainController.class, getLocale(), getTranslator()));
+		
+		this.datas = datas;
+		this.courseOres = courseOres;
+		this.hasAssessableNodes = hasAssessableNodes;
+		Roles roles = ureq.getUserSession().getRoles();
+		isAdministrativeUser = securityModule.isUserAllowedAdminProps(roles);
+		
+		initForm(ureq);
+	}
+	
+	@Override
+	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		
+		FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();;
+		int colPos = 0;
+		if(isAdministrativeUser) {
+			columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("table.header.name", CertificatesSelectionDataModel.USERNAME_COL));
+		}
+		
+		List<UserPropertyHandler> userPropertyHandlers = userManager.getUserPropertyHandlersFor(AssessedIdentitiesTableDataModel.usageIdentifyer, isAdministrativeUser);
+		List<UserPropertyHandler> resultingPropertyHandlers = new ArrayList<UserPropertyHandler>();
+		// followed by the users fields
+		for (int i = 0; i < userPropertyHandlers.size(); i++) {
+			UserPropertyHandler userPropertyHandler	= userPropertyHandlers.get(i);
+			boolean visible = userManager.isMandatoryUserProperty(AssessedIdentitiesTableDataModel.usageIdentifyer , userPropertyHandler);
+			if(visible) {
+				resultingPropertyHandlers.add(userPropertyHandler);
+				columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(userPropertyHandler.i18nColumnDescriptorLabelKey(), colPos++));
+			}
+		}
+		
+		if(hasAssessableNodes) {
+			columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("table.header.passed", CertificatesSelectionDataModel.PASSED_COL, new PassedCellRenderer()));
+			columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("table.header.score", CertificatesSelectionDataModel.SCORE_COL));
+		}
+		
+		tableModel = new CertificatesSelectionDataModel(columnsModel, resultingPropertyHandlers);
+
+		Set<Integer> preselectedRows = new HashSet<>();
+		ICourse course = CourseFactory.loadCourse(courseOres);
+		CourseNode rootNode = course.getRunStructure().getRootNode();
+		List<CertificateInfos> infos = new ArrayList<CertificateInfos>(datas.size());
+		
+		int count = 0;
+		for(AssessedIdentityWrapper data:datas) {
+			ScoreEvaluation scoreEval = data.getUserCourseEnvironment().getScoreAccounting().getScoreEvaluation(rootNode);
+			Float score = scoreEval == null ? null : scoreEval.getScore();
+			Boolean passed = scoreEval == null ? null : scoreEval.getPassed();
+			Identity assessedIdentity = data.getIdentity();
+			infos.add(new CertificateInfos(assessedIdentity, score, passed));
+			if(passed != null && passed.booleanValue()) {
+				preselectedRows.add(new Integer(count));
+			}
+			count++;
+		}
+		tableModel.setObjects(infos);
+
+		tableEl = uifactory.addTableElement(getWindowControl(), "selection", tableModel, formLayout);
+		tableEl.setMultiSelect(true);
+		tableEl.setSelectAllEnable(true);
+		tableEl.setMultiSelectedIndex(preselectedRows);
+	}
+
+	@Override
+	protected void doDispose() {
+		//
+	}
+
+	@Override
+	protected void formOK(UserRequest ureq) {
+		if(tableEl.getMultiSelectedIndex().size() > 0) {
+			Set<Integer> selectedRows = tableEl.getMultiSelectedIndex();
+			List<CertificateInfos> selectedInfos = new ArrayList<>(selectedRows.size());
+			for(Integer selectedRow:selectedRows) {
+				selectedInfos.add(tableModel.getObject(selectedRow.intValue()));
+			}
+			addToRunContext("infos", selectedInfos);
+			fireEvent(ureq, StepsEvent.ACTIVATE_NEXT);
+		}
+	}
+}
diff --git a/src/main/java/org/olat/course/certificate/ui/CertificatesSelectionDataModel.java b/src/main/java/org/olat/course/certificate/ui/CertificatesSelectionDataModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..3ed28b5994d0d420ff7a7e0b67b76c25b3e16a08
--- /dev/null
+++ b/src/main/java/org/olat/course/certificate/ui/CertificatesSelectionDataModel.java
@@ -0,0 +1,72 @@
+/**
+ * <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.course.certificate.ui;
+
+import java.util.List;
+
+import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiTableDataModel;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
+import org.olat.core.id.Identity;
+import org.olat.course.assessment.AssessmentHelper;
+import org.olat.course.certificate.model.CertificateInfos;
+import org.olat.user.propertyhandlers.UserPropertyHandler;
+
+/**
+ * 
+ * Initial date: 28.10.2014<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class CertificatesSelectionDataModel extends DefaultFlexiTableDataModel<CertificateInfos> {
+	
+	protected static final int USERNAME_COL = 10000;
+	protected static final int PASSED_COL = 10001;
+	protected static final int SCORE_COL = 10002;
+	
+	private List<UserPropertyHandler> userPropertyHandlers;
+	
+	public CertificatesSelectionDataModel(FlexiTableColumnModel columnModel, List<UserPropertyHandler> userPropertyHandlers) {
+		super(columnModel);
+		this.userPropertyHandlers = userPropertyHandlers;
+	}
+
+	@Override
+	public CertificatesSelectionDataModel createCopyWithEmptyList() {
+		return new CertificatesSelectionDataModel(getTableColumnModel(), userPropertyHandlers);
+	}
+
+	@Override
+	public Object getValueAt(int row, int col) {
+		CertificateInfos infos = getObject(row);
+		Identity identity = infos.getAssessedIdentity();
+		if(col == USERNAME_COL) {
+			return identity.getName();
+		} else if(col == PASSED_COL) {
+			return infos.getPassed();
+		} else if(col == SCORE_COL) {
+			Float score = infos.getScore();
+			return AssessmentHelper.getRoundedScore(score);
+		} else if(col >= 0 && col < userPropertyHandlers.size()) {
+			UserPropertyHandler handler = userPropertyHandlers.get(col);
+			return handler.getUserProperty(identity.getUser(), null);
+		}
+		return null;
+	}
+}
diff --git a/src/main/java/org/olat/course/certificate/ui/CertificatesSelectionOverviewController.java b/src/main/java/org/olat/course/certificate/ui/CertificatesSelectionOverviewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..cf3a89b35b516924369cc65d917367a3cce3b5a1
--- /dev/null
+++ b/src/main/java/org/olat/course/certificate/ui/CertificatesSelectionOverviewController.java
@@ -0,0 +1,119 @@
+/**
+ * <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.course.certificate.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.olat.basesecurity.BaseSecurityModule;
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.form.flexible.FormItemContainer;
+import org.olat.core.gui.components.form.flexible.impl.Form;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory;
+import org.olat.core.gui.control.Controller;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.core.gui.control.generic.wizard.StepFormBasicController;
+import org.olat.core.gui.control.generic.wizard.StepsEvent;
+import org.olat.core.gui.control.generic.wizard.StepsRunContext;
+import org.olat.core.id.Roles;
+import org.olat.core.util.Util;
+import org.olat.course.assessment.AssessedIdentitiesTableDataModel;
+import org.olat.course.assessment.AssessmentMainController;
+import org.olat.course.assessment.bulk.PassedCellRenderer;
+import org.olat.course.certificate.model.CertificateInfos;
+import org.olat.user.UserManager;
+import org.olat.user.propertyhandlers.UserPropertyHandler;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * 
+ * Initial date: 28.10.2014<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class CertificatesSelectionOverviewController extends StepFormBasicController {
+	
+	private CertificatesSelectionDataModel tableModel;
+	
+	private final boolean hasAssessableNodes;
+	private final boolean isAdministrativeUser;
+	
+	@Autowired
+	private UserManager userManager;
+	@Autowired
+	private BaseSecurityModule securityModule;
+	
+	public CertificatesSelectionOverviewController(UserRequest ureq, WindowControl wControl, Form rootForm,
+			StepsRunContext runContext, boolean hasAssessableNodes) {
+		super(ureq, wControl, rootForm, runContext, LAYOUT_BAREBONE, null);
+		setTranslator(Util.createPackageTranslator(UserPropertyHandler.class, getLocale(), getTranslator()));
+		setTranslator(Util.createPackageTranslator(AssessmentMainController.class, getLocale(), getTranslator()));
+		
+		Roles roles = ureq.getUserSession().getRoles();
+		isAdministrativeUser = securityModule.isUserAllowedAdminProps(roles);
+		this.hasAssessableNodes = hasAssessableNodes;
+		
+		initForm(ureq);
+	}
+	
+	@Override
+	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();;
+		int colPos = 0;
+		if(isAdministrativeUser) {
+			columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("table.header.name", CertificatesSelectionDataModel.USERNAME_COL));
+		}
+		
+		List<UserPropertyHandler> userPropertyHandlers = userManager.getUserPropertyHandlersFor(AssessedIdentitiesTableDataModel.usageIdentifyer, isAdministrativeUser);
+		List<UserPropertyHandler> resultingPropertyHandlers = new ArrayList<UserPropertyHandler>();
+		// followed by the users fields
+		for (int i = 0; i < userPropertyHandlers.size(); i++) {
+			UserPropertyHandler userPropertyHandler	= userPropertyHandlers.get(i);
+			boolean visible = userManager.isMandatoryUserProperty(AssessedIdentitiesTableDataModel.usageIdentifyer , userPropertyHandler);
+			if(visible) {
+				resultingPropertyHandlers.add(userPropertyHandler);
+				columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(userPropertyHandler.i18nColumnDescriptorLabelKey(), colPos++));
+			}
+		}
+		
+		if(hasAssessableNodes) {
+			columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("table.header.passed", CertificatesSelectionDataModel.PASSED_COL, new PassedCellRenderer()));
+			columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("table.header.score", CertificatesSelectionDataModel.SCORE_COL));
+		}
+		
+		tableModel = new CertificatesSelectionDataModel(columnsModel, resultingPropertyHandlers);
+		@SuppressWarnings("unchecked")
+		List<CertificateInfos> selectedInfos =  (List<CertificateInfos>)getFromRunContext("infos");
+		tableModel.setObjects(selectedInfos);
+		uifactory.addTableElement(getWindowControl(), "selection", tableModel, formLayout);
+	}
+
+	@Override
+	protected void doDispose() {
+		//
+	}
+
+	@Override
+	protected void formOK(UserRequest ureq) {
+		fireEvent(ureq, StepsEvent.INFORM_FINISHED);
+	}
+}
diff --git a/src/main/java/org/olat/course/certificate/ui/CertificatesWizardController.java b/src/main/java/org/olat/course/certificate/ui/CertificatesWizardController.java
new file mode 100644
index 0000000000000000000000000000000000000000..d001da4e50dea72070b703c62364321d6f862ded
--- /dev/null
+++ b/src/main/java/org/olat/course/certificate/ui/CertificatesWizardController.java
@@ -0,0 +1,141 @@
+/**
+ * <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.course.certificate.ui;
+
+import java.util.List;
+
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.Component;
+import org.olat.core.gui.components.link.Link;
+import org.olat.core.gui.components.link.LinkFactory;
+import org.olat.core.gui.control.Controller;
+import org.olat.core.gui.control.Event;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.core.gui.control.controller.BasicController;
+import org.olat.core.gui.control.generic.wizard.Step;
+import org.olat.core.gui.control.generic.wizard.StepRunnerCallback;
+import org.olat.core.gui.control.generic.wizard.StepsMainRunController;
+import org.olat.core.gui.control.generic.wizard.StepsRunContext;
+import org.olat.core.id.OLATResourceable;
+import org.olat.core.util.mail.MailerResult;
+import org.olat.course.CourseFactory;
+import org.olat.course.ICourse;
+import org.olat.course.assessment.AssessedIdentitiesTableDataModel;
+import org.olat.course.assessment.AssessedIdentityWrapper;
+import org.olat.course.certificate.CertificateTemplate;
+import org.olat.course.certificate.CertificatesManager;
+import org.olat.course.certificate.model.CertificateInfos;
+import org.olat.repository.RepositoryEntry;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * 
+ * Initial date: 28.10.2014<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class CertificatesWizardController extends BasicController {
+	
+	private Link startButton;
+	private StepsMainRunController wizardCtrl;
+	
+	private final boolean hasAssessableNodes;
+	private final OLATResourceable courseOres;
+	private final AssessedIdentitiesTableDataModel dataModel;
+	
+	@Autowired
+	private CertificatesManager certificatesManager;
+	
+	public CertificatesWizardController(UserRequest ureq, WindowControl wControl,
+			AssessedIdentitiesTableDataModel dataModel, OLATResourceable courseOres, boolean hasAssessableNodes) {
+		super(ureq, wControl);
+		
+		this.dataModel = dataModel;
+		this.courseOres = courseOres;
+		this.hasAssessableNodes = hasAssessableNodes;
+		
+		startButton = LinkFactory.createButton("generate.certificate", null, this);
+		startButton.setTranslator(getTranslator());
+		putInitialPanel(startButton);
+		getInitialComponent().setSpanAsDomReplaceable(true);
+	}
+	
+	@Override
+	protected void doDispose() {
+		//
+	}
+
+	@Override
+	protected void event(UserRequest ureq, Component source, Event event) {
+		if(startButton == source) {
+			doStartWizard(ureq);
+		}
+	}
+	
+	@Override
+	protected void event(UserRequest ureq, Controller source, Event event) {
+		if(wizardCtrl == source) {
+			if(event == Event.CANCELLED_EVENT || event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) {
+				getWindowControl().pop();
+				removeAsListenerAndDispose(wizardCtrl);
+				wizardCtrl = null;
+				if(event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) {
+					fireEvent(ureq, Event.DONE_EVENT);
+				}
+			}
+		}
+		super.event(ureq, source, event);
+	}
+
+	private void doStartWizard(UserRequest ureq) {
+		List<AssessedIdentityWrapper> datas = dataModel.getObjects();
+		Certificates_1_SelectionStep start = new Certificates_1_SelectionStep(ureq, courseOres, datas, hasAssessableNodes);
+		StepRunnerCallback finish = new StepRunnerCallback() {
+			@Override
+			public Step execute(UserRequest ureq, WindowControl wControl, StepsRunContext runContext) {
+				@SuppressWarnings("unchecked")
+				List<CertificateInfos> assessedIdentitiesInfos = (List<CertificateInfos>)runContext.get("infos");
+				if(assessedIdentitiesInfos != null && assessedIdentitiesInfos.size() > 0) {
+					doGenerateCertificates(assessedIdentitiesInfos);
+					return StepsMainRunController.DONE_MODIFIED;
+				}
+				return StepsMainRunController.DONE_UNCHANGED;
+			}
+		};
+		
+		wizardCtrl = new StepsMainRunController(ureq, getWindowControl(), start, finish, null,
+				translate("certificates.wizard.title"), "o_sel_certificates_wizard");
+		listenTo(wizardCtrl);
+		getWindowControl().pushAsModalDialog(wizardCtrl.getInitialComponent());
+	}
+	
+	private void doGenerateCertificates(List<CertificateInfos> assessedIdentitiesInfos) {
+		ICourse course = CourseFactory.loadCourse(courseOres);
+		RepositoryEntry resource = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
+		Long templateKey = course.getCourseConfig().getCertificateTemplate();
+		CertificateTemplate template = null;
+		if(templateKey != null) {
+			template = certificatesManager.getTemplateById(templateKey);
+		}
+		
+		MailerResult result = new MailerResult();
+		certificatesManager.generateCertificates(assessedIdentitiesInfos, resource, template, result);
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/certificate/ui/Certificates_1_SelectionStep.java b/src/main/java/org/olat/course/certificate/ui/Certificates_1_SelectionStep.java
new file mode 100644
index 0000000000000000000000000000000000000000..b86d040922fdf938b6f78263f4920185e4f98c10
--- /dev/null
+++ b/src/main/java/org/olat/course/certificate/ui/Certificates_1_SelectionStep.java
@@ -0,0 +1,67 @@
+/**
+ * <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.course.certificate.ui;
+
+import java.util.List;
+
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.form.flexible.impl.Form;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.core.gui.control.generic.wizard.BasicStep;
+import org.olat.core.gui.control.generic.wizard.PrevNextFinishConfig;
+import org.olat.core.gui.control.generic.wizard.StepFormController;
+import org.olat.core.gui.control.generic.wizard.StepsRunContext;
+import org.olat.core.id.OLATResourceable;
+import org.olat.course.assessment.AssessedIdentityWrapper;
+
+/**
+ * 
+ * Initial date: 28.10.2014<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class Certificates_1_SelectionStep extends BasicStep {
+	
+	private final boolean hasAssessableNodes;
+	private final OLATResourceable courseOres;
+	private final List<AssessedIdentityWrapper> datas;
+	
+	public Certificates_1_SelectionStep(UserRequest ureq, OLATResourceable courseOres,
+			List<AssessedIdentityWrapper> datas, boolean hasAssessableNodes) {
+		super(ureq);
+		this.datas = datas;
+		this.courseOres = courseOres;
+		this.hasAssessableNodes = hasAssessableNodes;
+		setNextStep(new Certificates_2_OverviewStep(ureq, hasAssessableNodes));
+		setI18nTitleAndDescr("certificates.wizard.select", "certificates.wizard.select");
+	}
+
+	@Override
+	public PrevNextFinishConfig getInitialPrevNextFinishConfig() {
+		return new PrevNextFinishConfig(false, true, false);
+	}
+
+	@Override
+	public StepFormController getStepController(UserRequest ureq, WindowControl wControl, StepsRunContext runContext, Form form) {
+		CertificatesSelectionController selectCtrl = new CertificatesSelectionController(ureq, wControl, form, runContext,
+				courseOres, datas, hasAssessableNodes);
+		return selectCtrl;
+	}
+}
diff --git a/src/main/java/org/olat/course/certificate/ui/Certificates_2_OverviewStep.java b/src/main/java/org/olat/course/certificate/ui/Certificates_2_OverviewStep.java
new file mode 100644
index 0000000000000000000000000000000000000000..df042fd4231d7c9df8b4c621f5131ff58b8e869b
--- /dev/null
+++ b/src/main/java/org/olat/course/certificate/ui/Certificates_2_OverviewStep.java
@@ -0,0 +1,58 @@
+/**
+ * <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.course.certificate.ui;
+
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.form.flexible.impl.Form;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.core.gui.control.generic.wizard.BasicStep;
+import org.olat.core.gui.control.generic.wizard.PrevNextFinishConfig;
+import org.olat.core.gui.control.generic.wizard.StepFormController;
+import org.olat.core.gui.control.generic.wizard.StepsRunContext;
+
+/**
+ * 
+ * Initial date: 28.10.2014<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class Certificates_2_OverviewStep extends BasicStep {
+	
+	private final boolean hasAssessableNodes;
+	
+	public Certificates_2_OverviewStep(UserRequest ureq, boolean hasAssessableNodes) {
+		super(ureq);
+		this.hasAssessableNodes = hasAssessableNodes;
+		setNextStep(NOSTEP);
+		setI18nTitleAndDescr("certificates.wizard.overview", "certificates.wizard.overview");
+	}
+
+	@Override
+	public PrevNextFinishConfig getInitialPrevNextFinishConfig() {
+		return new PrevNextFinishConfig(true, false, true);
+	}
+
+	@Override
+	public StepFormController getStepController(UserRequest ureq, WindowControl wControl, StepsRunContext runContext, Form form) {
+		CertificatesSelectionOverviewController overviewCtrl
+			= new CertificatesSelectionOverviewController(ureq, wControl, form, runContext, hasAssessableNodes);
+		return overviewCtrl;
+	}
+}
diff --git a/src/main/java/org/olat/course/certificate/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/certificate/ui/_i18n/LocalStrings_de.properties
index 82f20e3b6cabd26bfdedc5cf3f493a8ef11f9704..28c494b7db5f68f1af62a0236765ac59aed450fb 100644
--- a/src/main/java/org/olat/course/certificate/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/course/certificate/ui/_i18n/LocalStrings_de.properties
@@ -37,3 +37,6 @@ certification.email.subject=Sie haben eine neue Zertifikat erhalten
 certification.email.body=Gratueliere!\n\nSie haben eine neue Zertifikat erhalten.\nAls Anhang der Zertifikat von Kurs: "{0}".
 confirm.certificate.title=Zertifikat erstellen
 confirm.certificate.text=Ein Zertifikat wurde schon erstellt und den Period für Rezertifikation ist noch nicht abgelaufen. Wollen Sie trotzdem ein neues Zertifikat erstellen?
+certificates.wizard.title=Zertifikaten erstellen
+certificates.wizard.select=Benutzer auswählen
+certificates.wizard.overview=Ubersicht
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/coach/ui/CourseController.java b/src/main/java/org/olat/modules/coach/ui/CourseController.java
index b86e04ce48e42a96641b74994791321c9fc08ef7..bb732d2bc72d9cd725ac8b3cdc6a0bad09f834cb 100644
--- a/src/main/java/org/olat/modules/coach/ui/CourseController.java
+++ b/src/main/java/org/olat/modules/coach/ui/CourseController.java
@@ -320,7 +320,7 @@ public class CourseController extends BasicController implements Activateable2 {
 
 		OLATResourceable ores = OresHelper.createOLATResourceableInstance(Identity.class, entry.getStudentKey());
 		WindowControl bwControl = addToHistory(ureq, ores, null);
-		statementCtrl = new EfficiencyStatementDetailsController(ureq, bwControl, entry, null);
+		statementCtrl = new EfficiencyStatementDetailsController(ureq, bwControl, entry);
 		listenTo(statementCtrl);
 		mainVC.put("efficiencyDetails", statementCtrl.getInitialComponent());
 		
diff --git a/src/main/java/org/olat/modules/coach/ui/EfficiencyStatementDetailsController.java b/src/main/java/org/olat/modules/coach/ui/EfficiencyStatementDetailsController.java
index 395f0ecee267144e64cc731bc27ad3fc7f0303ef..586ccd980c3f86db427eb98db15240e4985713a2 100644
--- a/src/main/java/org/olat/modules/coach/ui/EfficiencyStatementDetailsController.java
+++ b/src/main/java/org/olat/modules/coach/ui/EfficiencyStatementDetailsController.java
@@ -47,7 +47,6 @@ import org.olat.course.assessment.EfficiencyStatementManager;
 import org.olat.course.assessment.IdentityAssessmentEditController;
 import org.olat.course.assessment.UserEfficiencyStatement;
 import org.olat.course.certificate.ui.CertificateAndEfficiencyStatementController;
-import org.olat.group.BusinessGroup;
 import org.olat.modules.coach.model.EfficiencyStatementEntry;
 import org.olat.repository.RepositoryEntry;
 
@@ -73,19 +72,17 @@ public class EfficiencyStatementDetailsController extends BasicController implem
 	
 	private final Identity assessedIdentity;
 	
-	private final BusinessGroup group;
 	private final BaseSecurity securityManager;
 	private final EfficiencyStatementManager efficiencyStatementManager;
 	
 	public EfficiencyStatementDetailsController(UserRequest ureq, WindowControl wControl,
-			EfficiencyStatementEntry statementEntry, BusinessGroup group) {
+			EfficiencyStatementEntry statementEntry) {
 		super(ureq, wControl);
 		
 		efficiencyStatementManager = EfficiencyStatementManager.getInstance();
 		securityManager = CoreSpringFactory.getImpl(BaseSecurity.class);
 
 		mainVC = createVelocityContainer("efficiency_details");
-		this.group = group;
 		this.statementEntry = statementEntry;
 
 		segmentView = SegmentViewFactory.createSegmentView("segments", mainVC, this);
diff --git a/src/main/java/org/olat/modules/coach/ui/GroupController.java b/src/main/java/org/olat/modules/coach/ui/GroupController.java
index 051d73920850f960a36846eb222334ae57cabc47..603837b2a74066f26b26239355f91c1e82adcf2a 100644
--- a/src/main/java/org/olat/modules/coach/ui/GroupController.java
+++ b/src/main/java/org/olat/modules/coach/ui/GroupController.java
@@ -305,7 +305,7 @@ public class GroupController extends BasicController implements Activateable2 {
 		
 		OLATResourceable ores = OresHelper.createOLATResourceableInstance(Identity.class, entry.getStudentKey());
 		WindowControl bwControl = addToHistory(ureq, ores, null);
-		statementCtrl = new EfficiencyStatementDetailsController(ureq, bwControl, entry, group);
+		statementCtrl = new EfficiencyStatementDetailsController(ureq, bwControl, entry);
 		listenTo(statementCtrl);
 		mainVC.put("efficiencyDetails", statementCtrl.getInitialComponent());
 		
diff --git a/src/main/java/org/olat/modules/coach/ui/StudentCoursesController.java b/src/main/java/org/olat/modules/coach/ui/StudentCoursesController.java
index faed7480fc9c1d80e0791734b121a6c6c50796fc..19d1b312814cf88065f39fffa10d23ebb972147f 100644
--- a/src/main/java/org/olat/modules/coach/ui/StudentCoursesController.java
+++ b/src/main/java/org/olat/modules/coach/ui/StudentCoursesController.java
@@ -347,7 +347,7 @@ public class StudentCoursesController extends BasicController implements Activat
 		
 		OLATResourceable ores = OresHelper.createOLATResourceableInstance(RepositoryEntry.class, entry.getCourse().getKey());
 		WindowControl bwControl = addToHistory(ureq, ores, null);
-		statementCtrl = new EfficiencyStatementDetailsController(ureq, bwControl, entry, null);
+		statementCtrl = new EfficiencyStatementDetailsController(ureq, bwControl, entry);
 		listenTo(statementCtrl);
 		detailsCmp.setText(entry.getCourse().getDisplayname());
 
diff --git a/src/main/java/org/olat/modules/coach/ui/StudentOverviewController.java b/src/main/java/org/olat/modules/coach/ui/StudentOverviewController.java
index 3c65b07882728be5611d33e7d32094bca6595ec1..ab88fa8a4229beadef836802271e00e5c879a6a3 100644
--- a/src/main/java/org/olat/modules/coach/ui/StudentOverviewController.java
+++ b/src/main/java/org/olat/modules/coach/ui/StudentOverviewController.java
@@ -289,7 +289,7 @@ public class StudentOverviewController extends BasicController implements Activa
 		
 		OLATResourceable ores = OresHelper.createOLATResourceableInstance(RepositoryEntry.class, statement.getCourseRepoKey());
 		WindowControl bwControl = addToHistory(ureq, ores, null);
-		statementCtrl = new EfficiencyStatementDetailsController(ureq, bwControl, entry, null);
+		statementCtrl = new EfficiencyStatementDetailsController(ureq, bwControl, entry);
 		listenTo(statementCtrl);
 		detailsCmp.setText(statement.getShortTitle());