From: Roland Häder <roland@mxchange.org>
Date: Fri, 17 Apr 2020 14:54:20 +0000 (+0200)
Subject: Please cherry-pick:
X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=a2217130c8fe900f370747a522d2b009b4a999e1;p=jjobs-war.git

Please cherry-pick:
- heavy rewrite on (almost?) all admin-list-foo views, to use @ViewScoped beans
  and working JSR107 caching
- also sorted out mixed usage of userController (or so?) as the login and
  register backing beans can surely have their own properties
- rewrote web/WEB-INF/resources/tags/admin/dropdown/ to have it included back
  in views again, was a bad idea

Signed-off-by: Roland Häder <roland@mxchange.org>
---

diff --git a/src/java/org/mxchange/jjobs/beans/business/basicdata/list/JobsBasicDataListWebViewBean.java b/src/java/org/mxchange/jjobs/beans/business/basicdata/list/JobsBasicDataListWebViewBean.java
index 8a46d65b..dd5898ec 100644
--- a/src/java/org/mxchange/jjobs/beans/business/basicdata/list/JobsBasicDataListWebViewBean.java
+++ b/src/java/org/mxchange/jjobs/beans/business/basicdata/list/JobsBasicDataListWebViewBean.java
@@ -198,7 +198,7 @@ public class JobsBasicDataListWebViewBean extends BaseJobsBean implements JobsBa
 		// Is cache there?
 		if (!this.basicDataCache.iterator().hasNext()) {
 			// Add all
-			for (final BasicData basicData : this.basicDataBean.allBusinessBasicData()) {
+			for (final BasicData basicData : this.basicDataBean.fetchAllBusinessBasicData()) {
 				// Add it to cache
 				this.basicDataCache.put(basicData.getBasicDataId(), basicData);
 			}
diff --git a/src/java/org/mxchange/jjobs/beans/business/branchoffice/JobsAdminBranchOfficeWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/business/branchoffice/JobsAdminBranchOfficeWebRequestBean.java
index 75a538c3..3ce8f59f 100644
--- a/src/java/org/mxchange/jjobs/beans/business/branchoffice/JobsAdminBranchOfficeWebRequestBean.java
+++ b/src/java/org/mxchange/jjobs/beans/business/branchoffice/JobsAdminBranchOfficeWebRequestBean.java
@@ -922,7 +922,7 @@ public class JobsAdminBranchOfficeWebRequestBean extends BaseJobsBean implements
 	 */
 	private boolean isBranchOfficeCreatedByRequiredData (final BranchOffice branchOffice) {
 		// Get full list from other bean
-		final List<BranchOffice> branchOffices = this.branchOfficeListController.allBranchOffices();
+		final List<BranchOffice> branchOffices = this.branchOfficeListController.getAllBranchOffices();
 
 		// Default is not found
 		boolean isFound = false;
diff --git a/src/java/org/mxchange/jjobs/beans/business/branchoffice/list/JobsBranchOfficeListWebViewBean.java b/src/java/org/mxchange/jjobs/beans/business/branchoffice/list/JobsBranchOfficeListWebViewBean.java
index aea07075..0a23589e 100644
--- a/src/java/org/mxchange/jjobs/beans/business/branchoffice/list/JobsBranchOfficeListWebViewBean.java
+++ b/src/java/org/mxchange/jjobs/beans/business/branchoffice/list/JobsBranchOfficeListWebViewBean.java
@@ -115,13 +115,7 @@ public class JobsBranchOfficeListWebViewBean extends BaseJobsBean implements Job
 
 		// Add instance to cache
 		this.branchOfficeCache.put(event.getBranchOffice().getBranchId(), event.getBranchOffice());
-		this.allBranchOffices.add(event.getBranchOffice());
-	}
-
-	@Override
-	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
-	public List<BranchOffice> allBranchOffices () {
-		return this.allBranchOffices;
+		this.getAllBranchOffices().add(event.getBranchOffice());
 	}
 
 	@Override
@@ -145,6 +139,12 @@ public class JobsBranchOfficeListWebViewBean extends BaseJobsBean implements Job
 		return branchOffice;
 	}
 
+	@Override
+	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
+	public List<BranchOffice> getAllBranchOffices () {
+		return this.allBranchOffices;
+	}
+
 	/**
 	 * Getter for a list of filtered branch offices
 	 * <p>
@@ -191,22 +191,22 @@ public class JobsBranchOfficeListWebViewBean extends BaseJobsBean implements Job
 		// Is cache there?
 		if (!this.branchOfficeCache.iterator().hasNext()) {
 			// Add all
-			for (final BranchOffice branchOffice : this.branchOfficeBean.allBranchOffices()) {
+			for (final BranchOffice branchOffice : this.branchOfficeBean.fetchAllBranchOffices()) {
 				// Add it to cache
 				this.branchOfficeCache.put(branchOffice.getBranchId(), branchOffice);
 			}
 		}
 
 		// Is the list empty, but filled cache?
-		if (this.allBranchOffices.isEmpty() && this.branchOfficeCache.iterator().hasNext()) {
+		if (this.getAllBranchOffices().isEmpty() && this.branchOfficeCache.iterator().hasNext()) {
 			// Build up list
 			for (final Cache.Entry<Long, BranchOffice> currentEntry : this.branchOfficeCache) {
 				// Add to list
-				this.allBranchOffices.add(currentEntry.getValue());
+				this.getAllBranchOffices().add(currentEntry.getValue());
 			}
 
 			// Sort list
-			this.allBranchOffices.sort(new Comparator<BranchOffice>() {
+			this.getAllBranchOffices().sort(new Comparator<BranchOffice>() {
 				@Override
 				public int compare (final BranchOffice branchOffice1, final BranchOffice branchOffice2) {
 					return branchOffice1.getBranchId() > branchOffice2.getBranchId() ? 1 : branchOffice1.getBranchId() < branchOffice2.getBranchId() ? -1 : 0;
@@ -230,7 +230,7 @@ public class JobsBranchOfficeListWebViewBean extends BaseJobsBean implements Job
 		boolean isFound = false;
 
 		// Check all entries
-		for (final BranchOffice branchOffice : this.allBranchOffices()) {
+		for (final BranchOffice branchOffice : this.getAllBranchOffices()) {
 			// Is email address used?
 			if (Objects.equals(branchOffice.getBranchEmailAddress(), emailAddress)) {
 				// Found it
diff --git a/src/java/org/mxchange/jjobs/beans/business/branchoffice/list/JobsBranchOfficeListWebViewController.java b/src/java/org/mxchange/jjobs/beans/business/branchoffice/list/JobsBranchOfficeListWebViewController.java
index f9770038..f11accab 100644
--- a/src/java/org/mxchange/jjobs/beans/business/branchoffice/list/JobsBranchOfficeListWebViewController.java
+++ b/src/java/org/mxchange/jjobs/beans/business/branchoffice/list/JobsBranchOfficeListWebViewController.java
@@ -43,7 +43,7 @@ public interface JobsBranchOfficeListWebViewController extends Serializable {
 	 * <p>
 	 * @return A list of all branch offices
 	 */
-	List<BranchOffice> allBranchOffices ();
+	List<BranchOffice> getAllBranchOffices ();
 
 	/**
 	 * Tries to find a branch office with given id number
diff --git a/src/java/org/mxchange/jjobs/beans/business/department/list/JobsDepartmentListWebViewBean.java b/src/java/org/mxchange/jjobs/beans/business/department/list/JobsDepartmentListWebViewBean.java
index 4e309da2..05294fe0 100644
--- a/src/java/org/mxchange/jjobs/beans/business/department/list/JobsDepartmentListWebViewBean.java
+++ b/src/java/org/mxchange/jjobs/beans/business/department/list/JobsDepartmentListWebViewBean.java
@@ -195,7 +195,7 @@ public class JobsDepartmentListWebViewBean extends BaseJobsBean implements JobsD
 		// Is cache there?
 		if (!this.departmentCache.iterator().hasNext()) {
 			// Add all
-			for (final Department department : this.departmentBean.allDepartments()) {
+			for (final Department department : this.departmentBean.fetchAllDepartments()) {
 				// Add it to cache
 				this.departmentCache.put(department.getDepartmentId(), department);
 			}
diff --git a/src/java/org/mxchange/jjobs/beans/business/employee/JobsAdminEmployeeWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/business/employee/JobsAdminEmployeeWebRequestBean.java
index daba8d86..2fb6b2fb 100644
--- a/src/java/org/mxchange/jjobs/beans/business/employee/JobsAdminEmployeeWebRequestBean.java
+++ b/src/java/org/mxchange/jjobs/beans/business/employee/JobsAdminEmployeeWebRequestBean.java
@@ -40,6 +40,7 @@ import org.mxchange.jphone.model.phonenumbers.mobile.DialableMobileNumber;
 import org.mxchange.jphone.model.phonenumbers.mobile.MobileNumber;
 import org.mxchange.jphone.model.phonenumbers.mobileprovider.MobileProvider;
 import org.mxchange.jusercore.model.user.User;
+import org.mxchange.jfinancials.beans.business.employee.list.FinancialsEmployeeListWebViewController;
 
 /**
  * A request-scoped bean for administrative purposes for administrative employee
@@ -69,6 +70,12 @@ public class JobsAdminEmployeeWebRequestBean extends BaseJobsBean implements Job
 	@EJB (lookup = "java:global/jjobs-ejb/adminEmployee!org.mxchange.jcontactsbusiness.model.employee.AdminEmployeeSessionBeanRemote")
 	private AdminEmployeeSessionBeanRemote adminEmployeeBean;
 
+	/**
+	 * Administrative list-all-employees controller
+	 */
+	@Inject
+	private FinancialsEmployeeListWebViewController adminEmployeeListController;
+
 	/**
 	 * Assigned basic data instance
 	 */
@@ -433,7 +440,7 @@ public class JobsAdminEmployeeWebRequestBean extends BaseJobsBean implements Job
 		boolean isFound = false;
 
 		// Check all employees
-		for (final Employable otherEmployee : this.employeeController.allEmployees()) {
+		for (final Employable otherEmployee : this.adminEmployeeListController.getAllEmployees()) {
 			// Is same found?
 			if (Employees.isSameEmployeeFound(employee, otherEmployee)) {
 				// Okay, found it
diff --git a/src/java/org/mxchange/jjobs/beans/business/employee/JobsEmployeeWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/business/employee/JobsEmployeeWebRequestBean.java
index e6cddb5b..5611fff7 100644
--- a/src/java/org/mxchange/jjobs/beans/business/employee/JobsEmployeeWebRequestBean.java
+++ b/src/java/org/mxchange/jjobs/beans/business/employee/JobsEmployeeWebRequestBean.java
@@ -16,23 +16,8 @@
  */
 package org.mxchange.jjobs.beans.business.employee;
 
-import fish.payara.cdi.jsr107.impl.NamedCache;
-import java.text.MessageFormat;
-import java.util.Comparator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Objects;
-import javax.annotation.PostConstruct;
-import javax.cache.Cache;
-import javax.ejb.EJB;
 import javax.enterprise.context.RequestScoped;
-import javax.enterprise.event.Observes;
-import javax.inject.Inject;
 import javax.inject.Named;
-import org.mxchange.jcontactsbusiness.events.employee.added.ObservableEmployeeAddedEvent;
-import org.mxchange.jcontactsbusiness.exceptions.employee.EmployeeNotFoundException;
-import org.mxchange.jcontactsbusiness.model.employee.Employable;
-import org.mxchange.jcontactsbusiness.model.employee.EmployeeSessionBeanRemote;
 import org.mxchange.jjobs.beans.BaseJobsBean;
 
 /**
@@ -49,171 +34,12 @@ public class JobsEmployeeWebRequestBean extends BaseJobsBean implements JobsEmpl
 	 */
 	private static final long serialVersionUID = 12_886_968_547_361L;
 
-	/**
-	 * List of all employees
-	 */
-	private final List<Employable> allEmployees;
-
-	/**
-	 * EJB for general company employee purposes
-	 */
-	@EJB (lookup = "java:global/jjobs-ejb/employee!org.mxchange.jcontactsbusiness.model.employee.EmployeeSessionBeanRemote")
-	private EmployeeSessionBeanRemote employeeBean;
-
-	/**
-	 * List of all company employees
-	 */
-	@Inject
-	@NamedCache (cacheName = "companyEmployeeCache")
-	private Cache<Long, Employable> employeeCache;
-
-	/**
-	 * A list of filtered employees
-	 */
-	private List<Employable> filteredEmployees;
-
 	/**
 	 * Default constructor
 	 */
 	public JobsEmployeeWebRequestBean () {
 		// Call super constructor
 		super();
-
-		// Init list
-		this.allEmployees = new LinkedList<>();
-	}
-
-	/**
-	 * Observes events being fired when an employee has been added
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterEmployeeAddedEvent (@Observes final ObservableEmployeeAddedEvent event) {
-		// Validate parameter
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getEmployee() == null) {
-			// Throw it again
-			throw new NullPointerException("event.employee is null"); //NOI18N
-		} else if (event.getEmployee().getEmployeeId() == null) {
-			// Throw it again
-			throw new NullPointerException("event.employee.employeeId is null"); //NOI18N
-		} else if (event.getEmployee().getEmployeeId() < 1) {
-			// Throw IAE
-			throw new IllegalArgumentException(MessageFormat.format("event.employee.employeeId={0} is invalid", event.getEmployee().getEmployeeId())); //NOI18N
-		}
-
-		// Add employee to cache and list
-		this.employeeCache.put(event.getEmployee().getEmployeeId(), event.getEmployee());
-		this.allEmployees.add(event.getEmployee());
-	}
-
-	@Override
-	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
-	public List<Employable> allEmployees () {
-		return this.allEmployees;
-	}
-
-	@Override
-	public Employable findEmployeeById (final Long employeeId) throws EmployeeNotFoundException {
-		// Validate parameter
-		if (null == employeeId) {
-			// Throw NPE
-			throw new NullPointerException("employeeId is null"); //NOI18N
-		} else if (employeeId < 1) {
-			// Throw IAE
-			throw new IllegalArgumentException(MessageFormat.format("employeeId={0} is invalid", employeeId)); //NOI18N
-		} else if (!this.employeeCache.containsKey(employeeId)) {
-			// Not found
-			throw new EmployeeNotFoundException(employeeId);
-		}
-
-		// Get it from cache
-		final Employable employee = this.employeeCache.get(employeeId);
-
-		// Return it
-		return employee;
-	}
-
-	/**
-	 * Getter for filtered list of employees
-	 * <p>
-	 * @return Filtered list of employees
-	 */
-	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
-	public List<Employable> getFilteredEmployees () {
-		return this.filteredEmployees;
-	}
-
-	/**
-	 * Getter for filtered list of employees
-	 * <p>
-	 * @param filteredEmployees Filtered list of employees
-	 */
-	@SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter")
-	public void setFilteredEmployees (final List<Employable> filteredEmployees) {
-		this.filteredEmployees = filteredEmployees;
-	}
-
-	/**
-	 * Initialization method
-	 */
-	@PostConstruct
-	public void init () {
-		// Is cache there?
-		if (!this.employeeCache.iterator().hasNext()) {
-			// Add all
-			for (final Employable employee : this.employeeBean.allEmployees()) {
-				// Add it to cache
-				this.employeeCache.put(employee.getEmployeeId(), employee);
-			}
-		}
-
-		// Is cache filled and list is empty
-		if ((this.employeeCache.iterator().hasNext()) && (this.allEmployees.isEmpty())) {
-			// Build up list
-			for (final Cache.Entry<Long, Employable> currentEntry : this.employeeCache) {
-				// Add to list
-				this.allEmployees.add(currentEntry.getValue());
-			}
-
-			// Sort list
-			this.allEmployees.sort(new Comparator<Employable>() {
-				@Override
-				public int compare (final Employable employee1, final Employable employee2) {
-					return employee1.getEmployeeId() > employee2.getEmployeeId() ? 1 : employee1.getEmployeeId() < employee2.getEmployeeId() ? -1 : 0;
-				}
-			});
-		}
-	}
-
-	@Override
-	public Boolean isEmailAddressRegistered (final String emailAddress) {
-		// Validate parameter
-		if (null == emailAddress) {
-			// Throw NPE
-			throw new NullPointerException("emailAddress is null"); //NOI18N
-		} else if (emailAddress.isEmpty()) {
-			// Throw IAE
-			throw new IllegalArgumentException("emailAddress is empty"); //NOI18N
-		}
-
-		// Default is not found
-		boolean isFound = false;
-
-		// Check all entries
-		for (final Employable basicData : this.allEmployees()) {
-			// Is email address used?
-			if (Objects.equals(basicData.getEmployeeEmailAddress(), emailAddress)) {
-				// Found it
-				isFound = true;
-				break;
-			}
-		}
-
-		// Return flag
-		return isFound;
 	}
 
 }
diff --git a/src/java/org/mxchange/jjobs/beans/business/employee/JobsEmployeeWebRequestController.java b/src/java/org/mxchange/jjobs/beans/business/employee/JobsEmployeeWebRequestController.java
index 297475e8..26917eb1 100644
--- a/src/java/org/mxchange/jjobs/beans/business/employee/JobsEmployeeWebRequestController.java
+++ b/src/java/org/mxchange/jjobs/beans/business/employee/JobsEmployeeWebRequestController.java
@@ -17,9 +17,6 @@
 package org.mxchange.jjobs.beans.business.employee;
 
 import java.io.Serializable;
-import java.util.List;
-import org.mxchange.jcontactsbusiness.exceptions.employee.EmployeeNotFoundException;
-import org.mxchange.jcontactsbusiness.model.employee.Employable;
 
 /**
  * An interface for request-scoped general company employee beans
@@ -28,31 +25,4 @@ import org.mxchange.jcontactsbusiness.model.employee.Employable;
  */
 public interface JobsEmployeeWebRequestController extends Serializable {
 
-	/**
-	 * Validates if given email address is already in use by an employee
-	 * <p>
-	 * @param emailAddress Email address to be validated
-	 * <p>
-	 * @return Whether the email address is already used
-	 */
-	Boolean isEmailAddressRegistered (final String emailAddress);
-
-	/**
-	 * Returns a list of all company employees
-	 * <p>
-	 * @return List of all company employees
-	 */
-	List<Employable> allEmployees ();
-
-	/**
-	 * Finds a company employee by given employee id
-	 * <p>
-	 * @param employeeId Employable id to find company employee instance for
-	 * <p>
-	 * @return Company employee instance
-	 * <p>
-	 * @throws EmployeeNotFoundException If the company employee was not found
-	 */
-	Employable findEmployeeById (final Long employeeId) throws EmployeeNotFoundException;
-
 }
diff --git a/src/java/org/mxchange/jjobs/beans/business/employee/list/FinancialsEmployeeListWebViewBean.java b/src/java/org/mxchange/jjobs/beans/business/employee/list/FinancialsEmployeeListWebViewBean.java
new file mode 100644
index 00000000..966e4329
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/business/employee/list/FinancialsEmployeeListWebViewBean.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2017 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.business.employee.list;
+
+import fish.payara.cdi.jsr107.impl.NamedCache;
+import java.text.MessageFormat;
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import javax.annotation.PostConstruct;
+import javax.cache.Cache;
+import javax.ejb.EJB;
+import javax.enterprise.event.Observes;
+import javax.faces.view.ViewScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jcontactsbusiness.events.employee.added.ObservableEmployeeAddedEvent;
+import org.mxchange.jcontactsbusiness.exceptions.employee.EmployeeNotFoundException;
+import org.mxchange.jcontactsbusiness.model.employee.Employable;
+import org.mxchange.jcontactsbusiness.model.employee.EmployeeSessionBeanRemote;
+import org.mxchange.jfinancials.beans.BaseFinancialsBean;
+
+/**
+ * A view-scoped bean for listing purposes for e.g. administrative employee
+ * purposes.
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("employeeListController")
+@ViewScoped
+public class FinancialsEmployeeListWebViewBean extends BaseFinancialsBean implements FinancialsEmployeeListWebViewController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 12_886_968_547_362L;
+
+	/**
+	 * List of all employees
+	 */
+	private final List<Employable> allEmployees;
+
+	/**
+	 * EJB for general company employee purposes
+	 */
+	@EJB (lookup = "java:global/jfinancials-ejb/employee!org.mxchange.jcontactsbusiness.model.employee.EmployeeSessionBeanRemote")
+	private EmployeeSessionBeanRemote employeeBean;
+
+	/**
+	 * List of all company employees
+	 */
+	@Inject
+	@NamedCache (cacheName = "companyEmployeeCache")
+	private transient Cache<Long, Employable> employeeCache;
+
+	/**
+	 * A list of filtered employees
+	 */
+	private List<Employable> filteredEmployees;
+
+	/**
+	 * Currently selected employee
+	 */
+	private Employable selectedEmployee;
+
+	/**
+	 * Default constructor
+	 */
+	public FinancialsEmployeeListWebViewBean () {
+		// Call super constructor
+		super();
+
+		// Init list
+		this.allEmployees = new LinkedList<>();
+	}
+
+	/**
+	 * Observes events being fired when an employee has been added
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterEmployeeAddedEvent (@Observes final ObservableEmployeeAddedEvent event) {
+		// Validate parameter
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getEmployee() == null) {
+			// Throw it again
+			throw new NullPointerException("event.employee is null"); //NOI18N
+		} else if (event.getEmployee().getEmployeeId() == null) {
+			// Throw it again
+			throw new NullPointerException("event.employee.employeeId is null"); //NOI18N
+		} else if (event.getEmployee().getEmployeeId() < 1) {
+			// Throw IAE
+			throw new IllegalArgumentException(MessageFormat.format("event.employee.employeeId={0} is invalid", event.getEmployee().getEmployeeId())); //NOI18N
+		}
+
+		// Add employee to cache and list
+		this.employeeCache.put(event.getEmployee().getEmployeeId(), event.getEmployee());
+		this.getAllEmployees().add(event.getEmployee());
+	}
+
+	@Override
+	public Employable findEmployeeById (final Long employeeId) throws EmployeeNotFoundException {
+		// Validate parameter
+		if (null == employeeId) {
+			// Throw NPE
+			throw new NullPointerException("employeeId is null"); //NOI18N
+		} else if (employeeId < 1) {
+			// Throw IAE
+			throw new IllegalArgumentException(MessageFormat.format("employeeId={0} is invalid", employeeId)); //NOI18N
+		} else if (!this.employeeCache.containsKey(employeeId)) {
+			// Not found
+			throw new EmployeeNotFoundException(employeeId);
+		}
+
+		// Get it from cache
+		final Employable employee = this.employeeCache.get(employeeId);
+
+		// Return it
+		return employee;
+	}
+
+	@Override
+	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
+	public List<Employable> getAllEmployees () {
+		return this.allEmployees;
+	}
+
+	/**
+	 * Getter for filtered list of employees
+	 * <p>
+	 * @return Filtered list of employees
+	 */
+	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
+	public List<Employable> getFilteredEmployees () {
+		return this.filteredEmployees;
+	}
+
+	/**
+	 * Getter for filtered list of employees
+	 * <p>
+	 * @param filteredEmployees Filtered list of employees
+	 */
+	@SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter")
+	public void setFilteredEmployees (final List<Employable> filteredEmployees) {
+		this.filteredEmployees = filteredEmployees;
+	}
+
+	/**
+	 * Getter for currently selected employee
+	 * <p>
+	 * @return Currently selected employee
+	 */
+	public Employable getSelectedEmployee () {
+		return this.selectedEmployee;
+	}
+
+	/**
+	 * Setter for currently selected employee
+	 * <p>
+	 * @param selectedEmployee Currently selected employee
+	 */
+	public void setSelectedEmployee (final Employable selectedEmployee) {
+		this.selectedEmployee = selectedEmployee;
+	}
+
+	/**
+	 * Initialization method
+	 */
+	@PostConstruct
+	public void initializeList () {
+		// Is cache there?
+		if (!this.employeeCache.iterator().hasNext()) {
+			// Add all
+			for (final Employable employee : this.employeeBean.fetchAllEmployees()) {
+				// Add it to cache
+				this.employeeCache.put(employee.getEmployeeId(), employee);
+			}
+		}
+
+		// Is cache filled and list is empty
+		if ((this.employeeCache.iterator().hasNext()) && (this.getAllEmployees().isEmpty())) {
+			// Build up list
+			for (final Cache.Entry<Long, Employable> currentEntry : this.employeeCache) {
+				// Add to list
+				this.getAllEmployees().add(currentEntry.getValue());
+			}
+
+			// Sort list
+			this.getAllEmployees().sort(new Comparator<Employable>() {
+				@Override
+				public int compare (final Employable employee1, final Employable employee2) {
+					return employee1.getEmployeeId() > employee2.getEmployeeId() ? 1 : employee1.getEmployeeId() < employee2.getEmployeeId() ? -1 : 0;
+				}
+			});
+		}
+	}
+
+	@Override
+	public Boolean isEmailAddressRegistered (final String emailAddress) {
+		// Validate parameter
+		if (null == emailAddress) {
+			// Throw NPE
+			throw new NullPointerException("emailAddress is null"); //NOI18N
+		} else if (emailAddress.isEmpty()) {
+			// Throw IAE
+			throw new IllegalArgumentException("emailAddress is empty"); //NOI18N
+		}
+
+		// Default is not found
+		boolean isFound = false;
+
+		// Check all entries
+		for (final Employable basicData : this.getAllEmployees()) {
+			// Is email address used?
+			if (Objects.equals(basicData.getEmployeeEmailAddress(), emailAddress)) {
+				// Found it
+				isFound = true;
+				break;
+			}
+		}
+
+		// Return flag
+		return isFound;
+	}
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/business/employee/list/FinancialsEmployeeListWebViewController.java b/src/java/org/mxchange/jjobs/beans/business/employee/list/FinancialsEmployeeListWebViewController.java
new file mode 100644
index 00000000..306bb460
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/business/employee/list/FinancialsEmployeeListWebViewController.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2017 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.business.employee.list;
+
+import java.io.Serializable;
+import java.util.List;
+import org.mxchange.jcontactsbusiness.exceptions.employee.EmployeeNotFoundException;
+import org.mxchange.jcontactsbusiness.model.employee.Employable;
+
+/**
+ * An interface for request-scoped administrative company employee beans
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsEmployeeListWebViewController extends Serializable {
+
+	/**
+	 * Returns a list of all company employees
+	 * <p>
+	 * @return List of all company employees
+	 */
+	List<Employable> getAllEmployees ();
+
+	/**
+	 * Validates if given email address is already in use by an employee
+	 * <p>
+	 * @param emailAddress Email address to be validated
+	 * <p>
+	 * @return Whether the email address is already used
+	 */
+	Boolean isEmailAddressRegistered (final String emailAddress);
+
+	/**
+	 * Finds a company employee by given employee id
+	 * <p>
+	 * @param employeeId Employable id to find company employee instance for
+	 * <p>
+	 * @return Company employee instance
+	 * <p>
+	 * @throws EmployeeNotFoundException If the company employee was not found
+	 */
+	Employable findEmployeeById (final Long employeeId) throws EmployeeNotFoundException;
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/business/headquarter/list/JobsHeadquarterListWebViewBean.java b/src/java/org/mxchange/jjobs/beans/business/headquarter/list/JobsHeadquarterListWebViewBean.java
index 0c106562..245a04d7 100644
--- a/src/java/org/mxchange/jjobs/beans/business/headquarter/list/JobsHeadquarterListWebViewBean.java
+++ b/src/java/org/mxchange/jjobs/beans/business/headquarter/list/JobsHeadquarterListWebViewBean.java
@@ -192,7 +192,7 @@ public class JobsHeadquarterListWebViewBean extends BaseJobsBean implements Jobs
 		// Is cache there?
 		if (!this.headquarterCache.iterator().hasNext()) {
 			// Add all
-			for (final Headquarter headquarter : this.headquarterBean.allHeadquarters()) {
+			for (final Headquarter headquarter : this.headquarterBean.fetchAllHeadquarters()) {
 				// Add it to cache
 				this.headquarterCache.put(headquarter.getHeadquarterId(), headquarter);
 			}
diff --git a/src/java/org/mxchange/jjobs/beans/business/opening_time/JobsAdminOpeningTimeWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/business/opening_time/JobsAdminOpeningTimeWebRequestBean.java
index 2cda591c..cc8b0142 100644
--- a/src/java/org/mxchange/jjobs/beans/business/opening_time/JobsAdminOpeningTimeWebRequestBean.java
+++ b/src/java/org/mxchange/jjobs/beans/business/opening_time/JobsAdminOpeningTimeWebRequestBean.java
@@ -91,7 +91,7 @@ public class JobsAdminOpeningTimeWebRequestBean extends BaseJobsBean implements
 	 * method will validate if the openingTime's address is already registered
 	 * and if found, it will output a proper faces message.
 	 */
-	public void addOpeningTimes () {
+	public void addOpeningTime () {
 		// Get instance
 		final OpeningTime openingTime = this.createOpeningTimes();
 
diff --git a/src/java/org/mxchange/jjobs/beans/business/opening_time/JobsOpeningTimeWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/business/opening_time/JobsOpeningTimeWebRequestBean.java
index 94a490e1..43012959 100644
--- a/src/java/org/mxchange/jjobs/beans/business/opening_time/JobsOpeningTimeWebRequestBean.java
+++ b/src/java/org/mxchange/jjobs/beans/business/opening_time/JobsOpeningTimeWebRequestBean.java
@@ -16,21 +16,9 @@
  */
 package org.mxchange.jjobs.beans.business.opening_time;
 
-import fish.payara.cdi.jsr107.impl.NamedCache;
-import java.text.MessageFormat;
-import java.util.Comparator;
-import java.util.LinkedList;
-import java.util.List;
-import javax.annotation.PostConstruct;
-import javax.cache.Cache;
 import javax.ejb.EJB;
 import javax.enterprise.context.RequestScoped;
-import javax.enterprise.event.Observes;
-import javax.inject.Inject;
 import javax.inject.Named;
-import org.mxchange.jcontactsbusiness.events.opening_time.added.ObservableOpeningTimeAddedEvent;
-import org.mxchange.jcontactsbusiness.exceptions.opening_time.OpeningTimeNotFoundException;
-import org.mxchange.jcontactsbusiness.model.opening_time.OpeningTime;
 import org.mxchange.jcontactsbusiness.model.opening_time.OpeningTimeSessionBeanRemote;
 import org.mxchange.jjobs.beans.BaseJobsBean;
 
@@ -48,144 +36,18 @@ public class JobsOpeningTimeWebRequestBean extends BaseJobsBean implements JobsO
 	 */
 	private static final long serialVersionUID = 5_028_697_360_462L;
 
-	/**
-	 * A list of all opening times
-	 */
-	private final List<OpeningTime> allOpeningTimes;
-
-	/**
-	 * A list of filtered opening times
-	 */
-	private List<OpeningTime> filteredOpeningTimes;
-
 	/**
 	 * EJB for administrative purposes
 	 */
 	@EJB (lookup = "java:global/jjobs-ejb/openingTimes!org.mxchange.jcontactsbusiness.model.opening_time.OpeningTimeSessionBeanRemote")
 	private OpeningTimeSessionBeanRemote openingTimesBean;
 
-	/**
-	 * A list of all opening times (globally)
-	 */
-	@Inject
-	@NamedCache (cacheName = "openingTimesCache")
-	private Cache<Long, OpeningTime> openingTimesCache;
-
 	/**
 	 * Default constructor
 	 */
 	public JobsOpeningTimeWebRequestBean () {
 		// Call super constructor
 		super();
-
-		// Init list
-		this.allOpeningTimes = new LinkedList<>();
-	}
-
-	/**
-	 * Observes events being thrown when a new opening time has been added
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterOpeningTimeAddedEvent (@Observes final ObservableOpeningTimeAddedEvent event) {
-		// Validate parameter
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null");
-		} else if (event.getOpeningTime() == null) {
-			// Throw it again
-			throw new NullPointerException("event.openingTime is null");
-		} else if (event.getOpeningTime().getOpeningId() == null) {
-			// Throw it again
-			throw new NullPointerException("event.openingTime.openingId is null");
-		} else if (event.getOpeningTime().getOpeningId() < 1) {
-			// Throw it again
-			throw new NullPointerException(MessageFormat.format("event.openingTime.openingId={0} is invalid", event.getOpeningTime().getOpeningId()));
-		}
-
-		// Add to cache and list
-		this.openingTimesCache.put(event.getOpeningTime().getOpeningId(), event.getOpeningTime());
-		this.allOpeningTimes.add(event.getOpeningTime());
-	}
-
-	@Override
-	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
-	public List<OpeningTime> allOpeningTimes () {
-		return this.allOpeningTimes;
-	}
-
-	@Override
-	public OpeningTime findOpeningTimeById (final Long openingId) throws OpeningTimeNotFoundException {
-		// Validate parameter
-		if (null == openingId) {
-			// Throw NPE
-			throw new NullPointerException("openingId is null"); //NOI18N
-		} else if (openingId < 1) {
-			// Throw IAE
-			throw new IllegalArgumentException("openingId=" + openingId + " is invalid"); //NOI18N
-		} else if (!this.openingTimesCache.containsKey(openingId)) {
-			// Not found
-			throw new OpeningTimeNotFoundException(openingId);
-		}
-
-		// Get it from cache
-		final OpeningTime opening = this.openingTimesCache.get(openingId);
-
-		// Return it
-		return opening;
-	}
-
-	/**
-	 * Getter for a list of filtered opening times
-	 * <p>
-	 * @return Filtered opening times
-	 */
-	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
-	public List<OpeningTime> getFilteredOpeningTimes () {
-		return this.filteredOpeningTimes;
-	}
-
-	/**
-	 * Setter for a list of filtered opening times
-	 * <p>
-	 * @param filteredOpeningTimes Filtered opening times
-	 */
-	@SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter")
-	public void setFilteredOpeningTimes (final List<OpeningTime> filteredOpeningTimes) {
-		this.filteredOpeningTimes = filteredOpeningTimes;
-	}
-
-	/**
-	 * Initializer method
-	 */
-	@PostConstruct
-	public void initializeList () {
-		// Is cache there?
-		if (!this.openingTimesCache.iterator().hasNext()) {
-			// Add all
-			for (final OpeningTime openingTime : this.openingTimesBean.allOpeningTimes()) {
-				// Add it to cache
-				this.openingTimesCache.put(openingTime.getOpeningId(), openingTime);
-			}
-		}
-
-		// Is the list empty, but filled cache?
-		if (this.allOpeningTimes.isEmpty() && this.openingTimesCache.iterator().hasNext()) {
-			// Build up list
-			for (final Cache.Entry<Long, OpeningTime> currentEntry : this.openingTimesCache) {
-				// Add to list
-				this.allOpeningTimes.add(currentEntry.getValue());
-			}
-
-			// Sort list
-			this.allOpeningTimes.sort(new Comparator<OpeningTime>() {
-				@Override
-				public int compare (final OpeningTime openingTime1, final OpeningTime openingTime2) {
-					return openingTime1.getOpeningId() > openingTime2.getOpeningId() ? 1 : openingTime1.getOpeningId() < openingTime2.getOpeningId() ? -1 : 0;
-				}
-			}
-			);
-		}
 	}
 
 }
diff --git a/src/java/org/mxchange/jjobs/beans/business/opening_time/JobsOpeningTimeWebRequestController.java b/src/java/org/mxchange/jjobs/beans/business/opening_time/JobsOpeningTimeWebRequestController.java
index 5630164d..6ea8d866 100644
--- a/src/java/org/mxchange/jjobs/beans/business/opening_time/JobsOpeningTimeWebRequestController.java
+++ b/src/java/org/mxchange/jjobs/beans/business/opening_time/JobsOpeningTimeWebRequestController.java
@@ -17,9 +17,6 @@
 package org.mxchange.jjobs.beans.business.opening_time;
 
 import java.io.Serializable;
-import java.util.List;
-import org.mxchange.jcontactsbusiness.exceptions.opening_time.OpeningTimeNotFoundException;
-import org.mxchange.jcontactsbusiness.model.opening_time.OpeningTime;
 
 /**
  * An interface for general opening times controller
@@ -28,24 +25,4 @@ import org.mxchange.jcontactsbusiness.model.opening_time.OpeningTime;
  */
 public interface JobsOpeningTimeWebRequestController extends Serializable {
 
-	/**
-	 * Returns a list of all opening times
-	 * <p>
-	 * @return A list of all opening times
-	 */
-	List<OpeningTime> allOpeningTimes ();
-
-	/**
-	 * Retrieves a single company department entity for given id number or
-	 * throws a proper exception if not found.
-	 * <p>
-	 * @param openingId Company department id to lookup
-	 * <p>
-	 * @return Company department instance
-	 * <p>
-	 * @throws OpeningTimeNotFoundException If the id number could not be looked
-	 * up and solved into an entity
-	 */
-	OpeningTime findOpeningTimeById (final Long openingId) throws OpeningTimeNotFoundException;
-
 }
diff --git a/src/java/org/mxchange/jjobs/beans/business/opening_time/list/FinancialsOpeningTimeListWebViewBean.java b/src/java/org/mxchange/jjobs/beans/business/opening_time/list/FinancialsOpeningTimeListWebViewBean.java
new file mode 100644
index 00000000..d82c0404
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/business/opening_time/list/FinancialsOpeningTimeListWebViewBean.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2017 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.business.opening_time.list;
+
+import fish.payara.cdi.jsr107.impl.NamedCache;
+import java.text.MessageFormat;
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import javax.cache.Cache;
+import javax.ejb.EJB;
+import javax.enterprise.event.Observes;
+import javax.faces.view.ViewScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jcontactsbusiness.events.opening_time.added.ObservableOpeningTimeAddedEvent;
+import org.mxchange.jcontactsbusiness.exceptions.opening_time.OpeningTimeNotFoundException;
+import org.mxchange.jcontactsbusiness.model.opening_time.OpeningTime;
+import org.mxchange.jcontactsbusiness.model.opening_time.OpeningTimeSessionBeanRemote;
+import org.mxchange.jfinancials.beans.BaseFinancialsBean;
+
+/**
+ * A general bean for opening times
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("openingTimeListController")
+@ViewScoped
+public class FinancialsOpeningTimeListWebViewBean extends BaseFinancialsBean implements FinancialsOpeningTimeListWebViewController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 5_028_697_360_467L;
+
+	/**
+	 * A list of all opening times
+	 */
+	private final List<OpeningTime> allOpeningTimes;
+
+	/**
+	 * A list of filtered opening times
+	 */
+	private List<OpeningTime> filteredOpeningTimes;
+
+	/**
+	 * EJB for administrative purposes
+	 */
+	@EJB (lookup = "java:global/jfinancials-ejb/openingTimes!org.mxchange.jcontactsbusiness.model.opening_time.OpeningTimeSessionBeanRemote")
+	private OpeningTimeSessionBeanRemote openingTimesBean;
+
+	/**
+	 * A list of all opening times (globally)
+	 */
+	@Inject
+	@NamedCache (cacheName = "openingTimesCache")
+	private transient Cache<Long, OpeningTime> openingTimesCache;
+
+	/**
+	 * Selected opening-time instance
+	 */
+	private OpeningTime selectedOpeningTime;
+
+	/**
+	 * Default constructor
+	 */
+	public FinancialsOpeningTimeListWebViewBean () {
+		// Call super constructor
+		super();
+
+		// Init list
+		this.allOpeningTimes = new LinkedList<>();
+	}
+
+	/**
+	 * Observes events being thrown when a new opening time has been added
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterOpeningTimeAddedEvent (@Observes final ObservableOpeningTimeAddedEvent event) {
+		// Validate parameter
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null");
+		} else if (event.getOpeningTime() == null) {
+			// Throw it again
+			throw new NullPointerException("event.openingTime is null");
+		} else if (event.getOpeningTime().getOpeningTimeId() == null) {
+			// Throw it again
+			throw new NullPointerException("event.openingTime.openingTimeId is null");
+		} else if (event.getOpeningTime().getOpeningTimeId() < 1) {
+			// Throw it again
+			throw new NullPointerException(MessageFormat.format("event.openingTime.openingTimeId={0} is invalid", event.getOpeningTime().getOpeningTimeId()));
+		}
+
+		// Add to cache and list
+		this.openingTimesCache.put(event.getOpeningTime().getOpeningTimeId(), event.getOpeningTime());
+		this.getAllOpeningTimes().add(event.getOpeningTime());
+	}
+
+	@Override
+	public OpeningTime findOpeningTimeById (final Long openingTimeId) throws OpeningTimeNotFoundException {
+		// Validate parameter
+		if (null == openingTimeId) {
+			// Throw NPE
+			throw new NullPointerException("openingTimeId is null"); //NOI18N
+		} else if (openingTimeId < 1) {
+			// Throw IAE
+			throw new IllegalArgumentException("openingTimeId=" + openingTimeId + " is invalid"); //NOI18N
+		} else if (!this.openingTimesCache.containsKey(openingTimeId)) {
+			// Not found
+			throw new OpeningTimeNotFoundException(openingTimeId);
+		}
+
+		// Get it from cache
+		final OpeningTime opening = this.openingTimesCache.get(openingTimeId);
+
+		// Return it
+		return opening;
+	}
+
+	/**
+	 * Returns a list of all opening times
+	 * <p>
+	 * @return A list of all opening times
+	 */
+	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
+	public List<OpeningTime> getAllOpeningTimes () {
+		return this.allOpeningTimes;
+	}
+
+	/**
+	 * Getter for a list of filtered opening times
+	 * <p>
+	 * @return Filtered opening times
+	 */
+	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
+	public List<OpeningTime> getFilteredOpeningTimes () {
+		return this.filteredOpeningTimes;
+	}
+
+	/**
+	 * Setter for a list of filtered opening times
+	 * <p>
+	 * @param filteredOpeningTimes Filtered opening times
+	 */
+	@SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter")
+	public void setFilteredOpeningTimes (final List<OpeningTime> filteredOpeningTimes) {
+		this.filteredOpeningTimes = filteredOpeningTimes;
+	}
+
+	/**
+	 * Getter for selected open-time instance
+	 * <p>
+	 * @return Selected open-time instance
+	 */
+	public OpeningTime getSelectedOpeningTime () {
+		return this.selectedOpeningTime;
+	}
+
+	/**
+	 * Setter for selected open-time instance
+	 * <p>
+	 * @param selectedOpeningTime Selected open-time instance
+	 */
+	public void setSelectedOpeningTime (final OpeningTime selectedOpeningTime) {
+		this.selectedOpeningTime = selectedOpeningTime;
+	}
+
+	/**
+	 * Initializer method
+	 */
+	@PostConstruct
+	public void initializeList () {
+		// Is cache there?
+		if (!this.openingTimesCache.iterator().hasNext()) {
+			// Add all
+			for (final OpeningTime openingTime : this.openingTimesBean.fetchAllOpeningTimes()) {
+				// Add it to cache
+				this.openingTimesCache.put(openingTime.getOpeningTimeId(), openingTime);
+			}
+		}
+
+		// Is the list empty, but filled cache?
+		if (this.getAllOpeningTimes().isEmpty() && this.openingTimesCache.iterator().hasNext()) {
+			// Build up list
+			for (final Cache.Entry<Long, OpeningTime> currentEntry : this.openingTimesCache) {
+				// Add to list
+				this.getAllOpeningTimes().add(currentEntry.getValue());
+			}
+
+			// Sort list
+			this.getAllOpeningTimes().sort(new Comparator<OpeningTime>() {
+				@Override
+				public int compare (final OpeningTime openingTime1, final OpeningTime openingTime2) {
+					return openingTime1.getOpeningTimeId() > openingTime2.getOpeningTimeId() ? 1 : openingTime1.getOpeningTimeId() < openingTime2.getOpeningTimeId() ? -1 : 0;
+				}
+			}
+			);
+		}
+	}
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/business/opening_time/list/FinancialsOpeningTimeListWebViewController.java b/src/java/org/mxchange/jjobs/beans/business/opening_time/list/FinancialsOpeningTimeListWebViewController.java
new file mode 100644
index 00000000..cadae503
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/business/opening_time/list/FinancialsOpeningTimeListWebViewController.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2017 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.business.opening_time.list;
+
+import java.io.Serializable;
+import org.mxchange.jcontactsbusiness.exceptions.opening_time.OpeningTimeNotFoundException;
+import org.mxchange.jcontactsbusiness.model.opening_time.OpeningTime;
+
+/**
+ * An interface for general opening times controller
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsOpeningTimeListWebViewController extends Serializable {
+
+	/**
+	 * Retrieves a single opening-time entity for given id number or throws a
+	 * proper exception if not found.
+	 * <p>
+	 * @param openingTimeId Opening time id to lookup
+	 * <p>
+	 * @return Company department instance
+	 * <p>
+	 * @throws OpeningTimeNotFoundException If the id number could not be looked
+	 * up and solved into an entity
+	 */
+	OpeningTime findOpeningTimeById (final Long openingTimeId) throws OpeningTimeNotFoundException;
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/contact/JobsAdminContactWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/contact/JobsAdminContactWebRequestBean.java
index 85fab507..3d007ad5 100644
--- a/src/java/org/mxchange/jjobs/beans/contact/JobsAdminContactWebRequestBean.java
+++ b/src/java/org/mxchange/jjobs/beans/contact/JobsAdminContactWebRequestBean.java
@@ -348,9 +348,9 @@ public class JobsAdminContactWebRequestBean extends BaseJobsBean implements Jobs
 		// Is the cell phone set?
 		if (contact.getContactMobileNumber() instanceof DialableMobileNumber) {
 			// ... cmobile data
-			this.setMobileId(contact.getContactMobileNumber().getPhoneId());
+			this.setMobileId(contact.getContactMobileNumber().getMobileId());
 			this.setMobileProvider(contact.getContactMobileNumber().getMobileProvider());
-			this.setMobileNumber(contact.getContactMobileNumber().getPhoneNumber());
+			this.setMobileNumber(contact.getContactMobileNumber().getMobileNumber());
 		}
 
 		// Is the fax set?
@@ -403,13 +403,8 @@ public class JobsAdminContactWebRequestBean extends BaseJobsBean implements Jobs
 		// Create new instance
 		final Contact contact = new UserContact(this.getPersonalTitle(), this.getFirstName(), this.getFamilyName());
 
-		// Is contact id set?
-		if (this.getContactId() instanceof Long) {
-			// Set it, too
-			contact.setContactId(this.getContactId());
-		}
-
 		// Add all others
+		contact.setContactId(this.getContactId());
 		contact.setContactTitle(this.getAcademicTitle());
 		contact.setContactBirthday(this.getBirthday());
 		contact.setContactStreet(this.getStreet());
@@ -469,10 +464,10 @@ public class JobsAdminContactWebRequestBean extends BaseJobsBean implements Jobs
 		// Is the provider set?
 		if ((mobile instanceof DialableMobileNumber) && (this.getMobileProvider() instanceof MobileProvider) && (this.getMobileNumber() != null) && (this.getMobileNumber() > 0)) {
 			// Is the number set?
-			if (mobile.getPhoneNumber() == null) {
+			if (mobile.getMobileNumber() == null) {
 				// Is null
 				throw new NullPointerException("cmobile.phoneNumber is null"); //NOI18N
-			} else if (mobile.getPhoneNumber() < 1) {
+			} else if (mobile.getMobileNumber() < 1) {
 				// Abort here
 				throw new IllegalArgumentException("cmobile.phoneNumber is zero or below."); //NOI18N
 			}
@@ -536,7 +531,7 @@ public class JobsAdminContactWebRequestBean extends BaseJobsBean implements Jobs
 					 "%s%d%d", //NOI18N
 					 mobileNumber.getMobileProvider().getProviderCountry().getCountryExternalDialPrefix(),
 					 mobileNumber.getMobileProvider().getProviderDialPrefix(),
-					 mobileNumber.getPhoneNumber()
+					 mobileNumber.getMobileNumber()
 			 );
 
 		// Return it
@@ -685,12 +680,6 @@ public class JobsAdminContactWebRequestBean extends BaseJobsBean implements Jobs
 		return "admin"; //NOI18N
 	}
 
-	@Override
-	@Deprecated
-	public void setControllerType (final String controllerType) {
-		throw new UnsupportedOperationException("Setting controller type is not supported."); //NOI18N
-	}
-
 	/**
 	 * Getter for email address
 	 * <p>
diff --git a/src/java/org/mxchange/jjobs/beans/contact/JobsAdminContactWebRequestController.java b/src/java/org/mxchange/jjobs/beans/contact/JobsAdminContactWebRequestController.java
index f9582272..c5c76433 100644
--- a/src/java/org/mxchange/jjobs/beans/contact/JobsAdminContactWebRequestController.java
+++ b/src/java/org/mxchange/jjobs/beans/contact/JobsAdminContactWebRequestController.java
@@ -45,14 +45,4 @@ public interface JobsAdminContactWebRequestController extends Serializable {
 	 */
 	String getControllerType ();
 
-	/**
-	 * Setter for controller type
-	 * <p>
-	 * @param controllerType Controller type
-	 * <p>
-	 * @deprecated Don't use this method
-	 */
-	@Deprecated
-	void setControllerType (final String controllerType);
-
 }
diff --git a/src/java/org/mxchange/jjobs/beans/contact/JobsContactWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/contact/JobsContactWebRequestBean.java
index 8617ab39..7e8a6687 100644
--- a/src/java/org/mxchange/jjobs/beans/contact/JobsContactWebRequestBean.java
+++ b/src/java/org/mxchange/jjobs/beans/contact/JobsContactWebRequestBean.java
@@ -44,6 +44,7 @@ import org.mxchange.jphone.model.phonenumbers.mobile.MobileNumber;
 import org.mxchange.jphone.model.phonenumbers.mobileprovider.MobileProvider;
 import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
 import org.mxchange.jusercore.events.user.linked.ObservableAdminLinkedUserEvent;
+import org.mxchange.jusercore.events.user.update.pre.ObservablePreUserPersonalDataUpdatedEvent;
 import org.mxchange.juserlogincore.events.login.ObservableUserLoggedInEvent;
 import org.mxchange.juserlogincore.exceptions.UserPasswordMismatchException;
 
@@ -142,21 +143,6 @@ public class JobsContactWebRequestBean extends BaseJobsBean implements JobsConta
 	 */
 	private String houseNumberExtension;
 
-	/**
-	 * Whether a fax entry has been unlinked
-	 */
-	private boolean isFaxUnlinked;
-
-	/**
-	 * Whether a land-line number has been unlinked
-	 */
-	private boolean isLandLineUnlinked;
-
-	/**
-	 * Whether a mobile entry has been unlinked
-	 */
-	private boolean isMobileUnlinked;
-
 	/**
 	 * Phone number area code
 	 */
@@ -287,7 +273,27 @@ public class JobsContactWebRequestBean extends BaseJobsBean implements JobsConta
 		}
 
 		// Copy all data to this bean
-		this.copyContact(event.getLoggedInUser().getUserContact());
+		this.copyFromContact(event.getLoggedInUser().getUserContact());
+	}
+
+	/**
+	 * Observes events being fired before an updated of personal data done by a
+	 * user has started.
+	 * <p>
+	 * @param event Event being observed
+	 */
+	public void beforeUserUpdatedPersonalDataEvent (@Observes final ObservablePreUserPersonalDataUpdatedEvent event) {
+		// Is the instance valid?
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUpdatedUser() == null) {
+			// Throw NPE
+			throw new NullPointerException("event.updatedUser is null"); //NOI18N
+		}
+
+		// Set all
+		this.copyToContact(event.getUpdatedUser().getUserContact());
 	}
 
 	@Override
@@ -308,81 +314,14 @@ public class JobsContactWebRequestBean extends BaseJobsBean implements JobsConta
 		// Required personal data must be set
 		assert (this.isRequiredPersonalDataSet()) : "not all personal data is set"; //NOI18N
 
-		// Generate phone number
-		final DialableLandLineNumber landLine = new LandLineNumber(this.getLandLineCountry(), this.getLandLineAreaCode(), this.getLandLineNumber());
-		final DialableMobileNumber mobile = new MobileNumber(this.getMobileProvider(), this.getMobileNumber());
-		final DialableFaxNumber fax = new FaxNumber(this.getFaxCountry(), this.getFaxAreaCode(), this.getFaxNumber());
-
 		// Create new contact
-		Contact contact = new UserContact(this.getPersonalTitle(), this.getFirstName(), this.getFamilyName());
-		contact.setContactStreet(this.getStreet());
-		contact.setContactHouseNumber(this.getHouseNumber());
-		contact.setContactHouseNumberExtension(this.getHouseNumberExtension());
-		contact.setContactZipCode(this.getZipCode());
-		contact.setContactCity(this.getCity());
-		contact.setContactCountry(this.getCountry());
-		contact.setContactEmailAddress(this.getEmailAddress());
-		contact.setContactBirthday(this.getBirthday());
-		contact.setContactComment(this.getComment());
+		final Contact contact = new UserContact(
+					  this.getPersonalTitle(),
+					  this.getFirstName(),
+					  this.getFamilyName()
+			  );
 
-		// Don't set null or wrong references
-		if ((landLine instanceof DialableLandLineNumber) && (landLine.getPhoneCountry() instanceof Country) && (this.getLandLineAreaCode() != null) && (this.getLandLineNumber() != null) && (this.getLandLineAreaCode() > 0) && (this.getLandLineNumber() > 0)) {
-			// Now the number must be given
-			if (landLine.getPhoneAreaCode() == null) {
-				// Is null
-				throw new NullPointerException("phone.phoneAreaCode is null"); //NOI18N
-			} else if (landLine.getPhoneAreaCode() < 1) {
-				// Abort here
-				throw new IllegalArgumentException("phone.phoneAreaCode is zero or below."); //NOI18N
-			} else if (landLine.getPhoneNumber() == null) {
-				// Is null
-				throw new NullPointerException("phone.phoneNumber is null"); //NOI18N
-			} else if (landLine.getPhoneNumber() < 1) {
-				// Abort here
-				throw new IllegalArgumentException("phone.phoneNumber is zero or below."); //NOI18N
-			}
-
-			// Set phone number
-			contact.setContactLandLineNumber(landLine);
-		}
-
-		// Don't set null or wrong references
-		if ((fax instanceof DialableFaxNumber) && (fax.getPhoneCountry() instanceof Country) && (this.getFaxAreaCode() != null) && (this.getFaxNumber() != null) && (this.getFaxAreaCode() > 0) && (this.getFaxNumber() > 0)) {
-			// Now the number must be given
-			if (fax.getPhoneAreaCode() == null) {
-				// Is null
-				throw new NullPointerException("fax.phoneAreaCode is null"); //NOI18N
-			} else if (fax.getPhoneAreaCode() < 1) {
-				// Abort here
-				throw new IllegalArgumentException("fax.phoneAreaCode is zero or below."); //NOI18N
-			} else if (fax.getPhoneNumber() == null) {
-				// Is null
-				throw new NullPointerException("fax.phoneNumber is null"); //NOI18N
-			} else if (fax.getPhoneNumber() < 1) {
-				// Abort here
-				throw new IllegalArgumentException("fax.phoneNumber is zero or below."); //NOI18N
-			}
-
-			// Set fax number
-			contact.setContactFaxNumber(fax);
-		}
-
-		// Is the provider set?
-		if ((mobile instanceof DialableMobileNumber) && (this.getMobileProvider() instanceof MobileProvider) && (this.getMobileNumber() != null) && (this.getMobileNumber() > 0)) {
-			// Is the number set?
-			if (mobile.getPhoneNumber() == null) {
-				// Is null
-				throw new NullPointerException("mobile.phoneNumber is null"); //NOI18N
-			} else if (mobile.getPhoneNumber() < 1) {
-				// Abort here
-				throw new IllegalArgumentException("mobile.phoneNumber is zero or below."); //NOI18N
-			}
-
-			// Set mobile number
-			contact.setContactMobileNumber(mobile);
-		}
-
-		// Return it
+		// Return instance
 		return contact;
 	}
 
@@ -402,7 +341,7 @@ public class JobsContactWebRequestBean extends BaseJobsBean implements JobsConta
 		}
 
 		// Get contact instance
-		Contact contact = this.userLoginController.getLoggedInUser().getUserContact();
+		final Contact contact = this.userLoginController.getLoggedInUser().getUserContact();
 
 		// It should be there, so run some tests on it
 		assert (contact instanceof Contact) : "Instance userLoginController.loggedInUser.userContact is null"; //NOI18N
@@ -421,16 +360,16 @@ public class JobsContactWebRequestBean extends BaseJobsBean implements JobsConta
 		contact.setContactCountry(this.getCountry());
 
 		// Update contact's mobile number
-		this.isMobileUnlinked = Contacts.updateMobileNumber(contact, this.getMobileProvider(), this.getMobileNumber());
+		final boolean isMobileUnlinked = Contacts.updateMobileNumber(contact, this.getMobileProvider(), this.getMobileNumber());
 
 		// Update contact's land-line number
-		this.isLandLineUnlinked = Contacts.updateLandLineNumber(contact, this.getLandLineCountry(), this.getLandLineAreaCode(), this.getLandLineNumber());
+		final boolean isLandLineUnlinked = Contacts.updateLandLineNumber(contact, this.getLandLineCountry(), this.getLandLineAreaCode(), this.getLandLineNumber());
 
 		// Update contact's fax number
-		this.isFaxUnlinked = Contacts.updateFaxNumber(contact, this.getFaxCountry(), this.getFaxAreaCode(), this.getFaxNumber());
+		final boolean isFaxUnlinked = Contacts.updateFaxNumber(contact, this.getFaxCountry(), this.getFaxAreaCode(), this.getFaxNumber());
 
 		// Send it to the EJB
-		this.contactBean.updateContactData(contact, this.isMobileUnlinked, this.isLandLineUnlinked, this.isFaxUnlinked);
+		this.contactBean.updateContactData(contact, isMobileUnlinked, isLandLineUnlinked, isFaxUnlinked);
 
 		// All fine
 		return "contact_data_saved"; //NOI18N
@@ -909,24 +848,6 @@ public class JobsContactWebRequestBean extends BaseJobsBean implements JobsConta
 		return (Objects.equals(this.getEmailAddress(), this.getEmailAddressRepeat()));
 	}
 
-	@Override
-	public void updateContactDataFromController (final Contact contact) {
-		// Is the instance valid?
-		if (null == contact) {
-			// Throw NPE
-			throw new NullPointerException("contact is null"); //NOI18N
-		} else if (contact.getContactId() == null) {
-			// Throw NPE
-			throw new NullPointerException("contact.contactId is null"); //NOI18N
-		} else if (contact.getContactId() < 1) {
-			// Not valid id number
-			throw new IllegalArgumentException(MessageFormat.format("contact.contactId={0} is not valid.", contact.getContactId())); //NOI18N
-		}
-
-		// Set all
-		this.copyContact(contact);
-	}
-
 	/**
 	 * Clears this bean
 	 */
@@ -961,11 +882,11 @@ public class JobsContactWebRequestBean extends BaseJobsBean implements JobsConta
 	}
 
 	/**
-	 * Copies given contact into the controller
+	 * Copies given contact data into the controller
 	 * <p>
 	 * @param contact Contact instance
 	 */
-	private void copyContact (final Contact contact) {
+	private void copyFromContact (final Contact contact) {
 		// Copy all fields:
 		// - base data
 		this.setPersonalTitle(contact.getContactPersonalTitle());
@@ -983,26 +904,111 @@ public class JobsContactWebRequestBean extends BaseJobsBean implements JobsConta
 		this.setComment(contact.getContactComment());
 
 		// Get mobile, phone and fax instance
-		DialableMobileNumber mobile = contact.getContactMobileNumber();
-		DialableFaxNumber fax = contact.getContactFaxNumber();
-		DialableLandLineNumber phone = contact.getContactLandLineNumber();
+		final DialableFaxNumber fax = contact.getContactFaxNumber();
+		final DialableLandLineNumber landLine = contact.getContactLandLineNumber();
+		final DialableMobileNumber mobile = contact.getContactMobileNumber();
 
-		// - contact data
-		if ((phone instanceof DialableLandLineNumber) && (phone.getPhoneAreaCode() > 0)) {
-			this.setLandLineCountry(phone.getPhoneCountry());
-			this.setLandLineAreaCode(phone.getPhoneAreaCode());
-			this.setLandLineNumber(phone.getPhoneNumber());
+		// Is a fax number set?
+		if ((fax instanceof DialableFaxNumber) && (fax.getPhoneAreaCode() > 0)) {
+			// Copy elements
+			this.setFaxCountry(fax.getPhoneCountry());
+			this.setFaxAreaCode(fax.getPhoneAreaCode());
+			this.setFaxNumber(fax.getPhoneNumber());
+		}
+
+		// Is a land-line number set?
+		if ((landLine instanceof DialableLandLineNumber) && (landLine.getPhoneAreaCode() > 0)) {
+			// Copy elements
+			this.setLandLineCountry(landLine.getPhoneCountry());
+			this.setLandLineAreaCode(landLine.getPhoneAreaCode());
+			this.setLandLineNumber(landLine.getPhoneNumber());
 		}
 
+		// Is a mobile number set?
 		if ((mobile instanceof DialableMobileNumber) && (mobile.getMobileProvider() instanceof MobileProvider)) {
+			// Copy elements
 			this.setMobileProvider(mobile.getMobileProvider());
-			this.setMobileNumber(mobile.getPhoneNumber());
+			this.setMobileNumber(mobile.getMobileNumber());
 		}
+	}
 
-		if ((fax instanceof DialableFaxNumber) && (fax.getPhoneAreaCode() > 0)) {
-			this.setFaxCountry(fax.getPhoneCountry());
-			this.setFaxAreaCode(fax.getPhoneAreaCode());
-			this.setFaxNumber(fax.getPhoneNumber());
+	/**
+	 * Copies all fields from this backing bean into given instance.
+	 * <p>
+	 * @param contact An instance of a Contact class
+	 */
+	private void copyToContact (final Contact contact) {
+		// Set other elements
+		contact.setContactStreet(this.getStreet());
+		contact.setContactHouseNumber(this.getHouseNumber());
+		contact.setContactHouseNumberExtension(this.getHouseNumberExtension());
+		contact.setContactZipCode(this.getZipCode());
+		contact.setContactCity(this.getCity());
+		contact.setContactCountry(this.getCountry());
+		contact.setContactEmailAddress(this.getEmailAddress());
+		contact.setContactBirthday(this.getBirthday());
+		contact.setContactComment(this.getComment());
+
+		// Generate phone number
+		final DialableLandLineNumber landLine = new LandLineNumber(this.getLandLineCountry(), this.getLandLineAreaCode(), this.getLandLineNumber());
+		final DialableMobileNumber mobile = new MobileNumber(this.getMobileProvider(), this.getMobileNumber());
+		final DialableFaxNumber fax = new FaxNumber(this.getFaxCountry(), this.getFaxAreaCode(), this.getFaxNumber());
+
+		// Don't set null or wrong references
+		if ((landLine instanceof DialableLandLineNumber) && (landLine.getPhoneCountry() instanceof Country) && (this.getLandLineAreaCode() != null) && (this.getLandLineNumber() != null) && (this.getLandLineAreaCode() > 0) && (this.getLandLineNumber() > 0)) {
+			// Now the number must be given
+			if (landLine.getPhoneAreaCode() == null) {
+				// Is null
+				throw new NullPointerException("phone.phoneAreaCode is null"); //NOI18N
+			} else if (landLine.getPhoneAreaCode() < 1) {
+				// Abort here
+				throw new IllegalArgumentException("phone.phoneAreaCode is zero or below."); //NOI18N
+			} else if (landLine.getPhoneNumber() == null) {
+				// Is null
+				throw new NullPointerException("phone.phoneNumber is null"); //NOI18N
+			} else if (landLine.getPhoneNumber() < 1) {
+				// Abort here
+				throw new IllegalArgumentException("phone.phoneNumber is zero or below."); //NOI18N
+			}
+
+			// Set phone number
+			contact.setContactLandLineNumber(landLine);
+		}
+
+		// Don't set null or wrong references
+		if ((fax instanceof DialableFaxNumber) && (fax.getPhoneCountry() instanceof Country) && (this.getFaxAreaCode() != null) && (this.getFaxNumber() != null) && (this.getFaxAreaCode() > 0) && (this.getFaxNumber() > 0)) {
+			// Now the number must be given
+			if (fax.getPhoneAreaCode() == null) {
+				// Is null
+				throw new NullPointerException("fax.phoneAreaCode is null"); //NOI18N
+			} else if (fax.getPhoneAreaCode() < 1) {
+				// Abort here
+				throw new IllegalArgumentException("fax.phoneAreaCode is zero or below."); //NOI18N
+			} else if (fax.getPhoneNumber() == null) {
+				// Is null
+				throw new NullPointerException("fax.phoneNumber is null"); //NOI18N
+			} else if (fax.getPhoneNumber() < 1) {
+				// Abort here
+				throw new IllegalArgumentException("fax.phoneNumber is zero or below."); //NOI18N
+			}
+
+			// Set fax number
+			contact.setContactFaxNumber(fax);
+		}
+
+		// Is the provider set?
+		if ((mobile instanceof DialableMobileNumber) && (this.getMobileProvider() instanceof MobileProvider) && (this.getMobileNumber() != null) && (this.getMobileNumber() > 0)) {
+			// Is the number set?
+			if (mobile.getMobileNumber() == null) {
+				// Is null
+				throw new NullPointerException("mobile.phoneNumber is null"); //NOI18N
+			} else if (mobile.getMobileNumber() < 1) {
+				// Abort here
+				throw new IllegalArgumentException("mobile.phoneNumber is zero or below."); //NOI18N
+			}
+
+			// Set mobile number
+			contact.setContactMobileNumber(mobile);
 		}
 	}
 
diff --git a/src/java/org/mxchange/jjobs/beans/contact/JobsContactWebRequestController.java b/src/java/org/mxchange/jjobs/beans/contact/JobsContactWebRequestController.java
index a09dcf2c..3f58bb01 100644
--- a/src/java/org/mxchange/jjobs/beans/contact/JobsContactWebRequestController.java
+++ b/src/java/org/mxchange/jjobs/beans/contact/JobsContactWebRequestController.java
@@ -43,13 +43,6 @@ public interface JobsContactWebRequestController extends Serializable {
 	 */
 	void clearEmailAddresses ();
 
-	/**
-	 * Updates all data from bean in given contact instance
-	 * <p>
-	 * @param userContact Contact instance to update
-	 */
-	void updateContactDataFromController (final Contact userContact);
-
 	/**
 	 * Creates an instance from all properties
 	 * <p>
diff --git a/src/java/org/mxchange/jjobs/beans/contact/list/JobsContactListWebViewBean.java b/src/java/org/mxchange/jjobs/beans/contact/list/JobsContactListWebViewBean.java
index b46f0eab..0cd3e999 100644
--- a/src/java/org/mxchange/jjobs/beans/contact/list/JobsContactListWebViewBean.java
+++ b/src/java/org/mxchange/jjobs/beans/contact/list/JobsContactListWebViewBean.java
@@ -31,6 +31,9 @@ import javax.inject.Inject;
 import javax.inject.Named;
 import org.mxchange.jcontacts.events.contact.add.ObservableAdminAddedContactEvent;
 import org.mxchange.jcontacts.events.contact.update.ObservableAdminUpdatedContactEvent;
+import org.mxchange.jcontacts.events.fax.unlinked.ObservableAdminUnlinkedFaxNumberEvent;
+import org.mxchange.jcontacts.events.landline.unlinked.ObservableAdminUnlinkedLandLineNumberEvent;
+import org.mxchange.jcontacts.events.mobile.unlinked.ObservableAdminUnlinkedMobileNumberEvent;
 import org.mxchange.jcontacts.exceptions.ContactNotFoundException;
 import org.mxchange.jcontacts.model.contact.Contact;
 import org.mxchange.jcontacts.model.contact.ContactSessionBeanRemote;
@@ -120,6 +123,108 @@ public class JobsContactListWebViewBean extends BaseJobsBean implements JobsCont
 		this.uniqueAddContact(event.getAddedContact());
 	}
 
+	/**
+	 * Event observer for unlinked fax contact by administrators
+	 * <p>
+	 * @param event Unlinked fax contact event
+	 */
+	public void afterAdminUnlinkedFaxContactDataEvent (@Observes final ObservableAdminUnlinkedFaxNumberEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUnlinkedFaxNumber() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.unlinkedFaxNumber is null"); //NOI18N
+		} else if (event.getUnlinkedFaxNumber().getPhoneId() == null) {
+			// userId is null
+			throw new NullPointerException("event.unlinkedFaxNumber.contactId is null"); //NOI18N
+		} else if (event.getUnlinkedFaxNumber().getPhoneId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUnlinkedFaxNumber(), event.getUnlinkedFaxNumber().getPhoneId())); //NOI18N
+		}
+
+		// Remove it from any entry
+		for (final Cache.Entry<Long, Contact> entry : this.contactCache) {
+			// Get contact instance from it
+			final Contact contact = entry.getValue();
+
+			// Is the number matching?
+			if (Objects.equals(event.getUnlinkedFaxNumber(), contact.getContactFaxNumber())) {
+				// Yes, then unset it
+				contact.setContactFaxNumber(null);
+			}
+		}
+	}
+
+	/**
+	 * Event observer for unlinked land-line contact by administrators
+	 * <p>
+	 * @param event Unlinked land-line contact event
+	 */
+	public void afterAdminUnlinkedLandLineContactDataEvent (@Observes final ObservableAdminUnlinkedLandLineNumberEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUnlinkedLandLineNumber() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.unlinkedLandLineNumber is null"); //NOI18N
+		} else if (event.getUnlinkedLandLineNumber().getPhoneId() == null) {
+			// userId is null
+			throw new NullPointerException("event.unlinkedLandLineNumber.contactId is null"); //NOI18N
+		} else if (event.getUnlinkedLandLineNumber().getPhoneId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUnlinkedLandLineNumber(), event.getUnlinkedLandLineNumber().getPhoneId())); //NOI18N
+		}
+
+		// Remove it from any entry
+		for (final Cache.Entry<Long, Contact> entry : this.contactCache) {
+			// Get contact instance from it
+			final Contact contact = entry.getValue();
+
+			// Is the number matching?
+			if (Objects.equals(event.getUnlinkedLandLineNumber(), contact.getContactLandLineNumber())) {
+				// Yes, then unset it
+				contact.setContactLandLineNumber(null);
+			}
+		}
+	}
+
+	/**
+	 * Event observer for unlinked mobile contact by administrators
+	 * <p>
+	 * @param event Unlinked mobile contact event
+	 */
+	public void afterAdminUnlinkedMobileContactDataEvent (@Observes final ObservableAdminUnlinkedMobileNumberEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUnlinkedMobileNumber() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.unlinkedMobileNumber is null"); //NOI18N
+		} else if (event.getUnlinkedMobileNumber().getMobileId() == null) {
+			// userId is null
+			throw new NullPointerException("event.unlinkedMobileNumber.contactId is null"); //NOI18N
+		} else if (event.getUnlinkedMobileNumber().getMobileId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUnlinkedMobileNumber(), event.getUnlinkedMobileNumber().getMobileId())); //NOI18N
+		}
+
+		// Remove it from any entry
+		for (final Cache.Entry<Long, Contact> entry : this.contactCache) {
+			// Get contact instance from it
+			final Contact contact = entry.getValue();
+
+			// Is the number matching?
+			if (Objects.equals(event.getUnlinkedMobileNumber(), contact.getContactMobileNumber())) {
+				// Yes, then unset it
+				contact.setContactMobileNumber(null);
+			}
+		}
+	}
+
 	/**
 	 * Event observer for updated contact data by administrators
 	 * <p>
@@ -238,7 +343,7 @@ public class JobsContactListWebViewBean extends BaseJobsBean implements JobsCont
 					 "%s%d%d", //NOI18N
 					 mobileNumber.getMobileProvider().getProviderCountry().getCountryExternalDialPrefix(),
 					 mobileNumber.getMobileProvider().getProviderDialPrefix(),
-					 mobileNumber.getPhoneNumber()
+					 mobileNumber.getMobileNumber()
 			 );
 
 		// Return it
@@ -324,7 +429,7 @@ public class JobsContactListWebViewBean extends BaseJobsBean implements JobsCont
 		// Is cache there?
 		if (!this.contactCache.iterator().hasNext()) {
 			// Add all
-			for (final Contact contact : this.contactBean.allContacts()) {
+			for (final Contact contact : this.contactBean.fetchAllContacts()) {
 				// Add it to cache
 				this.contactCache.put(contact.getContactId(), contact);
 			}
diff --git a/src/java/org/mxchange/jjobs/beans/contact/mobile/FinancialsAdminContactMobileWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/contact/mobile/FinancialsAdminContactMobileWebRequestBean.java
new file mode 100644
index 00000000..bde080e6
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/contact/mobile/FinancialsAdminContactMobileWebRequestBean.java
@@ -0,0 +1,531 @@
+/*
+ * Copyright (C) 2016 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.contact.mobile;
+
+import java.text.MessageFormat;
+import java.util.Date;
+import javax.ejb.EJB;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.event.Event;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Any;
+import javax.faces.application.FacesMessage;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jcontacts.events.contact.add.ObservableAdminAddedContactEvent;
+import org.mxchange.jcontacts.events.contact.created.ObservableCreatedContactEvent;
+import org.mxchange.jcontacts.events.contact.update.ObservableAdminUpdatedContactEvent;
+import org.mxchange.jcontacts.events.mobile.linked.AdminLinkedMobileNumberEvent;
+import org.mxchange.jcontacts.events.mobile.linked.ObservableAdminLinkedMobileNumberEvent;
+import org.mxchange.jcontacts.events.mobile.unlinked.AdminUnlinkedMobileNumberEvent;
+import org.mxchange.jcontacts.events.mobile.unlinked.ObservableAdminUnlinkedMobileNumberEvent;
+import org.mxchange.jcontacts.model.contact.Contact;
+import org.mxchange.jcontacts.model.phone.AdminContactsPhoneSessionBeanRemote;
+import org.mxchange.jfinancials.beans.BaseFinancialsBean;
+import org.mxchange.jfinancials.beans.phone.FinancialsAdminPhoneWebRequestController;
+import org.mxchange.jphone.events.mobile.created.ObservableCreatedMobileNumberEvent;
+import org.mxchange.jphone.exceptions.phone.PhoneNumberAlreadyLinkedException;
+import org.mxchange.jphone.exceptions.phone.PhoneNumberNotLinkedException;
+import org.mxchange.jphone.model.phonenumbers.mobile.DialableMobileNumber;
+import org.mxchange.jphone.model.phonenumbers.mobile.MobileNumber;
+import org.mxchange.jphone.model.phonenumbers.mobileprovider.MobileProvider;
+import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
+
+/**
+ * An administrative contact mobile controller (bean)
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("adminContactMobileController")
+@RequestScoped
+public class FinancialsAdminContactMobileWebRequestBean extends BaseFinancialsBean implements FinancialsAdminContactMobileWebRequestController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 542_145_347_919L;
+
+	/**
+	 * Administrative EJB for phone number
+	 */
+	@EJB (lookup = "java:global/jfinancials-ejb/adminContactPhone!org.mxchange.jcontacts.model.phone.AdminContactsPhoneSessionBeanRemote")
+	private AdminContactsPhoneSessionBeanRemote adminContactPhoneBean;
+
+	/**
+	 * Event being fired when a mobile number has been linked
+	 */
+	@Inject
+	@Any
+	private Event<ObservableAdminLinkedMobileNumberEvent> adminLinkedMobileNumberEvent;
+
+	/**
+	 * Administrative phone controller
+	 */
+	@Inject
+	private FinancialsAdminPhoneWebRequestController adminPhoneController;
+
+	/**
+	 * Contact instance
+	 */
+	private Contact contact;
+
+	/**
+	 * When mobile number has been created
+	 */
+	private Date mobileEntryCreated;
+
+	/**
+	 * When mobile number has been updated
+	 */
+	private Date mobileEntryUpdated;
+
+	/**
+	 * Phone id (primary key)
+	 */
+	private Long mobileId;
+
+	/**
+	 * Mobile number
+	 */
+	private Long mobileNumber;
+
+	/**
+	 * Event being fired when administrator unlinks mobile from contact
+	 */
+	@Inject
+	@Any
+	private Event<ObservableAdminUnlinkedMobileNumberEvent> mobileNumberUnlinkedEvent;
+
+	/**
+	 * Mobile provider
+	 */
+	private MobileProvider mobileProvider;
+
+	/**
+	 * Default constructor
+	 */
+	public FinancialsAdminContactMobileWebRequestBean () {
+		// Call super constructor
+		super();
+
+		// String caller = MessageFormat.format("{0}.{1}", Thread.currentThread().getStackTrace()[3].getClassName(), Thread.currentThread().getStackTrace()[3].getMethodName());
+		// System.out.println(MessageFormat.format("{0}: Constructed, caller: {1}", this.getClass().getSimpleName(), caller));
+	}
+
+	/**
+	 * Observes events being fired when an administrator has added a new
+	 * contact.
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminAddedContactEvent (@Observes final ObservableAdminAddedContactEvent event) {
+		// The event must be valid
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getAddedContact() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.addedContact is null"); //NOI18N
+		} else if (event.getAddedContact().getContactId() == null) {
+			// ... and again
+			throw new NullPointerException("event.addedContact.contactId is null"); //NOI18N
+		} else if (event.getAddedContact().getContactId() < 1) {
+			// Not valid
+			throw new IllegalArgumentException(MessageFormat.format("event.addedContact.contactId={0} is not valid", event.getAddedContact().getContactId())); //NOI18N
+		}
+
+		// Clear this bean
+		this.clear();
+	}
+
+	/**
+	 * Event observer for newly added users by administrator
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getAddedUser() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.addedUser is null"); //NOI18N
+		} else if (event.getAddedUser().getUserId() == null) {
+			// userId is null
+			throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
+		} else if (event.getAddedUser().getUserId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
+		}
+
+		// Clear all data
+		this.clear();
+	}
+
+	/**
+	 * Event observer for updated contact data by administrators
+	 * <p>
+	 * @param event Updated contact data event
+	 */
+	public void afterAdminUpdatedContactDataEvent (@Observes final ObservableAdminUpdatedContactEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUpdatedContact() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.updatedContact is null"); //NOI18N
+		} else if (event.getUpdatedContact().getContactId() == null) {
+			// userId is null
+			throw new NullPointerException("event.updatedContact.contactId is null"); //NOI18N
+		} else if (event.getUpdatedContact().getContactId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUpdatedContact(), event.getUpdatedContact().getContactId())); //NOI18N
+		}
+
+		// Clear all data
+		this.clear();
+	}
+
+	/**
+	 * Observer for events being fired when a bean helper has successfully
+	 * created a contact instance.
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterCreatedContactEvent (@Observes final ObservableCreatedContactEvent event) {
+		// Log message
+		//* NOISY-DEBUG: */ System.out.println(MessageFormat.format("AdminContactController::afterCreatedContactEvent(): contact={0} - CALLED!", contact)); //NOI18N
+
+		// The event instance must be valid
+		if (null == event) {
+			// Throw NPE again
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getCreatedContact() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.createdContact is null"); //NOI18N //NOI18N
+		} else if (event.getCreatedContact().getContactId() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.createdContact.contactId is null"); //NOI18N //NOI18N
+		} else if (event.getCreatedContact().getContactId() < 1) {
+			// Not valid
+			throw new IllegalStateException(MessageFormat.format("event.createdContact.contactId={0} is not valid.", event.getCreatedContact().getContactId())); //NOI18N
+		}
+
+		// Set it here
+		this.setContact(event.getCreatedContact());
+	}
+
+	/**
+	 * Observes events being fired when a bean helper has successfully created a
+	 * mobile number instance.
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterCreatedMobileNumberEvent (@Observes final ObservableCreatedMobileNumberEvent event) {
+		// The event instance must be valid
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getMobileNumber() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.mobileNumber is null"); //NOI18N
+		} else if (event.getMobileNumber().getMobileId() == null) {
+			// Throw NPE yet again
+			throw new NullPointerException("event.mobileNumber.mobileId is null"); //NOI18N
+		} else if (event.getMobileNumber().getMobileId() < 1) {
+			// Throw NPE yet again
+			throw new NullPointerException(MessageFormat.format("event.mobileNumber.mobileId={0} is invalid", event.getMobileNumber().getMobileId())); //NOI18N
+		}
+
+		// Get fax number from event
+		final DialableMobileNumber number = event.getMobileNumber();
+
+		// Copy all data to this bean
+		this.setMobileId(number.getMobileId());
+		this.setMobileProvider(number.getMobileProvider());
+		this.setMobileNumber(number.getMobileNumber());
+		this.setMobileEntryCreated(number.getMobileEntryCreated());
+		this.setMobileEntryUpdated(number.getMobileEntryUpdated());
+	}
+
+	/**
+	 * Links mobile number to contact from bean helper as "main mobile number".
+	 * <p>
+	 * @return Redirect outcome
+	 */
+	public String doLinkMainMobileNumber () {
+		// Get contact from helper
+		final Contact targetContact = this.getContact();
+
+		// Is all data properly set?
+		if (null == targetContact) {
+			// Throw NPE
+			throw new NullPointerException("targetContact is null"); //NOI18N
+		} else if (targetContact.getContactId() == null) {
+			// Throw it again
+			throw new NullPointerException("targetContact.contactId is null"); //NOI18N
+		} else if (targetContact.getContactId() < 1) {
+			// Is not valid
+			throw new IllegalArgumentException(MessageFormat.format("targetContact.contactId={0} is not valid", targetContact.getContactId())); //NOI18N
+		} else if (this.getMobileProvider() == null) {
+			// Throw NPE
+			throw new NullPointerException("this.mobileProvider is null"); //NOI18N
+		} else if (this.getMobileProvider().getProviderId() == null) {
+			// Throw NPE
+			throw new NullPointerException("this.mobileProvider.providerId is null"); //NOI18N
+		} else if (this.getMobileProvider().getProviderId() < 1) {
+			// Throw NPE
+			throw new NullPointerException(MessageFormat.format("this.mobileProvider.providerId={0} is invalid", this.getMobileProvider().getProviderId())); //NOI18N
+		} else if (this.getMobileNumber() == null) {
+			// Throw NPE again
+			throw new NullPointerException("this.mobileNumber is null"); //NOI18N
+		} else if (this.getMobileNumber() < 1) {
+			// Invalid id number
+			throw new IllegalArgumentException(MessageFormat.format("this.mobileNumber={0} is invalid", this.getMobileNumber())); //NOI18N
+		}
+
+		// Init instance
+		final Contact updatedContact;
+		final DialableMobileNumber number = new MobileNumber(this.getMobileProvider(), this.getMobileNumber());
+
+		// Try it again
+		try {
+			// Link it, too
+			updatedContact = this.adminContactPhoneBean.linkNewMobileNumberWithContact(targetContact, number);
+		} catch (final PhoneNumberAlreadyLinkedException ex) {
+			// Throw again as cause
+			this.showFacesMessage("form_add_contact_mobile:mobileNumber", ex, FacesMessage.SEVERITY_ERROR); //NOI18N
+			return ""; //NOI18N
+		}
+
+		// Fire event
+		this.adminLinkedMobileNumberEvent.fire(new AdminLinkedMobileNumberEvent(updatedContact, number));
+
+		// Return to contact profile
+		return "admin_show_contact"; //NOI18N
+	}
+
+	/**
+	 * Getter for contact instance
+	 * <p>
+	 * @return Contact instance
+	 */
+	public Contact getContact () {
+		return this.contact;
+	}
+
+	/**
+	 * Setter for contact instance
+	 * <p>
+	 * @param contact Contact instance
+	 */
+	public void setContact (final Contact contact) {
+		this.contact = contact;
+	}
+
+	/**
+	 * Setter for phone id
+	 * <p>
+	 * @return Phone id
+	 */
+	public Long getMobileId () {
+		return this.mobileId;
+	}
+
+	/**
+	 * Getter for phone id
+	 * <p>
+	 * @param mobileId Phone id
+	 */
+	public void setMobileId (final Long mobileId) {
+		this.mobileId = mobileId;
+	}
+
+	/**
+	 * Getter for mobile number
+	 * <p>
+	 * @return Mobile number
+	 */
+	public Long getMobileNumber () {
+		return this.mobileNumber;
+	}
+
+	/**
+	 * Setter for mobile number
+	 * <p>
+	 * @param mobileNumber Mobile number
+	 */
+	public void setMobileNumber (final Long mobileNumber) {
+		this.mobileNumber = mobileNumber;
+	}
+
+	/**
+	 * Getter for mobile provider
+	 * <p>
+	 * @return Mobile provider
+	 */
+	public MobileProvider getMobileProvider () {
+		return this.mobileProvider;
+	}
+
+	/**
+	 * Setter for mobile provider
+	 * <p>
+	 * @param mobileProvider Mobile provider
+	 */
+	public void setMobileProvider (final MobileProvider mobileProvider) {
+		this.mobileProvider = mobileProvider;
+	}
+
+	/**
+	 * Unlinks mobile data with current contact
+	 * <p>
+	 * @return Redirect outcome
+	 */
+	public String unlinkMobileContactData () {
+		// Create fax number instance
+		final DialableMobileNumber number = this.createMobileNumber();
+
+		// Is all data set
+		if (number == null) {
+			// Not set, throw NPE
+			throw new NullPointerException("number is null"); //NOI18N
+		} else if (number.getMobileId() == null) {
+			// Throw NPE again
+			throw new NullPointerException("number.phoneId is null"); //NOI18N
+		} else if (number.getMobileId() < 1) {
+			// Invalid number
+			throw new IllegalArgumentException(MessageFormat.format("number.phoneId={0} is not valid", number.getMobileId())); //NOI18N
+		} else if (number.getMobileProvider() == null) {
+			// Throw NPE
+			throw new NullPointerException("number.mobileProvider is null"); //NOI18N
+		} else if (number.getMobileProvider().getProviderId() == null) {
+			// ... throw again
+			throw new NullPointerException("number.mobileProvider.providerId is null"); //NOI18N
+		} else if (number.getMobileProvider().getProviderId() < 1) {
+			// Id not valid
+			throw new IllegalArgumentException(MessageFormat.format("number.mobileProvider.providerId={0} is not valid.", number.getMobileProvider().getProviderId())); //NOI18N
+		} else if (number.getMobileNumber() == null) {
+			// Throw NPE again
+			throw new NullPointerException("number.phoneNumber is null"); //NOI18N
+		} else if (number.getMobileNumber() < 1) {
+			// Throw it again ...
+			throw new NullPointerException(MessageFormat.format("number.phoneNumber={0} is not valid.", number.getMobileNumber())); //NOI18N
+		} else if (this.getContact() == null) {
+			// ... and throw again
+			throw new NullPointerException("this.contact is null"); //NOI18N
+		} else if (this.getContact().getContactId() == null) {
+			// ... and again ...
+			throw new NullPointerException("this.contact.contactId is null"); //NOI18N
+		} else if (this.getContact().getContactId() < 1) {
+			// Invalid id number
+			throw new IllegalArgumentException(MessageFormat.format("this.contact.contactId={0} is invalid.", this.getContact().getContactId())); //NOI18N
+		}
+
+		// Init contact instance
+		final Contact updatedContact;
+
+		try {
+			// Unlink it and return contact without mobile instance
+			updatedContact = this.adminContactPhoneBean.unlinkMobileDataFromContact(this.getContact(), number);
+		} catch (final PhoneNumberNotLinkedException ex) {
+			// Did not work
+			this.showFacesMessage("form_unlink_contact_mobile:mobileNumberId", ex, FacesMessage.SEVERITY_ERROR); //NOI18N
+			return ""; //NOI18N
+		}
+
+		// Fire event
+		this.mobileNumberUnlinkedEvent.fire(new AdminUnlinkedMobileNumberEvent(updatedContact, number));
+
+		// All fine here
+		return "admin_show_contact"; //NOI18N
+	}
+
+	/**
+	 * Clears this bean
+	 */
+	private void clear () {
+		// Clear all data
+	}
+
+	/**
+	 * Returns an instance of a DialableMobileNumber from all fields stored in
+	 * this bean.
+	 * <p>
+	 * @return An instance of a DialableMobileNumber class
+	 */
+	private DialableMobileNumber createMobileNumber () {
+		// Initialize it
+		final DialableMobileNumber number = new MobileNumber(this.getMobileProvider(), this.getMobileNumber());
+
+		// Add all other data
+		number.setMobileEntryCreated(this.getMobileEntryCreated());
+		number.setMobileEntryUpdated(this.getMobileEntryUpdated());
+
+		// Is id number set?
+		if (this.getMobileId() instanceof Long) {
+			// Set it
+			number.setMobileId(this.getMobileId());
+		}
+
+		// Return it
+		return number;
+	}
+
+	/**
+	 * Getter for mobile entry created
+	 * <p>
+	 * @return Mobile entry created
+	 */
+	@SuppressWarnings ("ReturnOfDateField")
+	private Date getMobileEntryCreated () {
+		return this.mobileEntryCreated;
+	}
+
+	/**
+	 * Setter for mobile entry created
+	 * <p>
+	 * @param mobileEntryCreated Mobile entry created
+	 */
+	@SuppressWarnings ("AssignmentToDateFieldFromParameter")
+	private void setMobileEntryCreated (final Date mobileEntryCreated) {
+		this.mobileEntryCreated = mobileEntryCreated;
+	}
+
+	/**
+	 * Getter for mobile entry updated
+	 * <p>
+	 * @return Mobile entry updated
+	 */
+	@SuppressWarnings ("ReturnOfDateField")
+	private Date getMobileEntryUpdated () {
+		return this.mobileEntryUpdated;
+	}
+
+	/**
+	 * Setter for mobile entry updated
+	 * <p>
+	 * @param mobileEntryUpdated Mobile entry updated
+	 */
+	@SuppressWarnings ("AssignmentToDateFieldFromParameter")
+	private void setMobileEntryUpdated (final Date mobileEntryUpdated) {
+		this.mobileEntryUpdated = mobileEntryUpdated;
+	}
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/contact/mobile/FinancialsAdminContactMobileWebRequestController.java b/src/java/org/mxchange/jjobs/beans/contact/mobile/FinancialsAdminContactMobileWebRequestController.java
new file mode 100644
index 00000000..0e0f0b20
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/contact/mobile/FinancialsAdminContactMobileWebRequestController.java
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright (C) 2016 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.contact.mobile;
+
+import org.mxchange.jfinancials.beans.contact.phone.*;
+import java.io.Serializable;
+
+/**
+ * An interface for user beans
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsAdminContactMobileWebRequestController extends Serializable {
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/contact/mobile/FinancialsContactMobileWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/contact/mobile/FinancialsContactMobileWebRequestBean.java
new file mode 100644
index 00000000..a3ef2762
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/contact/mobile/FinancialsContactMobileWebRequestBean.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2016 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.contact.mobile;
+
+import java.text.MessageFormat;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.event.Observes;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jcontacts.events.contact.add.ObservableAdminAddedContactEvent;
+import org.mxchange.jcontacts.events.contact.update.ObservableAdminUpdatedContactEvent;
+import org.mxchange.jcontacts.model.contact.Contact;
+import org.mxchange.jfinancials.beans.BaseFinancialsBean;
+import org.mxchange.jfinancials.beans.contact.list.FinancialsContactListWebViewController;
+import org.mxchange.jphone.events.mobile.created.ObservableCreatedMobileNumberEvent;
+import org.mxchange.jphone.model.phonenumbers.mobile.DialableMobileNumber;
+import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
+
+/**
+ * A general contact bean (controller)
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("contactMobileController")
+@RequestScoped
+public class FinancialsContactMobileWebRequestBean extends BaseFinancialsBean implements FinancialsContactMobileWebRequestController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 542_145_347_916L;
+
+	/**
+	 * An instance of a contact-list controller
+	 */
+	@Inject
+	private FinancialsContactListWebViewController contactListController;
+
+	/**
+	 * Chosen mobile number
+	 */
+	private DialableMobileNumber mobileNumber;
+
+	/**
+	 * Default constructor
+	 */
+	public FinancialsContactMobileWebRequestBean () {
+		// Call super constructor
+		super();
+	}
+
+	/**
+	 * Observes events being fired when an administrator has added a new
+	 * contact.
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminAddedContactEvent (@Observes final ObservableAdminAddedContactEvent event) {
+		// The event must be valid
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getAddedContact() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.addedContact is null"); //NOI18N
+		} else if (event.getAddedContact().getContactId() == null) {
+			// ... and again
+			throw new NullPointerException("event.addedContact.contactId is null"); //NOI18N
+		} else if (event.getAddedContact().getContactId() < 1) {
+			// Not valid
+			throw new IllegalArgumentException(MessageFormat.format("event.addedContact.contactId={0} is not valid", event.getAddedContact().getContactId())); //NOI18N
+		}
+
+		// Clear this bean
+		this.clear();
+	}
+
+	/**
+	 * Event observer for newly added users by administrator
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getAddedUser() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.addedUser is null"); //NOI18N
+		} else if (event.getAddedUser().getUserId() == null) {
+			// userId is null
+			throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
+		} else if (event.getAddedUser().getUserId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
+		}
+
+		// Clear all data
+		this.clear();
+	}
+
+	/**
+	 * Event observer for updated contact data by administrators
+	 * <p>
+	 * @param event Updated contact data event
+	 */
+	public void afterAdminUpdatedContactDataEvent (@Observes final ObservableAdminUpdatedContactEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUpdatedContact() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.updatedContact is null"); //NOI18N
+		} else if (event.getUpdatedContact().getContactId() == null) {
+			// userId is null
+			throw new NullPointerException("event.updatedContact.contactId is null"); //NOI18N
+		} else if (event.getUpdatedContact().getContactId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUpdatedContact(), event.getUpdatedContact().getContactId())); //NOI18N
+		}
+
+		// Clear all data
+		this.clear();
+	}
+
+	/**
+	 * Observes events being fired when a bean helper has successfully created a
+	 * mobile number instance.
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterCreatedMobileNumberEvent (@Observes final ObservableCreatedMobileNumberEvent event) {
+		// The event instance must be valid
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getMobileNumber() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.mobileNumber is null"); //NOI18N
+		} else if (event.getMobileNumber().getMobileId() == null) {
+			// Throw NPE yet again
+			throw new NullPointerException("event.mobileNumber.mobileId is null"); //NOI18N
+		} else if (event.getMobileNumber().getMobileId() < 1) {
+			// Throw NPE yet again
+			throw new NullPointerException(MessageFormat.format("event.mobileNumber.mobileId={0} is invalid", event.getMobileNumber().getMobileId())); //NOI18N
+		}
+
+		// Set it here
+		this.setMobileNumber(event.getMobileNumber());
+	}
+
+	/**
+	 * Getter for all contacts having current mobile number linked
+	 * <p>
+	 * @return List of all linked contacts
+	 */
+	public List<Contact> allCurrentMobileNumberContacts () {
+		// Get id
+		final DialableMobileNumber dialableMobileNumber = this.getMobileNumber();
+
+		// Init list
+		final List<Contact> contacts = new LinkedList<>();
+
+		// "Walk" through all contacts
+		for (final Contact contact : this.contactListController.getAllContacts()) {
+			// Is mobile instance the same?
+			if (Objects.equals(contact.getContactMobileNumber(), dialableMobileNumber)) {
+				// Found one
+				contacts.add(contact);
+			}
+		}
+
+		// Return now-cached list
+		return contacts;
+	}
+
+	/**
+	 * Getter for chosen mobile number
+	 * <p>
+	 * @return mobile number
+	 */
+	public DialableMobileNumber getMobileNumber () {
+		return this.mobileNumber;
+	}
+
+	/**
+	 * Setter for chosen mobile number
+	 * <p>
+	 * @param mobileNumber mobile number
+	 */
+	public void setMobileNumber (final DialableMobileNumber mobileNumber) {
+		this.mobileNumber = mobileNumber;
+	}
+
+	/**
+	 * Clears this bean
+	 */
+	private void clear () {
+		// Clear all data
+	}
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/contact/mobile/FinancialsContactMobileWebRequestController.java b/src/java/org/mxchange/jjobs/beans/contact/mobile/FinancialsContactMobileWebRequestController.java
new file mode 100644
index 00000000..1501a46c
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/contact/mobile/FinancialsContactMobileWebRequestController.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.contact.mobile;
+
+import org.mxchange.jfinancials.beans.contact.phone.*;
+import java.io.Serializable;
+
+/**
+ * An interface for user beans
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsContactMobileWebRequestController extends Serializable {
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/contact/phone/JobsAdminContactPhoneWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/contact/phone/JobsAdminContactPhoneWebRequestBean.java
index f411c9e2..5d1f90be 100644
--- a/src/java/org/mxchange/jjobs/beans/contact/phone/JobsAdminContactPhoneWebRequestBean.java
+++ b/src/java/org/mxchange/jjobs/beans/contact/phone/JobsAdminContactPhoneWebRequestBean.java
@@ -37,10 +37,6 @@ import org.mxchange.jcontacts.events.landline.linked.AdminLinkedLandLineNumberEv
 import org.mxchange.jcontacts.events.landline.linked.ObservableAdminLinkedLandLineNumberEvent;
 import org.mxchange.jcontacts.events.landline.unlinked.AdminUnlinkedLandLineNumberEvent;
 import org.mxchange.jcontacts.events.landline.unlinked.ObservableAdminUnlinkedLandLineNumberEvent;
-import org.mxchange.jcontacts.events.mobile.linked.AdminLinkedMobileNumberEvent;
-import org.mxchange.jcontacts.events.mobile.linked.ObservableAdminLinkedMobileNumberEvent;
-import org.mxchange.jcontacts.events.mobile.unlinked.AdminUnlinkedMobileNumberEvent;
-import org.mxchange.jcontacts.events.mobile.unlinked.ObservableAdminUnlinkedMobileNumberEvent;
 import org.mxchange.jcontacts.model.contact.Contact;
 import org.mxchange.jcontacts.model.phone.AdminContactsPhoneSessionBeanRemote;
 import org.mxchange.jcountry.model.data.Country;
@@ -48,16 +44,12 @@ import org.mxchange.jjobs.beans.BaseJobsBean;
 import org.mxchange.jjobs.beans.phone.JobsAdminPhoneWebRequestController;
 import org.mxchange.jphone.events.fax.created.ObservableCreatedFaxNumberEvent;
 import org.mxchange.jphone.events.landline.created.ObservableCreatedLandLineNumberEvent;
-import org.mxchange.jphone.events.mobile.created.ObservableCreatedMobileNumberEvent;
 import org.mxchange.jphone.exceptions.phone.PhoneNumberAlreadyLinkedException;
 import org.mxchange.jphone.exceptions.phone.PhoneNumberNotLinkedException;
 import org.mxchange.jphone.model.phonenumbers.fax.DialableFaxNumber;
 import org.mxchange.jphone.model.phonenumbers.fax.FaxNumber;
 import org.mxchange.jphone.model.phonenumbers.landline.DialableLandLineNumber;
 import org.mxchange.jphone.model.phonenumbers.landline.LandLineNumber;
-import org.mxchange.jphone.model.phonenumbers.mobile.DialableMobileNumber;
-import org.mxchange.jphone.model.phonenumbers.mobile.MobileNumber;
-import org.mxchange.jphone.model.phonenumbers.mobileprovider.MobileProvider;
 import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
 
 /**
@@ -99,13 +91,6 @@ public class JobsAdminContactPhoneWebRequestBean extends BaseJobsBean implements
 	@Any
 	private Event<ObservableAdminLinkedLandLineNumberEvent> adminLinkedLandLineNumberEvent;
 
-	/**
-	 * Event being fired when a mobile number has been linked
-	 */
-	@Inject
-	@Any
-	private Event<ObservableAdminLinkedMobileNumberEvent> adminLinkedMobileNumberEvent;
-
 	/**
 	 * Administrative phone controller
 	 */
@@ -162,29 +147,12 @@ public class JobsAdminContactPhoneWebRequestBean extends BaseJobsBean implements
 	private Event<ObservableAdminUnlinkedLandLineNumberEvent> landLineNumberUnlinkedEvent;
 
 	/**
-	 * Mobile number
-	 */
-	private Long mobileNumber;
-
-	/**
-	 * Event being fired when administrator unlinks mobile from contact
-	 */
-	@Inject
-	@Any
-	private Event<ObservableAdminUnlinkedMobileNumberEvent> mobileNumberUnlinkedEvent;
-
-	/**
-	 * Mobile provider
-	 */
-	private MobileProvider mobileProvider;
-
-	/**
-	 * When fax number has been created
+	 * When phone number has been created
 	 */
 	private Date phoneEntryCreated;
 
 	/**
-	 * When fax number has been updated
+	 * When phone number has been updated
 	 */
 	private Date phoneEntryUpdated;
 
@@ -377,39 +345,6 @@ public class JobsAdminContactPhoneWebRequestBean extends BaseJobsBean implements
 		this.setPhoneEntryUpdated(number.getPhoneEntryUpdated());
 	}
 
-	/**
-	 * Observes events being fired when a bean helper has successfully created a
-	 * mobile number instance.
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterCreatedMobileNumberEvent (@Observes final ObservableCreatedMobileNumberEvent event) {
-		// The event instance must be valid
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getMobileNumber() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.mobileNumber is null"); //NOI18N
-		} else if (event.getMobileNumber().getPhoneId() == null) {
-			// Throw NPE yet again
-			throw new NullPointerException("event.mobileNumber.phoneId is null"); //NOI18N
-		} else if (event.getMobileNumber().getPhoneId() < 1) {
-			// Throw NPE yet again
-			throw new NullPointerException(MessageFormat.format("event.mobileNumber.phoneId={0} is invalid", event.getMobileNumber().getPhoneId())); //NOI18N
-		}
-
-		// Get fax number from event
-		final DialableMobileNumber number = event.getMobileNumber();
-
-		// Copy all data to this bean
-		this.setPhoneId(number.getPhoneId());
-		this.setMobileProvider(number.getMobileProvider());
-		this.setMobileNumber(number.getPhoneNumber());
-		this.setPhoneEntryCreated(number.getPhoneEntryCreated());
-		this.setPhoneEntryUpdated(number.getPhoneEntryUpdated());
-	}
-
 	/**
 	 * Links fax number to contact from bean helper as "main fax number".
 	 * <p>
@@ -537,63 +472,6 @@ public class JobsAdminContactPhoneWebRequestBean extends BaseJobsBean implements
 		return "admin_show_contact"; //NOI18N
 	}
 
-	/**
-	 * Links mobile number to contact from bean helper as "main mobile number".
-	 * <p>
-	 * @return Redirect outcome
-	 */
-	public String doLinkMainMobileNumber () {
-		// Get contact from helper
-		final Contact targetContact = this.getContact();
-
-		// Is all data properly set?
-		if (null == targetContact) {
-			// Throw NPE
-			throw new NullPointerException("targetContact is null"); //NOI18N
-		} else if (targetContact.getContactId() == null) {
-			// Throw it again
-			throw new NullPointerException("targetContact.contactId is null"); //NOI18N
-		} else if (targetContact.getContactId() < 1) {
-			// Is not valid
-			throw new IllegalArgumentException(MessageFormat.format("targetContact.contactId={0} is not valid", targetContact.getContactId())); //NOI18N
-		} else if (this.getMobileProvider() == null) {
-			// Throw NPE
-			throw new NullPointerException("this.mobileProvider is null"); //NOI18N
-		} else if (this.getMobileProvider().getProviderId() == null) {
-			// Throw NPE
-			throw new NullPointerException("this.mobileProvider.providerId is null"); //NOI18N
-		} else if (this.getMobileProvider().getProviderId() < 1) {
-			// Throw NPE
-			throw new NullPointerException(MessageFormat.format("this.mobileProvider.providerId={0} is invalid", this.getMobileProvider().getProviderId())); //NOI18N
-		} else if (this.getMobileNumber() == null) {
-			// Throw NPE again
-			throw new NullPointerException("this.mobileNumber is null"); //NOI18N
-		} else if (this.getMobileNumber() < 1) {
-			// Invalid id number
-			throw new IllegalArgumentException(MessageFormat.format("this.mobileNumber={0} is invalid", this.getMobileNumber())); //NOI18N
-		}
-
-		// Init instance
-		final Contact updatedContact;
-		final DialableMobileNumber number = new MobileNumber(this.getMobileProvider(), this.getMobileNumber());
-
-		// Try it again
-		try {
-			// Link it, too
-			updatedContact = this.adminContactPhoneBean.linkNewMobileNumberWithContact(targetContact, number);
-		} catch (final PhoneNumberAlreadyLinkedException ex) {
-			// Throw again as cause
-			this.showFacesMessage("form_add_contact_mobile:mobileNumber", ex, FacesMessage.SEVERITY_ERROR); //NOI18N
-			return ""; //NOI18N
-		}
-
-		// Fire event
-		this.adminLinkedMobileNumberEvent.fire(new AdminLinkedMobileNumberEvent(updatedContact, number));
-
-		// Return to contact profile
-		return "admin_show_contact"; //NOI18N
-	}
-
 	/**
 	 * Getter for contact instance
 	 * <p>
@@ -720,42 +598,6 @@ public class JobsAdminContactPhoneWebRequestBean extends BaseJobsBean implements
 		this.landLineNumber = landLineNumber;
 	}
 
-	/**
-	 * Getter for mobile number
-	 * <p>
-	 * @return Mobile number
-	 */
-	public Long getMobileNumber () {
-		return this.mobileNumber;
-	}
-
-	/**
-	 * Setter for mobile number
-	 * <p>
-	 * @param mobileNumber Mobile number
-	 */
-	public void setMobileNumber (final Long mobileNumber) {
-		this.mobileNumber = mobileNumber;
-	}
-
-	/**
-	 * Getter for mobile provider
-	 * <p>
-	 * @return Mobile provider
-	 */
-	public MobileProvider getMobileProvider () {
-		return this.mobileProvider;
-	}
-
-	/**
-	 * Setter for mobile provider
-	 * <p>
-	 * @param mobileProvider Mobile provider
-	 */
-	public void setMobileProvider (final MobileProvider mobileProvider) {
-		this.mobileProvider = mobileProvider;
-	}
-
 	/**
 	 * Setter for phone id
 	 * <p>
@@ -884,70 +726,6 @@ public class JobsAdminContactPhoneWebRequestBean extends BaseJobsBean implements
 		return "admin_show_contact"; //NOI18N
 	}
 
-	/**
-	 * Unlinks mobile data with current contact
-	 * <p>
-	 * @return Redirect outcome
-	 */
-	public String unlinkMobileContactData () {
-		// Create fax number instance
-		final DialableMobileNumber number = this.createMobileNumber();
-
-		// Is all data set
-		if (number == null) {
-			// Not set, throw NPE
-			throw new NullPointerException("number is null"); //NOI18N
-		} else if (number.getPhoneId() == null) {
-			// Throw NPE again
-			throw new NullPointerException("number.phoneId is null"); //NOI18N
-		} else if (number.getPhoneId() < 1) {
-			// Invalid number
-			throw new IllegalArgumentException(MessageFormat.format("number.phoneId={0} is not valid", number.getPhoneId())); //NOI18N
-		} else if (number.getMobileProvider() == null) {
-			// Throw NPE
-			throw new NullPointerException("number.mobileProvider is null"); //NOI18N
-		} else if (number.getMobileProvider().getProviderId() == null) {
-			// ... throw again
-			throw new NullPointerException("number.mobileProvider.providerId is null"); //NOI18N
-		} else if (number.getMobileProvider().getProviderId() < 1) {
-			// Id not valid
-			throw new IllegalArgumentException(MessageFormat.format("number.mobileProvider.providerId={0} is not valid.", number.getMobileProvider().getProviderId())); //NOI18N
-		} else if (number.getPhoneNumber() == null) {
-			// Throw NPE again
-			throw new NullPointerException("number.phoneNumber is null"); //NOI18N
-		} else if (number.getPhoneNumber() < 1) {
-			// Throw it again ...
-			throw new NullPointerException(MessageFormat.format("number.phoneNumber={0} is not valid.", number.getPhoneNumber())); //NOI18N
-		} else if (this.getContact() == null) {
-			// ... and throw again
-			throw new NullPointerException("this.contact is null"); //NOI18N
-		} else if (this.getContact().getContactId() == null) {
-			// ... and again ...
-			throw new NullPointerException("this.contact.contactId is null"); //NOI18N
-		} else if (this.getContact().getContactId() < 1) {
-			// Invalid id number
-			throw new IllegalArgumentException(MessageFormat.format("this.contact.contactId={0} is invalid.", this.getContact().getContactId())); //NOI18N
-		}
-
-		// Init contact instance
-		final Contact updatedContact;
-
-		try {
-			// Unlink it and return contact without mobile instance
-			updatedContact = this.adminContactPhoneBean.unlinkMobileDataFromContact(this.getContact(), number);
-		} catch (final PhoneNumberNotLinkedException ex) {
-			// Did not work
-			this.showFacesMessage("form_unlink_contact_mobile:mobileNumberId", ex, FacesMessage.SEVERITY_ERROR); //NOI18N
-			return ""; //NOI18N
-		}
-
-		// Fire event
-		this.mobileNumberUnlinkedEvent.fire(new AdminUnlinkedMobileNumberEvent(updatedContact, number));
-
-		// All fine here
-		return "admin_show_contact"; //NOI18N
-	}
-
 	/**
 	 * Clears this bean
 	 */
@@ -967,12 +745,7 @@ public class JobsAdminContactPhoneWebRequestBean extends BaseJobsBean implements
 		// Set all other fields
 		number.setPhoneEntryCreated(this.getPhoneEntryCreated());
 		number.setPhoneEntryUpdated(this.getPhoneEntryUpdated());
-
-		// Is id number there?
-		if (this.getPhoneId() instanceof Long) {
-			// Set it
-			number.setPhoneId(this.getPhoneId());
-		}
+		number.setPhoneId(this.getPhoneId());
 
 		// Return it
 		return number;
@@ -991,36 +764,7 @@ public class JobsAdminContactPhoneWebRequestBean extends BaseJobsBean implements
 		// Add all other data
 		number.setPhoneEntryCreated(this.getPhoneEntryCreated());
 		number.setPhoneEntryUpdated(this.getPhoneEntryUpdated());
-
-		// Is id number set?
-		if (this.getPhoneId() instanceof Long) {
-			// Set it
-			number.setPhoneId(this.getPhoneId());
-		}
-
-		// Return it
-		return number;
-	}
-
-	/**
-	 * Returns an instance of a DialableMobileNumber from all fields stored in
-	 * this bean.
-	 * <p>
-	 * @return An instance of a DialableMobileNumber class
-	 */
-	private DialableMobileNumber createMobileNumber () {
-		// Initialize it
-		final DialableMobileNumber number = new MobileNumber(this.getMobileProvider(), this.getMobileNumber());
-
-		// Add all other data
-		number.setPhoneEntryCreated(this.getPhoneEntryCreated());
-		number.setPhoneEntryUpdated(this.getPhoneEntryUpdated());
-
-		// Is id number set?
-		if (this.getPhoneId() instanceof Long) {
-			// Set it
-			number.setPhoneId(this.getPhoneId());
-		}
+		number.setPhoneId(this.getPhoneId());
 
 		// Return it
 		return number;
@@ -1029,7 +773,7 @@ public class JobsAdminContactPhoneWebRequestBean extends BaseJobsBean implements
 	/**
 	 * Getter for phone entry created
 	 * <p>
-	 * @param faxNumberEntryCreated Phone entry created
+	 * @return Phone entry created
 	 */
 	@SuppressWarnings ("ReturnOfDateField")
 	private Date getPhoneEntryCreated () {
diff --git a/src/java/org/mxchange/jjobs/beans/contact/phone/JobsContactPhoneWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/contact/phone/JobsContactPhoneWebRequestBean.java
index b2f8a75b..ed939622 100644
--- a/src/java/org/mxchange/jjobs/beans/contact/phone/JobsContactPhoneWebRequestBean.java
+++ b/src/java/org/mxchange/jjobs/beans/contact/phone/JobsContactPhoneWebRequestBean.java
@@ -16,31 +16,23 @@
  */
 package org.mxchange.jjobs.beans.contact.phone;
 
-import fish.payara.cdi.jsr107.impl.NamedCache;
 import java.text.MessageFormat;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Objects;
-import javax.cache.Cache;
 import javax.enterprise.context.RequestScoped;
 import javax.enterprise.event.Observes;
 import javax.inject.Inject;
 import javax.inject.Named;
 import org.mxchange.jcontacts.events.contact.add.ObservableAdminAddedContactEvent;
 import org.mxchange.jcontacts.events.contact.update.ObservableAdminUpdatedContactEvent;
-import org.mxchange.jcontacts.events.fax.unlinked.ObservableAdminUnlinkedFaxNumberEvent;
-import org.mxchange.jcontacts.events.landline.unlinked.ObservableAdminUnlinkedLandLineNumberEvent;
-import org.mxchange.jcontacts.events.mobile.unlinked.ObservableAdminUnlinkedMobileNumberEvent;
 import org.mxchange.jcontacts.model.contact.Contact;
 import org.mxchange.jjobs.beans.BaseJobsBean;
 import org.mxchange.jjobs.beans.contact.list.JobsContactListWebViewController;
 import org.mxchange.jphone.events.fax.created.ObservableCreatedFaxNumberEvent;
 import org.mxchange.jphone.events.landline.created.ObservableCreatedLandLineNumberEvent;
-import org.mxchange.jphone.events.mobile.created.ObservableCreatedMobileNumberEvent;
-import org.mxchange.jphone.model.phonenumbers.DialableNumber;
 import org.mxchange.jphone.model.phonenumbers.fax.DialableFaxNumber;
 import org.mxchange.jphone.model.phonenumbers.landline.DialableLandLineNumber;
-import org.mxchange.jphone.model.phonenumbers.mobile.DialableMobileNumber;
 import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
 
 /**
@@ -63,15 +55,6 @@ public class JobsContactPhoneWebRequestBean extends BaseJobsBean implements Jobs
 	@Inject
 	private JobsContactListWebViewController contactListController;
 
-	/**
-	 * "Cache" for contact's mobile, land-line and fax numbers. Currently one
-	 * per each type is supported. Maybe later this will change into a OneToMany
-	 * relationship (one contact, many numbers).
-	 */
-	@Inject
-	@NamedCache (cacheName = "contactsPhoneCache")
-	private Cache<DialableNumber, List<Contact>> contactsPhoneCache;
-
 	/**
 	 * fax number
 	 */
@@ -82,11 +65,6 @@ public class JobsContactPhoneWebRequestBean extends BaseJobsBean implements Jobs
 	 */
 	private DialableLandLineNumber landLineNumber;
 
-	/**
-	 * Chosen mobile number
-	 */
-	private DialableMobileNumber mobileNumber;
-
 	/**
 	 * Default constructor
 	 */
@@ -146,90 +124,6 @@ public class JobsContactPhoneWebRequestBean extends BaseJobsBean implements Jobs
 		this.clear();
 	}
 
-	/**
-	 * Event observer for unlinked fax contact by administrators
-	 * <p>
-	 * @param event Unlinked fax contact event
-	 */
-	public void afterAdminUnlinkedFaxContactDataEvent (@Observes final ObservableAdminUnlinkedFaxNumberEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getUnlinkedFaxNumber() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.unlinkedFaxNumber is null"); //NOI18N
-		} else if (event.getUnlinkedFaxNumber().getPhoneId() == null) {
-			// userId is null
-			throw new NullPointerException("event.unlinkedFaxNumber.contactId is null"); //NOI18N
-		} else if (event.getUnlinkedFaxNumber().getPhoneId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUnlinkedFaxNumber(), event.getUnlinkedFaxNumber().getPhoneId())); //NOI18N
-		}
-
-		// Remove it from list
-		this.contactsPhoneCache.remove(event.getUnlinkedFaxNumber());
-
-		// Clear all data
-		this.clear();
-	}
-
-	/**
-	 * Event observer for unlinked land-line contact by administrators
-	 * <p>
-	 * @param event Unlinked land-line contact event
-	 */
-	public void afterAdminUnlinkedLandLineContactDataEvent (@Observes final ObservableAdminUnlinkedLandLineNumberEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getUnlinkedLandLineNumber() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.unlinkedLandLineNumber is null"); //NOI18N
-		} else if (event.getUnlinkedLandLineNumber().getPhoneId() == null) {
-			// userId is null
-			throw new NullPointerException("event.unlinkedLandLineNumber.contactId is null"); //NOI18N
-		} else if (event.getUnlinkedLandLineNumber().getPhoneId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUnlinkedLandLineNumber(), event.getUnlinkedLandLineNumber().getPhoneId())); //NOI18N
-		}
-
-		// Remove it from list
-		this.contactsPhoneCache.remove(event.getUnlinkedLandLineNumber());
-
-		// Clear all data
-		this.clear();
-	}
-
-	/**
-	 * Event observer for unlinked mobile contact by administrators
-	 * <p>
-	 * @param event Unlinked mobile contact event
-	 */
-	public void afterAdminUnlinkedMobileContactDataEvent (@Observes final ObservableAdminUnlinkedMobileNumberEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getUnlinkedMobileNumber() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.unlinkedMobileNumber is null"); //NOI18N
-		} else if (event.getUnlinkedMobileNumber().getPhoneId() == null) {
-			// userId is null
-			throw new NullPointerException("event.unlinkedMobileNumber.contactId is null"); //NOI18N
-		} else if (event.getUnlinkedMobileNumber().getPhoneId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUnlinkedMobileNumber(), event.getUnlinkedMobileNumber().getPhoneId())); //NOI18N
-		}
-
-		// Remove it from list
-		this.contactsPhoneCache.remove(event.getUnlinkedMobileNumber());
-
-		// Clear all data
-		this.clear();
-	}
-
 	/**
 	 * Event observer for updated contact data by administrators
 	 * <p>
@@ -307,64 +201,29 @@ public class JobsContactPhoneWebRequestBean extends BaseJobsBean implements Jobs
 		this.setLandLineNumber(event.getLandLineNumber());
 	}
 
-	/**
-	 * Observes events being fired when a bean helper has successfully created a
-	 * mobile number instance.
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterCreatedMobileNumberEvent (@Observes final ObservableCreatedMobileNumberEvent event) {
-		// The event instance must be valid
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getMobileNumber() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.mobileNumber is null"); //NOI18N
-		} else if (event.getMobileNumber().getPhoneId() == null) {
-			// Throw NPE yet again
-			throw new NullPointerException("event.mobileNumber.phoneId is null"); //NOI18N
-		} else if (event.getMobileNumber().getPhoneId() < 1) {
-			// Throw NPE yet again
-			throw new NullPointerException(MessageFormat.format("event.mobileNumber.phoneId={0} is invalid", event.getMobileNumber().getPhoneId())); //NOI18N
-		}
-
-		// Set it here
-		this.setMobileNumber(event.getMobileNumber());
-	}
-
 	/**
 	 * Getter for all contacts having current fax number linked
 	 * <p>
 	 * @return List of all linked contacts
 	 */
-	public List<Contact> getAllCurrentFaxNumberContacts () {
+	public List<Contact> allCurrentFaxNumberContacts () {
 		// Get id
 		final DialableFaxNumber number = this.getFaxNumber();
 
-		// Is cache there?
-		if (this.contactsPhoneCache.containsKey(number)) {
-			// Return cached version
-			return this.contactsPhoneCache.get(number);
-		} else {
-			// Ask bean
-			final List<Contact> list = new LinkedList<>();
+		// Init list
+		final List<Contact> contacts = new LinkedList<>();
 
-			// "Walk" through all contacts
-			for (final Contact contact : this.contactListController.getAllContacts()) {
-				// Is mobile instance the same?
-				if (Objects.equals(contact.getContactFaxNumber(), number)) {
-					// Found one
-					list.add(contact);
-				}
+		// "Walk" through all contacts
+		for (final Contact contact : this.contactListController.getAllContacts()) {
+			// Is mobile instance the same?
+			if (Objects.equals(contact.getContactFaxNumber(), number)) {
+				// Found one
+				contacts.add(contact);
 			}
-
-			// Store result in cache
-			this.contactsPhoneCache.put(number, list);
-
-			// Return now-cached list
-			return list;
 		}
+
+		// Return now-cached list
+		return contacts;
 	}
 
 	/**
@@ -373,66 +232,23 @@ public class JobsContactPhoneWebRequestBean extends BaseJobsBean implements Jobs
 	 * @return List of all linked contacts
 	 */
 	public List<Contact> allCurrentLandLineNumberContacts () {
-		// Get id
+		// Get it locally
 		final DialableLandLineNumber number = this.getLandLineNumber();
 
-		// Is cache there?
-		if (this.contactsPhoneCache.containsKey(number)) {
-			// Return cached version
-			return this.contactsPhoneCache.get(number);
-		} else {
-			// Ask bean
-			final List<Contact> list = new LinkedList<>();
+		// Init list
+		final List<Contact> contacts = new LinkedList<>();
 
-			// "Walk" through all contacts
-			for (final Contact contact : this.contactListController.getAllContacts()) {
-				// Is mobile instance the same?
-				if (Objects.equals(contact.getContactLandLineNumber(), number)) {
-					// Found one
-					list.add(contact);
-				}
+		// "Walk" through all contacts
+		for (final Contact contact : this.contactListController.getAllContacts()) {
+			// Is mobile instance the same?
+			if (Objects.equals(contact.getContactLandLineNumber(), number)) {
+				// Found one
+				contacts.add(contact);
 			}
-
-			// Store result in cache
-			this.contactsPhoneCache.put(number, list);
-
-			// Return now-cached list
-			return list;
 		}
-	}
-
-	/**
-	 * Getter for all contacts having current mobile number linked
-	 * <p>
-	 * @return List of all linked contacts
-	 */
-	public List<Contact> allCurrentMobileNumberContacts () {
-		// Get id
-		final DialableMobileNumber number = this.getMobileNumber();
-
-		// Is cache there?
-		if (this.contactsPhoneCache.containsKey(number)) {
-			// Return cached version
-			return this.contactsPhoneCache.get(number);
-		} else {
-			// Ask bean
-			final List<Contact> list = new LinkedList<>();
-
-			// "Walk" through all contacts
-			for (final Contact contact : this.contactListController.getAllContacts()) {
-				// Is mobile instance the same?
-				if (Objects.equals(contact.getContactMobileNumber(), number)) {
-					// Found one
-					list.add(contact);
-				}
-			}
 
-			// Store result in cache
-			this.contactsPhoneCache.put(number, list);
-
-			// Return now-cached list
-			return list;
-		}
+		// Return now-cached list
+		return contacts;
 	}
 
 	/**
@@ -471,24 +287,6 @@ public class JobsContactPhoneWebRequestBean extends BaseJobsBean implements Jobs
 		this.landLineNumber = landLineNumber;
 	}
 
-	/**
-	 * Getter for chosen mobile number
-	 * <p>
-	 * @return mobile number
-	 */
-	public DialableMobileNumber getMobileNumber () {
-		return this.mobileNumber;
-	}
-
-	/**
-	 * Setter for chosen mobile number
-	 * <p>
-	 * @param mobileNumber mobile number
-	 */
-	public void setMobileNumber (final DialableMobileNumber mobileNumber) {
-		this.mobileNumber = mobileNumber;
-	}
-
 	/**
 	 * Clears this bean
 	 */
diff --git a/src/java/org/mxchange/jjobs/beans/contact/phone/action/FinancialsUserActionWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/contact/phone/action/FinancialsUserActionWebRequestBean.java
new file mode 100644
index 00000000..b47710e0
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/contact/phone/action/FinancialsUserActionWebRequestBean.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2016 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.user.action;
+
+import java.text.MessageFormat;
+import javax.ejb.EJB;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.event.Event;
+import javax.enterprise.inject.Any;
+import javax.faces.view.facelets.FaceletException;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jcontacts.model.contact.Contact;
+import org.mxchange.jfinancials.beans.BaseFinancialsBean;
+import org.mxchange.jfinancials.beans.contact.FinancialsContactWebRequestController;
+import org.mxchange.jfinancials.beans.features.FinancialsFeaturesWebApplicationController;
+import org.mxchange.jfinancials.beans.user.login.FinancialsUserLoginWebSessionController;
+import org.mxchange.jusercore.events.user.update.post.ObservablePostUserPersonalDataUpdatedEvent;
+import org.mxchange.jusercore.events.user.update.post.PostUserPersonalDataUpdatedEvent;
+import org.mxchange.jusercore.events.user.update.pre.ObservablePreUserPersonalDataUpdatedEvent;
+import org.mxchange.jusercore.events.user.update.pre.PreUserPersonalDataUpdatedEvent;
+import org.mxchange.jusercore.model.user.User;
+import org.mxchange.jusercore.model.user.UserSessionBeanRemote;
+import org.mxchange.juserlogincore.exceptions.UserPasswordMismatchException;
+
+/**
+ * A user action bean (controller)
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("userActionController")
+@RequestScoped
+public class FinancialsUserActionWebRequestBean extends BaseFinancialsBean implements FinancialsUserActionWebRequestController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 542_145_347_920L;
+
+	/**
+	 * General contact controller
+	 */
+	@Inject
+	private FinancialsContactWebRequestController contactController;
+
+	/**
+	 * Features controller
+	 */
+	@Inject
+	private FinancialsFeaturesWebApplicationController featureController;
+
+	/**
+	 * Event being fired when user updated personal data
+	 */
+	@Inject
+	@Any
+	private Event<ObservablePostUserPersonalDataUpdatedEvent> postUpdatedPersonalDataEvent;
+
+	/**
+	 * Event being fired when user updated personal data
+	 */
+	@Inject
+	@Any
+	private Event<ObservablePreUserPersonalDataUpdatedEvent> preUpdatedPersonalDataEvent;
+
+	/**
+	 * Remote user bean
+	 */
+	@EJB (lookup = "java:global/jfinancials-ejb/user!org.mxchange.jusercore.model.user.UserSessionBeanRemote")
+	private UserSessionBeanRemote userBean;
+
+	/**
+	 * Login controller (bean)
+	 */
+	@Inject
+	private FinancialsUserLoginWebSessionController userLoginController;
+
+	/**
+	 * Default constructor
+	 */
+	public FinancialsUserActionWebRequestBean () {
+		// Call super constructor
+		super();
+	}
+
+	@Override
+	public String doChangePersonalData () {
+		// This method shall only be called if the user is logged-in
+		if (!this.userLoginController.isUserLoggedIn()) {
+			// Not logged-in
+			throw new IllegalStateException("User is not logged-in"); //NOI18N
+		} else if (!this.contactController.isRequiredChangePersonalDataSet()) {
+			// Not all required fields are set
+			throw new FaceletException("Not all required fields are set."); //NOI18N
+		} else if (!this.userLoginController.ifCurrentPasswordMatches()) {
+			// Password not matching
+			throw new FaceletException(new UserPasswordMismatchException(this.userLoginController.getLoggedInUser()));
+		} else if (!this.featureController.isFeatureEnabled("change_user_personal_data")) { //NOI18N
+			// Editing is not allowed
+			throw new IllegalStateException("User tried to edit personal data."); //NOI18N
+		}
+
+		// Get user instance
+		final User user = this.userLoginController.getLoggedInUser();
+
+		// Fire pre-update event
+		this.preUpdatedPersonalDataEvent.fire(new PreUserPersonalDataUpdatedEvent(user));
+
+		// It should be there, so run some tests on it
+		assert (user instanceof User) : "Instance userLoginController.loggedInUser is null"; //NOI18N
+		assert (user.getUserId() instanceof Long) : "Instance userLoginController.loggedInUser.userId is null"; //NOI18N
+		assert (user.getUserId() > 0) : MessageFormat.format("userLoginController.loggedInUser.userId={0} is invalid", user.getUserId()); //NOI18N
+		assert (user.getUserContact() instanceof Contact) : "Instance userLoginController.loggedInUser.userContact is null"; //NOI18N
+		assert (user.getUserContact().getContactId() instanceof Long) : "Instance userLoginController.userContact.contactId is null"; //NOI18N
+		assert (user.getUserContact().getContactId() > 0) : MessageFormat.format("Instance userLoginController.userContact.contactId={0} is invalid", user.getUserContact().getContactId()); //NOI18N
+
+		// Send it to the EJB
+		final User updatedUser = this.userBean.updateUserPersonalData(user);
+
+		// Fire post-update event
+		this.postUpdatedPersonalDataEvent.fire(new PostUserPersonalDataUpdatedEvent(updatedUser));
+
+		// All fine
+		return "user_contact_data_saved"; //NOI18N
+	}
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/contact/phone/action/FinancialsUserActionWebRequestController.java b/src/java/org/mxchange/jjobs/beans/contact/phone/action/FinancialsUserActionWebRequestController.java
new file mode 100644
index 00000000..ed6cd2d9
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/contact/phone/action/FinancialsUserActionWebRequestController.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.user.action;
+
+import java.io.Serializable;
+
+/**
+ * An interface for user beans
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsUserActionWebRequestController extends Serializable {
+
+	/**
+	 * Minimum password length
+	 * <p>
+	 * @deprecated Better set as context parameter
+	 */
+	@Deprecated
+	public static final Integer MINIMUM_PASSWORD_LENGTH = 5;
+
+	/**
+	 * Changes logged-in user's personal data if the current password matches
+	 * and TAC + privacy statement has been accepted.
+	 * <p>
+	 * @return New target page
+	 */
+	String doChangePersonalData ();
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/contact/phone/email_address/list/FinancialsEmailChangeListWebViewBean.java b/src/java/org/mxchange/jjobs/beans/contact/phone/email_address/list/FinancialsEmailChangeListWebViewBean.java
new file mode 100644
index 00000000..7c79cdf6
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/contact/phone/email_address/list/FinancialsEmailChangeListWebViewBean.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2016 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.user.email_address.list;
+
+import fish.payara.cdi.jsr107.impl.NamedCache;
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import javax.cache.Cache;
+import javax.ejb.EJB;
+import javax.faces.view.ViewScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jfinancials.beans.BaseFinancialsBean;
+import org.mxchange.jfinancials.beans.features.FinancialsFeaturesWebApplicationController;
+import org.mxchange.jusercore.model.email_address.ChangeableEmailAddress;
+import org.mxchange.jusercore.model.user.email_address.UserEmailChangeSessionBeanRemote;
+
+/**
+ * A view-scoped bean for listing email address changes
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("emailChangeListController")
+@ViewScoped
+public class FinancialsEmailChangeListWebViewBean extends BaseFinancialsBean implements FinancialsEmailChangeListWebViewController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 186_078_724_659_154L;
+
+	/**
+	 * A list of all mobile numbers
+	 */
+	private final List<ChangeableEmailAddress> allEmailAddressChanges;
+
+	/**
+	 * Remote email change bean
+	 */
+	@EJB (lookup = "java:global/jfinancials-ejb/userEmailChange!org.mxchange.jusercore.model.user.email_address.UserEmailChangeSessionBeanRemote")
+	private UserEmailChangeSessionBeanRemote emailChangeBean;
+
+	/**
+	 * Features controller
+	 */
+	@Inject
+	private FinancialsFeaturesWebApplicationController featureController;
+
+	/**
+	 * A list of filtered mobile numbers
+	 */
+	private List<ChangeableEmailAddress> filteredEmailAddressChanges;
+
+	/**
+	 * Local list of already queued email addresses
+	 */
+	@Inject
+	@NamedCache (cacheName = "queuedEmailCache")
+	private transient Cache<Long, ChangeableEmailAddress> queuedEmailCache;
+
+	/**
+	 * Default constructor
+	 */
+	public FinancialsEmailChangeListWebViewBean () {
+		// Call super constructor
+		super();
+
+		// Initialize list
+		this.allEmailAddressChanges = new LinkedList<>();
+	}
+
+	@Override
+	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
+	public List<ChangeableEmailAddress> getAllEmailAddressChanges () {
+		return this.allEmailAddressChanges;
+	}
+
+	/**
+	 * Getter for filtered email address changed
+	 * <p>
+	 * @return Filtered email address changed
+	 */
+	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
+	public List<ChangeableEmailAddress> getFilteredEmailAddressChanges () {
+		return this.filteredEmailAddressChanges;
+	}
+
+	/**
+	 * Setter for filtered email address changed
+	 * <p>
+	 * @param filteredEmailAddressChanges Filtered email address changed
+	 */
+	@SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter")
+	public void setFilteredEmailAddressChanges (final List<ChangeableEmailAddress> filteredEmailAddressChanges) {
+		this.filteredEmailAddressChanges = filteredEmailAddressChanges;
+	}
+
+	/**
+	 * Post-construction
+	 */
+	@PostConstruct
+	public void initializeList () {
+		// Is cache there?
+		if (!this.queuedEmailCache.iterator().hasNext()) {
+			// Add all
+			for (final ChangeableEmailAddress currentEmailAddress : this.emailChangeBean.fetchAllQueuedAddressChanges()) {
+				// Add it to cache
+				this.queuedEmailCache.put(currentEmailAddress.getEmailChangeId(), currentEmailAddress);
+			}
+		}
+
+		// Is cache filled and list is empty
+		if ((this.queuedEmailCache.iterator().hasNext()) && (this.getAllEmailAddressChanges().isEmpty())) {
+			// Build up list
+			for (final Cache.Entry<Long, ChangeableEmailAddress> currentEntry : this.queuedEmailCache) {
+				// Add to list
+				this.getAllEmailAddressChanges().add(currentEntry.getValue());
+			}
+
+			// Sort list
+			this.getAllEmailAddressChanges().sort(new Comparator<ChangeableEmailAddress>() {
+				@Override
+				public int compare (final ChangeableEmailAddress queuedEmail1, final ChangeableEmailAddress queuedEmail2) {
+					return queuedEmail1.getEmailChangeId() > queuedEmail2.getEmailChangeId() ? 1 : queuedEmail1.getEmailChangeId() < queuedEmail2.getEmailChangeId() ? -1 : 0;
+				}
+			});
+
+			// Set full list
+			this.setFilteredEmailAddressChanges(this.getAllEmailAddressChanges());
+		}
+	}
+
+	@Override
+	public boolean isEmailAddressQueued (final String emailAddress) {
+		// Check if parameter is valid
+		if (null == emailAddress) {
+			// Throw NPE
+			throw new NullPointerException("emailAddress is null"); //NOI18N
+		} else if (emailAddress.isEmpty()) {
+			// Throw IAE
+			throw new IllegalArgumentException("emailAddress is empty."); //NOI18N
+		}
+
+		// Default is not found
+		boolean isFound = false;
+
+		// Iterate through whole list
+		for (final ChangeableEmailAddress address : this.getAllEmailAddressChanges()) {
+			// Does current match?
+			if (emailAddress.equals(address.getEmailAddress())) {
+				// Yes, set flag and abort iteration
+				isFound = true;
+				break;
+			}
+		}
+
+		// Return flag
+		return isFound;
+	}
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/contact/phone/email_address/list/FinancialsEmailChangeListWebViewController.java b/src/java/org/mxchange/jjobs/beans/contact/phone/email_address/list/FinancialsEmailChangeListWebViewController.java
new file mode 100644
index 00000000..ca0fa540
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/contact/phone/email_address/list/FinancialsEmailChangeListWebViewController.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.user.email_address.list;
+
+import java.io.Serializable;
+import java.util.List;
+import org.mxchange.jusercore.model.email_address.ChangeableEmailAddress;
+
+/**
+ * An interface for an email change controller
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsEmailChangeListWebViewController extends Serializable {
+
+	/**
+	 * Returns a list of all email address changes. For performance reasons, the
+	 * controller (bean) should be view-scoped as from user to user nothing
+	 * changes. And the controller's post-construct method should load all
+	 * numbers and cache it in the controller.
+	 * <p>
+	 * @return List of all mobile numbers
+	 */
+	List<ChangeableEmailAddress> getAllEmailAddressChanges ();
+
+	/**
+	 * Checks if given email address has already been queued. First a local list
+	 * is being checked, if not found, the EJB is called. Only if found, the
+	 * result is "cached" in the list.
+	 * <p>
+	 * @param emailAddress Email address to verify
+	 * <p>
+	 * @return Whether the email address in field emailAddress is already queued
+	 */
+	boolean isEmailAddressQueued (final String emailAddress);
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/contact/phone/list/JobsUserListWebViewBean.java b/src/java/org/mxchange/jjobs/beans/contact/phone/list/JobsUserListWebViewBean.java
new file mode 100644
index 00000000..232cbf58
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/contact/phone/list/JobsUserListWebViewBean.java
@@ -0,0 +1,588 @@
+/*
+ * Copyright (C) 2016 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.user.list;
+
+import fish.payara.cdi.jsr107.impl.NamedCache;
+import java.text.MessageFormat;
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import javax.annotation.PostConstruct;
+import javax.cache.Cache;
+import javax.ejb.EJB;
+import javax.enterprise.event.Observes;
+import javax.faces.view.ViewScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jfinancials.beans.BaseJobsBean;
+import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
+import org.mxchange.jusercore.events.user.delete.ObservableAdminDeletedUserEvent;
+import org.mxchange.jusercore.events.user.linked.ObservableAdminLinkedUserEvent;
+import org.mxchange.jusercore.events.user.locked.ObservableAdminLockedUserEvent;
+import org.mxchange.jusercore.events.user.unlocked.ObservableAdminUnlockedUserEvent;
+import org.mxchange.jusercore.exceptions.UserEmailAddressNotFoundException;
+import org.mxchange.jusercore.exceptions.UserNotFoundException;
+import org.mxchange.jusercore.model.user.User;
+import org.mxchange.jusercore.model.user.UserSessionBeanRemote;
+import org.mxchange.juserlogincore.events.confirmation.ObservableUserConfirmedAccountEvent;
+import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent;
+import org.mxchange.juserlogincore.events.user.password_change.ObservableUpdatedUserPasswordEvent;
+import org.mxchange.jusercore.events.user.update.post.ObservableAdminPostUserDataUpdatedEvent;
+import org.mxchange.jusercore.events.user.update.post.ObservablePostUserPersonalDataUpdatedEvent;
+
+/**
+ * A user list bean (controller)
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("userListController")
+@ViewScoped
+public class JobsUserListWebViewBean extends BaseJobsBean implements JobsUserListWebViewController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 542_145_347_918L;
+
+	/**
+	 * List of all users
+	 */
+	private final List<User> allUsers;
+
+	/**
+	 * List of filtered users
+	 */
+	private List<User> filteredUsers;
+
+	/**
+	 * Selected user instance
+	 */
+	private User selectedUser;
+
+	/**
+	 * Remote user bean
+	 */
+	@EJB (lookup = "java:global/jfinancials-ejb/user!org.mxchange.jusercore.model.user.UserSessionBeanRemote")
+	private UserSessionBeanRemote userBean;
+
+	/**
+	 * A list of all user profiles
+	 */
+	@Inject
+	@NamedCache (cacheName = "userCache")
+	private transient Cache<Long, User> userCache;
+
+	/**
+	 * Default constructor
+	 */
+	public JobsUserListWebViewBean () {
+		// Call super constructor
+		super();
+
+		// Init list
+		this.allUsers = new LinkedList<>();
+	}
+
+	/**
+	 * Event observer for newly added users by administrator
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getAddedUser() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.addedUser is null"); //NOI18N
+		} else if (event.getAddedUser().getUserId() == null) {
+			// userId is null
+			throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
+		} else if (event.getAddedUser().getUserId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
+		}
+
+		// Update user list
+		this.updateList(event.getAddedUser());
+	}
+
+	/**
+	 * Event observer for deleted user accounts (by administrator)
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminDeletedUserEvent (@Observes final ObservableAdminDeletedUserEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getDeletedUser() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.deletedUser is null"); //NOI18N
+		} else if (event.getDeletedUser().getUserId() == null) {
+			// userId is null
+			throw new NullPointerException("event.deletedUser.userId is null"); //NOI18N
+		} else if (event.getDeletedUser().getUserId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getDeletedUser(), event.getDeletedUser().getUserId())); //NOI18N
+		}
+
+		// Update user list
+		this.removeFromList(event.getDeletedUser());
+	}
+
+	/**
+	 * Event observer for linked users with existing contact data
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminLinkedUserEvent (@Observes final ObservableAdminLinkedUserEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getLinkedUser() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.linkedUser is null"); //NOI18N
+		} else if (event.getLinkedUser().getUserId() == null) {
+			// userId is null
+			throw new NullPointerException("event.linkedUser.userId is null"); //NOI18N
+		} else if (event.getLinkedUser().getUserId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLinkedUser(), event.getLinkedUser().getUserId())); //NOI18N
+		}
+
+		// Update user list
+		this.updateList(event.getLinkedUser());
+	}
+
+	/**
+	 * Event observer for locked users
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminLockedUserEvent (@Observes final ObservableAdminLockedUserEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getLockedUser() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.lockedUser is null"); //NOI18N
+		} else if (event.getLockedUser().getUserId() == null) {
+			// userId is null
+			throw new NullPointerException("event.lockedUser.userId is null"); //NOI18N
+		} else if (event.getLockedUser().getUserId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLockedUser(), event.getLockedUser().getUserId())); //NOI18N
+		}
+
+		// Update user list
+		this.updateList(event.getLockedUser());
+	}
+
+	/**
+	 * Event observer for unlocked users
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminUnlockedUserEvent (@Observes final ObservableAdminUnlockedUserEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUnlockedUser() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.unlockedUser is null"); //NOI18N
+		} else if (event.getUnlockedUser().getUserId() == null) {
+			// userId is null
+			throw new NullPointerException("event.unlockedUser.userId is null"); //NOI18N
+		} else if (event.getUnlockedUser().getUserId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUnlockedUser(), event.getUnlockedUser().getUserId())); //NOI18N
+		}
+
+		// Update user list
+		this.updateList(event.getUnlockedUser());
+	}
+
+	/**
+	 * Event observer for updated user data by administrator
+	 * <p>
+	 * @param event Event being updated
+	 */
+	public void afterAdminUpdatedUserDataEvent (@Observes final ObservableAdminPostUserDataUpdatedEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUpdatedUser() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.updatedUser is null"); //NOI18N
+		} else if (event.getUpdatedUser().getUserId() == null) {
+			// userId is null
+			throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
+		} else if (event.getUpdatedUser().getUserId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUpdatedUser(), event.getUpdatedUser().getUserId())); //NOI18N
+		}
+
+		// Update user list
+		this.updateList(event.getUpdatedUser());
+	}
+
+	/**
+	 * Event observer when user confirmed account.
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterUserConfirmedAccountEvent (@Observes final ObservableUserConfirmedAccountEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getConfirmedUser() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.confirmedUser is null"); //NOI18N
+		} else if (event.getConfirmedUser().getUserId() == null) {
+			// userId is null
+			throw new NullPointerException("event.confirmedUser.userId is null"); //NOI18N
+		} else if (event.getConfirmedUser().getUserId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getConfirmedUser(), event.getConfirmedUser().getUserId())); //NOI18N
+		}
+
+		// Update user list
+		this.updateList(event.getConfirmedUser());
+	}
+
+	/**
+	 * Event observer for new user registrations
+	 * <p>
+	 * @param event User registration event
+	 */
+	public void afterUserRegistrationEvent (@Observes final ObservableUserRegisteredEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getRegisteredUser() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.registeredUser is null"); //NOI18N
+		} else if (event.getRegisteredUser().getUserId() == null) {
+			// userId is null
+			throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
+		} else if (event.getRegisteredUser().getUserId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getRegisteredUser(), event.getRegisteredUser().getUserId())); //NOI18N
+		}
+
+		// Update user list
+		this.updateList(event.getRegisteredUser());
+	}
+
+	/**
+	 * Method being call after user's password has been updated (and history
+	 * entry has been created).
+	 * <p>
+	 * @param event Event being observed
+	 */
+	public void afterUserUpdatedPasswordEvent (@Observes final ObservableUpdatedUserPasswordEvent event) {
+		// Check parameter
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getPasswordHistory() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.passwordHistory is null"); //NOI18N
+		} else if (event.getPasswordHistory().getUserPasswordHistoryId() == null) {
+			// ... and again
+			throw new NullPointerException("event.passwordHistory.userPasswordHistoryId is null"); //NOI18N
+		} else if (event.getPasswordHistory().getUserPasswordHistoryId() < 1) {
+			// Invalid value
+			throw new IllegalArgumentException(MessageFormat.format("event.passwordHistory.userPasswordHistoryId={0} is in valid", event.getPasswordHistory().getUserPasswordHistoryId())); //NOI18N
+		}
+
+		// Update user list
+		this.updateList(event.getPasswordHistory().getUserPasswordHistoryUser());
+	}
+
+	/**
+	 * Listens to fired event when user updated personal data
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterUserUpdatedPersonalDataEvent (@Observes final ObservablePostUserPersonalDataUpdatedEvent event) {
+		// Check parameter
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUpdatedUser() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.updatedUser is null"); //NOI18N
+		} else if (event.getUpdatedUser().getUserId() == null) {
+			// ... and again
+			throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
+		} else if (event.getUpdatedUser().getUserId() < 1) {
+			// Invalid value
+			throw new IllegalArgumentException(MessageFormat.format("event.updatedUser.userId={0} is in valid", event.getUpdatedUser().getUserId())); //NOI18N
+		}
+
+		// Update user list
+		this.updateList(event.getUpdatedUser());
+	}
+
+	@Override
+	public User findUserById (final Long userId) throws UserNotFoundException {
+		// Validate parameter
+		if (null == userId) {
+			// Throw NPE
+			throw new NullPointerException("userId is null"); //NOI18N
+		} else if (userId < 1) {
+			// Throw IAE
+			throw new IllegalArgumentException("userId=" + userId + " is invalid."); //NOI18N
+		} else if (!this.userCache.containsKey(userId)) {
+			// Not found
+			throw new UserNotFoundException(userId);
+		}
+
+		// Get it from cache
+		final User user = this.userCache.get(userId);
+
+		// Return it
+		return user;
+	}
+
+	@Override
+	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
+	public List<User> getAllUsers () {
+		return this.allUsers;
+	}
+
+	/**
+	 * Getter for filtered users list
+	 * <p>
+	 * @return Filtered users list
+	 */
+	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
+	public List<User> getFilteredUsers () {
+		return this.filteredUsers;
+	}
+
+	/**
+	 * Setter for filtered users list
+	 * <p>
+	 * @param filteredUsers Filtered users list
+	 */
+	@SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter")
+	public void setFilteredUsers (final List<User> filteredUsers) {
+		this.filteredUsers = filteredUsers;
+	}
+
+	/**
+	 * Getter for selected user instance
+	 * <p>
+	 * @return Selected user instance
+	 */
+	public User getSelectedUser () {
+		return this.selectedUser;
+	}
+
+	/**
+	 * Setter for selected user instance
+	 * <p>
+	 * @param selectedUser Selected user instance
+	 */
+	public void setSelectedUser (final User selectedUser) {
+		this.selectedUser = selectedUser;
+	}
+
+	@Override
+	public boolean ifUserIdExists (final Long userId) {
+		// Validate parameter
+		if (null == userId) {
+			// Throw NPE
+			throw new NullPointerException("userId is null"); //NOI18N
+		} else if (userId < 1) {
+			// Throw IAE
+			throw new IllegalArgumentException("userId=" + userId + " is invalid."); //NOI18N
+		}
+
+		// Check if key is there
+		boolean isFound = this.userCache.containsKey(userId);
+
+		// Return flag
+		return isFound;
+	}
+
+	/**
+	 * Post-initialization of this class
+	 */
+	@PostConstruct
+	public void initializeList () {
+		// Is cache there?
+		if (!this.userCache.iterator().hasNext()) {
+			// Add all
+			for (final User user : this.userBean.fetchAllUsers()) {
+				// Add it to cache
+				this.userCache.put(user.getUserId(), user);
+			}
+		}
+
+		// Is cache filled and list is empty
+		if ((this.userCache.iterator().hasNext()) && (this.getAllUsers().isEmpty())) {
+			// Build up list
+			for (final Cache.Entry<Long, User> currentEntry : this.userCache) {
+				// Add to list
+				this.getAllUsers().add(currentEntry.getValue());
+			}
+
+			// Sort list
+			this.getAllUsers().sort(new Comparator<User>() {
+				@Override
+				public int compare (final User user1, final User user2) {
+					return user1.getUserId() > user2.getUserId() ? 1 : user1.getUserId() < user2.getUserId() ? -1 : 0;
+				}
+			});
+
+			// Set full list
+			this.setFilteredUsers(this.getAllUsers());
+		}
+	}
+
+	@Override
+	public boolean isUserNameRegistered (final User user) {
+		// Default is not found
+		boolean isFound = false;
+
+		// Determine it
+		for (final User currentUser : this.getAllUsers()) {
+			// Is same name found?
+			if (Objects.equals(user.getUserName(), currentUser.getUserName())) {
+				// Yes, then set flag and abort loop
+				isFound = true;
+				break;
+			}
+		}
+
+		// Return flag
+		return isFound;
+	}
+
+	@Override
+	public User lookupUserByEmailAddress (final String emailAddress) throws UserEmailAddressNotFoundException {
+		// Parameter must be valid
+		if (null == emailAddress) {
+			// Throw NPE
+			throw new NullPointerException("emailAddress is null"); //NOI18N
+		} else if (emailAddress.isEmpty()) {
+			// Not valid
+			throw new IllegalArgumentException("emailAddress is empty"); //NOI18N
+		}
+
+		// Init variable
+		User user = null;
+
+		// Try to lookup it in visible user list
+		for (final Cache.Entry<Long, User> currentUser : this.userCache) {
+			// Contact should be set
+			if (currentUser.getValue().getUserContact() == null) {
+				// Contact is null
+				throw new NullPointerException(MessageFormat.format("currentUser.userContact is null for user id {0}", currentUser.getKey())); //NOI18N
+			} else if (currentUser.getValue().getUserContact().getContactEmailAddress() == null) {
+				// Email address should be set
+				throw new NullPointerException(MessageFormat.format("currentUser.userContact.contactEmailAddress is null for user id {0}", currentUser.getKey())); //NOI18N
+			}
+
+			// Is the email address found?
+			if (Objects.equals(currentUser.getValue().getUserContact().getContactEmailAddress(), emailAddress)) {
+				// Copy to other variable
+				user = currentUser.getValue();
+				break;
+			}
+		}
+
+		// Is it still null?
+		if (null == user) {
+			// Not visible for the current user
+			throw new UserEmailAddressNotFoundException(emailAddress);
+		}
+
+		// Return it
+		return user;
+	}
+
+	@Override
+	public User lookupUserById (final Long userId) throws UserNotFoundException {
+		// Parameter must be valid
+		if (null == userId) {
+			// Throw NPE
+			throw new NullPointerException("userId is null"); //NOI18N
+		} else if (userId < 1) {
+			// Not valid
+			throw new IllegalArgumentException(MessageFormat.format("userId={0} is not valid.", userId)); //NOI18N
+		}
+
+		// Init variable
+		User user = null;
+
+		// Try to lookup it in visible user list
+		for (final Cache.Entry<Long, User> currentUser : this.userCache) {
+			// Is the user id found?
+			if (Objects.equals(currentUser.getKey(), userId)) {
+				// Copy to other variable
+				user = currentUser.getValue();
+				break;
+			}
+		}
+
+		// Is it still null?
+		if (null == user) {
+			// Not visible for the current user
+			throw new UserNotFoundException(userId);
+		}
+
+		// Return it
+		return user;
+	}
+
+	/**
+	 * Removes user from all lists
+	 * <p>
+	 * @param user User to remove
+	 */
+	private void removeFromList (final User user) {
+		// Remove it from lists
+		this.getAllUsers().remove(user);
+		this.userCache.remove(user.getUserId());
+	}
+
+	/**
+	 * Updates list with given user instance
+	 * <p>
+	 * @param user User instance
+	 */
+	private void updateList (final User user) {
+		// Add/update user
+		this.userCache.put(user.getUserId(), user);
+		this.getAllUsers().add(user);
+	}
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/contact/phone/list/JobsUserListWebViewtBean.java b/src/java/org/mxchange/jjobs/beans/contact/phone/list/JobsUserListWebViewtBean.java
deleted file mode 100644
index 4a44547f..00000000
--- a/src/java/org/mxchange/jjobs/beans/contact/phone/list/JobsUserListWebViewtBean.java
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
- * Copyright (C) 2016 - 2020 Free Software Foundation
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.user.list;
-
-import fish.payara.cdi.jsr107.impl.NamedCache;
-import java.text.MessageFormat;
-import java.util.Comparator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Objects;
-import javax.annotation.PostConstruct;
-import javax.cache.Cache;
-import javax.ejb.EJB;
-import javax.enterprise.event.Observes;
-import javax.faces.view.ViewScoped;
-import javax.inject.Inject;
-import javax.inject.Named;
-import org.mxchange.jfinancials.beans.BaseJobsBean;
-import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
-import org.mxchange.jusercore.events.user.delete.ObservableAdminDeletedUserEvent;
-import org.mxchange.jusercore.events.user.linked.ObservableAdminLinkedUserEvent;
-import org.mxchange.jusercore.events.user.locked.ObservableAdminLockedUserEvent;
-import org.mxchange.jusercore.events.user.unlocked.ObservableAdminUnlockedUserEvent;
-import org.mxchange.jusercore.events.user.update.ObservableAdminUpdatedUserDataEvent;
-import org.mxchange.jusercore.events.user.update.ObservableUpdatedUserPersonalDataEvent;
-import org.mxchange.jusercore.exceptions.UserEmailAddressNotFoundException;
-import org.mxchange.jusercore.exceptions.UserNotFoundException;
-import org.mxchange.jusercore.model.user.User;
-import org.mxchange.jusercore.model.user.UserSessionBeanRemote;
-import org.mxchange.juserlogincore.events.confirmation.ObservableUserConfirmedAccountEvent;
-import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent;
-import org.mxchange.juserlogincore.events.user.password_change.ObservableUpdatedUserPasswordEvent;
-
-/**
- * A user list bean (controller)
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-@Named ("userListController")
-@ViewScoped
-public class JobsUserListWebViewtBean extends BaseJobsBean implements JobsUserListWebViewController {
-
-	/**
-	 * Serial number
-	 */
-	private static final long serialVersionUID = 542_145_347_918L;
-
-	/**
-	 * List of all users
-	 */
-	private final List<User> allUsers;
-
-	/**
-	 * List of filtered users
-	 */
-	private List<User> filteredUsers;
-
-	/**
-	 * Selected user instance
-	 */
-	private User selectedUser;
-
-	/**
-	 * Remote user bean
-	 */
-	@EJB (lookup = "java:global/jfinancials-ejb/user!org.mxchange.jusercore.model.user.UserSessionBeanRemote")
-	private UserSessionBeanRemote userBean;
-
-	/**
-	 * A list of all user profiles
-	 */
-	@Inject
-	@NamedCache (cacheName = "userCache")
-	private transient Cache<Long, User> userCache;
-
-	/**
-	 * Default constructor
-	 */
-	public JobsUserListWebViewtBean () {
-		// Call super constructor
-		super();
-
-		// Init list
-		this.allUsers = new LinkedList<>();
-	}
-
-	/**
-	 * Event observer for newly added users by administrator
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getAddedUser() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.addedUser is null"); //NOI18N
-		} else if (event.getAddedUser().getUserId() == null) {
-			// userId is null
-			throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
-		} else if (event.getAddedUser().getUserId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
-		}
-
-		// Update user list
-		this.updateList(event.getAddedUser());
-	}
-
-	/**
-	 * Event observer for deleted user accounts (by administrator)
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminDeletedUserEvent (@Observes final ObservableAdminDeletedUserEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getDeletedUser() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.deletedUser is null"); //NOI18N
-		} else if (event.getDeletedUser().getUserId() == null) {
-			// userId is null
-			throw new NullPointerException("event.deletedUser.userId is null"); //NOI18N
-		} else if (event.getDeletedUser().getUserId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getDeletedUser(), event.getDeletedUser().getUserId())); //NOI18N
-		}
-
-		// Update user list
-		this.removeFromList(event.getDeletedUser());
-	}
-
-	/**
-	 * Event observer for linked users with existing contact data
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminLinkedUserEvent (@Observes final ObservableAdminLinkedUserEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getLinkedUser() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.linkedUser is null"); //NOI18N
-		} else if (event.getLinkedUser().getUserId() == null) {
-			// userId is null
-			throw new NullPointerException("event.linkedUser.userId is null"); //NOI18N
-		} else if (event.getLinkedUser().getUserId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLinkedUser(), event.getLinkedUser().getUserId())); //NOI18N
-		}
-
-		// Update user list
-		this.updateList(event.getLinkedUser());
-	}
-
-	/**
-	 * Event observer for locked users
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminLockedUserEvent (@Observes final ObservableAdminLockedUserEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getLockedUser() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.lockedUser is null"); //NOI18N
-		} else if (event.getLockedUser().getUserId() == null) {
-			// userId is null
-			throw new NullPointerException("event.lockedUser.userId is null"); //NOI18N
-		} else if (event.getLockedUser().getUserId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLockedUser(), event.getLockedUser().getUserId())); //NOI18N
-		}
-
-		// Update user list
-		this.updateList(event.getLockedUser());
-	}
-
-	/**
-	 * Event observer for unlocked users
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminUnlockedUserEvent (@Observes final ObservableAdminUnlockedUserEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getUnlockedUser() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.unlockedUser is null"); //NOI18N
-		} else if (event.getUnlockedUser().getUserId() == null) {
-			// userId is null
-			throw new NullPointerException("event.unlockedUser.userId is null"); //NOI18N
-		} else if (event.getUnlockedUser().getUserId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUnlockedUser(), event.getUnlockedUser().getUserId())); //NOI18N
-		}
-
-		// Update user list
-		this.updateList(event.getUnlockedUser());
-	}
-
-	/**
-	 * Event observer for updated user data by administrator
-	 * <p>
-	 * @param event Event being updated
-	 */
-	public void afterAdminUpdatedUserDataEvent (@Observes final ObservableAdminUpdatedUserDataEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getUpdatedUser() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.updatedUser is null"); //NOI18N
-		} else if (event.getUpdatedUser().getUserId() == null) {
-			// userId is null
-			throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
-		} else if (event.getUpdatedUser().getUserId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUpdatedUser(), event.getUpdatedUser().getUserId())); //NOI18N
-		}
-
-		// Update user list
-		this.updateList(event.getUpdatedUser());
-	}
-
-	/**
-	 * Event observer when user confirmed account.
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterUserConfirmedAccountEvent (@Observes final ObservableUserConfirmedAccountEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getConfirmedUser() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.confirmedUser is null"); //NOI18N
-		} else if (event.getConfirmedUser().getUserId() == null) {
-			// userId is null
-			throw new NullPointerException("event.confirmedUser.userId is null"); //NOI18N
-		} else if (event.getConfirmedUser().getUserId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getConfirmedUser(), event.getConfirmedUser().getUserId())); //NOI18N
-		}
-
-		// Update user list
-		this.updateList(event.getConfirmedUser());
-	}
-
-	/**
-	 * Event observer for new user registrations
-	 * <p>
-	 * @param event User registration event
-	 */
-	public void afterUserRegistrationEvent (@Observes final ObservableUserRegisteredEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getRegisteredUser() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.registeredUser is null"); //NOI18N
-		} else if (event.getRegisteredUser().getUserId() == null) {
-			// userId is null
-			throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
-		} else if (event.getRegisteredUser().getUserId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getRegisteredUser(), event.getRegisteredUser().getUserId())); //NOI18N
-		}
-
-		// Update user list
-		this.updateList(event.getRegisteredUser());
-	}
-
-	/**
-	 * Method being call after user's password has been updated (and history
-	 * entry has been created).
-	 * <p>
-	 * @param event Event being observed
-	 */
-	public void afterUserUpdatedPasswordEvent (@Observes final ObservableUpdatedUserPasswordEvent event) {
-		// Check parameter
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getPasswordHistory() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.passwordHistory is null"); //NOI18N
-		} else if (event.getPasswordHistory().getUserPasswordHistoryId() == null) {
-			// ... and again
-			throw new NullPointerException("event.passwordHistory.userPasswordHistoryId is null"); //NOI18N
-		} else if (event.getPasswordHistory().getUserPasswordHistoryId() < 1) {
-			// Invalid value
-			throw new IllegalArgumentException(MessageFormat.format("event.passwordHistory.userPasswordHistoryId={0} is in valid", event.getPasswordHistory().getUserPasswordHistoryId())); //NOI18N
-		}
-
-		// Update user list
-		this.updateList(event.getPasswordHistory().getUserPasswordHistoryUser());
-	}
-
-	/**
-	 * Listens to fired event when user updated personal data
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterUserUpdatedPersonalDataEvent (@Observes final ObservableUpdatedUserPersonalDataEvent event) {
-		// Check parameter
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getUpdatedUser() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.updatedUser is null"); //NOI18N
-		} else if (event.getUpdatedUser().getUserId() == null) {
-			// ... and again
-			throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
-		} else if (event.getUpdatedUser().getUserId() < 1) {
-			// Invalid value
-			throw new IllegalArgumentException(MessageFormat.format("event.updatedUser.userId={0} is in valid", event.getUpdatedUser().getUserId())); //NOI18N
-		}
-
-		// Update user list
-		this.updateList(event.getUpdatedUser());
-	}
-
-	@Override
-	public User findUserById (final Long userId) throws UserNotFoundException {
-		// Validate parameter
-		if (null == userId) {
-			// Throw NPE
-			throw new NullPointerException("userId is null"); //NOI18N
-		} else if (userId < 1) {
-			// Throw IAE
-			throw new IllegalArgumentException("userId=" + userId + " is invalid."); //NOI18N
-		} else if (!this.userCache.containsKey(userId)) {
-			// Not found
-			throw new UserNotFoundException(userId);
-		}
-
-		// Get it from cache
-		final User user = this.userCache.get(userId);
-
-		// Return it
-		return user;
-	}
-
-	@Override
-	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
-	public List<User> getAllUsers () {
-		return this.allUsers;
-	}
-
-	/**
-	 * Getter for filtered users list
-	 * <p>
-	 * @return Filtered users list
-	 */
-	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
-	public List<User> getFilteredUsers () {
-		return this.filteredUsers;
-	}
-
-	/**
-	 * Setter for filtered users list
-	 * <p>
-	 * @param filteredUsers Filtered users list
-	 */
-	@SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter")
-	public void setFilteredUsers (final List<User> filteredUsers) {
-		this.filteredUsers = filteredUsers;
-	}
-
-	/**
-	 * Getter for selected user instance
-	 * <p>
-	 * @return Selected user instance
-	 */
-	public User getSelectedUser () {
-		return this.selectedUser;
-	}
-
-	/**
-	 * Setter for selected user instance
-	 * <p>
-	 * @param selectedUser Selected user instance
-	 */
-	public void setSelectedUser (final User selectedUser) {
-		this.selectedUser = selectedUser;
-	}
-
-	@Override
-	public boolean ifUserIdExists (final Long userId) {
-		// Validate parameter
-		if (null == userId) {
-			// Throw NPE
-			throw new NullPointerException("userId is null"); //NOI18N
-		} else if (userId < 1) {
-			// Throw IAE
-			throw new IllegalArgumentException("userId=" + userId + " is invalid."); //NOI18N
-		}
-
-		// Check if key is there
-		boolean isFound = this.userCache.containsKey(userId);
-
-		// Return flag
-		return isFound;
-	}
-
-	/**
-	 * Post-initialization of this class
-	 */
-	@PostConstruct
-	public void initializeList () {
-		// Is cache there?
-		if (!this.userCache.iterator().hasNext()) {
-			// Add all
-			for (final User user : this.userBean.allUsers()) {
-				// Add it to cache
-				this.userCache.put(user.getUserId(), user);
-			}
-		}
-
-		// Is cache filled and list is empty
-		if ((this.userCache.iterator().hasNext()) && (this.getAllUsers().isEmpty())) {
-			// Build up list
-			for (final Cache.Entry<Long, User> currentEntry : this.userCache) {
-				// Add to list
-				this.getAllUsers().add(currentEntry.getValue());
-			}
-
-			// Sort list
-			this.getAllUsers().sort(new Comparator<User>() {
-				@Override
-				public int compare (final User user1, final User user2) {
-					return user1.getUserId() > user2.getUserId() ? 1 : user1.getUserId() < user2.getUserId() ? -1 : 0;
-				}
-			});
-
-			// Set full list
-			this.setFilteredUsers(this.getAllUsers());
-		}
-	}
-
-	@Override
-	public boolean isUserNameRegistered (final User user) {
-		// Default is not found
-		boolean isFound = false;
-
-		// Determine it
-		for (final User currentUser : this.getAllUsers()) {
-			// Is same name found?
-			if (Objects.equals(user.getUserName(), currentUser.getUserName())) {
-				// Yes, then set flag and abort loop
-				isFound = true;
-				break;
-			}
-		}
-
-		// Return flag
-		return isFound;
-	}
-
-	@Override
-	public User lookupUserByEmailAddress (final String emailAddress) throws UserEmailAddressNotFoundException {
-		// Parameter must be valid
-		if (null == emailAddress) {
-			// Throw NPE
-			throw new NullPointerException("emailAddress is null"); //NOI18N
-		} else if (emailAddress.isEmpty()) {
-			// Not valid
-			throw new IllegalArgumentException("emailAddress is empty"); //NOI18N
-		}
-
-		// Init variable
-		User user = null;
-
-		// Try to lookup it in visible user list
-		for (final Cache.Entry<Long, User> currentUser : this.userCache) {
-			// Contact should be set
-			if (currentUser.getValue().getUserContact() == null) {
-				// Contact is null
-				throw new NullPointerException(MessageFormat.format("currentUser.userContact is null for user id {0}", currentUser.getKey())); //NOI18N
-			} else if (currentUser.getValue().getUserContact().getContactEmailAddress() == null) {
-				// Email address should be set
-				throw new NullPointerException(MessageFormat.format("currentUser.userContact.contactEmailAddress is null for user id {0}", currentUser.getKey())); //NOI18N
-			}
-
-			// Is the email address found?
-			if (Objects.equals(currentUser.getValue().getUserContact().getContactEmailAddress(), emailAddress)) {
-				// Copy to other variable
-				user = currentUser.getValue();
-				break;
-			}
-		}
-
-		// Is it still null?
-		if (null == user) {
-			// Not visible for the current user
-			throw new UserEmailAddressNotFoundException(emailAddress);
-		}
-
-		// Return it
-		return user;
-	}
-
-	@Override
-	public User lookupUserById (final Long userId) throws UserNotFoundException {
-		// Parameter must be valid
-		if (null == userId) {
-			// Throw NPE
-			throw new NullPointerException("userId is null"); //NOI18N
-		} else if (userId < 1) {
-			// Not valid
-			throw new IllegalArgumentException(MessageFormat.format("userId={0} is not valid.", userId)); //NOI18N
-		}
-
-		// Init variable
-		User user = null;
-
-		// Try to lookup it in visible user list
-		for (final Cache.Entry<Long, User> currentUser : this.userCache) {
-			// Is the user id found?
-			if (Objects.equals(currentUser.getKey(), userId)) {
-				// Copy to other variable
-				user = currentUser.getValue();
-				break;
-			}
-		}
-
-		// Is it still null?
-		if (null == user) {
-			// Not visible for the current user
-			throw new UserNotFoundException(userId);
-		}
-
-		// Return it
-		return user;
-	}
-
-	/**
-	 * Removes user from all lists
-	 * <p>
-	 * @param user User to remove
-	 */
-	private void removeFromList (final User user) {
-		// Remove it from lists
-		this.getAllUsers().remove(user);
-		this.userCache.remove(user.getUserId());
-	}
-
-	/**
-	 * Updates list with given user instance
-	 * <p>
-	 * @param user User instance
-	 */
-	private void updateList (final User user) {
-		// Add/update user
-		this.userCache.put(user.getUserId(), user);
-		this.getAllUsers().add(user);
-	}
-
-}
diff --git a/src/java/org/mxchange/jjobs/beans/country/list/JobsCountryListWebViewBean.java b/src/java/org/mxchange/jjobs/beans/country/list/JobsCountryListWebViewBean.java
index b41c00b0..2939a46d 100644
--- a/src/java/org/mxchange/jjobs/beans/country/list/JobsCountryListWebViewBean.java
+++ b/src/java/org/mxchange/jjobs/beans/country/list/JobsCountryListWebViewBean.java
@@ -186,7 +186,7 @@ public class JobsCountryListWebViewBean extends BaseJobsBean implements JobsCoun
 		// Is cache there?
 		if (!this.countryCache.iterator().hasNext()) {
 			// Add all
-			for (final Country country : this.countryBean.allCountries()) {
+			for (final Country country : this.countryBean.fetchAllCountries()) {
 				// Add it to cache
 				this.countryCache.put(country.getCountryId(), country);
 			}
diff --git a/src/java/org/mxchange/jjobs/beans/helper/JobsWebViewHelperBean.java b/src/java/org/mxchange/jjobs/beans/helper/JobsWebViewHelperBean.java
index ba985837..ac672e79 100644
--- a/src/java/org/mxchange/jjobs/beans/helper/JobsWebViewHelperBean.java
+++ b/src/java/org/mxchange/jjobs/beans/helper/JobsWebViewHelperBean.java
@@ -74,6 +74,12 @@ public class JobsWebViewHelperBean extends BaseJobsBean implements JobsWebViewHe
 	@Inject
 	private Event<ObservableCreatedContactEvent> contactCreatedEvent;
 
+	/**
+	 * Regular user controller
+	 */
+	@Inject
+	private FinancialsContactListWebViewController contactListController;
+
 	/**
 	 * Fax number
 	 */
@@ -121,12 +127,6 @@ public class JobsWebViewHelperBean extends BaseJobsBean implements JobsWebViewHe
 	 */
 	private User user;
 
-	/**
-	 * Regular user controller
-	 */
-	@Inject
-	private JobsUserWebRequestController userListController;
-
 	/**
 	 * Event for when a user instance was created
 	 */
@@ -383,12 +383,12 @@ public class JobsWebViewHelperBean extends BaseJobsBean implements JobsWebViewHe
 		if (this.getMobileNumber() == null) {
 			// Throw NPE
 			throw new NullPointerException("this.mobileNumber is null"); //NOI18N
-		} else if (this.getMobileNumber().getPhoneId() == null) {
+		} else if (this.getMobileNumber().getMobileId() == null) {
 			// Throw again
-			throw new NullPointerException("this.mobileNumber.phoneId is null"); //NOI18N
-		} else if (this.getMobileNumber().getPhoneId() < 1) {
+			throw new NullPointerException("this.mobileNumber.mobileId is null"); //NOI18N
+		} else if (this.getMobileNumber().getMobileId() < 1) {
 			// Invalid id number
-			throw new IllegalArgumentException(MessageFormat.format("this.mobileNumber.phoneId={0} is not valid", this.getMobileNumber().getPhoneId())); //NOI18N
+			throw new IllegalArgumentException(MessageFormat.format("this.mobileNumber.mobileId={0} is not valid", this.getMobileNumber().getMobileId())); //NOI18N
 		} else if (this.getMobileNumber().getMobileProvider() == null) {
 			// Throw NPE again
 			throw new NullPointerException("this.mobileNumber.mobileProvider is null"); //NOI18N
@@ -398,12 +398,12 @@ public class JobsWebViewHelperBean extends BaseJobsBean implements JobsWebViewHe
 		} else if (this.getMobileNumber().getMobileProvider().getProviderId() < 1) {
 			// Invalid id
 			throw new IllegalArgumentException(MessageFormat.format("this.mobileNumber.mobileProvider.providerId={0} is invalid", this.getMobileNumber().getMobileProvider().getProviderId())); //NOI18N
-		} else if (this.getMobileNumber().getPhoneNumber() == null) {
+		} else if (this.getMobileNumber().getMobileNumber() == null) {
 			// Throw NPE again ...
-			throw new NullPointerException("this.mobileNumber.phoneNumber is null"); //NOI18N
-		} else if (this.getMobileNumber().getPhoneNumber() < 1) {
+			throw new NullPointerException("this.mobileNumber.mobileNumber is null"); //NOI18N
+		} else if (this.getMobileNumber().getMobileNumber() < 1) {
 			// Invalid id number
-			throw new IllegalArgumentException(MessageFormat.format("this.mobileNumber.phoneNumber={0} is not valid", this.getMobileNumber().getPhoneNumber())); //NOI18N
+			throw new IllegalArgumentException(MessageFormat.format("this.mobileNumber.mobileNumber={0} is not valid", this.getMobileNumber().getMobileNumber())); //NOI18N
 		}
 
 		// Fire event
@@ -495,7 +495,19 @@ public class JobsWebViewHelperBean extends BaseJobsBean implements JobsWebViewHe
 		// Is a branch office instance given?
 		if (branchOffice instanceof BranchOffice) {
 			// This should not happen:
-			assert (branchOffice.getBranchCompany() instanceof BasicData) : "branchOffice.branchCompany is null"; //NOI18N
+			if (branchOffice.getBranchId() == null) {
+				// Throw NPE
+				throw new NullPointerException("branchOffice.branchId is null"); //NOI18N
+			} else if (branchOffice.getBranchId() < 1) {
+				// Throw IAE
+				throw new IllegalArgumentException(MessageFormat.format("branchOffice.branchId={0} is invalid.", branchOffice.getBranchId())); //NOI18N
+			} else if (branchOffice.getBranchCompany() == null) {
+				// Throw NPE
+				throw new NullPointerException("branchOffice.branchCompany is null"); //NOI18N
+			} else if (branchOffice.getBranchCountry() == null) {
+				// Throw NPE again
+				throw new NullPointerException("branchOffice.branchCountry is null"); //NOI18N
+			}
 
 			// Yes, then append all data
 			sb.append(this.renderBasicData(branchOffice.getBranchCompany(), true));
@@ -719,7 +731,7 @@ public class JobsWebViewHelperBean extends BaseJobsBean implements JobsWebViewHe
 			sb.append(" ("); //NOI18N
 			sb.append(mobileNumber.getMobileProvider().getProviderDialPrefix());
 			sb.append(") "); //NOI18N
-			sb.append(mobileNumber.getPhoneNumber());
+			sb.append(mobileNumber.getMobileNumber());
 		}
 
 		// Return it
diff --git a/src/java/org/mxchange/jjobs/beans/mobile/FinancialsAdminMobileWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/mobile/FinancialsAdminMobileWebRequestBean.java
new file mode 100644
index 00000000..8851f632
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/mobile/FinancialsAdminMobileWebRequestBean.java
@@ -0,0 +1,423 @@
+/*
+ * Copyright (C) 2016 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.mobile;
+
+import java.text.MessageFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+import javax.ejb.EJB;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.event.Event;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Any;
+import javax.faces.application.FacesMessage;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jfinancials.beans.BaseFinancialsBean;
+import org.mxchange.jfinancials.beans.mobile.list.FinancialsMobileListWebViewController;
+import org.mxchange.jphone.events.mobile.created.ObservableCreatedMobileNumberEvent;
+import org.mxchange.jphone.events.mobile.deleted.AdminDeletedMobileNumberEvent;
+import org.mxchange.jphone.events.mobile.deleted.AdminMobileNumberDeletedEvent;
+import org.mxchange.jphone.events.mobile.remove.AdminMobileNumberRemovedFromListEvent;
+import org.mxchange.jphone.events.mobile.remove.AdminRemoveMobileNumberFromListEvent;
+import org.mxchange.jphone.events.mobile.updated.AdminMobileNumberUpdatedEvent;
+import org.mxchange.jphone.events.mobile.updated.AdminUpdatedMobileNumberEvent;
+import org.mxchange.jphone.model.phonenumbers.mobile.AdminMobileSessionBeanRemote;
+import org.mxchange.jphone.model.phonenumbers.mobile.DialableMobileNumber;
+import org.mxchange.jphone.model.phonenumbers.mobile.MobileNumber;
+import org.mxchange.jphone.model.phonenumbers.mobileprovider.MobileProvider;
+
+/**
+ * Administrative bean (controller) for mobile numbers
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("adminMobileController")
+@RequestScoped
+public class FinancialsAdminMobileWebRequestBean extends BaseFinancialsBean implements FinancialsAdminMobileWebRequestController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 184_598_175_371_269_017L;
+
+	/**
+	 * Remote EJB for phone number (administrative)
+	 */
+	@EJB (lookup = "java:global/jfinancials-ejb/adminMobile!org.mxchange.jphone.model.phonenumbers.mobile.AdminMobileSessionBeanRemote")
+	private AdminMobileSessionBeanRemote adminMobileBean;
+
+	/**
+	 * When the phone entry has been created (persisted)
+	 */
+	private Date mobileEntryCreated;
+
+	/**
+	 * When the phone entry has been updated
+	 */
+	private Date mobileEntryUpdated;
+
+	/**
+	 * Mobile id (aka primary key)
+	 */
+	private Long mobileId;
+
+	/**
+	 * Generic hone controller
+	 */
+	@Inject
+	private FinancialsMobileListWebViewController mobileListController;
+
+	/**
+	 * Mobile number
+	 */
+	private Long mobileNumber;
+
+	/**
+	 * Event being fired when an administrator has deleted mobile number
+	 */
+	@Inject
+	@Any
+	private Event<AdminDeletedMobileNumberEvent> mobileNumberDeletedEvent;
+
+	/**
+	 * Event being fired when an administrator has updated land-line number
+	 */
+	@Inject
+	@Any
+	private Event<AdminUpdatedMobileNumberEvent> mobileNumberUpdatedEvent;
+
+	/**
+	 * Mobile provider
+	 */
+	private MobileProvider mobileProvider;
+
+	/**
+	 * Event being fired when a list of all unused mobile numbers is being
+	 * created.
+	 */
+	@Inject
+	@Any
+	private Event<AdminRemoveMobileNumberFromListEvent> removeLinkedMobileNumbersEvent;
+
+	/**
+	 * Chosen mobile number
+	 */
+	private DialableMobileNumber selectedMobileNumber;
+
+	/**
+	 * Default constructor
+	 */
+	public FinancialsAdminMobileWebRequestBean () {
+		// Call super constructor
+		super();
+	}
+
+	/**
+	 * Observes events being fired when a bean helper has successfully created a
+	 * mobile number instance.
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterCreatedMobileNumberEvent (@Observes final ObservableCreatedMobileNumberEvent event) {
+		// The event instance must be valid
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getMobileNumber() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.mobileNumber is null"); //NOI18N
+		} else if (event.getMobileNumber().getMobileId() == null) {
+			// Throw NPE yet again
+			throw new NullPointerException("event.mobileNumber.mobileId is null"); //NOI18N
+		} else if (event.getMobileNumber().getMobileId() < 1) {
+			// Throw NPE yet again
+			throw new NullPointerException(MessageFormat.format("event.mobileNumber.mobileId={0} is invalid", event.getMobileNumber().getMobileId())); //NOI18N
+		}
+
+		// Get fax number from event
+		final DialableMobileNumber number = event.getMobileNumber();
+
+		// Copy all data to this bean
+		this.setMobileId(number.getMobileId());
+		this.setMobileProvider(number.getMobileProvider());
+		this.setMobileNumber(number.getMobileNumber());
+		this.setMobileEntryCreated(number.getMobileEntryCreated());
+		this.setMobileEntryUpdated(number.getMobileEntryUpdated());
+	}
+
+	/**
+	 * Returns a list of all unused ("non-linked") mobile numbers
+	 * <p>
+	 * @return List with all unused mobile numbers
+	 */
+	public List<DialableMobileNumber> allNonLinkedMobileNumbers () {
+		// Get list of all mobile numbers
+		final List<DialableMobileNumber> numbers = this.mobileListController.getAllMobileNumbers();
+
+		// Visit all controllers to reduce the list
+		this.removeLinkedMobileNumbersEvent.fire(new AdminMobileNumberRemovedFromListEvent(numbers));
+
+		// Return it
+		return numbers;
+	}
+
+	/**
+	 * Deletes given mobile entry data
+	 */
+	public void deleteMobileData () {
+		// Get mobile number from helper
+		final DialableMobileNumber number = this.createMobileNumber();
+
+		// Is all data set
+		if (number == null) {
+			// Not set, throw NPE
+			throw new NullPointerException("mobileNumber is null"); //NOI18N
+		} else if (number.getMobileId() == null) {
+			// Throw NPE again
+			throw new NullPointerException("mobileNumber.mobileId is null"); //NOI18N
+		} else if (number.getMobileId() < 1) {
+			// Invalid number
+			throw new IllegalArgumentException(MessageFormat.format("mobileNumber.mobileId={0} is not valid", number.getMobileId())); //NOI18N
+		} else if (number.getMobileProvider() == null) {
+			// Throw NPE
+			throw new NullPointerException("mobileNumber.mobileProvider is null"); //NOI18N
+		} else if (number.getMobileProvider().getProviderId() == null) {
+			// ... throw again
+			throw new NullPointerException("mobileNumber.mobileProvider.providerId is null"); //NOI18N
+		} else if (number.getMobileProvider().getProviderId() < 1) {
+			// Id not valid
+			throw new IllegalArgumentException(MessageFormat.format("mobileNumber.mobileProvider.providerId={0} is not valid.", number.getMobileProvider().getProviderId())); //NOI18N
+		} else if (number.getMobileNumber() == null) {
+			// Throw NPE again
+			throw new NullPointerException("mobileNumber.mobileNumber is null"); //NOI18N
+		} else if (number.getMobileNumber() < 1) {
+			// Throw NPE again
+			throw new NullPointerException(MessageFormat.format("mobileNumber.mobileNumber={0} is not valid.", number.getMobileNumber())); //NOI18N
+		}
+
+		// Call EJB
+		this.adminMobileBean.deleteMobileData(number);
+
+		// Fire event
+		this.mobileNumberDeletedEvent.fire(new AdminMobileNumberDeletedEvent(number));
+	}
+
+	/**
+	 * Changes mobile entry data
+	 * <p>
+	 * @return Redirect outcome
+	 */
+	public String doUpdateMobileNumber () {
+		// Get mobile number from helper
+		final DialableMobileNumber number = this.createMobileNumber();
+
+		// Is all data set
+		if (number == null) {
+			// Not set, throw NPE
+			throw new NullPointerException("mobileNumber is null"); //NOI18N
+		} else if (number.getMobileId() == null) {
+			// Throw NPE again
+			throw new NullPointerException("mobileNumber.mobileId is null"); //NOI18N
+		} else if (number.getMobileId() < 1) {
+			// Invalid number
+			throw new IllegalArgumentException(MessageFormat.format("mobileNumber.mobileId={0} is not valid", number.getMobileId())); //NOI18N
+		} else if (number.getMobileProvider() == null) {
+			// Throw NPE
+			throw new NullPointerException("mobileNumber.mobileProvider is null"); //NOI18N
+		} else if (number.getMobileProvider().getProviderId() == null) {
+			// ... throw again
+			throw new NullPointerException("mobileNumber.mobileProvider.providerId is null"); //NOI18N
+		} else if (number.getMobileProvider().getProviderId() < 1) {
+			// Id not valid
+			throw new IllegalArgumentException(MessageFormat.format("mobileNumber.mobileProvider.providerId={0} is not valid.", number.getMobileProvider().getProviderId())); //NOI18N
+		} else if (number.getMobileNumber() == null) {
+			// Throw NPE again
+			throw new NullPointerException("mobileNumber.mobileNumber is null"); //NOI18N
+		} else if (number.getMobileNumber() < 1) {
+			// Throw NPE again
+			throw new NullPointerException(MessageFormat.format("mobileNumber.mobileNumber={0} is not valid.", number.getMobileNumber())); //NOI18N
+		} else if (this.getMobileProvider() == null) {
+			// Throw NPE again
+			throw new NullPointerException("this.mobileProvider is null"); //NOI18N
+		} else if (this.getMobileProvider().getProviderId() == null) {
+			// Throw NPE again ...
+			throw new NullPointerException("this.mobileProvider.providerId is null"); //NOI18N
+		} else if (this.getMobileProvider().getProviderId() < 0) {
+			// Invalid id number
+			throw new IllegalArgumentException(MessageFormat.format("this.mobileProvider.providerId={0} is not valid.", this.getMobileProvider().getProviderId())); //NOI18N
+		} else if (this.getMobileNumber() == null) {
+			// Throw NPE
+			throw new NullPointerException("this.phoneNumber is null"); //NOI18N
+		}
+
+		// Is the mobile provider and number the same?
+		if ((Objects.equals(this.getMobileProvider(), number.getMobileProvider())) && (Objects.equals(this.getMobileNumber(), number.getMobileNumber()))) {
+			// Show message
+			this.showFacesMessage("form_edit_mobile:mobileNumber", "ERROR_ADMIN_NO_CHANGE_ENTERED", FacesMessage.SEVERITY_WARN); //NOI18N
+
+			// No difference in both together, no need to edit
+			return ""; //NOI18N
+		}
+
+		// Set all data
+		number.setMobileProvider(this.getMobileProvider());
+		number.setMobileNumber(this.getMobileNumber());
+
+		// Send to bean
+		final DialableMobileNumber updatedNumber = this.adminMobileBean.updateMobileData(number);
+
+		// Fire event
+		this.mobileNumberUpdatedEvent.fire(new AdminMobileNumberUpdatedEvent(updatedNumber));
+
+		// All fine, redirect
+		return "admin_show_mobile"; //NOI18N
+	}
+
+	/**
+	 * Getter for phone entry created timestamp
+	 * <p>
+	 * @return Mobile entry created timestamp
+	 */
+	@SuppressWarnings ("ReturnOfDateField")
+	public Date getMobileEntryCreated () {
+		return this.mobileEntryCreated;
+	}
+
+	/**
+	 * Setter for phone entry created timestamp
+	 * <p>
+	 * @param mobileEntryCreated Mobile entry created timestamp
+	 */
+	@SuppressWarnings ("AssignmentToDateFieldFromParameter")
+	public void setMobileEntryCreated (final Date mobileEntryCreated) {
+		this.mobileEntryCreated = mobileEntryCreated;
+	}
+
+	/**
+	 * Getter for phone entry updated timestamp
+	 * <p>
+	 * @return Mobile entry updated timestamp
+	 */
+	@SuppressWarnings ("ReturnOfDateField")
+	public Date getMobileEntryUpdated () {
+		return this.mobileEntryUpdated;
+	}
+
+	/**
+	 * Setter for phone entry updated timestamp
+	 * <p>
+	 * @param mobileEntryUpdated Mobile entry updated timestamp
+	 */
+	@SuppressWarnings ("AssignmentToDateFieldFromParameter")
+	public void setMobileEntryUpdated (final Date mobileEntryUpdated) {
+		this.mobileEntryUpdated = mobileEntryUpdated;
+	}
+
+	/**
+	 * Getter for phone id
+	 * <p>
+	 * @return Mobile id
+	 */
+	public Long getMobileId () {
+		return this.mobileId;
+	}
+
+	/**
+	 * Setter for phone id
+	 * <p>
+	 * @param mobileId Mobile id
+	 */
+	public void setMobileId (final Long mobileId) {
+		this.mobileId = mobileId;
+	}
+
+	/**
+	 * Getter for dial number without prefix
+	 * <p>
+	 * @return Dial number without prefix
+	 */
+	public Long getMobileNumber () {
+		return this.mobileNumber;
+	}
+
+	/**
+	 * Setter for dial number without prefix
+	 * <p>
+	 * @param mobileNumber Dial number without prefix
+	 */
+	public void setMobileNumber (final Long mobileNumber) {
+		this.mobileNumber = mobileNumber;
+	}
+
+	/**
+	 * Getter for mobile provider
+	 * <p>
+	 * @return Mobile provider
+	 */
+	public MobileProvider getMobileProvider () {
+		return this.mobileProvider;
+	}
+
+	/**
+	 * Setter for mobile provider
+	 * <p>
+	 * @param mobileProvider Mobile provider
+	 */
+	public void setMobileProvider (final MobileProvider mobileProvider) {
+		this.mobileProvider = mobileProvider;
+	}
+
+	/**
+	 * Getter for chosen mobile number
+	 * <p>
+	 * @return mobile number
+	 */
+	public DialableMobileNumber getSelectedMobileNumber () {
+		return this.selectedMobileNumber;
+	}
+
+	/**
+	 * Setter for chosen mobile number
+	 * <p>
+	 * @param selectedMobileNumber mobile number
+	 */
+	public void setSelectedMobileNumber (final DialableMobileNumber selectedMobileNumber) {
+		this.selectedMobileNumber = selectedMobileNumber;
+	}
+
+	/**
+	 * Returns an instance of a DialableMobileNumber from all fields stored in
+	 * this bean.
+	 * <p>
+	 * @return An instance of a DialableMobileNumber class
+	 */
+	private DialableMobileNumber createMobileNumber () {
+		// Initialize it
+		final DialableMobileNumber number = new MobileNumber(this.getMobileProvider(), this.getMobileNumber());
+
+		// Add all other data
+		number.setMobileEntryCreated(this.getMobileEntryCreated());
+		number.setMobileEntryUpdated(this.getMobileEntryUpdated());
+		number.setMobileId(this.getMobileId());
+
+		// Return it
+		return number;
+	}
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/mobile/FinancialsAdminMobileWebRequestController.java b/src/java/org/mxchange/jjobs/beans/mobile/FinancialsAdminMobileWebRequestController.java
new file mode 100644
index 00000000..3a5a8f7f
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/mobile/FinancialsAdminMobileWebRequestController.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.mobile;
+
+import java.io.Serializable;
+
+/**
+ * An interface for a request web controller (bean) for administrative phone
+ * number purposes.
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsAdminMobileWebRequestController extends Serializable {
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/mobile/list/FinancialsMobileListWebViewBean.java b/src/java/org/mxchange/jjobs/beans/mobile/list/FinancialsMobileListWebViewBean.java
new file mode 100644
index 00000000..5c6a03f0
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/mobile/list/FinancialsMobileListWebViewBean.java
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2016 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.mobile.list;
+
+import fish.payara.cdi.jsr107.impl.NamedCache;
+import java.text.MessageFormat;
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import javax.annotation.PostConstruct;
+import javax.cache.Cache;
+import javax.ejb.EJB;
+import javax.enterprise.event.Observes;
+import javax.faces.view.ViewScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jcontacts.events.contact.add.ObservableAdminAddedContactEvent;
+import org.mxchange.jcontacts.events.contact.update.ObservableAdminUpdatedContactEvent;
+import org.mxchange.jcontacts.events.mobile.linked.ObservableAdminLinkedMobileNumberEvent;
+import org.mxchange.jcontacts.model.contact.Contact;
+import org.mxchange.jfinancials.beans.BaseFinancialsBean;
+import org.mxchange.jphone.events.mobile.deleted.AdminDeletedMobileNumberEvent;
+import org.mxchange.jphone.events.mobile.updated.AdminUpdatedMobileNumberEvent;
+import org.mxchange.jphone.exceptions.mobile.MobileEntityNotFoundException;
+import org.mxchange.jphone.model.phonenumbers.mobile.DialableMobileNumber;
+import org.mxchange.jphone.model.phonenumbers.mobile.MobileSessionBeanRemote;
+import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
+
+/**
+ * Administrative listing controller (bean) for mobile numbers
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("mobileListController")
+@ViewScoped
+public class FinancialsMobileListWebViewBean extends BaseFinancialsBean implements FinancialsMobileListWebViewController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 491_058_674_675_690_106L;
+
+	/**
+	 * A list of all mobile numbers
+	 */
+	private final List<DialableMobileNumber> allMobileNumbers;
+
+	/**
+	 * A list of filtered mobile numbers
+	 */
+	private List<DialableMobileNumber> filteredMobileNumbers;
+
+	/**
+	 * General EJB for mobile numbers
+	 */
+	@EJB (lookup = "java:global/jfinancials-ejb/mobile!org.mxchange.jphone.model.phonenumbers.mobile.MobileSessionBeanRemote")
+	private MobileSessionBeanRemote mobileBean;
+
+	/**
+	 * Cache for mobile numbers
+	 */
+	@Inject
+	@NamedCache (cacheName = "mobileNumberCache")
+	private transient Cache<Long, DialableMobileNumber> mobileNumberCache;
+
+	/**
+	 * Default constructor
+	 */
+	public FinancialsMobileListWebViewBean () {
+		// Call super constructor
+		super();
+
+		// Init list
+		this.allMobileNumbers = new LinkedList<>();
+	}
+
+	/**
+	 * Observes events being fired when an administrator has added a new
+	 * contact.
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminAddedContactEvent (@Observes final ObservableAdminAddedContactEvent event) {
+		// The event must be valid
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getAddedContact() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.addedContact is null"); //NOI18N
+		} else if (event.getAddedContact().getContactId() == null) {
+			// ... and again
+			throw new NullPointerException("event.addedContact.contactId is null"); //NOI18N
+		} else if (event.getAddedContact().getContactId() < 1) {
+			// Not valid
+			throw new IllegalArgumentException(MessageFormat.format("event.addedContact.contactId={0} is not valid", event.getAddedContact().getContactId())); //NOI18N
+		}
+
+		// Update contact's mobile, land-line and mobile number
+		this.updateContactMobileNumbers(event.getAddedContact());
+
+		// Clear this bean
+		this.clear();
+	}
+
+	/**
+	 * Event observer for newly added users by administrator
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getAddedUser() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.addedUser is null"); //NOI18N
+		} else if (event.getAddedUser().getUserId() == null) {
+			// userId is null
+			throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
+		} else if (event.getAddedUser().getUserId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
+		}
+
+		// Update contact's mobile, land-line and mobile number
+		this.updateContactMobileNumbers(event.getAddedUser().getUserContact());
+
+		// Clear all data
+		this.clear();
+	}
+
+	/**
+	 * Observes events being fired when an administrator has deleted a land-line
+	 * number
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminDeletedMobileNumberEvent (@Observes final AdminDeletedMobileNumberEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getDeletedMobileNumber() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.deletedMobileNumber is null"); //NOI18N
+		} else if (event.getDeletedMobileNumber().getMobileId() == null) {
+			// userId is null
+			throw new NullPointerException("event.deletedMobileNumber.mobileId is null"); //NOI18N
+		} else if (event.getDeletedMobileNumber().getMobileId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("mobileId of contact={0} is not valid: {1}", event.getDeletedMobileNumber(), event.getDeletedMobileNumber().getMobileId())); //NOI18N
+		}
+
+		// Update contact's mobile, land-line and mobile number
+		this.getAllMobileNumbers().remove(event.getDeletedMobileNumber());
+
+		// Clear all data
+		this.clear();
+	}
+
+	/**
+	 * Observes events being fired when an administrator has a linked a
+	 * land-line number
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminLinkedMobileNumberEvent (@Observes final ObservableAdminLinkedMobileNumberEvent event) {
+		// Is the event fine?
+		if (event == null) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getContact() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.contact is null"); //NOI18N
+		} else if (event.getContact().getContactId() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.contact.contactId is null"); //NOI18N
+		} else if (event.getContact().getContactId() < 1) {
+			// Throw again ...
+			throw new NullPointerException(MessageFormat.format("event.contact.contactId={0} is invalid", event.getContact().getContactId())); //NOI18N
+		} else if (event.getContact().getContactMobileNumber() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.contact.contactMobileNumber is null"); //NOI18N
+		} else if (event.getContact().getContactMobileNumber().getMobileId() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.contact.contactMobileNumber.mobileId is null"); //NOI18N
+		} else if (event.getContact().getContactMobileNumber().getMobileId() < 1) {
+			// Throw again ...
+			throw new NullPointerException(MessageFormat.format("event.contact.contactMobileNumber.mobileId={0} is invalid", event.getContact().getContactMobileNumber().getMobileId())); //NOI18N
+		} else if (event.getLinkedMobileNumber() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.linkedMobileNumer is null"); //NOI18N
+		}
+
+		// Is the id number in linked number not set?
+		if (event.getLinkedMobileNumber().getMobileId() == null) {
+			// Then it is a new number, so add it from contact as there the id number has been set
+			this.uniqueAddMobileNumber(event.getContact().getContactMobileNumber());
+		}
+	}
+
+	/**
+	 * Observes events being fired when an administrator has updated contact
+	 * data.
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminUpdatedContactDataEvent (@Observes final ObservableAdminUpdatedContactEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUpdatedContact() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.updatedContact is null"); //NOI18N
+		} else if (event.getUpdatedContact().getContactId() == null) {
+			// userId is null
+			throw new NullPointerException("event.updatedContact.contactId is null"); //NOI18N
+		} else if (event.getUpdatedContact().getContactId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUpdatedContact(), event.getUpdatedContact().getContactId())); //NOI18N
+		}
+
+		// Update contact's mobile, land-line and mobile number
+		this.updateContactMobileNumbers(event.getUpdatedContact());
+
+		// Clear all data
+		this.clear();
+	}
+
+	/**
+	 * Observes events being fired when an administrator has updated a land-line
+	 * number.
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminUpdatedMobileNumberEvent (@Observes final AdminUpdatedMobileNumberEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUpdatedMobileNumber() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.updatedMobileNumber is null"); //NOI18N
+		} else if (event.getUpdatedMobileNumber().getMobileId() == null) {
+			// userId is null
+			throw new NullPointerException("event.updatedMobileNumber.mobileId is null"); //NOI18N
+		} else if (event.getUpdatedMobileNumber().getMobileId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("mobileId of contact={0} is not valid: {1}", event.getUpdatedMobileNumber(), event.getUpdatedMobileNumber().getMobileId())); //NOI18N
+		}
+
+		// Uniquely add it
+		this.uniqueAddMobileNumber(event.getUpdatedMobileNumber());
+
+		// Clear it
+		this.clear();
+	}
+
+	@Override
+	public DialableMobileNumber findMobileNumberById (final Long mobileNumberId) throws MobileEntityNotFoundException {
+		// Validate paramter
+		if (null == mobileNumberId) {
+			// Throw NPE
+			throw new NullPointerException("mobileNumberId is null"); //NOI18N
+		} else if (mobileNumberId < 1) {
+			// Throw IAE
+			throw new IllegalArgumentException(MessageFormat.format("mobileNumberId={0} is invalid.", mobileNumberId)); //NOI18N
+		} else if (!this.mobileNumberCache.containsKey(mobileNumberId)) {
+			// Not found
+			throw new MobileEntityNotFoundException(mobileNumberId);
+		}
+
+		// Get it from cache
+		final DialableMobileNumber mobileNumber = this.mobileNumberCache.get(mobileNumberId);
+
+		// Return it
+		return mobileNumber;
+	}
+
+	@Override
+	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
+	public List<DialableMobileNumber> getAllMobileNumbers () {
+		return this.allMobileNumbers;
+	}
+
+	/**
+	 * Getter for filtered mobile numbers
+	 * <p>
+	 * @return Filtered mobile numbers
+	 */
+	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
+	public List<DialableMobileNumber> getFilteredMobileNumbers () {
+		return this.filteredMobileNumbers;
+	}
+
+	/**
+	 * Setter for filtered mobile numbers
+	 * <p>
+	 * @param filteredMobileNumbers Filtered mobile numbers
+	 */
+	@SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter")
+	public void setFilteredMobileNumbers (final List<DialableMobileNumber> filteredMobileNumbers) {
+		this.filteredMobileNumbers = filteredMobileNumbers;
+	}
+
+	/**
+	 * Post-construction method
+	 */
+	@PostConstruct
+	public void initializeList () {
+		// Is cache there?
+		if (!this.mobileNumberCache.iterator().hasNext()) {
+			// Add all
+			for (final DialableMobileNumber currentNumber : this.mobileBean.fetchAllMobileNumbers()) {
+				// Add it to cache
+				this.mobileNumberCache.put(currentNumber.getMobileId(), currentNumber);
+			}
+		}
+
+		// Is cache filled and list is empty
+		if ((this.mobileNumberCache.iterator().hasNext()) && (this.getAllMobileNumbers().isEmpty())) {
+			// Build up list
+			for (final Cache.Entry<Long, DialableMobileNumber> currentEntry : this.mobileNumberCache) {
+				// Add to list
+				this.getAllMobileNumbers().add(currentEntry.getValue());
+			}
+
+			// Sort list
+			this.getAllMobileNumbers().sort(new Comparator<DialableMobileNumber>() {
+				@Override
+				public int compare (final DialableMobileNumber mobileNumber1, final DialableMobileNumber mobileNumber2) {
+					return mobileNumber1.getMobileId() > mobileNumber2.getMobileId() ? 1 : mobileNumber1.getMobileId() < mobileNumber2.getMobileId() ? -1 : 0;
+				}
+			});
+
+			// Set full list
+			this.setFilteredMobileNumbers(this.getAllMobileNumbers());
+		}
+	}
+
+	/**
+	 * Clears this bean
+	 */
+	private void clear () {
+		// Clear all data
+	}
+
+	/**
+	 * Uniquely add given land-line number to this bean's list. First remove the
+	 * old instance (by id number), then re-add it again.
+	 * <p>
+	 * @param mobileNumber Land-line number to add
+	 */
+	private void uniqueAddMobileNumber (final DialableMobileNumber mobileNumber) {
+		// Make sure the parameter is valid
+		if (null == mobileNumber) {
+			// Throw NPE
+			throw new NullPointerException("mobileNumber is null"); //NOI18N
+		} else if (mobileNumber.getMobileId() == null) {
+			// Throw again ...
+			throw new NullPointerException("mobileNumber.mobileId is null"); //NOI18N
+		} else if (mobileNumber.getMobileId() < 1) {
+			// Not valid
+			throw new IllegalArgumentException(MessageFormat.format("mobileNumber.mobileId={0} is not valid.", mobileNumber.getMobileId())); //NOI18N
+		}
+
+		// First remove it
+		if (!this.getAllMobileNumbers().remove(mobileNumber)) {
+			// Did not work, try by id number
+			for (final DialableMobileNumber currentNumber : this.getAllMobileNumbers()) {
+				// Is id number the same?
+				if (Objects.equals(currentNumber.getMobileId(), mobileNumber.getMobileId())) {
+					// Found it
+					this.getAllMobileNumbers().remove(currentNumber);
+					break;
+				}
+			}
+		}
+
+		// ... then add it
+		this.getAllMobileNumbers().add(mobileNumber);
+	}
+
+	/**
+	 * Updates given contact's mobile number
+	 * <p>
+	 * @param contact Contact instance
+	 */
+	private void updateContactMobileNumbers (final Contact contact) {
+		// Parameter must be valid
+		if (null == contact) {
+			// Throw NPE
+			throw new NullPointerException("contact is null"); //NOI18N
+		} else if (contact.getContactId() == null) {
+			// Throw again
+			throw new NullPointerException("contact.contactId is null"); //NOI18N
+		} else if (contact.getContactId() < 1) {
+			// Id number is not valid
+		}
+
+		// Is land-line set?
+		if (contact.getContactMobileNumber() instanceof DialableMobileNumber) {
+			// Unique-add it
+			this.uniqueAddMobileNumber(contact.getContactMobileNumber());
+		}
+	}
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/mobile/list/FinancialsMobileListWebViewController.java b/src/java/org/mxchange/jjobs/beans/mobile/list/FinancialsMobileListWebViewController.java
new file mode 100644
index 00000000..18a38fb6
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/mobile/list/FinancialsMobileListWebViewController.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.mobile.list;
+
+import java.io.Serializable;
+import java.util.List;
+import org.mxchange.jphone.exceptions.mobile.MobileEntityNotFoundException;
+import org.mxchange.jphone.model.phonenumbers.mobile.DialableMobileNumber;
+
+/**
+ * An interface for a request web controller (bean) for administrative phone
+ * number purposes.
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsMobileListWebViewController extends Serializable {
+
+	/**
+	 * Returns a list of all mobile numbers. For performance reasons, the
+	 * controller (bean) should be view-scoped as from user to user nothing
+	 * changes. And the controller's post-construct method should load all
+	 * numbers and cache it in the controller.
+	 * <p>
+	 * @return List of all mobile numbers
+	 */
+	List<DialableMobileNumber> getAllMobileNumbers ();
+
+	/**
+	 * Finds a mobile entry by given id number
+	 * <p>
+	 * @param mobileNumberId Mobile entry id number
+	 * <p>
+	 * @return A valid mobile instance
+	 * <p>
+	 * @throws MobileEntityNotFoundException If the entity was not found
+	 */
+	DialableMobileNumber findMobileNumberById (Long mobileNumberId) throws MobileEntityNotFoundException;
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/mobileprovider/JobsAdminMobileProviderWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/mobileprovider/JobsAdminMobileProviderWebRequestBean.java
index b66314fa..bd3fccd7 100644
--- a/src/java/org/mxchange/jjobs/beans/mobileprovider/JobsAdminMobileProviderWebRequestBean.java
+++ b/src/java/org/mxchange/jjobs/beans/mobileprovider/JobsAdminMobileProviderWebRequestBean.java
@@ -27,6 +27,7 @@ import javax.inject.Inject;
 import javax.inject.Named;
 import org.mxchange.jcountry.model.data.Country;
 import org.mxchange.jjobs.beans.BaseJobsBean;
+import org.mxchange.jfinancials.beans.mobileprovider.list.FinancialsMobileProviderListWebViewController;
 import org.mxchange.jphone.events.mobileprovider.added.AdminAddedMobileProviderEvent;
 import org.mxchange.jphone.events.mobileprovider.added.AdminMobileProviderAddedEvent;
 import org.mxchange.jphone.exceptions.mobileprovider.MobileProviderAlreadyAddedException;
@@ -55,10 +56,10 @@ public class JobsAdminMobileProviderWebRequestBean extends BaseJobsBean implemen
 	private AdminMobileProviderSessionBeanRemote adminRemoteBean;
 
 	/**
-	 * Regular bean
+	 * Mobile provider list view
 	 */
 	@Inject
-	private JobsMobileProviderWebRequestController mobileController;
+	private FinancialsMobileProviderListWebViewController mobileProviderListController;
 
 	/**
 	 * Event being fired when the mobile provider was added
@@ -213,7 +214,7 @@ public class JobsAdminMobileProviderWebRequestBean extends BaseJobsBean implemen
 		boolean isFound = false;
 
 		// Loop through all
-		for (final MobileProvider currentMobileProvider : this.mobileController.allMobileProviders()) {
+		for (final MobileProvider currentMobileProvider : this.mobileProviderListController.getAllMobileProviders()) {
 			// Is the provider's dial prefix and country the same?
 			if (Objects.equals(mobileProvider, currentMobileProvider)) {
 				// Is the same, abort loop
diff --git a/src/java/org/mxchange/jjobs/beans/mobileprovider/JobsMobileProviderWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/mobileprovider/JobsMobileProviderWebRequestBean.java
index fb8ca25a..c42041b8 100644
--- a/src/java/org/mxchange/jjobs/beans/mobileprovider/JobsMobileProviderWebRequestBean.java
+++ b/src/java/org/mxchange/jjobs/beans/mobileprovider/JobsMobileProviderWebRequestBean.java
@@ -16,22 +16,10 @@
  */
 package org.mxchange.jjobs.beans.mobileprovider;
 
-import fish.payara.cdi.jsr107.impl.NamedCache;
-import java.text.MessageFormat;
-import java.util.Comparator;
-import java.util.LinkedList;
-import java.util.List;
-import javax.annotation.PostConstruct;
-import javax.cache.Cache;
 import javax.ejb.EJB;
 import javax.enterprise.context.RequestScoped;
-import javax.enterprise.event.Observes;
-import javax.inject.Inject;
 import javax.inject.Named;
 import org.mxchange.jjobs.beans.BaseJobsBean;
-import org.mxchange.jphone.events.mobileprovider.added.AdminAddedMobileProviderEvent;
-import org.mxchange.jphone.exceptions.mobileprovider.MobileProviderNotFoundException;
-import org.mxchange.jphone.model.phonenumbers.mobileprovider.MobileProvider;
 import org.mxchange.jphone.model.phonenumbers.mobileprovider.MobileProviderSingletonBeanRemote;
 
 /**
@@ -48,144 +36,17 @@ public class JobsMobileProviderWebRequestBean extends BaseJobsBean implements Jo
 	 */
 	private static final long serialVersionUID = 15_869_423_671_950_276L;
 
-	/**
-	 * A list of all mobile providers
-	 */
-	private final List<MobileProvider> allMobileProviders;
-
-	/**
-	 * A list of filtered mobile providers
-	 */
-	private List<MobileProvider> filteredMobileProviders;
-
 	/**
 	 * Remote EJB for mobile providers (regular)
 	 */
 	@EJB (lookup = "java:global/jjobs-ejb/mobileProvider!org.mxchange.jphone.model.phonenumbers.mobileprovider.MobileProviderSingletonBeanRemote")
 	private MobileProviderSingletonBeanRemote mobileProviderBean;
 
-	/**
-	 * "Cached" list of mobile providers
-	 */
-	@Inject
-	@NamedCache (cacheName = "mobileProviderCache")
-	private Cache<Long, MobileProvider> mobileProviderCache;
-
 	/**
 	 * Default constructor
 	 */
 	public JobsMobileProviderWebRequestBean () {
 		// Call super constructor
 		super();
-
-		// Init list
-		this.allMobileProviders = new LinkedList<>();
-	}
-
-	/**
-	 * Observes events being fired after the administrator has added a new
-	 * mobile provider
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminAddedMobileProviderEvent (@Observes final AdminAddedMobileProviderEvent event) {
-		// Is all valid?
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getAddedMobileProvider() == null) {
-			// Throw again ...
-			throw new NullPointerException("event.addedMobileProvider is null"); //NOI18N
-		} else if (event.getAddedMobileProvider().getProviderId() == null) {
-			// And again ...
-			throw new NullPointerException("event.addedMobileProvider.providerId is null"); //NOI18N
-		} else if (event.getAddedMobileProvider().getProviderId() < 1) {
-			// Id is invalid
-			throw new IllegalArgumentException(MessageFormat.format("event.addedMobileProvider.providerId={0} is not valid.", event.getAddedMobileProvider().getProviderId())); //NOI18N
-		}
-
-		// Add it to the list
-		this.mobileProviderCache.put(event.getAddedMobileProvider().getProviderId(), event.getAddedMobileProvider());
-		this.allMobileProviders.add(event.getAddedMobileProvider());
-	}
-
-	@Override
-	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
-	public List<MobileProvider> allMobileProviders () {
-		// Return it
-		return this.allMobileProviders;
-	}
-
-	@Override
-	public MobileProvider findMobileProviderById (final Long mobileProviderId) throws MobileProviderNotFoundException {
-		// Validate parameter
-		if (null == mobileProviderId) {
-			// Throw NPE
-			throw new NullPointerException("mobileProviderId is null"); //NOI18N
-		} else if (mobileProviderId < 1) {
-			// Throw IAE
-			throw new IllegalArgumentException("mobileProviderId=" + mobileProviderId + " is invalid."); //NOI18N
-		} else if (!this.mobileProviderCache.containsKey(mobileProviderId)) {
-			// Not found
-			throw new MobileProviderNotFoundException(mobileProviderId);
-		}
-
-		// Get it from cache
-		final MobileProvider mobileProvider = this.mobileProviderCache.get(mobileProviderId);
-
-		// Return it
-		return mobileProvider;
-	}
-
-	/**
-	 * Getter for filtered mobile provider list
-	 * <p>
-	 * @return Filtered mobile providers
-	 */
-	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
-	public List<MobileProvider> getFilteredMobileProviders () {
-		return this.filteredMobileProviders;
-	}
-
-	/**
-	 * Getter for filtered mobile provider list
-	 * <p>
-	 * @param filteredMobileProviders Filtered mobile providers
-	 */
-	@SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter")
-	public void setFilteredMobileProviders (final List<MobileProvider> filteredMobileProviders) {
-		this.filteredMobileProviders = filteredMobileProviders;
-	}
-
-	/**
-	 * Post-construction method
-	 */
-	@PostConstruct
-	public void initCache () {
-		// Is cache there?
-		if (!this.mobileProviderCache.iterator().hasNext()) {
-			// Add all
-			for (final MobileProvider mobileProvider : this.mobileProviderBean.allMobileProviders()) {
-				// Add it to cache
-				this.mobileProviderCache.put(mobileProvider.getProviderId(), mobileProvider);
-			}
-		}
-
-		// Is the list empty, but filled cache?
-		if (this.allMobileProviders.isEmpty() && this.mobileProviderCache.iterator().hasNext()) {
-			// Build up list
-			for (final Cache.Entry<Long, MobileProvider> currentEntry : this.mobileProviderCache) {
-				// Add to list
-				this.allMobileProviders.add(currentEntry.getValue());
-			}
-
-			// Sort list
-			this.allMobileProviders.sort(new Comparator<MobileProvider>() {
-				@Override
-				public int compare (final MobileProvider mobileProvider1, final MobileProvider mobileProvider2) {
-					return mobileProvider1.getProviderId() > mobileProvider2.getProviderId() ? 1 : mobileProvider1.getProviderId() < mobileProvider2.getProviderId() ? -1 : 0;
-				}
-			});
-		}
 	}
 }
diff --git a/src/java/org/mxchange/jjobs/beans/mobileprovider/JobsMobileProviderWebRequestController.java b/src/java/org/mxchange/jjobs/beans/mobileprovider/JobsMobileProviderWebRequestController.java
index 15cb847b..98bb7ae1 100644
--- a/src/java/org/mxchange/jjobs/beans/mobileprovider/JobsMobileProviderWebRequestController.java
+++ b/src/java/org/mxchange/jjobs/beans/mobileprovider/JobsMobileProviderWebRequestController.java
@@ -17,9 +17,6 @@
 package org.mxchange.jjobs.beans.mobileprovider;
 
 import java.io.Serializable;
-import java.util.List;
-import org.mxchange.jphone.exceptions.mobileprovider.MobileProviderNotFoundException;
-import org.mxchange.jphone.model.phonenumbers.mobileprovider.MobileProvider;
 
 /**
  * An interface for general mobile provider controller
@@ -28,24 +25,4 @@ import org.mxchange.jphone.model.phonenumbers.mobileprovider.MobileProvider;
  */
 public interface JobsMobileProviderWebRequestController extends Serializable {
 
-	/**
-	 * Returns a mobile provider instance by given primary key. If not found, a
-	 * proper exception is thrown.
-	 * <p>
-	 * @param mobileProviderId Primary key
-	 * <p>
-	 * @return Mobile provider instance
-	 * <p>
-	 * @throws MobileProviderNotFoundException If the primary key could not be
-	 * found
-	 */
-	MobileProvider findMobileProviderById (final Long mobileProviderId) throws MobileProviderNotFoundException;
-
-	/**
-	 * Returns a list of all mobile providers
-	 * <p>
-	 * @return A list of all mobile providers
-	 */
-	List<MobileProvider> allMobileProviders ();
-
 }
diff --git a/src/java/org/mxchange/jjobs/beans/mobileprovider/list/FinancialsMobileProviderListWebViewBean.java b/src/java/org/mxchange/jjobs/beans/mobileprovider/list/FinancialsMobileProviderListWebViewBean.java
new file mode 100644
index 00000000..8a5e1f16
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/mobileprovider/list/FinancialsMobileProviderListWebViewBean.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2016 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.mobileprovider.list;
+
+import fish.payara.cdi.jsr107.impl.NamedCache;
+import java.text.MessageFormat;
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import javax.cache.Cache;
+import javax.ejb.EJB;
+import javax.enterprise.event.Observes;
+import javax.faces.view.ViewScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jfinancials.beans.BaseFinancialsBean;
+import org.mxchange.jphone.events.mobileprovider.added.AdminAddedMobileProviderEvent;
+import org.mxchange.jphone.exceptions.mobileprovider.MobileProviderNotFoundException;
+import org.mxchange.jphone.model.phonenumbers.mobileprovider.MobileProvider;
+import org.mxchange.jphone.model.phonenumbers.mobileprovider.MobileProviderSingletonBeanRemote;
+
+/**
+ * A views-scoped bean for mobile providers
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("mobileProviderListController")
+@ViewScoped
+public class FinancialsMobileProviderListWebViewBean extends BaseFinancialsBean implements FinancialsMobileProviderListWebViewController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 15_869_423_671_950_277L;
+
+	/**
+	 * A list of all mobile providers
+	 */
+	private final List<MobileProvider> allMobileProviders;
+
+	/**
+	 * A list of filtered mobile providers
+	 */
+	private List<MobileProvider> filteredMobileProviders;
+
+	/**
+	 * Remote EJB for mobile providers (regular)
+	 */
+	@EJB (lookup = "java:global/jfinancials-ejb/mobileProvider!org.mxchange.jphone.model.phonenumbers.mobileprovider.MobileProviderSingletonBeanRemote")
+	private MobileProviderSingletonBeanRemote mobileProviderBean;
+
+	/**
+	 * "Cached" list of mobile providers
+	 */
+	@Inject
+	@NamedCache (cacheName = "mobileProviderCache")
+	private transient Cache<Long, MobileProvider> mobileProviderCache;
+
+	/**
+	 * Selected mobile provider instance
+	 */
+	private MobileProvider selectedMobileProvider;
+
+	/**
+	 * Default constructor
+	 */
+	public FinancialsMobileProviderListWebViewBean () {
+		// Call super constructor
+		super();
+
+		// Init list
+		this.allMobileProviders = new LinkedList<>();
+	}
+
+	/**
+	 * Observes events being fired after the administrator has added a new
+	 * mobile provider
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminAddedMobileProviderEvent (@Observes final AdminAddedMobileProviderEvent event) {
+		// Is all valid?
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getAddedMobileProvider() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.addedMobileProvider is null"); //NOI18N
+		} else if (event.getAddedMobileProvider().getProviderId() == null) {
+			// And again ...
+			throw new NullPointerException("event.addedMobileProvider.providerId is null"); //NOI18N
+		} else if (event.getAddedMobileProvider().getProviderId() < 1) {
+			// Id is invalid
+			throw new IllegalArgumentException(MessageFormat.format("event.addedMobileProvider.providerId={0} is not valid.", event.getAddedMobileProvider().getProviderId())); //NOI18N
+		}
+
+		// Add it to the list
+		this.mobileProviderCache.put(event.getAddedMobileProvider().getProviderId(), event.getAddedMobileProvider());
+		this.getAllMobileProviders().add(event.getAddedMobileProvider());
+	}
+
+	@Override
+	public MobileProvider findMobileProviderById (final Long mobileProviderId) throws MobileProviderNotFoundException {
+		// Validate parameter
+		if (null == mobileProviderId) {
+			// Throw NPE
+			throw new NullPointerException("mobileProviderId is null"); //NOI18N
+		} else if (mobileProviderId < 1) {
+			// Throw IAE
+			throw new IllegalArgumentException("mobileProviderId=" + mobileProviderId + " is invalid."); //NOI18N
+		} else if (!this.mobileProviderCache.containsKey(mobileProviderId)) {
+			// Not found
+			throw new MobileProviderNotFoundException(mobileProviderId);
+		}
+
+		// Get it from cache
+		final MobileProvider mobileProvider = this.mobileProviderCache.get(mobileProviderId);
+
+		// Return it
+		return mobileProvider;
+	}
+
+	@Override
+	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
+	public List<MobileProvider> getAllMobileProviders () {
+		// Return it
+		return this.allMobileProviders;
+	}
+
+	/**
+	 * Getter for filtered mobile provider list
+	 * <p>
+	 * @return Filtered mobile providers
+	 */
+	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
+	public List<MobileProvider> getFilteredMobileProviders () {
+		return this.filteredMobileProviders;
+	}
+
+	/**
+	 * Getter for filtered mobile provider list
+	 * <p>
+	 * @param filteredMobileProviders Filtered mobile providers
+	 */
+	@SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter")
+	public void setFilteredMobileProviders (final List<MobileProvider> filteredMobileProviders) {
+		this.filteredMobileProviders = filteredMobileProviders;
+	}
+
+	/**
+	 * Getter for selected mobile provider instance
+	 * <p>
+	 * @return Selected mobile provider instance
+	 */
+	public MobileProvider getSelectedMobileProvider () {
+		return this.selectedMobileProvider;
+	}
+
+	/**
+	 * Setter for selected mobile provider instance
+	 * <p>
+	 * @param selectedMobileProvider Selected mobile provider instance
+	 */
+	public void setSelectedMobileProvider (final MobileProvider selectedMobileProvider) {
+		this.selectedMobileProvider = selectedMobileProvider;
+	}
+
+	/**
+	 * Post-construction method
+	 */
+	@PostConstruct
+	public void initializeList () {
+		// Is cache there?
+		if (!this.mobileProviderCache.iterator().hasNext()) {
+			// Add all
+			for (final MobileProvider mobileProvider : this.mobileProviderBean.fetchAllMobileProviders()) {
+				// Add it to cache
+				this.mobileProviderCache.put(mobileProvider.getProviderId(), mobileProvider);
+			}
+		}
+
+		// Is the list empty, but filled cache?
+		if (this.getAllMobileProviders().isEmpty() && this.mobileProviderCache.iterator().hasNext()) {
+			// Build up list
+			for (final Cache.Entry<Long, MobileProvider> currentEntry : this.mobileProviderCache) {
+				// Add to list
+				this.getAllMobileProviders().add(currentEntry.getValue());
+			}
+
+			// Sort list
+			this.getAllMobileProviders().sort(new Comparator<MobileProvider>() {
+				@Override
+				public int compare (final MobileProvider mobileProvider1, final MobileProvider mobileProvider2) {
+					return mobileProvider1.getProviderId() > mobileProvider2.getProviderId() ? 1 : mobileProvider1.getProviderId() < mobileProvider2.getProviderId() ? -1 : 0;
+				}
+			});
+		}
+	}
+}
diff --git a/src/java/org/mxchange/jjobs/beans/mobileprovider/list/FinancialsMobileProviderListWebViewController.java b/src/java/org/mxchange/jjobs/beans/mobileprovider/list/FinancialsMobileProviderListWebViewController.java
new file mode 100644
index 00000000..fa035528
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/mobileprovider/list/FinancialsMobileProviderListWebViewController.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.mobileprovider.list;
+
+import java.io.Serializable;
+import java.util.List;
+import org.mxchange.jphone.exceptions.mobileprovider.MobileProviderNotFoundException;
+import org.mxchange.jphone.model.phonenumbers.mobileprovider.MobileProvider;
+
+/**
+ * An interface for general mobile provider controller
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsMobileProviderListWebViewController extends Serializable {
+
+	/**
+	 * Returns a mobile provider instance by given primary key. If not found, a
+	 * proper exception is thrown.
+	 * <p>
+	 * @param mobileProviderId Primary key
+	 * <p>
+	 * @return Mobile provider instance
+	 * <p>
+	 * @throws MobileProviderNotFoundException If the primary key could not be
+	 * found
+	 */
+	MobileProvider findMobileProviderById (final Long mobileProviderId) throws MobileProviderNotFoundException;
+
+	/**
+	 * Returns a list of all mobile providers
+	 * <p>
+	 * @return A list of all mobile providers
+	 */
+	List<MobileProvider> getAllMobileProviders ();
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/phone/JobsAdminPhoneWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/phone/JobsAdminPhoneWebRequestBean.java
index cc089f35..9901d763 100644
--- a/src/java/org/mxchange/jjobs/beans/phone/JobsAdminPhoneWebRequestBean.java
+++ b/src/java/org/mxchange/jjobs/beans/phone/JobsAdminPhoneWebRequestBean.java
@@ -30,6 +30,7 @@ import javax.inject.Inject;
 import javax.inject.Named;
 import org.mxchange.jcountry.model.data.Country;
 import org.mxchange.jjobs.beans.BaseJobsBean;
+import org.mxchange.jfinancials.beans.phone.list.FinancialsPhoneListWebViewController;
 import org.mxchange.jphone.events.fax.created.ObservableCreatedFaxNumberEvent;
 import org.mxchange.jphone.events.fax.deleted.AdminDeletedFaxNumberEvent;
 import org.mxchange.jphone.events.fax.deleted.AdminFaxNumberDeletedEvent;
@@ -44,20 +45,11 @@ import org.mxchange.jphone.events.landline.removed.AdminLandLineNumberRemovedFro
 import org.mxchange.jphone.events.landline.removed.AdminRemoveLandLineNumberFromListEvent;
 import org.mxchange.jphone.events.landline.updated.AdminLandLineNumberUpdatedEvent;
 import org.mxchange.jphone.events.landline.updated.AdminUpdatedLandLineNumberEvent;
-import org.mxchange.jphone.events.mobile.created.ObservableCreatedMobileNumberEvent;
-import org.mxchange.jphone.events.mobile.deleted.AdminDeletedMobileNumberEvent;
-import org.mxchange.jphone.events.mobile.deleted.AdminMobileNumberDeletedEvent;
-import org.mxchange.jphone.events.mobile.remove.AdminMobileNumberRemovedFromListEvent;
 import org.mxchange.jphone.events.mobile.remove.AdminRemoveMobileNumberFromListEvent;
-import org.mxchange.jphone.events.mobile.updated.AdminMobileNumberUpdatedEvent;
-import org.mxchange.jphone.events.mobile.updated.AdminUpdatedMobileNumberEvent;
 import org.mxchange.jphone.model.phonenumbers.fax.DialableFaxNumber;
 import org.mxchange.jphone.model.phonenumbers.fax.FaxNumber;
 import org.mxchange.jphone.model.phonenumbers.landline.DialableLandLineNumber;
 import org.mxchange.jphone.model.phonenumbers.landline.LandLineNumber;
-import org.mxchange.jphone.model.phonenumbers.mobile.DialableMobileNumber;
-import org.mxchange.jphone.model.phonenumbers.mobile.MobileNumber;
-import org.mxchange.jphone.model.phonenumbers.mobileprovider.MobileProvider;
 import org.mxchange.jphone.model.phonenumbers.phone.AdminPhoneSessionBeanRemote;
 
 /**
@@ -118,41 +110,11 @@ public class JobsAdminPhoneWebRequestBean extends BaseJobsBean implements JobsAd
 	@Any
 	private Event<AdminUpdatedLandLineNumberEvent> landLineNumberUpdatedEvent;
 
-	/**
-	 * Chosen mobile number
-	 */
-	private DialableMobileNumber mobileNumber;
-
-	/**
-	 * Event being fired when an administrator has deleted mobile number
-	 */
-	@Inject
-	@Any
-	private Event<AdminDeletedMobileNumberEvent> mobileNumberDeletedEvent;
-
-	/**
-	 * Event being fired when an administrator has updated land-line number
-	 */
-	@Inject
-	@Any
-	private Event<AdminUpdatedMobileNumberEvent> mobileNumberUpdatedEvent;
-
-	/**
-	 * Mobile provider
-	 */
-	private MobileProvider mobileProvider;
-
 	/**
 	 * Area code (city dial prefix)
 	 */
 	private Integer phoneAreaCode;
 
-	/**
-	 * Generic hone controller
-	 */
-	@Inject
-	private JobsPhoneWebRequestController phoneController;
-
 	/**
 	 * Country (for dial prefix)
 	 */
@@ -173,6 +135,12 @@ public class JobsAdminPhoneWebRequestBean extends BaseJobsBean implements JobsAd
 	 */
 	private Long phoneId;
 
+	/**
+	 * Generic hone controller
+	 */
+	@Inject
+	private FinancialsPhoneListWebViewController phoneListController;
+
 	/**
 	 * Phone number
 	 */
@@ -211,7 +179,7 @@ public class JobsAdminPhoneWebRequestBean extends BaseJobsBean implements JobsAd
 
 	/**
 	 * Observes events being fired when a bean helper has successfully created a
-	 * fax number instance.
+	 * land-line number instance.
 	 * <p>
 	 * @param event Event being fired
 	 */
@@ -222,17 +190,17 @@ public class JobsAdminPhoneWebRequestBean extends BaseJobsBean implements JobsAd
 			throw new NullPointerException("event is null"); //NOI18N
 		} else if (event.getFaxNumber() == null) {
 			// Throw NPE again
-			throw new NullPointerException("event.faxNumber is null"); //NOI18N
+			throw new NullPointerException("event.landLineNumber is null"); //NOI18N
 		} else if (event.getFaxNumber().getPhoneId() == null) {
 			// Throw NPE yet again
-			throw new NullPointerException("event.faxNumber.phoneId is null"); //NOI18N
+			throw new NullPointerException("event.landLineNumber.phoneId is null"); //NOI18N
 		} else if (event.getFaxNumber().getPhoneId() < 1) {
 			// Throw NPE yet again
-			throw new NullPointerException(MessageFormat.format("event.faxNumber.phoneId={0} is invalid", event.getFaxNumber().getPhoneId())); //NOI18N
+			throw new NullPointerException(MessageFormat.format("event.landLineNumber.phoneId={0} is invalid", event.getFaxNumber().getPhoneId())); //NOI18N
 		}
 
 		// Get fax number from event
-		DialableFaxNumber number = event.getFaxNumber();
+		final DialableFaxNumber number = event.getFaxNumber();
 
 		// Copy all data to this bean
 		this.setPhoneId(number.getPhoneId());
@@ -266,7 +234,7 @@ public class JobsAdminPhoneWebRequestBean extends BaseJobsBean implements JobsAd
 		}
 
 		// Get fax number from event
-		DialableLandLineNumber number = event.getLandLineNumber();
+		final DialableLandLineNumber number = event.getLandLineNumber();
 
 		// Copy all data to this bean
 		this.setPhoneId(number.getPhoneId());
@@ -277,39 +245,6 @@ public class JobsAdminPhoneWebRequestBean extends BaseJobsBean implements JobsAd
 		this.setPhoneEntryUpdated(number.getPhoneEntryUpdated());
 	}
 
-	/**
-	 * Observes events being fired when a bean helper has successfully created a
-	 * mobile number instance.
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterCreatedMobileNumberEvent (@Observes final ObservableCreatedMobileNumberEvent event) {
-		// The event instance must be valid
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getMobileNumber() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.mobileNumber is null"); //NOI18N
-		} else if (event.getMobileNumber().getPhoneId() == null) {
-			// Throw NPE yet again
-			throw new NullPointerException("event.mobileNumber.phoneId is null"); //NOI18N
-		} else if (event.getMobileNumber().getPhoneId() < 1) {
-			// Throw NPE yet again
-			throw new NullPointerException(MessageFormat.format("event.mobileNumber.phoneId={0} is invalid", event.getMobileNumber().getPhoneId())); //NOI18N
-		}
-
-		// Get fax number from event
-		DialableMobileNumber number = event.getMobileNumber();
-
-		// Copy all data to this bean
-		this.setPhoneId(number.getPhoneId());
-		this.setMobileProvider(number.getMobileProvider());
-		this.setPhoneNumber(number.getPhoneNumber());
-		this.setPhoneEntryCreated(number.getPhoneEntryCreated());
-		this.setPhoneEntryUpdated(number.getPhoneEntryUpdated());
-	}
-
 	/**
 	 * Returns a list of all unused ("non-linked") land-line numbers
 	 * <p>
@@ -317,13 +252,13 @@ public class JobsAdminPhoneWebRequestBean extends BaseJobsBean implements JobsAd
 	 */
 	public List<DialableFaxNumber> allNonLinkedFaxNumbers () {
 		// Get list of all mobile numbers
-		List<DialableFaxNumber> list = this.phoneController.allFaxNumbers();
+		final List<DialableFaxNumber> numbers = this.phoneListController.getAllFaxNumbers();
 
 		// Visit all controllers to reduce the list
-		this.removeLinkedFaxNumbersEvent.fire(new AdminFaxNumberRemovedFromListEvent(list));
+		this.removeLinkedFaxNumbersEvent.fire(new AdminFaxNumberRemovedFromListEvent(numbers));
 
 		// Return it
-		return list;
+		return numbers;
 	}
 
 	/**
@@ -333,29 +268,13 @@ public class JobsAdminPhoneWebRequestBean extends BaseJobsBean implements JobsAd
 	 */
 	public List<DialableLandLineNumber> allNonLinkedLandLineNumbers () {
 		// Get list of all mobile numbers
-		List<DialableLandLineNumber> list = this.phoneController.allLandLineNumbers();
+		final List<DialableLandLineNumber> numbers = this.phoneListController.getAllLandLineNumbers();
 
 		// Visit all controllers to reduce the list
-		this.removeLinkedLandLineNumbersEvent.fire(new AdminLandLineNumberRemovedFromListEvent(list));
+		this.removeLinkedLandLineNumbersEvent.fire(new AdminLandLineNumberRemovedFromListEvent(numbers));
 
 		// Return it
-		return list;
-	}
-
-	/**
-	 * Returns a list of all unused ("non-linked") mobile numbers
-	 * <p>
-	 * @return List with all unused mobile numbers
-	 */
-	public List<DialableMobileNumber> allNonLinkedMobileNumbers () {
-		// Get list of all mobile numbers
-		List<DialableMobileNumber> list = this.phoneController.allMobileNumbers();
-
-		// Visit all controllers to reduce the list
-		this.removeLinkedMobileNumbersEvent.fire(new AdminMobileNumberRemovedFromListEvent(list));
-
-		// Return it
-		return list;
+		return numbers;
 	}
 
 	/**
@@ -364,7 +283,7 @@ public class JobsAdminPhoneWebRequestBean extends BaseJobsBean implements JobsAd
 	 */
 	public void deleteFaxData () {
 		// Get fax number from bean helper
-		DialableFaxNumber number = this.createFaxNumber();
+		final DialableFaxNumber number = this.createFaxNumber();
 
 		// Is all data set
 		if (number == null) {
@@ -411,7 +330,7 @@ public class JobsAdminPhoneWebRequestBean extends BaseJobsBean implements JobsAd
 	 */
 	public void deleteLandLineData () {
 		// Get land-line number from helper
-		DialableLandLineNumber number = this.createLandLineNumber();
+		final DialableLandLineNumber number = this.createLandLineNumber();
 
 		// Is all data set
 		if (number == null) {
@@ -453,47 +372,6 @@ public class JobsAdminPhoneWebRequestBean extends BaseJobsBean implements JobsAd
 		this.landLineNumberDeletedEvent.fire(new AdminLandLineNumberDeletedEvent(number));
 	}
 
-	/**
-	 * Deletes given mobile entry data
-	 */
-	public void deleteMobileData () {
-		// Get mobile number from helper
-		DialableMobileNumber number = this.createMobileNumber();
-
-		// Is all data set
-		if (number == null) {
-			// Not set, throw NPE
-			throw new NullPointerException("mobileNumber is null"); //NOI18N
-		} else if (number.getPhoneId() == null) {
-			// Throw NPE again
-			throw new NullPointerException("mobileNumber.phoneId is null"); //NOI18N
-		} else if (number.getPhoneId() < 1) {
-			// Invalid number
-			throw new IllegalArgumentException(MessageFormat.format("mobileNumber.phoneId={0} is not valid", number.getPhoneId())); //NOI18N
-		} else if (number.getMobileProvider() == null) {
-			// Throw NPE
-			throw new NullPointerException("mobileNumber.mobileProvider is null"); //NOI18N
-		} else if (number.getMobileProvider().getProviderId() == null) {
-			// ... throw again
-			throw new NullPointerException("mobileNumber.mobileProvider.providerId is null"); //NOI18N
-		} else if (number.getMobileProvider().getProviderId() < 1) {
-			// Id not valid
-			throw new IllegalArgumentException(MessageFormat.format("mobileNumber.mobileProvider.providerId={0} is not valid.", number.getMobileProvider().getProviderId())); //NOI18N
-		} else if (number.getPhoneNumber() == null) {
-			// Throw NPE again
-			throw new NullPointerException("mobileNumber.phoneNumber is null"); //NOI18N
-		} else if (number.getPhoneNumber() < 1) {
-			// Throw NPE again
-			throw new NullPointerException(MessageFormat.format("mobileNumber.phoneNumber={0} is not valid.", number.getPhoneNumber())); //NOI18N
-		}
-
-		// Call EJB
-		this.adminPhoneBean.deleteMobileData(number);
-
-		// Fire event
-		this.mobileNumberDeletedEvent.fire(new AdminMobileNumberDeletedEvent(number));
-	}
-
 	/**
 	 * Changes fax entry data
 	 * <p>
@@ -501,7 +379,7 @@ public class JobsAdminPhoneWebRequestBean extends BaseJobsBean implements JobsAd
 	 */
 	public String doChangeFaxNumber () {
 		// Get fax number from bean helper
-		DialableFaxNumber number = this.createFaxNumber();
+		final DialableFaxNumber number = this.createFaxNumber();
 
 		// Is all data set
 		if (number == null) {
@@ -551,7 +429,7 @@ public class JobsAdminPhoneWebRequestBean extends BaseJobsBean implements JobsAd
 		number.setPhoneNumber(this.getPhoneNumber());
 
 		// Send to bean
-		DialableFaxNumber updatedNumber = this.adminPhoneBean.updateFaxData(number);
+		final DialableFaxNumber updatedNumber = this.adminPhoneBean.updateFaxData(number);
 
 		// Fire event
 		this.faxNumberUpdatedEvent.fire(new AdminFaxNumberUpdatedEvent(updatedNumber));
@@ -567,7 +445,7 @@ public class JobsAdminPhoneWebRequestBean extends BaseJobsBean implements JobsAd
 	 */
 	public String doChangeLandLineNumber () {
 		// Get land-line number from helper
-		DialableLandLineNumber number = this.createLandLineNumber();
+		final DialableLandLineNumber number = this.createLandLineNumber();
 
 		// Is all data set
 		if (number == null) {
@@ -617,7 +495,7 @@ public class JobsAdminPhoneWebRequestBean extends BaseJobsBean implements JobsAd
 		number.setPhoneNumber(this.getPhoneNumber());
 
 		// Send to bean
-		DialableLandLineNumber updatedNumber = this.adminPhoneBean.updateLandLineData(number);
+		final DialableLandLineNumber updatedNumber = this.adminPhoneBean.updateLandLineData(number);
 
 		// Fire event
 		this.landLineNumberUpdatedEvent.fire(new AdminLandLineNumberUpdatedEvent(updatedNumber));
@@ -626,77 +504,6 @@ public class JobsAdminPhoneWebRequestBean extends BaseJobsBean implements JobsAd
 		return "admin_show_landline"; //NOI18N
 	}
 
-	/**
-	 * Changes mobile entry data
-	 * <p>
-	 * @return Redirect outcome
-	 */
-	public String doUpdateMobileNumber () {
-		// Get mobile number from helper
-		DialableMobileNumber number = this.createMobileNumber();
-
-		// Is all data set
-		if (number == null) {
-			// Not set, throw NPE
-			throw new NullPointerException("mobileNumber is null"); //NOI18N
-		} else if (number.getPhoneId() == null) {
-			// Throw NPE again
-			throw new NullPointerException("mobileNumber.phoneId is null"); //NOI18N
-		} else if (number.getPhoneId() < 1) {
-			// Invalid number
-			throw new IllegalArgumentException(MessageFormat.format("mobileNumber.phoneId={0} is not valid", number.getPhoneId())); //NOI18N
-		} else if (number.getMobileProvider() == null) {
-			// Throw NPE
-			throw new NullPointerException("mobileNumber.mobileProvider is null"); //NOI18N
-		} else if (number.getMobileProvider().getProviderId() == null) {
-			// ... throw again
-			throw new NullPointerException("mobileNumber.mobileProvider.providerId is null"); //NOI18N
-		} else if (number.getMobileProvider().getProviderId() < 1) {
-			// Id not valid
-			throw new IllegalArgumentException(MessageFormat.format("mobileNumber.mobileProvider.providerId={0} is not valid.", number.getMobileProvider().getProviderId())); //NOI18N
-		} else if (number.getPhoneNumber() == null) {
-			// Throw NPE again
-			throw new NullPointerException("mobileNumber.phoneNumber is null"); //NOI18N
-		} else if (number.getPhoneNumber() < 1) {
-			// Throw NPE again
-			throw new NullPointerException(MessageFormat.format("mobileNumber.phoneNumber={0} is not valid.", number.getPhoneNumber())); //NOI18N
-		} else if (this.getMobileProvider() == null) {
-			// Throw NPE again
-			throw new NullPointerException("this.mobileProvider is null"); //NOI18N
-		} else if (this.getMobileProvider().getProviderId() == null) {
-			// Throw NPE again ...
-			throw new NullPointerException("this.mobileProvider.providerId is null"); //NOI18N
-		} else if (this.getMobileProvider().getProviderId() < 0) {
-			// Invalid id number
-			throw new IllegalArgumentException(MessageFormat.format("this.mobileProvider.providerId={0} is not valid.", this.getMobileProvider().getProviderId())); //NOI18N
-		} else if (this.getPhoneNumber() == null) {
-			// Throw NPE
-			throw new NullPointerException("this.phoneNumber is null"); //NOI18N
-		}
-
-		// Is the mobile provider and number the same?
-		if ((Objects.equals(this.getMobileProvider(), number.getMobileProvider())) && (Objects.equals(this.getPhoneNumber(), number.getPhoneNumber()))) {
-			// Show message
-			this.showFacesMessage("form_edit_mobile:mobileNumber", "ERROR_ADMIN_NO_CHANGE_ENTERED", FacesMessage.SEVERITY_WARN); //NOI18N
-
-			// No difference in both together, no need to edit
-			return ""; //NOI18N
-		}
-
-		// Set all data
-		number.setMobileProvider(this.getMobileProvider());
-		number.setPhoneNumber(this.getPhoneNumber());
-
-		// Send to bean
-		DialableMobileNumber updatedNumber = this.adminPhoneBean.updateMobileData(number);
-
-		// Fire event
-		this.mobileNumberUpdatedEvent.fire(new AdminMobileNumberUpdatedEvent(updatedNumber));
-
-		// All fine, redirect
-		return "admin_show_mobile"; //NOI18N
-	}
-
 	/**
 	 * Getter for chosen fax number
 	 * <p>
@@ -733,42 +540,6 @@ public class JobsAdminPhoneWebRequestBean extends BaseJobsBean implements JobsAd
 		this.landLineNumber = landLineNumber;
 	}
 
-	/**
-	 * Getter for chosen mobile number
-	 * <p>
-	 * @return mobile number
-	 */
-	public DialableMobileNumber getMobileNumber () {
-		return this.mobileNumber;
-	}
-
-	/**
-	 * Setter for chosen mobile number
-	 * <p>
-	 * @param mobileNumber mobile number
-	 */
-	public void setMobileNumber (final DialableMobileNumber mobileNumber) {
-		this.mobileNumber = mobileNumber;
-	}
-
-	/**
-	 * Getter for mobile provider
-	 * <p>
-	 * @return Mobile provider
-	 */
-	public MobileProvider getMobileProvider () {
-		return this.mobileProvider;
-	}
-
-	/**
-	 * Setter for mobile provider
-	 * <p>
-	 * @param mobileProvider Mobile provider
-	 */
-	public void setMobileProvider (final MobileProvider mobileProvider) {
-		this.mobileProvider = mobileProvider;
-	}
-
 	/**
 	 * Getter for phone area code
 	 * <p>
@@ -889,7 +660,11 @@ public class JobsAdminPhoneWebRequestBean extends BaseJobsBean implements JobsAd
 	 */
 	private DialableFaxNumber createFaxNumber () {
 		// Initialize it
-		DialableFaxNumber number = new FaxNumber(this.getPhoneCountry(), this.getPhoneAreaCode(), this.getPhoneNumber());
+		final DialableFaxNumber number = new FaxNumber(
+								this.getPhoneCountry(),
+								this.getPhoneAreaCode(),
+								this.getPhoneNumber()
+						);
 
 		// Add all other data
 		number.setPhoneEntryCreated(this.getPhoneEntryCreated());
@@ -913,31 +688,11 @@ public class JobsAdminPhoneWebRequestBean extends BaseJobsBean implements JobsAd
 	 */
 	private DialableLandLineNumber createLandLineNumber () {
 		// Initialize it
-		DialableLandLineNumber number = new LandLineNumber(this.getPhoneCountry(), this.getPhoneAreaCode(), this.getPhoneNumber());
-
-		// Add all other data
-		number.setPhoneEntryCreated(this.getPhoneEntryCreated());
-		number.setPhoneEntryUpdated(this.getPhoneEntryUpdated());
-
-		// Is id number set?
-		if (this.getPhoneId() instanceof Long) {
-			// Set it
-			number.setPhoneId(this.getPhoneId());
-		}
-
-		// Return it
-		return number;
-	}
-
-	/**
-	 * Returns an instance of a DialableMobileNumber from all fields stored in
-	 * this bean.
-	 * <p>
-	 * @return An instance of a DialableMobileNumber class
-	 */
-	private DialableMobileNumber createMobileNumber () {
-		// Initialize it
-		DialableMobileNumber number = new MobileNumber(this.getMobileProvider(), this.getPhoneNumber());
+		final DialableLandLineNumber number = new LandLineNumber(
+									 this.getPhoneCountry(),
+									 this.getPhoneAreaCode(),
+									 this.getPhoneNumber()
+							 );
 
 		// Add all other data
 		number.setPhoneEntryCreated(this.getPhoneEntryCreated());
diff --git a/src/java/org/mxchange/jjobs/beans/phone/JobsPhoneWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/phone/JobsPhoneWebRequestBean.java
index c1006edf..d0c88162 100644
--- a/src/java/org/mxchange/jjobs/beans/phone/JobsPhoneWebRequestBean.java
+++ b/src/java/org/mxchange/jjobs/beans/phone/JobsPhoneWebRequestBean.java
@@ -16,37 +16,9 @@
  */
 package org.mxchange.jjobs.beans.phone;
 
-import fish.payara.cdi.jsr107.impl.NamedCache;
-import java.text.MessageFormat;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Objects;
-import javax.annotation.PostConstruct;
-import javax.cache.Cache;
-import javax.ejb.EJB;
 import javax.enterprise.context.RequestScoped;
-import javax.enterprise.event.Observes;
-import javax.inject.Inject;
 import javax.inject.Named;
-import org.mxchange.jcontacts.events.contact.add.ObservableAdminAddedContactEvent;
-import org.mxchange.jcontacts.events.contact.update.ObservableAdminUpdatedContactEvent;
-import org.mxchange.jcontacts.events.fax.linked.ObservableAdminLinkedFaxNumberEvent;
-import org.mxchange.jcontacts.events.landline.linked.ObservableAdminLinkedLandLineNumberEvent;
-import org.mxchange.jcontacts.events.mobile.linked.ObservableAdminLinkedMobileNumberEvent;
-import org.mxchange.jcontacts.model.contact.Contact;
 import org.mxchange.jjobs.beans.BaseJobsBean;
-import org.mxchange.jphone.events.fax.deleted.AdminDeletedFaxNumberEvent;
-import org.mxchange.jphone.events.fax.updated.AdminUpdatedFaxNumberEvent;
-import org.mxchange.jphone.events.landline.deleted.AdminDeletedLandLineNumberEvent;
-import org.mxchange.jphone.events.landline.updated.AdminUpdatedLandLineNumberEvent;
-import org.mxchange.jphone.events.mobile.deleted.AdminDeletedMobileNumberEvent;
-import org.mxchange.jphone.events.mobile.updated.AdminUpdatedMobileNumberEvent;
-import org.mxchange.jphone.exceptions.phone.PhoneEntityNotFoundException;
-import org.mxchange.jphone.model.phonenumbers.fax.DialableFaxNumber;
-import org.mxchange.jphone.model.phonenumbers.landline.DialableLandLineNumber;
-import org.mxchange.jphone.model.phonenumbers.mobile.DialableMobileNumber;
-import org.mxchange.jphone.model.phonenumbers.phone.PhoneSessionBeanRemote;
-import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
 
 /**
  * Regular controller (bean) for phone numbers
@@ -62,33 +34,6 @@ public class JobsPhoneWebRequestBean extends BaseJobsBean implements JobsPhoneWe
 	 */
 	private static final long serialVersionUID = 491_058_674_675_690_105L;
 
-	/**
-	 * All fax numbers
-	 */
-	@Inject
-	@NamedCache (cacheName = "faxNumberCache")
-	private Cache<Long, DialableFaxNumber> faxNumberCache;
-
-	/**
-	 * All land-line numbers
-	 */
-	@Inject
-	@NamedCache (cacheName = "landLineNumberCache")
-	private Cache<Long, DialableLandLineNumber> landLineNumberCache;
-
-	/**
-	 * All mobile numbers
-	 */
-	@Inject
-	@NamedCache (cacheName = "mobileNumberCache")
-	private Cache<Long, DialableMobileNumber> mobileNumberCache;
-
-	/**
-	 * General EJB for phone numbers
-	 */
-	@EJB (lookup = "java:global/jjobs-ejb/phone!org.mxchange.jphone.model.phonenumbers.phone.PhoneSessionBeanRemote")
-	private PhoneSessionBeanRemote phoneBean;
-
 	/**
 	 * Default constructor
 	 */
@@ -97,682 +42,4 @@ public class JobsPhoneWebRequestBean extends BaseJobsBean implements JobsPhoneWe
 		super();
 	}
 
-	/**
-	 * Observes events being fired when an administrator has added a new
-	 * contact.
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminAddedContactEvent (@Observes final ObservableAdminAddedContactEvent event) {
-		// The event must be valid
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getAddedContact() == null) {
-			// Throw again ...
-			throw new NullPointerException("event.addedContact is null"); //NOI18N
-		} else if (event.getAddedContact().getContactId() == null) {
-			// ... and again
-			throw new NullPointerException("event.addedContact.contactId is null"); //NOI18N
-		} else if (event.getAddedContact().getContactId() < 1) {
-			// Not valid
-			throw new IllegalArgumentException(MessageFormat.format("event.addedContact.contactId={0} is not valid", event.getAddedContact().getContactId())); //NOI18N
-		}
-
-		// Update contact's mobile, land-line and fax number
-		this.updateContactPhoneNumbers(event.getAddedContact());
-
-		// Clear this bean
-		this.clear();
-	}
-
-	/**
-	 * Event observer for newly added users by administrator
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getAddedUser() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.addedUser is null"); //NOI18N
-		} else if (event.getAddedUser().getUserId() == null) {
-			// userId is null
-			throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
-		} else if (event.getAddedUser().getUserId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
-		}
-
-		// Update contact's mobile, land-line and fax number
-		this.updateContactPhoneNumbers(event.getAddedUser().getUserContact());
-
-		// Clear all data
-		this.clear();
-	}
-
-	/**
-	 * Observes events being fired when an administrator has deleted a fax
-	 * number
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminDeletedFaxNumberEvent (@Observes final AdminDeletedFaxNumberEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getDeletedFaxNumber() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.deletedFaxNumber is null"); //NOI18N
-		} else if (event.getDeletedFaxNumber().getPhoneId() == null) {
-			// userId is null
-			throw new NullPointerException("event.deletedFaxNumber.phoneId is null"); //NOI18N
-		} else if (event.getDeletedFaxNumber().getPhoneId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getDeletedFaxNumber(), event.getDeletedFaxNumber().getPhoneId())); //NOI18N
-		}
-
-		// Update contact's mobile, land-line and fax number
-		this.allFaxNumbers().remove(event.getDeletedFaxNumber());
-
-		// Clear all data
-		this.clear();
-	}
-
-	/**
-	 * Observes events being fired when an administrator has deleted a land-line
-	 * number
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminDeletedLandLineNumberEvent (@Observes final AdminDeletedLandLineNumberEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getDeletedLandLineNumber() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.deletedLandLineNumber is null"); //NOI18N
-		} else if (event.getDeletedLandLineNumber().getPhoneId() == null) {
-			// userId is null
-			throw new NullPointerException("event.deletedLandLineNumber.phoneId is null"); //NOI18N
-		} else if (event.getDeletedLandLineNumber().getPhoneId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getDeletedLandLineNumber(), event.getDeletedLandLineNumber().getPhoneId())); //NOI18N
-		}
-
-		// Update contact's mobile, land-line and fax number
-		this.allLandLineNumbers().remove(event.getDeletedLandLineNumber());
-
-		// Clear all data
-		this.clear();
-	}
-
-	/**
-	 * Observes events being fired when an administrator has deleted a mobile
-	 * number
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminDeletedMobileNumberEvent (@Observes final AdminDeletedMobileNumberEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getDeletedMobileNumber() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.deletedMobileNumber is null"); //NOI18N
-		} else if (event.getDeletedMobileNumber().getPhoneId() == null) {
-			// userId is null
-			throw new NullPointerException("event.deletedMobileNumber.phoneId is null"); //NOI18N
-		} else if (event.getDeletedMobileNumber().getPhoneId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getDeletedMobileNumber(), event.getDeletedMobileNumber().getPhoneId())); //NOI18N
-		}
-
-		// Update contact's mobile, land-line and fax number
-		this.allMobileNumbers().remove(event.getDeletedMobileNumber());
-
-		// Clear all data
-		this.clear();
-	}
-
-	/**
-	 * Observes events being fired when an administrator has a linked a fax
-	 * number
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminLinkedFaxNumberEvent (@Observes final ObservableAdminLinkedFaxNumberEvent event) {
-		// Is the event fine?
-		if (event == null) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getContact() == null) {
-			// Throw again ...
-			throw new NullPointerException("event.contact is null"); //NOI18N
-		} else if (event.getContact().getContactId() == null) {
-			// Throw again ...
-			throw new NullPointerException("event.contact.contactId is null"); //NOI18N
-		} else if (event.getContact().getContactId() < 1) {
-			// Throw again ...
-			throw new NullPointerException("event.contact.contactId=" + event.getContact().getContactId() + " is invalid"); //NOI18N
-		} else if (event.getContact().getContactFaxNumber() == null) {
-			// Throw again ...
-			throw new NullPointerException("event.contact.contactFaxNumber is null"); //NOI18N
-		} else if (event.getContact().getContactFaxNumber().getPhoneId() == null) {
-			// Throw again ...
-			throw new NullPointerException("event.contact.contactFaxNumber.phoneId is null"); //NOI18N
-		} else if (event.getContact().getContactFaxNumber().getPhoneId() < 1) {
-			// Throw again ...
-			throw new NullPointerException("event.contact.contactFaxNumber.phoneId=" + event.getContact().getContactFaxNumber().getPhoneId() + " is invalid"); //NOI18N
-		} else if (event.getLinkedFaxNumber() == null) {
-			// Throw again ...
-			throw new NullPointerException("event.linkedFaxNumer is null"); //NOI18N
-		}
-
-		// Is the id number in linked number not set?
-		if (event.getLinkedFaxNumber().getPhoneId() == null) {
-			// Then it is a new number, so add it from contact as there the id number has been set
-			this.uniqueAddFaxNumber(event.getContact().getContactFaxNumber());
-		}
-	}
-
-	/**
-	 * Observes events being fired when an administrator has a linked a
-	 * land-line number
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminLinkedLandLineNumberEvent (@Observes final ObservableAdminLinkedLandLineNumberEvent event) {
-		// Is the event fine?
-		if (event == null) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getContact() == null) {
-			// Throw again ...
-			throw new NullPointerException("event.contact is null"); //NOI18N
-		} else if (event.getContact().getContactId() == null) {
-			// Throw again ...
-			throw new NullPointerException("event.contact.contactId is null"); //NOI18N
-		} else if (event.getContact().getContactId() < 1) {
-			// Throw again ...
-			throw new NullPointerException("event.contact.contactId=" + event.getContact().getContactId() + " is invalid"); //NOI18N
-		} else if (event.getContact().getContactLandLineNumber() == null) {
-			// Throw again ...
-			throw new NullPointerException("event.contact.contactLandLineNumber is null"); //NOI18N
-		} else if (event.getContact().getContactLandLineNumber().getPhoneId() == null) {
-			// Throw again ...
-			throw new NullPointerException("event.contact.contactLandLineNumber.phoneId is null"); //NOI18N
-		} else if (event.getContact().getContactLandLineNumber().getPhoneId() < 1) {
-			// Throw again ...
-			throw new NullPointerException("event.contact.contactLandLineNumber.phoneId=" + event.getContact().getContactLandLineNumber().getPhoneId() + " is invalid"); //NOI18N
-		} else if (event.getLinkedLandLineNumber() == null) {
-			// Throw again ...
-			throw new NullPointerException("event.linkedLandLineNumer is null"); //NOI18N
-		}
-
-		// Is the id number in linked number not set?
-		if (event.getLinkedLandLineNumber().getPhoneId() == null) {
-			// Then it is a new number, so add it from contact as there the id number has been set
-			this.uniqueAddLandLineNumber(event.getContact().getContactLandLineNumber());
-		}
-	}
-
-	/**
-	 * Observes events being fired when an administrator has a linked a mobile
-	 * number
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminLinkedMobileNumberEvent (@Observes final ObservableAdminLinkedMobileNumberEvent event) {
-		// Is the event fine?
-		if (event == null) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getContact() == null) {
-			// Throw again ...
-			throw new NullPointerException("event.contact is null"); //NOI18N
-		} else if (event.getContact().getContactId() == null) {
-			// Throw again ...
-			throw new NullPointerException("event.contact.contactId is null"); //NOI18N
-		} else if (event.getContact().getContactId() < 1) {
-			// Throw again ...
-			throw new NullPointerException("event.contact.contactId=" + event.getContact().getContactId() + " is invalid"); //NOI18N
-		} else if (event.getContact().getContactMobileNumber() == null) {
-			// Throw again ...
-			throw new NullPointerException("event.contact.contactMobileNumber is null"); //NOI18N
-		} else if (event.getContact().getContactMobileNumber().getPhoneId() == null) {
-			// Throw again ...
-			throw new NullPointerException("event.contact.contactMobileNumber.phoneId is null"); //NOI18N
-		} else if (event.getContact().getContactMobileNumber().getPhoneId() < 1) {
-			// Throw again ...
-			throw new NullPointerException("event.contact.contactMobileNumber.phoneId=" + event.getContact().getContactMobileNumber().getPhoneId() + " is invalid"); //NOI18N
-		} else if (event.getLinkedMobileNumber() == null) {
-			// Throw again ...
-			throw new NullPointerException("event.linkedMobileNumer is null"); //NOI18N
-		}
-
-		// Is the id number in linked number not set?
-		if (event.getLinkedMobileNumber().getPhoneId() == null) {
-			// Then it is a new number, so add it from contact as there the id number has been set
-			this.uniqueAddMobileNumber(event.getContact().getContactMobileNumber());
-		}
-	}
-
-	/**
-	 * Observes events being fired when an administrator has updated contact
-	 * data.
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminUpdatedContactDataEvent (@Observes final ObservableAdminUpdatedContactEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getUpdatedContact() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.updatedContact is null"); //NOI18N
-		} else if (event.getUpdatedContact().getContactId() == null) {
-			// userId is null
-			throw new NullPointerException("event.updatedContact.contactId is null"); //NOI18N
-		} else if (event.getUpdatedContact().getContactId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUpdatedContact(), event.getUpdatedContact().getContactId())); //NOI18N
-		}
-
-		// Update contact's mobile, land-line and fax number
-		this.updateContactPhoneNumbers(event.getUpdatedContact());
-
-		// Clear all data
-		this.clear();
-	}
-
-	/**
-	 * Observes events being fired when an administrator has updated a fax
-	 * number.
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminUpdatedFaxNumberEvent (@Observes final AdminUpdatedFaxNumberEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getUpdatedFaxNumber() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.updatedFaxNumber is null"); //NOI18N
-		} else if (event.getUpdatedFaxNumber().getPhoneId() == null) {
-			// userId is null
-			throw new NullPointerException("event.updatedFaxNumber.phoneId is null"); //NOI18N
-		} else if (event.getUpdatedFaxNumber().getPhoneId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getUpdatedFaxNumber(), event.getUpdatedFaxNumber().getPhoneId())); //NOI18N
-		}
-
-		// Uniquely add it
-		this.uniqueAddFaxNumber(event.getUpdatedFaxNumber());
-
-		// Clear it
-		this.clear();
-	}
-
-	/**
-	 * Observes events being fired when an administrator has updated a land-line
-	 * number.
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminUpdatedLandLineNumberEvent (@Observes final AdminUpdatedLandLineNumberEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getUpdatedLandLineNumber() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.updatedLandLineNumber is null"); //NOI18N
-		} else if (event.getUpdatedLandLineNumber().getPhoneId() == null) {
-			// userId is null
-			throw new NullPointerException("event.updatedLandLineNumber.phoneId is null"); //NOI18N
-		} else if (event.getUpdatedLandLineNumber().getPhoneId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getUpdatedLandLineNumber(), event.getUpdatedLandLineNumber().getPhoneId())); //NOI18N
-		}
-
-		// Uniquely add it
-		this.uniqueAddLandLineNumber(event.getUpdatedLandLineNumber());
-
-		// Clear it
-		this.clear();
-	}
-
-	/**
-	 * Observes events being fired when an administrator has updated a mobile
-	 * number.
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminUpdatedMobileNumberEvent (@Observes final AdminUpdatedMobileNumberEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getUpdatedMobileNumber() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.updatedMobileNumber is null"); //NOI18N
-		} else if (event.getUpdatedMobileNumber().getPhoneId() == null) {
-			// userId is null
-			throw new NullPointerException("event.updatedMobileNumber.phoneId is null"); //NOI18N
-		} else if (event.getUpdatedMobileNumber().getPhoneId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getUpdatedMobileNumber(), event.getUpdatedMobileNumber().getPhoneId())); //NOI18N
-		}
-
-		// Uniquely add it
-		this.uniqueAddMobileNumber(event.getUpdatedMobileNumber());
-
-		// Clear it
-		this.clear();
-	}
-
-	@Override
-	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
-	public List<DialableFaxNumber> allFaxNumbers () {
-		// Init list
-		final List<DialableFaxNumber> list = new LinkedList<>();
-
-		// Loop over all
-		for (final Cache.Entry<Long, DialableFaxNumber> currentEntry : this.faxNumberCache) {
-			// Add value to list
-			list.add(currentEntry.getValue());
-		}
-
-		// Return it
-		return list;
-	}
-
-	@Override
-	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
-	public List<DialableLandLineNumber> allLandLineNumbers () {
-		// Init list
-		final List<DialableLandLineNumber> list = new LinkedList<>();
-
-		// Loop over all
-		for (final Cache.Entry<Long, DialableLandLineNumber> currentEntry : this.landLineNumberCache) {
-			// Add value to list
-			list.add(currentEntry.getValue());
-		}
-
-		// Return it
-		return list;
-	}
-
-	@Override
-	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
-	public List<DialableMobileNumber> allMobileNumbers () {
-		// Init list
-		final List<DialableMobileNumber> list = new LinkedList<>();
-
-		// Loop over all
-		for (final Cache.Entry<Long, DialableMobileNumber> currentEntry : this.mobileNumberCache) {
-			// Add value to list
-			list.add(currentEntry.getValue());
-		}
-
-		// Return it
-		return list;
-	}
-
-	@Override
-	public DialableFaxNumber findFaxNumberById (final Long faxNumberId) throws PhoneEntityNotFoundException {
-		// Validate paramter
-		if (null == faxNumberId) {
-			// Throw NPE
-			throw new NullPointerException("faxNumberId is null"); //NOI18N
-		} else if (faxNumberId < 1) {
-			// Throw IAE
-			throw new IllegalArgumentException("faxNumberId=" + faxNumberId + " is invalid."); //NOI18N
-		} else if (!this.faxNumberCache.containsKey(faxNumberId)) {
-			// Not found
-			throw new PhoneEntityNotFoundException(faxNumberId);
-		}
-
-		// Get it from cache
-		final DialableFaxNumber faxNumber = this.faxNumberCache.get(faxNumberId);
-
-		// Return it
-		return faxNumber;
-	}
-
-	@Override
-	public DialableLandLineNumber findLandLineNumberById (final Long landLineNumberId) throws PhoneEntityNotFoundException {
-		// Validate paramter
-		if (null == landLineNumberId) {
-			// Throw NPE
-			throw new NullPointerException("landLineNumberId is null"); //NOI18N
-		} else if (landLineNumberId < 1) {
-			// Throw IAE
-			throw new IllegalArgumentException("landLineNumberId=" + landLineNumberId + " is invalid."); //NOI18N
-		} else if (!this.landLineNumberCache.containsKey(landLineNumberId)) {
-			// Not found
-			throw new PhoneEntityNotFoundException(landLineNumberId);
-		}
-
-		// Get it from cache
-		final DialableLandLineNumber landLineNumber = this.landLineNumberCache.get(landLineNumberId);
-
-		// Return it
-		return landLineNumber;
-	}
-
-	@Override
-	public DialableMobileNumber findMobileNumberById (final Long mobileNumberId) throws PhoneEntityNotFoundException {
-		// Validate paramter
-		if (null == mobileNumberId) {
-			// Throw NPE
-			throw new NullPointerException("mobileNumberId is null"); //NOI18N
-		} else if (mobileNumberId < 1) {
-			// Throw IAE
-			throw new IllegalArgumentException("mobileNumberId=" + mobileNumberId + " is invalid."); //NOI18N
-		} else if (!this.mobileNumberCache.containsKey(mobileNumberId)) {
-			// Not found
-			throw new PhoneEntityNotFoundException(mobileNumberId);
-		}
-
-		// Get it from cache
-		final DialableMobileNumber mobileNumber = this.mobileNumberCache.get(mobileNumberId);
-
-		// Return it
-		return mobileNumber;
-	}
-
-	/**
-	 * Post-construction method
-	 */
-	@PostConstruct
-	public void init () {
-		// Is cache there?
-		if (!this.faxNumberCache.iterator().hasNext()) {
-			// Add all
-			for (final DialableFaxNumber faxNumber : this.phoneBean.allFaxNumbers()) {
-				// Add it to cache
-				this.faxNumberCache.put(faxNumber.getPhoneId(), faxNumber);
-			}
-		}
-
-		// Is cache there?
-		if (!this.landLineNumberCache.iterator().hasNext()) {
-			// Add all
-			for (final DialableLandLineNumber lineNumber : this.phoneBean.allLandLineNumbers()) {
-				// Add it to cache
-				this.landLineNumberCache.put(lineNumber.getPhoneId(), lineNumber);
-			}
-		}
-
-		// Is cache there?
-		if (!this.mobileNumberCache.iterator().hasNext()) {
-			// Add all
-			for (final DialableMobileNumber mobileNumber : this.phoneBean.allMobileNumbers()) {
-				// Add it to cache
-				this.mobileNumberCache.put(mobileNumber.getPhoneId(), mobileNumber);
-			}
-		}
-	}
-
-	/**
-	 * Clears this bean
-	 */
-	private void clear () {
-		// Clear all data
-	}
-
-	/**
-	 * Uniquely add given fax number to this bean's list. First remove the old
-	 * instance (by id number), then re-add it again.
-	 * <p>
-	 * @param faxNumber number to add
-	 */
-	private void uniqueAddFaxNumber (final DialableFaxNumber faxNumber) {
-		// Make sure the parameter is valid
-		if (null == faxNumber) {
-			// Throw NPE
-			throw new NullPointerException("faxNumber is null"); //NOI18N
-		} else if (faxNumber.getPhoneId() == null) {
-			// Throw again ...
-			throw new NullPointerException("faxNumber.phoneId is null"); //NOI18N
-		} else if (faxNumber.getPhoneId() < 1) {
-			// Not valid
-			throw new IllegalArgumentException(MessageFormat.format("faxNumber.phoneId={0} is not valid.", faxNumber.getPhoneId())); //NOI18N
-		}
-
-		// First remove it
-		if (!this.allFaxNumbers().remove(faxNumber)) {
-			// Did not work, try by id number
-			for (final DialableFaxNumber fax : this.allFaxNumbers()) {
-				// Is id number the same?
-				if (Objects.equals(fax.getPhoneId(), faxNumber.getPhoneId())) {
-					// Found it
-					this.allFaxNumbers().remove(fax);
-					break;
-				}
-			}
-		}
-
-		// ... then add it
-		this.allFaxNumbers().add(faxNumber);
-	}
-
-	/**
-	 * Uniquely add given land-line number to this bean's list. First remove the
-	 * old instance (by id number), then re-add it again.
-	 * <p>
-	 * @param landLineNumber Land-line number to add
-	 */
-	private void uniqueAddLandLineNumber (final DialableLandLineNumber landLineNumber) {
-		// Make sure the parameter is valid
-		if (null == landLineNumber) {
-			// Throw NPE
-			throw new NullPointerException("landLineNumber is null"); //NOI18N
-		} else if (landLineNumber.getPhoneId() == null) {
-			// Throw again ...
-			throw new NullPointerException("landLineNumber.phoneId is null"); //NOI18N
-		} else if (landLineNumber.getPhoneId() < 1) {
-			// Not valid
-			throw new IllegalArgumentException(MessageFormat.format("landLineNumber.phoneId={0} is not valid.", landLineNumber.getPhoneId())); //NOI18N
-		}
-
-		// First remove it
-		if (!this.allLandLineNumbers().remove(landLineNumber)) {
-			// Did not work, try by id number
-			for (final DialableLandLineNumber landLine : this.allLandLineNumbers()) {
-				// Is id number the same?
-				if (Objects.equals(landLine.getPhoneId(), landLineNumber.getPhoneId())) {
-					// Found it
-					this.allLandLineNumbers().remove(landLine);
-					break;
-				}
-			}
-		}
-
-		// ... then add it
-		this.allLandLineNumbers().add(landLineNumber);
-	}
-
-	/**
-	 * Uniquely add given mobile number to this bean's list. First remove the
-	 * old instance (by id number), then re-add it again.
-	 * <p>
-	 * @param mobileNumber Mobile number to add
-	 */
-	private void uniqueAddMobileNumber (final DialableMobileNumber mobileNumber) {
-		// Make sure the parameter is valid
-		if (null == mobileNumber) {
-			// Throw NPE
-			throw new NullPointerException("mobileNumber is null"); //NOI18N
-		} else if (mobileNumber.getPhoneId() == null) {
-			// Throw again ...
-			throw new NullPointerException("mobileNumber.phoneId is null"); //NOI18N
-		} else if (mobileNumber.getPhoneId() < 1) {
-			// Not valid
-			throw new IllegalArgumentException(MessageFormat.format("mobileNumber.phoneId={0} is not valid.", mobileNumber.getPhoneId())); //NOI18N
-		}
-
-		// First remove it by object
-		if (!this.allMobileNumbers().remove(mobileNumber)) {
-			// Did not work, try by id number
-			for (final DialableMobileNumber cell : this.allMobileNumbers()) {
-				// Is id number the same?
-				if (Objects.equals(cell.getPhoneId(), mobileNumber.getPhoneId())) {
-					// Found it
-					this.allMobileNumbers().remove(cell);
-					break;
-				}
-			}
-		}
-
-		// ... then add it
-		this.allMobileNumbers().add(mobileNumber);
-	}
-
-	/**
-	 * Updates given contact's mobile, land-line and fax number
-	 * <p>
-	 * @param contact Contact instance
-	 */
-	private void updateContactPhoneNumbers (final Contact contact) {
-		// Parameter must be valid
-		if (null == contact) {
-			// Throw NPE
-			throw new NullPointerException("contact is null"); //NOI18N
-		} else if (contact.getContactId() == null) {
-			// Throw again
-			throw new NullPointerException("contact.contactId is null"); //NOI18N
-		} else if (contact.getContactId() < 1) {
-			// Id number is not valid
-		}
-
-		// Is mobile set?
-		if (contact.getContactMobileNumber() instanceof DialableMobileNumber) {
-			// Unique-add it
-			this.uniqueAddMobileNumber(contact.getContactMobileNumber());
-		}
-
-		// Is land-line set?
-		if (contact.getContactLandLineNumber() instanceof DialableLandLineNumber) {
-			// Unique-add it
-			this.uniqueAddLandLineNumber(contact.getContactLandLineNumber());
-		}
-
-		// Is fax set?
-		if (contact.getContactFaxNumber() instanceof DialableFaxNumber) {
-			// Unique-add it
-			this.uniqueAddFaxNumber(contact.getContactFaxNumber());
-		}
-	}
-
 }
diff --git a/src/java/org/mxchange/jjobs/beans/phone/JobsPhoneWebRequestController.java b/src/java/org/mxchange/jjobs/beans/phone/JobsPhoneWebRequestController.java
index 948c467b..80f36d09 100644
--- a/src/java/org/mxchange/jjobs/beans/phone/JobsPhoneWebRequestController.java
+++ b/src/java/org/mxchange/jjobs/beans/phone/JobsPhoneWebRequestController.java
@@ -17,11 +17,6 @@
 package org.mxchange.jjobs.beans.phone;
 
 import java.io.Serializable;
-import java.util.List;
-import org.mxchange.jphone.exceptions.phone.PhoneEntityNotFoundException;
-import org.mxchange.jphone.model.phonenumbers.fax.DialableFaxNumber;
-import org.mxchange.jphone.model.phonenumbers.landline.DialableLandLineNumber;
-import org.mxchange.jphone.model.phonenumbers.mobile.DialableMobileNumber;
 
 /**
  * An interface for a request web controller (bean) for administrative phone
@@ -31,67 +26,4 @@ import org.mxchange.jphone.model.phonenumbers.mobile.DialableMobileNumber;
  */
 public interface JobsPhoneWebRequestController extends Serializable {
 
-	/**
-	 * Returns a list of all mobile numbers. For performance reasons, the
-	 * controller (bean) should be application-scoped as from user to user
-	 * nothing changes. And the controller's post-construct method should load
-	 * all numbers and cache it in the controller.
-	 * <p>
-	 * @return List of all mobile numbers
-	 */
-	List<DialableMobileNumber> allMobileNumbers ();
-
-	/**
-	 * Returns a list of all fax numbers. For performance reasons, the
-	 * controller (bean) should be application-scoped as from user to user
-	 * nothing changes. And the controller's post-construct method should load
-	 * all numbers and cache it in the controller.
-	 * <p>
-	 * @return List of all fax numbers
-	 */
-	List<DialableFaxNumber> allFaxNumbers ();
-
-	/**
-	 * Returns a list of all land-line numbers. For performance reasons, the
-	 * controller (bean) should be application-scoped as from user to user
-	 * nothing changes. And the controller's post-construct method should load
-	 * all numbers and cache it in the controller.
-	 * <p>
-	 * @return List of all land-line numbers
-	 */
-	List<DialableLandLineNumber> allLandLineNumbers ();
-
-	/**
-	 * Finds a fax entry by given id number
-	 * <p>
-	 * @param faxNumberId Fax entry id number
-	 * <p>
-	 * @return A valid fax instance
-	 * <p>
-	 * @throws PhoneEntityNotFoundException If the entity was not found
-	 */
-	DialableFaxNumber findFaxNumberById (final Long faxNumberId) throws PhoneEntityNotFoundException;
-
-	/**
-	 * Finds a land-line entry by given id number
-	 * <p>
-	 * @param landLineNumberId Land-line entry id number
-	 * <p>
-	 * @return A valid land-line instance
-	 * <p>
-	 * @throws PhoneEntityNotFoundException If the entity was not found
-	 */
-	DialableLandLineNumber findLandLineNumberById (final Long landLineNumberId) throws PhoneEntityNotFoundException;
-
-	/**
-	 * Finds a mobile entry by given id number
-	 * <p>
-	 * @param mobileNumberId Mobile entry id number
-	 * <p>
-	 * @return A valid mobile instance
-	 * <p>
-	 * @throws PhoneEntityNotFoundException If the entity was not found
-	 */
-	DialableMobileNumber findMobileNumberById (Long mobileNumberId) throws PhoneEntityNotFoundException;
-
 }
diff --git a/src/java/org/mxchange/jjobs/beans/phone/list/FinancialsPhoneListWebViewBean.java b/src/java/org/mxchange/jjobs/beans/phone/list/FinancialsPhoneListWebViewBean.java
new file mode 100644
index 00000000..58642aed
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/phone/list/FinancialsPhoneListWebViewBean.java
@@ -0,0 +1,636 @@
+/*
+ * Copyright (C) 2016 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.phone.list;
+
+import fish.payara.cdi.jsr107.impl.NamedCache;
+import java.text.MessageFormat;
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import javax.annotation.PostConstruct;
+import javax.cache.Cache;
+import javax.ejb.EJB;
+import javax.enterprise.event.Observes;
+import javax.faces.view.ViewScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jcontacts.events.contact.add.ObservableAdminAddedContactEvent;
+import org.mxchange.jcontacts.events.contact.update.ObservableAdminUpdatedContactEvent;
+import org.mxchange.jcontacts.events.fax.linked.ObservableAdminLinkedFaxNumberEvent;
+import org.mxchange.jcontacts.events.landline.linked.ObservableAdminLinkedLandLineNumberEvent;
+import org.mxchange.jcontacts.model.contact.Contact;
+import org.mxchange.jfinancials.beans.BaseFinancialsBean;
+import org.mxchange.jphone.events.fax.deleted.AdminDeletedFaxNumberEvent;
+import org.mxchange.jphone.events.fax.updated.AdminUpdatedFaxNumberEvent;
+import org.mxchange.jphone.events.landline.deleted.AdminDeletedLandLineNumberEvent;
+import org.mxchange.jphone.events.landline.updated.AdminUpdatedLandLineNumberEvent;
+import org.mxchange.jphone.exceptions.phone.PhoneEntityNotFoundException;
+import org.mxchange.jphone.model.phonenumbers.fax.DialableFaxNumber;
+import org.mxchange.jphone.model.phonenumbers.landline.DialableLandLineNumber;
+import org.mxchange.jphone.model.phonenumbers.phone.PhoneSessionBeanRemote;
+
+/**
+ * Administrative listing controller (bean) for phone numbers
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("phoneListController")
+@ViewScoped
+public class FinancialsPhoneListWebViewBean extends BaseFinancialsBean implements FinancialsPhoneListWebViewController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 491_058_674_675_690_107L;
+
+	/**
+	 * A list of all fax numbers
+	 */
+	private final List<DialableFaxNumber> allFaxNumbers;
+
+	/**
+	 * A list of all land-line numbers
+	 */
+	private final List<DialableLandLineNumber> allLandLineNumbers;
+
+	/**
+	 * All fax numbers
+	 */
+	@Inject
+	@NamedCache (cacheName = "faxNumberCache")
+	private transient Cache<Long, DialableFaxNumber> faxNumberCache;
+
+	/**
+	 * A list of filtered fax numbers
+	 */
+	private List<DialableFaxNumber> filteredFaxNumbers;
+
+	/**
+	 * A list of filtered land-line numbers
+	 */
+	private List<DialableLandLineNumber> filteredLandLineNumbers;
+
+	/**
+	 * All land-line numbers
+	 */
+	@Inject
+	@NamedCache (cacheName = "landLineNumberCache")
+	private transient Cache<Long, DialableLandLineNumber> landLineNumberCache;
+
+	/**
+	 * General EJB for phone numbers
+	 */
+	@EJB (lookup = "java:global/jfinancials-ejb/phone!org.mxchange.jphone.model.phonenumbers.phone.PhoneSessionBeanRemote")
+	private PhoneSessionBeanRemote phoneBean;
+
+	/**
+	 * Default constructor
+	 */
+	public FinancialsPhoneListWebViewBean () {
+		// Call super constructor
+		super();
+
+		// Initialize lists
+		this.allFaxNumbers = new LinkedList<>();
+		this.allLandLineNumbers = new LinkedList<>();
+	}
+
+	/**
+	 * Observes events being fired when an administrator has added a new
+	 * contact.
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminAddedContactEvent (@Observes final ObservableAdminAddedContactEvent event) {
+		// The event must be valid
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getAddedContact() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.addedContact is null"); //NOI18N
+		} else if (event.getAddedContact().getContactId() == null) {
+			// ... and again
+			throw new NullPointerException("event.addedContact.contactId is null"); //NOI18N
+		} else if (event.getAddedContact().getContactId() < 1) {
+			// Not valid
+			throw new IllegalArgumentException(MessageFormat.format("event.addedContact.contactId={0} is not valid", event.getAddedContact().getContactId())); //NOI18N
+		}
+
+		// Update contact's mobile, land-line and fax number
+		this.updateContactPhoneNumbers(event.getAddedContact());
+
+		// Clear this bean
+		this.clear();
+	}
+
+	/**
+	 * Observes events being fired when an administrator has deleted a fax
+	 * number
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminDeletedFaxNumberEvent (@Observes final AdminDeletedFaxNumberEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getDeletedFaxNumber() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.deletedFaxNumber is null"); //NOI18N
+		} else if (event.getDeletedFaxNumber().getPhoneId() == null) {
+			// phoneId is null
+			throw new NullPointerException("event.deletedFaxNumber.phoneId is null"); //NOI18N
+		} else if (event.getDeletedFaxNumber().getPhoneId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getDeletedFaxNumber(), event.getDeletedFaxNumber().getPhoneId())); //NOI18N
+		}
+
+		// Update contact's mobile, land-line and fax number
+		this.getAllFaxNumbers().remove(event.getDeletedFaxNumber());
+
+		// Clear all data
+		this.clear();
+	}
+
+	/**
+	 * Observes events being fired when an administrator has deleted a land-line
+	 * number
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminDeletedLandLineNumberEvent (@Observes final AdminDeletedLandLineNumberEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getDeletedLandLineNumber() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.deletedLandLineNumber is null"); //NOI18N
+		} else if (event.getDeletedLandLineNumber().getPhoneId() == null) {
+			// phoneId is null
+			throw new NullPointerException("event.deletedLandLineNumber.phoneId is null"); //NOI18N
+		} else if (event.getDeletedLandLineNumber().getPhoneId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getDeletedLandLineNumber(), event.getDeletedLandLineNumber().getPhoneId())); //NOI18N
+		}
+
+		// Update contact's mobile, land-line and fax number
+		this.getAllLandLineNumbers().remove(event.getDeletedLandLineNumber());
+
+		// Clear all data
+		this.clear();
+	}
+
+	/**
+	 * Observes events being fired when an administrator has a linked a fax
+	 * number
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminLinkedFaxNumberEvent (@Observes final ObservableAdminLinkedFaxNumberEvent event) {
+		// Is the event fine?
+		if (event == null) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getContact() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.contact is null"); //NOI18N
+		} else if (event.getContact().getContactId() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.contact.contactId is null"); //NOI18N
+		} else if (event.getContact().getContactId() < 1) {
+			// Throw again ...
+			throw new NullPointerException(MessageFormat.format("event.contact.contactId={0} is invalid", event.getContact().getContactId())); //NOI18N
+		} else if (event.getContact().getContactFaxNumber() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.contact.contactFaxNumber is null"); //NOI18N
+		} else if (event.getContact().getContactFaxNumber().getPhoneId() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.contact.contactFaxNumber.phoneId is null"); //NOI18N
+		} else if (event.getContact().getContactFaxNumber().getPhoneId() < 1) {
+			// Throw again ...
+			throw new NullPointerException(MessageFormat.format("event.contact.contactFaxNumber.phoneId={0} is invalid", event.getContact().getContactFaxNumber().getPhoneId())); //NOI18N
+		} else if (event.getLinkedFaxNumber() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.linkedFaxNumer is null"); //NOI18N
+		}
+
+		// Is the id number in linked number not set?
+		if (event.getLinkedFaxNumber().getPhoneId() == null) {
+			// Then it is a new number, so add it from contact as there the id number has been set
+			this.uniqueAddFaxNumber(event.getContact().getContactFaxNumber());
+		}
+	}
+
+	/**
+	 * Observes events being fired when an administrator has a linked a
+	 * land-line number
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminLinkedLandLineNumberEvent (@Observes final ObservableAdminLinkedLandLineNumberEvent event) {
+		// Is the event fine?
+		if (event == null) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getContact() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.contact is null"); //NOI18N
+		} else if (event.getContact().getContactId() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.contact.contactId is null"); //NOI18N
+		} else if (event.getContact().getContactId() < 1) {
+			// Throw again ...
+			throw new NullPointerException(MessageFormat.format("event.contact.contactId={0} is invalid", event.getContact().getContactId())); //NOI18N
+		} else if (event.getContact().getContactLandLineNumber() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.contact.contactLandLineNumber is null"); //NOI18N
+		} else if (event.getContact().getContactLandLineNumber().getPhoneId() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.contact.contactLandLineNumber.phoneId is null"); //NOI18N
+		} else if (event.getContact().getContactLandLineNumber().getPhoneId() < 1) {
+			// Throw again ...
+			throw new NullPointerException(MessageFormat.format("event.contact.contactLandLineNumber.phoneId={0} is invalid", event.getContact().getContactLandLineNumber().getPhoneId())); //NOI18N
+		} else if (event.getLinkedLandLineNumber() == null) {
+			// Throw again ...
+			throw new NullPointerException("event.linkedLandLineNumer is null"); //NOI18N
+		}
+
+		// Is the id number in linked number not set?
+		if (event.getLinkedLandLineNumber().getPhoneId() == null) {
+			// Then it is a new number, so add it from contact as there the id number has been set
+			this.uniqueAddLandLineNumber(event.getContact().getContactLandLineNumber());
+		}
+	}
+
+	/**
+	 * Observes events being fired when an administrator has updated contact
+	 * data.
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminUpdatedContactDataEvent (@Observes final ObservableAdminUpdatedContactEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUpdatedContact() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.updatedContact is null"); //NOI18N
+		} else if (event.getUpdatedContact().getContactId() == null) {
+			// phoneId is null
+			throw new NullPointerException("event.updatedContact.contactId is null"); //NOI18N
+		} else if (event.getUpdatedContact().getContactId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUpdatedContact(), event.getUpdatedContact().getContactId())); //NOI18N
+		}
+
+		// Update contact's mobile, land-line and fax number
+		this.updateContactPhoneNumbers(event.getUpdatedContact());
+
+		// Clear all data
+		this.clear();
+	}
+
+	/**
+	 * Observes events being fired when an administrator has updated a fax
+	 * number.
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminUpdatedFaxNumberEvent (@Observes final AdminUpdatedFaxNumberEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUpdatedFaxNumber() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.updatedFaxNumber is null"); //NOI18N
+		} else if (event.getUpdatedFaxNumber().getPhoneId() == null) {
+			// phoneId is null
+			throw new NullPointerException("event.updatedFaxNumber.phoneId is null"); //NOI18N
+		} else if (event.getUpdatedFaxNumber().getPhoneId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getUpdatedFaxNumber(), event.getUpdatedFaxNumber().getPhoneId())); //NOI18N
+		}
+
+		// Uniquely add it
+		this.uniqueAddFaxNumber(event.getUpdatedFaxNumber());
+
+		// Clear it
+		this.clear();
+	}
+
+	/**
+	 * Observes events being fired when an administrator has updated a land-line
+	 * number.
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminUpdatedLandLineNumberEvent (@Observes final AdminUpdatedLandLineNumberEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUpdatedLandLineNumber() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.updatedLandLineNumber is null"); //NOI18N
+		} else if (event.getUpdatedLandLineNumber().getPhoneId() == null) {
+			// phoneId is null
+			throw new NullPointerException("event.updatedLandLineNumber.phoneId is null"); //NOI18N
+		} else if (event.getUpdatedLandLineNumber().getPhoneId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getUpdatedLandLineNumber(), event.getUpdatedLandLineNumber().getPhoneId())); //NOI18N
+		}
+
+		// Uniquely add it
+		this.uniqueAddLandLineNumber(event.getUpdatedLandLineNumber());
+
+		// Clear it
+		this.clear();
+	}
+
+	@Override
+	public DialableFaxNumber findFaxNumberById (final Long phoneId) throws PhoneEntityNotFoundException {
+		// Validate paramter
+		if (null == phoneId) {
+			// Throw NPE
+			throw new NullPointerException("phoneId is null"); //NOI18N
+		} else if (phoneId < 1) {
+			// Throw IAE
+			throw new IllegalArgumentException("phoneId=" + phoneId + " is invalid."); //NOI18N
+		} else if (!this.faxNumberCache.containsKey(phoneId)) {
+			// Not found
+			throw new PhoneEntityNotFoundException(phoneId);
+		}
+
+		// Get it from cache
+		final DialableFaxNumber faxNumber = this.faxNumberCache.get(phoneId);
+
+		// Return it
+		return faxNumber;
+	}
+
+	@Override
+	public DialableLandLineNumber findLandLineNumberById (final Long landLineNumberId) throws PhoneEntityNotFoundException {
+		// Validate paramter
+		if (null == landLineNumberId) {
+			// Throw NPE
+			throw new NullPointerException("landLineNumberId is null"); //NOI18N
+		} else if (landLineNumberId < 1) {
+			// Throw IAE
+			throw new IllegalArgumentException(MessageFormat.format("landLineNumberId={0} is invalid.", landLineNumberId)); //NOI18N
+		} else if (!this.landLineNumberCache.containsKey(landLineNumberId)) {
+			// Not found
+			throw new PhoneEntityNotFoundException(landLineNumberId);
+		}
+
+		// Get it from cache
+		final DialableLandLineNumber landLineNumber = this.landLineNumberCache.get(landLineNumberId);
+
+		// Return it
+		return landLineNumber;
+	}
+
+	@Override
+	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
+	public List<DialableFaxNumber> getAllFaxNumbers () {
+		return this.allFaxNumbers;
+	}
+
+	@Override
+	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
+	public List<DialableLandLineNumber> getAllLandLineNumbers () {
+		return this.allLandLineNumbers;
+	}
+
+	/**
+	 * Getter for filtered fax number list
+	 * <p>
+	 * @return Filtered fax number list
+	 */
+	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
+	public List<DialableFaxNumber> getFilteredFaxNumbers () {
+		return this.filteredFaxNumbers;
+	}
+
+	/**
+	 * Setter for filtered fax number list
+	 *
+	 * @param filteredFaxNumbers Filtered fax number list
+	 */
+	@SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter")
+	public void setFilteredFaxNumbers (final List<DialableFaxNumber> filteredFaxNumbers) {
+		this.filteredFaxNumbers = filteredFaxNumbers;
+	}
+
+	/**
+	 * Getter for filtered land-line number list
+	 * <p>
+	 * @return Filtered land-line number list
+	 */
+	@SuppressWarnings ("ReturnOfCollectionOrArrayField")
+	public List<DialableLandLineNumber> getFilteredLandLineNumbers () {
+		return this.filteredLandLineNumbers;
+	}
+
+	/**
+	 * Setter for filtered land-line number list
+	 *
+	 * @param filteredLandLineNumbers Filtered land-line number list
+	 */
+	@SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter")
+	public void setFilteredLandLineNumbers (final List<DialableLandLineNumber> filteredLandLineNumbers) {
+		this.filteredLandLineNumbers = filteredLandLineNumbers;
+	}
+
+	/**
+	 * Post-construction method
+	 */
+	@PostConstruct
+	public void initializeList () {
+		// Is cache there?
+		if (!this.faxNumberCache.iterator().hasNext()) {
+			// Add all
+			for (final DialableFaxNumber currentNumber : this.phoneBean.fetchAllFaxNumbers()) {
+				// Add it to cache
+				this.faxNumberCache.put(currentNumber.getPhoneId(), currentNumber);
+			}
+		}
+
+		// Is cache there?
+		if (!this.landLineNumberCache.iterator().hasNext()) {
+			// Add all
+			for (final DialableLandLineNumber currentNumber : this.phoneBean.fetchAllLandLineNumbers()) {
+				// Add it to cache
+				this.landLineNumberCache.put(currentNumber.getPhoneId(), currentNumber);
+			}
+		}
+
+		// Is cache filled and list is empty
+		if ((this.faxNumberCache.iterator().hasNext()) && (this.getAllFaxNumbers().isEmpty())) {
+			// Build up list
+			for (final Cache.Entry<Long, DialableFaxNumber> currentEntry : this.faxNumberCache) {
+				// Add to list
+				this.getAllFaxNumbers().add(currentEntry.getValue());
+			}
+
+			// Sort list
+			this.getAllFaxNumbers().sort(new Comparator<DialableFaxNumber>() {
+				@Override
+				public int compare (final DialableFaxNumber faxNumber1, final DialableFaxNumber faxNumber2) {
+					return faxNumber1.getPhoneId() > faxNumber2.getPhoneId() ? 1 : faxNumber1.getPhoneId() < faxNumber2.getPhoneId() ? -1 : 0;
+				}
+			});
+
+			// Set full list
+			this.setFilteredFaxNumbers(this.getAllFaxNumbers());
+		}
+
+		// Is cache filled and list is empty
+		if ((this.landLineNumberCache.iterator().hasNext()) && (this.getAllLandLineNumbers().isEmpty())) {
+			// Build up list
+			for (final Cache.Entry<Long, DialableLandLineNumber> currentEntry : this.landLineNumberCache) {
+				// Add to list
+				this.getAllLandLineNumbers().add(currentEntry.getValue());
+			}
+
+			// Sort list
+			this.getAllLandLineNumbers().sort(new Comparator<DialableLandLineNumber>() {
+				@Override
+				public int compare (final DialableLandLineNumber landLineNumber1, final DialableLandLineNumber landLineNumber2) {
+					return landLineNumber1.getPhoneId() > landLineNumber2.getPhoneId() ? 1 : landLineNumber1.getPhoneId() < landLineNumber2.getPhoneId() ? -1 : 0;
+				}
+			});
+
+			// Set full list
+			this.setFilteredLandLineNumbers(this.getAllLandLineNumbers());
+		}
+	}
+
+	/**
+	 * Clears this bean
+	 */
+	private void clear () {
+		// Clear all data
+	}
+
+	/**
+	 * Uniquely add given fax number to this bean's list. First remove the old
+	 * instance (by id number), then re-add it again.
+	 * <p>
+	 * @param faxNumber number to add
+	 */
+	private void uniqueAddFaxNumber (final DialableFaxNumber faxNumber) {
+		// Make sure the parameter is valid
+		if (null == faxNumber) {
+			// Throw NPE
+			throw new NullPointerException("faxNumber is null"); //NOI18N
+		} else if (faxNumber.getPhoneId() == null) {
+			// Throw again ...
+			throw new NullPointerException("faxNumber.phoneId is null"); //NOI18N
+		} else if (faxNumber.getPhoneId() < 1) {
+			// Not valid
+			throw new IllegalArgumentException(MessageFormat.format("faxNumber.phoneId={0} is not valid.", faxNumber.getPhoneId())); //NOI18N
+		}
+
+		// First remove it
+		if (!this.getAllFaxNumbers().remove(faxNumber)) {
+			// Did not work, try by id number
+			for (final DialableFaxNumber currentNumber : this.getAllFaxNumbers()) {
+				// Is id number the same?
+				if (Objects.equals(currentNumber.getPhoneId(), faxNumber.getPhoneId())) {
+					// Found it
+					this.getAllFaxNumbers().remove(currentNumber);
+					break;
+				}
+			}
+		}
+
+		// ... then add it
+		this.getAllFaxNumbers().add(faxNumber);
+	}
+
+	/**
+	 * Uniquely add given land-line number to this bean's list. First remove the
+	 * old instance (by id number), then re-add it again.
+	 * <p>
+	 * @param landLineNumber Land-line number to add
+	 */
+	private void uniqueAddLandLineNumber (final DialableLandLineNumber landLineNumber) {
+		// Make sure the parameter is valid
+		if (null == landLineNumber) {
+			// Throw NPE
+			throw new NullPointerException("landLineNumber is null"); //NOI18N
+		} else if (landLineNumber.getPhoneId() == null) {
+			// Throw again ...
+			throw new NullPointerException("landLineNumber.phoneId is null"); //NOI18N
+		} else if (landLineNumber.getPhoneId() < 1) {
+			// Not valid
+			throw new IllegalArgumentException(MessageFormat.format("landLineNumber.phoneId={0} is not valid.", landLineNumber.getPhoneId())); //NOI18N
+		}
+
+		// First remove it
+		if (!this.getAllLandLineNumbers().remove(landLineNumber)) {
+			// Did not work, try by id number
+			for (final DialableLandLineNumber currentNumber : this.getAllLandLineNumbers()) {
+				// Is id number the same?
+				if (Objects.equals(currentNumber.getPhoneId(), landLineNumber.getPhoneId())) {
+					// Found it
+					this.getAllLandLineNumbers().remove(currentNumber);
+					break;
+				}
+			}
+		}
+
+		// ... then add it
+		this.getAllLandLineNumbers().add(landLineNumber);
+	}
+
+	/**
+	 * Updates given contact's mobile, land-line and fax number
+	 * <p>
+	 * @param contact Contact instance
+	 */
+	private void updateContactPhoneNumbers (final Contact contact) {
+		// Parameter must be valid
+		if (null == contact) {
+			// Throw NPE
+			throw new NullPointerException("contact is null"); //NOI18N
+		} else if (contact.getContactId() == null) {
+			// Throw again
+			throw new NullPointerException("contact.contactId is null"); //NOI18N
+		} else if (contact.getContactId() < 1) {
+			// Id number is not valid
+		}
+
+		// Is land-line set?
+		if (contact.getContactLandLineNumber() instanceof DialableLandLineNumber) {
+			// Unique-add it
+			this.uniqueAddLandLineNumber(contact.getContactLandLineNumber());
+		}
+
+		// Is fax set?
+		if (contact.getContactFaxNumber() instanceof DialableFaxNumber) {
+			// Unique-add it
+			this.uniqueAddFaxNumber(contact.getContactFaxNumber());
+		}
+	}
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/phone/list/FinancialsPhoneListWebViewController.java b/src/java/org/mxchange/jjobs/beans/phone/list/FinancialsPhoneListWebViewController.java
new file mode 100644
index 00000000..24176e8f
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/phone/list/FinancialsPhoneListWebViewController.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2016 - 2020 Free Software Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.phone.list;
+
+import java.io.Serializable;
+import java.util.List;
+import org.mxchange.jphone.exceptions.phone.PhoneEntityNotFoundException;
+import org.mxchange.jphone.model.phonenumbers.fax.DialableFaxNumber;
+import org.mxchange.jphone.model.phonenumbers.landline.DialableLandLineNumber;
+
+/**
+ * An interface for a request web controller (bean) for administrative phone
+ * number purposes.
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsPhoneListWebViewController extends Serializable {
+
+	/**
+	 * Returns a list of all fax numbers. For performance reasons, the
+	 * controller (bean) should be view-scoped as from user to user nothing
+	 * changes. And the controller's post-construct method should load all
+	 * numbers and cache it in the controller.
+	 * <p>
+	 * @return List of all fax numbers
+	 */
+	List<DialableFaxNumber> getAllFaxNumbers ();
+
+	/**
+	 * Returns a list of all land-line numbers. For performance reasons, the
+	 * controller (bean) should be view-scoped as from user to user nothing
+	 * changes. And the controller's post-construct method should load all
+	 * numbers and cache it in the controller.
+	 * <p>
+	 * @return List of all land-line numbers
+	 */
+	List<DialableLandLineNumber> getAllLandLineNumbers ();
+
+	/**
+	 * Finds a fax entry by given id number
+	 * <p>
+	 * @param faxNumberId Fax entry id number
+	 * <p>
+	 * @return A valid fax instance
+	 * <p>
+	 * @throws PhoneEntityNotFoundException If the entity was not found
+	 */
+	DialableFaxNumber findFaxNumberById (final Long faxNumberId) throws PhoneEntityNotFoundException;
+
+	/**
+	 * Finds a land-line entry by given id number
+	 * <p>
+	 * @param landLineNumberId Land-line entry id number
+	 * <p>
+	 * @return A valid land-line instance
+	 * <p>
+	 * @throws PhoneEntityNotFoundException If the entity was not found
+	 */
+	DialableLandLineNumber findLandLineNumberById (final Long landLineNumberId) throws PhoneEntityNotFoundException;
+
+}
diff --git a/src/java/org/mxchange/jjobs/beans/user/JobsAdminUserWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/user/JobsAdminUserWebRequestBean.java
index 9d2fe7f5..f24d0437 100644
--- a/src/java/org/mxchange/jjobs/beans/user/JobsAdminUserWebRequestBean.java
+++ b/src/java/org/mxchange/jjobs/beans/user/JobsAdminUserWebRequestBean.java
@@ -47,8 +47,7 @@ import org.mxchange.jusercore.events.user.locked.AdminLockedUserEvent;
 import org.mxchange.jusercore.events.user.locked.ObservableAdminLockedUserEvent;
 import org.mxchange.jusercore.events.user.unlocked.AdminUnlockedUserEvent;
 import org.mxchange.jusercore.events.user.unlocked.ObservableAdminUnlockedUserEvent;
-import org.mxchange.jusercore.events.user.update.AdminUpdatedUserDataEvent;
-import org.mxchange.jusercore.events.user.update.ObservableAdminUpdatedUserDataEvent;
+import org.mxchange.jusercore.events.user.update.post.AdminPostUserDataUpdatedEvent;
 import org.mxchange.jusercore.exceptions.EmailAddressAlreadyRegisteredException;
 import org.mxchange.jusercore.exceptions.UserNameAlreadyRegisteredException;
 import org.mxchange.jusercore.exceptions.UserNotFoundException;
@@ -65,6 +64,7 @@ import org.mxchange.juserlogincore.container.login.UserLoginContainer;
 import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent;
 import org.mxchange.juserlogincore.exceptions.UserPasswordRepeatMismatchException;
 import org.mxchange.juserlogincore.login.UserLoginUtils;
+import org.mxchange.jusercore.events.user.update.post.ObservableAdminPostUserDataUpdatedEvent;
 
 /**
  * A user controller (bean)
@@ -128,7 +128,7 @@ public class JobsAdminUserWebRequestBean extends BaseJobsBean implements JobsAdm
 	 */
 	@Inject
 	@Any
-	private Event<ObservableAdminUpdatedUserDataEvent> updatedUserDataEvent;
+	private Event<ObservableAdminPostUserDataUpdatedEvent> updatedUserDataEvent;
 
 	/**
 	 * User instance
@@ -436,7 +436,7 @@ public class JobsAdminUserWebRequestBean extends BaseJobsBean implements JobsAdm
 		final User updatedUser = this.userBean.updateUserData(this.getUser());
 
 		// Fire event
-		this.updatedUserDataEvent.fire(new AdminUpdatedUserDataEvent(updatedUser));
+		this.updatedUserDataEvent.fire(new AdminPostUserDataUpdatedEvent(updatedUser));
 	}
 
 	/**
diff --git a/src/java/org/mxchange/jjobs/beans/user/JobsUserWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/user/JobsUserWebRequestBean.java
index 9a082abb..0269e0f2 100644
--- a/src/java/org/mxchange/jjobs/beans/user/JobsUserWebRequestBean.java
+++ b/src/java/org/mxchange/jjobs/beans/user/JobsUserWebRequestBean.java
@@ -16,39 +16,9 @@
  */
 package org.mxchange.jjobs.beans.user;
 
-import java.text.MessageFormat;
-import java.util.Objects;
-import javax.ejb.EJB;
 import javax.enterprise.context.RequestScoped;
-import javax.enterprise.event.Event;
-import javax.enterprise.event.Observes;
-import javax.enterprise.inject.Any;
-import javax.faces.context.FacesContext;
-import javax.faces.view.facelets.FaceletException;
-import javax.inject.Inject;
 import javax.inject.Named;
-import org.mxchange.jcontacts.model.contact.Contact;
-import org.mxchange.jcoreee.events.locale.ObservableLocaleChangeEvent;
 import org.mxchange.jjobs.beans.BaseJobsBean;
-import org.mxchange.jjobs.beans.contact.JobsContactWebRequestController;
-import org.mxchange.jjobs.beans.features.JobsFeaturesWebApplicationController;
-import org.mxchange.jjobs.beans.user.login.JobsUserLoginWebSessionController;
-import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
-import org.mxchange.jusercore.events.user.clear.password.ObservableClearUserPasswordEvent;
-import org.mxchange.jusercore.events.user.clear.username.ObservableClearUserNameEvent;
-import org.mxchange.jusercore.events.user.created.ObservableCreatedUserEvent;
-import org.mxchange.jusercore.events.user.linked.ObservableAdminLinkedUserEvent;
-import org.mxchange.jusercore.events.user.update.ObservableUpdatedUserPersonalDataEvent;
-import org.mxchange.jusercore.events.user.update.UpdatedUserPersonalDataEvent;
-import org.mxchange.jusercore.model.user.LoginUser;
-import org.mxchange.jusercore.model.user.User;
-import org.mxchange.jusercore.model.user.UserSessionBeanRemote;
-import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
-import org.mxchange.juserlogincore.events.login.ObservableUserLoggedInEvent;
-import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent;
-import org.mxchange.juserlogincore.events.user.password_change.ObservableUpdatedUserPasswordEvent;
-import org.mxchange.juserlogincore.exceptions.UserPasswordMismatchException;
-import org.mxchange.juserlogincore.login.UserLoginUtils;
 
 /**
  * A user controller (bean)
@@ -64,68 +34,6 @@ public class JobsUserWebRequestBean extends BaseJobsBean implements JobsUserWebR
 	 */
 	private static final long serialVersionUID = 542_145_347_916L;
 
-	/**
-	 * General contact controller
-	 */
-	@Inject
-	private JobsContactWebRequestController contactController;
-
-	/**
-	 * Features controller
-	 */
-	@Inject
-	private JobsFeaturesWebApplicationController featureController;
-
-	/**
-	 * Localization controller
-	 */
-	@Inject
-	private JobsLocalizationSessionController localizationController;
-
-	/**
-	 * Event being fired when user updated personal data
-	 */
-	@Inject
-	@Any
-	private Event<ObservableUpdatedUserPersonalDataEvent> updatedPersonalDataEvent;
-
-	/**
-	 * Remote user bean
-	 */
-	@EJB (lookup = "java:global/jjobs-ejb/user!org.mxchange.jusercore.model.user.UserSessionBeanRemote")
-	private UserSessionBeanRemote userBean;
-
-	/**
-	 * User id
-	 */
-	private Long userId;
-
-	/**
-	 * Login controller (bean)
-	 */
-	@Inject
-	private JobsUserLoginWebSessionController userLoginController;
-
-	/**
-	 * User name
-	 */
-	private String userName;
-
-	/**
-	 * User password (clear-text from web form)
-	 */
-	private String userPassword;
-
-	/**
-	 * User password repeated (clear-text from web form)
-	 */
-	private String userPasswordRepeat;
-
-	/**
-	 * Whether the user wants a public profile
-	 */
-	private ProfileMode userProfileMode;
-
 	/**
 	 * Default constructor
 	 */
@@ -134,483 +42,4 @@ public class JobsUserWebRequestBean extends BaseJobsBean implements JobsUserWebR
 		super();
 	}
 
-	/**
-	 * Event observer for newly added users by administrator
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getAddedUser() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.addedUser is null"); //NOI18N
-		} else if (event.getAddedUser().getUserId() == null) {
-			// userId is null
-			throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
-		} else if (event.getAddedUser().getUserId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
-		}
-
-		// Set user id again
-		this.setUserId(event.getAddedUser().getUserId());
-	}
-
-	/**
-	 * Event observer for linked users with existing contact data
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterAdminLinkedUserEvent (@Observes final ObservableAdminLinkedUserEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getLinkedUser() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.linkedUser is null"); //NOI18N
-		} else if (event.getLinkedUser().getUserId() == null) {
-			// userId is null
-			throw new NullPointerException("event.linkedUser.userId is null"); //NOI18N
-		} else if (event.getLinkedUser().getUserId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLinkedUser(), event.getLinkedUser().getUserId())); //NOI18N
-		}
-
-		// Set user id again
-		this.setUserId(event.getLinkedUser().getUserId());
-	}
-
-	/**
-	 * Event observer for when a bean helper has successfully created a user
-	 * instance, means the user exists. If the user does not exist, this event
-	 * should not fire but instead a proper exception must be thrown.
-	 * <p>
-	 * @param event User created event
-	 */
-	public void afterCreatedUserEvent (@Observes final ObservableCreatedUserEvent event) {
-		// Is the instance valid?
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getCreatedUser() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.createdUser is null"); //NOI18N
-		} else if (event.getCreatedUser().getUserId() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.createdUser.userId is null"); //NOI18N
-		} else if (event.getCreatedUser().getUserId() < 1) {
-			// Throw NPE again
-			throw new NullPointerException(MessageFormat.format("event.createdUser.userId={0} is not valid", event.getCreatedUser().getUserId())); //NOI18N
-		}
-
-		// Get user instance
-		final User user = event.getCreatedUser();
-
-		// Set all fields here
-		this.copyUser(user);
-	}
-
-	/**
-	 * Event observer for logged-in user
-	 * <p>
-	 * @param event Event instance
-	 */
-	public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getLoggedInUser() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.registeredUser is null"); //NOI18N
-		} else if (event.getLoggedInUser().getUserId() == null) {
-			// userId is null
-			throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
-		} else if (event.getLoggedInUser().getUserId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
-		}
-
-		// "Cache" user instance
-		final User loggedInUser = event.getLoggedInUser();
-
-		// Copy all data to this bean
-		this.copyUser(loggedInUser);
-	}
-
-	/**
-	 * Event observer for user password changes
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void afterUserPasswordChangedEvent (@Observes final ObservableUpdatedUserPasswordEvent event) {
-		// Is it valid?
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getUserPassword() == null) {
-			// Throw NPE
-			throw new NullPointerException("event.userPassword is null"); //NOI18N
-		} else if (event.getUserPassword().isEmpty()) {
-			// Throw NPE
-			throw new IllegalArgumentException("event.userPassword is empty"); //NOI18N
-		}
-
-		// Set it here
-		this.setUserPassword(event.getUserPassword());
-		this.setUserPasswordRepeat(event.getUserPassword());
-	}
-
-	/**
-	 * Event observer for new user registrations
-	 * <p>
-	 * @param event User registration event
-	 */
-	public void afterUserRegistrationEvent (@Observes final ObservableUserRegisteredEvent event) {
-		// Event and contained entity instance should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getRegisteredUser() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.registeredUser is null"); //NOI18N
-		} else if (event.getRegisteredUser().getUserId() == null) {
-			// userId is null
-			throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
-		} else if (event.getRegisteredUser().getUserId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getRegisteredUser(), event.getRegisteredUser().getUserId())); //NOI18N
-		}
-
-		// Get user instance
-		final User registeredUser = event.getRegisteredUser();
-
-		// Copy all data from registered->user
-		this.copyUser(registeredUser);
-
-		// Set user id again
-		this.setUserId(registeredUser.getUserId());
-	}
-
-	/**
-	 * Event observer for when a user name should be cleared
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void clearUserNameEvent (@Observes final ObservableClearUserNameEvent event) {
-		// Is it valid?
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		}
-
-		// Clear it
-		this.clearUserName();
-	}
-
-	/**
-	 * Event observer for when both user passwords should be cleared
-	 * <p>
-	 * @param event Event being fired
-	 */
-	public void clearUserPasswordEvent (@Observes final ObservableClearUserPasswordEvent event) {
-		// Is it valid?
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		}
-
-		// Clear it
-		this.clearUserPasswords();
-	}
-
-	@Override
-	public User createUserInstance (final boolean createContactData) {
-		// Required personal data must be set
-		assert (this.isRequiredPersonalDataSet()) : "not all personal data is set"; //NOI18N
-
-		// Is user name required?
-		if (!this.isUserNameRequired()) {
-			// Generate pseudo-random user name
-			// @TODO Refacture this to avoid EJB call
-			final String randomName = this.userBean.generateRandomUserName();
-
-			// Set it and inivisible profile
-			this.setUserName(randomName);
-			this.setUserProfileMode(ProfileMode.INVISIBLE);
-
-			// Generate random password
-			final String randomPassword = UserLoginUtils.createRandomPassword(JobsUserWebRequestController.MINIMUM_PASSWORD_LENGTH);
-
-			// Set random password
-			this.setUserPassword(randomPassword);
-			this.setUserPasswordRepeat(randomPassword);
-		}
-
-		// Create new user instance
-		final User user = new LoginUser();
-
-		// Set user name profile mode and locale
-		user.setUserName(this.getUserName());
-		user.setUserProfileMode(this.getUserProfileMode());
-		user.setUserLocale(this.localizationController.getLocale());
-
-		// Is multiple registration page
-		if ((createContactData) || (!this.featureController.isFeatureEnabled("user_register_multiple_page"))) { //NOI18N
-			// Create contact instance
-			final Contact contact = this.contactController.createContactInstance();
-
-			// Set contact in user
-			user.setUserContact(contact);
-		}
-
-		// Return it
-		return user;
-	}
-
-	@Override
-	public User createUserLogin () {
-		// Is all data set?
-		if (this.getUserName() == null) {
-			// Throw NPE
-			throw new NullPointerException("userName is null"); //NOI18N
-		} else if (this.getUserName().isEmpty()) {
-			// Is empty
-			throw new IllegalStateException("userName is empty."); //NOI18N
-		}
-
-		// Create new user instance
-		final User user = new LoginUser();
-
-		// Update all data ...
-		user.setUserName(this.getUserName());
-
-		// Return the new instance
-		return user;
-	}
-
-	@Override
-	public String doChangePersonalData () {
-		// This method shall only be called if the user is logged-in
-		if (!this.userLoginController.isUserLoggedIn()) {
-			// Not logged-in
-			throw new IllegalStateException("User is not logged-in"); //NOI18N
-		} else if (!this.isRequiredChangePersonalDataSet()) {
-			// Not all required fields are set
-			throw new FaceletException("Not all required fields are set."); //NOI18N
-		} else if (!this.userLoginController.ifCurrentPasswordMatches()) {
-			// Password not matching
-			throw new FaceletException(new UserPasswordMismatchException(this.userLoginController.getLoggedInUser()));
-		} else if (!this.featureController.isFeatureEnabled("change_user_personal_data")) { //NOI18N
-			// Editing is not allowed
-			throw new IllegalStateException("User tried to edit personal data."); //NOI18N
-		}
-
-		// Get user instance
-		final User user = this.userLoginController.getLoggedInUser();
-
-		// Copy contact data to contact instance
-		this.contactController.updateContactDataFromController(user.getUserContact());
-
-		// It should be there, so run some tests on it
-		assert (user instanceof User) : "Instance userLoginController.loggedInUser is null"; //NOI18N
-		assert (user.getUserId() instanceof Long) : "Instance userLoginController.loggedInUser.userId is null"; //NOI18N
-		assert (user.getUserId() > 0) : MessageFormat.format("userLoginController.loggedInUser.userId={0} is invalid", user.getUserId()); //NOI18N
-		assert (user.getUserContact() instanceof Contact) : "Instance userLoginController.loggedInUser.userContact is null"; //NOI18N
-		assert (user.getUserContact().getContactId() instanceof Long) : "Instance userLoginController.userContact.contactId is null"; //NOI18N
-		assert (user.getUserContact().getContactId() > 0) : MessageFormat.format("Instance userLoginController.userContact.contactId={0} is invalid", user.getUserContact().getContactId()); //NOI18N
-
-		// Update all fields
-		user.setUserProfileMode(this.getUserProfileMode());
-
-		// Send it to the EJB
-		final User updatedUser = this.userBean.updateUserPersonalData(user);
-
-		// Fire event
-		this.updatedPersonalDataEvent.fire(new UpdatedUserPersonalDataEvent(updatedUser));
-
-		// All fine
-		return "user_contact_data_saved"; //NOI18N
-	}
-
-	/**
-	 * Getter for user id
-	 * <p>
-	 * @return User id
-	 */
-	public Long getUserId () {
-		return this.userId;
-	}
-
-	/**
-	 * Setter for user id
-	 * <p>
-	 * @param userId User id
-	 */
-	public void setUserId (final Long userId) {
-		this.userId = userId;
-	}
-
-	/**
-	 * Getter for user name
-	 * <p>
-	 * @return User name
-	 */
-	public String getUserName () {
-		return this.userName;
-	}
-
-	/**
-	 * Setter for user name
-	 * <p>
-	 * @param userName User name
-	 */
-	public void setUserName (final String userName) {
-		this.userName = userName;
-	}
-
-	@Override
-	public String getUserPassword () {
-		return this.userPassword;
-	}
-
-	/**
-	 * Setter for clear-text user password
-	 * <p>
-	 * @param userPassword Clear-text user password
-	 */
-	public void setUserPassword (final String userPassword) {
-		this.userPassword = userPassword;
-	}
-
-	/**
-	 * Getter for clear-text user password repeated
-	 * <p>
-	 * @return Clear-text user password repeated
-	 */
-	public String getUserPasswordRepeat () {
-		return this.userPasswordRepeat;
-	}
-
-	/**
-	 * Setter for clear-text user password repeated
-	 * <p>
-	 * @param userPasswordRepeat Clear-text user password repeated
-	 */
-	public void setUserPasswordRepeat (final String userPasswordRepeat) {
-		this.userPasswordRepeat = userPasswordRepeat;
-	}
-
-	/**
-	 * Getter for user profile mode
-	 * <p>
-	 * @return User profile mode
-	 */
-	public ProfileMode getUserProfileMode () {
-		return this.userProfileMode;
-	}
-
-	/**
-	 * Setter for user profile mode
-	 * <p>
-	 * @param userProfileMode User profile mode
-	 */
-	public void setUserProfileMode (final ProfileMode userProfileMode) {
-		this.userProfileMode = userProfileMode;
-	}
-
-	@Override
-	public boolean ifBothPasswordsEmptyAllowed () {
-		// Check feature first
-		return ((this.featureController.isFeatureEnabled("allow_user_registration_empty_password")) && //NOI18N
-				((this.getUserPassword() == null) || (this.getUserPassword().isEmpty())) &&
-				((this.getUserPasswordRepeat() == null) || (this.getUserPasswordRepeat().isEmpty())));
-	}
-
-	@Override
-	public boolean isRequiredChangePersonalDataSet () {
-		return ((this.getUserProfileMode() != null) &&
-				(this.getUserName() != null) && (!this.getUserName().isEmpty()) &&
-				(this.contactController.isRequiredChangePersonalDataSet()));
-	}
-
-	@Override
-	public boolean isRequiredPersonalDataSet () {
-		if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N
-			// Multiple registration page
-			return this.contactController.isRequiredPersonalDataSet();
-		} else {
-			// Single registration page
-			return (((this.getUserName() != null) || (!this.isUserNameRequired())) &&
-					(this.getUserProfileMode() != null) &&
-					(this.contactController.isRequiredPersonalDataSet()) &&
-					(this.getUserPassword() != null) &&
-					(this.getUserPasswordRepeat() != null));
-		}
-	}
-
-	@Override
-	public boolean isSamePasswordEntered () {
-		return ((!this.getUserPassword().isEmpty()) && (Objects.equals(this.getUserPassword(), this.getUserPasswordRepeat())));
-	}
-
-	@Override
-	public boolean isUserIdEmpty () {
-		return ((this.getUserId() == null) || (this.getUserId() == 0));
-	}
-
-	@Override
-	public boolean isUserNameRequired () {
-		// Get context parameter
-		final String contextParameter = FacesContext.getCurrentInstance().getExternalContext().getInitParameter("is_user_login_require_user_name"); //NOI18N
-
-		// Is it set?
-		final boolean isRequired = ((contextParameter instanceof String) && (contextParameter.toLowerCase().equals("true"))); //NOI18N
-
-		// Return value
-		return isRequired;
-	}
-
-	/**
-	 * Clears user name
-	 */
-	private void clearUserName () {
-		// Clear it
-		this.setUserName(null);
-	}
-
-	/**
-	 * Clears both user passwords
-	 */
-	private void clearUserPasswords () {
-		// Clear both
-		this.setUserPassword(null);
-		this.setUserPasswordRepeat(null);
-	}
-
-	/**
-	 * Copies given user into the controller
-	 * <p>
-	 * @param user User instance
-	 */
-	private void copyUser (final User user) {
-		// Make sure the instance is valid
-		if (null == user) {
-			// Throw NPE
-			throw new NullPointerException("user is null"); //NOI18N
-		} else if (user.getUserContact() == null) {
-			// Throw again ...
-			throw new NullPointerException("user.userContact is null"); //NOI18N
-		}
-
-		// Copy all fields:
-		// - base data
-		this.setUserId(user.getUserId());
-		this.setUserProfileMode(user.getUserProfileMode());
-	}
-
 }
diff --git a/src/java/org/mxchange/jjobs/beans/user/JobsUserWebRequestController.java b/src/java/org/mxchange/jjobs/beans/user/JobsUserWebRequestController.java
index d68fd421..894ca4d7 100644
--- a/src/java/org/mxchange/jjobs/beans/user/JobsUserWebRequestController.java
+++ b/src/java/org/mxchange/jjobs/beans/user/JobsUserWebRequestController.java
@@ -17,7 +17,6 @@
 package org.mxchange.jjobs.beans.user;
 
 import java.io.Serializable;
-import org.mxchange.jusercore.model.user.User;
 
 /**
  * An interface for user beans
@@ -34,81 +33,4 @@ public interface JobsUserWebRequestController extends Serializable {
 	@Deprecated
 	public static final Integer MINIMUM_PASSWORD_LENGTH = 5;
 
-	/**
-	 * Getter for clear-text user password
-	 * <p>
-	 * @return Clear-text user password
-	 */
-	String getUserPassword ();
-
-	/**
-	 * Checks if both user passwords are left empty and if this is enabled
-	 * (allowed) in context parameter. If true, the calling bean should create a
-	 * random password (preferable with UserUtils.createRandomPassword() and set
-	 * it in both user password fields.
-	 * <p>
-	 * @return Whether empty passwords are allowed
-	 */
-	boolean ifBothPasswordsEmptyAllowed ();
-
-	/**
-	 * Creates an instance from all properties
-	 * <p>
-	 * @param createContactData Whether contact data should be created
-	 * <p>
-	 * @return A user instance
-	 */
-	User createUserInstance (final boolean createContactData);
-
-	/**
-	 * Creates a user instance for login phase
-	 * <p>
-	 * @return User instance
-	 */
-	User createUserLogin ();
-
-	/**
-	 * Checks whether all required personal data is set
-	 * <p>
-	 * @return Whether the required personal data is set
-	 */
-	boolean isRequiredPersonalDataSet ();
-
-	/**
-	 * Checks whether all required personal data is set for changing them
-	 * <p>
-	 * @return Whether the required personal data is set
-	 */
-	boolean isRequiredChangePersonalDataSet ();
-
-	/**
-	 * Checks whether same passwords has been entered
-	 * <p>
-	 * @return Whether same passwords has been entered
-	 */
-	boolean isSamePasswordEntered ();
-
-	/**
-	 * Checks if the user id is empty
-	 * <p>
-	 * @return Whether the user id is empty
-	 */
-	boolean isUserIdEmpty ();
-
-	/**
-	 * Changes logged-in user's personal data if the current password matches
-	 * and TAC + privacy statement has been accepted.
-	 * <p>
-	 * @return New target page
-	 */
-	String doChangePersonalData ();
-
-	/**
-	 * Checks whether this application requires a user name to be entered.
-	 * Otherwise a random name like "userXXXXX" is generated
-	 * <p>
-	 * @return Whether this application requires a user name
-	 */
-	boolean isUserNameRequired ();
-
 }
diff --git a/src/java/org/mxchange/jjobs/beans/user/activity/JobsUserActivityWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/user/activity/JobsUserActivityWebRequestBean.java
index a5032306..16a96a1e 100644
--- a/src/java/org/mxchange/jjobs/beans/user/activity/JobsUserActivityWebRequestBean.java
+++ b/src/java/org/mxchange/jjobs/beans/user/activity/JobsUserActivityWebRequestBean.java
@@ -36,8 +36,6 @@ import org.mxchange.jusercore.events.user.delete.ObservableAdminDeletedUserEvent
 import org.mxchange.jusercore.events.user.linked.ObservableAdminLinkedUserEvent;
 import org.mxchange.jusercore.events.user.locked.ObservableAdminLockedUserEvent;
 import org.mxchange.jusercore.events.user.unlocked.ObservableAdminUnlockedUserEvent;
-import org.mxchange.jusercore.events.user.update.ObservableAdminUpdatedUserDataEvent;
-import org.mxchange.jusercore.events.user.update.ObservableUpdatedUserPersonalDataEvent;
 import org.mxchange.jusercore.model.user.User;
 import org.mxchange.jusercore.model.user.activity.LogableUserActivity;
 import org.mxchange.jusercore.model.user.activity.UserActivityLog;
@@ -49,6 +47,8 @@ import org.mxchange.juserlogincore.events.logout.ObservableUserLogoutEvent;
 import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent;
 import org.mxchange.juserlogincore.events.resendlink.ObservableUserResendLinkAccountEvent;
 import org.mxchange.juserlogincore.events.user.password_change.ObservableUpdatedUserPasswordEvent;
+import org.mxchange.jusercore.events.user.update.post.ObservableAdminPostUserDataUpdatedEvent;
+import org.mxchange.jusercore.events.user.update.post.ObservablePostUserPersonalDataUpdatedEvent;
 
 /**
  * A controller (bean) for user activity log
@@ -221,7 +221,7 @@ public class JobsUserActivityWebRequestBean extends BaseJobsBean implements Jobs
 	 * <p>
 	 * @param event Event being updated
 	 */
-	public void afterAdminUpdatedUserDataEvent (@Observes final ObservableAdminUpdatedUserDataEvent event) {
+	public void afterAdminUpdatedUserDataEvent (@Observes final ObservableAdminPostUserDataUpdatedEvent event) {
 		// Event and contained entity instance should not be null
 		if (null == event) {
 			// Throw NPE
@@ -424,7 +424,7 @@ public class JobsUserActivityWebRequestBean extends BaseJobsBean implements Jobs
 	 * <p>
 	 * @param event Event being fired
 	 */
-	public void afterUserUpdatedPersonalDataEvent (@Observes final ObservableUpdatedUserPersonalDataEvent event) {
+	public void afterUserUpdatedPersonalDataEvent (@Observes final ObservablePostUserPersonalDataUpdatedEvent event) {
 		// Check parameter
 		if (null == event) {
 			// Throw NPE
diff --git a/src/java/org/mxchange/jjobs/beans/user/email_address/JobsEmailChangeWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/user/email_address/JobsEmailChangeWebRequestBean.java
index 9f689a6a..31f1998b 100644
--- a/src/java/org/mxchange/jjobs/beans/user/email_address/JobsEmailChangeWebRequestBean.java
+++ b/src/java/org/mxchange/jjobs/beans/user/email_address/JobsEmailChangeWebRequestBean.java
@@ -16,11 +16,8 @@
  */
 package org.mxchange.jjobs.beans.user.email_address;
 
-import fish.payara.cdi.jsr107.impl.NamedCache;
 import java.text.MessageFormat;
 import java.util.Objects;
-import javax.annotation.PostConstruct;
-import javax.cache.Cache;
 import javax.ejb.EJB;
 import javax.enterprise.context.RequestScoped;
 import javax.faces.application.FacesMessage;
@@ -69,17 +66,16 @@ public class JobsEmailChangeWebRequestBean extends BaseJobsBean implements JobsE
 	private UserEmailChangeSessionBeanRemote emailChangeBean;
 
 	/**
-	 * Features controller
+	 * Controller for listing email address changes
 	 */
 	@Inject
-	private JobsFeaturesWebApplicationController featureController;
+	private FinancialsEmailChangeListWebViewController emailChangeListController;
 
 	/**
-	 * Local list of already queued email addresses
+	 * Features controller
 	 */
 	@Inject
-	@NamedCache (cacheName = "queuedEmailCache")
-	private Cache<String, Boolean> queuedEmailCache;
+	private FinancialsFeaturesWebApplicationController featureController;
 
 	/**
 	 * Login controller (bean)
@@ -133,7 +129,7 @@ public class JobsEmailChangeWebRequestBean extends BaseJobsBean implements JobsE
 		assert (user.getUserContact().getContactId() > 0) : MessageFormat.format("Instance userLoginController.userContact.contactId={0} is invalid", user.getUserContact().getContactId()); //NOI18N
 
 		// Check if the email address is already enqueued
-		if (this.isEmailAddressQueued(this.getEmailAddress())) {
+		if (this.emailChangeListController.isEmailAddressQueued(this.getEmailAddress())) {
 			// Clear both email addresses
 			this.setEmailAddress(null);
 			this.setEmailAddressRepeat(null);
@@ -195,21 +191,6 @@ public class JobsEmailChangeWebRequestBean extends BaseJobsBean implements JobsE
 		this.emailAddressRepeat = emailAddressRepeat;
 	}
 
-	/**
-	 * Post-construction
-	 */
-	@PostConstruct
-	public void init () {
-		// Is cache there?
-		if (!this.queuedEmailCache.iterator().hasNext()) {
-			// Add all
-			for (final String currentEmailAddress : this.emailChangeBean.allQueuedAddresses()) {
-				// Add it to cache
-				this.queuedEmailCache.put(currentEmailAddress, Boolean.TRUE);
-			}
-		}
-	}
-
 	@Override
 	public boolean isRequiredChangeEmailAddressSet () {
 		return ((this.getEmailAddress() != null) &&
@@ -225,37 +206,4 @@ public class JobsEmailChangeWebRequestBean extends BaseJobsBean implements JobsE
 		this.setEmailAddressRepeat(null);
 	}
 
-	/**
-	 * Checks if given email address has already been queued. First a local list
-	 * is being checked, if not found, the EJB is called. Only if found, the
-	 * result is "cached" in the list.
-	 * <p>
-	 * @param emailAddress Email address to verify
-	 * <p>
-	 * @return Whether the email address in field emailAddress is already queued
-	 */
-	private boolean isEmailAddressQueued (final String emailAddress) {
-		// It should be there
-		assert (emailAddress != null) : "emailAddress should not be null"; //NOI18N
-		assert (!emailAddress.trim().isEmpty()) : "emailAddress should not be empty"; //NOI18N
-
-		// Check list
-		if (this.queuedEmailCache.containsKey(emailAddress)) {
-			// Okay, found it
-			return true;
-		}
-
-		// Check EJB
-		final boolean isQueued = this.emailChangeBean.isEmailAddressEnqueued(emailAddress);
-
-		// Is it there?
-		if (isQueued) {
-			// Add to list
-			this.queuedEmailCache.put(emailAddress, Boolean.TRUE);
-		}
-
-		// Return status
-		return isQueued;
-	}
-
 }
diff --git a/src/java/org/mxchange/jjobs/beans/user/login/JobsUserLoginWebSessionBean.java b/src/java/org/mxchange/jjobs/beans/user/login/JobsUserLoginWebSessionBean.java
index adf2e69b..09aae448 100644
--- a/src/java/org/mxchange/jjobs/beans/user/login/JobsUserLoginWebSessionBean.java
+++ b/src/java/org/mxchange/jjobs/beans/user/login/JobsUserLoginWebSessionBean.java
@@ -45,10 +45,9 @@ import org.mxchange.juserlogincore.events.login.ObservableUserLoggedInEvent;
 import org.mxchange.juserlogincore.events.login.UserLoggedInEvent;
 import org.mxchange.juserlogincore.events.logout.ObservableUserLogoutEvent;
 import org.mxchange.juserlogincore.events.logout.UserLogoutEvent;
+import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent;
 import org.mxchange.juserlogincore.events.user.password_change.ObservableUpdatedUserPasswordEvent;
-import org.mxchange.juserlogincore.exceptions.UserPasswordMismatchException;
 import org.mxchange.juserlogincore.login.UserLoginUtils;
-import org.mxchange.juserlogincore.model.user.login.UserLoginSessionBeanRemote;
 
 /**
  * A web bean for user registration
@@ -97,15 +96,20 @@ public class JobsUserLoginWebSessionBean extends BaseJobsBean implements JobsUse
 	private String userCurrentPassword;
 
 	/**
-	 * Flag whether the user has logged-in, set only from inside
+	 * User id
 	 */
-	private boolean userLoggedIn;
+	private Long userId;
+
+	/**
+	 * Administrative user-list controller
+	 */
+	@Inject
+	private FinancialsUserListWebViewController userListController;
 
 	/**
-	 * Remote register session-scoped bean
+	 * Flag whether the user has logged-in, set only from inside
 	 */
-	@EJB (lookup = "java:global/jjobs-ejb/userLogin!org.mxchange.juserlogincore.model.user.login.UserLoginSessionBeanRemote")
-	private UserLoginSessionBeanRemote userLoginBean;
+	private boolean userLoggedIn;
 
 	/**
 	 * Event fired when user has logged in
@@ -121,6 +125,16 @@ public class JobsUserLoginWebSessionBean extends BaseJobsBean implements JobsUse
 	@Any
 	private Event<ObservableUserLogoutEvent> userLogoutEvent;
 
+	/**
+	 * User name
+	 */
+	private String userName;
+
+	/**
+	 * User password (clear-text from web form)
+	 */
+	private String userPassword;
+
 	/**
 	 * User's password history
 	 */
@@ -132,6 +146,11 @@ public class JobsUserLoginWebSessionBean extends BaseJobsBean implements JobsUse
 	@EJB (lookup = "java:global/jjobs-ejb/userPasswordHistory!org.mxchange.jusercore.model.user.password_history.UserPasswordHistorySessionBeanRemote")
 	private UserPasswordHistorySessionBeanRemote userPasswordHistoryBean;
 
+	/**
+	 * Whether the user wants a public profile
+	 */
+	private ProfileMode userProfileMode;
+
 	/**
 	 * Default constructor
 	 */
@@ -144,31 +163,167 @@ public class JobsUserLoginWebSessionBean extends BaseJobsBean implements JobsUse
 	}
 
 	/**
-	 * Method being call after user's password has been updated (and history
-	 * entry has been created).
+	 * Event observer for newly added users by administrator
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getAddedUser() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.addedUser is null"); //NOI18N
+		} else if (event.getAddedUser().getUserId() == null) {
+			// userId is null
+			throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
+		} else if (event.getAddedUser().getUserId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
+		}
+
+		// Set user id again
+		this.setUserId(event.getAddedUser().getUserId());
+	}
+
+	/**
+	 * Event observer for linked users with existing contact data
 	 * <p>
-	 * @param event Event being observed
+	 * @param event Event being fired
 	 */
-	public void afterUserUpdatedPasswordEvent (@Observes final ObservableUpdatedUserPasswordEvent event) {
-		// Check parameter
+	public void afterAdminLinkedUserEvent (@Observes final ObservableAdminLinkedUserEvent event) {
+		// Event and contained entity instance should not be null
 		if (null == event) {
 			// Throw NPE
 			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getPasswordHistory() == null) {
+		} else if (event.getLinkedUser() == null) {
 			// Throw NPE again
-			throw new NullPointerException("event.passwordHistory is null"); //NOI18N
-		} else if (event.getPasswordHistory().getUserPasswordHistoryId() == null) {
-			// ... and again
-			throw new NullPointerException("event.passwordHistory.userPasswordHistoryId is null"); //NOI18N
-		} else if (event.getPasswordHistory().getUserPasswordHistoryId() < 1) {
-			// Invalid value
-			throw new IllegalArgumentException(MessageFormat.format("event.passwordHistory.userPasswordHistoryId={0} is in valid", event.getPasswordHistory().getUserPasswordHistoryId())); //NOI18N
+			throw new NullPointerException("event.linkedUser is null"); //NOI18N
+		} else if (event.getLinkedUser().getUserId() == null) {
+			// userId is null
+			throw new NullPointerException("event.linkedUser.userId is null"); //NOI18N
+		} else if (event.getLinkedUser().getUserId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLinkedUser(), event.getLinkedUser().getUserId())); //NOI18N
 		}
 
-		// All fine, so update list
+		// Set user id again
+		this.setUserId(event.getLinkedUser().getUserId());
+	}
+
+	/**
+	 * Event observer for when a bean helper has successfully created a user
+	 * instance, means the user exists. If the user does not exist, this event
+	 * should not fire but instead a proper exception must be thrown.
+	 * <p>
+	 * @param event User created event
+	 */
+	public void afterCreatedUserEvent (@Observes final ObservableCreatedUserEvent event) {
+		// Is the instance valid?
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getCreatedUser() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.createdUser is null"); //NOI18N
+		} else if (event.getCreatedUser().getUserId() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.createdUser.userId is null"); //NOI18N
+		} else if (event.getCreatedUser().getUserId() < 1) {
+			// Throw NPE again
+			throw new NullPointerException(MessageFormat.format("event.createdUser.userId={0} is not valid", event.getCreatedUser().getUserId())); //NOI18N
+		}
+
+		// Get user instance
+		final User user = event.getCreatedUser();
+
+		// Set all fields here
+		this.copyUser(user);
+	}
+
+	/**
+	 * Event observer for logged-in user
+	 * <p>
+	 * @param event Event instance
+	 */
+	public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getLoggedInUser() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.registeredUser is null"); //NOI18N
+		} else if (event.getLoggedInUser().getUserId() == null) {
+			// userId is null
+			throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
+		} else if (event.getLoggedInUser().getUserId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
+		}
+
+		// "Cache" user instance
+		final User user = event.getLoggedInUser();
+
+		// Copy all data to this bean
+		this.copyUser(user);
+	}
+
+	/**
+	 * Event observer for user password changes
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterUserPasswordChangedEvent (@Observes final ObservableUpdatedUserPasswordEvent event) {
+		// Is it valid?
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUserPassword() == null) {
+			// Throw NPE
+			throw new NullPointerException("event.userPassword is null"); //NOI18N
+		} else if (event.getUserPassword().isEmpty()) {
+			// Throw NPE
+			throw new IllegalArgumentException("event.userPassword is empty"); //NOI18N
+		}
+
+		// Set it here
+		this.setUserPassword(event.getUserPassword());
 		this.updatePasswordHistory(event.getPasswordHistory());
 	}
 
+	/**
+	 * Event observer for new user registrations
+	 * <p>
+	 * @param event User registration event
+	 */
+	public void afterUserRegistrationEvent (@Observes final ObservableUserRegisteredEvent event) {
+		// Event and contained entity instance should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getRegisteredUser() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.registeredUser is null"); //NOI18N
+		} else if (event.getRegisteredUser().getUserId() == null) {
+			// userId is null
+			throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
+		} else if (event.getRegisteredUser().getUserId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getRegisteredUser(), event.getRegisteredUser().getUserId())); //NOI18N
+		}
+
+		// Get user instance
+		final User registeredUser = event.getRegisteredUser();
+
+		// Copy all data from registered->user
+		this.copyUser(registeredUser);
+
+		// Set user id again
+		this.setUserId(registeredUser.getUserId());
+	}
+
 	/**
 	 * Logout for administrator area. If a logged-in user instance exists, it is
 	 * being logged-out, too.
@@ -198,48 +353,52 @@ public class JobsUserLoginWebSessionBean extends BaseJobsBean implements JobsUse
 	 * @return Redirect target
 	 */
 	public String doUserLogin () {
-		// Get user instance
-		final User user = this.userController.createUserLogin();
-
-		// Create login container
-		final LoginContainer loginContainer = new UserLoginContainer(user, this.userController.getUserPassword());
-
-		try {
-			// Call bean
-			final User confirmedUser = this.userLoginBean.validateUserAccountStatus(loginContainer);
-
-			// All fine here so set it here
-			this.setLoggedInUser(confirmedUser);
-
-			// Retrieve user's password list
-			this.userPasswordHistory = this.userPasswordHistoryBean.getUserPasswordHistory(confirmedUser);
-
-			// Set template to "login"
-			this.setBaseTemplatePathName(USER_BASE_TEMPLATE_NAME); //NOI18N
-
-			// Fire event away. Keep this last before return statement.
-			this.userLoginEvent.fire(new UserLoggedInEvent(confirmedUser));
-
-			// Clear this bean
-			this.clear();
+		// Found user instance
+		User updatedUser = null;
+
+		// Iterate over all users
+		for (final User currentUser : this.userListController.getAllUsers()) {
+			// Is the user name matching?
+			if (currentUser.getUserName().equals(this.getUserName())) {
+				// Yes, same user, then set it and stop iteration
+				updatedUser = currentUser;
+				break;
+			}
+		}
 
-			// All fine
-			return "login_user"; //NOI18N
-		} catch (final UserNotFoundException ex) {
+		if (null == updatedUser) {
 			// Show JSF message
 			this.showFacesMessage("form_user_login:userName", "ERROR_USER_NOT_FOUND", FacesMessage.SEVERITY_ERROR); //NOI18N
 			return ""; //NOI18N
-		} catch (final UserStatusLockedException ex) {
+		} else if (updatedUser.getUserAccountStatus().equals(UserAccountStatus.LOCKED)) {
 			this.showFacesMessage("form_user_login:userName", "ERROR_USER_STATUS_LOCKED", FacesMessage.SEVERITY_WARN); //NOI18N
 			return ""; //NOI18N
-		} catch (final UserStatusUnconfirmedException ex) {
+		} else if (updatedUser.getUserAccountStatus().equals(UserAccountStatus.UNCONFIRMED)) {
 			this.showFacesMessage("form_user_login:userName", "ERROR_USER_STATUS_UNCONFIRMED", FacesMessage.SEVERITY_INFO); //NOI18N
 			return ""; //NOI18N
-		} catch (final UserPasswordMismatchException ex) {
+		} else if (!UserLoginUtils.ifPasswordMatches(this.getUserPassword(), updatedUser)) {
 			// Show JSF message
 			this.showFacesMessage("form_user_login:userPassword", "ERROR_USER_PASSWORD_MISMATCH", FacesMessage.SEVERITY_WARN); //NOI18N
 			return ""; //NOI18N
 		}
+
+		// All fine here so set it here
+		this.setLoggedInUser(updatedUser);
+
+		// Retrieve user's password list
+		this.userPasswordHistory = this.userPasswordHistoryBean.fetchPasswordHistoryByUser(updatedUser);
+
+		// Set template to "login"
+		this.setBaseTemplatePathName(USER_BASE_TEMPLATE_NAME);
+
+		// Fire event away. Keep this last before return statement.
+		this.userLoginEvent.fire(new UserLoggedInEvent(updatedUser));
+
+		// Clear this bean
+		this.clear();
+
+		// All fine
+		return "login_user"; //NOI18N
 	}
 
 	/**
@@ -312,11 +471,83 @@ public class JobsUserLoginWebSessionBean extends BaseJobsBean implements JobsUse
 		this.userCurrentPassword = userCurrentPassword;
 	}
 
+	/**
+	 * Getter for user id
+	 * <p>
+	 * @return User id
+	 */
+	public Long getUserId () {
+		return this.userId;
+	}
+
+	/**
+	 * Setter for user id
+	 * <p>
+	 * @param userId User id
+	 */
+	public void setUserId (final Long userId) {
+		this.userId = userId;
+	}
+
+	/**
+	 * Getter for user name
+	 * <p>
+	 * @return User name
+	 */
+	public String getUserName () {
+		return this.userName;
+	}
+
+	/**
+	 * Setter for user name
+	 * <p>
+	 * @param userName User name
+	 */
+	public void setUserName (final String userName) {
+		this.userName = userName;
+	}
+
+	/**
+	 * Getter for clear-text user password
+	 * <p>
+	 * @return Clear-text user password
+	 */
+	public String getUserPassword () {
+		return this.userPassword;
+	}
+
+	/**
+	 * Setter for clear-text user password
+	 * <p>
+	 * @param userPassword Clear-text user password
+	 */
+	public void setUserPassword (final String userPassword) {
+		this.userPassword = userPassword;
+	}
+
 	@Override
 	public List<PasswordHistory> getUserPasswordHistory () {
 		return Collections.unmodifiableList(this.userPasswordHistory);
 	}
 
+	/**
+	 * Getter for user profile mode
+	 * <p>
+	 * @return User profile mode
+	 */
+	public ProfileMode getUserProfileMode () {
+		return this.userProfileMode;
+	}
+
+	/**
+	 * Setter for user profile mode
+	 * <p>
+	 * @param userProfileMode User profile mode
+	 */
+	public void setUserProfileMode (final ProfileMode userProfileMode) {
+		this.userProfileMode = userProfileMode;
+	}
+
 	@Override
 	public boolean ifCurrentPasswordMatches () {
 		// The current password must be set and not empty
@@ -381,6 +612,15 @@ public class JobsUserLoginWebSessionBean extends BaseJobsBean implements JobsUse
 		return isPasswordInHistory;
 	}
 
+	/**
+	 * Checks if the user id is empty
+	 * <p>
+	 * @return Whether the user id is empty
+	 */
+	public boolean isUserIdEmpty () {
+		return ((this.getUserId() == null) || (this.getUserId() == 0));
+	}
+
 	@Override
 	public boolean isUserLoggedIn () {
 		// Compare instance
@@ -395,7 +635,24 @@ public class JobsUserLoginWebSessionBean extends BaseJobsBean implements JobsUse
 	 */
 	private void clear () {
 		// Clear all fields
+		this.setLoggedInUser(null);
+		this.setUserName(null);
+		this.setUserPassword(null);
 		this.setUserCurrentPassword(null);
+		this.setUserProfileMode(null);
+	}
+
+	/**
+	 * Copies given user into the controller
+	 * <p>
+	 * @param user User instance
+	 */
+	private void copyUser (final User user) {
+		// Copy all fields:
+		// - base data
+		this.setUserId(user.getUserId());
+		this.setUserName(user.getUserName());
+		this.setUserProfileMode(user.getUserProfileMode());
 	}
 
 	/**
diff --git a/src/java/org/mxchange/jjobs/beans/user/register/JobsUserRegisterWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/user/register/JobsUserRegisterWebRequestBean.java
index 40c751f0..77d79963 100644
--- a/src/java/org/mxchange/jjobs/beans/user/register/JobsUserRegisterWebRequestBean.java
+++ b/src/java/org/mxchange/jjobs/beans/user/register/JobsUserRegisterWebRequestBean.java
@@ -16,9 +16,11 @@
  */
 package org.mxchange.jjobs.beans.user.register;
 
+import java.util.Objects;
 import javax.ejb.EJB;
 import javax.enterprise.context.RequestScoped;
 import javax.enterprise.event.Event;
+import javax.enterprise.event.Observes;
 import javax.enterprise.inject.Any;
 import javax.faces.application.FacesMessage;
 import javax.faces.view.facelets.FaceletException;
@@ -38,9 +40,12 @@ import org.mxchange.jusercore.events.user.clear.username.ObservableClearUserName
 import org.mxchange.jusercore.exceptions.DataRepeatMismatchException;
 import org.mxchange.jusercore.exceptions.EmailAddressAlreadyRegisteredException;
 import org.mxchange.jusercore.exceptions.UserNameAlreadyRegisteredException;
+import org.mxchange.jusercore.model.user.LoginUser;
 import org.mxchange.jusercore.model.user.User;
+import org.mxchange.jusercore.model.user.Users;
 import org.mxchange.jusercore.model.user.password_history.PasswordHistory;
 import org.mxchange.jusercore.model.user.password_history.UserPasswordHistory;
+import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
 import org.mxchange.jusercore.model.user.status.UserAccountStatus;
 import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent;
 import org.mxchange.juserlogincore.events.registration.UserRegisteredEvent;
@@ -63,20 +68,6 @@ public class JobsUserRegisterWebRequestBean extends BaseJobsBean implements Jobs
 	 */
 	private static final long serialVersionUID = 47_828_986_719_691_592L;
 
-	/**
-	 * An event being fired when a user name should be cleared
-	 */
-	@Inject
-	@Any
-	private Event<ObservableClearUserNameEvent> clearUserNameEvent;
-
-	/**
-	 * An event being fired when a user password should be cleared
-	 */
-	@Inject
-	@Any
-	private Event<ObservableClearUserPasswordEvent> clearUserPasswordEvent;
-
 	/**
 	 * Contact controller
 	 */
@@ -89,6 +80,12 @@ public class JobsUserRegisterWebRequestBean extends BaseJobsBean implements Jobs
 	@Inject
 	private JobsFeaturesWebApplicationController featureController;
 
+	/**
+	 * Localization controller
+	 */
+	@Inject
+	private FinancialsLocalizationSessionController localizationController;
+
 	/**
 	 * Remote register session-scoped bean
 	 */
@@ -96,16 +93,20 @@ public class JobsUserRegisterWebRequestBean extends BaseJobsBean implements Jobs
 	private UserRegistrationSessionBeanRemote registerBean;
 
 	/**
-	 * User controller
+	 * User list controller
 	 */
 	@Inject
-	private JobsUserWebRequestController userController;
+	private FinancialsUserListWebViewController userListController;
 
 	/**
-	 * User list controller
+	 * User name
 	 */
-	@Inject
-	private JobsUserListWebViewController userListController;
+	private String userName;
+
+	/**
+	 * User password (clear-text from web form)
+	 */
+	private String userPassword;
 
 	/**
 	 * An event being fired when a user password was changed
@@ -114,6 +115,16 @@ public class JobsUserRegisterWebRequestBean extends BaseJobsBean implements Jobs
 	@Any
 	private Event<ObservableUpdatedUserPasswordEvent> userPasswordChangedEvent;
 
+	/**
+	 * User password repeated (clear-text from web form)
+	 */
+	private String userPasswordRepeat;
+
+	/**
+	 * Whether the user wants a public profile
+	 */
+	private ProfileMode userProfileMode;
+
 	/**
 	 * An event being fired when a new user has registered
 	 */
@@ -129,6 +140,29 @@ public class JobsUserRegisterWebRequestBean extends BaseJobsBean implements Jobs
 		super();
 	}
 
+	/**
+	 * Event observer for user password changes
+	 * <p>
+	 * @param event Event being fired
+	 */
+	public void afterUserPasswordChangedEvent (@Observes final ObservableUpdatedUserPasswordEvent event) {
+		// Is it valid?
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUserPassword() == null) {
+			// Throw NPE
+			throw new NullPointerException("event.userPassword is null"); //NOI18N
+		} else if (event.getUserPassword().isEmpty()) {
+			// Throw NPE
+			throw new IllegalArgumentException("event.userPassword is empty"); //NOI18N
+		}
+
+		// Set it here
+		this.setUserPassword(event.getUserPassword());
+		this.setUserPasswordRepeat(event.getUserPassword());
+	}
+
 	/**
 	 * Registers the user, if not found. Otherwise this method should throw an
 	 * exception.
@@ -143,7 +177,7 @@ public class JobsUserRegisterWebRequestBean extends BaseJobsBean implements Jobs
 		}
 
 		// Get user instance
-		final User user = this.userController.createUserInstance(true);
+		final User user = this.createUserInstance(true);
 
 		// Null random password means registration requires user-entered password
 		String randomPassword = null;
@@ -152,7 +186,7 @@ public class JobsUserRegisterWebRequestBean extends BaseJobsBean implements Jobs
 		if (null == user) {
 			// user must be set
 			throw new NullPointerException("user is null after createUserInstance() was called"); //NOI18N
-		} else if (!this.userController.isRequiredPersonalDataSet()) {
+		} else if (!this.isRequiredPersonalDataSet()) {
 			// Not all required fields are set
 			throw new FaceletException("Not all required fields are set."); //NOI18N
 		} else if ((this.featureController.isFeatureEnabled("user_login_require_user_name")) && (this.userListController.isUserNameRegistered(user))) { //NOI18N
@@ -161,8 +195,8 @@ public class JobsUserRegisterWebRequestBean extends BaseJobsBean implements Jobs
 				// User name is already used, should not happen here
 				throw new FaceletException(new UserNameAlreadyRegisteredException(user));
 			} else {
-				// May happen here, fire event
-				this.clearUserNameEvent.fire(new ClearUserNameEvent());
+				// May happen here, clear user name
+				this.clearUserName();
 
 				// Output message
 				this.showFacesMessage("form_register_single:userName", "ERROR_USER_NAME_ALREADY_USED", FacesMessage.SEVERITY_WARN); //NOI18N
@@ -190,12 +224,12 @@ public class JobsUserRegisterWebRequestBean extends BaseJobsBean implements Jobs
 				this.showFacesMessage("form_register_single:emailAddressRepeat", "ERROR_EMAIL_ADDRESSES_MISMATCHING", FacesMessage.SEVERITY_INFO); //NOI18N
 				return ""; //NOI18N
 			}
-		} else if (!this.userController.isSamePasswordEntered()) {
+		} else if (!this.isSamePasswordEntered()) {
 			// Is multi-page enabled?
 			if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N
 				// Not same password entered, should no longer happen here
 				throw new FaceletException(new DataRepeatMismatchException("Passwords not matching.")); //NOI18N
-			} else if (this.userController.ifBothPasswordsEmptyAllowed()) {
+			} else if (this.ifBothPasswordsEmptyAllowed()) {
 				// Both passwords are left empty and is allowed, then generate a random password
 				randomPassword = UserLoginUtils.createRandomPassword(JobsUserWebRequestController.MINIMUM_PASSWORD_LENGTH);
 
@@ -208,7 +242,7 @@ public class JobsUserRegisterWebRequestBean extends BaseJobsBean implements Jobs
 		}
 
 		// Encrypt password
-		final String encryptedPassword = UserLoginUtils.encryptPassword(this.userController.getUserPassword());
+		final String encryptedPassword = UserLoginUtils.encryptPassword(this.getUserPassword());
 
 		// Set it here
 		user.setUserEncryptedPassword(encryptedPassword);
@@ -264,7 +298,7 @@ public class JobsUserRegisterWebRequestBean extends BaseJobsBean implements Jobs
 		}
 
 		// Get user instance
-		final User user = this.userController.createUserInstance(false);
+		final User user = this.createUserInstance(false);
 
 		// First check if user is not null and user name is not used + if same email address is entered
 		if (null == user) {
@@ -272,7 +306,7 @@ public class JobsUserRegisterWebRequestBean extends BaseJobsBean implements Jobs
 			throw new NullPointerException("user is null after createUserInstance() was called"); //NOI18N
 		} else if ((this.featureController.isFeatureEnabled("user_login_require_user_name")) && (this.userListController.isUserNameRegistered(user))) { //NOI18N
 			// User name is already used, so clear it
-			this.clearUserNameEvent.fire(new ClearUserNameEvent());
+			this.clearUserName();
 
 			// Output message
 			this.showFacesMessage("form_register_page1:userName", "ERROR_USER_NAME_ALREADY_USED", FacesMessage.SEVERITY_WARN); //NOI18N
@@ -282,22 +316,22 @@ public class JobsUserRegisterWebRequestBean extends BaseJobsBean implements Jobs
 			this.contactController.clearEmailAddresses();
 			this.showFacesMessage("form_register_page1:emailAddressRepeat", "ERROR_EMAIL_ADDRESSES_MISMATCHING", FacesMessage.SEVERITY_WARN); //NOI18N
 			return ""; //NOI18N
-		} else if (!this.userController.isSamePasswordEntered()) {
+		} else if (!this.isSamePasswordEntered()) {
 			// Is multi-page enabled?
 			if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N
-				// Unset both
-				this.clearUserPasswordEvent.fire(new ClearUserPasswordEvent());
+				// Clear passwords
+				this.clearUserPasswords();
 
 				// Output faces message
 				this.showFacesMessage("form_register_page1:userPassword", "ERROR_USER_PASSWORD_EMPTY", FacesMessage.SEVERITY_WARN); //NOI18N
 				this.showFacesMessage("form_register_page1:userPasswordRepeat", "ERROR_USER_PASSWORD_REPEAT_EMPTY", FacesMessage.SEVERITY_WARN); //NOI18N
 				return ""; //NOI18N
-			} else if (this.userController.ifBothPasswordsEmptyAllowed()) {
+			} else if (this.ifBothPasswordsEmptyAllowed()) {
 				// Both passwords are left empty and is allowed, then generate a random password
-				String randomPassword = UserLoginUtils.createRandomPassword(JobsUserWebRequestController.MINIMUM_PASSWORD_LENGTH);
+				final String randomPassword = UserLoginUtils.createRandomPassword(FinancialsUserWebRequestController.MINIMUM_PASSWORD_LENGTH);
 
 				// Generate (ignored) password-history
-				PasswordHistory passwordHistory = new UserPasswordHistory(randomPassword, user);
+				final PasswordHistory passwordHistory = new UserPasswordHistory(randomPassword, user);
 
 				// Fire event
 				this.userPasswordChangedEvent.fire(new UpdatedUserPasswordEvent(passwordHistory, randomPassword));
@@ -323,4 +357,211 @@ public class JobsUserRegisterWebRequestBean extends BaseJobsBean implements Jobs
 		return "user_register_page2"; //NOI18N
 	}
 
+	/**
+	 * Getter for user name
+	 * <p>
+	 * @return User name
+	 */
+	public String getUserName () {
+		return this.userName;
+	}
+
+	/**
+	 * Setter for user name
+	 * <p>
+	 * @param userName User name
+	 */
+	public void setUserName (final String userName) {
+		this.userName = userName;
+	}
+
+	/**
+	 * Getter for clear-text user password
+	 * <p>
+	 * @return Clear-text user password
+	 */
+	public String getUserPassword () {
+		return this.userPassword;
+	}
+
+	/**
+	 * Setter for clear-text user password
+	 * <p>
+	 * @param userPassword Clear-text user password
+	 */
+	public void setUserPassword (final String userPassword) {
+		this.userPassword = userPassword;
+	}
+
+	/**
+	 * Getter for clear-text user password repeated
+	 * <p>
+	 * @return Clear-text user password repeated
+	 */
+	public String getUserPasswordRepeat () {
+		return this.userPasswordRepeat;
+	}
+
+	/**
+	 * Setter for clear-text user password repeated
+	 * <p>
+	 * @param userPasswordRepeat Clear-text user password repeated
+	 */
+	public void setUserPasswordRepeat (final String userPasswordRepeat) {
+		this.userPasswordRepeat = userPasswordRepeat;
+	}
+
+	/**
+	 * Getter for user profile mode
+	 * <p>
+	 * @return User profile mode
+	 */
+	public ProfileMode getUserProfileMode () {
+		return this.userProfileMode;
+	}
+
+	/**
+	 * Setter for user profile mode
+	 * <p>
+	 * @param userProfileMode User profile mode
+	 */
+	public void setUserProfileMode (final ProfileMode userProfileMode) {
+		this.userProfileMode = userProfileMode;
+	}
+
+	@Override
+	public boolean isRequiredChangePersonalDataSet () {
+		return ((this.getUserProfileMode() != null) &&
+				(this.getUserName() != null) &&
+				(!this.getUserName().isEmpty()) &&
+				(this.contactController.isRequiredChangePersonalDataSet()));
+	}
+
+	/**
+	 * Clears user name
+	 */
+	private void clearUserName () {
+		// Clear it
+		this.setUserName(null);
+	}
+
+	/**
+	 * Clears both user passwords
+	 */
+	private void clearUserPasswords () {
+		// Clear both
+		this.setUserPassword(null);
+		this.setUserPasswordRepeat(null);
+	}
+
+	/**
+	 * Creates an instance from all properties
+	 * <p>
+	 * @param createContactData Whether contact data should be created
+	 * <p>
+	 * @return A user instance
+	 */
+	private User createUserInstance (final boolean createContactData) {
+		// Required personal data must be set
+		assert (this.isRequiredPersonalDataSet()) : "All required personal data must be set before invoking this method."; //NOI18N
+
+		// Is user name required?
+		if (!this.featureController.isFeatureEnabled("user_login_require_username")) {
+			// Init variables
+			String randomName = null;
+			boolean isUsernameFree = false;
+
+			// Get full list
+			for (final User user : this.userListController.getAllUsers()) {
+				// Loop until a user name is found
+				while ((randomName == null) || (randomName.equals(user.getUserName()))) {
+					// Generate random name
+					randomName = Users.generateRandomUserName();
+					isUsernameFree = true;
+				}
+
+				// Is non-existing username found
+				if (isUsernameFree) {
+					// Also stop looping here
+					break;
+				}
+			}
+
+			// Set it and inivisible profile
+			this.setUserName(randomName);
+			this.setUserProfileMode(ProfileMode.INVISIBLE);
+
+			// Generate random password
+			final String randomPassword = UserLoginUtils.createRandomPassword(FinancialsUserWebRequestController.MINIMUM_PASSWORD_LENGTH);
+
+			// Set random password
+			this.setUserPassword(randomPassword);
+			this.setUserPasswordRepeat(randomPassword);
+		}
+
+		// Create new user instance
+		final User user = new LoginUser();
+
+		// Set user name profile mode and locale
+		user.setUserName(this.getUserName());
+		user.setUserProfileMode(this.getUserProfileMode());
+		user.setUserLocale(this.localizationController.getLocale());
+
+		// Is multiple registration page
+		if ((createContactData) || (!this.featureController.isFeatureEnabled("user_register_multiple_page"))) { //NOI18N
+			// Create contact instance
+			final Contact contact = this.contactController.createContactInstance();
+
+			// Set contact in user
+			user.setUserContact(contact);
+		}
+
+		// Return it
+		return user;
+	}
+
+	/**
+	 * Checks if both user passwords are left empty and if this is enabled
+	 * (allowed) in context parameter. If true, the calling bean should create a
+	 * random password (preferable with UserUtils.createRandomPassword() and set
+	 * it in both user password fields.
+	 * <p>
+	 * @return Whether empty passwords are allowed
+	 */
+	private boolean ifBothPasswordsEmptyAllowed () {
+		// Check feature first
+		return ((this.featureController.isFeatureEnabled("allow_user_registration_empty_password")) && //NOI18N
+				((this.getUserPassword() == null) || (this.getUserPassword().isEmpty())) &&
+				((this.getUserPasswordRepeat() == null) || (this.getUserPasswordRepeat().isEmpty())));
+	}
+
+	/**
+	 * Checks whether all required personal data is set
+	 * <p>
+	 * @return Whether the required personal data is set
+	 */
+	private boolean isRequiredPersonalDataSet () {
+		// Check conditions based on of multi-page registration is enabled
+		if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N
+			// Multiple registration page
+			return this.contactController.isRequiredPersonalDataSet();
+		} else {
+			// Single registration page
+			return (((this.getUserName() != null) || (!this.featureController.isFeatureEnabled("user_login_require_username"))) && //NOI18N
+					(this.getUserProfileMode() != null) &&
+					(this.contactController.isRequiredPersonalDataSet()) &&
+					(this.getUserPassword() != null) &&
+					(this.getUserPasswordRepeat() != null));
+		}
+	}
+
+	/**
+	 * Checks whether same passwords has been entered
+	 * <p>
+	 * @return Whether same passwords has been entered
+	 */
+	private boolean isSamePasswordEntered () {
+		return ((!this.getUserPassword().isEmpty()) && (Objects.equals(this.getUserPassword(), this.getUserPasswordRepeat())));
+	}
+
 }
diff --git a/src/java/org/mxchange/jjobs/beans/user/register/JobsUserRegisterWebRequestController.java b/src/java/org/mxchange/jjobs/beans/user/register/JobsUserRegisterWebRequestController.java
index 968da2d0..979f37b2 100644
--- a/src/java/org/mxchange/jjobs/beans/user/register/JobsUserRegisterWebRequestController.java
+++ b/src/java/org/mxchange/jjobs/beans/user/register/JobsUserRegisterWebRequestController.java
@@ -25,4 +25,11 @@ import java.io.Serializable;
  */
 public interface JobsUserRegisterWebRequestController extends Serializable {
 
+	/**
+	 * Checks whether all required personal data is set for changing them
+	 * <p>
+	 * @return Whether the required personal data is set
+	 */
+	boolean isRequiredChangePersonalDataSet ();
+
 }
diff --git a/src/java/org/mxchange/jjobs/converter/business/company_employee/JobsEmployeeConverter.java b/src/java/org/mxchange/jjobs/converter/business/company_employee/JobsEmployeeConverter.java
index 4480d6f8..590cd203 100644
--- a/src/java/org/mxchange/jjobs/converter/business/company_employee/JobsEmployeeConverter.java
+++ b/src/java/org/mxchange/jjobs/converter/business/company_employee/JobsEmployeeConverter.java
@@ -38,21 +38,12 @@ public class JobsEmployeeConverter implements Converter<Employable> {
 	/**
 	 * Employable EJB
 	 */
-	private static JobsEmployeeWebRequestController EMPLOYEE_CONTROLLER;
+	private static FinancialsEmployeeListWebViewController EMPLOYEE_LIST_CONTROLLER;
 
 	@Override
 	public Employable getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) {
-		// Is the instance there?
-		if (null == EMPLOYEE_CONTROLLER) {
-			// Get bean from CDI directly
-			EMPLOYEE_CONTROLLER = CDI.current().select(JobsEmployeeWebRequestBean.class).get();
-		}
-
 		// Is the value null or empty?
 		if ((null == submittedValue) || (submittedValue.trim().isEmpty())) {
-			// Warning message
-			// @TODO Not working with JNDI (no remote interface) this.loggerBeanLocal.logWarning(MessageFormat.format("{0}.getAsObject(): submittedValue is null or empty - EXIT!", this.getClass().getSimpleName())); //NOI18N
-
 			// Return null
 			return null;
 		}
@@ -64,8 +55,14 @@ public class JobsEmployeeConverter implements Converter<Employable> {
 			// Try to parse the value as long
 			final Long employeeId = Long.valueOf(submittedValue);
 
+			// Is the instance there?
+			if (null == EMPLOYEE_LIST_CONTROLLER) {
+				// Get bean from CDI directly
+				EMPLOYEE_LIST_CONTROLLER = CDI.current().select(FinancialsEmployeeListWebViewBean.class).get();
+			}
+
 			// Try to get user instance from it
-			companyEmployee = EMPLOYEE_CONTROLLER.findEmployeeById(employeeId);
+			companyEmployee = EMPLOYEE_LIST_CONTROLLER.findEmployeeById(employeeId);
 		} catch (final NumberFormatException ex) {
 			// Throw again
 			throw new ConverterException(ex);
diff --git a/src/java/org/mxchange/jjobs/converter/business/employee/JobsEmployeeConverter.java b/src/java/org/mxchange/jjobs/converter/business/employee/JobsEmployeeConverter.java
index 5d075d16..2c895c62 100644
--- a/src/java/org/mxchange/jjobs/converter/business/employee/JobsEmployeeConverter.java
+++ b/src/java/org/mxchange/jjobs/converter/business/employee/JobsEmployeeConverter.java
@@ -38,14 +38,14 @@ public class JobsEmployeeConverter implements Converter<Employable> {
 	/**
 	 * Employable EJB
 	 */
-	private static JobsEmployeeWebRequestController EMPLOYEE_CONTROLLER;
+	private static JobsEmployeeWebRequestController EMPLOYEE_LIST_CONTROLLER;
 
 	@Override
 	public Employable getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) {
 		// Is the instance there?
-		if (null == EMPLOYEE_CONTROLLER) {
+		if (null == EMPLOYEE_LIST_CONTROLLER) {
 			// Get bean from CDI directly
-			EMPLOYEE_CONTROLLER = CDI.current().select(JobsEmployeeWebRequestBean.class).get();
+			EMPLOYEE_LIST_CONTROLLER = CDI.current().select(JobsEmployeeWebRequestBean.class).get();
 		}
 
 		// Is the value null or empty?
@@ -65,7 +65,7 @@ public class JobsEmployeeConverter implements Converter<Employable> {
 			final Long employeeId = Long.valueOf(submittedValue);
 
 			// Try to get user instance from it
-			companyEmployee = EMPLOYEE_CONTROLLER.findEmployeeById(employeeId);
+			companyEmployee = EMPLOYEE_LIST_CONTROLLER.findEmployeeById(employeeId);
 		} catch (final NumberFormatException ex) {
 			// Throw again
 			throw new ConverterException(ex);
diff --git a/src/java/org/mxchange/jjobs/converter/business/opening_time/JobsCompanyOpeningTimeConverter.java b/src/java/org/mxchange/jjobs/converter/business/opening_time/JobsCompanyOpeningTimeConverter.java
index b8f822f3..26e6db1b 100644
--- a/src/java/org/mxchange/jjobs/converter/business/opening_time/JobsCompanyOpeningTimeConverter.java
+++ b/src/java/org/mxchange/jjobs/converter/business/opening_time/JobsCompanyOpeningTimeConverter.java
@@ -38,16 +38,10 @@ public class JobsCompanyOpeningTimeConverter implements Converter<OpeningTime> {
 	/**
 	 * Opening time backing bean
 	 */
-	private static JobsOpeningTimeWebRequestController OPENING_TIMES_CONTROLLER;
+	private static JobsOpeningTimeWebRequestController OPENING_TIMES_LIST_CONTROLLER;
 
 	@Override
 	public OpeningTime getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) {
-		// Is the instance there?
-		if (null == OPENING_TIMES_CONTROLLER) {
-			// Get bean from CDI directly
-			OPENING_TIMES_CONTROLLER = CDI.current().select(JobsOpeningTimeWebRequestBean.class).get();
-		}
-
 		// Is the value null or empty?
 		if ((null == submittedValue) || (submittedValue.trim().isEmpty())) {
 			// Warning message
@@ -62,10 +56,16 @@ public class JobsCompanyOpeningTimeConverter implements Converter<OpeningTime> {
 
 		try {
 			// Try to parse the value as long
-			final Long openingId = Long.valueOf(submittedValue);
+			final Long openingTimeId = Long.valueOf(submittedValue);
+
+			// Is the instance there?
+			if (null == OPENING_TIME_LIST_CONTROLLER) {
+				// Get bean from CDI directly
+				OPENING_TIME_LIST_CONTROLLER = CDI.current().select(FinancialsOpeningTimeListWebViewBean.class).get();
+			}
 
 			// Try to get user instance from it
-			openingTime = OPENING_TIMES_CONTROLLER.findOpeningTimeById(openingId);
+			openingTime = OPENING_TIME_LIST_CONTROLLER.findOpeningTimeById(openingTimeId);
 		} catch (final NumberFormatException ex) {
 			// Throw again
 			throw new ConverterException(ex);
@@ -87,7 +87,7 @@ public class JobsCompanyOpeningTimeConverter implements Converter<OpeningTime> {
 		}
 
 		// Return id number
-		return String.valueOf(value.getOpeningId());
+		return String.valueOf(value.getOpeningTimeId());
 	}
 
 }
diff --git a/src/java/org/mxchange/jjobs/converter/fax/JobsFaxNumberConverter.java b/src/java/org/mxchange/jjobs/converter/fax/JobsFaxNumberConverter.java
index 559046ba..b2e43c39 100644
--- a/src/java/org/mxchange/jjobs/converter/fax/JobsFaxNumberConverter.java
+++ b/src/java/org/mxchange/jjobs/converter/fax/JobsFaxNumberConverter.java
@@ -38,24 +38,12 @@ public class JobsFaxNumberConverter implements Converter<DialableFaxNumber> {
 	/**
 	 * Phone EJB
 	 */
-	private static JobsPhoneWebRequestController PHONE_CONTROLLER;
+	private static JobsPhoneWebRequestController PHONE_LIST_CONTROLLER;
 
 	@Override
 	public DialableFaxNumber getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) {
-		// Is the instance there?
-		if (null == PHONE_CONTROLLER) {
-			// Get bean from CDI directly
-			PHONE_CONTROLLER = CDI.current().select(JobsPhoneWebRequestBean.class).get();
-		}
-
-		// Log message
-		// @TODO Not possible here: this.loggerBeanLocal.logTrace(MessageFormat.format("{0}.getAsObject: context={1},component={2},submittedValue={3} - CALLED!", this.getClass().getSimpleName(), context, component, submittedValue)); //NOI18N
-
 		// Is the value null or empty?
 		if ((null == submittedValue) || (submittedValue.trim().isEmpty())) {
-			// Warning message
-			// @TODO Not possible here: this.loggerBeanLocal.logWarning(MessageFormat.format("{0}.getAsObject(): submittedValue is null or empty - EXIT!", this.getClass().getSimpleName())); //NOI18N
-
 			// Return null
 			return null;
 		}
@@ -67,10 +55,14 @@ public class JobsFaxNumberConverter implements Converter<DialableFaxNumber> {
 			// Try to parse the value as long
 			final Long faxNumberId = Long.valueOf(submittedValue);
 
-			// Log message
-			// @TODO Not possible here: this.loggerBeanLocal.logDebug(MessageFormat.format("{0}.getAsObject: faxNumberId={1}", this.getClass().getSimpleName(), faxNumberId)); //NOI18N
+			// Is the instance there?
+			if (null == PHONE_LIST_CONTROLLER) {
+				// Get bean from CDI directly
+				PHONE_LIST_CONTROLLER = CDI.current().select(FinancialsPhoneListWebViewBean.class).get();
+			}
+
 			// Try to get mobile instance from it
-			faxNumber = PHONE_CONTROLLER.findFaxNumberById(faxNumberId);
+			faxNumber = PHONE_LIST_CONTROLLER.findFaxNumberById(faxNumberId);
 		} catch (final NumberFormatException ex) {
 			// Throw again
 			throw new ConverterException(ex);
@@ -79,8 +71,6 @@ public class JobsFaxNumberConverter implements Converter<DialableFaxNumber> {
 			// @TODO Not possible here: this.loggerBeanLocal.logDebug(MessageFormat.format("{0}.getAsObject(): Exception: {1} - Returning null ...", this.getClass().getSimpleName(), ex)); //NOI18N
 		}
 
-		// Log message
-		// @TODO Not possible here: this.loggerBeanLocal.logTrace(MessageFormat.format("{0}.getAsObject: faxNumber={1} - EXIT!", this.getClass().getSimpleName(), faxNumber)); //NOI18N
 		// Return it
 		return faxNumber;
 	}
diff --git a/src/java/org/mxchange/jjobs/converter/landline/JobsLandLineNumberConverter.java b/src/java/org/mxchange/jjobs/converter/landline/JobsLandLineNumberConverter.java
index 70d3af86..73ad9e16 100644
--- a/src/java/org/mxchange/jjobs/converter/landline/JobsLandLineNumberConverter.java
+++ b/src/java/org/mxchange/jjobs/converter/landline/JobsLandLineNumberConverter.java
@@ -38,21 +38,12 @@ public class JobsLandLineNumberConverter implements Converter<DialableLandLineNu
 	/**
 	 * Phone EJB
 	 */
-	private static JobsPhoneWebRequestController PHONE_CONTROLLER;
+	private static JobsPhoneWebRequestController PHONE_LIST_CONTROLLER;
 
 	@Override
 	public DialableLandLineNumber getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) {
-		// Is the instance there?
-		if (null == PHONE_CONTROLLER) {
-			// Get bean from CDI directly
-			PHONE_CONTROLLER = CDI.current().select(JobsPhoneWebRequestBean.class).get();
-		}
-
 		// Is the value null or empty?
 		if ((null == submittedValue) || (submittedValue.trim().isEmpty())) {
-			// Warning message
-			// @TODO Not possible here: this.loggerBeanLocal.logWarning(MessageFormat.format("{0}.getAsObject(): submittedValue is null or empty - EXIT!", this.getClass().getSimpleName())); //NOI18N
-
 			// Return null
 			return null;
 		}
@@ -64,8 +55,14 @@ public class JobsLandLineNumberConverter implements Converter<DialableLandLineNu
 			// Try to parse the value as long
 			final Long landLineNumberId = Long.valueOf(submittedValue);
 
+			// Is the instance there?
+			if (null == PHONE_LIST_CONTROLLER) {
+				// Get bean from CDI directly
+				PHONE_LIST_CONTROLLER = CDI.current().select(FinancialsPhoneListWebViewBean.class).get();
+			}
+
 			// Try to get mobile instance from it
-			landLineNumber = PHONE_CONTROLLER.findLandLineNumberById(landLineNumberId);
+			landLineNumber = PHONE_LIST_CONTROLLER.findLandLineNumberById(landLineNumberId);
 		} catch (final NumberFormatException ex) {
 			// Throw again
 			throw new ConverterException(ex);
diff --git a/src/java/org/mxchange/jjobs/converter/mobile/JobsMobileNumberConverter.java b/src/java/org/mxchange/jjobs/converter/mobile/JobsMobileNumberConverter.java
index 1b23e115..8d237daf 100644
--- a/src/java/org/mxchange/jjobs/converter/mobile/JobsMobileNumberConverter.java
+++ b/src/java/org/mxchange/jjobs/converter/mobile/JobsMobileNumberConverter.java
@@ -38,21 +38,12 @@ public class JobsMobileNumberConverter implements Converter<DialableMobileNumber
 	/**
 	 * Phone EJB
 	 */
-	private static JobsPhoneWebRequestController PHONE_CONTROLLER;
+	private static JobsPhoneWebRequestController PHONE_LIST_CONTROLLER;
 
 	@Override
 	public DialableMobileNumber getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) {
-		// Is the instance there?
-		if (null == PHONE_CONTROLLER) {
-			// Get bean from CDI directly
-			PHONE_CONTROLLER = CDI.current().select(JobsPhoneWebRequestBean.class).get();
-		}
-
 		// Is the value null or empty?
 		if ((null == submittedValue) || (submittedValue.trim().isEmpty())) {
-			// Warning message
-			// @TODO Not working with JNDI (no remote interface) this.loggerBeanLocal.logWarning(MessageFormat.format("{0}.getAsObject(): submittedValue is null or empty - EXIT!", this.getClass().getSimpleName())); //NOI18N
-
 			// Return null
 			return null;
 		}
@@ -64,12 +55,18 @@ public class JobsMobileNumberConverter implements Converter<DialableMobileNumber
 			// Try to parse the value as long
 			final Long mobileNumberId = Long.valueOf(submittedValue);
 
+			// Is the instance there?
+			if (null == MOBILE_LIST_CONTROLLER) {
+				// Get bean from CDI directly
+				MOBILE_LIST_CONTROLLER = CDI.current().select(FinancialsMobileListWebViewBean.class).get();
+			}
+
 			// Try to get mobile instance from it
-			mobileNumber = PHONE_CONTROLLER.findMobileNumberById(mobileNumberId);
+			mobileNumber = MOBILE_LIST_CONTROLLER.findMobileNumberById(mobileNumberId);
 		} catch (final NumberFormatException ex) {
 			// Throw again
 			throw new ConverterException(ex);
-		} catch (final PhoneEntityNotFoundException ex) {
+		} catch (final MobileEntityNotFoundException ex) {
 			// Debug message
 			// @TODO Not working with JNDI (no remote interface) this.loggerBeanLocal.logDebug(MessageFormat.format("{0}.getAsObject(): Exception: {1} - Returning null ...", this.getClass().getSimpleName(), ex)); //NOI18N
 		}
@@ -87,7 +84,7 @@ public class JobsMobileNumberConverter implements Converter<DialableMobileNumber
 		}
 
 		// Return id number
-		return String.valueOf(value.getPhoneId());
+		return String.valueOf(value.getMobileId());
 	}
 
 }
diff --git a/src/java/org/mxchange/jjobs/converter/mobileprovider/JobsMobileProviderConverter.java b/src/java/org/mxchange/jjobs/converter/mobileprovider/JobsMobileProviderConverter.java
index 2942eaee..8ec5284d 100644
--- a/src/java/org/mxchange/jjobs/converter/mobileprovider/JobsMobileProviderConverter.java
+++ b/src/java/org/mxchange/jjobs/converter/mobileprovider/JobsMobileProviderConverter.java
@@ -38,21 +38,12 @@ public class JobsMobileProviderConverter implements Converter<MobileProvider> {
 	/**
 	 * Mobile provider backing bean
 	 */
-	private static JobsMobileProviderWebRequestController MOBILE_PROVIDER_CONTROLLER;
+	private static JobsMobileProviderWebRequestController MOBILE_PROVIDER_LIST_CONTROLLER;
 
 	@Override
 	public MobileProvider getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) {
-		// Is the instance there?
-		if (null == MOBILE_PROVIDER_CONTROLLER) {
-			// Get bean from CDI directly
-			MOBILE_PROVIDER_CONTROLLER = CDI.current().select(JobsMobileProviderWebRequestBean.class).get();
-		}
-
 		// Is the value null or empty?
 		if ((null == submittedValue) || (submittedValue.trim().isEmpty())) {
-			// Warning message
-			// @TODO Not working with JNDI (no remote interface) this.loggerBeanLocal.logWarning(MessageFormat.format("{0}.getAsObject(): submittedValue is null or empty - EXIT!", this.getClass().getSimpleName())); //NOI18N
-
 			// Return null
 			return null;
 		}
@@ -65,8 +56,14 @@ public class JobsMobileProviderConverter implements Converter<MobileProvider> {
 			// Convert it to long
 			final Long providerId = Long.parseLong(submittedValue);
 
+			// Is the instance there?
+			if (null == MOBILE_PROVIDER_LIST_CONTROLLER) {
+				// Get bean from CDI directly
+				MOBILE_PROVIDER_LIST_CONTROLLER = CDI.current().select(FinancialsMobileProviderListWebViewBean.class).get();
+			}
+
 			// Lookup of mobile provider
-			mobileProvider = MOBILE_PROVIDER_CONTROLLER.findMobileProviderById(providerId);
+			mobileProvider = MOBILE_PROVIDER_LIST_CONTROLLER.findMobileProviderById(providerId);
 		} catch (final NumberFormatException ex) {
 			// Throw again
 			throw new ConverterException(ex);
diff --git a/src/java/org/mxchange/jjobs/validator/emailaddress/employee/JobsEmployeeEmailAddressValidator.java b/src/java/org/mxchange/jjobs/validator/emailaddress/employee/JobsEmployeeEmailAddressValidator.java
index 01a704e9..55d2c37f 100644
--- a/src/java/org/mxchange/jjobs/validator/emailaddress/employee/JobsEmployeeEmailAddressValidator.java
+++ b/src/java/org/mxchange/jjobs/validator/emailaddress/employee/JobsEmployeeEmailAddressValidator.java
@@ -44,7 +44,7 @@ public class JobsEmployeeEmailAddressValidator extends BaseStringValidator {
 	/**
 	 * Employee backing bean
 	 */
-	private static JobsEmployeeWebRequestController EMPLOYEE_CONTROLLER;
+	private static JobsEmployeeWebRequestController EMPLOYEE_LIST_CONTROLLER;
 
 	/**
 	 * Pattern matcher
@@ -115,13 +115,13 @@ public class JobsEmployeeEmailAddressValidator extends BaseStringValidator {
 		final String clientId = component.getClientId();
 
 		// Is the instance there?
-		if (null == EMPLOYEE_CONTROLLER) {
+		if (null == EMPLOYEE_LIST_CONTROLLER) {
 			// Get bean from CDI directly
-			EMPLOYEE_CONTROLLER = CDI.current().select(JobsEmployeeWebRequestBean.class).get();
+			EMPLOYEE_LIST_CONTROLLER = CDI.current().select(JobsEmployeeWebRequestBean.class).get();
 		}
 
 		// Is it registered?
-		final Boolean isRegistered = EMPLOYEE_CONTROLLER.isEmailAddressRegistered(emailAddress);
+		final Boolean isRegistered = EMPLOYEE_LIST_CONTROLLER.isEmailAddressRegistered(emailAddress);
 
 		// Is the email address already registered?
 		if ((!clientId.endsWith("resendEmailAddress")) && (isRegistered)) { //NOI18N
diff --git a/src/java/org/mxchange/localization/generic_de_DE.properties b/src/java/org/mxchange/localization/generic_de_DE.properties
index b0c451f9..fd3b1e60 100644
--- a/src/java/org/mxchange/localization/generic_de_DE.properties
+++ b/src/java/org/mxchange/localization/generic_de_DE.properties
@@ -601,8 +601,6 @@ CONTENT_TITLE_ADMIN_LIST_CONTACT_MOBILE_NUMBER=Auflisten von Mobiltelefonnummern
 ADMIN_MENU_PHONE_NUMBERS_TITLE=Telefonnummern
 ADMIN_LINK_LIST_MOBILE_PHONE_NUMBERS=Handynummern
 ADMIN_LINK_LIST_MOBILE_PHONE_NUMBERS_TITLE=Alle Mobilfunknummern auflisten.
-ADMIN_SHOW_PHONE_CREATED=Telefoneintrag erstellt:
-ADMIN_SHOW_PHONE_UPDATED=Telefoneintrag zuletzt ge\u00e4ndert:
 ADMIN_EDIT_MOBILE_NUMBER_TITLE=Mobiltelefoneintrag {0} editieren:
 ADMIN_MOBILE_NUMBER_DATA_LEGEND=Mobiltelefonnummerdaten editeren:
 ADMIN_EDIT_MOBILE_PROVIDER=Mobilfunkanbieter \u00e4ndern:
diff --git a/src/java/org/mxchange/localization/generic_en_US.properties b/src/java/org/mxchange/localization/generic_en_US.properties
index 63ca7b5b..f1d254a6 100644
--- a/src/java/org/mxchange/localization/generic_en_US.properties
+++ b/src/java/org/mxchange/localization/generic_en_US.properties
@@ -581,8 +581,6 @@ CONTENT_TITLE_ADMIN_LIST_CONTACT_MOBILE_NUMBER=List mobile phone numbers:
 ADMIN_MENU_PHONE_NUMBERS_TITLE=Phone numbers
 ADMIN_LINK_LIST_MOBILE_PHONE_NUMBERS=Mobile numbers
 ADMIN_LINK_LIST_MOBILE_PHONE_NUMBERS_TITLE=List all mobile numbers.
-ADMIN_SHOW_PHONE_CREATED=Created:
-ADMIN_SHOW_PHONE_UPDATED=Last changed:
 ADMIN_EDIT_MOBILE_NUMBER_TITLE=Edit mobile entry {0}:
 ADMIN_MOBILE_NUMBER_DATA_LEGEND=Edit mobile data:
 ADMIN_EDIT_MOBILE_PROVIDER=Change mobile phone provider:
diff --git a/web/WEB-INF/links.jsf.taglib.xml b/web/WEB-INF/links.jsf.taglib.xml
index e7811b96..681291de 100644
--- a/web/WEB-INF/links.jsf.taglib.xml
+++ b/web/WEB-INF/links.jsf.taglib.xml
@@ -39,254 +39,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 			<type>java.lang.Boolean</type>
 		</attribute>
 	</tag>
-	<tag>
-		<tag-name>outputFaxNumberAdminDropdownMenu</tag-name>
-		<description>This tag renders a full h:panelGroup for an administrative drop-down menu for fax data.</description>
-		<source>resources/tags/admin/dropdown/fax/admin_fax_links.tpl</source>
-		<attribute>
-			<name>faxNumber</name>
-			<description>The fax instance that provides the data for this tag.</description>
-			<required>true</required>
-			<type>org.mxchange.jphone.model.phonenumbers.fax.DialableFaxNumber</type>
-		</attribute>
-		<attribute>
-			<name>contact</name>
-			<description>The contact instance that provides contact data for additional JSF links.</description>
-			<required>false</required>
-			<type>org.mxchange.jcontacts.model.contact.Contact</type>
-		</attribute>
-		<attribute>
-			<name>renderShowLink</name>
-			<description>Whether this tag is used to show fax data (default true).</description>
-			<required>false</required>
-			<type>java.lang.Boolean</type>
-		</attribute>
-		<attribute>
-			<name>rendered</name>
-			<description>Whether this tag is being rendered by JSF engine (default: true).</description>
-			<required>false</required>
-			<type>java.lang.Boolean</type>
-		</attribute>
-	</tag>
-	<tag>
-		<tag-name>outputLandLineNumberAdminDropdownMenu</tag-name>
-		<description>This tag renders a full h:panelGroup for an administrative drop-down menu for land-line data.</description>
-		<source>resources/tags/admin/dropdown/landline/admin_landline_links.tpl</source>
-		<attribute>
-			<name>landLineNumber</name>
-			<description>The fax instance that provides the data for this tag.</description>
-			<required>true</required>
-			<type>org.mxchange.jphone.model.phonenumbers.landline.DialableLandLineNumber</type>
-		</attribute>
-		<attribute>
-			<name>contact</name>
-			<description>The contact instance that provides contact data for additional JSF links.</description>
-			<required>false</required>
-			<type>org.mxchange.jcontacts.model.contact.Contact</type>
-		</attribute>
-		<attribute>
-			<name>renderShowLink</name>
-			<description>Whether this tag is used to show land-line data (default true).</description>
-			<required>false</required>
-			<type>java.lang.Boolean</type>
-		</attribute>
-		<attribute>
-			<name>rendered</name>
-			<description>Whether this tag is being rendered by JSF engine (default: true).</description>
-			<required>false</required>
-			<type>java.lang.Boolean</type>
-		</attribute>
-	</tag>
-	<tag>
-		<tag-name>outputMobileNumberAdminDropdownMenu</tag-name>
-		<description>This tag renders a full h:panelGroup for an administrative drop-down menu for mobile data.</description>
-		<source>resources/tags/admin/dropdown/mobile/admin_mobile_links.tpl</source>
-		<attribute>
-			<name>mobileNumber</name>
-			<description>The mobile number instance that provides the data for this tag.</description>
-			<required>true</required>
-			<type>org.mxchange.jphone.model.phonenumbers.mobile.DialableMobileNumber</type>
-		</attribute>
-		<attribute>
-			<name>contact</name>
-			<description>The contact instance that provides contact data for additional JSF links.</description>
-			<required>false</required>
-			<type>org.mxchange.jcontacts.model.contact.Contact</type>
-		</attribute>
-		<attribute>
-			<name>renderShowLink</name>
-			<description>Whether this tag is used to show mobile data (default true).</description>
-			<required>false</required>
-			<type>java.lang.Boolean</type>
-		</attribute>
-		<attribute>
-			<name>rendered</name>
-			<description>Whether this tag is being rendered by JSF engine (default: true).</description>
-			<required>false</required>
-			<type>java.lang.Boolean</type>
-		</attribute>
-	</tag>
-	<tag>
-		<tag-name>outputMobileProviderAdminDropdownMenu</tag-name>
-		<description>This tag renders a full h:panelGroup for an administrative drop-down menu for mobile provider data.</description>
-		<source>resources/tags/admin/dropdown/mobile_provider/admin_mobile_provider_links.tpl</source>
-		<attribute>
-			<name>mobileProvider</name>
-			<description>The mobile provider instance that provides the data for this tag.</description>
-			<required>true</required>
-			<type>org.mxchange.jphone.model.phonenumbers.mobileprovider.MobileProvider</type>
-		</attribute>
-		<attribute>
-			<name>renderShowLink</name>
-			<description>Whether this tag is used to show mobile provider data (default true).</description>
-			<required>false</required>
-			<type>java.lang.Boolean</type>
-		</attribute>
-		<attribute>
-			<name>rendered</name>
-			<description>Whether this tag is being rendered by JSF engine (default: true).</description>
-			<required>false</required>
-			<type>java.lang.Boolean</type>
-		</attribute>
-	</tag>
-	<tag>
-		<tag-name>outputBasicDataAdminDropdownMenu</tag-name>
-		<description>This tag renders an administrative drop-down menu for given basic data instance.</description>
-		<source>resources/tags/admin/dropdown/basic_data/admin_basic_data_links.tpl</source>
-		<attribute>
-			<name>basicData</name>
-			<description>The basic company data for this tag.</description>
-			<required>true</required>
-			<type>org.mxchange.jcontactsbusiness.model.basicdata.BusinessBasicData</type>
-		</attribute>
-		<attribute>
-			<name>renderShowLink</name>
-			<description>Whether to render (default: true) "show basic data" link.</description>
-			<required>false</required>
-			<type>java.langBoolean</type>
-		</attribute>
-		<attribute>
-			<name>rendered</name>
-			<description>Whether this tag is being rendered by JSF engine (default: true).</description>
-			<required>false</required>
-			<type>java.lang.Boolean</type>
-		</attribute>
-	</tag>
-	<tag>
-		<tag-name>outputHeadquarterAdminDropdownMenu</tag-name>
-		<description>This tag renders an administrative drop-down menu for given headquarter instance.</description>
-		<source>resources/tags/admin/dropdown/headquarter/admin_headquarter_links.tpl</source>
-		<attribute>
-			<name>headquarter</name>
-			<description>The headquarter instance that provides the data for this tag.</description>
-			<required>true</required>
-			<type>org.mxchange.jcontactsbusiness.model.headquarter.HeadquarterData</type>
-		</attribute>
-		<attribute>
-			<name>renderShowLink</name>
-			<description>Whether to render (default: true) "show headquarter" link.</description>
-			<required>false</required>
-			<type>java.langBoolean</type>
-		</attribute>
-		<attribute>
-			<name>rendered</name>
-			<description>Whether this tag is being rendered by JSF engine (default: true).</description>
-			<required>false</required>
-			<type>java.lang.Boolean</type>
-		</attribute>
-	</tag>
-	<tag>
-		<tag-name>outputBranchOfficeAdminDropdownMenu</tag-name>
-		<description>This tag renders an administrative drop-down menu for given branchOffice instance.</description>
-		<source>resources/tags/admin/dropdown/branch_office/admin_branch_office_links.tpl</source>
-		<attribute>
-			<name>branchOffice</name>
-			<description>The branch office instance that provides the data for this tag.</description>
-			<required>true</required>
-			<type>org.mxchange.jcontactsbusiness.model.branchoffice.BranchOffice</type>
-		</attribute>
-		<attribute>
-			<name>renderShowLink</name>
-			<description>Whether to render (default: true) "show branch office" link.</description>
-			<required>false</required>
-			<type>java.langBoolean</type>
-		</attribute>
-		<attribute>
-			<name>rendered</name>
-			<description>Whether this tag is being rendered by JSF engine (default: true).</description>
-			<required>false</required>
-			<type>java.lang.Boolean</type>
-		</attribute>
-	</tag>
-	<tag>
-		<tag-name>outputDepartmentAdminDropdownMenu</tag-name>
-		<description>This tag renders an administrative drop-down menu for given department instance.</description>
-		<source>resources/tags/admin/dropdown/department/admin_department_links.tpl</source>
-		<attribute>
-			<name>department</name>
-			<description>The department instance that provides the data for this tag.</description>
-			<required>true</required>
-			<type>org.mxchange.jcontactsbusiness.model.department.Department</type>
-		</attribute>
-		<attribute>
-			<name>renderShowLink</name>
-			<description>Whether to render (default: true) "show department" link.</description>
-			<required>false</required>
-			<type>java.langBoolean</type>
-		</attribute>
-		<attribute>
-			<name>rendered</name>
-			<description>Whether this tag is being rendered by JSF engine (default: true).</description>
-			<required>false</required>
-			<type>java.lang.Boolean</type>
-		</attribute>
-	</tag>
-	<tag>
-		<tag-name>outputEmployeeAdminDropdownMenu</tag-name>
-		<description>This tag renders an administrative drop-down menu for given employee instance.</description>
-		<source>resources/tags/admin/dropdown/employee/admin_employee_links.tpl</source>
-		<attribute>
-			<name>employee</name>
-			<description>The employee instance that provides the data for this tag.</description>
-			<required>true</required>
-			<type>org.mxchange.jcontactsbusiness.model.employee.Employee</type>
-		</attribute>
-		<attribute>
-			<name>renderShowLink</name>
-			<description>Whether to render (default: true) "show employee" link.</description>
-			<required>false</required>
-			<type>java.langBoolean</type>
-		</attribute>
-		<attribute>
-			<name>rendered</name>
-			<description>Whether this tag is being rendered by JSF engine (default: true).</description>
-			<required>false</required>
-			<type>java.lang.Boolean</type>
-		</attribute>
-	</tag>
-	<tag>
-		<tag-name>outputOpeningTimeAdminDropdownMenu</tag-name>
-		<description>This tag renders an administrative drop-down menu for given opening time instance.</description>
-		<source>resources/tags/admin/dropdown/opening_time/admin_opening_time_links.tpl</source>
-		<attribute>
-			<name>openingTime</name>
-			<description>The opening time instance that provides the data for this tag.</description>
-			<required>true</required>
-			<type>org.mxchange.jcontactsbusiness.model.opening_time.OpeningTimes</type>
-		</attribute>
-		<attribute>
-			<name>renderShowLink</name>
-			<description>Whether to render (default: true) "show opening time" link.</description>
-			<required>false</required>
-			<type>java.langBoolean</type>
-		</attribute>
-		<attribute>
-			<name>rendered</name>
-			<description>Whether this tag is being rendered by JSF engine (default: true).</description>
-			<required>false</required>
-			<type>java.lang.Boolean</type>
-		</attribute>
-	</tag>
 	<tag>
 		<tag-name>outputContactAdminDropdownMenu</tag-name>
 		<description>This tag renders an administrative drop-down menu for given contact instance.</description>
@@ -310,29 +62,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 			<type>java.lang.Boolean</type>
 		</attribute>
 	</tag>
-	<tag>
-		<tag-name>outputCountryAdminDropdownMenu</tag-name>
-		<description>This tag renders an administrative drop-down menu for given country instance.</description>
-		<source>resources/tags/admin/dropdown/country/admin_country_links.tpl</source>
-		<attribute>
-			<name>country</name>
-			<description>The country instance that provides the data for this tag.</description>
-			<required>true</required>
-			<type>org.mxchange.jcountry.model.data.Country</type>
-		</attribute>
-		<attribute>
-			<name>renderShowLink</name>
-			<description>Whether to render (default: true) "show country" link.</description>
-			<required>false</required>
-			<type>java.langBoolean</type>
-		</attribute>
-		<attribute>
-			<name>rendered</name>
-			<description>Whether this tag is being rendered by JSF engine (default: true).</description>
-			<required>false</required>
-			<type>java.lang.Boolean</type>
-		</attribute>
-	</tag>
 	<tag>
 		<tag-name>outputUserAdminDropdownMenu</tag-name>
 		<description>This tag renders an administrative drop-down menu for given user instance.</description>
diff --git a/web/WEB-INF/resources/tags/admin/columns/admin_contact_data_columns.tpl b/web/WEB-INF/resources/tags/admin/columns/admin_contact_data_columns.tpl
index 7be60aca..43fbd891 100644
--- a/web/WEB-INF/resources/tags/admin/columns/admin_contact_data_columns.tpl
+++ b/web/WEB-INF/resources/tags/admin/columns/admin_contact_data_columns.tpl
@@ -15,17 +15,17 @@
 	</p:column>
 
 	<p:column>
-		<p:outputLabel for="contactCreated" styleClass="table-data-label" value="#{msg.ADMIN_CONTACT_CREATED}" />
+		<p:outputLabel for="contactEntryCreated" styleClass="table-data-label" value="#{msg.ADMIN_CONTACT_CREATED}" />
 
-		<h:outputText id="contactCreated" styleClass="table-data-field" value="#{beanHelper.contact.contactCreated}">
+		<h:outputText id="contactEntryCreated" styleClass="table-data-field" value="#{beanHelper.contact.contactEntryCreated}">
 			<f:convertDateTime type="both" />
 		</h:outputText>
 	</p:column>
 
 	<p:column>
-		<p:outputLabel for="contactUpdated" styleClass="table-data-label" value="#{msg.ADMIN_CONTACT_UPDATED}" />
+		<p:outputLabel for="contactEntryUpdated" styleClass="table-data-label" value="#{msg.ADMIN_CONTACT_UPDATED}" />
 
-		<h:outputText id="contactUpdated" styleClass="table-data-field" value="#{beanHelper.contact.contactUpdated}">
+		<h:outputText id="contactEntryUpdated" styleClass="table-data-field" value="#{beanHelper.contact.contactEntryUpdated}">
 			<f:convertDateTime type="both" />
 		</h:outputText>
 	</p:column>
diff --git a/web/WEB-INF/resources/tags/admin/dropdown/basic_data/admin_basic_data_links.tpl b/web/WEB-INF/resources/tags/admin/dropdown/basic_data/admin_basic_data_links.tpl
deleted file mode 100644
index 86648287..00000000
--- a/web/WEB-INF/resources/tags/admin/dropdown/basic_data/admin_basic_data_links.tpl
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<ui:composition
-	xmlns="http://www.w3.org/1999/xhtml"
-	xmlns:f="http://java.sun.com/jsf/core"
-	xmlns:h="http://java.sun.com/jsf/html"
-	xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
-	xmlns:p="http://primefaces.org/ui"
-	>
-
-	<p:menuButton value="#{msg.OPTIONS}" rendered="#{empty rendered or rendered}">
-		<p:menuitem outcome="admin_show_basic_data" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_BASIC_DATA_TITLE}" rendered="#{empty renderShowLink or renderShowLink}">
-			<f:param name="basicDataId" value="#{basicData.basicDataId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_edit_basic_data" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_BASIC_DATA_TITLE}">
-			<f:param name="basicDataId" value="#{basicData.basicDataId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_delete_basic_data">
-			<h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_BASIC_DATA_TITLE}" />
-			<f:param name="basicDataId" value="#{basicData.basicDataId}" />
-		</p:menuitem>
-	</p:menuButton>
-</ui:composition>
diff --git a/web/WEB-INF/resources/tags/admin/dropdown/branch_office/admin_branch_office_links.tpl b/web/WEB-INF/resources/tags/admin/dropdown/branch_office/admin_branch_office_links.tpl
deleted file mode 100644
index 5967f146..00000000
--- a/web/WEB-INF/resources/tags/admin/dropdown/branch_office/admin_branch_office_links.tpl
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<ui:composition
-	xmlns="http://www.w3.org/1999/xhtml"
-	xmlns:f="http://java.sun.com/jsf/core"
-	xmlns:h="http://java.sun.com/jsf/html"
-	xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
-	xmlns:p="http://primefaces.org/ui"
-	>
-
-	<p:menuButton value="#{msg.OPTIONS}" rendered="#{empty rendered or rendered}">
-		<p:menuitem outcome="admin_show_branch_office" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_BRANCH_OFFICE_TITLE}" rendered="#{empty renderShowLink or renderShowLink}">
-			<f:param name="branchId" value="#{branchOffice.branchId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_edit_branch_office" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_BRANCH_OFFICE_TITLE}">
-			<f:param name="branchId" value="#{branchOffice.branchId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_delete_branch_office">
-			<h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_BRANCH_OFFICE_TITLE}" />
-			<f:param name="branchId" value="#{branchOffice.branchId}" />
-		</p:menuitem>
-	</p:menuButton>
-</ui:composition>
diff --git a/web/WEB-INF/resources/tags/admin/dropdown/country/admin_country_links.tpl b/web/WEB-INF/resources/tags/admin/dropdown/country/admin_country_links.tpl
deleted file mode 100644
index 869fb578..00000000
--- a/web/WEB-INF/resources/tags/admin/dropdown/country/admin_country_links.tpl
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<ui:composition
-	xmlns="http://www.w3.org/1999/xhtml"
-	xmlns:f="http://java.sun.com/jsf/core"
-	xmlns:h="http://java.sun.com/jsf/html"
-	xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
-	xmlns:p="http://primefaces.org/ui"
-	>
-
-	<p:menuButton value="#{msg.OPTIONS}" rendered="#{empty rendered or rendered}">
-		<p:menuitem outcome="admin_show_country" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_COUNTRY_TITLE}" rendered="#{empty renderShowLink or renderShowLink}">
-			<f:param name="countryId" value="#{country.countryId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_edit_country" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_COUNTRY_TITLE}">
-			<f:param name="countryId" value="#{country.countryId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_delete_country">
-			<h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_COUNTRY_TITLE}" />
-			<f:param name="countryId" value="#{country.countryId}" />
-		</p:menuitem>
-	</p:menuButton>
-</ui:composition>
diff --git a/web/WEB-INF/resources/tags/admin/dropdown/department/admin_department_links.tpl b/web/WEB-INF/resources/tags/admin/dropdown/department/admin_department_links.tpl
deleted file mode 100644
index ccc75cf8..00000000
--- a/web/WEB-INF/resources/tags/admin/dropdown/department/admin_department_links.tpl
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<ui:composition
-	xmlns="http://www.w3.org/1999/xhtml"
-	xmlns:f="http://java.sun.com/jsf/core"
-	xmlns:h="http://java.sun.com/jsf/html"
-	xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
-	xmlns:p="http://primefaces.org/ui"
-	>
-
-	<p:menuButton value="#{msg.OPTIONS}" rendered="#{empty rendered or rendered}">
-		<p:menuitem outcome="admin_show_department" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_DEPARTMENT_TITLE}" rendered="#{empty renderShowLink or renderShowLink}">
-			<f:param name="departmentId" value="#{department.departmentId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_edit_department" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_DEPARTMENT_TITLE}">
-			<f:param name="departmentId" value="#{department.departmentId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_delete_department">
-			<h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_DEPARTMENT_TITLE}" />
-			<f:param name="departmentId" value="#{department.departmentId}" />
-		</p:menuitem>
-	</p:menuButton>
-</ui:composition>
diff --git a/web/WEB-INF/resources/tags/admin/dropdown/employee/admin_employee_links.tpl b/web/WEB-INF/resources/tags/admin/dropdown/employee/admin_employee_links.tpl
deleted file mode 100644
index fe11cac5..00000000
--- a/web/WEB-INF/resources/tags/admin/dropdown/employee/admin_employee_links.tpl
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<ui:composition
-	xmlns="http://www.w3.org/1999/xhtml"
-	xmlns:f="http://java.sun.com/jsf/core"
-	xmlns:h="http://java.sun.com/jsf/html"
-	xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
-	xmlns:p="http://primefaces.org/ui"
-	>
-
-	<p:menuButton value="#{msg.OPTIONS}" rendered="#{empty rendered or rendered}">
-		<p:menuitem outcome="admin_show_employee" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_EMPLOYEE_TITLE}" rendered="#{empty renderShowLink or renderShowLink}">
-			<f:param name="employeeId" value="#{employee.employeeId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_edit_employee" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_EMPLOYEE_TITLE}">
-			<f:param name="employeeId" value="#{employee.employeeId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_delete_employee">
-			<h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_EMPLOYEE_TITLE}" />
-			<f:param name="employeeId" value="#{employee.employeeId}" />
-		</p:menuitem>
-	</p:menuButton>
-</ui:composition>
diff --git a/web/WEB-INF/resources/tags/admin/dropdown/fax/admin_fax_links.tpl b/web/WEB-INF/resources/tags/admin/dropdown/fax/admin_fax_links.tpl
deleted file mode 100644
index ab723678..00000000
--- a/web/WEB-INF/resources/tags/admin/dropdown/fax/admin_fax_links.tpl
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<ui:composition
-	xmlns="http://www.w3.org/1999/xhtml"
-	xmlns:f="http://java.sun.com/jsf/core"
-	xmlns:h="http://java.sun.com/jsf/html"
-	xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
-	xmlns:p="http://primefaces.org/ui"
-	>
-
-	<p:menuButton value="#{msg.OPTIONS}" rendered="#{empty rendered or rendered}">
-		<p:menuitem outcome="admin_show_fax" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_FAX_NUMBER_TITLE}" rendered="#{empty renderShowLink or renderShowLink}">
-			<f:param name="phoneId" value="#{faxNumber.phoneId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_edit_fax" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_FAX_NUMBER_TITLE}">
-			<f:param name="phoneId" value="#{faxNumber.phoneId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_unlink_contact_fax" rendered="#{not empty contact}">
-			<h:outputText styleClass="link-warning" value="#{msg.ADMIN_LINK_UNLINK_SHORT}" title="#{msg.ADMIN_LINK_UNLINK_FAX_NUMBER_CONTACT_TITLE}" />
-			<f:param name="phoneId" value="#{faxNumber.phoneId}" />
-			<f:param name="contactId" value="#{contact.contactId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_delete_fax">
-			<h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_FAX_NUMBER_TITLE}" />
-			<f:param name="phoneId" value="#{faxNumber.phoneId}" />
-		</p:menuitem>
-	</p:menuButton>
-</ui:composition>
diff --git a/web/WEB-INF/resources/tags/admin/dropdown/headquarter/admin_headquarter_links.tpl b/web/WEB-INF/resources/tags/admin/dropdown/headquarter/admin_headquarter_links.tpl
deleted file mode 100644
index 3809f0c7..00000000
--- a/web/WEB-INF/resources/tags/admin/dropdown/headquarter/admin_headquarter_links.tpl
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<ui:composition
-	xmlns="http://www.w3.org/1999/xhtml"
-	xmlns:f="http://java.sun.com/jsf/core"
-	xmlns:h="http://java.sun.com/jsf/html"
-	xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
-	xmlns:p="http://primefaces.org/ui"
-	>
-
-	<p:menuButton value="#{msg.OPTIONS}" rendered="#{empty rendered or rendered}">
-		<p:menuitem outcome="admin_show_headquarter" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_HEADQUARTER_TITLE}" rendered="#{empty renderShowLink or renderShowLink}">
-			<f:param name="headquarterId" value="#{headquarter.headquarterId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_edit_headquarter" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_HEADQUARTER_TITLE}">
-			<f:param name="headquarterId" value="#{headquarter.headquarterId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_delete_headquarter">
-			<h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_HEADQUARTER_TITLE}" />
-			<f:param name="headquarterId" value="#{headquarter.headquarterId}" />
-		</p:menuitem>
-	</p:menuButton>
-</ui:composition>
diff --git a/web/WEB-INF/resources/tags/admin/dropdown/landline/admin_landline_links.tpl b/web/WEB-INF/resources/tags/admin/dropdown/landline/admin_landline_links.tpl
deleted file mode 100644
index 77437135..00000000
--- a/web/WEB-INF/resources/tags/admin/dropdown/landline/admin_landline_links.tpl
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<ui:composition
-	xmlns="http://www.w3.org/1999/xhtml"
-	xmlns:f="http://java.sun.com/jsf/core"
-	xmlns:h="http://java.sun.com/jsf/html"
-	xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
-	xmlns:p="http://primefaces.org/ui"
-	>
-
-	<p:menuButton value="#{msg.OPTIONS}" rendered="#{empty rendered or rendered}">
-		<p:menuitem outcome="admin_show_landline" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_LAND_LINE_NUMBER_TITLE}" rendered="#{empty renderShowLink or renderShowLink}">
-			<f:param name="phoneId" value="#{landLineNumber.phoneId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_edit_landline" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_LAND_LINE_NUMBER_TITLE}">
-			<f:param name="phoneId" value="#{landLineNumber.phoneId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_unlink_contact_landline" rendered="#{not empty contact}">
-			<h:outputText styleClass="link-warning" value="#{msg.ADMIN_LINK_UNLINK_SHORT}" title="#{msg.ADMIN_LINK_UNLINK_LAND_LINE_NUMBER_CONTACT_TITLE}" />
-			<f:param name="phoneId" value="#{landLineNumber.phoneId}" />
-			<f:param name="contactId" value="#{contact.contactId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_delete_landline">
-			<h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_LAND_LINE_NUMBER_TITLE}" />
-			<f:param name="phoneId" value="#{landLineNumber.phoneId}" />
-		</p:menuitem>
-	</p:menuButton>
-</ui:composition>
diff --git a/web/WEB-INF/resources/tags/admin/dropdown/mobile/admin_mobile_links.tpl b/web/WEB-INF/resources/tags/admin/dropdown/mobile/admin_mobile_links.tpl
deleted file mode 100644
index 0a5d8eb7..00000000
--- a/web/WEB-INF/resources/tags/admin/dropdown/mobile/admin_mobile_links.tpl
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<ui:composition
-	xmlns="http://www.w3.org/1999/xhtml"
-	xmlns:f="http://java.sun.com/jsf/core"
-	xmlns:h="http://java.sun.com/jsf/html"
-	xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
-	xmlns:p="http://primefaces.org/ui"
-	>
-
-	<p:menuButton value="#{msg.OPTIONS}" rendered="#{empty rendered or rendered}">
-		<p:menuitem outcome="admin_show_mobile" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_MOBILE_NUMBER_TITLE}" rendered="#{empty renderShowLink or renderShowLink}">
-			<f:param name="phoneId" value="#{mobileNumber.phoneId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_edit_mobile" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_MOBILE_NUMBER_TITLE}">
-			<f:param name="phoneId" value="#{mobileNumber.phoneId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_unlink_contact_mobile" rendered="#{not empty contact}">
-			<h:outputText styleClass="link-warning" value="#{msg.ADMIN_LINK_UNLINK_SHORT}" title="#{msg.ADMIN_LINK_UNLINK_MOBILE_NUMBER_CONTACT_TITLE}" />
-			<f:param name="phoneId" value="#{mobileNumber.phoneId}" />
-			<f:param name="contactId" value="#{contact.contactId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_delete_mobile">
-			<h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_MOBILE_NUMBER_TITLE}" />
-			<f:param name="phoneId" value="#{mobileNumber.phoneId}" />
-		</p:menuitem>
-	</p:menuButton>
-</ui:composition>
diff --git a/web/WEB-INF/resources/tags/admin/dropdown/mobile_provider/admin_mobile_provider_links.tpl b/web/WEB-INF/resources/tags/admin/dropdown/mobile_provider/admin_mobile_provider_links.tpl
deleted file mode 100644
index eba65afc..00000000
--- a/web/WEB-INF/resources/tags/admin/dropdown/mobile_provider/admin_mobile_provider_links.tpl
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<ui:composition
-	xmlns="http://www.w3.org/1999/xhtml"
-	xmlns:f="http://java.sun.com/jsf/core"
-	xmlns:h="http://java.sun.com/jsf/html"
-	xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
-	xmlns:p="http://primefaces.org/ui"
-	>
-
-	<p:menuButton value="#{msg.OPTIONS}" rendered="#{empty rendered or rendered}">
-		<p:menuitem outcome="admin_show_mobile_provider" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_MOBILE_PROVIDER_TITLE}" rendered="#{empty renderShowLink or renderShowLink}">
-			<f:param name="providerId" value="#{mobileProvider.providerId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_edit_mobile_provider" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_MOBILE_PROVIDER_TITLE}">
-			<f:param name="providerId" value="#{mobileProvider.providerId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_delete_mobile_provider">
-			<h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_MOBILE_PROVIDER_TITLE}" />
-			<f:param name="providerId" value="#{mobileProvider.providerId}" />
-		</p:menuitem>
-	</p:menuButton>
-</ui:composition>
diff --git a/web/WEB-INF/resources/tags/admin/dropdown/opening_time/admin_opening_time_links.tpl b/web/WEB-INF/resources/tags/admin/dropdown/opening_time/admin_opening_time_links.tpl
deleted file mode 100644
index 9a8a733b..00000000
--- a/web/WEB-INF/resources/tags/admin/dropdown/opening_time/admin_opening_time_links.tpl
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<ui:composition
-	xmlns="http://www.w3.org/1999/xhtml"
-	xmlns:f="http://java.sun.com/jsf/core"
-	xmlns:h="http://java.sun.com/jsf/html"
-	xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
-	xmlns:p="http://primefaces.org/ui"
-	>
-
-	<p:menuButton value="#{msg.OPTIONS}" rendered="#{empty rendered or rendered}">
-		<p:menuitem outcome="admin_show_opening_time" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_OPENING_TIME_TITLE}" rendered="#{empty renderShowLink or renderShowLink}">
-			<f:param name="openingId" value="#{openingTime.openingId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_edit_opening_time" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_OPENING_TIME_TITLE}">
-			<f:param name="openingId" value="#{openingTime.openingId}" />
-		</p:menuitem>
-
-		<p:menuitem outcome="admin_delete_opening_time">
-			<h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_OPENING_TIME_TITLE}" />
-			<f:param name="openingId" value="#{openingTime.openingId}" />
-		</p:menuitem>
-	</p:menuButton>
-</ui:composition>
diff --git a/web/WEB-INF/resources/tags/admin/form_data/mobile/admin_form_mobile_data.tpl b/web/WEB-INF/resources/tags/admin/form_data/mobile/admin_form_mobile_data.tpl
index 9bffd379..265dad9f 100644
--- a/web/WEB-INF/resources/tags/admin/form_data/mobile/admin_form_mobile_data.tpl
+++ b/web/WEB-INF/resources/tags/admin/form_data/mobile/admin_form_mobile_data.tpl
@@ -20,7 +20,7 @@
 				</div>
 
 				<div class="table-right-medium">
-					<h:outputText id="mobileNumberId" value="#{mobileNumber.phoneId}" />
+					<h:outputText id="mobileNumberId" value="#{mobileNumber.mobileId}" />
 				</div>
 			</h:panelGroup>
 
@@ -40,7 +40,7 @@
 					<f:selectItem itemValue="#{null}" itemLabel="#{msg.NONE_SELECTED}" />
 
 					<f:selectItems
-						value="#{mobileProviderController.allMobileProviders()}"
+						value="#{mobileProviderListController.allMobileProviders}"
 						var="mobileProvider"
 						itemValue="#{mobileProvider}"
 						itemLabel="#{mobileProvider.providerCountry.countryExternalDialPrefix}#{mobileProvider.providerDialPrefix} (#{mobileProvider.providerName})"
diff --git a/web/WEB-INF/resources/tags/admin/panel_grids/fax/admin_fax_data.tpl b/web/WEB-INF/resources/tags/admin/panel_grids/fax/admin_fax_data.tpl
index d50ff5e5..f7de319d 100644
--- a/web/WEB-INF/resources/tags/admin/panel_grids/fax/admin_fax_data.tpl
+++ b/web/WEB-INF/resources/tags/admin/panel_grids/fax/admin_fax_data.tpl
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <ui:composition
 	xmlns="http://www.w3.org/1999/xhtml"
-	xmlns:links="http://mxchange.org/jsf/core/links"
 	xmlns:f="http://java.sun.com/jsf/core"
 	xmlns:h="http://java.sun.com/jsf/html"
 	xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
@@ -36,7 +35,7 @@
 		</p:column>
 
 		<p:column>
-			<p:outputLabel for="faxCreated" styleClass="table-data-label" value="#{msg.ADMIN_SHOW_PHONE_CREATED}" />
+			<p:outputLabel for="faxCreated" styleClass="table-data-label" value="#{msg.ENTRY_CREATED_HEADER}" />
 
 			<h:outputText id="faxCreated" styleClass="table-data-field" value="#{faxNumber.phoneEntryCreated}">
 				<f:convertDateTime type="both" />
@@ -44,7 +43,7 @@
 		</p:column>
 
 		<p:column>
-			<p:outputLabel for="faxUpdated" styleClass="table-data-label" value="#{msg.ADMIN_SHOW_PHONE_UPDATED}" />
+			<p:outputLabel for="faxUpdated" styleClass="table-data-label" value="#{msg.ENTRY_UPDATED_HEADER}" />
 
 			<h:outputText id="faxUpdated" styleClass="table-data-field" value="#{faxNumber.phoneEntryUpdated}">
 				<f:convertDateTime type="both" />
@@ -57,7 +56,26 @@
 			<p:outputLabel styleClass="table-data-label" value="#{msg.ADMIN_SHOW_ADMINISTRATIVE_LINKS}" />
 
 			<h:panelGroup styleClass="table-data-field" layout="block">
-				<links:outputFaxNumberAdminDropdownMenu faxNumber="#{faxNumber}" contact="#{contact}" renderShowLink="#{renderShowLink == true}" />
+				<p:menuButton value="#{msg.OPTIONS}" rendered="#{empty rendered or rendered}">
+					<p:menuitem outcome="admin_show_fax" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_FAX_NUMBER_TITLE}" rendered="#{empty renderShowLink or renderShowLink}">
+						<f:param name="phoneId" value="#{faxNumber.phoneId}" />
+					</p:menuitem>
+
+					<p:menuitem outcome="admin_edit_fax" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_FAX_NUMBER_TITLE}">
+						<f:param name="phoneId" value="#{faxNumber.phoneId}" />
+					</p:menuitem>
+
+					<p:menuitem outcome="admin_unlink_contact_fax" rendered="#{not empty contact}">
+						<h:outputText styleClass="link-warning" value="#{msg.ADMIN_LINK_UNLINK_SHORT}" title="#{msg.ADMIN_LINK_UNLINK_FAX_NUMBER_CONTACT_TITLE}" />
+						<f:param name="phoneId" value="#{faxNumber.phoneId}" />
+						<f:param name="contactId" value="#{contact.contactId}" />
+					</p:menuitem>
+
+					<p:menuitem outcome="admin_delete_fax">
+						<h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_FAX_NUMBER_TITLE}" />
+						<f:param name="phoneId" value="#{faxNumber.phoneId}" />
+					</p:menuitem>
+				</p:menuButton>
 			</h:panelGroup>
 		</p:column>
 	</p:panelGrid>
diff --git a/web/WEB-INF/resources/tags/admin/panel_grids/landline/admin_landline_data.tpl b/web/WEB-INF/resources/tags/admin/panel_grids/landline/admin_landline_data.tpl
index 87e71974..a4cb85dd 100644
--- a/web/WEB-INF/resources/tags/admin/panel_grids/landline/admin_landline_data.tpl
+++ b/web/WEB-INF/resources/tags/admin/panel_grids/landline/admin_landline_data.tpl
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <ui:composition
 	xmlns="http://www.w3.org/1999/xhtml"
-	xmlns:links="http://mxchange.org/jsf/core/links"
 	xmlns:f="http://java.sun.com/jsf/core"
 	xmlns:h="http://java.sun.com/jsf/html"
 	xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
@@ -36,7 +35,7 @@
 		</p:column>
 
 		<p:column>
-			<p:outputLabel for="landLineCreated" styleClass="table-data-label" value="#{msg.ADMIN_SHOW_PHONE_CREATED}" />
+			<p:outputLabel for="landLineCreated" styleClass="table-data-label" value="#{msg.ENTRY_CREATED_HEADER}" />
 
 			<h:outputText id="landLineCreated" styleClass="table-data-field" value="#{landLineNumber.phoneEntryCreated}">
 				<f:convertDateTime type="both" />
@@ -44,7 +43,7 @@
 		</p:column>
 
 		<p:column>
-			<p:outputLabel for="landLineUpdated" styleClass="table-data-label" value="#{msg.ADMIN_SHOW_PHONE_UPDATED}" />
+			<p:outputLabel for="landLineUpdated" styleClass="table-data-label" value="#{msg.ENTRY_UPDATED_HEADER}" />
 
 			<h:outputText id="landLineUpdated" styleClass="table-data-field" value="#{landLineNumber.phoneEntryUpdated}">
 				<f:convertDateTime type="both" />
@@ -57,7 +56,26 @@
 			<p:outputLabel styleClass="table-data-label" value="#{msg.ADMIN_SHOW_ADMINISTRATIVE_LINKS}" />
 
 			<h:panelGroup styleClass="table-data-field" layout="block">
-				<links:outputLandLineNumberAdminDropdownMenu landLineNumber="#{landLineNumber}" contact="#{contact}" renderShowLink="#{renderShowLink == true}" />
+				<p:menuButton value="#{msg.OPTIONS}" rendered="#{empty rendered or rendered}">
+					<p:menuitem outcome="admin_show_landline" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_LAND_LINE_NUMBER_TITLE}" rendered="#{empty renderShowLink or renderShowLink}">
+						<f:param name="phoneId" value="#{landLineNumber.phoneId}" />
+					</p:menuitem>
+
+					<p:menuitem outcome="admin_edit_landline" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_LAND_LINE_NUMBER_TITLE}">
+						<f:param name="phoneId" value="#{landLineNumber.phoneId}" />
+					</p:menuitem>
+
+					<p:menuitem outcome="admin_unlink_contact_landline" rendered="#{not empty contact}">
+						<h:outputText styleClass="link-warning" value="#{msg.ADMIN_LINK_UNLINK_SHORT}" title="#{msg.ADMIN_LINK_UNLINK_LAND_LINE_NUMBER_CONTACT_TITLE}" />
+						<f:param name="phoneId" value="#{landLineNumber.phoneId}" />
+						<f:param name="contactId" value="#{contact.contactId}" />
+					</p:menuitem>
+
+					<p:menuitem outcome="admin_delete_landline">
+						<h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_LAND_LINE_NUMBER_TITLE}" />
+						<f:param name="phoneId" value="#{landLineNumber.phoneId}" />
+					</p:menuitem>
+				</p:menuButton>
 			</h:panelGroup>
 		</p:column>
 	</p:panelGrid>
diff --git a/web/WEB-INF/resources/tags/admin/panel_grids/mobile/admin_mobile_data.tpl b/web/WEB-INF/resources/tags/admin/panel_grids/mobile/admin_mobile_data.tpl
index a5c6bfb2..5c4c16cf 100644
--- a/web/WEB-INF/resources/tags/admin/panel_grids/mobile/admin_mobile_data.tpl
+++ b/web/WEB-INF/resources/tags/admin/panel_grids/mobile/admin_mobile_data.tpl
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <ui:composition
 	xmlns="http://www.w3.org/1999/xhtml"
-	xmlns:links="http://mxchange.org/jsf/core/links"
 	xmlns:f="http://java.sun.com/jsf/core"
 	xmlns:h="http://java.sun.com/jsf/html"
 	xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
@@ -22,7 +21,7 @@
 		<p:column>
 			<p:outputLabel for="mobileNumberId" styleClass="table-data-label" value="#{msg.ADMIN_LABEL_ID_NUMBER}" />
 
-			<h:outputText id="mobileNumberId" styleClass="table-data-field" value="#{mobileNumber.phoneId}" />
+			<h:outputText id="mobileNumberId" styleClass="table-data-field" value="#{mobileNumber.mobileId}" />
 		</p:column>
 
 		<p:column>
@@ -44,7 +43,7 @@
 		</p:column>
 
 		<p:column>
-			<p:outputLabel for="mobileCreated" styleClass="table-data-label" value="#{msg.ADMIN_SHOW_PHONE_CREATED}" />
+			<p:outputLabel for="mobileCreated" styleClass="table-data-label" value="#{msg.ENTRY_CREATED_HEADER}" />
 
 			<h:outputText id="mobileCreated" styleClass="table-data-field" value="#{mobileNumber.phoneEntryCreated}">
 				<f:convertDateTime type="both" />
@@ -52,7 +51,7 @@
 		</p:column>
 
 		<p:column>
-			<p:outputLabel for="mobileUpdated" styleClass="table-data-label" value="#{msg.ADMIN_SHOW_PHONE_UPDATED}" />
+			<p:outputLabel for="mobileUpdated" styleClass="table-data-label" value="#{msg.ENTRY_UPDATED_HEADER}" />
 
 			<h:outputText id="mobileUpdated" styleClass="table-data-field" value="#{mobileNumber.phoneEntryUpdated}">
 				<f:convertDateTime type="both" />
@@ -65,7 +64,26 @@
 			<p:outputLabel styleClass="table-data-label" value="#{msg.ADMIN_SHOW_ADMINISTRATIVE_LINKS}" />
 
 			<h:panelGroup styleClass="table-data-field" layout="block">
-				<links:outputMobileNumberAdminDropdownMenu mobileNumber="#{mobileNumber}" contact="#{contact}" renderShowLink="#{renderShowLink == true}" />
+				<p:menuButton value="#{msg.OPTIONS}" rendered="#{empty rendered or rendered}">
+					<p:menuitem outcome="admin_show_mobile" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_MOBILE_NUMBER_TITLE}" rendered="#{empty renderShowLink or renderShowLink}">
+						<f:param name="phoneId" value="#{mobileNumber.mobileId}" />
+					</p:menuitem>
+
+					<p:menuitem outcome="admin_edit_mobile" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_MOBILE_NUMBER_TITLE}">
+						<f:param name="phoneId" value="#{mobileNumber.mobileId}" />
+					</p:menuitem>
+
+					<p:menuitem outcome="admin_unlink_contact_mobile" rendered="#{not empty contact}">
+						<h:outputText styleClass="link-warning" value="#{msg.ADMIN_LINK_UNLINK_SHORT}" title="#{msg.ADMIN_LINK_UNLINK_MOBILE_NUMBER_CONTACT_TITLE}" />
+						<f:param name="phoneId" value="#{mobileNumber.mobileId}" />
+						<f:param name="contactId" value="#{contact.contactId}" />
+					</p:menuitem>
+
+					<p:menuitem outcome="admin_delete_mobile">
+						<h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_MOBILE_NUMBER_TITLE}" />
+						<f:param name="phoneId" value="#{mobileNumber.mobileId}" />
+					</p:menuitem>
+				</p:menuButton>
 			</h:panelGroup>
 		</p:column>
 	</p:panelGrid>
diff --git a/web/WEB-INF/resources/tags/input/panel_grid/mobile_input_panel_grid.tpl b/web/WEB-INF/resources/tags/input/panel_grid/mobile_input_panel_grid.tpl
index 59b7ca91..d9280ede 100644
--- a/web/WEB-INF/resources/tags/input/panel_grid/mobile_input_panel_grid.tpl
+++ b/web/WEB-INF/resources/tags/input/panel_grid/mobile_input_panel_grid.tpl
@@ -15,7 +15,12 @@
 			>
 			<f:converter converterId="MobileProviderConverter" />
 			<f:selectItem itemValue="#{null}" itemLabel="#{msg.NONE_SELECTED}" />
-			<f:selectItems value="#{mobileProviderController.allMobileProviders()}" var="mobileProvider" itemValue="#{mobileProvider}" itemLabel="#{mobileProvider.providerCountry.countryExternalDialPrefix}#{mobileProvider.providerDialPrefix} (#{mobileProvider.providerName})" />
+			<f:selectItems
+				value="#{mobileProviderListController.allMobileProviders}"
+				var="mobileProvider"
+				itemValue="#{mobileProvider}"
+				itemLabel="#{mobileProvider.providerCountry.countryExternalDialPrefix}#{mobileProvider.providerDialPrefix} (#{mobileProvider.providerName})"
+				/>
 		</p:selectOneMenu>
 
 		<p:inputText id="mobileNumber" size="10" maxlength="20" value="#{targetController.mobileNumber}">
diff --git a/web/WEB-INF/resources/tags/table_rows/user_profile_mode_table_row.tpl b/web/WEB-INF/resources/tags/table_rows/user_profile_mode_table_row.tpl
deleted file mode 100644
index 7f6432bc..00000000
--- a/web/WEB-INF/resources/tags/table_rows/user_profile_mode_table_row.tpl
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<ui:composition
-	xmlns="http://www.w3.org/1999/xhtml"
-	xmlns:f="http://java.sun.com/jsf/core"
-	xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
-	xmlns:p="http://primefaces.org/ui"
-	>
-
-	<p:row rendered="#{empty rendered or rendered == true}">
-		<p:outputLabel for="profileMode" value="#{labelMessage}" />
-
-		<p:selectOneMenu
-			id="profileMode"
-			value="#{targetController.userProfileMode}"
-			filter="true"
-			filterMatchMode="contains"
-			>
-
-			<f:selectItem itemValue="#{null}" itemLabel="#{msg.PLEASE_SELECT}" noSelectionOption="true" itemDisabled="true" />
-
-			<f:selectItems
-				value="#{dataController.profileModes}"
-				var="profileMode"
-				itemValue="#{profileMode}"
-				itemLabel="#{msg[profileMode.messageKey]}"
-				/>
-		</p:selectOneMenu>
-
-		<p:message for="personalTitle" />
-	</p:row>
-</ui:composition>
diff --git a/web/WEB-INF/templates/admin/basic_data/admin_form_basic_data.tpl b/web/WEB-INF/templates/admin/basic_data/admin_form_basic_data.tpl
index a3926ae3..79b1bc88 100644
--- a/web/WEB-INF/templates/admin/basic_data/admin_form_basic_data.tpl
+++ b/web/WEB-INF/templates/admin/basic_data/admin_form_basic_data.tpl
@@ -92,7 +92,7 @@
 					<f:selectItem itemValue="#{null}" itemLabel="#{msg.NONE_SELECTED}" />
 
 					<f:selectItems
-						value="#{employeeController.allEmployees()}"
+						value="#{employeeListController.allEmployees}"
 						var="companyEmployee"
 						itemValue="#{companyEmployee}"
 						itemLabel="#{beanHelper.renderEmployee(companyEmployee)}"
@@ -112,7 +112,7 @@
 					<f:selectItem itemValue="#{null}" itemLabel="#{msg.NONE_SELECTED}" />
 
 					<f:selectItems
-						value="#{employeeController.allEmployees()}"
+						value="#{employeeListController.allEmployees}"
 						var="companyEmployee"
 						itemValue="#{companyEmployee}"
 						itemLabel="#{beanHelper.renderEmployee(companyEmployee)}"
diff --git a/web/WEB-INF/templates/admin/branch_office/admin_form_branch_office_data.tpl b/web/WEB-INF/templates/admin/branch_office/admin_form_branch_office_data.tpl
index 7421b753..e39371c3 100644
--- a/web/WEB-INF/templates/admin/branch_office/admin_form_branch_office_data.tpl
+++ b/web/WEB-INF/templates/admin/branch_office/admin_form_branch_office_data.tpl
@@ -53,7 +53,7 @@
 				<f:selectItem itemValue="#{null}" itemLabel="#{msg.NONE_SELECTED}" />
 
 				<f:selectItems
-					value="#{employeeController.allEmployees()}"
+					value="#{employeeListController.allEmployees}"
 					var="companyEmployee"
 					itemValue="#{companyEmployee}"
 					itemLabel="#{beanHelper.renderEmployee(companyEmployee)}"
@@ -73,7 +73,7 @@
 				<f:selectItem itemValue="#{null}" itemLabel="#{msg.NONE_SELECTED}" />
 
 				<f:selectItems
-					value="#{employeeController.allEmployees()}"
+					value="#{employeeListController.allEmployees}"
 					var="companyEmployee"
 					itemValue="#{companyEmployee}"
 					itemLabel="#{beanHelper.renderEmployee(companyEmployee)}"
diff --git a/web/WEB-INF/templates/admin/department/admin_form_department_data.tpl b/web/WEB-INF/templates/admin/department/admin_form_department_data.tpl
index e8ecea93..2233585d 100644
--- a/web/WEB-INF/templates/admin/department/admin_form_department_data.tpl
+++ b/web/WEB-INF/templates/admin/department/admin_form_department_data.tpl
@@ -59,7 +59,7 @@
 				<f:selectItem itemValue="#{null}" itemLabel="#{msg.NONE_SELECTED}" />
 
 				<f:selectItems
-					value="#{branchOfficeListController.allBranchOffices()}"
+					value="#{branchOfficeListController.allBranchOffices}"
 					var="branchOffice"
 					itemValue="#{branchOffice}"
 					itemLabel="#{beanHelper.renderBranchOffice(branchOffice)}"
@@ -99,7 +99,7 @@
 				<f:selectItem itemValue="#{null}" itemLabel="#{msg.NONE_SELECTED}" />
 
 				<f:selectItems
-					value="#{employeeController.allEmployees()}"
+					value="#{employeeListController.allEmployees}"
 					var="employee"
 					itemValue="#{employee}"
 					itemLabel="#{beanHelper.renderEmployee(employee)}"
diff --git a/web/WEB-INF/templates/admin/employee/admin_form_employee_data.tpl b/web/WEB-INF/templates/admin/employee/admin_form_employee_data.tpl
index b6acdd78..b2afd25f 100644
--- a/web/WEB-INF/templates/admin/employee/admin_form_employee_data.tpl
+++ b/web/WEB-INF/templates/admin/employee/admin_form_employee_data.tpl
@@ -58,7 +58,7 @@
 				<f:selectItem itemValue="#{null}" itemLabel="#{msg.NONE_SELECTED}" />
 
 				<f:selectItems
-					value="#{branchOfficeListController.allBranchOffices()}"
+					value="#{branchOfficeListController.allBranchOffices}"
 					var="branchOffice"
 					itemValue="#{branchOffice}"
 					itemLabel="#{beanHelper.renderBranchOffice(branchOffice)}"
diff --git a/web/WEB-INF/templates/admin/fax/admin_form_add_contact_fax.tpl b/web/WEB-INF/templates/admin/fax/admin_form_add_contact_fax.tpl
index 7e928833..65dab7cf 100644
--- a/web/WEB-INF/templates/admin/fax/admin_form_add_contact_fax.tpl
+++ b/web/WEB-INF/templates/admin/fax/admin_form_add_contact_fax.tpl
@@ -32,7 +32,7 @@
 						<f:selectItem itemValue="#{null}" itemLabel="#{msg.NONE_SELECTED}" />
 
 						<f:selectItems
-							value="#{adminPhoneController.allNonLinkedFaxNumbers()}"
+							value="#{adminPhoneListController.allNonLinkedFaxNumbers}"
 							var="faxNumber"
 							itemValue="#{faxNumber}"
 							itemLabel="#{faxNumber.phoneCountry.countryExternalDialPrefix} (#{faxNumber.phoneAreaCode}) #{faxNumber.phoneNumber}"
diff --git a/web/WEB-INF/templates/admin/headquarter/admin_form_headquarter.tpl b/web/WEB-INF/templates/admin/headquarter/admin_form_headquarter.tpl
index 3daa375a..396c483b 100644
--- a/web/WEB-INF/templates/admin/headquarter/admin_form_headquarter.tpl
+++ b/web/WEB-INF/templates/admin/headquarter/admin_form_headquarter.tpl
@@ -44,7 +44,7 @@
 				<f:selectItem itemValue="#{null}" itemLabel="#{msg.NONE_SELECTED}" />
 
 				<f:selectItems
-					value="#{employeeController.allEmployees()}"
+					value="#{employeeListController.allEmployees}"
 					var="companyEmployee"
 					itemValue="#{companyEmployee}"
 					itemLabel="#{beanHelper.renderEmployee(companyEmployee)}"
diff --git a/web/WEB-INF/templates/admin/landline/admin_form_add_contact_landline.tpl b/web/WEB-INF/templates/admin/landline/admin_form_add_contact_landline.tpl
index 57870cb4..4d9d9740 100644
--- a/web/WEB-INF/templates/admin/landline/admin_form_add_contact_landline.tpl
+++ b/web/WEB-INF/templates/admin/landline/admin_form_add_contact_landline.tpl
@@ -32,7 +32,7 @@
 						<f:selectItem itemValue="#{null}" itemLabel="#{msg.NONE_SELECTED}" />
 
 						<f:selectItems
-							value="#{adminPhoneController.allNonLinkedLandLineNumbers()}"
+							value="#{adminPhoneListController.allNonLinkedLandLineNumbers}"
 							var="landlineNumber"
 							itemValue="#{landlineNumber}"
 							itemLabel="#{landlineNumber.phoneCountry.countryExternalDialPrefix} (#{landlineNumber.phoneAreaCode}) #{landlineNumber.phoneNumber}"
diff --git a/web/WEB-INF/templates/admin/mobile/admin_form_add_contact_mobile.tpl b/web/WEB-INF/templates/admin/mobile/admin_form_add_contact_mobile.tpl
index 4cbcf12b..c69cc57f 100644
--- a/web/WEB-INF/templates/admin/mobile/admin_form_add_contact_mobile.tpl
+++ b/web/WEB-INF/templates/admin/mobile/admin_form_add_contact_mobile.tpl
@@ -32,7 +32,7 @@
 						<f:selectItem itemValue="#{null}" itemLabel="#{msg.NONE_SELECTED}" />
 
 						<f:selectItems
-							value="#{adminPhoneController.allNonLinkedMobileNumbers()}"
+							value="#{adminPhoneListController.allNonLinkedMobileNumbers}"
 							var="mobileNumber"
 							itemValue="#{mobileNumber}"
 							itemLabel="#{beanHelper.renderMobileNumber(mobileNumber)}"
diff --git a/web/WEB-INF/templates/contact/form_contact_data.tpl b/web/WEB-INF/templates/contact/form_contact_data.tpl
index f64ef0b7..05aab6b4 100644
--- a/web/WEB-INF/templates/contact/form_contact_data.tpl
+++ b/web/WEB-INF/templates/contact/form_contact_data.tpl
@@ -228,7 +228,26 @@
 				<h:outputText value="#{msg.USER_PROFILE_LEGEND}" />
 			</legend>
 
-			<core:outputProfileModeTableRow targetController="#{userController}" labelMessage="#{msg.USER_PROFILE_MODE}" />
+			<h:panelGroup styleClass="table-row" layout="block">
+				<p:outputLabel for="profileMode" value="#{msg.USER_PROFILE_MODE}" />
+
+				<p:selectOneMenu
+					id="profileMode"
+					value="#{targetController.userProfileMode}"
+					filter="true"
+					filterMatchMode="contains"
+					>
+
+					<f:selectItem itemValue="#{null}" itemLabel="#{msg.PLEASE_SELECT}" noSelectionOption="true" itemDisabled="true" />
+
+					<f:selectItems
+						value="#{dataController.profileModes}"
+						var="profileMode"
+						itemValue="#{profileMode}"
+						itemLabel="#{msg[profileMode.messageKey]}"
+						/>
+				</p:selectOneMenu>
+			</h:panelGroup>
 
 			<h:panelGroup styleClass="table-row" layout="block">
 				<div class="para notice">
diff --git a/web/WEB-INF/templates/guest/user/guest_login_form.tpl b/web/WEB-INF/templates/guest/user/guest_login_form.tpl
index b55fd895..ce1f7f28 100644
--- a/web/WEB-INF/templates/guest/user/guest_login_form.tpl
+++ b/web/WEB-INF/templates/guest/user/guest_login_form.tpl
@@ -25,7 +25,7 @@
 						</div>
 
 						<div class="table-right">
-							<p:inputText id="userName" value="#{userController.userName}" size="10" maxlength="20" required="true" requiredMessage="#{msg.LOGIN_NO_USER_NAME_MESSAGE}" />
+							<p:inputText id="userName" value="#{userLoginController.userName}" size="10" maxlength="20" required="true" requiredMessage="#{msg.LOGIN_NO_USER_NAME_MESSAGE}" />
 						</div>
 					</h:panelGroup>
 
@@ -39,7 +39,7 @@
 						</div>
 
 						<div class="table-right">
-							<p:inputText type="secret" id="userPassword" value="#{userController.userPassword}" size="10" maxlength="255" required="true" requiredMessage="#{msg.LOGIN_NO_PASSWORD_MESSAGE}" />
+							<p:inputText type="secret" id="userPassword" value="#{userLoginController.userPassword}" size="10" maxlength="255" required="true" requiredMessage="#{msg.LOGIN_NO_PASSWORD_MESSAGE}" />
 						</div>
 					</h:panelGroup>
 
diff --git a/web/WEB-INF/templates/guest/user/register/guest_form_register_page1.tpl b/web/WEB-INF/templates/guest/user/register/guest_form_register_page1.tpl
index fcd38724..23c7b37e 100644
--- a/web/WEB-INF/templates/guest/user/register/guest_form_register_page1.tpl
+++ b/web/WEB-INF/templates/guest/user/register/guest_form_register_page1.tpl
@@ -26,7 +26,14 @@
 							</div>
 
 							<div class="table-right-medium">
-								<p:inputText id="userName" size="20" maxlength="255" value="#{userController.userName}" required="true" requiredMessage="#{msg.GUEST_REGISTRATION_USER_NAME_NOT_ENTERED}" />
+								<p:inputText
+									id="userName"
+									size="20"
+									maxlength="255"
+									value="#{userRegistrationController.userName}"
+									required="true"
+									requiredMessage="#{msg.GUEST_REGISTRATION_USER_NAME_NOT_ENTERED}"
+									/>
 							</div>
 						</h:panelGroup>
 
@@ -46,7 +53,7 @@
 							</div>
 
 							<div class="table-right-medium">
-								<p:inputText type="secret" id="userPassword" size="10" maxlength="255" value="#{userController.userPassword}" required="#{not featureController.isFeatureEnabled('allow_user_registration_empty_password')}" requiredMessage="#{msg.GUEST_REGISTRATION_PASSWORD_NOT_ENTERED}" />
+								<p:inputText type="secret" id="userPassword" size="10" maxlength="255" value="#{userRegistrationController.userPassword}" required="#{not featureController.isFeatureEnabled('allow_user_registration_empty_password')}" requiredMessage="#{msg.GUEST_REGISTRATION_PASSWORD_NOT_ENTERED}" />
 							</div>
 						</h:panelGroup>
 
@@ -60,7 +67,7 @@
 							</div>
 
 							<div class="table-right-medium">
-								<p:inputText type="secret" id="userPasswordRepeat" size="10" maxlength="255" value="#{userController.userPasswordRepeat}" required="#{not featureController.isFeatureEnabled('allow_user_registration_empty_password')}" requiredMessage="#{msg.GUEST_REGISTRATION_PASSWORD_REPEAT_NOT_ENTERED}" />
+								<p:inputText type="secret" id="userPasswordRepeat" size="10" maxlength="255" value="#{userRegistrationController.userPasswordRepeat}" required="#{not featureController.isFeatureEnabled('allow_user_registration_empty_password')}" requiredMessage="#{msg.GUEST_REGISTRATION_PASSWORD_REPEAT_NOT_ENTERED}" />
 							</div>
 						</h:panelGroup>
 
diff --git a/web/WEB-INF/templates/guest/user/register/guest_form_register_page2.tpl b/web/WEB-INF/templates/guest/user/register/guest_form_register_page2.tpl
index b6342704..5bdccf1b 100644
--- a/web/WEB-INF/templates/guest/user/register/guest_form_register_page2.tpl
+++ b/web/WEB-INF/templates/guest/user/register/guest_form_register_page2.tpl
@@ -13,7 +13,9 @@
 				<h:outputText value="#{msg.GUEST_REGISTRATION_PAGE2_TITLE}" />
 			</div>
 
-			<ui:include src="/WEB-INF/templates/contact/form_contact_data.tpl" />
+			<ui:include src="/WEB-INF/templates/contact/form_contact_data.tpl">
+				<ui:param name="targetController" value="#{userRegistrationController}" />
+			</ui:include>
 
 			<p:panelGrid columns="2" layout="grid">
 				<p:commandButton
diff --git a/web/WEB-INF/templates/guest/user/register/guest_form_register_single.tpl b/web/WEB-INF/templates/guest/user/register/guest_form_register_single.tpl
index d99a8f80..98cec771 100644
--- a/web/WEB-INF/templates/guest/user/register/guest_form_register_single.tpl
+++ b/web/WEB-INF/templates/guest/user/register/guest_form_register_single.tpl
@@ -13,7 +13,9 @@
 				<h:outputText value="#{msg.GUEST_REGISTRATION_TITLE}" />
 			</div>
 
-			<ui:include src="/WEB-INF/templates/contact/form_contact_data.tpl" />
+			<ui:include src="/WEB-INF/templates/contact/form_contact_data.tpl">
+				<ui:param name="targetController" value="#{userRegistrationController}" />
+			</ui:include>
 
 			<div class="para">
 				<fieldset class="fieldset">
@@ -28,7 +30,14 @@
 							</div>
 
 							<div class="table-right">
-								<p:inputText id="userName" size="20" maxlength="255" value="#{userController.userName}" required="true" requiredMessage="#{msg.GUEST_REGISTRATION_USER_NAME_NOT_ENTERED}" />
+								<p:inputText
+									id="userName"
+									size="20"
+									maxlength="255"
+									value="#{userRegistrationController.userName}"
+									required="true"
+									requiredMessage="#{msg.GUEST_REGISTRATION_USER_NAME_NOT_ENTERED}"
+									/>
 							</div>
 						</h:panelGroup>
 
@@ -48,7 +57,7 @@
 							</div>
 
 							<div class="table-right">
-								<p:inputText type="secret" id="userPassword" size="10" maxlength="255" value="#{userController.userPassword}" />
+								<p:inputText type="secret" id="userPassword" size="10" maxlength="255" value="#{userRegistrationController.userPassword}" />
 							</div>
 						</h:panelGroup>
 
@@ -62,7 +71,7 @@
 							</div>
 
 							<div class="table-right">
-								<p:inputText type="secret" id="userPasswordRepeat" size="10" maxlength="255" value="#{userController.userPasswordRepeat}" />
+								<p:inputText type="secret" id="userPasswordRepeat" size="10" maxlength="255" value="#{userRegistrationController.userPasswordRepeat}" />
 							</div>
 						</h:panelGroup>
 
diff --git a/web/WEB-INF/web.xml b/web/WEB-INF/web.xml
index 0f912c06..c181c427 100644
--- a/web/WEB-INF/web.xml
+++ b/web/WEB-INF/web.xml
@@ -153,10 +153,15 @@
         <param-value>true</param-value>
     </context-param>
     <context-param>
-        <description>Whether the public user profile is enabled. If this option is enabled, the setting "is_user_login_require_user_name" must also be enabled as it is mandadory.</description>
+        <description>Whether the public user profile is enabled. If this option is enabled, the setting "is_feature_user_login_require_username_enabled" must also be enabled as it is mandadory.</description>
         <param-name>is_feature_public_user_profile_enabled</param-name>
         <param-value>true</param-value>
     </context-param>
+    <context-param>
+        <description>Whether user names are required for completing registration.</description>
+        <param-name>is_feature_user_login_require_username_enabled</param-name>
+        <param-value>true</param-value>
+    </context-param>
     <context-param>
         <description>Maximum passwords that must be different.</description>
         <param-name>max_user_password_history</param-name>
diff --git a/web/WEB-INF/widgets.jsf.taglib.xml b/web/WEB-INF/widgets.jsf.taglib.xml
index abc546d8..b2e5cbfe 100644
--- a/web/WEB-INF/widgets.jsf.taglib.xml
+++ b/web/WEB-INF/widgets.jsf.taglib.xml
@@ -86,30 +86,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 			<type>org.mxchange.jcoreee.bean.faces.BaseFacesBean</type>
 		</attribute>
 	</tag>
-	<tag>
-		<tag-name>outputProfileModeTableRow</tag-name>
-		<description>This tag renders a selection box for user's profile mode.</description>
-		<source>resources/tags/table_rows/user_profile_mode_table_row.tpl</source>
-		<attribute>
-			<name>labelMessage</name>
-			<description>A localized message for the rendered label tag. You should use EL code here to add a label message from your bundle.</description>
-			<required>true</required>
-			<type>java.lang.String</type>
-		</attribute>
-		<attribute>
-			<name>rendered</name>
-			<description>Whether this tag is being rendered by JSF engine (default: true).</description>
-			<required>false</required>
-			<type>java.lang.Boolean</type>
-		</attribute>
-		<attribute>
-			<name>targetController</name>
-			<description>A target backing bean (EL code resolving into it) extending at least BaseFacesBean where to set the data in.</description>
-			<required>true</required>
-			<!-- @TODO Find an interface for BaseFacesBean and set it here instead -->
-			<type>org.mxchange.jcoreee.bean.faces.BaseFacesBean</type>
-		</attribute>
-	</tag>
 	<tag>
 		<tag-name>outputAdminContactDataFormFields</tag-name>
 		<description>This tag renders a fieldset for administrative purposes of contact data.</description>
diff --git a/web/admin/basic_data/admin_basic_data_list.xhtml b/web/admin/basic_data/admin_basic_data_list.xhtml
index 71952482..fb75adfd 100644
--- a/web/admin/basic_data/admin_basic_data_list.xhtml
+++ b/web/admin/basic_data/admin_basic_data_list.xhtml
@@ -144,7 +144,7 @@
 							<f:converter converterId="EmployeeConverter" />
 
 							<f:selectItems
-								value="#{employeeController.allEmployees()}"
+								value="#{employeeListController.allEmployees}"
 								var="employee"
 								itemValue="#{employee}"
 								itemLabel="#{beanHelper.renderEmployee(employee)}"
@@ -189,7 +189,7 @@
 							<f:converter converterId="EmployeeConverter" />
 
 							<f:selectItems
-								value="#{employeeController.allEmployees()}"
+								value="#{employeeListController.allEmployees}"
 								var="employee"
 								itemValue="#{employee}"
 								itemLabel="#{beanHelper.renderEmployee(employee)}"
@@ -270,13 +270,42 @@
 					<h:outputText value="#{basicData.companyTaxNumber}" />
 				</p:column>
 
+				<p:column
+					headerText="#{msg.LANDLINE_NUMBER_HEADER}"
+					sortBy="#{basicData.companyLandLineNumber}"
+					filterBy="#{basicData.companyLandLineNumber}"
+					filterMatchMode="contains"
+					>
+					<h:outputText value="#{beanHelper.renderPhoneNumber(basicData.companyLandLineNumber)}" />
+				</p:column>
+
+				<p:column
+					headerText="#{msg.FAX_NUMBER_HEADER}"
+					sortBy="#{basicData.companyFaxNumber}"
+					filterBy="#{basicData.companyFaxNumber}"
+					filterMatchMode="contains"
+					>
+					<h:outputText value="#{beanHelper.renderPhoneNumber(basicData.companyFaxNumber)}" />
+				</p:column>
+
 				<p:column
 					headerText="#{msg.ENTRY_CREATED_HEADER}"
-					sortBy="#{basicData.companyCreated}"
-					filterBy="#{basicData.companyCreated}"
+					sortBy="#{basicData.companyEntryCreated}"
+					filterBy="#{basicData.companyEntryCreated}"
 					filterMatchMode="contains"
 					>
-					<h:outputText value="#{basicData.companyCreated}">
+					<h:outputText value="#{basicData.companyEntryCreated}">
+						<f:convertDateTime type="both" timeStyle="short" dateStyle="short" />
+					</h:outputText>
+				</p:column>
+
+				<p:column
+					headerText="#{msg.ENTRY_UPDATED_HEADER}"
+					sortBy="#{basicData.companyEntryUpdated}"
+					filterBy="#{basicData.companyEntryUpdated}"
+					filterMatchMode="contains"
+					>
+					<h:outputText value="#{basicData.companyEntryUpdated}">
 						<f:convertDateTime type="both" timeStyle="short" dateStyle="short" />
 					</h:outputText>
 				</p:column>
@@ -286,7 +315,32 @@
 					sortable="false"
 					filterable="false"
 					>
-					<links:outputBasicDataAdminDropdownMenu basicData="#{basicData}" />
+					<p:menuButton value="#{msg.OPTIONS}">
+						<p:menuitem
+							outcome="admin_show_basic_data"
+							value="#{msg.ADMIN_LINK_SHOW_SHORT}"
+							title="#{msg.ADMIN_LINK_SHOW_BASIC_DATA_TITLE}"
+							>
+							<f:param name="basicDataId" value="#{basicData.basicDataId}" />
+						</p:menuitem>
+
+						<p:menuitem
+							outcome="admin_edit_basic_data"
+							value="#{msg.ADMIN_LINK_EDIT_SHORT}"
+							title="#{msg.ADMIN_LINK_EDIT_BASIC_DATA_TITLE}"
+							>
+							<f:param name="basicDataId" value="#{basicData.basicDataId}" />
+						</p:menuitem>
+
+						<p:menuitem outcome="admin_delete_basic_data">
+							<h:outputText
+								styleClass="link-danger"
+								value="#{msg.ADMIN_LINK_DELETE_SHORT}"
+								title="#{msg.ADMIN_LINK_DELETE_BASIC_DATA_TITLE}"
+								/>
+							<f:param name="basicDataId" value="#{basicData.basicDataId}" />
+						</p:menuitem>
+					</p:menuButton>
 				</p:column>
 			</p:dataTable>
 
diff --git a/web/admin/branch_office/admin_branch_office_list.xhtml b/web/admin/branch_office/admin_branch_office_list.xhtml
index 26522083..fa234ae3 100644
--- a/web/admin/branch_office/admin_branch_office_list.xhtml
+++ b/web/admin/branch_office/admin_branch_office_list.xhtml
@@ -23,7 +23,7 @@
 			<p:dataTable
 				id="branchOfficeList"
 				var="branchOffice"
-				value="#{branchOfficeListController.allBranchOffices()}"
+				value="#{branchOfficeListController.allBranchOffices}"
 				paginator="true"
 				paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
 				filteredValue="#{branchOfficeListController.filteredBranchOffices}"
@@ -235,7 +235,7 @@
 							<f:converter converterId="EmployeeConverter" />
 
 							<f:selectItems
-								value="#{employeeController.allEmployees()}"
+								value="#{employeeListController.allEmployees}"
 								var="employee"
 								itemValue="#{employee}"
 								itemLabel="#{beanHelper.renderEmployee(employee)}"
@@ -264,10 +264,20 @@
 
 				<p:column
 					headerText="#{msg.ENTRY_CREATED_HEADER}"
-					sortBy="#{branchOffice.branchCreated}"
+					sortBy="#{branchOffice.branchEntryCreated}"
 					filterable="false"
 					>
-					<h:outputText id="branchCreated" value="#{branchOffice.branchCreated}">
+					<h:outputText value="#{branchOffice.branchEntryCreated}">
+						<f:convertDateTime type="both" timeStyle="short" dateStyle="short" />
+					</h:outputText>
+				</p:column>
+
+				<p:column
+					headerText="#{msg.ENTRY_UPDATED_HEADER}"
+					sortBy="#{branchOffice.branchEntryUpdated}"
+					filterable="false"
+					>
+					<h:outputText value="#{branchOffice.branchEntryUpdated}">
 						<f:convertDateTime type="both" timeStyle="short" dateStyle="short" />
 					</h:outputText>
 				</p:column>
@@ -277,7 +287,32 @@
 					sortable="false"
 					filterable="false"
 					>
-					<links:outputBranchOfficeAdminDropdownMenu branchOffice="#{branchOffice}" />
+					<p:menuButton value="#{msg.OPTIONS}">
+						<p:menuitem
+							outcome="admin_show_branch_office"
+							value="#{msg.ADMIN_LINK_SHOW_SHORT}"
+							title="#{msg.ADMIN_LINK_SHOW_BRANCH_OFFICE_TITLE}"
+							>
+							<f:param name="branchId" value="#{branchOffice.branchId}" />
+						</p:menuitem>
+
+						<p:menuitem
+							outcome="admin_edit_branch_office"
+							value="#{msg.ADMIN_LINK_EDIT_SHORT}"
+							title="#{msg.ADMIN_LINK_EDIT_BRANCH_OFFICE_TITLE}"
+							>
+							<f:param name="branchId" value="#{branchOffice.branchId}" />
+						</p:menuitem>
+
+						<p:menuitem outcome="admin_delete_branch_office">
+							<h:outputText
+								styleClass="link-danger"
+								value="#{msg.ADMIN_LINK_DELETE_SHORT}"
+								title="#{msg.ADMIN_LINK_DELETE_BRANCH_OFFICE_TITLE}"
+								/>
+							<f:param name="branchId" value="#{branchOffice.branchId}" />
+						</p:menuitem>
+					</p:menuButton>
 				</p:column>
 			</p:dataTable>
 
diff --git a/web/admin/contact/admin_contact_export.xhtml b/web/admin/contact/admin_contact_export.xhtml
index 0db88b4f..644af7fa 100644
--- a/web/admin/contact/admin_contact_export.xhtml
+++ b/web/admin/contact/admin_contact_export.xhtml
@@ -163,8 +163,28 @@
 						<h:outputText value="#{msg.ADMIN_EXPORT_CONTACT_CREATED}" />
 					</f:facet>
 
-					<h:outputText id="contactCreated" value="#{contact.contactCreated}">
-						<f:convertDateTime type="both" timeStyle="short" dateStyle="short" locale="#{localizationController.locale}" />
+					<h:outputText value="#{contact.contactEntryCreated}">
+						<f:convertDateTime
+							type="both"
+							timeStyle="short"
+							dateStyle="short"
+							locale="#{localizationController.locale}"
+							/>
+					</h:outputText>
+				</p:column>
+
+				<p:column>
+					<f:facet name="header">
+						<h:outputText value="#{msg.ADMIN_EXPORT_CONTACT_UPDATED}" />
+					</f:facet>
+
+					<h:outputText value="#{contact.contactEntryUpdated}">
+						<f:convertDateTime
+							type="both"
+							timeStyle="short"
+							dateStyle="short"
+							locale="#{localizationController.locale}"
+							/>
 					</h:outputText>
 				</p:column>
 			</p:dataTable>
diff --git a/web/admin/contact/admin_contact_list.xhtml b/web/admin/contact/admin_contact_list.xhtml
index 83bfb78f..d07b6c24 100644
--- a/web/admin/contact/admin_contact_list.xhtml
+++ b/web/admin/contact/admin_contact_list.xhtml
@@ -144,22 +144,22 @@
 
 				<p:column
 					headerText="#{msg.ENTRY_CREATED_HEADER}"
-					sortBy="#{contact.contactCreated}"
-					filterBy="#{contact.contactCreated}"
+					sortBy="#{contact.contactEntryCreated}"
+					filterBy="#{contact.contactEntryCreated}"
 					filterMatchMode="contains"
 					>
-					<h:outputText value="#{contact.contactCreated}">
+					<h:outputText value="#{contact.contactEntryCreated}">
 						<f:convertDateTime type="both" timeStyle="short" dateStyle="short" />
 					</h:outputText>
 				</p:column>
 
 				<p:column
 					headerText="#{msg.ENTRY_UPDATED_HEADER}"
-					sortBy="#{contact.contactUpdated}"
-					filterBy="#{contact.contactUpdated}"
+					sortBy="#{contact.contactEntryUpdated}"
+					filterBy="#{contact.contactEntryUpdated}"
 					filterMatchMode="contains"
 					>
-					<h:outputText value="#{contact.contactUpdated}">
+					<h:outputText value="#{contact.contactEntryUpdated}">
 						<f:convertDateTime type="both" timeStyle="short" dateStyle="short" />
 					</h:outputText>
 				</p:column>
diff --git a/web/admin/contact/unlink/admin_contact_mobile_unlink.xhtml b/web/admin/contact/unlink/admin_contact_mobile_unlink.xhtml
index aa699eb7..49b41a66 100644
--- a/web/admin/contact/unlink/admin_contact_mobile_unlink.xhtml
+++ b/web/admin/contact/unlink/admin_contact_mobile_unlink.xhtml
@@ -62,7 +62,7 @@
 		</h:form>
 
 		<h:outputFormat styleClass="alert-danger" value="#{msg.ERROR_MOBILE_NUMBER_CONTACT_NOT_LINKED}" rendered="#{not empty beanHelper.mobileNumber and not empty beanHelper.contact and beanHelper.contact.contactMobileNumber != beanHelper.mobileNumber}">
-			<f:param value="#{beanHelper.mobileNumber.phoneId}" />
+			<f:param value="#{beanHelper.mobileNumber.mobileId}" />
 			<f:param value="#{beanHelper.contact.contactId}" />
 		</h:outputFormat>
 	</ui:define>
diff --git a/web/admin/country/admin_country_list.xhtml b/web/admin/country/admin_country_list.xhtml
index 8f1e91cc..b77176e4 100644
--- a/web/admin/country/admin_country_list.xhtml
+++ b/web/admin/country/admin_country_list.xhtml
@@ -191,7 +191,32 @@
 					filterable="false"
 					sortable="false"
 					>
-					<links:outputCountryAdminDropdownMenu country="#{country}" />
+					<p:menuButton value="#{msg.OPTIONS}">
+						<p:menuitem
+							outcome="admin_show_country"
+							value="#{msg.ADMIN_LINK_SHOW_SHORT}"
+							title="#{msg.ADMIN_LINK_SHOW_COUNTRY_TITLE}"
+							>
+							<f:param name="countryId" value="#{country.countryId}" />
+						</p:menuitem>
+
+						<p:menuitem
+							outcome="admin_edit_country"
+							value="#{msg.ADMIN_LINK_EDIT_SHORT}"
+							title="#{msg.ADMIN_LINK_EDIT_COUNTRY_TITLE}"
+							>
+							<f:param name="countryId" value="#{country.countryId}" />
+						</p:menuitem>
+
+						<p:menuitem outcome="admin_delete_country">
+							<h:outputText
+								styleClass="link-danger"
+								value="#{msg.ADMIN_LINK_DELETE_SHORT}"
+								title="#{msg.ADMIN_LINK_DELETE_COUNTRY_TITLE}"
+								/>
+							<f:param name="countryId" value="#{country.countryId}" />
+						</p:menuitem>
+					</p:menuButton>
 				</p:column>
 			</p:dataTable>
 
diff --git a/web/admin/department/admin_department_list.xhtml b/web/admin/department/admin_department_list.xhtml
index 7b7d8f4f..6d02e8c2 100644
--- a/web/admin/department/admin_department_list.xhtml
+++ b/web/admin/department/admin_department_list.xhtml
@@ -164,7 +164,7 @@
 							<f:converter converterId="BranchOfficeConverter" />
 
 							<f:selectItems
-								value="#{branchOfficeListController.allBranchOffices()}"
+								value="#{branchOfficeListController.allBranchOffices}"
 								var="branchOffice"
 								itemValue="#{branchOffice}"
 								itemLabel="#{beanHelper.renderBranchOffice(branchOffice)}"
@@ -209,7 +209,7 @@
 							<f:converter converterId="EmployeeConverter" />
 
 							<f:selectItems
-								value="#{employeeController.allEmployees()}"
+								value="#{employeeListController.allEmployees}"
 								var="employee"
 								itemValue="#{employee}"
 								itemLabel="#{beanHelper.renderEmployee(employee)}"
@@ -296,7 +296,32 @@
 					sortable="false"
 					filterable="false"
 					>
-					<links:outputDepartmentAdminDropdownMenu department="#{department}" />
+					<p:menuButton value="#{msg.OPTIONS}">
+						<p:menuitem
+							outcome="admin_show_department"
+							value="#{msg.ADMIN_LINK_SHOW_SHORT}"
+							title="#{msg.ADMIN_LINK_SHOW_DEPARTMENT_TITLE}"
+							>
+							<f:param name="departmentId" value="#{department.departmentId}" />
+						</p:menuitem>
+
+						<p:menuitem
+							outcome="admin_edit_department"
+							value="#{msg.ADMIN_LINK_EDIT_SHORT}"
+							title="#{msg.ADMIN_LINK_EDIT_DEPARTMENT_TITLE}"
+							>
+							<f:param name="departmentId" value="#{department.departmentId}" />
+						</p:menuitem>
+
+						<p:menuitem outcome="admin_delete_department">
+							<h:outputText
+								styleClass="link-danger"
+								value="#{msg.ADMIN_LINK_DELETE_SHORT}"
+								title="#{msg.ADMIN_LINK_DELETE_DEPARTMENT_TITLE}"
+								/>
+							<f:param name="departmentId" value="#{department.departmentId}" />
+						</p:menuitem>
+					</p:menuButton>
 				</p:column>
 			</p:dataTable>
 
diff --git a/web/admin/employee/admin_employee_list.xhtml b/web/admin/employee/admin_employee_list.xhtml
index eabf7468..0363e00a 100644
--- a/web/admin/employee/admin_employee_list.xhtml
+++ b/web/admin/employee/admin_employee_list.xhtml
@@ -18,29 +18,58 @@
 	</ui:define>
 
 	<ui:define name="content">
-		<h:form id="form-list-company-employees">
+		<h:form id="form-list-employees">
 			<p:dataTable
 				id="employeeList"
 				var="employee"
-				value="#{employeeController.allEmployees()}"
-				filteredValue="#{employeeController.filteredEmployees}"
+				value="#{employeeListController.allEmployees}"
 				paginator="true"
 				paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
+				filteredValue="#{employeeListController.filteredEmployees}"
 				rows="10"
+				rowKey="#{employee.employeeId}"
 				reflow="true"
 				resizableColumns="true"
 				rowsPerPageTemplate="5,10,20,50,100"
 				sortMode="multiple"
-				summary="#{msg.TABLE_SUMMARY_ADMIN_LIST_EMPLOYEES}"
-				emptyMessage="#{msg.ADMIN_EMPTY_LIST_EMPLOYEES}"
+				summary="#{msg.TABLE_SUMMARY_ADMIN_LIST_EMPLOYEESS}"
+				emptyMessage="#{msg.ADMIN_EMPTY_LIST_EMPLOYEESS}"
 				widgetVar="employeeList"
+				selectionMode="single"
+				selection="#{employeeListController.selectedEmployee}"
+				skipChildren="true"
 				>
 
 				<f:facet name="header">
-					<p:panelGrid columns="2" columnClasses="ui-grid-col-10,ui-grid-col-2" layout="grid" styleClass="ui-noborder ui-transparent-widget">
-						<h:outputText value="#{msg.ADMIN_LIST_EMPLOYEES_HEADER}" />
+					<p:panelGrid
+						columns="3"
+						layout="grid"
+						columnClasses="ui-grid-col-4,ui-grid-col-6,ui-grid-col-2"
+						>
+						<p:spacer />
+
+						<p:panelGrid
+							columns="2"
+							columnClasses="ui-grid-4,ui-grid-8"
+							layout="grid"
+							styleClass="ui-noborder"
+							>
+							<p:outputLabel
+								for="globalFilter"
+								value="#{msg.SEARCH_ALL_FIELDS}"
+								style="float: right"
+								/>
+
+							<p:inputText
+								id="globalFilter"
+								onkeyup="PF('employeeList').filter()"
+								placeholder="#{msg.ENTER_KEYWORD}"
+								/>
+						</p:panelGrid>
+
+						<p:outputPanel>
+							<p:spacer height="4" />
 
-						<h:panelGroup>
 							<p:commandButton
 								id="toggler"
 								type="button"
@@ -49,10 +78,16 @@
 								/>
 
 							<p:columnToggler datasource="employeeList" trigger="toggler" />
-						</h:panelGroup>
+						</p:outputPanel>
 					</p:panelGrid>
 				</f:facet>
 
+				<p:ajax
+					event="rowSelect"
+					update="form-list-employees:employee-details"
+					oncomplete="PF('employeeDialog').show()"
+					/>
+
 				<p:column
 					headerText="#{msg.ID_HEADER}"
 					sortBy="#{employee.employeeId}"
@@ -95,7 +130,7 @@
 							<f:converter converterId="BranchOfficeConverter" />
 
 							<f:selectItems
-								value="#{branchOfficeListController.allBranchOffices()}"
+								value="#{branchOfficeListController.allBranchOffices}"
 								var="branchOffice"
 								itemValue="#{branchOffice}"
 								itemLabel="#{beanHelper.renderBranchOffice(branchOffice)}"
@@ -218,10 +253,20 @@
 
 				<p:column
 					headerText="#{msg.ENTRY_CREATED_HEADER}"
-					sortBy="#{employee.employeeCreated}"
+					sortBy="#{employee.employeeEntryCreated}"
+					filterable="false"
+					>
+					<h:outputText value="#{employee.employeeEntryCreated}">
+						<f:convertDateTime type="both" timeStyle="short" dateStyle="short" />
+					</h:outputText>
+				</p:column>
+
+				<p:column
+					headerText="#{msg.ENTRY_UPDATED_HEADER}"
+					sortBy="#{employee.employeeEntryUpdated}"
 					filterable="false"
 					>
-					<h:outputText id="employeeCreated" value="#{employee.employeeCreated}">
+					<h:outputText value="#{employee.employeeEntryUpdated}">
 						<f:convertDateTime type="both" timeStyle="short" dateStyle="short" />
 					</h:outputText>
 				</p:column>
@@ -231,9 +276,73 @@
 					sortable="false"
 					filterable="false"
 					>
-					<links:outputEmployeeAdminDropdownMenu employee="#{employee}" />
+					<p:menuButton value="#{msg.OPTIONS}">
+						<p:menuitem
+							outcome="admin_show_employee"
+							value="#{msg.ADMIN_LINK_SHOW_SHORT}"
+							title="#{msg.ADMIN_LINK_SHOW_EMPLOYEE_TITLE}"
+							>
+							<f:param name="employeeId" value="#{employee.employeeId}" />
+						</p:menuitem>
+
+						<p:menuitem
+							outcome="admin_edit_employee"
+							value="#{msg.ADMIN_LINK_EDIT_SHORT}"
+							title="#{msg.ADMIN_LINK_EDIT_EMPLOYEE_TITLE}"
+							>
+							<f:param name="employeeId" value="#{employee.employeeId}" />
+						</p:menuitem>
+
+						<p:menuitem outcome="admin_delete_employee">
+							<h:outputText
+								styleClass="link-danger"
+								value="#{msg.ADMIN_LINK_DELETE_SHORT}"
+								title="#{msg.ADMIN_LINK_DELETE_EMPLOYEE_TITLE}"
+								/>
+							<f:param name="employeeId" value="#{employee.employeeId}" />
+						</p:menuitem>
+					</p:menuButton>
 				</p:column>
 			</p:dataTable>
+
+			<p:dialog
+				dynamic="true"
+				modal="true"
+				resizable="false"
+				header="#{msg.ADMIN_SINGLE_EMPLOYEE_DETAILS_HEADER}"
+				hideEffect="fade"
+				showEffect="fade"
+				widgetVar="employeeDialog"
+				position="top"
+				responsive="true"
+				closeOnEscape="true"
+				>
+				<p:outputPanel id="employee-details">
+					<p:panelGrid
+						columns="2"
+						rendered="#{not empty employeeListController.selectedEmployee}"
+						>
+						<f:facet name="header">
+							<h:outputFormat
+								value="#{msg.ADMIN_EMPLOYEE_NUMBER_DETAILS_HEADER}"
+								rendered="#{empty employeeListController.selectedEmployee.employeePersonalData}"
+								>
+								<f:param value="#{employeeListController.selectedEmployee.employeeId}" />
+							</h:outputFormat>
+
+							<h:outputFormat
+								value="#{msg.ADMIN_EMPLOYEE_NAME_DETAILS_HEADER}"
+								rendered="#{not empty employeeListController.selectedEmployee.employeePersonalData}"
+								>
+								<f:param value="#{beanHelper.renderContact(employeeListController.selectedEmployee.employeePersonalData)}" />
+							</h:outputFormat>
+						</f:facet>
+
+						<p:outputLabel value="#{msg.ID_HEADER}" title="#{msg.EMPLOYEE_ID_NUMBER_TITLE}" />
+						<h:outputText value="#{employeeListController.selectedEmployee.employeeId}" />
+					</p:panelGrid>
+				</p:outputPanel>
+			</p:dialog>
 		</h:form>
 
 		<h:form>
@@ -262,7 +371,7 @@
 							type="submit"
 							value="#{msg.BUTTON_ADMIN_ADD_EMPLOYEE}"
 							action="#{adminEmployeeController.addEmployee()}"
-							update="form-list-company-employees:employeeList"
+							update="form-list-employees:employeeList"
 							/>
 					</p:panelGrid>
 				</f:facet>
diff --git a/web/admin/fax/admin_fax_list.xhtml b/web/admin/fax/admin_fax_list.xhtml
index ded37152..2146923a 100644
--- a/web/admin/fax/admin_fax_list.xhtml
+++ b/web/admin/fax/admin_fax_list.xhtml
@@ -21,7 +21,7 @@
 		<p:dataTable
 			id="table_list_fax"
 			var="faxNumber"
-			value="#{phoneController.allFaxNumbers()}"
+			value="#{phoneListController.allFaxNumbers}"
 			paginator="true"
 			rows="10"
 			summary="#{msg.TABLE_SUMMARY_ADMIN_LIST_FAXS}"
@@ -51,7 +51,7 @@
 
 			<p:column>
 				<f:facet name="header">
-					<h:outputText value="#{msg.ADMIN_SHOW_PHONE_CREATED}" />
+					<h:outputText value="#{msg.ENTRY_CREATED_HEADER}" />
 				</f:facet>
 
 				<h:outputText value="#{faxNumber.phoneEntryCreated}">
@@ -61,7 +61,7 @@
 
 			<p:column>
 				<f:facet name="header">
-					<h:outputText value="#{msg.ADMIN_SHOW_PHONE_UPDATED}" />
+					<h:outputText value="#{msg.ENTRY_UPDATED_HEADER}" />
 				</f:facet>
 
 				<h:outputText value="#{faxNumber.phoneEntryUpdated}">
diff --git a/web/admin/fax/admin_fax_show.xhtml b/web/admin/fax/admin_fax_show.xhtml
index 5d179a83..18c9ada8 100644
--- a/web/admin/fax/admin_fax_show.xhtml
+++ b/web/admin/fax/admin_fax_show.xhtml
@@ -30,7 +30,7 @@
 		<p:dataTable
 			id="contact_fax_link"
 			var="contact"
-			value="#{contactPhoneController.allCurrentFaxNumberContacts}"
+			value="#{contactPhoneController.allCurrentFaxNumberContacts()}"
 			summary="#{msg.TABLE_SUMMARY_ADMIN_SHOW_ADMINISTRATIVE_LINKS}"
 			>
 			<f:facet name="header">
diff --git a/web/admin/headquarter/admin_headquarter_list.xhtml b/web/admin/headquarter/admin_headquarter_list.xhtml
index d985667d..c0268868 100644
--- a/web/admin/headquarter/admin_headquarter_list.xhtml
+++ b/web/admin/headquarter/admin_headquarter_list.xhtml
@@ -189,7 +189,7 @@
 							<f:converter converterId="EmployeeConverter" />
 
 							<f:selectItems
-								value="#{employeeController.allEmployees()}"
+								value="#{employeeListController.allEmployees}"
 								var="employee"
 								itemValue="#{employee}"
 								itemLabel="#{beanHelper.renderEmployee(employee)}"
@@ -231,7 +231,32 @@
 					sortable="false"
 					filterable="false"
 					>
-					<links:outputHeadquarterAdminDropdownMenu headquarter="#{headquarter}" />
+					<p:menuButton value="#{msg.OPTIONS}">
+						<p:menuitem
+							outcome="admin_show_headquarter"
+							value="#{msg.ADMIN_LINK_SHOW_SHORT}"
+							title="#{msg.ADMIN_LINK_SHOW_HEADQUARTER_TITLE}"
+							>
+							<f:param name="headquarterId" value="#{headquarter.headquarterId}" />
+						</p:menuitem>
+
+						<p:menuitem
+							outcome="admin_edit_headquarter"
+							value="#{msg.ADMIN_LINK_EDIT_SHORT}"
+							title="#{msg.ADMIN_LINK_EDIT_HEADQUARTER_TITLE}"
+							>
+							<f:param name="headquarterId" value="#{headquarter.headquarterId}" />
+						</p:menuitem>
+
+						<p:menuitem outcome="admin_delete_headquarter">
+							<h:outputText
+								styleClass="link-danger"
+								value="#{msg.ADMIN_LINK_DELETE_SHORT}"
+								title="#{msg.ADMIN_LINK_DELETE_HEADQUARTER_TITLE}"
+								/>
+							<f:param name="headquarterId" value="#{headquarter.headquarterId}" />
+						</p:menuitem>
+					</p:menuButton>
 				</p:column>
 			</p:dataTable>
 
diff --git a/web/admin/landline/admin_landline_list.xhtml b/web/admin/landline/admin_landline_list.xhtml
index 7685a861..64b62818 100644
--- a/web/admin/landline/admin_landline_list.xhtml
+++ b/web/admin/landline/admin_landline_list.xhtml
@@ -20,7 +20,7 @@
 		<p:dataTable
 			id="table_list_landline"
 			var="landLineNumber"
-			value="#{phoneController.allLandLineNumbers()}"
+			value="#{phoneListController.allLandLineNumbers}"
 			paginator="true"
 			rows="10"
 			summary="#{msg.TABLE_SUMMARY_ADMIN_LIST_LAND_LINES}"
@@ -50,7 +50,7 @@
 
 			<p:column>
 				<f:facet name="header">
-					<h:outputText value="#{msg.ADMIN_SHOW_PHONE_CREATED}" />
+					<h:outputText value="#{msg.ENTRY_CREATED_HEADER}" />
 				</f:facet>
 
 				<h:outputText value="#{landLineNumber.phoneEntryCreated}">
@@ -60,7 +60,7 @@
 
 			<p:column>
 				<f:facet name="header">
-					<h:outputText value="#{msg.ADMIN_SHOW_PHONE_UPDATED}" />
+					<h:outputText value="#{msg.ENTRY_UPDATED_HEADER}" />
 				</f:facet>
 
 				<h:outputText value="#{landLineNumber.phoneEntryUpdated}">
diff --git a/web/admin/mobile/admin_contact_mobile_list.xhtml b/web/admin/mobile/admin_contact_mobile_list.xhtml
index 7747849b..d99b94d7 100644
--- a/web/admin/mobile/admin_contact_mobile_list.xhtml
+++ b/web/admin/mobile/admin_contact_mobile_list.xhtml
@@ -20,7 +20,7 @@
 		<p:dataTable
 			id="table_list_mobiles"
 			var="mobile"
-			value="#{phoneController.allMobileNumbers()}"
+			value="#{phoneListController.allMobileNumbers}"
 			paginator="true"
 			rows="10"
 			summary="#{msg.TABLE_SUMMARY_ADMIN_LIST_MOBILE_NUMBERS}"
diff --git a/web/admin/mobile/admin_mobile_edit.xhtml b/web/admin/mobile/admin_mobile_edit.xhtml
index f7ff0a47..5ac28359 100644
--- a/web/admin/mobile/admin_mobile_edit.xhtml
+++ b/web/admin/mobile/admin_mobile_edit.xhtml
@@ -31,7 +31,7 @@
 			<h:panelGroup layout="block">
 				<div class="table-header">
 					<h:outputFormat value="#{msg.ADMIN_EDIT_MOBILE_NUMBER_TITLE}">
-						<f:param value="#{beanHelper.mobileNumber.phoneId}" />
+						<f:param value="#{beanHelper.mobileNumber.mobileId}" />
 					</h:outputFormat>
 				</div>
 
diff --git a/web/admin/mobile/admin_mobile_list.xhtml b/web/admin/mobile/admin_mobile_list.xhtml
index db23ca34..1ab86f42 100644
--- a/web/admin/mobile/admin_mobile_list.xhtml
+++ b/web/admin/mobile/admin_mobile_list.xhtml
@@ -20,7 +20,7 @@
 		<p:dataTable
 			id="mobileNumberList"
 			var="mobileNumber"
-			value="#{phoneController.allMobileNumbers()}"
+			value="#{mobileListController.allMobileNumbers}"
 			paginator="true"
 			rows="10"
 			summary="#{msg.TABLE_SUMMARY_ADMIN_LIST_MOBILES}"
@@ -33,10 +33,10 @@
 
 				<p:link
 					outcome="admin_show_mobile"
-					value="#{mobileNumber.phoneId}"
+					value="#{mobileNumber.mobileId}"
 					title="#{msg.ADMIN_LINK_SHOW_MOBILE_NUMBER_TITLE}"
 					>
-					<f:param name="phoneId" value="#{mobileNumber.phoneId}" />
+					<f:param name="mobileId" value="#{mobileNumber.mobileId}" />
 				</p:link>
 			</p:column>
 
@@ -64,20 +64,20 @@
 
 			<p:column>
 				<f:facet name="header">
-					<h:outputText value="#{msg.ADMIN_SHOW_PHONE_CREATED}" />
+					<h:outputText value="#{msg.ENTRY_CREATED_HEADER}" />
 				</f:facet>
 
-				<h:outputText value="#{mobileNumber.phoneEntryCreated}">
+				<h:outputText value="#{mobileNumber.mobileEntryCreated}">
 					<f:convertDateTime type="both" />
 				</h:outputText>
 			</p:column>
 
 			<p:column>
 				<f:facet name="header">
-					<h:outputText value="#{msg.ADMIN_SHOW_PHONE_UPDATED}" />
+					<h:outputText value="#{msg.ENTRY_UPDATED_HEADER}" />
 				</f:facet>
 
-				<h:outputText value="#{mobileNumber.phoneEntryUpdated}">
+				<h:outputText value="#{mobileNumber.mobileEntryUpdated}">
 					<f:convertDateTime type="both" />
 				</h:outputText>
 			</p:column>
diff --git a/web/admin/mobile/admin_mobile_show.xhtml b/web/admin/mobile/admin_mobile_show.xhtml
index e4e4068e..8549b428 100644
--- a/web/admin/mobile/admin_mobile_show.xhtml
+++ b/web/admin/mobile/admin_mobile_show.xhtml
@@ -30,12 +30,12 @@
 		<p:dataTable
 			id="contact_mobile_link"
 			var="contact"
-			value="#{contactPhoneController.allCurrentMobileNumberContacts()}"
+			value="#{contactMobileController.allCurrentMobileNumberContacts()}"
 			summary="#{msg.TABLE_SUMMARY_ADMIN_SHOW_ADMINISTRATIVE_LINKS}"
 			>
 			<f:facet name="header">
 				<h:outputFormat value="#{msg.ADMIN_SHOW_MOBILE_NUMBER_LINKS_HEADER}">
-					<f:param value="#{beanHelper.mobileNumber.phoneId}" />
+					<f:param value="#{beanHelper.mobileNumber.mobileId}" />
 				</h:outputFormat>
 			</f:facet>
 
@@ -98,7 +98,7 @@
 								outcome="admin_unlink_contact_mobile"
 								>
 								<h:outputText styleClass="link-warning" value="#{msg.ADMIN_LINK_UNLINK_SHORT}" title="#{msg.ADMIN_LINK_UNLINK_MOBILE_NUMBER_CONTACT_TITLE}" />
-								<f:param name="phoneId" value="#{beanHelper.mobileNumber.phoneId}" />
+								<f:param name="phoneId" value="#{beanHelper.mobileNumber.mobileId}" />
 								<f:param name="contactId" value="#{contact.contactId}" />
 							</p:link>
 						</li>
diff --git a/web/admin/mobile_provider/admin_mobile_provider_list.xhtml b/web/admin/mobile_provider/admin_mobile_provider_list.xhtml
index 8487edd6..dd3b0b16 100644
--- a/web/admin/mobile_provider/admin_mobile_provider_list.xhtml
+++ b/web/admin/mobile_provider/admin_mobile_provider_list.xhtml
@@ -18,39 +18,76 @@
 	</ui:define>
 
 	<ui:define name="content">
-		<h:form id="form-list-mobile-provider">
+		<h:form id="form-list-mobile-providers">
 			<p:dataTable
 				id="mobileProviderList"
 				var="mobileProvider"
-				value="#{mobileProviderController.allMobileProviders()}"
+				value="#{mobileProviderListController.allMobileProviders}"
 				paginator="true"
 				paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
-				filteredValue="#{mobileProviderController.filteredMobileProviders}"
+				filteredValue="#{mobileProviderListController.filteredMobileProviders}"
 				rows="10"
+				rowKey="#{mobileProvider.providerId}"
 				reflow="true"
 				resizableColumns="true"
 				rowsPerPageTemplate="5,10,20,50,100"
 				sortMode="multiple"
 				summary="#{msg.TABLE_SUMMARY_ADMIN_LIST_MOBILE_PROVIDERS}"
-				emptyMessage="#{msg.ADMIN_EMPTY_LIST_MOBILE_PROVIDER}"
+				emptyMessage="#{msg.ADMIN_EMPTY_LIST_MOBILE_PROVIDERS}"
 				widgetVar="mobileProviderList"
+				selectionMode="single"
+				selection="#{mobileProviderListController.selectedMobileProvider}"
+				skipChildren="true"
 				>
 
 				<f:facet name="header">
-					<p:panelGrid columns="2" columnClasses="ui-grid-col-10,ui-grid-col-2" layout="grid" styleClass="ui-noborder ui-transparent-widget">
-						<h:outputText value="#{msg.ADMIN_LIST_MOBILE_PROVIDERS_HEADER}" />
+					<p:panelGrid
+						columns="3"
+						layout="grid"
+						columnClasses="ui-grid-col-4,ui-grid-col-6,ui-grid-col-2"
+						>
+						<p:spacer />
+
+						<p:panelGrid
+							columns="2"
+							columnClasses="ui-grid-4,ui-grid-8"
+							layout="grid"
+							styleClass="ui-noborder"
+							>
+							<p:outputLabel
+								for="globalFilter"
+								value="#{msg.SEARCH_ALL_FIELDS}"
+								style="float: right"
+								/>
+
+							<p:inputText
+								id="globalFilter"
+								onkeyup="PF('mobileProviderList').filter()"
+								placeholder="#{msg.ENTER_KEYWORD}"
+								/>
+						</p:panelGrid>
 
-						<p:commandButton
-							id="toggler"
-							type="button"
-							value="#{msg.SELECT_SHOWN_COLUMNS}"
-							styleClass="column-selector"
-							/>
+						<p:outputPanel>
+							<p:spacer height="4" />
 
-						<p:columnToggler datasource="mobileProviderList" trigger="toggler" />
+							<p:commandButton
+								id="toggler"
+								type="button"
+								value="#{msg.SELECT_SHOWN_COLUMNS}"
+								styleClass="column-selector"
+								/>
+
+							<p:columnToggler datasource="mobileProviderList" trigger="toggler" />
+						</p:outputPanel>
 					</p:panelGrid>
 				</f:facet>
 
+				<p:ajax
+					event="rowSelect"
+					update="form-list-mobile-providers:mobile-provider-details"
+					oncomplete="PF('mobileProviderDialog').show()"
+					/>
+
 				<p:column
 					headerText="#{msg.ID_HEADER}"
 					sortBy="#{mobileProvider.providerId}"
@@ -115,7 +152,16 @@
 					headerText="#{msg.ENTRY_CREATED_HEADER}"
 					sortBy="#{mobileProvider.providerEntryCreated}"
 					>
-					<h:outputText id="providerEntryCreated" value="#{mobileProvider.providerEntryCreated}">
+					<h:outputText value="#{mobileProvider.providerEntryCreated}">
+						<f:convertDateTime type="both" timeStyle="short" dateStyle="short" />
+					</h:outputText>
+				</p:column>
+
+				<p:column
+					headerText="#{msg.ENTRY_UPDATED_HEADER}"
+					sortBy="#{mobileProvider.providerEntryUpdated}"
+					>
+					<h:outputText value="#{mobileProvider.providerEntryUpdated}">
 						<f:convertDateTime type="both" timeStyle="short" dateStyle="short" />
 					</h:outputText>
 				</p:column>
@@ -124,9 +170,61 @@
 					headerText="#{msg.ADMIN_ACTION_LINKS_HEADER}"
 					sortable="false"
 					>
-					<links:outputMobileProviderAdminDropdownMenu mobileProvider="#{mobileProvider}" />
+					<p:menuButton value="#{msg.OPTIONS}">
+						<p:menuitem
+							outcome="admin_show_mobile_provider"
+							value="#{msg.ADMIN_LINK_SHOW_SHORT}"
+							title="#{msg.ADMIN_LINK_SHOW_MOBILE_PROVIDER_TITLE}"
+							>
+							<f:param name="providerId" value="#{mobileProvider.providerId}" />
+						</p:menuitem>
+
+						<p:menuitem
+							outcome="admin_edit_mobile_provider"
+							value="#{msg.ADMIN_LINK_EDIT_SHORT}"
+							title="#{msg.ADMIN_LINK_EDIT_MOBILE_PROVIDER_TITLE}"
+							>
+							<f:param name="providerId" value="#{mobileProvider.providerId}" />
+						</p:menuitem>
+
+						<p:menuitem outcome="admin_delete_mobile_provider">
+							<h:outputText
+								styleClass="link-danger"
+								value="#{msg.ADMIN_LINK_DELETE_SHORT}"
+								title="#{msg.ADMIN_LINK_DELETE_MOBILE_PROVIDER_TITLE}"
+								/>
+							<f:param name="providerId" value="#{mobileProvider.providerId}" />
+						</p:menuitem>
+					</p:menuButton>
 				</p:column>
 			</p:dataTable>
+
+			<p:dialog
+				dynamic="true"
+				modal="true"
+				resizable="false"
+				header="#{msg.ADMIN_SINGLE_MOBILE_PROVIDER_DETAILS_HEADER}"
+				hideEffect="fade"
+				showEffect="fade"
+				widgetVar="mobileProviderDialog"
+				position="top"
+				responsive="true"
+				closeOnEscape="true"
+				>
+				<p:outputPanel id="mobile-provider-details">
+					<p:panelGrid columns="2" rendered="#{not empty mobileProviderListController.selectedMobileProvider}">
+						<f:facet name="header">
+							<h:outputFormat value="#{msg.ADMIN_MOBILE_PROVIDER_DETAILS_HEADER}">
+								<f:param value="#{mobileProviderListController.selectedMobileProvider.providerName}" />
+								<f:param value="#{mobileProviderListController.selectedMobileProvider.providerId}" />
+							</h:outputFormat>
+						</f:facet>
+
+						<p:outputLabel value="#{msg.ID_HEADER}" title="#{msg.MOBILE_PROVIDER_ID_NUMBER_TITLE}" />
+						<h:outputText value="#{mobileProviderListController.selectedMobileProvider.providerId}" />
+					</p:panelGrid>
+				</p:outputPanel>
+			</p:dialog>
 		</h:form>
 
 		<h:form>
@@ -147,7 +245,7 @@
 						type="submit"
 						value="#{msg.BUTTON_ADMIN_ADD_MOBILE_PROVIDER}"
 						action="#{adminMobileProviderController.addMobileProvider()}"
-						update="form-list-mobile-provider:mobileProviderList"
+						update="form-list-mobile-providers:mobileProviderList"
 						/>
 				</p:panelGrid>
 			</h:panelGroup>
diff --git a/web/admin/opening_time/admin_opening_time_list.xhtml b/web/admin/opening_time/admin_opening_time_list.xhtml
index 21f9d6d1..5c9d3b97 100644
--- a/web/admin/opening_time/admin_opening_time_list.xhtml
+++ b/web/admin/opening_time/admin_opening_time_list.xhtml
@@ -18,15 +18,16 @@
 	</ui:define>
 
 	<ui:define name="content">
-		<h:form id="form-list-opening-time">
+		<h:form id="form-list-opening-times">
 			<p:dataTable
 				id="openingTimeList"
 				var="openingTime"
-				value="#{openingTimeController.allOpeningTimes()}"
+				value="#{openingTimeListController.allOpeningTimes}"
 				paginator="true"
 				paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
-				filteredValue="#{openingTimeController.filteredOpeningTimes}"
+				filteredValue="#{openingTimeListController.filteredOpeningTimes}"
 				rows="10"
+				rowKey="#{openingTime.openingTimeId}"
 				reflow="true"
 				resizableColumns="true"
 				rowsPerPageTemplate="5,10,20,50,100"
@@ -34,13 +35,41 @@
 				summary="#{msg.TABLE_SUMMARY_ADMIN_LIST_OPENING_TIMES}"
 				emptyMessage="#{msg.ADMIN_EMPTY_LIST_OPENING_TIMES}"
 				widgetVar="openingTimeList"
+				selectionMode="single"
+				selection="#{openingTimeListController.selectedOpeningTime}"
+				skipChildren="true"
 				>
 
 				<f:facet name="header">
-					<p:panelGrid columns="2" columnClasses="ui-grid-col-10,ui-grid-col-2" layout="grid" styleClass="ui-noborder ui-transparent-widget">
-						<h:outputText value="#{msg.ADMIN_LIST_OPENING_TIMES_HEADER}" />
+					<p:panelGrid
+						columns="3"
+						layout="grid"
+						columnClasses="ui-grid-col-4,ui-grid-col-6,ui-grid-col-2"
+						>
+						<p:spacer />
+
+						<p:panelGrid
+							columns="2"
+							columnClasses="ui-grid-4,ui-grid-8"
+							layout="grid"
+							styleClass="ui-noborder"
+							>
+							<p:outputLabel
+								for="globalFilter"
+								value="#{msg.SEARCH_ALL_FIELDS}"
+								style="float: right"
+								/>
+
+							<p:inputText
+								id="globalFilter"
+								onkeyup="PF('openingTimeList').filter()"
+								placeholder="#{msg.ENTER_KEYWORD}"
+								/>
+						</p:panelGrid>
+
+						<p:outputPanel>
+							<p:spacer height="4" />
 
-						<h:panelGroup>
 							<p:commandButton
 								id="toggler"
 								type="button"
@@ -49,21 +78,27 @@
 								/>
 
 							<p:columnToggler datasource="openingTimeList" trigger="toggler" />
-						</h:panelGroup>
+						</p:outputPanel>
 					</p:panelGrid>
 				</f:facet>
 
+				<p:ajax
+					event="rowSelect"
+					update="form-list-opening-times:opening-time-details"
+					oncomplete="PF('openingTimeDialog').show()"
+					/>
+
 				<p:column
 					headerText="#{msg.ID_HEADER}"
-					sortBy="#{openingTime.openingId}"
+					sortBy="#{openingTime.openingTimeId}"
 					filterable="false"
 					>
 					<p:link
 						outcome="admin_show_opening_time"
-						value="#{openingTime.openingId}"
-						title="#{msg.ADMIN_LINK_SHOW_DEPARTMENT_TITLE}"
+						value="#{openingTime.openingTimeId}"
+						title="#{msg.ADMIN_LINK_SHOW_OPENING_TIME_TITLE}"
 						>
-						<f:param name="openingId" value="#{openingTime.openingId}" />
+						<f:param name="openingTimeId" value="#{openingTime.openingTimeId}" />
 					</p:link>
 				</p:column>
 
@@ -143,14 +178,75 @@
 					</h:outputText>
 				</p:column>
 
+				<p:column
+					headerText="#{msg.ENTRY_CREATED_HEADER}"
+					sortBy="#{openingTime.openingTimeEntryCreated}"
+					filterBy="#{openingTime.openingTimeEntryCreated}"
+					filterMatchMode="contains"
+					>
+					<h:outputText value="#{openingTime.openingTimeEntryCreated}">
+						<f:convertDateTime type="both" timeStyle="short" dateStyle="short" />
+					</h:outputText>
+				</p:column>
+
+				<p:column
+					headerText="#{msg.ENTRY_UPDATED_HEADER}"
+					sortBy="#{openingTime.openingTimeEntryUpdated}"
+					filterBy="#{openingTime.openingTimeEntryUpdated}"
+					filterMatchMode="contains"
+					>
+					<h:outputText value="#{openingTime.openingTimeEntryUpdated}">
+						<f:convertDateTime type="both" timeStyle="short" dateStyle="short" />
+					</h:outputText>
+				</p:column>
+
 				<p:column
 					headerText="#{msg.ADMIN_ACTION_LINKS_HEADER}"
 					sortable="false"
 					filterable="false"
 					>
-					<links:outputOpeningTimeAdminDropdownMenu openingTime="#{openingTime}" />
+					<p:menuButton value="#{msg.OPTIONS}">
+						<p:menuitem outcome="admin_show_opening_time" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_OPENING_TIME_TITLE}">
+							<f:param name="openingTimeId" value="#{openingTime.openingTimeId}" />
+						</p:menuitem>
+
+						<p:menuitem outcome="admin_edit_opening_time" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_OPENING_TIME_TITLE}">
+							<f:param name="openingTimeId" value="#{openingTime.openingTimeId}" />
+						</p:menuitem>
+
+						<p:menuitem outcome="admin_delete_opening_time">
+							<h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_OPENING_TIME_TITLE}" />
+							<f:param name="openingTimeId" value="#{openingTime.openingTimeId}" />
+						</p:menuitem>
+					</p:menuButton>
 				</p:column>
 			</p:dataTable>
+
+			<p:dialog
+				dynamic="true"
+				modal="true"
+				resizable="false"
+				header="#{msg.ADMIN_SINGLE_OPENING_TIME_DETAILS_HEADER}"
+				hideEffect="fade"
+				showEffect="fade"
+				widgetVar="openingTimeDialog"
+				position="top"
+				responsive="true"
+				closeOnEscape="true"
+				>
+				<p:outputPanel id="opening-time-details">
+					<p:panelGrid columns="2" rendered="#{not empty openingTimeListController.selectedOpeningTime}">
+						<f:facet name="header">
+							<h:outputFormat value="#{msg.ADMIN_OPENING_TIME_DETAILS_HEADER}">
+								<f:param value="#{openingTimeListController.selectedOpeningTime.openingTimeId}" />
+							</h:outputFormat>
+						</f:facet>
+
+						<p:outputLabel value="#{msg.ID_HEADER}" title="#{msg.OPENING_TIME_ID_NUMBER_TITLE}" />
+						<h:outputText value="#{openingTimeListController.selectedOpeningTime.openingTimeId}" />
+					</p:panelGrid>
+				</p:outputPanel>
+			</p:dialog>
 		</h:form>
 
 		<h:form>
@@ -179,7 +275,7 @@
 							type="submit"
 							value="#{msg.BUTTON_ADMIN_ADD_OPENING_TIME}"
 							action="#{adminOpeningTimeController.addOpeningTime()}"
-							update="form-list-opening-time:openingTimeList"
+							update="form-list-opening-times:openingTimeList"
 							/>
 					</p:panelGrid>
 				</f:facet>
diff --git a/web/admin/user/admin_user_export.xhtml b/web/admin/user/admin_user_export.xhtml
index 371842e4..2d8b1362 100644
--- a/web/admin/user/admin_user_export.xhtml
+++ b/web/admin/user/admin_user_export.xhtml
@@ -179,8 +179,28 @@
 						<h:outputText value="#{msg.ADMIN_EXPORT_CONTACT_CREATED}" />
 					</f:facet>
 
-					<h:outputText id="contactCreated" value="#{user.userContact.contactCreated}">
-						<f:convertDateTime type="both" timeStyle="short" dateStyle="short" locale="#{localizationController.locale}" />
+					<h:outputText value="#{user.userContact.contactEntryCreated}">
+						<f:convertDateTime
+							type="both"
+							timeStyle="short"
+							dateStyle="short"
+							locale="#{localizationController.locale}"
+							/>
+					</h:outputText>
+				</p:column>
+
+				<p:column>
+					<f:facet name="header">
+						<h:outputText value="#{msg.ADMIN_EXPORT_CONTACT_UPDATED}" />
+					</f:facet>
+
+					<h:outputText value="#{user.userContact.contactEntryUpdated}">
+						<f:convertDateTime
+							type="both"
+							timeStyle="short"
+							dateStyle="short"
+							locale="#{localizationController.locale}"
+							/>
 					</h:outputText>
 				</p:column>
 			</p:dataTable>
diff --git a/web/guest/user/user_profile.xhtml b/web/guest/user/user_profile.xhtml
index 5c12d183..84243482 100644
--- a/web/guest/user/user_profile.xhtml
+++ b/web/guest/user/user_profile.xhtml
@@ -11,7 +11,14 @@
 
 	<ui:define name="metadata">
 		<f:metadata>
-			<f:viewParam name="userId" value="#{beanHelper.user}" converter="UserConverter" required="true" requiredMessage="#{msg.ERROR_PARAMETER_USER_ID_NOT_SET}" converterMessage="#{msg.PARAMETER_USER_ID_INVALID}" />
+			<f:viewParam
+				name="userId"
+				value="#{beanHelper.user}"
+				converter="UserConverter"
+				required="true"
+				requiredMessage="#{msg.ERROR_PARAMETER_USER_ID_NOT_SET}"
+				converterMessage="#{msg.PARAMETER_USER_ID_INVALID}"
+				/>
 			<f:viewAction action="#{beanHelper.notifyControllerUserConverted()}" />
 		</f:metadata>
 	</ui:define>
@@ -29,14 +36,28 @@
 	</ui:define>
 
 	<ui:define name="content">
-		<core:outputMessageBox panelGroupId="errorUserProfileDisabled" message="#{msg.ERROR_GUEST_USER_PROFILE_DISABLED}" messageStyleClass="alert-danger" rendered="#{not userController.isPublicUserProfileEnabled()}" />
+		<core:outputMessageBox
+			panelGroupId="errorUserProfileDisabled"
+			message="#{msg.ERROR_GUEST_USER_PROFILE_DISABLED}"
+			messageStyleClass="alert-danger"
+			rendered="#{not featureController.isFeatureEnabled("public_user_profile")}"
+			/>
 
-		<core:outputMessageBox panelGroupId="errorUserIdEmpty" message="#{msg.TABLE_HEADER_ERROR_HANDLING_USER_ID}" rendered="#{userController.isUserIdEmpty()}" />
+		<core:outputMessageBox
+			panelGroupId="errorUserIdEmpty"
+			message="#{msg.TABLE_HEADER_ERROR_HANDLING_USER_ID}"
+			rendered="#{userLoginController.isUserIdEmpty()}"
+			/>
 
-		<ui:fragment rendered="#{userController.isPublicUserProfileEnabled()}">
-			<core:outputMessageBox panelGroupId="errorUserProfileHidden" message="#{msg.ERROR_PROFILE_NOT_VISIBLE}" messageStyleClass="alert-danger" rendered="#{not profileController.isProfileLinkVisibleById(userController.userId)}" />
+		<ui:fragment rendered="#{featureController.isFeatureEnabled("public_user_profile")}">
+			<core:outputMessageBox
+				panelGroupId="errorUserProfileHidden"
+				message="#{msg.ERROR_PROFILE_NOT_VISIBLE}"
+				messageStyleClass="alert-danger"
+				rendered="#{not profileController.isProfileLinkVisibleById(userLoginController.userId)}"
+				/>
 
-			<ui:fragment rendered="#{profileController.isProfileLinkVisibleById(userController.userId)}">
+			<ui:fragment rendered="#{profileController.isProfileLinkVisibleById(userLoginController.userId)}">
 				<p:panelGrid>
 					<f:facet name="header">
 						<h:outputText value="#{msg.PUBLIC_USER_PROFILE}" />
diff --git a/web/user/login_user_change_personal_data.xhtml b/web/user/login_user_change_personal_data.xhtml
index 27f83c81..7b5c18de 100644
--- a/web/user/login_user_change_personal_data.xhtml
+++ b/web/user/login_user_change_personal_data.xhtml
@@ -38,7 +38,9 @@
 			</div>
 
 			<h:form>
-				<ui:include src="/WEB-INF/templates/contact/form_contact_data.tpl" />
+				<ui:include src="/WEB-INF/templates/contact/form_contact_data.tpl">
+					<ui:param name="targetController" value="#{userLoginController}" />
+				</ui:include>
 
 				<ui:include src="/WEB-INF/templates/login/user/user_enter_current_password.tpl" />