From: Roland Haeder <roland@mxchange.org>
Date: Mon, 15 Feb 2016 19:34:36 +0000 (+0100)
Subject: renamed packages (addressbook import) + added event for logging in
X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=74e99167ce4e6f35f4bd7cb9e60d3f1f83238769;p=jjobs-war.git

renamed packages (addressbook import) + added event for logging in
---

diff --git a/src/java/org/mxchange/addressbook/beans/addressbook/AddressbookWebSessionBean.java b/src/java/org/mxchange/addressbook/beans/addressbook/AddressbookWebSessionBean.java
deleted file mode 100644
index d01fbbef..00000000
--- a/src/java/org/mxchange/addressbook/beans/addressbook/AddressbookWebSessionBean.java
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.addressbook.beans.addressbook;
-
-import java.text.MessageFormat;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.GregorianCalendar;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import javax.annotation.PostConstruct;
-import javax.enterprise.context.SessionScoped;
-import javax.enterprise.event.Observes;
-import javax.faces.view.facelets.FaceletException;
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import org.mxchange.addressbook.beans.login.UserLoginWebSessionController;
-import org.mxchange.addressbook.events.addressbook.AddressbookLoadedEvent;
-import org.mxchange.addressbook.exceptions.AddressbookNameAlreadyUsedException;
-import org.mxchange.addressbook.model.addressbook.Addressbook;
-import org.mxchange.addressbook.model.addressbook.AddressbookSessionBeanRemote;
-import org.mxchange.addressbook.model.addressbook.UserAddressbook;
-import org.mxchange.addressbook.model.addressbook.entry.AddressbookEntry;
-import org.mxchange.jusercore.events.login.UserLoggedInEvent;
-import org.mxchange.jusercore.model.user.User;
-
-/**
- * An address book bean (controller)
- * <p>
- * @author Roland Haeder<roland@mxchange.org>
- */
-@Named ("addressbookController")
-@SessionScoped
-public class AddressbookWebSessionBean implements AddressbookWebSessionController {
-
-	/**
-	 * Map for count of user's shared addresses
-	 */
-	private static ConcurrentMap<User, Integer> countSharesList;
-
-	/**
-	 * Serial number
-	 */
-	private static final long serialVersionUID = 185_781_756_712_969L;
-
-	/**
-	 * Address book instance
-	 */
-	private Addressbook addressbook;
-
-	/**
-	 * Remote address book bean
-	 */
-	private AddressbookSessionBeanRemote addressbookBean;
-
-	/**
-	 * When this address book has been created
-	 */
-	private Calendar addressbookCreated;
-
-	/**
-	 * Address book id number (from URL for example)
-	 */
-	private Long addressbookId;
-
-	/**
-	 * Name of the address book
-	 */
-	private String addressbookName;
-
-	/**
-	 * Who owns this address book
-	 */
-	private User addressbookUser;
-
-	/**
-	 * Login controller
-	 */
-	@Inject
-	private UserLoginWebSessionController loginController;
-
-	/**
-	 * A list of all user's address books
-	 */
-	private List<Addressbook> usersAddressbooks;
-
-	/**
-	 * Default constructor
-	 */
-	public AddressbookWebSessionBean () {
-		// Try it
-		try {
-			// Get initial context
-			Context context = new InitialContext();
-
-			// Try to lookup
-			this.addressbookBean = (AddressbookSessionBeanRemote) context.lookup("ejb/stateless-addressbook"); //NOI18N
-		} catch (final NamingException e) {
-			// Throw again
-			throw new FaceletException(e);
-		}
-
-		// Init list
-		AddressbookWebSessionBean.countSharesList = new ConcurrentHashMap<>(0);
-	}
-
-	@Override
-	public String addAddressbook () {
-		// Is this name already used?
-		if (!this.loginController.isUserLoggedIn()) {
-			// Not logged in
-			throw new FaceletException("This method can only be called as logged-in user."); //NOI18N
-		} else if (this.getAddressbookName() == null) {
-			// Address book name is null
-			throw new NullPointerException("addressbookName is null"); //NOI18N
-		} else if (this.getAddressbookName().isEmpty()) {
-			// Address book name is empty
-			throw new IllegalStateException("addressbookName is empty."); //NOI18N
-		} else if (this.isAddressbookNameUsed(this.getAddressbookName())) {
-			// Already used by this user
-			throw new FaceletException(MessageFormat.format("Address book name {0} already used.", this.getAddressbookName())); //NOI18N
-		}
-
-		// Create address book instance with name
-		Addressbook book = new UserAddressbook(this.getAddressbookName(), this.loginController.getLoggedInUser(), new GregorianCalendar());
-
-		try {
-			// Register this address book
-			Addressbook updatedAddressbook = this.addressbookBean.createAddressbook(book);
-
-			// Remove name
-			this.setAddressbookName(null);
-
-			// Add address book entry to list
-			this.usersAddressbooks.add(updatedAddressbook);
-
-			// All fine
-			return "login_own_addressbooks"; //NOI18N
-		} catch (final AddressbookNameAlreadyUsedException ex) {
-			// Throw again as cause
-			throw new FaceletException(ex);
-		}
-	}
-
-	@Override
-	public void afterAddressbookLoadedEvent (final @Observes AddressbookLoadedEvent event) {
-		// event should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getAddressbook() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.addressbook is null"); //NOI18N
-		} else if (event.getAddressbook().getAddressbookId() == null) {
-			// And again a NPE
-			throw new NullPointerException("event.addressbook.addressbookId is null"); //NOI18N
-		} else if (event.getAddressbook().getAddressbookId() < 1) {
-			// Invalid id number
-			throw new IllegalArgumentException(MessageFormat.format("Address book instance {0} has invalid id number: {1}", event.getAddressbook(), event.getAddressbook().getAddressbookId())); //NOI18N
-		} else if (event.getAddressbook().getAddressbookUser() == null) {
-			// One more NPE ...
-			throw new NullPointerException("event.addressbook.addressbookUser is null"); //NOI18N
-		}
-
-		// Get address book instance
-		Addressbook book = event.getAddressbook();
-
-		// Set address book data
-		this.setAddressbookId(book.getAddressbookId());
-		this.setAddressbookName(book.getAddressbookName());
-		this.setAddressbookUser(book.getAddressbookUser());
-		this.setAddressbookCreated(book.getAddressbookCreated());
-
-		// And instance ...
-		this.setAddressbook(book);
-	}
-
-	@Override
-	public void afterLoginEvent (final @Observes UserLoggedInEvent event) {
-		// Is the user logged in?
-		if (null == event) {
-			// Is null
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getUser() == null) {
-			// user is null
-			throw new NullPointerException("event.user is null"); //NOI18N
-		} else if (!event.getUser().equals(this.loginController.getLoggedInUser())) {
-			// Not matching
-			throw new IllegalStateException("event.user and loginController.loggedInUser don't match."); //NOI18N
-		} else if (!this.loginController.isUserLoggedIn()) {
-			// Not logged in
-			throw new FaceletException("This method can only be called as logged-in user."); //NOI18N
-		}
-
-		// Init user's address book list
-		this.initAddressbookList();
-	}
-
-	@Override
-	public List<Addressbook> allAddressbooks () {
-		// Is the user logged in?
-		if (!this.loginController.isUserLoggedIn()) {
-			// Not logged in
-			throw new FaceletException("This method can only be called as logged-in user."); //NOI18N
-		}
-
-		return Collections.unmodifiableList(this.usersAddressbooks);
-	}
-
-	@Override
-	public List<AddressbookEntry> allEntries (final Addressbook addressbook) {
-		// Is the user logged in?
-		if (!this.loginController.isUserLoggedIn()) {
-			// Not logged in
-			throw new FaceletException("This method can only be called as logged-in user."); //NOI18N
-		}
-
-		// Ask the bean
-		return this.addressbookBean.allEntries(addressbook);
-	}
-
-	@Override
-	public int allEntriesSize (final Addressbook addressbook) {
-		// Ask the bean
-		return this.allEntries(addressbook).size();
-	}
-
-	@Override
-	public List<User> allUsersNotSharing () {
-		// Is the user logged in?
-		if (!this.loginController.isUserLoggedIn()) {
-			// Not logged in
-			throw new FaceletException("This method can only be called as logged-in user."); //NOI18N
-		}
-
-		// Call EJB
-		return this.addressbookBean.allUsersNotSharing(this.loginController.getLoggedInUser(), this.getAddressbook());
-	}
-
-	@Override
-	public Integer countAllUserSharedAddressbooks (final User user) {
-		// Is there cache?
-		if (AddressbookWebSessionBean.countSharesList.containsKey(user)) {
-			// Return it instead
-			return AddressbookWebSessionBean.countSharesList.get(user);
-		}
-
-		// Call EJB ("expensive")
-		Integer count = this.addressbookBean.countAllUserSharedAddressbooks(user);
-
-		// Add to list
-		AddressbookWebSessionBean.countSharesList.put(user, count);
-
-		// Return it
-		return count;
-	}
-
-	@Override
-	public Addressbook getAddressbook () {
-		return this.addressbook;
-	}
-
-	@Override
-	public void setAddressbook (final Addressbook addressbook) {
-		this.addressbook = addressbook;
-	}
-
-	@Override
-	public Calendar getAddressbookCreated () {
-		return this.addressbookCreated;
-	}
-
-	@Override
-	public void setAddressbookCreated (final Calendar addressbookCreated) {
-		this.addressbookCreated = addressbookCreated;
-	}
-
-	@Override
-	public Long getAddressbookId () {
-		return this.addressbookId;
-	}
-
-	@Override
-	public void setAddressbookId (final Long addressbookId) {
-		this.addressbookId = addressbookId;
-	}
-
-	@Override
-	public String getAddressbookName () {
-		return this.addressbookName;
-	}
-
-	@Override
-	public void setAddressbookName (final String addressbookName) {
-		this.addressbookName = addressbookName;
-	}
-
-	@Override
-	public User getAddressbookUser () {
-		return this.addressbookUser;
-	}
-
-	@Override
-	public void setAddressbookUser (final User addressbookUser) {
-		this.addressbookUser = addressbookUser;
-	}
-
-	@Override
-	public boolean hasCreatedAddressbooks () {
-		// Is the user logged in?
-		if (!this.loginController.isUserLoggedIn()) {
-			// Not logged in
-			throw new FaceletException("This method can only be called as logged-in user."); //NOI18N
-		}
-
-		// Check if the list is filled
-		return (!this.usersAddressbooks.isEmpty());
-	}
-
-	@PostConstruct
-	public void init () {
-		// Init list
-		this.usersAddressbooks = new LinkedList<>();
-
-		// Is the user logged-in?
-		if (this.loginController.isUserLoggedIn()) {
-			// Initialize list
-			this.initAddressbookList();
-		}
-
-		// TODO Initialize list from bean with just one call
-		//this.addressbookBean.getUserCountMap()
-	}
-
-	@Override
-	public boolean isAddressbookNameUsed (final String addressbookName) {
-		// Is it zero size?
-		if (null == addressbookName) {
-			// Is null
-			throw new NullPointerException("addressbookName is null"); //NOI18N
-		} else if (this.usersAddressbooks.isEmpty()) {
-			// Not found!
-			return false;
-		}
-
-		// Default is not found
-		boolean isFound = false;
-
-		// Check all entries
-		for (final Addressbook book : this.usersAddressbooks) {
-			// Is the name same?
-			if (book.getAddressbookName().equals(addressbookName)) {
-				// Found a match
-				isFound = true;
-				break;
-			}
-		}
-
-		// Return status
-		return isFound;
-	}
-
-	@Override
-	public boolean isOtherAddressbook () {
-		// Just call the other method and invert it
-		return (!this.isOwnAddressbook());
-	}
-
-	@Override
-	public boolean isOwnAddressbook () {
-		// Is the user logged in?
-		if (!this.loginController.isUserLoggedIn()) {
-			// No, then no own address book
-			throw new IllegalStateException("isOwnAddressbook() has been invoked for a guest account"); //NOI18N
-		}
-
-		// Is same user?
-		return Objects.equals(this.getAddressbookUser(), this.loginController.getLoggedInUser());
-	}
-
-	@Override
-	public boolean isAddressbookLoaded () {
-		return ((this.getAddressbookId() instanceof Long)
-				&& (this.getAddressbookName() instanceof String)
-				&& (!this.getAddressbookName().isEmpty())
-				&& (this.getAddressbookUser() instanceof User));
-	}
-
-	/**
-	 * Initializes the user user's address book list
-	 */
-	private void initAddressbookList () {
-		// Get user instance
-		User user = this.loginController.getLoggedInUser();
-
-		// Fill list with entries
-		this.usersAddressbooks = this.addressbookBean.getUsersAddressbookList(user);
-	}
-}
diff --git a/src/java/org/mxchange/addressbook/beans/addressbook/AddressbookWebSessionController.java b/src/java/org/mxchange/addressbook/beans/addressbook/AddressbookWebSessionController.java
deleted file mode 100644
index af97a86b..00000000
--- a/src/java/org/mxchange/addressbook/beans/addressbook/AddressbookWebSessionController.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.addressbook.beans.addressbook;
-
-import java.io.Serializable;
-import java.util.Calendar;
-import java.util.List;
-import org.mxchange.addressbook.events.addressbook.AddressbookLoadedEvent;
-import org.mxchange.addressbook.model.addressbook.Addressbook;
-import org.mxchange.addressbook.model.addressbook.entry.AddressbookEntry;
-import org.mxchange.jusercore.events.login.UserLoggedInEvent;
-import org.mxchange.jusercore.model.user.User;
-
-/**
- * An interface for address book beans
- * <p>
- * @author Roland Haeder<roland@mxchange.org>
- */
-public interface AddressbookWebSessionController extends Serializable {
-
-	/**
-	 * Checks whether the user has created addressbooks. For this method to work
-	 * it is vital that the user is logged into his/her account.
-	 * <p>
-	 * @return Whether the user has created at least one addressbook
-	 */
-	boolean hasCreatedAddressbooks ();
-
-	/**
-	 * Creates a new address book with a name and redirects to proper target.
-	 * For this method to work it is vital that the user is logged into his/her
-	 * account.
-	 * <p>
-	 * @return Target to redirect to
-	 */
-	String addAddressbook ();
-
-	/**
-	 * Getter for address book name
-	 * <p>
-	 * @return Address book name
-	 */
-	String getAddressbookName ();
-
-	/**
-	 * Setter for address book name
-	 * <p>
-	 * @param addressbookName Address book name
-	 */
-	void setAddressbookName (final String addressbookName);
-
-	/**
-	 * Checks if the given address book name is already used by the user.
-	 * <p>
-	 * @param addressbookName Address book name to check
-	 * <p>
-	 * @return Whether the name has already been used by the user
-	 */
-	boolean isAddressbookNameUsed (final String addressbookName);
-
-	/**
-	 * Returns all address books with this user
-	 * <p>
-	 * @return A list of all address books by this user
-	 */
-	List<Addressbook> allAddressbooks ();
-
-	/**
-	 * Returns a list of all address book entries for given address book
-	 * <p>
-	 * @param addressbook Address book instance
-	 * <p>
-	 * @return List of all entries
-	 */
-	List<AddressbookEntry> allEntries (final Addressbook addressbook);
-
-	/**
-	 * Size of all entries in given address book
-	 * <p>
-	 * @param addressbook Address book instance
-	 * <p>
-	 * @return Size of the entries in address book
-	 */
-	int allEntriesSize (final Addressbook addressbook);
-
-	/**
-	 * Getter for address book id number
-	 * <p>
-	 * @return Address book id number
-	 */
-	Long getAddressbookId ();
-
-	/**
-	 * Setter for address book id number
-	 * <p>
-	 * @param addressbookId Address book id number
-	 */
-	void setAddressbookId (final Long addressbookId);
-
-	/**
-	 * Getter for address book user (owner)
-	 * <p>
-	 * @return Address book user (owner)
-	 */
-	User getAddressbookUser ();
-
-	/**
-	 * Setter for address book user (owner)
-	 * <p>
-	 * @param addressbookUser Address book user (owner)
-	 */
-	void setAddressbookUser (final User addressbookUser);
-
-	/**
-	 * Getter for when the address book has been created
-	 * <p>
-	 * @return When the address book has been created
-	 */
-	Calendar getAddressbookCreated ();
-
-	/**
-	 * Setter for when the address book has been created
-	 * <p>
-	 * @param addressbookCreated When the address book has been created
-	 */
-	void setAddressbookCreated (final Calendar addressbookCreated);
-
-	/**
-	 * This method is called when an address book has been successfully loaded
-	 * from JPA.
-	 * <p>
-	 * @param event Event with address book instance
-	 */
-	void afterAddressbookLoadedEvent (final AddressbookLoadedEvent event);
-
-	/**
-	 * Count all shared address books by given user id
-	 * <p>
-	 * @param user User instance to look for
-	 * <p>
-	 * @return Count of user's shared address books
-	 */
-	Integer countAllUserSharedAddressbooks (final User user);
-
-	/**
-	 * This method is called when a user has successfully logged in his/her
-	 * account.
-	 * <p>
-	 * @param event
-	 */
-	void afterLoginEvent (final UserLoggedInEvent event);
-
-	/**
-	 * Checks if the user is logged in and if so if it matches the current
-	 * address book owner.
-	 * <p>
-	 * @return Whether the owner matches currently logged-in user
-	 */
-	boolean isOwnAddressbook ();
-
-	/**
-	 * Checks if the owner of the current address book is NOT matching the
-	 * logged-in user.
-	 * <p>
-	 * @return Whether the user does NOT match
-	 */
-	boolean isOtherAddressbook ();
-
-	/**
-	 * Getter for address book instance
-	 * <p>
-	 * @return Address book instance
-	 */
-	Addressbook getAddressbook ();
-
-	/**
-	 * Setter for address book instance
-	 * <p>
-	 * @param addressbook Address book instance
-	 */
-	void setAddressbook (final Addressbook addressbook);
-
-	/**
-	 * Retrieves a list of all users this user is not sharing this address book
-	 * with.
-	 * <p>
-	 * @return List of not sharing users
-	 */
-	List<User> allUsersNotSharing ();
-
-	/**
-	 * Checks wether an address book has been loaded by checking the id number.
-	 * <p>
-	 * @return Whether the address book is loaded
-	 */
-	boolean isAddressbookLoaded ();
-}
diff --git a/src/java/org/mxchange/addressbook/beans/country/CountryWebApplicationBean.java b/src/java/org/mxchange/addressbook/beans/country/CountryWebApplicationBean.java
deleted file mode 100644
index b994cd84..00000000
--- a/src/java/org/mxchange/addressbook/beans/country/CountryWebApplicationBean.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package org.mxchange.addressbook.beans.country;
-
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify it under
- * the terms of the GNU 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 General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-import java.util.Collections;
-import java.util.List;
-import javax.annotation.PostConstruct;
-import javax.enterprise.context.ApplicationScoped;
-import javax.faces.view.facelets.FaceletException;
-import javax.inject.Named;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import org.mxchange.jcountry.data.AddressbookCountrySingletonBeanRemote;
-import org.mxchange.jcountry.data.Country;
-
-/**
- * A country bean
- * <p>
- * @author Roland Haeder<roland@mxchange.org>
- */
-@Named ("country")
-@ApplicationScoped
-public class CountryWebApplicationBean implements CountryWebApplicationController {
-
-	/**
-	 * Serial number
-	 */
-	private static final long serialVersionUID = 176_985_298_681_742_960L;
-
-	/**
-	 * Remote country EJB
-	 */
-	private AddressbookCountrySingletonBeanRemote countryBean;
-
-	/**
-	 * List of all countries
-	 */
-	private List<Country> countryList;
-
-	/**
-	 * Default constructor
-	 */
-	public CountryWebApplicationBean () {
-		// Try this
-		try {
-			// Get initial context
-			Context context = new InitialContext();
-
-			// Try to lookup the bean
-			this.countryBean = (AddressbookCountrySingletonBeanRemote) context.lookup("ejb/addressbook-singleton-country"); //NOI18N
-		} catch (final NamingException ex) {
-			// Continue to throw
-			throw new FaceletException(ex);
-		}
-	}
-
-	@Override
-	public List<Country> allCountries () {
-		// Return "cached" version
-		return Collections.unmodifiableList(this.countryList);
-	}
-
-	@PostConstruct
-	public void init () {
-		this.countryList = this.countryBean.allCountries();
-	}
-}
diff --git a/src/java/org/mxchange/addressbook/beans/country/CountryWebApplicationController.java b/src/java/org/mxchange/addressbook/beans/country/CountryWebApplicationController.java
deleted file mode 100644
index bc70b9ce..00000000
--- a/src/java/org/mxchange/addressbook/beans/country/CountryWebApplicationController.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.mxchange.addressbook.beans.country;
-
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify it under
- * the terms of the GNU 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 General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-import java.io.Serializable;
-import java.util.List;
-import org.mxchange.jcountry.data.Country;
-
-/**
- * An interface for country beans
- * <p>
- * @author Roland Haeder<roland@mxchange.org>
- */
-public interface CountryWebApplicationController extends Serializable {
-
-	/**
-	 * A list of all countries
-	 * <p>
-	 * @return All countries
-	 */
-	List<Country> allCountries ();
-}
diff --git a/src/java/org/mxchange/addressbook/beans/gender/GenderWebApplicationBean.java b/src/java/org/mxchange/addressbook/beans/gender/GenderWebApplicationBean.java
deleted file mode 100644
index 1738fcf1..00000000
--- a/src/java/org/mxchange/addressbook/beans/gender/GenderWebApplicationBean.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.addressbook.beans.gender;
-
-import java.util.List;
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Named;
-import org.mxchange.jcontacts.contact.gender.Gender;
-import org.mxchange.jcontacts.contact.gender.GenderUtils;
-
-/**
- * A gender bean
- * <p>
- * @author Roland Haeder<roland@mxchange.org>
- */
-@Named ("gender")
-@ApplicationScoped
-public class GenderWebApplicationBean implements GenderWebApplicationController {
-
-	/**
-	 * Serial number
-	 */
-	private static final long serialVersionUID = 835_482_364_189L;
-
-	/**
-	 * Default constructor
-	 */
-	public GenderWebApplicationBean () {
-	}
-
-	@Override
-	public Gender[] getAllGenders () {
-		// Return it
-		return Gender.values();
-	}
-
-	@Override
-	public List<Gender> getSelectableGenders () {
-		// Init array
-		List<Gender> genders = GenderUtils.selectableGenders();
-
-		// Return it
-		return genders;
-	}
-}
diff --git a/src/java/org/mxchange/addressbook/beans/gender/GenderWebApplicationController.java b/src/java/org/mxchange/addressbook/beans/gender/GenderWebApplicationController.java
deleted file mode 100644
index 9f24dbfd..00000000
--- a/src/java/org/mxchange/addressbook/beans/gender/GenderWebApplicationController.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.addressbook.beans.gender;
-
-import java.io.Serializable;
-import java.util.List;
-import org.mxchange.jcontacts.contact.gender.Gender;
-
-/**
- * An interface for data beans
- * <p>
- * @author Roland Haeder<roland@mxchange.org>
- */
-public interface GenderWebApplicationController extends Serializable {
-
-	/**
-	 * Getter for all genders as array
-	 * <p>
-	 * @return All genders as array
-	 */
-	Gender[] getAllGenders ();
-
-	/**
-	 * Getter for only selectable genders as array, UNKNOWN is not selectable
-	 * <p>
-	 * @return All genders as array
-	 */
-	List<Gender> getSelectableGenders ();
-}
diff --git a/src/java/org/mxchange/addressbook/beans/login/UserLoginWebSessionBean.java b/src/java/org/mxchange/addressbook/beans/login/UserLoginWebSessionBean.java
deleted file mode 100644
index 314285e4..00000000
--- a/src/java/org/mxchange/addressbook/beans/login/UserLoginWebSessionBean.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.addressbook.beans.login;
-
-import java.util.Objects;
-import javax.enterprise.context.SessionScoped;
-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 javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import org.mxchange.addressbook.beans.user.UserWebSessionController;
-import org.mxchange.jusercore.container.login.LoginContainer;
-import org.mxchange.jusercore.container.login.UserLoginContainer;
-import org.mxchange.jusercore.events.login.UserLoggedInEvent;
-import org.mxchange.jusercore.events.login.UserLoginEvent;
-import org.mxchange.jusercore.exceptions.UserNotFoundException;
-import org.mxchange.jusercore.exceptions.UserPasswordMismatchException;
-import org.mxchange.jusercore.exceptions.UserStatusLockedException;
-import org.mxchange.jusercore.exceptions.UserStatusUnconfirmedException;
-import org.mxchange.jusercore.model.login.UserLoginSessionBeanRemote;
-import org.mxchange.jusercore.model.user.User;
-import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
-import org.mxchange.jusercore.model.user.status.UserAccountStatus;
-
-/**
- * A web bean for user registration
- * <p>
- * @author Roland Haeder
- */
-@Named ("loginController")
-@SessionScoped
-public class UserLoginWebSessionBean implements UserLoginWebSessionController {
-
-	/**
-	 * Serial number
-	 */
-	private static final long serialVersionUID = 47_828_986_719_691_592L;
-
-	/**
-	 * Logged-in user instance
-	 */
-	private User loggedInUser;
-
-	/**
-	 * Reemote register session bean
-	 */
-	private UserLoginSessionBeanRemote loginBean;
-
-	/**
-	 * Event fired when user has logged in
-	 */
-	@Inject
-	@Any
-	private Event<UserLoggedInEvent> loginEvent;
-
-	/**
-	 * Template type for pages that might be displayed in guest area and login
-	 * area. Default is guest area.
-	 */
-	private String templateType = "guest"; //NOI18N
-
-	/**
-	 * User controller
-	 */
-	@Inject
-	private UserWebSessionController userController;
-
-	/**
-	 * Flag whether the user has logged-in, set only from inside
-	 */
-	private boolean userLoggedIn;
-
-	/**
-	 * Default constructor
-	 */
-	public UserLoginWebSessionBean () {
-		try {
-			// Get initial context
-			Context context = new InitialContext();
-
-			// Try to lookup
-			this.loginBean = (UserLoginSessionBeanRemote) context.lookup("ejb/stateless-login"); //NOI18N
-		} catch (final NamingException ex) {
-			// Continue to throw
-			throw new FaceletException(ex);
-		}
-	}
-
-	@Override
-	public String doLogin () {
-		// Get user instance
-		User user = this.userController.createUserInstance();
-
-		// Create login container
-		LoginContainer container = new UserLoginContainer(user, this.userController.getUserPassword());
-
-		try {
-			// Call bean
-			User confirmedUser = this.loginBean.validateUserAccountStatus(container);
-
-			// All fine here so set it here
-			this.setLoggedInUser(confirmedUser);
-
-			// Set template to "login"
-			this.setTemplateType("login"); //NOI18N
-
-			// Fire event away. Keep this last before return statement.
-			this.loginEvent.fire(new UserLoginEvent(confirmedUser));
-
-			// All fine
-			return "login"; //NOI18N
-		} catch (final UserNotFoundException | UserStatusLockedException | UserStatusUnconfirmedException | UserPasswordMismatchException ex) {
-			// Throw again
-			throw new FaceletException(ex);
-		}
-	}
-
-	@Override
-	public User getLoggedInUser () {
-		return this.loggedInUser;
-	}
-
-	@Override
-	public void setLoggedInUser (final User loggedInUser) {
-		this.loggedInUser = loggedInUser;
-	}
-
-	@Override
-	public String getTemplateType () {
-		return this.templateType;
-	}
-
-	@Override
-	public void setTemplateType (final String templateType) {
-		this.templateType = templateType;
-	}
-
-	@Override
-	public boolean isGuest () {
-		return (!this.isUserLoggedIn());
-	}
-
-	@Override
-	public boolean isInvisible () {
-		// Check on login
-		if (!this.isUserLoggedIn()) {
-			// Not logged in!
-			throw new IllegalStateException("isInvisible() has been invoked for a guest."); //NOI18N
-		}
-
-		// Check logged-in first, then invisibility
-		return this.getLoggedInUser().getUserProfileMode().equals(ProfileMode.INVISIBLE);
-	}
-
-	@Override
-	public boolean isUserLoggedIn () {
-		// Trace message
-		// NOISY: System.out.println(MessageFormat.format("UserLoginWebSessionBean:isUserLoggedIn: this.loggedInUser={0},this.templateType={1} - CALLED!", this.getLoggedInUser(), this.getTemplateType()));
-
-		// Compare instance
-		this.userLoggedIn = ((this.getLoggedInUser() instanceof User) && (Objects.equals(this.getLoggedInUser().getUserAccountStatus(), UserAccountStatus.CONFIRMED)));
-
-		// Trace message
-		// NOISY: System.out.println(MessageFormat.format("UserLoginWebSessionBean:isUserLoggedIn: this.userLoggedIn={0} - EXIT!", this.userLoggedIn));
-
-		// Return it
-		return this.userLoggedIn;
-	}
-}
diff --git a/src/java/org/mxchange/addressbook/beans/login/UserLoginWebSessionController.java b/src/java/org/mxchange/addressbook/beans/login/UserLoginWebSessionController.java
deleted file mode 100644
index 31d9b212..00000000
--- a/src/java/org/mxchange/addressbook/beans/login/UserLoginWebSessionController.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.addressbook.beans.login;
-
-import java.io.Serializable;
-import org.mxchange.jusercore.model.user.User;
-
-/**
- * An interface for registration web controllers
- * <p>
- * @author Roland Haeder
- */
-public interface UserLoginWebSessionController extends Serializable {
-
-	/**
-	 * Getter for template type
-	 * <p>
-	 * @return Template type
-	 */
-	String getTemplateType ();
-
-	/**
-	 * Setter for template type
-	 * <p>
-	 * @param templateType Template type
-	 */
-	void setTemplateType (final String templateType);
-
-	/**
-	 * Logins the user, if the account is found, confirmed and unlocked.
-	 * <p>
-	 * @return Redirect target
-	 */
-	String doLogin ();
-
-	/**
-	 * Getter for logged-in user instance
-	 * <p>
-	 * @return Logged-in user instance
-	 */
-	User getLoggedInUser ();
-
-	/**
-	 * Setter for logged-in user instance
-	 * <p>
-	 * @param loggedInUser Logged-in user instance
-	 */
-	void setLoggedInUser (final User loggedInUser);
-
-	/**
-	 * Checks whether the user is logged-in
-	 * <p>
-	 * @return Whether the user is logged-in
-	 */
-	boolean isUserLoggedIn ();
-
-	/**
-	 * Is this truly a guest?
-	 * <p>
-	 * @return Whether the user is truly a guest
-	 */
-	boolean isGuest ();
-
-	/**
-	 * Whether the currently logged-in user is invisible
-	 * <p>
-	 * @return Whether the currently logged-in user is invisible
-	 */
-	boolean isInvisible ();
-}
diff --git a/src/java/org/mxchange/addressbook/beans/profile/UserProfileWebRequestBean.java b/src/java/org/mxchange/addressbook/beans/profile/UserProfileWebRequestBean.java
deleted file mode 100644
index c10dff0c..00000000
--- a/src/java/org/mxchange/addressbook/beans/profile/UserProfileWebRequestBean.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.addressbook.beans.profile;
-
-import java.text.MessageFormat;
-import javax.enterprise.context.RequestScoped;
-import javax.faces.view.facelets.FaceletException;
-import javax.inject.Inject;
-import javax.inject.Named;
-import org.mxchange.addressbook.beans.login.UserLoginWebSessionController;
-import org.mxchange.addressbook.beans.user.UserWebSessionController;
-import org.mxchange.jusercore.exceptions.UserNotFoundException;
-import org.mxchange.jusercore.model.user.User;
-import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
-
-/**
- * A web request bean for user profiles
- * <p>
- * @author Roland Haeder
- */
-@Named (value = "profileController")
-@RequestScoped
-public class UserProfileWebRequestBean implements UserProfileWebRequestController {
-
-	/**
-	 * Serial number
-	 */
-	private static final long serialVersionUID = 187_687_145_286_710L;
-
-	/**
-	 * Login controller
-	 */
-	@Inject
-	private UserLoginWebSessionController loginController;
-
-	/**
-	 * User instance
-	 */
-	private User user;
-
-	/**
-	 * User controller
-	 */
-	@Inject
-	private UserWebSessionController userController;
-
-	@Override
-	public User getUser () {
-		return this.user;
-	}
-
-	@Override
-	public void setUser (final User user) {
-		this.user = user;
-	}
-
-	@Override
-	public boolean isProfileLinkVisible () {
-		// Check on user
-		if (this.getUser() == null) {
-			/*
-			 * Not set, means wrong invocation of this method as the user
-			 * instance needs to be set first.
-			 */
-			throw new NullPointerException("this.user is null"); //NOI18N
-		} else if (this.getUser().getUserId() == null) {
-			/*
-			 * If the id number is not set it means that the user instance has
-			 * not been persisted and the JPA has not been flushed. Or a
-			 * "virgin" instance (e.g. from registration) has been used.
-			 */
-			throw new NullPointerException("this.user.userId is null"); //NOI18N
-		} else if (this.getUser().getUserId() < 1) {
-			/*
-			 * The id number is set invalid for an unknown reason.
-			 */
-			throw new IllegalArgumentException(MessageFormat.format("this.user.userId={0} is invalid", this.getUser().getUserId())); //NOI18N
-		} else if (this.getUser().getUserProfileMode() == null) {
-			/*
-			 * Possibly an out-dated user profile is being used. This should not
-			 * happen.
-			 */
-			throw new NullPointerException("this.user.userProfileMode is null"); //NOI18N
-		}
-
-		// Get profile mode from user instance (safe now)
-		ProfileMode profileMode = this.getUser().getUserProfileMode();
-
-		// Check all conditions (except for admin)
-		// TODO: Add admin role somehow?
-		return ((profileMode.equals(ProfileMode.PUBLIC)) ||
-				 (this.loginController.isUserLoggedIn()) && (profileMode.equals(ProfileMode.MEMBERS)));
-	}
-
-	@Override
-	public boolean isProfileLinkVisibleById (final Long userId) {
-		// Init user instance
-		User u = null;
-
-		try {
-			// Try to get it
-			u = this.userController.lookupUserById(userId);
-		} catch (final UserNotFoundException ex) {
-			// Throw again
-			throw new FaceletException(ex);
-		}
-
-		// Set it here
-		this.setUser(u);
-
-		// Is it null?
-		if (null == u) {
-			// Not found, not visible.
-			return false;
-		}
-
-		// Ask other method
-		return this.isProfileLinkVisible();
-	}
-
-	@Override
-	public boolean isProfileLinkVisibleByUser (final User user) {
-		// Is it correctly set?
-		if (null == user) {
-			// Throw NPE
-			throw new NullPointerException("user is null");
-		} else if (user.getUserId() == null) {
-			// Throw NPE again
-			throw new NullPointerException("user.userId is null");
-		} else if (user.getUserId() < 1) {
-			// Invalid user id set
-			throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is not valid.", user.getUserId()));
-		}
-
-		// Set user here
-		this.setUser(user);
-
-		// Ask other method
-		return this.isProfileLinkVisible();
-	}
-}
diff --git a/src/java/org/mxchange/addressbook/beans/profile/UserProfileWebRequestController.java b/src/java/org/mxchange/addressbook/beans/profile/UserProfileWebRequestController.java
deleted file mode 100644
index e7306887..00000000
--- a/src/java/org/mxchange/addressbook/beans/profile/UserProfileWebRequestController.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.addressbook.beans.profile;
-
-import java.io.Serializable;
-import org.mxchange.jusercore.model.user.User;
-
-/**
- * A bean interface for user profiles
- * <p>
- * @author Roland Haeder
- */
-public interface UserProfileWebRequestController extends Serializable {
-
-	/**
-	 * Checks if the current user profile link is visible
-	 * <p>
-	 * @return Whether the profile link is visible
-	 */
-	boolean isProfileLinkVisible ();
-
-	/**
-	 * Checks if the user profile link is visible
-	 * <p>
-	 * @param userId User id
-	 * <p>
-	 * @return Whether the profile link is visible
-	 */
-	boolean isProfileLinkVisibleById (final Long userId);
-
-	/**
-	 * Checks if given user's profile is visible
-	 * <p>
-	 * @param user User instance to check
-	 * <p>
-	 * @return Whether the user's profile is visible
-	 */
-	boolean isProfileLinkVisibleByUser (final User user);
-
-	/**
-	 * Getter for user instance
-	 * <p>
-	 * @return User instance
-	 */
-	User getUser ();
-
-	/**
-	 * Setter for user instance
-	 * <p>
-	 * @param user User instance
-	 */
-	void setUser (final User user);
-}
diff --git a/src/java/org/mxchange/addressbook/beans/profilemode/ProfileModeWebApplicationBean.java b/src/java/org/mxchange/addressbook/beans/profilemode/ProfileModeWebApplicationBean.java
deleted file mode 100644
index fb45a7b1..00000000
--- a/src/java/org/mxchange/addressbook/beans/profilemode/ProfileModeWebApplicationBean.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.addressbook.beans.profilemode;
-
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Named;
-import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
-
-/**
- * A profile mode bean
- * <p>
- * @author Roland Haeder<roland@mxchange.org>
- */
-@Named ("profileMode")
-@ApplicationScoped
-public class ProfileModeWebApplicationBean implements ProfileModeWebApplicationController {
-
-	/**
-	 * Serial number
-	 */
-	private static final long serialVersionUID = 835_482_364_189L;
-
-	/**
-	 * Default constructor
-	 */
-	public ProfileModeWebApplicationBean () {
-	}
-
-	@Override
-	public ProfileMode[] getAllProfileModes () {
-		// Return it
-		return ProfileMode.values();
-	}
-}
diff --git a/src/java/org/mxchange/addressbook/beans/profilemode/ProfileModeWebApplicationController.java b/src/java/org/mxchange/addressbook/beans/profilemode/ProfileModeWebApplicationController.java
deleted file mode 100644
index 74e512fa..00000000
--- a/src/java/org/mxchange/addressbook/beans/profilemode/ProfileModeWebApplicationController.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.addressbook.beans.profilemode;
-
-import java.io.Serializable;
-import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
-
-/**
- * An interface for data beans
- * <p>
- * @author Roland Haeder<roland@mxchange.org>
- */
-public interface ProfileModeWebApplicationController extends Serializable {
-
-	/**
-	 * Getter for all genders as array
-	 * <p>
-	 * @return All genders as array
-	 */
-	ProfileMode[] getAllProfileModes ();
-}
diff --git a/src/java/org/mxchange/addressbook/beans/register/UserRegisterWebSessionBean.java b/src/java/org/mxchange/addressbook/beans/register/UserRegisterWebSessionBean.java
deleted file mode 100644
index c4ce4892..00000000
--- a/src/java/org/mxchange/addressbook/beans/register/UserRegisterWebSessionBean.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.addressbook.beans.register;
-
-import java.text.MessageFormat;
-import javax.enterprise.context.SessionScoped;
-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 javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import org.mxchange.addressbook.beans.user.UserWebSessionController;
-import org.mxchange.jusercore.events.registration.RegisteredUserEvent;
-import org.mxchange.jusercore.events.registration.UserRegisteredEvent;
-import org.mxchange.jusercore.exceptions.DataRepeatMismatchException;
-import org.mxchange.jusercore.exceptions.EmailAddressAlreadyRegisteredException;
-import org.mxchange.jusercore.exceptions.UserNameAlreadyRegisteredException;
-import org.mxchange.jusercore.model.register.UserRegistrationSessionBeanRemote;
-import org.mxchange.jusercore.model.user.User;
-import org.mxchange.jusercore.model.user.UserUtils;
-import org.mxchange.jusercore.model.user.status.UserAccountStatus;
-
-/**
- * A web bean for user registration
- * <p>
- * @author Roland Haeder
- */
-@Named ("registerController")
-@SessionScoped
-public class UserRegisterWebSessionBean implements UserRegisterWebSessionController {
-
-	/**
-	 * Serial number
-	 */
-	private static final long serialVersionUID = 47_828_986_719_691_592L;
-
-	/**
-	 * Reemote register session bean
-	 */
-	private UserRegistrationSessionBeanRemote registerBean;
-
-	/**
-	 * An en event fireable when a new user has registered
-	 */
-	@Inject
-	@Any
-	private Event<UserRegisteredEvent> registeredEvent;
-
-	/**
-	 * User controller
-	 */
-	@Inject
-	private UserWebSessionController userController;
-
-	/**
-	 * Default constructor
-	 */
-	public UserRegisterWebSessionBean () {
-		try {
-			// Get initial context
-			Context context = new InitialContext();
-
-			// Try to lookup
-			this.registerBean = (UserRegistrationSessionBeanRemote) context.lookup("ejb/stateless-register"); //NOI18N
-		} catch (final NamingException ex) {
-			// Continue to throw
-			throw new FaceletException(ex);
-		}
-	}
-
-	@Override
-	public String doRegister () {
-		// Get user instance
-		User user = this.userController.createUserInstance();
-
-		// Is the user already used?
-		if (null == user) {
-			// user must be set
-			throw new NullPointerException("user is null"); //NOI18N
-		} else if (!this.userController.isRequiredPersonalDataSet()) {
-			// Not all required fields are set
-			throw new FaceletException("Not all required fields are set."); //NOI18N
-		} else if (this.userController.isUserNameRegistered(user)) {
-			// User name is already used
-			throw new FaceletException(new UserNameAlreadyRegisteredException(user));
-		} else if (this.userController.isEmailAddressRegistered(user)) {
-			// Email address has already been taken
-			throw new FaceletException(new EmailAddressAlreadyRegisteredException(user));
-		} else if (!this.userController.isSameEmailAddressEntered()) {
-			// Not same email address entered
-			throw new FaceletException(new DataRepeatMismatchException(MessageFormat.format("Email addresses not matching: {0} != {1}", this.userController.getEmailAddress(), this.userController.getEmailAddressRepeat()))); //NOI18N
-		} else if (!this.userController.isSamePasswordEntered()) {
-			// Not same password entered
-			throw new FaceletException(new DataRepeatMismatchException("Passwords not matching.")); //NOI18N
-		}
-
-		// Encrypt password
-		String encryptedPassword = UserUtils.encryptPassword(this.userController.getUserPassword());
-
-		// Set it here
-		user.setUserEncryptedPassword(encryptedPassword);
-
-		// For debugging/programming only:
-		user.setUserAccountStatus(UserAccountStatus.CONFIRMED);
-
-		try {
-			// Call bean
-			User registeredUser = this.registerBean.registerUser(user);
-
-			// Fire event
-			this.registeredEvent.fire(new RegisteredUserEvent(registeredUser));
-
-			// All fine, redirect to proper page
-			return "register_done"; //NOI18N
-		} catch (final UserNameAlreadyRegisteredException | EmailAddressAlreadyRegisteredException ex) {
-			// Continue to throw
-			throw new FaceletException(ex);
-		}
-	}
-}
diff --git a/src/java/org/mxchange/addressbook/beans/register/UserRegisterWebSessionController.java b/src/java/org/mxchange/addressbook/beans/register/UserRegisterWebSessionController.java
deleted file mode 100644
index 6a9923b9..00000000
--- a/src/java/org/mxchange/addressbook/beans/register/UserRegisterWebSessionController.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.addressbook.beans.register;
-
-import java.io.Serializable;
-
-/**
- * An interface for registration web controllers
- * <p>
- * @author Roland Haeder
- */
-public interface UserRegisterWebSessionController extends Serializable {
-
-	/**
-	 * Registers the user, if not found. Otherwise this method should throw an
-	 * exception.
-	 * <p>
-	 * @return Redirection target
-	 */
-	String doRegister ();
-}
diff --git a/src/java/org/mxchange/addressbook/beans/shares/SharesWebSessionBean.java b/src/java/org/mxchange/addressbook/beans/shares/SharesWebSessionBean.java
deleted file mode 100644
index 988b25ca..00000000
--- a/src/java/org/mxchange/addressbook/beans/shares/SharesWebSessionBean.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.addressbook.beans.shares;
-
-import java.text.MessageFormat;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-import javax.annotation.PostConstruct;
-import javax.enterprise.context.SessionScoped;
-import javax.enterprise.event.Event;
-import javax.enterprise.event.Observes;
-import javax.enterprise.inject.Any;
-import javax.faces.view.facelets.FaceletException;
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import org.mxchange.addressbook.beans.login.UserLoginWebSessionController;
-import org.mxchange.addressbook.events.sharing.AddressbookSharingEvent;
-import org.mxchange.addressbook.events.sharing.StartedAddressbookSharingEvent;
-import org.mxchange.addressbook.events.sharing.type.SharingType;
-import org.mxchange.addressbook.exceptions.UserAlreadySharingAddressbookException;
-import org.mxchange.addressbook.model.addressbook.Addressbook;
-import org.mxchange.addressbook.model.addressbook.shared.ShareableAddressbook;
-import org.mxchange.addressbook.model.shared.SharedAddressbooksSessionBeanRemote;
-import org.mxchange.jusercore.events.login.UserLoggedInEvent;
-import org.mxchange.jusercore.model.user.User;
-import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
-
-/**
- * A bean for sharing address books with other users
- * <p>
- * @author Roland Haeder
- */
-@Named (value = "shareController")
-@SessionScoped
-public class SharesWebSessionBean implements SharesWebSessionController {
-
-	/**
-	 * Serial number
-	 */
-	private static final long serialVersionUID = 19_868_976_871_976_780L;
-
-	/**
-	 * Cached flag whether the user is sharing address books
-	 */
-	private Boolean isUserSharing = null;
-
-	/**
-	 * Login controller injection
-	 */
-	@Inject
-	private UserLoginWebSessionController loginController;
-
-	/**
-	 * Share instance
-	 */
-	private ShareableAddressbook share;
-
-	/**
-	 * Remote bean for sharing address books
-	 */
-	private SharedAddressbooksSessionBeanRemote shareBean;
-
-	/**
-	 * A list of all user's shared (with others) address books
-	 */
-	private List<ShareableAddressbook> sharedAddressbooks;
-
-	/**
-	 * User id of sharee
-	 */
-	private Long shareeUserId;
-
-	/**
-	 * An event triggered when address book sharing starts or ends
-	 */
-	@Inject
-	@Any
-	private Event<AddressbookSharingEvent> sharingEvent;
-
-	/**
-	 * Default constructor
-	 */
-	public SharesWebSessionBean () {
-		// Try it
-		try {
-			// Get initial context
-			Context context = new InitialContext();
-
-			// Look up bean
-			this.shareBean = (SharedAddressbooksSessionBeanRemote) context.lookup("ejb/stateless-share"); //NOI18N
-		} catch (final NamingException ex) {
-			// Continue to throw
-			throw new FaceletException(ex);
-		}
-	}
-
-	@Override
-	public void afterAdressbookShareEnded (final @Observes AddressbookSharingEvent event) {
-		// Validate parameter
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getSharingType() == null) {
-			// Throw NPE
-			throw new NullPointerException("event.sharingType is null"); //NOI18N
-		} else if (event.getSharingType() != SharingType.ENDED) {
-			// Wrong event
-			return;
-		}
-
-		// Validate event
-		this.validateEvent(event);
-
-		// Add it to list
-		this.sharedAddressbooks.remove(event.getShareableAddressbook());
-	}
-
-	@Override
-	public void afterAdressbookShareStarted (final @Observes AddressbookSharingEvent event) {
-		// Validate parameter
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getSharingType() == null) {
-			// Throw NPE
-			throw new NullPointerException("event.sharingType is null"); //NOI18N
-		} else if (event.getSharingType() != SharingType.STARTED) {
-			// Wrong event
-			return;
-		}
-
-		// Validate event
-		this.validateEvent(event);
-
-		// Add it to list
-		this.sharedAddressbooks.add(event.getShareableAddressbook());
-	}
-
-	@Override
-	public void afterLoginEvent (final @Observes UserLoggedInEvent event) {
-		// Is the user logged in?
-		if (null == event) {
-			// Is null
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getUser() == null) {
-			// user is null
-			throw new NullPointerException("event.user is null"); //NOI18N
-		}
-
-		// Init share list
-		this.sharedAddressbooks = this.shareBean.allSharedAddressbooks(event.getUser());
-	}
-
-	@Override
-	public List<ShareableAddressbook> allShares () {
-		// Is the user logged in?
-		if (!this.loginController.isUserLoggedIn()) {
-			// Not logged in
-			throw new FaceletException("This method can only be called as logged-in user."); //NOI18N
-		}
-
-		return Collections.unmodifiableList(this.sharedAddressbooks);
-	}
-
-	@Override
-	public ShareableAddressbook getShare () {
-		return this.share;
-	}
-
-	@Override
-	public void setShare (final ShareableAddressbook share) {
-		this.share = share;
-	}
-
-	@Override
-	public Long getShareeUserId () {
-		return this.shareeUserId;
-	}
-
-	@Override
-	public void setShareeUserId (final Long shareeUserId) {
-		this.shareeUserId = shareeUserId;
-	}
-
-	@PostConstruct
-	public void init () {
-		// Check conditions
-		if (!this.loginController.isUserLoggedIn()) {
-			// No, then throw exception
-			throw new FaceletException("This method can only be called as logged-in user."); //NOI18N
-		}
-
-		// Init share list
-		this.sharedAddressbooks = this.shareBean.allSharedAddressbooks(this.loginController.getLoggedInUser());
-	}
-
-	@Override
-	public boolean isShareeUserIdEmpty () {
-		return (!this.isShareeUserIdSet());
-	}
-
-	@Override
-	public boolean isShareeUserIdSet () {
-		return ((this.getShareeUserId() instanceof Long) && (this.getShareeUserId() > 0));
-	}
-
-	@Override
-	public boolean isSharingAddressbooks () {
-		// Only to be called for logged-in users
-		if (!this.loginController.isUserLoggedIn()) {
-			// Not logged in
-			throw new FaceletException("This method can only be called as logged-in user."); //NOI18N
-		} else if (this.isUserSharing instanceof Boolean) {
-			// Return cached value
-			return this.isUserSharing;
-		}
-
-		// Call the proper bean
-		this.isUserSharing = this.shareBean.isUserSharingAddressbooks(this.loginController.getLoggedInUser());
-
-		// Return it
-		return this.isUserSharing;
-	}
-
-	@Override
-	public String startSharing (final User user, final Addressbook addressbook) {
-		// Check conditions
-		if (!this.loginController.isUserLoggedIn()) {
-			// No, then throw exception
-			throw new FaceletException("This method can only be called as logged-in user."); //NOI18N
-		} else if (null == user) {
-			// Throw NPE
-			throw new NullPointerException("user is null"); //NOI18N
-		} else if (user.getUserId() == null) {
-			// Throw NPE again
-			throw new NullPointerException("user.userId is null"); //NOI18N
-		} else if (user.getUserId() < 1) {
-			// Invalid id number
-			throw new IllegalStateException(MessageFormat.format("user.userId={0} is invalid", user.getUserId())); //NOI18N
-		} else if (Objects.equals(user, this.loginController.getLoggedInUser())) {
-			// Sharing with yourself!
-			throw new IllegalStateException("User tries to share with himself."); //NOI18N
-		} else if (null == addressbook) {
-			// Throw NPE again
-			throw new NullPointerException("addressbook is null"); //NOI18N
-		} else if (addressbook.getAddressbookId() == null) {
-			// Throw NPE again
-			throw new NullPointerException("addressbook.addressbookId is null"); //NOI18N
-		} else if (addressbook.getAddressbookId() < 1) {
-			// Invalid id number
-			throw new IllegalArgumentException(MessageFormat.format("addressbook.addressbookId={0} is invalid.", addressbook.getAddressbookId())); //NOI18N
-		} else if (!Objects.equals(addressbook.getAddressbookUser(), this.loginController.getLoggedInUser())) {
-			// Not the same user!
-			throw new IllegalStateException(MessageFormat.format("Address book id {0} owner id {1} mismatching logged-in user id {2}", addressbook.getAddressbookId(), addressbook.getAddressbookUser().getUserId(), this.loginController.getLoggedInUser().getUserId())); //NOI18N
-		} else if (this.loginController.getLoggedInUser().getUserProfileMode() == ProfileMode.INVISIBLE) {
-			// User is invisible
-			throw new FaceletException(MessageFormat.format("user {0} is invisible and cannot start sharing address books.", this.loginController.getLoggedInUser().getUserId())); //NOI18N
-		} else if (user.getUserProfileMode() == ProfileMode.INVISIBLE) {
-			// User is invisible
-			throw new FaceletException(MessageFormat.format("user {0} is invisible and cannot be selected for sharing.", user.getUserId())); //NOI18N
-		}
-
-		try {
-			// Init sharing
-			ShareableAddressbook shared = this.shareBean.startSharing(user, addressbook);
-
-			// TODO Set it here
-			this.setShare(shared);
-
-			/// Trigger event
-			this.sharingEvent.fire(new StartedAddressbookSharingEvent(shared));
-		} catch (final UserAlreadySharingAddressbookException ex) {
-			// Throw again
-			throw new FaceletException(ex);
-		}
-
-		// TODO Unfinished
-		return null;
-	}
-
-	/**
-	 * Validates given event for all values and throws exceptions
-	 * <p>
-	 * @param event Event to validate
-	 */
-	private void validateEvent (final AddressbookSharingEvent event) {
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getSharingType() == null) {
-			// Throw NPE
-			throw new NullPointerException("event.sharingType is null"); //NOI18N
-		} else if (event.getShareableAddressbook() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.shareableAddressbook is null"); //NOI18N
-		} else if (event.getShareableAddressbook().getShareId() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.shareableAddressbook.shareId is null"); //NOI18N
-		} else if (event.getShareableAddressbook().getShareId() < 1) {
-			// Throw NPE again
-			throw new IllegalArgumentException(MessageFormat.format("event.shareableAddressbook.shareId={0} is invalid", event.getShareableAddressbook().getShareId())); //NOI18N
-		} else if (event.getShareableAddressbook().getShareAddressbook() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.shareableAddressbook.shareAddressbook is null"); //NOI18N
-		} else if (event.getShareableAddressbook().getShareAddressbook().getAddressbookId() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.shareableAddressbook.shareAddressbook.addressbookId is null"); //NOI18N
-		} else if (event.getShareableAddressbook().getShareAddressbook().getAddressbookId() < 1) {
-			// Throw NPE again
-			throw new IllegalArgumentException(MessageFormat.format("event.shareableAddressbook.shareAddressbook.addressbookId={0} is invalid", event.getShareableAddressbook().getShareAddressbook().getAddressbookId())); //NOI18N
-		} else if (event.getShareableAddressbook().getShareUserOwner() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.shareableAddressbook.shareUserOwner is null"); //NOI18N
-		} else if (event.getShareableAddressbook().getShareUserOwner().getUserId() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.shareableAddressbook.shareUserOwner.userId is null"); //NOI18N
-		} else if (event.getShareableAddressbook().getShareUserOwner().getUserId() < 1) {
-			// Throw NPE again
-			throw new IllegalArgumentException(MessageFormat.format("event.shareableAddressbook.shareUserOwner.userId={0} is invalid", event.getShareableAddressbook().getShareUserOwner().getUserId())); //NOI18N
-		} else if (event.getShareableAddressbook().getShareUserSharee() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.shareableAddressbook.shareUserSharee is null"); //NOI18N
-		} else if (event.getShareableAddressbook().getShareUserSharee().getUserId() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.shareableAddressbook.shareUserSharee.userId is null"); //NOI18N
-		} else if (event.getShareableAddressbook().getShareUserSharee().getUserId() < 1) {
-			// Throw NPE again
-			throw new IllegalArgumentException(MessageFormat.format("event.shareableAddressbook.shareUserSharee.userId={0} is invalid", event.getShareableAddressbook().getShareUserOwner().getUserId())); //NOI18N
-		}
-	}
-}
diff --git a/src/java/org/mxchange/addressbook/beans/shares/SharesWebSessionController.java b/src/java/org/mxchange/addressbook/beans/shares/SharesWebSessionController.java
deleted file mode 100644
index d2a96f5c..00000000
--- a/src/java/org/mxchange/addressbook/beans/shares/SharesWebSessionController.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.addressbook.beans.shares;
-
-import java.io.Serializable;
-import java.util.List;
-import org.mxchange.addressbook.events.sharing.AddressbookSharingEvent;
-import org.mxchange.addressbook.model.addressbook.Addressbook;
-import org.mxchange.addressbook.model.addressbook.shared.ShareableAddressbook;
-import org.mxchange.jusercore.events.login.UserLoggedInEvent;
-import org.mxchange.jusercore.model.user.User;
-
-/**
- * Controller interface sharing address books
- * <p>
- * @author Roland Haeder
- */
-public interface SharesWebSessionController extends Serializable {
-
-	/**
-	 * Observer method for ended sharing events
-	 * <p>
-	 * @param event Event instance
-	 */
-	void afterAdressbookShareEnded (final AddressbookSharingEvent event);
-
-	/**
-	 * Observer method for started sharing events
-	 * <p>
-	 * @param event Event instance
-	 */
-	void afterAdressbookShareStarted (final AddressbookSharingEvent event);
-
-	/**
-	 * This method is called when a user has successfully logged in his/her
-	 * account.
-	 * <p>
-	 * @param event
-	 */
-	void afterLoginEvent (final UserLoggedInEvent event);
-
-	/**
-	 * Returns a list of all address books the user is sharing with others.
-	 * <p>
-	 * @return List of all shared address books
-	 */
-	List<ShareableAddressbook> allShares ();
-
-	/**
-	 * Getter for share instance
-	 * <p>
-	 * @return Share instance
-	 */
-	ShareableAddressbook getShare ();
-
-	/**
-	 * Setter for share instance
-	 * <p>
-	 * @param share Share instance
-	 */
-	void setShare (final ShareableAddressbook share);
-
-	/**
-	 * Getter for sharee's user id
-	 * <p>
-	 * @return Sharee's user id
-	 */
-	Long getShareeUserId ();
-
-	/**
-	 * Setter for sharee's user id
-	 * <p>
-	 * @param shareeUserId Sharee's user id
-	 */
-	void setShareeUserId (final Long shareeUserId);
-
-	/**
-	 * Checks if the sharee's user id is empty.
-	 * <p>
-	 * @return Whether the sharee's user id is empty.
-	 */
-	boolean isShareeUserIdEmpty ();
-
-	/**
-	 * Checks whether the sharee's user id is set
-	 * <p>
-	 * @return Whether the sharee's user id is set
-	 */
-	boolean isShareeUserIdSet ();
-
-	/**
-	 * Checks wether the current user is sharing address books with others
-	 * <p>
-	 * @return Whether the current user is sharing address books
-	 */
-	boolean isSharingAddressbooks ();
-
-	/**
-	 * Starts an address book share between currently logged-in user and
-	 * assigned user for current address book.
-	 * <p>
-	 * @param user User instance
-	 * @param addressbook Address book instance
-	 * @return Redirect target
-	 */
-	String startSharing (final User user, final Addressbook addressbook);
-}
diff --git a/src/java/org/mxchange/addressbook/beans/smsprovider/SmsProviderWebApplicationBean.java b/src/java/org/mxchange/addressbook/beans/smsprovider/SmsProviderWebApplicationBean.java
deleted file mode 100644
index aa64620c..00000000
--- a/src/java/org/mxchange/addressbook/beans/smsprovider/SmsProviderWebApplicationBean.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package org.mxchange.addressbook.beans.smsprovider;
-
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify it under
- * the terms of the GNU 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 General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-import java.util.Collections;
-import java.util.List;
-import javax.annotation.PostConstruct;
-import javax.enterprise.context.ApplicationScoped;
-import javax.faces.view.facelets.FaceletException;
-import javax.inject.Named;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import org.mxchange.jphone.phonenumbers.smsprovider.AddressbookSmsProviderSingletonBeanRemote;
-import org.mxchange.jphone.phonenumbers.smsprovider.SmsProvider;
-
-/**
- * A SMS provider bean
- * <p>
- * @author Roland Haeder<roland@mxchange.org>
- */
-@Named ("cellphone")
-@ApplicationScoped
-public class SmsProviderWebApplicationBean implements SmsProviderWebApplicationController {
-
-	/**
-	 * Serial number
-	 */
-	private static final long serialVersionUID = 176_985_298_681_742_960L;
-
-	/**
-	 * Remote country EJB
-	 */
-	private AddressbookSmsProviderSingletonBeanRemote cellphoneBean;
-
-	/**
-	 * List of all countries
-	 */
-	private List<SmsProvider> cellphoneList;
-
-	/**
-	 * Default constructor
-	 */
-	public SmsProviderWebApplicationBean () {
-		// Try this
-		try {
-			// Get initial context
-			Context context = new InitialContext();
-
-			// Try to lookup the bean
-			this.cellphoneBean = (AddressbookSmsProviderSingletonBeanRemote) context.lookup("ejb/addressbook-singleton-smsprovider"); //NOI18N
-		} catch (final NamingException ex) {
-			// Continue to throw
-			throw new FaceletException(ex);
-		}
-	}
-
-	@Override
-	public List<SmsProvider> allSmsProvider () {
-		// Return "cached" version
-		return Collections.unmodifiableList(this.cellphoneList);
-	}
-
-	@PostConstruct
-	public void init () {
-		this.cellphoneList = this.cellphoneBean.allSmsProvider();
-	}
-}
diff --git a/src/java/org/mxchange/addressbook/beans/smsprovider/SmsProviderWebApplicationController.java b/src/java/org/mxchange/addressbook/beans/smsprovider/SmsProviderWebApplicationController.java
deleted file mode 100644
index 917ddcbd..00000000
--- a/src/java/org/mxchange/addressbook/beans/smsprovider/SmsProviderWebApplicationController.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.mxchange.addressbook.beans.smsprovider;
-
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify it under
- * the terms of the GNU 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 General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-import java.io.Serializable;
-import java.util.List;
-import org.mxchange.jphone.phonenumbers.smsprovider.SmsProvider;
-
-/**
- * An interface for country beans
- * <p>
- * @author Roland Haeder<roland@mxchange.org>
- */
-public interface SmsProviderWebApplicationController extends Serializable {
-
-	/**
-	 * A list of all countries
-	 * <p>
-	 * @return All countries
-	 */
-	List<SmsProvider> allSmsProvider ();
-}
diff --git a/src/java/org/mxchange/addressbook/beans/user/UserWebSessionBean.java b/src/java/org/mxchange/addressbook/beans/user/UserWebSessionBean.java
deleted file mode 100644
index cc31bdc1..00000000
--- a/src/java/org/mxchange/addressbook/beans/user/UserWebSessionBean.java
+++ /dev/null
@@ -1,866 +0,0 @@
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.addressbook.beans.user;
-
-import java.text.MessageFormat;
-import java.util.Collections;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Objects;
-import javax.annotation.PostConstruct;
-import javax.enterprise.context.SessionScoped;
-import javax.enterprise.event.Observes;
-import javax.faces.view.facelets.FaceletException;
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import org.mxchange.addressbook.beans.login.UserLoginWebSessionController;
-import org.mxchange.jcontacts.contact.Contact;
-import org.mxchange.jcontacts.contact.UserContact;
-import org.mxchange.jcontacts.contact.gender.Gender;
-import org.mxchange.jcountry.data.Country;
-import org.mxchange.jphone.phonenumbers.cellphone.CellphoneNumber;
-import org.mxchange.jphone.phonenumbers.cellphone.DialableCellphoneNumber;
-import org.mxchange.jphone.phonenumbers.fax.DialableFaxNumber;
-import org.mxchange.jphone.phonenumbers.fax.FaxNumber;
-import org.mxchange.jphone.phonenumbers.landline.DialableLandLineNumber;
-import org.mxchange.jphone.phonenumbers.landline.LandLineNumber;
-import org.mxchange.jphone.phonenumbers.smsprovider.SmsProvider;
-import org.mxchange.jusercore.events.login.UserLoggedInEvent;
-import org.mxchange.jusercore.events.registration.UserRegisteredEvent;
-import org.mxchange.jusercore.exceptions.UserNotFoundException;
-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;
-
-/**
- * A user bean (controller)
- * <p>
- * @author Roland Haeder<roland@mxchange.org>
- */
-@Named ("userController")
-@SessionScoped
-public class UserWebSessionBean implements UserWebSessionController {
-
-	/**
-	 * Serial number
-	 */
-	private static final long serialVersionUID = 542_145_347_916L;
-
-	/////////////////////// Properties /////////////////////
-	/**
-	 * Birth day
-	 */
-	private Date birthday;
-
-	/**
-	 * Cellphone number's carrier
-	 */
-	private SmsProvider cellphoneCarrier;
-
-	/**
-	 * Cellphone number
-	 */
-	private Long cellphoneNumber;
-
-	/**
-	 * City
-	 */
-	private String city;
-
-	/**
-	 * Optional comments
-	 */
-	private String comment;
-
-	/**
-	 * Country instance
-	 */
-	private Country country;
-
-	/**
-	 * Email address
-	 */
-	private String emailAddress;
-
-	/**
-	 * Email address list
-	 */
-	private List<String> emailAddressList;
-
-	/**
-	 * Email address repeated
-	 */
-	private String emailAddressRepeat;
-
-	/**
-	 * Family name
-	 */
-	private String familyName;
-
-	/**
-	 * Fax number's area code
-	 */
-	private Integer faxAreaCode;
-
-	/**
-	 * Country instance for fax number
-	 */
-	private Country faxCountry;
-
-	/**
-	 * Fax number
-	 */
-	private Long faxNumber;
-
-	/**
-	 * First name
-	 */
-	private String firstName;
-
-	/**
-	 * Gender instance
-	 */
-	private Gender gender;
-
-	/**
-	 * House number
-	 */
-	private Short houseNumber;
-
-	/**
-	 * Phone number area code
-	 */
-	private Integer phoneAreaCode;
-
-	/**
-	 * Country instance for phone number
-	 */
-	private Country phoneCountry;
-
-	/**
-	 * Phone number
-	 */
-	private Long phoneNumber;
-
-	/**
-	 * Street
-	 */
-	private String street;
-
-	/**
-	 * Remote user bean
-	 */
-	private final UserSessionBeanRemote userBean;
-
-	/**
-	 * User id
-	 */
-	private Long userId;
-
-	/**
-	 * User name
-	 */
-	private String userName;
-
-	/**
-	 * User name list
-	 */
-	private List<String> userNameList;
-
-	/**
-	 * User password (unencrypted from web form)
-	 */
-	private String userPassword;
-
-	/**
-	 * User password repeated (unencrypted from web form)
-	 */
-	private String userPasswordRepeat;
-
-	/**
-	 * Whether the user wants a public profile
-	 */
-	private ProfileMode userProfileMode;
-
-	/**
-	 * ZIP code
-	 */
-	private Integer zipCode;
-
-	/**
-	 * A list of all public user profiles
-	 */
-	private List<User> visibleUserList;
-
-	/**
-	 * Login bean (controller)
-	 */
-	@Inject
-	private UserLoginWebSessionController loginController;
-
-	/**
-	 * Default constructor
-	 */
-	public UserWebSessionBean () {
-		// Set gender to UNKNOWN
-		this.gender = Gender.UNKNOWN;
-
-		// Try it
-		try {
-			// Get initial context
-			Context context = new InitialContext();
-
-			// Try to lookup
-			this.userBean = (UserSessionBeanRemote) context.lookup("ejb/stateless-user"); //NOI18N
-		} catch (final NamingException e) {
-			// Throw again
-			throw new FaceletException(e);
-		}
-	}
-
-	@Override
-	public void afterUserLogin (final @Observes UserLoggedInEvent event) {
-		// Trace message
-		System.out.println(MessageFormat.format("UserWebBean:afterUserLogin: event={0} - CALLED!", event)); //NOI18N
-
-		// event should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getUser() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.user is null"); //NOI18N
-		} else if (event.getUser().getUserId() == null) {
-			// userId is null
-			throw new NullPointerException("event.user.userId is null"); //NOI18N
-		} else if (event.getUser().getUserId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUser(), event.getUser().getUserId())); //NOI18N
-		}
-
-		// Re-initialize list
-		this.visibleUserList = this.userBean.allMemberPublicVisibleUsers();
-
-		// Trace message
-		System.out.println(MessageFormat.format("UserWebBean:afterUserLogin: this.visibleUserList.size()={0} - EXIT!", this.visibleUserList.size())); //NOI18N
-	}
-
-	@Override
-	public void afterRegistrationEvent (final @Observes UserRegisteredEvent event) {
-		// Trace message
-		System.out.println(MessageFormat.format("UserWebBean:afterRegistration: event={0} - CALLED!", event)); //NOI18N
-
-		// event should not be null
-		if (null == event) {
-			// Throw NPE
-			throw new NullPointerException("event is null"); //NOI18N
-		} else if (event.getUser() == null) {
-			// Throw NPE again
-			throw new NullPointerException("event.user is null"); //NOI18N
-		} else if (event.getUser().getUserId() == null) {
-			// userId is null
-			throw new NullPointerException("event.user.userId is null"); //NOI18N
-		} else if (event.getUser().getUserId() < 1) {
-			// Not avalid id
-			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUser(), event.getUser().getUserId())); //NOI18N
-		}
-
-		// Get user instance
-		User registeredUser = event.getUser();
-
-		// Debug message
-		System.out.println(MessageFormat.format("UserWebBean:afterRegistration: registeredUser={0}", registeredUser)); //NOI18N
-
-		// Copy all data from registered->user
-		this.copyUser(registeredUser);
-
-		// Add user name and email address
-		this.addUserNameEmailAddress(registeredUser);
-
-		// Clear all data
-		this.clearData();
-
-		// Set user id again
-		this.setUserId(registeredUser.getUserId());
-
-		// Is the account public?
-		if (registeredUser.getUserProfileMode().equals(ProfileMode.PUBLIC)) {
-			// Also add it to this list
-			this.visibleUserList.add(registeredUser);
-		}
-
-		// Trace message
-		System.out.println("UserWebBean:afterRegistration: EXIT!"); //NOI18N
-	}
-
-	@Override
-	public List<User> allVisibleUsers () {
-		// Return it
-		return Collections.unmodifiableList(this.visibleUserList);
-	}
-
-	@Override
-	public User createUserInstance () {
-		// User message
-		//this.getLogger().logTrace("createUserInstance: CALLED!");
-
-		// Required personal data must be set
-		assert (this.isRequiredPersonalDataSet()) : "not all personal data is set"; //NOI18N
-
-		// Create new user instance
-		User user = new LoginUser();
-		user.setUserName(this.getUserName());
-		user.setUserProfileMode(this.getUserProfileMode());
-		user.setUserCreated(new GregorianCalendar());
-
-		// Generate phone number
-		DialableLandLineNumber phone = new LandLineNumber(this.getPhoneCountry(), this.getPhoneAreaCode(), this.getPhoneNumber(), new GregorianCalendar());
-		DialableCellphoneNumber cellphone = new CellphoneNumber(this.getCellphoneCarrier(), this.getCellphoneNumber(), new GregorianCalendar());
-		DialableFaxNumber fax = new FaxNumber(this.getFaxCountry(), this.getFaxAreaCode(), this.getFaxNumber(), new GregorianCalendar());
-
-		// Create new contact
-		Contact contact = new UserContact(this.getGender(), this.getFirstName(), this.getFamilyName());
-		contact.setContactStreet(this.getStreet());
-		contact.setContactHouseNumber(this.getHouseNumber());
-		contact.setContactZipCode(this.getZipCode());
-		contact.setContactCity(this.getCity());
-		contact.setContactCountry(this.getCountry());
-		contact.setContactEmailAddress(this.getEmailAddress());
-
-		// Don't set null or wrong references
-		if ((phone instanceof DialableLandLineNumber) && (phone.getPhoneCountry() instanceof Country) && (this.getPhoneAreaCode() != null) && (this.getPhoneNumber() != null) && (this.getPhoneAreaCode() > 0) && (this.getPhoneNumber() > 0)) {
-			// Now the number must be given
-			if (phone.getPhoneAreaCode() == null) {
-				// Is null
-				throw new NullPointerException("phone.phoneAreaCode is null"); //NOI18N
-			} else if (phone.getPhoneAreaCode() < 1) {
-				// Abort here
-				throw new IllegalArgumentException("phone.phoneAreaCode is zero or below."); //NOI18N
-			} else if (phone.getPhoneNumber() == null) {
-				// Is null
-				throw new NullPointerException("phone.phoneNumber is null"); //NOI18N
-			} else if (phone.getPhoneNumber() < 1) {
-				// Abort here
-				throw new IllegalArgumentException("phone.phoneNumber is zero or below."); //NOI18N
-			}
-
-			// Set phone number
-			contact.setContactPhoneNumber(phone);
-		}
-
-		// 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 ((cellphone instanceof DialableCellphoneNumber) && (this.getCellphoneCarrier() instanceof SmsProvider) && (this.getCellphoneNumber() != null) && (this.getCellphoneNumber() > 0)) {
-			// Is the number set?
-			if (cellphone.getPhoneNumber() == null) {
-				// Is null
-				throw new NullPointerException("cellphone.phoneNumber is null"); //NOI18N
-			} else if (cellphone.getPhoneNumber() < 1) {
-				// Abort here
-				throw new IllegalArgumentException("cellphone.phoneNumber is zero or below."); //NOI18N
-			}
-
-			// Set cellphone number
-			contact.setContactCellphoneNumber(cellphone);
-		}
-
-		contact.setContactBirthday(this.getBirthday());
-		contact.setContactComment(this.getComment());
-
-		// Created timestamp and ownContact
-		contact.setContactCreated(new GregorianCalendar());
-		contact.setContactOwnContact(Boolean.TRUE);
-
-		// Set contact in user
-		user.setUserContact(contact);
-
-		// Trace message
-		//this.getLogger().logTrace(MessageFormat.format("createUserInstance: user={0} - EXIT!", user));
-		// Return it
-		return user;
-	}
-
-	@Override
-	public Date getBirthday () {
-		return this.birthday;
-	}
-
-	@Override
-	public void setBirthday (final Date birthday) {
-		this.birthday = birthday;
-	}
-
-	@Override
-	public SmsProvider getCellphoneCarrier () {
-		return this.cellphoneCarrier;
-	}
-
-	@Override
-	public void setCellphoneCarrier (final SmsProvider cellphoneCarrier) {
-		this.cellphoneCarrier = cellphoneCarrier;
-	}
-
-	@Override
-	public Long getCellphoneNumber () {
-		return this.cellphoneNumber;
-	}
-
-	@Override
-	public void setCellphoneNumber (Long cellphoneNumber) {
-		this.cellphoneNumber = cellphoneNumber;
-	}
-
-	@Override
-	public String getCity () {
-		return this.city;
-	}
-
-	@Override
-	public void setCity (final String city) {
-		this.city = city;
-	}
-
-	@Override
-	public String getComment () {
-		return this.comment;
-	}
-
-	@Override
-	public void setComment (final String comment) {
-		this.comment = comment;
-	}
-
-	@Override
-	public Country getCountry () {
-		return this.country;
-	}
-
-	@Override
-	public void setCountry (final Country country) {
-		this.country = country;
-	}
-
-	@Override
-	public String getEmailAddress () {
-		return this.emailAddress;
-	}
-
-	@Override
-	public void setEmailAddress (final String emailAddress) {
-		this.emailAddress = emailAddress;
-	}
-
-	@Override
-	public String getEmailAddressRepeat () {
-		return this.emailAddressRepeat;
-	}
-
-	@Override
-	public void setEmailAddressRepeat (final String emailAddressRepeat) {
-		this.emailAddressRepeat = emailAddressRepeat;
-	}
-
-	@Override
-	public String getFamilyName () {
-		return this.familyName;
-	}
-
-	@Override
-	public void setFamilyName (final String familyName) {
-		this.familyName = familyName;
-	}
-
-	@Override
-	public Integer getFaxAreaCode () {
-		return this.faxAreaCode;
-	}
-
-	@Override
-	public void setFaxAreaCode (final Integer faxAreaCode) {
-		this.faxAreaCode = faxAreaCode;
-	}
-
-	@Override
-	public Country getFaxCountry () {
-		return this.faxCountry;
-	}
-
-	@Override
-	public void setFaxCountry (final Country faxCountry) {
-		this.faxCountry = faxCountry;
-	}
-
-	@Override
-	public Long getFaxNumber () {
-		return this.faxNumber;
-	}
-
-	@Override
-	public void setFaxNumber (final Long faxNumber) {
-		this.faxNumber = faxNumber;
-	}
-
-	@Override
-	public String getFirstName () {
-		return this.firstName;
-	}
-
-	@Override
-	public void setFirstName (final String firstName) {
-		this.firstName = firstName;
-	}
-
-	@Override
-	public Gender getGender () {
-		return this.gender;
-	}
-
-	@Override
-	public void setGender (final Gender gender) {
-		this.gender = gender;
-	}
-
-	@Override
-	public Short getHouseNumber () {
-		return this.houseNumber;
-	}
-
-	@Override
-	public void setHouseNumber (final Short houseNumber) {
-		this.houseNumber = houseNumber;
-	}
-
-	@Override
-	public Integer getPhoneAreaCode () {
-		return this.phoneAreaCode;
-	}
-
-	@Override
-	public void setPhoneAreaCode (final Integer phoneAreaCode) {
-		this.phoneAreaCode = phoneAreaCode;
-	}
-
-	@Override
-	public Country getPhoneCountry () {
-		return this.phoneCountry;
-	}
-
-	@Override
-	public void setPhoneCountry (final Country phoneCountry) {
-		this.phoneCountry = phoneCountry;
-	}
-
-	@Override
-	public Long getPhoneNumber () {
-		return this.phoneNumber;
-	}
-
-	@Override
-	public void setPhoneNumber (final Long phoneNumber) {
-		this.phoneNumber = phoneNumber;
-	}
-
-	@Override
-	public String getStreet () {
-		return this.street;
-	}
-
-	@Override
-	public void setStreet (final String street) {
-		this.street = street;
-	}
-
-	@Override
-	public Long getUserId () {
-		return this.userId;
-	}
-
-	@Override
-	public void setUserId (final Long userId) {
-		this.userId = userId;
-	}
-
-	@Override
-	public String getUserName () {
-		return this.userName;
-	}
-
-	@Override
-	public void setUserName (final String userName) {
-		this.userName = userName;
-	}
-
-	@Override
-	public String getUserPassword () {
-		return this.userPassword;
-	}
-
-	@Override
-	public void setUserPassword (final String userPassword) {
-		this.userPassword = userPassword;
-	}
-
-	@Override
-	public String getUserPasswordRepeat () {
-		return this.userPasswordRepeat;
-	}
-
-	@Override
-	public void setUserPasswordRepeat (final String userPasswordRepeat) {
-		this.userPasswordRepeat = userPasswordRepeat;
-	}
-
-	@Override
-	public ProfileMode getUserProfileMode () {
-		return this.userProfileMode;
-	}
-
-	@Override
-	public void setUserProfileMode (final ProfileMode userProfileMode) {
-		this.userProfileMode = userProfileMode;
-	}
-
-	@Override
-	public Integer getZipCode () {
-		return this.zipCode;
-	}
-
-	@Override
-	public void setZipCode (final Integer zipCode) {
-		this.zipCode = zipCode;
-	}
-
-	@PostConstruct
-	public void init () {
-		// Get full user name list for reducing EJB calls
-		this.userNameList = this.userBean.getUserNameList();
-
-		// Get full email address list for reducing EJB calls
-		this.emailAddressList = this.userBean.getEmailAddressList();
-
-		// Is the user logged-in?
-		if (this.loginController.isUserLoggedIn()) {
-			// Is logged-in, so load also users visible to memebers
-			this.visibleUserList = this.userBean.allMemberPublicVisibleUsers();
-		} else {
-			// Initialize user list
-			this.visibleUserList = this.userBean.allPublicUsers();
-		}
-	}
-
-	@Override
-	public boolean isEmailAddressRegistered (final User user) {
-		return ((this.emailAddressList instanceof List) && (this.emailAddressList.contains(user.getUserContact().getContactEmailAddress())));
-	}
-
-	@Override
-	public boolean isRequiredPersonalDataSet () {
-		return ((this.getUserName() != null) &&
-				(this.getUserProfileMode() != null) &&
-				(this.getGender() != null) &&
-				(this.getFirstName() != null) &&
-				(this.getFamilyName() != null) &&
-				(this.getStreet() != null) &&
-				(this.getHouseNumber() != null) &&
-				(this.getZipCode() != null) &&
-				(this.getCity() != null) &&
-				(this.getEmailAddress() != null) &&
-				(this.getEmailAddressRepeat() != null) &&
-				(this.getUserPassword() != null) &&
-				(this.getUserPasswordRepeat() != null));
-	}
-
-	@Override
-	public boolean isSameEmailAddressEntered () {
-		return (Objects.equals(this.getEmailAddress(), this.getEmailAddressRepeat()));
-	}
-
-	@Override
-	public boolean isSamePasswordEntered () {
-		return (Objects.equals(this.getUserPassword(), this.getUserPasswordRepeat()));
-	}
-
-	@Override
-	public boolean isUserNameRegistered (final User user) {
-		return ((this.userNameList instanceof List) && (this.userNameList.contains(user.getUserName())));
-	}
-
-	@Override
-	public boolean isVisibleUserFound () {
-		return ((this.visibleUserList instanceof List) && (this.visibleUserList.size() > 0));
-	}
-
-	@Override
-	public User lookupUserById (final Long userId) throws UserNotFoundException {
-		// Init variable
-		User user = null;
-
-		// Try to lookup it in visible user list
-		for (final Iterator<User> iterator = this.visibleUserList.iterator(); iterator.hasNext();) {
-			// Get next user
-			User next = iterator.next();
-
-			// Is the user id found?
-			if (Objects.equals(next.getUserId(), userId)) {
-				// Copy to other variable
-				user = next;
-				break;
-			}
-		}
-
-		// Is it still null?
-		if (null == user) {
-			// Not visible for the current user
-			throw new UserNotFoundException(userId);
-		}
-
-		// Return it
-		return user;
-	}
-
-	/**
-	 * Adds user's name and email address to bean's internal list. It also
-	 * updates the public user list if the user has decided to ha	}
-	 * <p>
-	 * @param user User instance
-	 */
-	private void addUserNameEmailAddress (final User user) {
-		// Make sure the entry is not added yet
-		if (this.userNameList.contains(user.getUserName())) {
-			// Abort here
-			throw new IllegalArgumentException(MessageFormat.format("User name {0} already added.", user.getUserName())); //NOI18N
-		} else if (this.emailAddressList.contains(user.getUserContact().getContactEmailAddress())) {
-			// Already added
-			throw new IllegalArgumentException(MessageFormat.format("Email address {0} already added.", user.getUserContact().getContactEmailAddress())); //NOI18N
-		}
-
-		// Add user name
-		this.userNameList.add(user.getUserName());
-
-		// Add email addres
-		this.emailAddressList.add(user.getUserContact().getContactEmailAddress());
-	}
-
-	/**
-	 * Clears all data in this bean
-	 */
-	private void clearData () {
-		// Clear all data
-		// - personal data
-		this.setUserId(null);
-		this.setGender(Gender.UNKNOWN);
-		this.setUserProfileMode(null);
-		this.setFirstName(null);
-		this.setFamilyName(null);
-		this.setStreet(null);
-		this.setHouseNumber(null);
-		this.setZipCode(null);
-		this.setCity(null);
-		this.setCountry(null);
-
-		// - contact data
-		this.setEmailAddress(null);
-		this.setEmailAddressRepeat(null);
-		this.setPhoneAreaCode(null);
-		this.setCellphoneCarrier(null);
-		this.setFaxAreaCode(null);
-
-		// - other data
-		this.setBirthday(null);
-		this.setComment(null);
-		this.setUserName(null);
-		this.setUserPassword(null);
-		this.setUserPasswordRepeat(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.setUserProfileMode(user.getUserProfileMode());
-		this.setGender(user.getUserContact().getContactGender());
-		this.setFirstName(user.getUserContact().getContactFirstName());
-		this.setFamilyName(user.getUserContact().getContactFamilyName());
-		this.setStreet(user.getUserContact().getContactStreet());
-		this.setHouseNumber(user.getUserContact().getContactHouseNumber());
-		this.setZipCode(user.getUserContact().getContactZipCode());
-		this.setCity(user.getUserContact().getContactCity());
-		this.setCountry(user.getUserContact().getContactCountry());
-
-		// Get cellphone, phone and fax instance
-		DialableCellphoneNumber cellphone = user.getUserContact().getContactCellphoneNumber();
-		DialableFaxNumber fax = user.getUserContact().getContactFaxNumber();
-		DialableLandLineNumber phone = user.getUserContact().getContactPhoneNumber();
-
-		// - contact data
-		if ((phone instanceof DialableLandLineNumber) && (phone.getPhoneAreaCode() > 0)) {
-			this.setPhoneCountry(phone.getPhoneCountry());
-			this.setPhoneAreaCode(phone.getPhoneAreaCode());
-			this.setPhoneNumber(phone.getPhoneNumber());
-		}
-		if ((cellphone instanceof DialableCellphoneNumber) && (cellphone.getCellphoneProvider() instanceof SmsProvider)) {
-			this.setCellphoneCarrier(cellphone.getCellphoneProvider());
-			this.setCellphoneNumber(cellphone.getPhoneNumber());
-		}
-		if ((fax instanceof DialableFaxNumber) && (fax.getPhoneAreaCode() > 0)) {
-			this.setFaxCountry(fax.getPhoneCountry());
-			this.setFaxAreaCode(fax.getPhoneAreaCode());
-			this.setFaxNumber(fax.getPhoneNumber());
-		}
-		this.setEmailAddress(user.getUserContact().getContactEmailAddress());
-
-		// -- other data
-		this.setBirthday(user.getUserContact().getContactBirthday());
-		this.setComment(user.getUserContact().getContactComment());
-	}
-
-	@Override
-	public boolean isUserIdEmpty () {
-		return ((this.getUserId() == null) || (this.getUserId() == 0));
-	}
-}
diff --git a/src/java/org/mxchange/addressbook/beans/user/UserWebSessionController.java b/src/java/org/mxchange/addressbook/beans/user/UserWebSessionController.java
deleted file mode 100644
index ac221cd8..00000000
--- a/src/java/org/mxchange/addressbook/beans/user/UserWebSessionController.java
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.addressbook.beans.user;
-
-import java.io.Serializable;
-import java.util.Date;
-import java.util.List;
-import org.mxchange.jcontacts.contact.gender.Gender;
-import org.mxchange.jcountry.data.Country;
-import org.mxchange.jphone.phonenumbers.smsprovider.SmsProvider;
-import org.mxchange.jusercore.events.login.UserLoggedInEvent;
-import org.mxchange.jusercore.events.registration.UserRegisteredEvent;
-import org.mxchange.jusercore.exceptions.UserNotFoundException;
-import org.mxchange.jusercore.model.user.User;
-import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
-
-/**
- * An interface for user beans
- * <p>
- * @author Roland Haeder<roland@mxchange.org>
- */
-public interface UserWebSessionController extends Serializable {
-
-	/**
-	 * Tries to lookup user by given id number. If the user is not found or the
-	 * account status is not CONFIRMED proper exceptions are thrown.
-	 * <p>
-	 * @param userId User id
-	 * <p>
-	 * @return User instance
-	 * <p>
-	 * @throws UserNotFoundException If the user is not found
-	 */
-	User lookupUserById (final Long userId) throws UserNotFoundException;
-
-	/**
-	 * Event observer for new user registrations
-	 * <p>
-	 * @param event User registration event
-	 */
-	void afterRegistrationEvent (final UserRegisteredEvent event);
-
-	/**
-	 * Event observer for logged-in user
-	 * <p>
-	 * @param event Event instance
-	 */
-	void afterUserLogin (final UserLoggedInEvent event);
-
-	/**
-	 * All public user profiles
-	 * <p>
-	 * @return A list of all public user profiles
-	 */
-	List<User> allVisibleUsers ();
-
-	/**
-	 * Creates an instance from all properties
-	 * <p>
-	 * @return A user instance
-	 */
-	User createUserInstance ();
-
-	/**
-	 * Getter for birth day
-	 * <p>
-	 * @return Birth day
-	 */
-	Date getBirthday ();
-
-	/**
-	 * Setter for birth day
-	 * <p>
-	 * @param birthday Birth day
-	 */
-	void setBirthday (final Date birthday);
-
-	/**
-	 * Getter for ellphone number's carrier
-	 * <p>
-	 * @return Cellphone number's carrier
-	 */
-	SmsProvider getCellphoneCarrier ();
-
-	/**
-	 * Setter for cellphone number's carrier prefix
-	 * <p>
-	 * @param cellphoneCarrier Cellphone number's carrier prefix
-	 */
-	void setCellphoneCarrier (final SmsProvider cellphoneCarrier);
-
-	/**
-	 * Getter for ellphone number
-	 * <p>
-	 * @return Cellphone number
-	 */
-	Long getCellphoneNumber ();
-
-	/**
-	 * Setter for ellphone number
-	 * <p>
-	 * @param cellphoneNumber Cellphone number
-	 */
-	void setCellphoneNumber (final Long cellphoneNumber);
-
-	/**
-	 * City
-	 * <p>
-	 * @return the city
-	 */
-	String getCity ();
-
-	/**
-	 * City
-	 * <p>
-	 * @param city the city to set
-	 */
-	void setCity (final String city);
-
-	/**
-	 * Getter for comments
-	 * <p>
-	 * @return Comments
-	 */
-	String getComment ();
-
-	/**
-	 * Setter for comment
-	 * <p>
-	 * @param comment Comments
-	 */
-	void setComment (final String comment);
-
-	/**
-	 * Getter for country instance
-	 * <p>
-	 * @return Country instance
-	 */
-	Country getCountry ();
-
-	/**
-	 * Setter for country instance
-	 * <p>
-	 * @param country Country instance
-	 */
-	void setCountry (final Country country);
-
-	/**
-	 * Getter for email address
-	 * <p>
-	 * @return Email address
-	 */
-	String getEmailAddress ();
-
-	/**
-	 * Setter for email address
-	 * <p>
-	 * @param emailAddress Email address
-	 */
-	void setEmailAddress (final String emailAddress);
-
-	/**
-	 * Getter for email address, repeated
-	 * <p>
-	 * @return the emailAddress, repeated
-	 */
-	String getEmailAddressRepeat ();
-
-	/**
-	 * Setter for email address repeated
-	 * <p>
-	 * @param emailAddressRepeat the emailAddress to set
-	 */
-	void setEmailAddressRepeat (final String emailAddressRepeat);
-
-	/**
-	 * Family name
-	 * <p>
-	 * @return the familyName
-	 */
-	String getFamilyName ();
-
-	/**
-	 * Family name
-	 * <p>
-	 * @param familyName the familyName to set
-	 */
-	void setFamilyName (final String familyName);
-
-	/**
-	 * Getter for fax number's area code
-	 * <p>
-	 * @return Fax number's area code
-	 */
-	Integer getFaxAreaCode ();
-
-	/**
-	 * Setter for fax number's area code
-	 * <p>
-	 * @param faxAreaCode Fax number's area code
-	 */
-	void setFaxAreaCode (final Integer faxAreaCode);
-
-	/**
-	 * Getter for fax's country instance
-	 * <p>
-	 * @return Fax' country instance
-	 */
-	Country getFaxCountry ();
-
-	/**
-	 * Setter for fax's country instance
-	 * <p>
-	 * @param faxCountry Fax' country instance
-	 */
-	void setFaxCountry (final Country faxCountry);
-
-	/**
-	 * Getter for fax number
-	 * <p>
-	 * @return Fax number
-	 */
-	Long getFaxNumber ();
-
-	/**
-	 * Setter for fax number
-	 * <p>
-	 * @param faxNumber Fax number
-	 */
-	void setFaxNumber (final Long faxNumber);
-
-	/**
-	 * First name
-	 * <p>
-	 * @return the first name
-	 */
-	String getFirstName ();
-
-	/**
-	 * First name
-	 * <p>
-	 * @param firstName the first name to set
-	 */
-	void setFirstName (final String firstName);
-
-	/**
-	 * Gender of the contact
-	 * <p>
-	 * @return the gender
-	 */
-	Gender getGender ();
-
-	/**
-	 * Gender of the contact
-	 * <p>
-	 * @param gender the gender to set
-	 */
-	void setGender (final Gender gender);
-
-	/**
-	 * House number
-	 * <p>
-	 * @return the houseNumber
-	 */
-	Short getHouseNumber ();
-
-	/**
-	 * House number
-	 * <p>
-	 * @param houseNumber the houseNumber to set
-	 */
-	void setHouseNumber (final Short houseNumber);
-
-	/**
-	 * Getter for phone number's area code
-	 * <p>
-	 * @return Phone number's area code
-	 */
-	Integer getPhoneAreaCode ();
-
-	/**
-	 * Setter for phone number's area code
-	 * <p>
-	 * @param phoneAreaCode Phone number's area code
-	 */
-	void setPhoneAreaCode (final Integer phoneAreaCode);
-
-	/**
-	 * Getter for phone number's country instance
-	 * <p>
-	 * @return Phone number's country instance
-	 */
-	Country getPhoneCountry ();
-
-	/**
-	 * Setter for phone number's country instance
-	 * <p>
-	 * @param phoneCountry Phone number's country instance
-	 */
-	void setPhoneCountry (final Country phoneCountry);
-
-	/**
-	 * Getter for phone number
-	 * <p>
-	 * @return Phone number
-	 */
-	Long getPhoneNumber ();
-
-	/**
-	 * Setter for phone number
-	 * <p>
-	 * @param phoneNumber Phone number
-	 */
-	void setPhoneNumber (final Long phoneNumber);
-
-	/**
-	 * Street
-	 * <p>
-	 * @return the street
-	 */
-	String getStreet ();
-
-	/**
-	 * Street
-	 * <p>
-	 * @param street the street to set
-	 */
-	void setStreet (final String street);
-
-	/**
-	 * Getter for user id
-	 * <p>
-	 * @return User id
-	 */
-	Long getUserId ();
-
-	/**
-	 * Setter for user id
-	 * <p>
-	 * @param userId User id
-	 */
-	void setUserId (final Long userId);
-
-	/**
-	 * Getter for user name
-	 * <p>
-	 * @return User name
-	 */
-	String getUserName ();
-
-	/**
-	 * Setter for user name
-	 * <p>
-	 * @param userName User name
-	 */
-	void setUserName (final String userName);
-
-	/**
-	 * Getter for unencrypted user password
-	 * <p>
-	 * @return Unencrypted user password
-	 */
-	String getUserPassword ();
-
-	/**
-	 * Setter for unencrypted user password
-	 * <p>
-	 * @param userPassword Unencrypted user password
-	 */
-	void setUserPassword (final String userPassword);
-
-	/**
-	 * Getter for unencrypted user password repeated
-	 * <p>
-	 * @return Unencrypted user password repeated
-	 */
-	String getUserPasswordRepeat ();
-
-	/**
-	 * Setter for unencrypted user password repeated
-	 * <p>
-	 * @param userPasswordRepeat Unencrypted user password repeated
-	 */
-	void setUserPasswordRepeat (final String userPasswordRepeat);
-
-	/**
-	 * Getter for user profile mode
-	 * <p>
-	 * @return User profile mode
-	 */
-	ProfileMode getUserProfileMode ();
-
-	/**
-	 * Setter for user profile mode
-	 * <p>
-	 * @param userProfileMode User profile mode
-	 */
-	void setUserProfileMode (final ProfileMode userProfileMode);
-
-	/**
-	 * ZIP code
-	 * <p>
-	 * @return the zipCode
-	 */
-	Integer getZipCode ();
-
-	/**
-	 * ZIP code
-	 * <p>
-	 * @param zipCode the zipCode to set
-	 */
-	void setZipCode (final Integer zipCode);
-
-	/**
-	 * Checks whether user instance's email address is used
-	 * <p>
-	 * @param user User instance's email address to check
-	 * <p>
-	 * @return Whether it is already used
-	 */
-	boolean isEmailAddressRegistered (final User user);
-
-	/**
-	 * Checks whether all required personal data is set
-	 * <p>
-	 * @return Whether the required personal data is set
-	 */
-	boolean isRequiredPersonalDataSet ();
-
-	/**
-	 * Checks whether same email addresses have been entered
-	 * <p>
-	 * @return Whether same email addresses have been entered
-	 */
-	boolean isSameEmailAddressEntered ();
-
-	/**
-	 * Checks whether same passwords has been entered
-	 * <p>
-	 * @return Whether same passwords has been entered
-	 */
-	boolean isSamePasswordEntered ();
-
-	/**
-	 * Checks whether given user instance's name is used
-	 * <p>
-	 * @param user User instance's name to check
-	 * <p>
-	 * @return Whether it is already used
-	 */
-	boolean isUserNameRegistered (final User user);
-
-	/**
-	 * Checks whether a public user account is registered. This means that at
-	 * least one user profile has its flag "public user profile" enabled.
-	 * <p>
-	 * @return Whether at least one user has a public profile
-	 */
-	boolean isVisibleUserFound ();
-
-	/**
-	 * Checks if the user id is empty
-	 * <p>
-	 * @return Whether the user id is empty
-	 */
-	boolean isUserIdEmpty ();
-}
diff --git a/src/java/org/mxchange/addressbook/converter/country/CountryConverter.java b/src/java/org/mxchange/addressbook/converter/country/CountryConverter.java
deleted file mode 100644
index c758b39d..00000000
--- a/src/java/org/mxchange/addressbook/converter/country/CountryConverter.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.addressbook.converter.country;
-
-import java.text.MessageFormat;
-import java.util.List;
-import java.util.Objects;
-import javax.faces.component.UIComponent;
-import javax.faces.context.FacesContext;
-import javax.faces.convert.Converter;
-import javax.faces.convert.FacesConverter;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import org.mxchange.jcoreeelogger.beans.local.logger.Log;
-import org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal;
-import org.mxchange.jcountry.data.AddressbookCountrySingletonBeanRemote;
-import org.mxchange.jcountry.data.Country;
-
-/**
- * Converter for country instance
- * <p>
- * @author Roland Haeder
- */
-@FacesConverter (value = "country")
-public class CountryConverter implements Converter {
-
-	/**
-	 * Country bean
-	 */
-	private AddressbookCountrySingletonBeanRemote countryController;
-
-	/**
-	 * Logger instance
-	 */
-	@Log
-	private LoggerBeanLocal loggerBeanLocal;
-
-	@Override
-	public Object getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) {
-		// Trace message
-		this.loggerBeanLocal.logTrace(MessageFormat.format("getAsObject: contect={0},component={1},submittedValue={2},this.countryController={3} - CALLED!", context, component, submittedValue, this.countryController)); //NOI18N
-
-		// Get full list
-		List<Country> countryList = this.countryController.allCountries();
-
-		// Is the value null or empty?
-		if ((null == submittedValue) || (submittedValue.trim().isEmpty())) {
-			// Return null
-			return null;
-		}
-
-		// Init value
-		Country country = null;
-
-		// Try this better
-		try {
-			// Convert it to long
-			Long countryId = Long.parseLong(submittedValue);
-
-			// Category id should not be below 1
-			assert (countryId > 0) : "countryId is smaller than one: " + countryId; //NOI18N
-
-			// Debug message
-			this.loggerBeanLocal.logDebug(MessageFormat.format("getAsObject: countryId={0}", countryId)); //NOI18N
-
-			// Try to find it
-			for (final Country cntry : countryList) {
-				// Is the id the same? (null-safe)
-				if (Objects.equals(cntry.getCountryId(), countryId)) {
-					// Found it
-					country = cntry;
-					break;
-				}
-			}
-		} catch (final NumberFormatException ex) {
-			// Log exception (maybe to much?)
-			this.loggerBeanLocal.logException(ex);
-		}
-
-		// Trace message
-		this.loggerBeanLocal.logTrace(MessageFormat.format("getAsObject: country={0} - EXIT!", country)); //NOI18N
-
-		// Return it
-		return country;
-	}
-
-	@Override
-	public String getAsString (final FacesContext context, final UIComponent component, final Object value) {
-		// Is the object null?
-		if ((null == value) || ((String.valueOf(value)).isEmpty())) {
-			// Is null
-			return ""; //NOI18N
-		} else if (!(value instanceof Country)) {
-			// Not same interface
-			throw new IllegalArgumentException(MessageFormat.format("value {0} does not implement Country.", value)); //NOI18N
-		}
-
-		// Return category id
-		return String.valueOf(((Country) value).getCountryId());
-	}
-
-	/**
-	 * Initialization of this converter
-	 */
-	public CountryConverter () {
-		// Try to get it
-		try {
-			// Get initial context
-			Context context = new InitialContext();
-
-			// Lookup logger
-			this.loggerBeanLocal = (LoggerBeanLocal) context.lookup("java:global/jcore-logger-ejb/logger!org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal"); //NOI18N
-
-			// ... and country controller
-			this.countryController = (AddressbookCountrySingletonBeanRemote) context.lookup("java:global/addressbook-ejb/country!org.mxchange.jcountry.data.AddressbookCountrySingletonBeanRemote"); //NOI18N
-		} catch (final NamingException ex) {
-			// Continue to throw it
-			throw new RuntimeException("context.lookup() failed.", ex); //NOI18N
-		}
-	}
-}
diff --git a/src/java/org/mxchange/addressbook/converter/smsprovider/SmsProviderConverter.java b/src/java/org/mxchange/addressbook/converter/smsprovider/SmsProviderConverter.java
deleted file mode 100644
index 464c113e..00000000
--- a/src/java/org/mxchange/addressbook/converter/smsprovider/SmsProviderConverter.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.addressbook.converter.smsprovider;
-
-import java.text.MessageFormat;
-import java.util.List;
-import java.util.Objects;
-import javax.faces.component.UIComponent;
-import javax.faces.context.FacesContext;
-import javax.faces.convert.Converter;
-import javax.faces.convert.FacesConverter;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import org.mxchange.jcoreeelogger.beans.local.logger.Log;
-import org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal;
-import org.mxchange.jphone.phonenumbers.smsprovider.AddressbookSmsProviderSingletonBeanRemote;
-import org.mxchange.jphone.phonenumbers.smsprovider.SmsProvider;
-
-/**
- * Converter for SMS provider instance
- * <p>
- * @author Roland Haeder
- */
-@FacesConverter (value = "cellphoneCarrier")
-public class SmsProviderConverter implements Converter {
-
-	/**
-	 * Logger instance
-	 */
-	@Log
-	private LoggerBeanLocal loggerBeanLocal;
-
-	/**
-	 * SMS provider bean
-	 */
-	private AddressbookSmsProviderSingletonBeanRemote providerController;
-
-	@Override
-	public Object getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) {
-		// Trace message
-		this.loggerBeanLocal.logTrace(MessageFormat.format("getAsObject: contect={0},component={1},submittedValue={2} - CALLED!", context, component, submittedValue)); //NOI18N
-
-		// Get full list
-		List<SmsProvider> providerList = this.providerController.allSmsProvider();
-
-		// Is the value null or empty?
-		if ((null == submittedValue) || (submittedValue.trim().isEmpty())) {
-			// Return null
-			return null;
-		}
-
-		// Init value
-		SmsProvider provider = null;
-
-		// Try this better
-		try {
-			// Convert it to long
-			Long providerId = Long.parseLong(submittedValue);
-
-			// Category id should not be below 1
-			assert (providerId > 0) : "providerId is smaller than one: " + providerId; //NOI18N
-
-			// Debug message
-			this.loggerBeanLocal.logDebug(MessageFormat.format("getAsObject: providerId={0}", providerId)); //NOI18N
-
-			// Try to find it
-			for (final SmsProvider prov : providerList) {
-				// Is the id the same? (null-safe)
-				if (Objects.equals(prov.getProviderId(), providerId)) {
-					// Found it
-					provider = prov;
-					break;
-				}
-			}
-		} catch (final NumberFormatException ex) {
-			// Log exception (maybe to much?)
-			this.loggerBeanLocal.logException(ex);
-		}
-
-		// Trace message
-		this.loggerBeanLocal.logTrace(MessageFormat.format("getAsObject: provider={0} - EXIT!", provider)); //NOI18N
-
-		// Return it
-		return provider;
-	}
-
-	@Override
-	public String getAsString (final FacesContext context, final UIComponent component, final Object value) {
-		// Is the object null?
-		if ((null == value) || ((String.valueOf(value)).isEmpty())) {
-			// Is null
-			return ""; //NOI18N
-		} else if (!(value instanceof SmsProvider)) {
-			// Not same interface
-			throw new IllegalArgumentException(MessageFormat.format("value {0} does not implement SmsProvider.", value)); //NOI18N
-		}
-
-		// Return category id
-		return String.valueOf(((SmsProvider) value).getProviderId());
-	}
-
-	/**
-	 * Initialization of this converter
-	 */
-	public SmsProviderConverter () {
-		// Try to get it
-		try {
-			// Get initial context
-			Context context = new InitialContext();
-
-			// Lookup logger
-			this.loggerBeanLocal = (LoggerBeanLocal) context.lookup("java:global/jcore-logger-ejb/logger!org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal"); //NOI18N
-
-			/// and SMS provider controller
-			this.providerController = (AddressbookSmsProviderSingletonBeanRemote) context.lookup("java:global/addressbook-ejb/smsprovider!org.mxchange.jphone.phonenumbers.smsprovider.AddressbookSmsProviderSingletonBeanRemote"); //NOI18N
-		} catch (final NamingException ex) {
-			// Continue to throw it
-			throw new RuntimeException("context.lookup() failed.", ex); //NOI18N
-		}
-	}
-
-}
diff --git a/src/java/org/mxchange/addressbook/converter/user/UserConverter.java b/src/java/org/mxchange/addressbook/converter/user/UserConverter.java
deleted file mode 100644
index 769dc443..00000000
--- a/src/java/org/mxchange/addressbook/converter/user/UserConverter.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2016 Roland Haeder
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.addressbook.converter.user;
-
-import java.text.MessageFormat;
-import javax.faces.component.UIComponent;
-import javax.faces.context.FacesContext;
-import javax.faces.convert.Converter;
-import javax.faces.convert.ConverterException;
-import javax.faces.convert.FacesConverter;
-import javax.inject.Inject;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import org.mxchange.addressbook.beans.user.UserWebSessionController;
-import org.mxchange.jcoreeelogger.beans.local.logger.Log;
-import org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal;
-import org.mxchange.jusercore.exceptions.UserNotFoundException;
-import org.mxchange.jusercore.model.user.User;
-
-/**
- * Converter for user id <-> valid user instance
- * <p>
- * @author Roland Haeder
- */
-@FacesConverter (value = "UserConverter")
-public class UserConverter implements Converter {
-
-	/**
-	 * Logger instance
-	 */
-	@Log
-	private LoggerBeanLocal loggerBeanLocal;
-
-	/**
-	 * User bean
-	 */
-	@Inject
-	private UserWebSessionController userController;
-
-	@Override
-	public Object getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) {
-		// Trace message
-		this.loggerBeanLocal.logTrace(MessageFormat.format("getAsObject: contect={0},component={1},submittedValue={2} - CALLED!", context, component, submittedValue)); //NOI18N
-
-		// Is the value null or empty?
-		if ((null == submittedValue) || (submittedValue.trim().isEmpty())) {
-			// Return null
-			return null;
-		}
-
-		// Init instance
-		User user = null;
-
-		try {
-			// Try to parse the value as long
-			Long userId = Long.valueOf(submittedValue);
-
-			// Debug message
-			this.loggerBeanLocal.logDebug(MessageFormat.format("getAsObject: userId{0}", userId));
-
-			// Try to get user instance from it
-			user = this.userController.lookupUserById(userId);
-
-			// Debug message
-			this.loggerBeanLocal.logDebug(MessageFormat.format("getAsObject: user={0}", user));
-		} catch (final NumberFormatException ex) {
-			// Throw again
-			throw new ConverterException(ex);
-		} catch (final UserNotFoundException ex) {
-			// Debug message
-			this.loggerBeanLocal.logDebug(MessageFormat.format("getAsObject: Exception: {0} - Returning null ...", ex));
-
-			// Return null
-			return null;
-		}
-
-		// Trace message
-		this.loggerBeanLocal.logTrace(MessageFormat.format("getAsObject: user={0} - EXIT!", user));
-
-		// Return it
-		return user;
-	}
-
-	@Override
-	public String getAsString (final FacesContext context, final UIComponent component, final Object value) {
-		// Is the object null?
-		if ((null == value) || ((String.valueOf(value)).isEmpty())) {
-			// Is null
-			return ""; //NOI18N
-		} else if (!(value instanceof User)) {
-			// Not same interface
-			throw new IllegalArgumentException(MessageFormat.format("value {0} does not implement User.", value)); //NOI18N
-		}
-
-		// Return category id
-		return String.valueOf(((User) value).getUserId());
-	}
-
-	/**
-	 * Initialization of this converter
-	 */
-	public UserConverter () {
-		// Try to get it
-		try {
-			// Get initial context
-			Context context = new InitialContext();
-
-			// Lookup logger
-			this.loggerBeanLocal = (LoggerBeanLocal) context.lookup("java:global/jcore-logger-ejb/logger!org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal"); //NOI18N
-
-			// ... and user controller
-			this.userController = (UserWebSessionController) context.lookup("java:global/juser-ejb/user!org.mxchange.jusercore.model.user.UserSessionBeanRemote"); //NOI18N
-		} catch (final NamingException ex) {
-			// Continue to throw it
-			throw new RuntimeException("context.lookup() failed.", ex); //NOI18N
-		}
-	}
-}
diff --git a/src/java/org/mxchange/jjobs/beans/addressbook/AddressbookWebSessionBean.java b/src/java/org/mxchange/jjobs/beans/addressbook/AddressbookWebSessionBean.java
new file mode 100644
index 00000000..861e0553
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/addressbook/AddressbookWebSessionBean.java
@@ -0,0 +1,419 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.beans.addressbook;
+
+import java.text.MessageFormat;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.GregorianCalendar;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.SessionScoped;
+import javax.enterprise.event.Observes;
+import javax.faces.view.facelets.FaceletException;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import org.mxchange.jjobs.beans.login.UserLoginWebSessionController;
+import org.mxchange.addressbook.events.addressbook.AddressbookLoadedEvent;
+import org.mxchange.addressbook.exceptions.AddressbookNameAlreadyUsedException;
+import org.mxchange.addressbook.model.addressbook.Addressbook;
+import org.mxchange.addressbook.model.addressbook.AddressbookSessionBeanRemote;
+import org.mxchange.addressbook.model.addressbook.UserAddressbook;
+import org.mxchange.addressbook.model.addressbook.entry.AddressbookEntry;
+import org.mxchange.jusercore.events.login.UserLoggedInEvent;
+import org.mxchange.jusercore.model.user.User;
+
+/**
+ * An address book bean (controller)
+ * <p>
+ * @author Roland Haeder<roland@mxchange.org>
+ */
+@Named ("addressbookController")
+@SessionScoped
+public class AddressbookWebSessionBean implements AddressbookWebSessionController {
+
+	/**
+	 * Map for count of user's shared addresses
+	 */
+	private static ConcurrentMap<User, Integer> countSharesList;
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 185_781_756_712_969L;
+
+	/**
+	 * Address book instance
+	 */
+	private Addressbook addressbook;
+
+	/**
+	 * Remote address book bean
+	 */
+	private AddressbookSessionBeanRemote addressbookBean;
+
+	/**
+	 * When this address book has been created
+	 */
+	private Calendar addressbookCreated;
+
+	/**
+	 * Address book id number (from URL for example)
+	 */
+	private Long addressbookId;
+
+	/**
+	 * Name of the address book
+	 */
+	private String addressbookName;
+
+	/**
+	 * Who owns this address book
+	 */
+	private User addressbookUser;
+
+	/**
+	 * Login controller
+	 */
+	@Inject
+	private UserLoginWebSessionController loginController;
+
+	/**
+	 * A list of all user's address books
+	 */
+	private List<Addressbook> usersAddressbooks;
+
+	/**
+	 * Default constructor
+	 */
+	public AddressbookWebSessionBean () {
+		// Try it
+		try {
+			// Get initial context
+			Context context = new InitialContext();
+
+			// Try to lookup
+			this.addressbookBean = (AddressbookSessionBeanRemote) context.lookup("ejb/stateless-addressbook"); //NOI18N
+		} catch (final NamingException e) {
+			// Throw again
+			throw new FaceletException(e);
+		}
+
+		// Init list
+		AddressbookWebSessionBean.countSharesList = new ConcurrentHashMap<>(0);
+	}
+
+	@Override
+	public String addAddressbook () {
+		// Is this name already used?
+		if (!this.loginController.isUserLoggedIn()) {
+			// Not logged in
+			throw new FaceletException("This method can only be called as logged-in user."); //NOI18N
+		} else if (this.getAddressbookName() == null) {
+			// Address book name is null
+			throw new NullPointerException("addressbookName is null"); //NOI18N
+		} else if (this.getAddressbookName().isEmpty()) {
+			// Address book name is empty
+			throw new IllegalStateException("addressbookName is empty."); //NOI18N
+		} else if (this.isAddressbookNameUsed(this.getAddressbookName())) {
+			// Already used by this user
+			throw new FaceletException(MessageFormat.format("Address book name {0} already used.", this.getAddressbookName())); //NOI18N
+		}
+
+		// Create address book instance with name
+		Addressbook book = new UserAddressbook(this.getAddressbookName(), this.loginController.getLoggedInUser(), new GregorianCalendar());
+
+		try {
+			// Register this address book
+			Addressbook updatedAddressbook = this.addressbookBean.createAddressbook(book);
+
+			// Remove name
+			this.setAddressbookName(null);
+
+			// Add address book entry to list
+			this.usersAddressbooks.add(updatedAddressbook);
+
+			// All fine
+			return "login_own_addressbooks"; //NOI18N
+		} catch (final AddressbookNameAlreadyUsedException ex) {
+			// Throw again as cause
+			throw new FaceletException(ex);
+		}
+	}
+
+	@Override
+	public void afterAddressbookLoadedEvent (final @Observes AddressbookLoadedEvent event) {
+		// event should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getAddressbook() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.addressbook is null"); //NOI18N
+		} else if (event.getAddressbook().getAddressbookId() == null) {
+			// And again a NPE
+			throw new NullPointerException("event.addressbook.addressbookId is null"); //NOI18N
+		} else if (event.getAddressbook().getAddressbookId() < 1) {
+			// Invalid id number
+			throw new IllegalArgumentException(MessageFormat.format("Address book instance {0} has invalid id number: {1}", event.getAddressbook(), event.getAddressbook().getAddressbookId())); //NOI18N
+		} else if (event.getAddressbook().getAddressbookUser() == null) {
+			// One more NPE ...
+			throw new NullPointerException("event.addressbook.addressbookUser is null"); //NOI18N
+		}
+
+		// Get address book instance
+		Addressbook book = event.getAddressbook();
+
+		// Set address book data
+		this.setAddressbookId(book.getAddressbookId());
+		this.setAddressbookName(book.getAddressbookName());
+		this.setAddressbookUser(book.getAddressbookUser());
+		this.setAddressbookCreated(book.getAddressbookCreated());
+
+		// And instance ...
+		this.setAddressbook(book);
+	}
+
+	@Override
+	public void afterLoginEvent (final @Observes UserLoggedInEvent event) {
+		// Is the user logged in?
+		if (null == event) {
+			// Is null
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUser() == null) {
+			// user is null
+			throw new NullPointerException("event.user is null"); //NOI18N
+		} else if (!event.getUser().equals(this.loginController.getLoggedInUser())) {
+			// Not matching
+			throw new IllegalStateException("event.user and loginController.loggedInUser don't match."); //NOI18N
+		} else if (!this.loginController.isUserLoggedIn()) {
+			// Not logged in
+			throw new FaceletException("This method can only be called as logged-in user."); //NOI18N
+		}
+
+		// Init user's address book list
+		this.initAddressbookList();
+	}
+
+	@Override
+	public List<Addressbook> allAddressbooks () {
+		// Is the user logged in?
+		if (!this.loginController.isUserLoggedIn()) {
+			// Not logged in
+			throw new FaceletException("This method can only be called as logged-in user."); //NOI18N
+		}
+
+		return Collections.unmodifiableList(this.usersAddressbooks);
+	}
+
+	@Override
+	public List<AddressbookEntry> allEntries (final Addressbook addressbook) {
+		// Is the user logged in?
+		if (!this.loginController.isUserLoggedIn()) {
+			// Not logged in
+			throw new FaceletException("This method can only be called as logged-in user."); //NOI18N
+		}
+
+		// Ask the bean
+		return this.addressbookBean.allEntries(addressbook);
+	}
+
+	@Override
+	public int allEntriesSize (final Addressbook addressbook) {
+		// Ask the bean
+		return this.allEntries(addressbook).size();
+	}
+
+	@Override
+	public List<User> allUsersNotSharing () {
+		// Is the user logged in?
+		if (!this.loginController.isUserLoggedIn()) {
+			// Not logged in
+			throw new FaceletException("This method can only be called as logged-in user."); //NOI18N
+		}
+
+		// Call EJB
+		return this.addressbookBean.allUsersNotSharing(this.loginController.getLoggedInUser(), this.getAddressbook());
+	}
+
+	@Override
+	public Integer countAllUserSharedAddressbooks (final User user) {
+		// Is there cache?
+		if (AddressbookWebSessionBean.countSharesList.containsKey(user)) {
+			// Return it instead
+			return AddressbookWebSessionBean.countSharesList.get(user);
+		}
+
+		// Call EJB ("expensive")
+		Integer count = this.addressbookBean.countAllUserSharedAddressbooks(user);
+
+		// Add to list
+		AddressbookWebSessionBean.countSharesList.put(user, count);
+
+		// Return it
+		return count;
+	}
+
+	@Override
+	public Addressbook getAddressbook () {
+		return this.addressbook;
+	}
+
+	@Override
+	public void setAddressbook (final Addressbook addressbook) {
+		this.addressbook = addressbook;
+	}
+
+	@Override
+	public Calendar getAddressbookCreated () {
+		return this.addressbookCreated;
+	}
+
+	@Override
+	public void setAddressbookCreated (final Calendar addressbookCreated) {
+		this.addressbookCreated = addressbookCreated;
+	}
+
+	@Override
+	public Long getAddressbookId () {
+		return this.addressbookId;
+	}
+
+	@Override
+	public void setAddressbookId (final Long addressbookId) {
+		this.addressbookId = addressbookId;
+	}
+
+	@Override
+	public String getAddressbookName () {
+		return this.addressbookName;
+	}
+
+	@Override
+	public void setAddressbookName (final String addressbookName) {
+		this.addressbookName = addressbookName;
+	}
+
+	@Override
+	public User getAddressbookUser () {
+		return this.addressbookUser;
+	}
+
+	@Override
+	public void setAddressbookUser (final User addressbookUser) {
+		this.addressbookUser = addressbookUser;
+	}
+
+	@Override
+	public boolean hasCreatedAddressbooks () {
+		// Is the user logged in?
+		if (!this.loginController.isUserLoggedIn()) {
+			// Not logged in
+			throw new FaceletException("This method can only be called as logged-in user."); //NOI18N
+		}
+
+		// Check if the list is filled
+		return (!this.usersAddressbooks.isEmpty());
+	}
+
+	@PostConstruct
+	public void init () {
+		// Init list
+		this.usersAddressbooks = new LinkedList<>();
+
+		// Is the user logged-in?
+		if (this.loginController.isUserLoggedIn()) {
+			// Initialize list
+			this.initAddressbookList();
+		}
+
+		// TODO Initialize list from bean with just one call
+		//this.addressbookBean.getUserCountMap()
+	}
+
+	@Override
+	public boolean isAddressbookNameUsed (final String addressbookName) {
+		// Is it zero size?
+		if (null == addressbookName) {
+			// Is null
+			throw new NullPointerException("addressbookName is null"); //NOI18N
+		} else if (this.usersAddressbooks.isEmpty()) {
+			// Not found!
+			return false;
+		}
+
+		// Default is not found
+		boolean isFound = false;
+
+		// Check all entries
+		for (final Addressbook book : this.usersAddressbooks) {
+			// Is the name same?
+			if (book.getAddressbookName().equals(addressbookName)) {
+				// Found a match
+				isFound = true;
+				break;
+			}
+		}
+
+		// Return status
+		return isFound;
+	}
+
+	@Override
+	public boolean isOtherAddressbook () {
+		// Just call the other method and invert it
+		return (!this.isOwnAddressbook());
+	}
+
+	@Override
+	public boolean isOwnAddressbook () {
+		// Is the user logged in?
+		if (!this.loginController.isUserLoggedIn()) {
+			// No, then no own address book
+			throw new IllegalStateException("isOwnAddressbook() has been invoked for a guest account"); //NOI18N
+		}
+
+		// Is same user?
+		return Objects.equals(this.getAddressbookUser(), this.loginController.getLoggedInUser());
+	}
+
+	@Override
+	public boolean isAddressbookLoaded () {
+		return ((this.getAddressbookId() instanceof Long)
+				&& (this.getAddressbookName() instanceof String)
+				&& (!this.getAddressbookName().isEmpty())
+				&& (this.getAddressbookUser() instanceof User));
+	}
+
+	/**
+	 * Initializes the user user's address book list
+	 */
+	private void initAddressbookList () {
+		// Get user instance
+		User user = this.loginController.getLoggedInUser();
+
+		// Fill list with entries
+		this.usersAddressbooks = this.addressbookBean.getUsersAddressbookList(user);
+	}
+}
diff --git a/src/java/org/mxchange/jjobs/beans/addressbook/AddressbookWebSessionController.java b/src/java/org/mxchange/jjobs/beans/addressbook/AddressbookWebSessionController.java
new file mode 100644
index 00000000..303d4f7b
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/addressbook/AddressbookWebSessionController.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.beans.addressbook;
+
+import java.io.Serializable;
+import java.util.Calendar;
+import java.util.List;
+import org.mxchange.addressbook.events.addressbook.AddressbookLoadedEvent;
+import org.mxchange.addressbook.model.addressbook.Addressbook;
+import org.mxchange.addressbook.model.addressbook.entry.AddressbookEntry;
+import org.mxchange.jusercore.events.login.UserLoggedInEvent;
+import org.mxchange.jusercore.model.user.User;
+
+/**
+ * An interface for address book beans
+ * <p>
+ * @author Roland Haeder<roland@mxchange.org>
+ */
+public interface AddressbookWebSessionController extends Serializable {
+
+	/**
+	 * Checks whether the user has created addressbooks. For this method to work
+	 * it is vital that the user is logged into his/her account.
+	 * <p>
+	 * @return Whether the user has created at least one addressbook
+	 */
+	boolean hasCreatedAddressbooks ();
+
+	/**
+	 * Creates a new address book with a name and redirects to proper target.
+	 * For this method to work it is vital that the user is logged into his/her
+	 * account.
+	 * <p>
+	 * @return Target to redirect to
+	 */
+	String addAddressbook ();
+
+	/**
+	 * Getter for address book name
+	 * <p>
+	 * @return Address book name
+	 */
+	String getAddressbookName ();
+
+	/**
+	 * Setter for address book name
+	 * <p>
+	 * @param addressbookName Address book name
+	 */
+	void setAddressbookName (final String addressbookName);
+
+	/**
+	 * Checks if the given address book name is already used by the user.
+	 * <p>
+	 * @param addressbookName Address book name to check
+	 * <p>
+	 * @return Whether the name has already been used by the user
+	 */
+	boolean isAddressbookNameUsed (final String addressbookName);
+
+	/**
+	 * Returns all address books with this user
+	 * <p>
+	 * @return A list of all address books by this user
+	 */
+	List<Addressbook> allAddressbooks ();
+
+	/**
+	 * Returns a list of all address book entries for given address book
+	 * <p>
+	 * @param addressbook Address book instance
+	 * <p>
+	 * @return List of all entries
+	 */
+	List<AddressbookEntry> allEntries (final Addressbook addressbook);
+
+	/**
+	 * Size of all entries in given address book
+	 * <p>
+	 * @param addressbook Address book instance
+	 * <p>
+	 * @return Size of the entries in address book
+	 */
+	int allEntriesSize (final Addressbook addressbook);
+
+	/**
+	 * Getter for address book id number
+	 * <p>
+	 * @return Address book id number
+	 */
+	Long getAddressbookId ();
+
+	/**
+	 * Setter for address book id number
+	 * <p>
+	 * @param addressbookId Address book id number
+	 */
+	void setAddressbookId (final Long addressbookId);
+
+	/**
+	 * Getter for address book user (owner)
+	 * <p>
+	 * @return Address book user (owner)
+	 */
+	User getAddressbookUser ();
+
+	/**
+	 * Setter for address book user (owner)
+	 * <p>
+	 * @param addressbookUser Address book user (owner)
+	 */
+	void setAddressbookUser (final User addressbookUser);
+
+	/**
+	 * Getter for when the address book has been created
+	 * <p>
+	 * @return When the address book has been created
+	 */
+	Calendar getAddressbookCreated ();
+
+	/**
+	 * Setter for when the address book has been created
+	 * <p>
+	 * @param addressbookCreated When the address book has been created
+	 */
+	void setAddressbookCreated (final Calendar addressbookCreated);
+
+	/**
+	 * This method is called when an address book has been successfully loaded
+	 * from JPA.
+	 * <p>
+	 * @param event Event with address book instance
+	 */
+	void afterAddressbookLoadedEvent (final AddressbookLoadedEvent event);
+
+	/**
+	 * Count all shared address books by given user id
+	 * <p>
+	 * @param user User instance to look for
+	 * <p>
+	 * @return Count of user's shared address books
+	 */
+	Integer countAllUserSharedAddressbooks (final User user);
+
+	/**
+	 * This method is called when a user has successfully logged in his/her
+	 * account.
+	 * <p>
+	 * @param event
+	 */
+	void afterLoginEvent (final UserLoggedInEvent event);
+
+	/**
+	 * Checks if the user is logged in and if so if it matches the current
+	 * address book owner.
+	 * <p>
+	 * @return Whether the owner matches currently logged-in user
+	 */
+	boolean isOwnAddressbook ();
+
+	/**
+	 * Checks if the owner of the current address book is NOT matching the
+	 * logged-in user.
+	 * <p>
+	 * @return Whether the user does NOT match
+	 */
+	boolean isOtherAddressbook ();
+
+	/**
+	 * Getter for address book instance
+	 * <p>
+	 * @return Address book instance
+	 */
+	Addressbook getAddressbook ();
+
+	/**
+	 * Setter for address book instance
+	 * <p>
+	 * @param addressbook Address book instance
+	 */
+	void setAddressbook (final Addressbook addressbook);
+
+	/**
+	 * Retrieves a list of all users this user is not sharing this address book
+	 * with.
+	 * <p>
+	 * @return List of not sharing users
+	 */
+	List<User> allUsersNotSharing ();
+
+	/**
+	 * Checks wether an address book has been loaded by checking the id number.
+	 * <p>
+	 * @return Whether the address book is loaded
+	 */
+	boolean isAddressbookLoaded ();
+}
diff --git a/src/java/org/mxchange/jjobs/beans/country/CountryWebApplicationBean.java b/src/java/org/mxchange/jjobs/beans/country/CountryWebApplicationBean.java
new file mode 100644
index 00000000..b74576c6
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/country/CountryWebApplicationBean.java
@@ -0,0 +1,82 @@
+package org.mxchange.jjobs.beans.country;
+
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.ApplicationScoped;
+import javax.faces.view.facelets.FaceletException;
+import javax.inject.Named;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import org.mxchange.jcountry.data.AddressbookCountrySingletonBeanRemote;
+import org.mxchange.jcountry.data.Country;
+
+/**
+ * A country bean
+ * <p>
+ * @author Roland Haeder<roland@mxchange.org>
+ */
+@Named ("country")
+@ApplicationScoped
+public class CountryWebApplicationBean implements CountryWebApplicationController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 176_985_298_681_742_960L;
+
+	/**
+	 * Remote country EJB
+	 */
+	private AddressbookCountrySingletonBeanRemote countryBean;
+
+	/**
+	 * List of all countries
+	 */
+	private List<Country> countryList;
+
+	/**
+	 * Default constructor
+	 */
+	public CountryWebApplicationBean () {
+		// Try this
+		try {
+			// Get initial context
+			Context context = new InitialContext();
+
+			// Try to lookup the bean
+			this.countryBean = (AddressbookCountrySingletonBeanRemote) context.lookup("ejb/addressbook-singleton-country"); //NOI18N
+		} catch (final NamingException ex) {
+			// Continue to throw
+			throw new FaceletException(ex);
+		}
+	}
+
+	@Override
+	public List<Country> allCountries () {
+		// Return "cached" version
+		return Collections.unmodifiableList(this.countryList);
+	}
+
+	@PostConstruct
+	public void init () {
+		this.countryList = this.countryBean.allCountries();
+	}
+}
diff --git a/src/java/org/mxchange/jjobs/beans/country/CountryWebApplicationController.java b/src/java/org/mxchange/jjobs/beans/country/CountryWebApplicationController.java
new file mode 100644
index 00000000..e72b1929
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/country/CountryWebApplicationController.java
@@ -0,0 +1,36 @@
+package org.mxchange.jjobs.beans.country;
+
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+import java.io.Serializable;
+import java.util.List;
+import org.mxchange.jcountry.data.Country;
+
+/**
+ * An interface for country beans
+ * <p>
+ * @author Roland Haeder<roland@mxchange.org>
+ */
+public interface CountryWebApplicationController extends Serializable {
+
+	/**
+	 * A list of all countries
+	 * <p>
+	 * @return All countries
+	 */
+	List<Country> allCountries ();
+}
diff --git a/src/java/org/mxchange/jjobs/beans/gender/GenderWebApplicationBean.java b/src/java/org/mxchange/jjobs/beans/gender/GenderWebApplicationBean.java
new file mode 100644
index 00000000..87943ab0
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/gender/GenderWebApplicationBean.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.beans.gender;
+
+import java.util.List;
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Named;
+import org.mxchange.jcontacts.contact.gender.Gender;
+import org.mxchange.jcontacts.contact.gender.GenderUtils;
+
+/**
+ * A gender bean
+ * <p>
+ * @author Roland Haeder<roland@mxchange.org>
+ */
+@Named ("gender")
+@ApplicationScoped
+public class GenderWebApplicationBean implements GenderWebApplicationController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 835_482_364_189L;
+
+	/**
+	 * Default constructor
+	 */
+	public GenderWebApplicationBean () {
+	}
+
+	@Override
+	public Gender[] getAllGenders () {
+		// Return it
+		return Gender.values();
+	}
+
+	@Override
+	public List<Gender> getSelectableGenders () {
+		// Init array
+		List<Gender> genders = GenderUtils.selectableGenders();
+
+		// Return it
+		return genders;
+	}
+}
diff --git a/src/java/org/mxchange/jjobs/beans/gender/GenderWebApplicationController.java b/src/java/org/mxchange/jjobs/beans/gender/GenderWebApplicationController.java
new file mode 100644
index 00000000..90280e84
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/gender/GenderWebApplicationController.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.beans.gender;
+
+import java.io.Serializable;
+import java.util.List;
+import org.mxchange.jcontacts.contact.gender.Gender;
+
+/**
+ * An interface for data beans
+ * <p>
+ * @author Roland Haeder<roland@mxchange.org>
+ */
+public interface GenderWebApplicationController extends Serializable {
+
+	/**
+	 * Getter for all genders as array
+	 * <p>
+	 * @return All genders as array
+	 */
+	Gender[] getAllGenders ();
+
+	/**
+	 * Getter for only selectable genders as array, UNKNOWN is not selectable
+	 * <p>
+	 * @return All genders as array
+	 */
+	List<Gender> getSelectableGenders ();
+}
diff --git a/src/java/org/mxchange/jjobs/beans/login/UserLoginWebSessionBean.java b/src/java/org/mxchange/jjobs/beans/login/UserLoginWebSessionBean.java
new file mode 100644
index 00000000..6bd77670
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/login/UserLoginWebSessionBean.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.beans.login;
+
+import java.util.Objects;
+import javax.enterprise.context.SessionScoped;
+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 javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import org.mxchange.jjobs.beans.user.UserWebSessionController;
+import org.mxchange.jusercore.container.login.LoginContainer;
+import org.mxchange.jusercore.container.login.UserLoginContainer;
+import org.mxchange.jusercore.events.login.UserLoggedInEvent;
+import org.mxchange.jusercore.events.login.UserLoginEvent;
+import org.mxchange.jusercore.exceptions.UserNotFoundException;
+import org.mxchange.jusercore.exceptions.UserPasswordMismatchException;
+import org.mxchange.jusercore.exceptions.UserStatusLockedException;
+import org.mxchange.jusercore.exceptions.UserStatusUnconfirmedException;
+import org.mxchange.jusercore.model.login.UserLoginSessionBeanRemote;
+import org.mxchange.jusercore.model.user.User;
+import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
+import org.mxchange.jusercore.model.user.status.UserAccountStatus;
+
+/**
+ * A web bean for user registration
+ * <p>
+ * @author Roland Haeder
+ */
+@Named ("loginController")
+@SessionScoped
+public class UserLoginWebSessionBean implements UserLoginWebSessionController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 47_828_986_719_691_592L;
+
+	/**
+	 * Logged-in user instance
+	 */
+	private User loggedInUser;
+
+	/**
+	 * Reemote register session bean
+	 */
+	private UserLoginSessionBeanRemote loginBean;
+
+	/**
+	 * Event fired when user has logged in
+	 */
+	@Inject
+	@Any
+	private Event<UserLoggedInEvent> loginEvent;
+
+	/**
+	 * Template type for pages that might be displayed in guest area and login
+	 * area. Default is guest area.
+	 */
+	private String templateType = "guest"; //NOI18N
+
+	/**
+	 * User controller
+	 */
+	@Inject
+	private UserWebSessionController userController;
+
+	/**
+	 * Flag whether the user has logged-in, set only from inside
+	 */
+	private boolean userLoggedIn;
+
+	/**
+	 * Default constructor
+	 */
+	public UserLoginWebSessionBean () {
+		try {
+			// Get initial context
+			Context context = new InitialContext();
+
+			// Try to lookup
+			this.loginBean = (UserLoginSessionBeanRemote) context.lookup("ejb/stateless-login"); //NOI18N
+		} catch (final NamingException ex) {
+			// Continue to throw
+			throw new FaceletException(ex);
+		}
+	}
+
+	@Override
+	public String doLogin () {
+		// Get user instance
+		User user = this.userController.createUserInstance();
+
+		// Create login container
+		LoginContainer container = new UserLoginContainer(user, this.userController.getUserPassword());
+
+		try {
+			// Call bean
+			User confirmedUser = this.loginBean.validateUserAccountStatus(container);
+
+			// All fine here so set it here
+			this.setLoggedInUser(confirmedUser);
+
+			// Set template to "login"
+			this.setTemplateType("login"); //NOI18N
+
+			// Fire event away. Keep this last before return statement.
+			this.loginEvent.fire(new UserLoginEvent(confirmedUser));
+
+			// All fine
+			return "login"; //NOI18N
+		} catch (final UserNotFoundException | UserStatusLockedException | UserStatusUnconfirmedException | UserPasswordMismatchException ex) {
+			// Throw again
+			throw new FaceletException(ex);
+		}
+	}
+
+	@Override
+	public User getLoggedInUser () {
+		return this.loggedInUser;
+	}
+
+	@Override
+	public void setLoggedInUser (final User loggedInUser) {
+		this.loggedInUser = loggedInUser;
+	}
+
+	@Override
+	public String getTemplateType () {
+		return this.templateType;
+	}
+
+	@Override
+	public void setTemplateType (final String templateType) {
+		this.templateType = templateType;
+	}
+
+	@Override
+	public boolean isGuest () {
+		return (!this.isUserLoggedIn());
+	}
+
+	@Override
+	public boolean isInvisible () {
+		// Check on login
+		if (!this.isUserLoggedIn()) {
+			// Not logged in!
+			throw new IllegalStateException("isInvisible() has been invoked for a guest."); //NOI18N
+		}
+
+		// Check logged-in first, then invisibility
+		return this.getLoggedInUser().getUserProfileMode().equals(ProfileMode.INVISIBLE);
+	}
+
+	@Override
+	public boolean isUserLoggedIn () {
+		// Trace message
+		// NOISY: System.out.println(MessageFormat.format("UserLoginWebSessionBean:isUserLoggedIn: this.loggedInUser={0},this.templateType={1} - CALLED!", this.getLoggedInUser(), this.getTemplateType()));
+
+		// Compare instance
+		this.userLoggedIn = ((this.getLoggedInUser() instanceof User) && (Objects.equals(this.getLoggedInUser().getUserAccountStatus(), UserAccountStatus.CONFIRMED)));
+
+		// Trace message
+		// NOISY: System.out.println(MessageFormat.format("UserLoginWebSessionBean:isUserLoggedIn: this.userLoggedIn={0} - EXIT!", this.userLoggedIn));
+
+		// Return it
+		return this.userLoggedIn;
+	}
+}
diff --git a/src/java/org/mxchange/jjobs/beans/login/UserLoginWebSessionController.java b/src/java/org/mxchange/jjobs/beans/login/UserLoginWebSessionController.java
new file mode 100644
index 00000000..7e156f8c
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/login/UserLoginWebSessionController.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.beans.login;
+
+import java.io.Serializable;
+import org.mxchange.jusercore.model.user.User;
+
+/**
+ * An interface for registration web controllers
+ * <p>
+ * @author Roland Haeder
+ */
+public interface UserLoginWebSessionController extends Serializable {
+
+	/**
+	 * Getter for template type
+	 * <p>
+	 * @return Template type
+	 */
+	String getTemplateType ();
+
+	/**
+	 * Setter for template type
+	 * <p>
+	 * @param templateType Template type
+	 */
+	void setTemplateType (final String templateType);
+
+	/**
+	 * Logins the user, if the account is found, confirmed and unlocked.
+	 * <p>
+	 * @return Redirect target
+	 */
+	String doLogin ();
+
+	/**
+	 * Getter for logged-in user instance
+	 * <p>
+	 * @return Logged-in user instance
+	 */
+	User getLoggedInUser ();
+
+	/**
+	 * Setter for logged-in user instance
+	 * <p>
+	 * @param loggedInUser Logged-in user instance
+	 */
+	void setLoggedInUser (final User loggedInUser);
+
+	/**
+	 * Checks whether the user is logged-in
+	 * <p>
+	 * @return Whether the user is logged-in
+	 */
+	boolean isUserLoggedIn ();
+
+	/**
+	 * Is this truly a guest?
+	 * <p>
+	 * @return Whether the user is truly a guest
+	 */
+	boolean isGuest ();
+
+	/**
+	 * Whether the currently logged-in user is invisible
+	 * <p>
+	 * @return Whether the currently logged-in user is invisible
+	 */
+	boolean isInvisible ();
+}
diff --git a/src/java/org/mxchange/jjobs/beans/profile/UserProfileWebRequestBean.java b/src/java/org/mxchange/jjobs/beans/profile/UserProfileWebRequestBean.java
new file mode 100644
index 00000000..b692c7fc
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/profile/UserProfileWebRequestBean.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.beans.profile;
+
+import java.text.MessageFormat;
+import javax.enterprise.context.RequestScoped;
+import javax.faces.view.facelets.FaceletException;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jjobs.beans.login.UserLoginWebSessionController;
+import org.mxchange.jjobs.beans.user.UserWebSessionController;
+import org.mxchange.jusercore.exceptions.UserNotFoundException;
+import org.mxchange.jusercore.model.user.User;
+import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
+
+/**
+ * A web request bean for user profiles
+ * <p>
+ * @author Roland Haeder
+ */
+@Named (value = "profileController")
+@RequestScoped
+public class UserProfileWebRequestBean implements UserProfileWebRequestController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 187_687_145_286_710L;
+
+	/**
+	 * Login controller
+	 */
+	@Inject
+	private UserLoginWebSessionController loginController;
+
+	/**
+	 * User instance
+	 */
+	private User user;
+
+	/**
+	 * User controller
+	 */
+	@Inject
+	private UserWebSessionController userController;
+
+	@Override
+	public User getUser () {
+		return this.user;
+	}
+
+	@Override
+	public void setUser (final User user) {
+		this.user = user;
+	}
+
+	@Override
+	public boolean isProfileLinkVisible () {
+		// Check on user
+		if (this.getUser() == null) {
+			/*
+			 * Not set, means wrong invocation of this method as the user
+			 * instance needs to be set first.
+			 */
+			throw new NullPointerException("this.user is null"); //NOI18N
+		} else if (this.getUser().getUserId() == null) {
+			/*
+			 * If the id number is not set it means that the user instance has
+			 * not been persisted and the JPA has not been flushed. Or a
+			 * "virgin" instance (e.g. from registration) has been used.
+			 */
+			throw new NullPointerException("this.user.userId is null"); //NOI18N
+		} else if (this.getUser().getUserId() < 1) {
+			/*
+			 * The id number is set invalid for an unknown reason.
+			 */
+			throw new IllegalArgumentException(MessageFormat.format("this.user.userId={0} is invalid", this.getUser().getUserId())); //NOI18N
+		} else if (this.getUser().getUserProfileMode() == null) {
+			/*
+			 * Possibly an out-dated user profile is being used. This should not
+			 * happen.
+			 */
+			throw new NullPointerException("this.user.userProfileMode is null"); //NOI18N
+		}
+
+		// Get profile mode from user instance (safe now)
+		ProfileMode profileMode = this.getUser().getUserProfileMode();
+
+		// Check all conditions (except for admin)
+		// TODO: Add admin role somehow?
+		return ((profileMode.equals(ProfileMode.PUBLIC)) ||
+				 (this.loginController.isUserLoggedIn()) && (profileMode.equals(ProfileMode.MEMBERS)));
+	}
+
+	@Override
+	public boolean isProfileLinkVisibleById (final Long userId) {
+		// Init user instance
+		User u = null;
+
+		try {
+			// Try to get it
+			u = this.userController.lookupUserById(userId);
+		} catch (final UserNotFoundException ex) {
+			// Throw again
+			throw new FaceletException(ex);
+		}
+
+		// Set it here
+		this.setUser(u);
+
+		// Is it null?
+		if (null == u) {
+			// Not found, not visible.
+			return false;
+		}
+
+		// Ask other method
+		return this.isProfileLinkVisible();
+	}
+
+	@Override
+	public boolean isProfileLinkVisibleByUser (final User user) {
+		// Is it correctly set?
+		if (null == user) {
+			// Throw NPE
+			throw new NullPointerException("user is null");
+		} else if (user.getUserId() == null) {
+			// Throw NPE again
+			throw new NullPointerException("user.userId is null");
+		} else if (user.getUserId() < 1) {
+			// Invalid user id set
+			throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is not valid.", user.getUserId()));
+		}
+
+		// Set user here
+		this.setUser(user);
+
+		// Ask other method
+		return this.isProfileLinkVisible();
+	}
+}
diff --git a/src/java/org/mxchange/jjobs/beans/profile/UserProfileWebRequestController.java b/src/java/org/mxchange/jjobs/beans/profile/UserProfileWebRequestController.java
new file mode 100644
index 00000000..34a5aa37
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/profile/UserProfileWebRequestController.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.beans.profile;
+
+import java.io.Serializable;
+import org.mxchange.jusercore.model.user.User;
+
+/**
+ * A bean interface for user profiles
+ * <p>
+ * @author Roland Haeder
+ */
+public interface UserProfileWebRequestController extends Serializable {
+
+	/**
+	 * Checks if the current user profile link is visible
+	 * <p>
+	 * @return Whether the profile link is visible
+	 */
+	boolean isProfileLinkVisible ();
+
+	/**
+	 * Checks if the user profile link is visible
+	 * <p>
+	 * @param userId User id
+	 * <p>
+	 * @return Whether the profile link is visible
+	 */
+	boolean isProfileLinkVisibleById (final Long userId);
+
+	/**
+	 * Checks if given user's profile is visible
+	 * <p>
+	 * @param user User instance to check
+	 * <p>
+	 * @return Whether the user's profile is visible
+	 */
+	boolean isProfileLinkVisibleByUser (final User user);
+
+	/**
+	 * Getter for user instance
+	 * <p>
+	 * @return User instance
+	 */
+	User getUser ();
+
+	/**
+	 * Setter for user instance
+	 * <p>
+	 * @param user User instance
+	 */
+	void setUser (final User user);
+}
diff --git a/src/java/org/mxchange/jjobs/beans/profilemode/ProfileModeWebApplicationBean.java b/src/java/org/mxchange/jjobs/beans/profilemode/ProfileModeWebApplicationBean.java
new file mode 100644
index 00000000..558cf6b9
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/profilemode/ProfileModeWebApplicationBean.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.beans.profilemode;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Named;
+import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
+
+/**
+ * A profile mode bean
+ * <p>
+ * @author Roland Haeder<roland@mxchange.org>
+ */
+@Named ("profileMode")
+@ApplicationScoped
+public class ProfileModeWebApplicationBean implements ProfileModeWebApplicationController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 835_482_364_189L;
+
+	/**
+	 * Default constructor
+	 */
+	public ProfileModeWebApplicationBean () {
+	}
+
+	@Override
+	public ProfileMode[] getAllProfileModes () {
+		// Return it
+		return ProfileMode.values();
+	}
+}
diff --git a/src/java/org/mxchange/jjobs/beans/profilemode/ProfileModeWebApplicationController.java b/src/java/org/mxchange/jjobs/beans/profilemode/ProfileModeWebApplicationController.java
new file mode 100644
index 00000000..b2e4d727
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/profilemode/ProfileModeWebApplicationController.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.beans.profilemode;
+
+import java.io.Serializable;
+import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
+
+/**
+ * An interface for data beans
+ * <p>
+ * @author Roland Haeder<roland@mxchange.org>
+ */
+public interface ProfileModeWebApplicationController extends Serializable {
+
+	/**
+	 * Getter for all genders as array
+	 * <p>
+	 * @return All genders as array
+	 */
+	ProfileMode[] getAllProfileModes ();
+}
diff --git a/src/java/org/mxchange/jjobs/beans/register/UserRegisterWebSessionBean.java b/src/java/org/mxchange/jjobs/beans/register/UserRegisterWebSessionBean.java
new file mode 100644
index 00000000..97857f45
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/register/UserRegisterWebSessionBean.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.beans.register;
+
+import java.text.MessageFormat;
+import javax.enterprise.context.SessionScoped;
+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 javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import org.mxchange.jjobs.beans.user.UserWebSessionController;
+import org.mxchange.jusercore.events.registration.RegisteredUserEvent;
+import org.mxchange.jusercore.events.registration.UserRegisteredEvent;
+import org.mxchange.jusercore.exceptions.DataRepeatMismatchException;
+import org.mxchange.jusercore.exceptions.EmailAddressAlreadyRegisteredException;
+import org.mxchange.jusercore.exceptions.UserNameAlreadyRegisteredException;
+import org.mxchange.jusercore.model.register.UserRegistrationSessionBeanRemote;
+import org.mxchange.jusercore.model.user.User;
+import org.mxchange.jusercore.model.user.UserUtils;
+import org.mxchange.jusercore.model.user.status.UserAccountStatus;
+
+/**
+ * A web bean for user registration
+ * <p>
+ * @author Roland Haeder
+ */
+@Named ("registerController")
+@SessionScoped
+public class UserRegisterWebSessionBean implements UserRegisterWebSessionController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 47_828_986_719_691_592L;
+
+	/**
+	 * Reemote register session bean
+	 */
+	private UserRegistrationSessionBeanRemote registerBean;
+
+	/**
+	 * An en event fireable when a new user has registered
+	 */
+	@Inject
+	@Any
+	private Event<UserRegisteredEvent> registeredEvent;
+
+	/**
+	 * User controller
+	 */
+	@Inject
+	private UserWebSessionController userController;
+
+	/**
+	 * Default constructor
+	 */
+	public UserRegisterWebSessionBean () {
+		try {
+			// Get initial context
+			Context context = new InitialContext();
+
+			// Try to lookup
+			this.registerBean = (UserRegistrationSessionBeanRemote) context.lookup("ejb/stateless-register"); //NOI18N
+		} catch (final NamingException ex) {
+			// Continue to throw
+			throw new FaceletException(ex);
+		}
+	}
+
+	@Override
+	public String doRegister () {
+		// Get user instance
+		User user = this.userController.createUserInstance();
+
+		// Is the user already used?
+		if (null == user) {
+			// user must be set
+			throw new NullPointerException("user is null"); //NOI18N
+		} else if (!this.userController.isRequiredPersonalDataSet()) {
+			// Not all required fields are set
+			throw new FaceletException("Not all required fields are set."); //NOI18N
+		} else if (this.userController.isUserNameRegistered(user)) {
+			// User name is already used
+			throw new FaceletException(new UserNameAlreadyRegisteredException(user));
+		} else if (this.userController.isEmailAddressRegistered(user)) {
+			// Email address has already been taken
+			throw new FaceletException(new EmailAddressAlreadyRegisteredException(user));
+		} else if (!this.userController.isSameEmailAddressEntered()) {
+			// Not same email address entered
+			throw new FaceletException(new DataRepeatMismatchException(MessageFormat.format("Email addresses not matching: {0} != {1}", this.userController.getEmailAddress(), this.userController.getEmailAddressRepeat()))); //NOI18N
+		} else if (!this.userController.isSamePasswordEntered()) {
+			// Not same password entered
+			throw new FaceletException(new DataRepeatMismatchException("Passwords not matching.")); //NOI18N
+		}
+
+		// Encrypt password
+		String encryptedPassword = UserUtils.encryptPassword(this.userController.getUserPassword());
+
+		// Set it here
+		user.setUserEncryptedPassword(encryptedPassword);
+
+		// For debugging/programming only:
+		user.setUserAccountStatus(UserAccountStatus.CONFIRMED);
+
+		try {
+			// Call bean
+			User registeredUser = this.registerBean.registerUser(user);
+
+			// Fire event
+			this.registeredEvent.fire(new RegisteredUserEvent(registeredUser));
+
+			// All fine, redirect to proper page
+			return "register_done"; //NOI18N
+		} catch (final UserNameAlreadyRegisteredException | EmailAddressAlreadyRegisteredException ex) {
+			// Continue to throw
+			throw new FaceletException(ex);
+		}
+	}
+}
diff --git a/src/java/org/mxchange/jjobs/beans/register/UserRegisterWebSessionController.java b/src/java/org/mxchange/jjobs/beans/register/UserRegisterWebSessionController.java
new file mode 100644
index 00000000..e5f6e0dd
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/register/UserRegisterWebSessionController.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.beans.register;
+
+import java.io.Serializable;
+
+/**
+ * An interface for registration web controllers
+ * <p>
+ * @author Roland Haeder
+ */
+public interface UserRegisterWebSessionController extends Serializable {
+
+	/**
+	 * Registers the user, if not found. Otherwise this method should throw an
+	 * exception.
+	 * <p>
+	 * @return Redirection target
+	 */
+	String doRegister ();
+}
diff --git a/src/java/org/mxchange/jjobs/beans/shares/SharesWebSessionBean.java b/src/java/org/mxchange/jjobs/beans/shares/SharesWebSessionBean.java
new file mode 100644
index 00000000..183cbd73
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/shares/SharesWebSessionBean.java
@@ -0,0 +1,341 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.beans.shares;
+
+import java.text.MessageFormat;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.SessionScoped;
+import javax.enterprise.event.Event;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Any;
+import javax.faces.view.facelets.FaceletException;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import org.mxchange.addressbook.events.sharing.AddressbookSharingEvent;
+import org.mxchange.addressbook.events.sharing.StartedAddressbookSharingEvent;
+import org.mxchange.addressbook.events.sharing.type.SharingType;
+import org.mxchange.addressbook.exceptions.UserAlreadySharingAddressbookException;
+import org.mxchange.addressbook.model.addressbook.Addressbook;
+import org.mxchange.addressbook.model.addressbook.shared.ShareableAddressbook;
+import org.mxchange.addressbook.model.shared.SharedAddressbooksSessionBeanRemote;
+import org.mxchange.jjobs.beans.login.UserLoginWebSessionController;
+import org.mxchange.jusercore.events.login.UserLoggedInEvent;
+import org.mxchange.jusercore.model.user.User;
+import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
+
+/**
+ * A bean for sharing address books with other users
+ * <p>
+ * @author Roland Haeder
+ */
+@Named (value = "shareController")
+@SessionScoped
+public class SharesWebSessionBean implements SharesWebSessionController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 19_868_976_871_976_780L;
+
+	/**
+	 * Cached flag whether the user is sharing address books
+	 */
+	private Boolean isUserSharing = null;
+
+	/**
+	 * Login controller injection
+	 */
+	@Inject
+	private UserLoginWebSessionController loginController;
+
+	/**
+	 * Share instance
+	 */
+	private ShareableAddressbook share;
+
+	/**
+	 * Remote bean for sharing address books
+	 */
+	private SharedAddressbooksSessionBeanRemote shareBean;
+
+	/**
+	 * A list of all user's shared (with others) address books
+	 */
+	private List<ShareableAddressbook> sharedAddressbooks;
+
+	/**
+	 * User id of sharee
+	 */
+	private Long shareeUserId;
+
+	/**
+	 * An event triggered when address book sharing starts or ends
+	 */
+	@Inject
+	@Any
+	private Event<AddressbookSharingEvent> sharingEvent;
+
+	/**
+	 * Default constructor
+	 */
+	public SharesWebSessionBean () {
+		// Try it
+		try {
+			// Get initial context
+			Context context = new InitialContext();
+
+			// Look up bean
+			this.shareBean = (SharedAddressbooksSessionBeanRemote) context.lookup("ejb/stateless-share"); //NOI18N
+		} catch (final NamingException ex) {
+			// Continue to throw
+			throw new FaceletException(ex);
+		}
+	}
+
+	@Override
+	public void afterAdressbookShareEnded (final @Observes AddressbookSharingEvent event) {
+		// Validate parameter
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getSharingType() == null) {
+			// Throw NPE
+			throw new NullPointerException("event.sharingType is null"); //NOI18N
+		} else if (event.getSharingType() != SharingType.ENDED) {
+			// Wrong event
+			return;
+		}
+
+		// Validate event
+		this.validateEvent(event);
+
+		// Add it to list
+		this.sharedAddressbooks.remove(event.getShareableAddressbook());
+	}
+
+	@Override
+	public void afterAdressbookShareStarted (final @Observes AddressbookSharingEvent event) {
+		// Validate parameter
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getSharingType() == null) {
+			// Throw NPE
+			throw new NullPointerException("event.sharingType is null"); //NOI18N
+		} else if (event.getSharingType() != SharingType.STARTED) {
+			// Wrong event
+			return;
+		}
+
+		// Validate event
+		this.validateEvent(event);
+
+		// Add it to list
+		this.sharedAddressbooks.add(event.getShareableAddressbook());
+	}
+
+	@Override
+	public void afterLoginEvent (final @Observes UserLoggedInEvent event) {
+		// Is the user logged in?
+		if (null == event) {
+			// Is null
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUser() == null) {
+			// user is null
+			throw new NullPointerException("event.user is null"); //NOI18N
+		}
+
+		// Init share list
+		this.sharedAddressbooks = this.shareBean.allSharedAddressbooks(event.getUser());
+	}
+
+	@Override
+	public List<ShareableAddressbook> allShares () {
+		// Is the user logged in?
+		if (!this.loginController.isUserLoggedIn()) {
+			// Not logged in
+			throw new FaceletException("This method can only be called as logged-in user."); //NOI18N
+		}
+
+		return Collections.unmodifiableList(this.sharedAddressbooks);
+	}
+
+	@Override
+	public ShareableAddressbook getShare () {
+		return this.share;
+	}
+
+	@Override
+	public void setShare (final ShareableAddressbook share) {
+		this.share = share;
+	}
+
+	@Override
+	public Long getShareeUserId () {
+		return this.shareeUserId;
+	}
+
+	@Override
+	public void setShareeUserId (final Long shareeUserId) {
+		this.shareeUserId = shareeUserId;
+	}
+
+	@PostConstruct
+	public void init () {
+	}
+
+	@Override
+	public boolean isShareeUserIdEmpty () {
+		return (!this.isShareeUserIdSet());
+	}
+
+	@Override
+	public boolean isShareeUserIdSet () {
+		return ((this.getShareeUserId() instanceof Long) && (this.getShareeUserId() > 0));
+	}
+
+	@Override
+	public boolean isSharingAddressbooks () {
+		// Only to be called for logged-in users
+		if (!this.loginController.isUserLoggedIn()) {
+			// Not logged in
+			throw new FaceletException("This method can only be called as logged-in user."); //NOI18N
+		} else if (this.isUserSharing instanceof Boolean) {
+			// Return cached value
+			return this.isUserSharing;
+		}
+
+		// Call the proper bean
+		this.isUserSharing = this.shareBean.isUserSharingAddressbooks(this.loginController.getLoggedInUser());
+
+		// Return it
+		return this.isUserSharing;
+	}
+
+	@Override
+	public String startSharing (final User user, final Addressbook addressbook) {
+		// Check conditions
+		if (!this.loginController.isUserLoggedIn()) {
+			// No, then throw exception
+			throw new FaceletException("This method can only be called as logged-in user."); //NOI18N
+		} else if (null == user) {
+			// Throw NPE
+			throw new NullPointerException("user is null"); //NOI18N
+		} else if (user.getUserId() == null) {
+			// Throw NPE again
+			throw new NullPointerException("user.userId is null"); //NOI18N
+		} else if (user.getUserId() < 1) {
+			// Invalid id number
+			throw new IllegalStateException(MessageFormat.format("user.userId={0} is invalid", user.getUserId())); //NOI18N
+		} else if (Objects.equals(user, this.loginController.getLoggedInUser())) {
+			// Sharing with yourself!
+			throw new IllegalStateException("User tries to share with himself."); //NOI18N
+		} else if (null == addressbook) {
+			// Throw NPE again
+			throw new NullPointerException("addressbook is null"); //NOI18N
+		} else if (addressbook.getAddressbookId() == null) {
+			// Throw NPE again
+			throw new NullPointerException("addressbook.addressbookId is null"); //NOI18N
+		} else if (addressbook.getAddressbookId() < 1) {
+			// Invalid id number
+			throw new IllegalArgumentException(MessageFormat.format("addressbook.addressbookId={0} is invalid.", addressbook.getAddressbookId())); //NOI18N
+		} else if (!Objects.equals(addressbook.getAddressbookUser(), this.loginController.getLoggedInUser())) {
+			// Not the same user!
+			throw new IllegalStateException(MessageFormat.format("Address book id {0} owner id {1} mismatching logged-in user id {2}", addressbook.getAddressbookId(), addressbook.getAddressbookUser().getUserId(), this.loginController.getLoggedInUser().getUserId())); //NOI18N
+		} else if (this.loginController.getLoggedInUser().getUserProfileMode() == ProfileMode.INVISIBLE) {
+			// User is invisible
+			throw new FaceletException(MessageFormat.format("user {0} is invisible and cannot start sharing address books.", this.loginController.getLoggedInUser().getUserId())); //NOI18N
+		} else if (user.getUserProfileMode() == ProfileMode.INVISIBLE) {
+			// User is invisible
+			throw new FaceletException(MessageFormat.format("user {0} is invisible and cannot be selected for sharing.", user.getUserId())); //NOI18N
+		}
+
+		try {
+			// Init sharing
+			ShareableAddressbook shared = this.shareBean.startSharing(user, addressbook);
+
+			// TODO Set it here
+			this.setShare(shared);
+
+			/// Trigger event
+			this.sharingEvent.fire(new StartedAddressbookSharingEvent(shared));
+		} catch (final UserAlreadySharingAddressbookException ex) {
+			// Throw again
+			throw new FaceletException(ex);
+		}
+
+		// TODO Unfinished
+		return null;
+	}
+
+	/**
+	 * Validates given event for all values and throws exceptions
+	 * <p>
+	 * @param event Event to validate
+	 */
+	private void validateEvent (final AddressbookSharingEvent event) {
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getSharingType() == null) {
+			// Throw NPE
+			throw new NullPointerException("event.sharingType is null"); //NOI18N
+		} else if (event.getShareableAddressbook() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.shareableAddressbook is null"); //NOI18N
+		} else if (event.getShareableAddressbook().getShareId() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.shareableAddressbook.shareId is null"); //NOI18N
+		} else if (event.getShareableAddressbook().getShareId() < 1) {
+			// Throw NPE again
+			throw new IllegalArgumentException(MessageFormat.format("event.shareableAddressbook.shareId={0} is invalid", event.getShareableAddressbook().getShareId())); //NOI18N
+		} else if (event.getShareableAddressbook().getShareAddressbook() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.shareableAddressbook.shareAddressbook is null"); //NOI18N
+		} else if (event.getShareableAddressbook().getShareAddressbook().getAddressbookId() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.shareableAddressbook.shareAddressbook.addressbookId is null"); //NOI18N
+		} else if (event.getShareableAddressbook().getShareAddressbook().getAddressbookId() < 1) {
+			// Throw NPE again
+			throw new IllegalArgumentException(MessageFormat.format("event.shareableAddressbook.shareAddressbook.addressbookId={0} is invalid", event.getShareableAddressbook().getShareAddressbook().getAddressbookId())); //NOI18N
+		} else if (event.getShareableAddressbook().getShareUserOwner() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.shareableAddressbook.shareUserOwner is null"); //NOI18N
+		} else if (event.getShareableAddressbook().getShareUserOwner().getUserId() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.shareableAddressbook.shareUserOwner.userId is null"); //NOI18N
+		} else if (event.getShareableAddressbook().getShareUserOwner().getUserId() < 1) {
+			// Throw NPE again
+			throw new IllegalArgumentException(MessageFormat.format("event.shareableAddressbook.shareUserOwner.userId={0} is invalid", event.getShareableAddressbook().getShareUserOwner().getUserId())); //NOI18N
+		} else if (event.getShareableAddressbook().getShareUserSharee() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.shareableAddressbook.shareUserSharee is null"); //NOI18N
+		} else if (event.getShareableAddressbook().getShareUserSharee().getUserId() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.shareableAddressbook.shareUserSharee.userId is null"); //NOI18N
+		} else if (event.getShareableAddressbook().getShareUserSharee().getUserId() < 1) {
+			// Throw NPE again
+			throw new IllegalArgumentException(MessageFormat.format("event.shareableAddressbook.shareUserSharee.userId={0} is invalid", event.getShareableAddressbook().getShareUserOwner().getUserId())); //NOI18N
+		}
+	}
+}
diff --git a/src/java/org/mxchange/jjobs/beans/shares/SharesWebSessionController.java b/src/java/org/mxchange/jjobs/beans/shares/SharesWebSessionController.java
new file mode 100644
index 00000000..0fb27e75
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/shares/SharesWebSessionController.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.beans.shares;
+
+import java.io.Serializable;
+import java.util.List;
+import org.mxchange.addressbook.events.sharing.AddressbookSharingEvent;
+import org.mxchange.addressbook.model.addressbook.Addressbook;
+import org.mxchange.addressbook.model.addressbook.shared.ShareableAddressbook;
+import org.mxchange.jusercore.events.login.UserLoggedInEvent;
+import org.mxchange.jusercore.model.user.User;
+
+/**
+ * Controller interface sharing address books
+ * <p>
+ * @author Roland Haeder
+ */
+public interface SharesWebSessionController extends Serializable {
+
+	/**
+	 * Observer method for ended sharing events
+	 * <p>
+	 * @param event Event instance
+	 */
+	void afterAdressbookShareEnded (final AddressbookSharingEvent event);
+
+	/**
+	 * Observer method for started sharing events
+	 * <p>
+	 * @param event Event instance
+	 */
+	void afterAdressbookShareStarted (final AddressbookSharingEvent event);
+
+	/**
+	 * This method is called when a user has successfully logged in his/her
+	 * account.
+	 * <p>
+	 * @param event
+	 */
+	void afterLoginEvent (final UserLoggedInEvent event);
+
+	/**
+	 * Returns a list of all address books the user is sharing with others.
+	 * <p>
+	 * @return List of all shared address books
+	 */
+	List<ShareableAddressbook> allShares ();
+
+	/**
+	 * Getter for share instance
+	 * <p>
+	 * @return Share instance
+	 */
+	ShareableAddressbook getShare ();
+
+	/**
+	 * Setter for share instance
+	 * <p>
+	 * @param share Share instance
+	 */
+	void setShare (final ShareableAddressbook share);
+
+	/**
+	 * Getter for sharee's user id
+	 * <p>
+	 * @return Sharee's user id
+	 */
+	Long getShareeUserId ();
+
+	/**
+	 * Setter for sharee's user id
+	 * <p>
+	 * @param shareeUserId Sharee's user id
+	 */
+	void setShareeUserId (final Long shareeUserId);
+
+	/**
+	 * Checks if the sharee's user id is empty.
+	 * <p>
+	 * @return Whether the sharee's user id is empty.
+	 */
+	boolean isShareeUserIdEmpty ();
+
+	/**
+	 * Checks whether the sharee's user id is set
+	 * <p>
+	 * @return Whether the sharee's user id is set
+	 */
+	boolean isShareeUserIdSet ();
+
+	/**
+	 * Checks wether the current user is sharing address books with others
+	 * <p>
+	 * @return Whether the current user is sharing address books
+	 */
+	boolean isSharingAddressbooks ();
+
+	/**
+	 * Starts an address book share between currently logged-in user and
+	 * assigned user for current address book.
+	 * <p>
+	 * @param user User instance
+	 * @param addressbook Address book instance
+	 * @return Redirect target
+	 */
+	String startSharing (final User user, final Addressbook addressbook);
+}
diff --git a/src/java/org/mxchange/jjobs/beans/smsprovider/SmsProviderWebApplicationBean.java b/src/java/org/mxchange/jjobs/beans/smsprovider/SmsProviderWebApplicationBean.java
new file mode 100644
index 00000000..64bdc56b
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/smsprovider/SmsProviderWebApplicationBean.java
@@ -0,0 +1,82 @@
+package org.mxchange.jjobs.beans.smsprovider;
+
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.ApplicationScoped;
+import javax.faces.view.facelets.FaceletException;
+import javax.inject.Named;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import org.mxchange.jphone.phonenumbers.smsprovider.AddressbookSmsProviderSingletonBeanRemote;
+import org.mxchange.jphone.phonenumbers.smsprovider.SmsProvider;
+
+/**
+ * A SMS provider bean
+ * <p>
+ * @author Roland Haeder<roland@mxchange.org>
+ */
+@Named ("cellphone")
+@ApplicationScoped
+public class SmsProviderWebApplicationBean implements SmsProviderWebApplicationController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 176_985_298_681_742_960L;
+
+	/**
+	 * Remote country EJB
+	 */
+	private AddressbookSmsProviderSingletonBeanRemote cellphoneBean;
+
+	/**
+	 * List of all countries
+	 */
+	private List<SmsProvider> cellphoneList;
+
+	/**
+	 * Default constructor
+	 */
+	public SmsProviderWebApplicationBean () {
+		// Try this
+		try {
+			// Get initial context
+			Context context = new InitialContext();
+
+			// Try to lookup the bean
+			this.cellphoneBean = (AddressbookSmsProviderSingletonBeanRemote) context.lookup("ejb/addressbook-singleton-smsprovider"); //NOI18N
+		} catch (final NamingException ex) {
+			// Continue to throw
+			throw new FaceletException(ex);
+		}
+	}
+
+	@Override
+	public List<SmsProvider> allSmsProvider () {
+		// Return "cached" version
+		return Collections.unmodifiableList(this.cellphoneList);
+	}
+
+	@PostConstruct
+	public void init () {
+		this.cellphoneList = this.cellphoneBean.allSmsProvider();
+	}
+}
diff --git a/src/java/org/mxchange/jjobs/beans/smsprovider/SmsProviderWebApplicationController.java b/src/java/org/mxchange/jjobs/beans/smsprovider/SmsProviderWebApplicationController.java
new file mode 100644
index 00000000..cb347283
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/smsprovider/SmsProviderWebApplicationController.java
@@ -0,0 +1,36 @@
+package org.mxchange.jjobs.beans.smsprovider;
+
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+import java.io.Serializable;
+import java.util.List;
+import org.mxchange.jphone.phonenumbers.smsprovider.SmsProvider;
+
+/**
+ * An interface for country beans
+ * <p>
+ * @author Roland Haeder<roland@mxchange.org>
+ */
+public interface SmsProviderWebApplicationController extends Serializable {
+
+	/**
+	 * A list of all countries
+	 * <p>
+	 * @return All countries
+	 */
+	List<SmsProvider> allSmsProvider ();
+}
diff --git a/src/java/org/mxchange/jjobs/beans/user/UserWebSessionBean.java b/src/java/org/mxchange/jjobs/beans/user/UserWebSessionBean.java
new file mode 100644
index 00000000..65f17ca2
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/user/UserWebSessionBean.java
@@ -0,0 +1,866 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.beans.user;
+
+import java.text.MessageFormat;
+import java.util.Collections;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.SessionScoped;
+import javax.enterprise.event.Observes;
+import javax.faces.view.facelets.FaceletException;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import org.mxchange.jjobs.beans.login.UserLoginWebSessionController;
+import org.mxchange.jcontacts.contact.Contact;
+import org.mxchange.jcontacts.contact.UserContact;
+import org.mxchange.jcontacts.contact.gender.Gender;
+import org.mxchange.jcountry.data.Country;
+import org.mxchange.jphone.phonenumbers.cellphone.CellphoneNumber;
+import org.mxchange.jphone.phonenumbers.cellphone.DialableCellphoneNumber;
+import org.mxchange.jphone.phonenumbers.fax.DialableFaxNumber;
+import org.mxchange.jphone.phonenumbers.fax.FaxNumber;
+import org.mxchange.jphone.phonenumbers.landline.DialableLandLineNumber;
+import org.mxchange.jphone.phonenumbers.landline.LandLineNumber;
+import org.mxchange.jphone.phonenumbers.smsprovider.SmsProvider;
+import org.mxchange.jusercore.events.login.UserLoggedInEvent;
+import org.mxchange.jusercore.events.registration.UserRegisteredEvent;
+import org.mxchange.jusercore.exceptions.UserNotFoundException;
+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;
+
+/**
+ * A user bean (controller)
+ * <p>
+ * @author Roland Haeder<roland@mxchange.org>
+ */
+@Named ("userController")
+@SessionScoped
+public class UserWebSessionBean implements UserWebSessionController {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 542_145_347_916L;
+
+	/////////////////////// Properties /////////////////////
+	/**
+	 * Birth day
+	 */
+	private Date birthday;
+
+	/**
+	 * Cellphone number's carrier
+	 */
+	private SmsProvider cellphoneCarrier;
+
+	/**
+	 * Cellphone number
+	 */
+	private Long cellphoneNumber;
+
+	/**
+	 * City
+	 */
+	private String city;
+
+	/**
+	 * Optional comments
+	 */
+	private String comment;
+
+	/**
+	 * Country instance
+	 */
+	private Country country;
+
+	/**
+	 * Email address
+	 */
+	private String emailAddress;
+
+	/**
+	 * Email address list
+	 */
+	private List<String> emailAddressList;
+
+	/**
+	 * Email address repeated
+	 */
+	private String emailAddressRepeat;
+
+	/**
+	 * Family name
+	 */
+	private String familyName;
+
+	/**
+	 * Fax number's area code
+	 */
+	private Integer faxAreaCode;
+
+	/**
+	 * Country instance for fax number
+	 */
+	private Country faxCountry;
+
+	/**
+	 * Fax number
+	 */
+	private Long faxNumber;
+
+	/**
+	 * First name
+	 */
+	private String firstName;
+
+	/**
+	 * Gender instance
+	 */
+	private Gender gender;
+
+	/**
+	 * House number
+	 */
+	private Short houseNumber;
+
+	/**
+	 * Phone number area code
+	 */
+	private Integer phoneAreaCode;
+
+	/**
+	 * Country instance for phone number
+	 */
+	private Country phoneCountry;
+
+	/**
+	 * Phone number
+	 */
+	private Long phoneNumber;
+
+	/**
+	 * Street
+	 */
+	private String street;
+
+	/**
+	 * Remote user bean
+	 */
+	private final UserSessionBeanRemote userBean;
+
+	/**
+	 * User id
+	 */
+	private Long userId;
+
+	/**
+	 * User name
+	 */
+	private String userName;
+
+	/**
+	 * User name list
+	 */
+	private List<String> userNameList;
+
+	/**
+	 * User password (unencrypted from web form)
+	 */
+	private String userPassword;
+
+	/**
+	 * User password repeated (unencrypted from web form)
+	 */
+	private String userPasswordRepeat;
+
+	/**
+	 * Whether the user wants a public profile
+	 */
+	private ProfileMode userProfileMode;
+
+	/**
+	 * ZIP code
+	 */
+	private Integer zipCode;
+
+	/**
+	 * A list of all public user profiles
+	 */
+	private List<User> visibleUserList;
+
+	/**
+	 * Login bean (controller)
+	 */
+	@Inject
+	private UserLoginWebSessionController loginController;
+
+	/**
+	 * Default constructor
+	 */
+	public UserWebSessionBean () {
+		// Set gender to UNKNOWN
+		this.gender = Gender.UNKNOWN;
+
+		// Try it
+		try {
+			// Get initial context
+			Context context = new InitialContext();
+
+			// Try to lookup
+			this.userBean = (UserSessionBeanRemote) context.lookup("ejb/stateless-user"); //NOI18N
+		} catch (final NamingException e) {
+			// Throw again
+			throw new FaceletException(e);
+		}
+	}
+
+	@Override
+	public void afterUserLogin (final @Observes UserLoggedInEvent event) {
+		// Trace message
+		System.out.println(MessageFormat.format("UserWebBean:afterUserLogin: event={0} - CALLED!", event)); //NOI18N
+
+		// event should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUser() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.user is null"); //NOI18N
+		} else if (event.getUser().getUserId() == null) {
+			// userId is null
+			throw new NullPointerException("event.user.userId is null"); //NOI18N
+		} else if (event.getUser().getUserId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUser(), event.getUser().getUserId())); //NOI18N
+		}
+
+		// Re-initialize list
+		this.visibleUserList = this.userBean.allMemberPublicVisibleUsers();
+
+		// Trace message
+		System.out.println(MessageFormat.format("UserWebBean:afterUserLogin: this.visibleUserList.size()={0} - EXIT!", this.visibleUserList.size())); //NOI18N
+	}
+
+	@Override
+	public void afterRegistrationEvent (final @Observes UserRegisteredEvent event) {
+		// Trace message
+		System.out.println(MessageFormat.format("UserWebBean:afterRegistration: event={0} - CALLED!", event)); //NOI18N
+
+		// event should not be null
+		if (null == event) {
+			// Throw NPE
+			throw new NullPointerException("event is null"); //NOI18N
+		} else if (event.getUser() == null) {
+			// Throw NPE again
+			throw new NullPointerException("event.user is null"); //NOI18N
+		} else if (event.getUser().getUserId() == null) {
+			// userId is null
+			throw new NullPointerException("event.user.userId is null"); //NOI18N
+		} else if (event.getUser().getUserId() < 1) {
+			// Not avalid id
+			throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUser(), event.getUser().getUserId())); //NOI18N
+		}
+
+		// Get user instance
+		User registeredUser = event.getUser();
+
+		// Debug message
+		System.out.println(MessageFormat.format("UserWebBean:afterRegistration: registeredUser={0}", registeredUser)); //NOI18N
+
+		// Copy all data from registered->user
+		this.copyUser(registeredUser);
+
+		// Add user name and email address
+		this.addUserNameEmailAddress(registeredUser);
+
+		// Clear all data
+		this.clearData();
+
+		// Set user id again
+		this.setUserId(registeredUser.getUserId());
+
+		// Is the account public?
+		if (registeredUser.getUserProfileMode().equals(ProfileMode.PUBLIC)) {
+			// Also add it to this list
+			this.visibleUserList.add(registeredUser);
+		}
+
+		// Trace message
+		System.out.println("UserWebBean:afterRegistration: EXIT!"); //NOI18N
+	}
+
+	@Override
+	public List<User> allVisibleUsers () {
+		// Return it
+		return Collections.unmodifiableList(this.visibleUserList);
+	}
+
+	@Override
+	public User createUserInstance () {
+		// User message
+		//this.getLogger().logTrace("createUserInstance: CALLED!");
+
+		// Required personal data must be set
+		assert (this.isRequiredPersonalDataSet()) : "not all personal data is set"; //NOI18N
+
+		// Create new user instance
+		User user = new LoginUser();
+		user.setUserName(this.getUserName());
+		user.setUserProfileMode(this.getUserProfileMode());
+		user.setUserCreated(new GregorianCalendar());
+
+		// Generate phone number
+		DialableLandLineNumber phone = new LandLineNumber(this.getPhoneCountry(), this.getPhoneAreaCode(), this.getPhoneNumber(), new GregorianCalendar());
+		DialableCellphoneNumber cellphone = new CellphoneNumber(this.getCellphoneCarrier(), this.getCellphoneNumber(), new GregorianCalendar());
+		DialableFaxNumber fax = new FaxNumber(this.getFaxCountry(), this.getFaxAreaCode(), this.getFaxNumber(), new GregorianCalendar());
+
+		// Create new contact
+		Contact contact = new UserContact(this.getGender(), this.getFirstName(), this.getFamilyName());
+		contact.setContactStreet(this.getStreet());
+		contact.setContactHouseNumber(this.getHouseNumber());
+		contact.setContactZipCode(this.getZipCode());
+		contact.setContactCity(this.getCity());
+		contact.setContactCountry(this.getCountry());
+		contact.setContactEmailAddress(this.getEmailAddress());
+
+		// Don't set null or wrong references
+		if ((phone instanceof DialableLandLineNumber) && (phone.getPhoneCountry() instanceof Country) && (this.getPhoneAreaCode() != null) && (this.getPhoneNumber() != null) && (this.getPhoneAreaCode() > 0) && (this.getPhoneNumber() > 0)) {
+			// Now the number must be given
+			if (phone.getPhoneAreaCode() == null) {
+				// Is null
+				throw new NullPointerException("phone.phoneAreaCode is null"); //NOI18N
+			} else if (phone.getPhoneAreaCode() < 1) {
+				// Abort here
+				throw new IllegalArgumentException("phone.phoneAreaCode is zero or below."); //NOI18N
+			} else if (phone.getPhoneNumber() == null) {
+				// Is null
+				throw new NullPointerException("phone.phoneNumber is null"); //NOI18N
+			} else if (phone.getPhoneNumber() < 1) {
+				// Abort here
+				throw new IllegalArgumentException("phone.phoneNumber is zero or below."); //NOI18N
+			}
+
+			// Set phone number
+			contact.setContactPhoneNumber(phone);
+		}
+
+		// 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 ((cellphone instanceof DialableCellphoneNumber) && (this.getCellphoneCarrier() instanceof SmsProvider) && (this.getCellphoneNumber() != null) && (this.getCellphoneNumber() > 0)) {
+			// Is the number set?
+			if (cellphone.getPhoneNumber() == null) {
+				// Is null
+				throw new NullPointerException("cellphone.phoneNumber is null"); //NOI18N
+			} else if (cellphone.getPhoneNumber() < 1) {
+				// Abort here
+				throw new IllegalArgumentException("cellphone.phoneNumber is zero or below."); //NOI18N
+			}
+
+			// Set cellphone number
+			contact.setContactCellphoneNumber(cellphone);
+		}
+
+		contact.setContactBirthday(this.getBirthday());
+		contact.setContactComment(this.getComment());
+
+		// Created timestamp and ownContact
+		contact.setContactCreated(new GregorianCalendar());
+		contact.setContactOwnContact(Boolean.TRUE);
+
+		// Set contact in user
+		user.setUserContact(contact);
+
+		// Trace message
+		//this.getLogger().logTrace(MessageFormat.format("createUserInstance: user={0} - EXIT!", user));
+		// Return it
+		return user;
+	}
+
+	@Override
+	public Date getBirthday () {
+		return this.birthday;
+	}
+
+	@Override
+	public void setBirthday (final Date birthday) {
+		this.birthday = birthday;
+	}
+
+	@Override
+	public SmsProvider getCellphoneCarrier () {
+		return this.cellphoneCarrier;
+	}
+
+	@Override
+	public void setCellphoneCarrier (final SmsProvider cellphoneCarrier) {
+		this.cellphoneCarrier = cellphoneCarrier;
+	}
+
+	@Override
+	public Long getCellphoneNumber () {
+		return this.cellphoneNumber;
+	}
+
+	@Override
+	public void setCellphoneNumber (Long cellphoneNumber) {
+		this.cellphoneNumber = cellphoneNumber;
+	}
+
+	@Override
+	public String getCity () {
+		return this.city;
+	}
+
+	@Override
+	public void setCity (final String city) {
+		this.city = city;
+	}
+
+	@Override
+	public String getComment () {
+		return this.comment;
+	}
+
+	@Override
+	public void setComment (final String comment) {
+		this.comment = comment;
+	}
+
+	@Override
+	public Country getCountry () {
+		return this.country;
+	}
+
+	@Override
+	public void setCountry (final Country country) {
+		this.country = country;
+	}
+
+	@Override
+	public String getEmailAddress () {
+		return this.emailAddress;
+	}
+
+	@Override
+	public void setEmailAddress (final String emailAddress) {
+		this.emailAddress = emailAddress;
+	}
+
+	@Override
+	public String getEmailAddressRepeat () {
+		return this.emailAddressRepeat;
+	}
+
+	@Override
+	public void setEmailAddressRepeat (final String emailAddressRepeat) {
+		this.emailAddressRepeat = emailAddressRepeat;
+	}
+
+	@Override
+	public String getFamilyName () {
+		return this.familyName;
+	}
+
+	@Override
+	public void setFamilyName (final String familyName) {
+		this.familyName = familyName;
+	}
+
+	@Override
+	public Integer getFaxAreaCode () {
+		return this.faxAreaCode;
+	}
+
+	@Override
+	public void setFaxAreaCode (final Integer faxAreaCode) {
+		this.faxAreaCode = faxAreaCode;
+	}
+
+	@Override
+	public Country getFaxCountry () {
+		return this.faxCountry;
+	}
+
+	@Override
+	public void setFaxCountry (final Country faxCountry) {
+		this.faxCountry = faxCountry;
+	}
+
+	@Override
+	public Long getFaxNumber () {
+		return this.faxNumber;
+	}
+
+	@Override
+	public void setFaxNumber (final Long faxNumber) {
+		this.faxNumber = faxNumber;
+	}
+
+	@Override
+	public String getFirstName () {
+		return this.firstName;
+	}
+
+	@Override
+	public void setFirstName (final String firstName) {
+		this.firstName = firstName;
+	}
+
+	@Override
+	public Gender getGender () {
+		return this.gender;
+	}
+
+	@Override
+	public void setGender (final Gender gender) {
+		this.gender = gender;
+	}
+
+	@Override
+	public Short getHouseNumber () {
+		return this.houseNumber;
+	}
+
+	@Override
+	public void setHouseNumber (final Short houseNumber) {
+		this.houseNumber = houseNumber;
+	}
+
+	@Override
+	public Integer getPhoneAreaCode () {
+		return this.phoneAreaCode;
+	}
+
+	@Override
+	public void setPhoneAreaCode (final Integer phoneAreaCode) {
+		this.phoneAreaCode = phoneAreaCode;
+	}
+
+	@Override
+	public Country getPhoneCountry () {
+		return this.phoneCountry;
+	}
+
+	@Override
+	public void setPhoneCountry (final Country phoneCountry) {
+		this.phoneCountry = phoneCountry;
+	}
+
+	@Override
+	public Long getPhoneNumber () {
+		return this.phoneNumber;
+	}
+
+	@Override
+	public void setPhoneNumber (final Long phoneNumber) {
+		this.phoneNumber = phoneNumber;
+	}
+
+	@Override
+	public String getStreet () {
+		return this.street;
+	}
+
+	@Override
+	public void setStreet (final String street) {
+		this.street = street;
+	}
+
+	@Override
+	public Long getUserId () {
+		return this.userId;
+	}
+
+	@Override
+	public void setUserId (final Long userId) {
+		this.userId = userId;
+	}
+
+	@Override
+	public String getUserName () {
+		return this.userName;
+	}
+
+	@Override
+	public void setUserName (final String userName) {
+		this.userName = userName;
+	}
+
+	@Override
+	public String getUserPassword () {
+		return this.userPassword;
+	}
+
+	@Override
+	public void setUserPassword (final String userPassword) {
+		this.userPassword = userPassword;
+	}
+
+	@Override
+	public String getUserPasswordRepeat () {
+		return this.userPasswordRepeat;
+	}
+
+	@Override
+	public void setUserPasswordRepeat (final String userPasswordRepeat) {
+		this.userPasswordRepeat = userPasswordRepeat;
+	}
+
+	@Override
+	public ProfileMode getUserProfileMode () {
+		return this.userProfileMode;
+	}
+
+	@Override
+	public void setUserProfileMode (final ProfileMode userProfileMode) {
+		this.userProfileMode = userProfileMode;
+	}
+
+	@Override
+	public Integer getZipCode () {
+		return this.zipCode;
+	}
+
+	@Override
+	public void setZipCode (final Integer zipCode) {
+		this.zipCode = zipCode;
+	}
+
+	@PostConstruct
+	public void init () {
+		// Get full user name list for reducing EJB calls
+		this.userNameList = this.userBean.getUserNameList();
+
+		// Get full email address list for reducing EJB calls
+		this.emailAddressList = this.userBean.getEmailAddressList();
+
+		// Is the user logged-in?
+		if (this.loginController.isUserLoggedIn()) {
+			// Is logged-in, so load also users visible to memebers
+			this.visibleUserList = this.userBean.allMemberPublicVisibleUsers();
+		} else {
+			// Initialize user list
+			this.visibleUserList = this.userBean.allPublicUsers();
+		}
+	}
+
+	@Override
+	public boolean isEmailAddressRegistered (final User user) {
+		return ((this.emailAddressList instanceof List) && (this.emailAddressList.contains(user.getUserContact().getContactEmailAddress())));
+	}
+
+	@Override
+	public boolean isRequiredPersonalDataSet () {
+		return ((this.getUserName() != null) &&
+				(this.getUserProfileMode() != null) &&
+				(this.getGender() != null) &&
+				(this.getFirstName() != null) &&
+				(this.getFamilyName() != null) &&
+				(this.getStreet() != null) &&
+				(this.getHouseNumber() != null) &&
+				(this.getZipCode() != null) &&
+				(this.getCity() != null) &&
+				(this.getEmailAddress() != null) &&
+				(this.getEmailAddressRepeat() != null) &&
+				(this.getUserPassword() != null) &&
+				(this.getUserPasswordRepeat() != null));
+	}
+
+	@Override
+	public boolean isSameEmailAddressEntered () {
+		return (Objects.equals(this.getEmailAddress(), this.getEmailAddressRepeat()));
+	}
+
+	@Override
+	public boolean isSamePasswordEntered () {
+		return (Objects.equals(this.getUserPassword(), this.getUserPasswordRepeat()));
+	}
+
+	@Override
+	public boolean isUserNameRegistered (final User user) {
+		return ((this.userNameList instanceof List) && (this.userNameList.contains(user.getUserName())));
+	}
+
+	@Override
+	public boolean isVisibleUserFound () {
+		return ((this.visibleUserList instanceof List) && (this.visibleUserList.size() > 0));
+	}
+
+	@Override
+	public User lookupUserById (final Long userId) throws UserNotFoundException {
+		// Init variable
+		User user = null;
+
+		// Try to lookup it in visible user list
+		for (final Iterator<User> iterator = this.visibleUserList.iterator(); iterator.hasNext();) {
+			// Get next user
+			User next = iterator.next();
+
+			// Is the user id found?
+			if (Objects.equals(next.getUserId(), userId)) {
+				// Copy to other variable
+				user = next;
+				break;
+			}
+		}
+
+		// Is it still null?
+		if (null == user) {
+			// Not visible for the current user
+			throw new UserNotFoundException(userId);
+		}
+
+		// Return it
+		return user;
+	}
+
+	/**
+	 * Adds user's name and email address to bean's internal list. It also
+	 * updates the public user list if the user has decided to ha	}
+	 * <p>
+	 * @param user User instance
+	 */
+	private void addUserNameEmailAddress (final User user) {
+		// Make sure the entry is not added yet
+		if (this.userNameList.contains(user.getUserName())) {
+			// Abort here
+			throw new IllegalArgumentException(MessageFormat.format("User name {0} already added.", user.getUserName())); //NOI18N
+		} else if (this.emailAddressList.contains(user.getUserContact().getContactEmailAddress())) {
+			// Already added
+			throw new IllegalArgumentException(MessageFormat.format("Email address {0} already added.", user.getUserContact().getContactEmailAddress())); //NOI18N
+		}
+
+		// Add user name
+		this.userNameList.add(user.getUserName());
+
+		// Add email addres
+		this.emailAddressList.add(user.getUserContact().getContactEmailAddress());
+	}
+
+	/**
+	 * Clears all data in this bean
+	 */
+	private void clearData () {
+		// Clear all data
+		// - personal data
+		this.setUserId(null);
+		this.setGender(Gender.UNKNOWN);
+		this.setUserProfileMode(null);
+		this.setFirstName(null);
+		this.setFamilyName(null);
+		this.setStreet(null);
+		this.setHouseNumber(null);
+		this.setZipCode(null);
+		this.setCity(null);
+		this.setCountry(null);
+
+		// - contact data
+		this.setEmailAddress(null);
+		this.setEmailAddressRepeat(null);
+		this.setPhoneAreaCode(null);
+		this.setCellphoneCarrier(null);
+		this.setFaxAreaCode(null);
+
+		// - other data
+		this.setBirthday(null);
+		this.setComment(null);
+		this.setUserName(null);
+		this.setUserPassword(null);
+		this.setUserPasswordRepeat(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.setUserProfileMode(user.getUserProfileMode());
+		this.setGender(user.getUserContact().getContactGender());
+		this.setFirstName(user.getUserContact().getContactFirstName());
+		this.setFamilyName(user.getUserContact().getContactFamilyName());
+		this.setStreet(user.getUserContact().getContactStreet());
+		this.setHouseNumber(user.getUserContact().getContactHouseNumber());
+		this.setZipCode(user.getUserContact().getContactZipCode());
+		this.setCity(user.getUserContact().getContactCity());
+		this.setCountry(user.getUserContact().getContactCountry());
+
+		// Get cellphone, phone and fax instance
+		DialableCellphoneNumber cellphone = user.getUserContact().getContactCellphoneNumber();
+		DialableFaxNumber fax = user.getUserContact().getContactFaxNumber();
+		DialableLandLineNumber phone = user.getUserContact().getContactPhoneNumber();
+
+		// - contact data
+		if ((phone instanceof DialableLandLineNumber) && (phone.getPhoneAreaCode() > 0)) {
+			this.setPhoneCountry(phone.getPhoneCountry());
+			this.setPhoneAreaCode(phone.getPhoneAreaCode());
+			this.setPhoneNumber(phone.getPhoneNumber());
+		}
+		if ((cellphone instanceof DialableCellphoneNumber) && (cellphone.getCellphoneProvider() instanceof SmsProvider)) {
+			this.setCellphoneCarrier(cellphone.getCellphoneProvider());
+			this.setCellphoneNumber(cellphone.getPhoneNumber());
+		}
+		if ((fax instanceof DialableFaxNumber) && (fax.getPhoneAreaCode() > 0)) {
+			this.setFaxCountry(fax.getPhoneCountry());
+			this.setFaxAreaCode(fax.getPhoneAreaCode());
+			this.setFaxNumber(fax.getPhoneNumber());
+		}
+		this.setEmailAddress(user.getUserContact().getContactEmailAddress());
+
+		// -- other data
+		this.setBirthday(user.getUserContact().getContactBirthday());
+		this.setComment(user.getUserContact().getContactComment());
+	}
+
+	@Override
+	public boolean isUserIdEmpty () {
+		return ((this.getUserId() == null) || (this.getUserId() == 0));
+	}
+}
diff --git a/src/java/org/mxchange/jjobs/beans/user/UserWebSessionController.java b/src/java/org/mxchange/jjobs/beans/user/UserWebSessionController.java
new file mode 100644
index 00000000..9917eab5
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/beans/user/UserWebSessionController.java
@@ -0,0 +1,481 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.beans.user;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+import org.mxchange.jcontacts.contact.gender.Gender;
+import org.mxchange.jcountry.data.Country;
+import org.mxchange.jphone.phonenumbers.smsprovider.SmsProvider;
+import org.mxchange.jusercore.events.login.UserLoggedInEvent;
+import org.mxchange.jusercore.events.registration.UserRegisteredEvent;
+import org.mxchange.jusercore.exceptions.UserNotFoundException;
+import org.mxchange.jusercore.model.user.User;
+import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
+
+/**
+ * An interface for user beans
+ * <p>
+ * @author Roland Haeder<roland@mxchange.org>
+ */
+public interface UserWebSessionController extends Serializable {
+
+	/**
+	 * Tries to lookup user by given id number. If the user is not found or the
+	 * account status is not CONFIRMED proper exceptions are thrown.
+	 * <p>
+	 * @param userId User id
+	 * <p>
+	 * @return User instance
+	 * <p>
+	 * @throws UserNotFoundException If the user is not found
+	 */
+	User lookupUserById (final Long userId) throws UserNotFoundException;
+
+	/**
+	 * Event observer for new user registrations
+	 * <p>
+	 * @param event User registration event
+	 */
+	void afterRegistrationEvent (final UserRegisteredEvent event);
+
+	/**
+	 * Event observer for logged-in user
+	 * <p>
+	 * @param event Event instance
+	 */
+	void afterUserLogin (final UserLoggedInEvent event);
+
+	/**
+	 * All public user profiles
+	 * <p>
+	 * @return A list of all public user profiles
+	 */
+	List<User> allVisibleUsers ();
+
+	/**
+	 * Creates an instance from all properties
+	 * <p>
+	 * @return A user instance
+	 */
+	User createUserInstance ();
+
+	/**
+	 * Getter for birth day
+	 * <p>
+	 * @return Birth day
+	 */
+	Date getBirthday ();
+
+	/**
+	 * Setter for birth day
+	 * <p>
+	 * @param birthday Birth day
+	 */
+	void setBirthday (final Date birthday);
+
+	/**
+	 * Getter for ellphone number's carrier
+	 * <p>
+	 * @return Cellphone number's carrier
+	 */
+	SmsProvider getCellphoneCarrier ();
+
+	/**
+	 * Setter for cellphone number's carrier prefix
+	 * <p>
+	 * @param cellphoneCarrier Cellphone number's carrier prefix
+	 */
+	void setCellphoneCarrier (final SmsProvider cellphoneCarrier);
+
+	/**
+	 * Getter for ellphone number
+	 * <p>
+	 * @return Cellphone number
+	 */
+	Long getCellphoneNumber ();
+
+	/**
+	 * Setter for ellphone number
+	 * <p>
+	 * @param cellphoneNumber Cellphone number
+	 */
+	void setCellphoneNumber (final Long cellphoneNumber);
+
+	/**
+	 * City
+	 * <p>
+	 * @return the city
+	 */
+	String getCity ();
+
+	/**
+	 * City
+	 * <p>
+	 * @param city the city to set
+	 */
+	void setCity (final String city);
+
+	/**
+	 * Getter for comments
+	 * <p>
+	 * @return Comments
+	 */
+	String getComment ();
+
+	/**
+	 * Setter for comment
+	 * <p>
+	 * @param comment Comments
+	 */
+	void setComment (final String comment);
+
+	/**
+	 * Getter for country instance
+	 * <p>
+	 * @return Country instance
+	 */
+	Country getCountry ();
+
+	/**
+	 * Setter for country instance
+	 * <p>
+	 * @param country Country instance
+	 */
+	void setCountry (final Country country);
+
+	/**
+	 * Getter for email address
+	 * <p>
+	 * @return Email address
+	 */
+	String getEmailAddress ();
+
+	/**
+	 * Setter for email address
+	 * <p>
+	 * @param emailAddress Email address
+	 */
+	void setEmailAddress (final String emailAddress);
+
+	/**
+	 * Getter for email address, repeated
+	 * <p>
+	 * @return the emailAddress, repeated
+	 */
+	String getEmailAddressRepeat ();
+
+	/**
+	 * Setter for email address repeated
+	 * <p>
+	 * @param emailAddressRepeat the emailAddress to set
+	 */
+	void setEmailAddressRepeat (final String emailAddressRepeat);
+
+	/**
+	 * Family name
+	 * <p>
+	 * @return the familyName
+	 */
+	String getFamilyName ();
+
+	/**
+	 * Family name
+	 * <p>
+	 * @param familyName the familyName to set
+	 */
+	void setFamilyName (final String familyName);
+
+	/**
+	 * Getter for fax number's area code
+	 * <p>
+	 * @return Fax number's area code
+	 */
+	Integer getFaxAreaCode ();
+
+	/**
+	 * Setter for fax number's area code
+	 * <p>
+	 * @param faxAreaCode Fax number's area code
+	 */
+	void setFaxAreaCode (final Integer faxAreaCode);
+
+	/**
+	 * Getter for fax's country instance
+	 * <p>
+	 * @return Fax' country instance
+	 */
+	Country getFaxCountry ();
+
+	/**
+	 * Setter for fax's country instance
+	 * <p>
+	 * @param faxCountry Fax' country instance
+	 */
+	void setFaxCountry (final Country faxCountry);
+
+	/**
+	 * Getter for fax number
+	 * <p>
+	 * @return Fax number
+	 */
+	Long getFaxNumber ();
+
+	/**
+	 * Setter for fax number
+	 * <p>
+	 * @param faxNumber Fax number
+	 */
+	void setFaxNumber (final Long faxNumber);
+
+	/**
+	 * First name
+	 * <p>
+	 * @return the first name
+	 */
+	String getFirstName ();
+
+	/**
+	 * First name
+	 * <p>
+	 * @param firstName the first name to set
+	 */
+	void setFirstName (final String firstName);
+
+	/**
+	 * Gender of the contact
+	 * <p>
+	 * @return the gender
+	 */
+	Gender getGender ();
+
+	/**
+	 * Gender of the contact
+	 * <p>
+	 * @param gender the gender to set
+	 */
+	void setGender (final Gender gender);
+
+	/**
+	 * House number
+	 * <p>
+	 * @return the houseNumber
+	 */
+	Short getHouseNumber ();
+
+	/**
+	 * House number
+	 * <p>
+	 * @param houseNumber the houseNumber to set
+	 */
+	void setHouseNumber (final Short houseNumber);
+
+	/**
+	 * Getter for phone number's area code
+	 * <p>
+	 * @return Phone number's area code
+	 */
+	Integer getPhoneAreaCode ();
+
+	/**
+	 * Setter for phone number's area code
+	 * <p>
+	 * @param phoneAreaCode Phone number's area code
+	 */
+	void setPhoneAreaCode (final Integer phoneAreaCode);
+
+	/**
+	 * Getter for phone number's country instance
+	 * <p>
+	 * @return Phone number's country instance
+	 */
+	Country getPhoneCountry ();
+
+	/**
+	 * Setter for phone number's country instance
+	 * <p>
+	 * @param phoneCountry Phone number's country instance
+	 */
+	void setPhoneCountry (final Country phoneCountry);
+
+	/**
+	 * Getter for phone number
+	 * <p>
+	 * @return Phone number
+	 */
+	Long getPhoneNumber ();
+
+	/**
+	 * Setter for phone number
+	 * <p>
+	 * @param phoneNumber Phone number
+	 */
+	void setPhoneNumber (final Long phoneNumber);
+
+	/**
+	 * Street
+	 * <p>
+	 * @return the street
+	 */
+	String getStreet ();
+
+	/**
+	 * Street
+	 * <p>
+	 * @param street the street to set
+	 */
+	void setStreet (final String street);
+
+	/**
+	 * Getter for user id
+	 * <p>
+	 * @return User id
+	 */
+	Long getUserId ();
+
+	/**
+	 * Setter for user id
+	 * <p>
+	 * @param userId User id
+	 */
+	void setUserId (final Long userId);
+
+	/**
+	 * Getter for user name
+	 * <p>
+	 * @return User name
+	 */
+	String getUserName ();
+
+	/**
+	 * Setter for user name
+	 * <p>
+	 * @param userName User name
+	 */
+	void setUserName (final String userName);
+
+	/**
+	 * Getter for unencrypted user password
+	 * <p>
+	 * @return Unencrypted user password
+	 */
+	String getUserPassword ();
+
+	/**
+	 * Setter for unencrypted user password
+	 * <p>
+	 * @param userPassword Unencrypted user password
+	 */
+	void setUserPassword (final String userPassword);
+
+	/**
+	 * Getter for unencrypted user password repeated
+	 * <p>
+	 * @return Unencrypted user password repeated
+	 */
+	String getUserPasswordRepeat ();
+
+	/**
+	 * Setter for unencrypted user password repeated
+	 * <p>
+	 * @param userPasswordRepeat Unencrypted user password repeated
+	 */
+	void setUserPasswordRepeat (final String userPasswordRepeat);
+
+	/**
+	 * Getter for user profile mode
+	 * <p>
+	 * @return User profile mode
+	 */
+	ProfileMode getUserProfileMode ();
+
+	/**
+	 * Setter for user profile mode
+	 * <p>
+	 * @param userProfileMode User profile mode
+	 */
+	void setUserProfileMode (final ProfileMode userProfileMode);
+
+	/**
+	 * ZIP code
+	 * <p>
+	 * @return the zipCode
+	 */
+	Integer getZipCode ();
+
+	/**
+	 * ZIP code
+	 * <p>
+	 * @param zipCode the zipCode to set
+	 */
+	void setZipCode (final Integer zipCode);
+
+	/**
+	 * Checks whether user instance's email address is used
+	 * <p>
+	 * @param user User instance's email address to check
+	 * <p>
+	 * @return Whether it is already used
+	 */
+	boolean isEmailAddressRegistered (final User user);
+
+	/**
+	 * Checks whether all required personal data is set
+	 * <p>
+	 * @return Whether the required personal data is set
+	 */
+	boolean isRequiredPersonalDataSet ();
+
+	/**
+	 * Checks whether same email addresses have been entered
+	 * <p>
+	 * @return Whether same email addresses have been entered
+	 */
+	boolean isSameEmailAddressEntered ();
+
+	/**
+	 * Checks whether same passwords has been entered
+	 * <p>
+	 * @return Whether same passwords has been entered
+	 */
+	boolean isSamePasswordEntered ();
+
+	/**
+	 * Checks whether given user instance's name is used
+	 * <p>
+	 * @param user User instance's name to check
+	 * <p>
+	 * @return Whether it is already used
+	 */
+	boolean isUserNameRegistered (final User user);
+
+	/**
+	 * Checks whether a public user account is registered. This means that at
+	 * least one user profile has its flag "public user profile" enabled.
+	 * <p>
+	 * @return Whether at least one user has a public profile
+	 */
+	boolean isVisibleUserFound ();
+
+	/**
+	 * Checks if the user id is empty
+	 * <p>
+	 * @return Whether the user id is empty
+	 */
+	boolean isUserIdEmpty ();
+}
diff --git a/src/java/org/mxchange/jjobs/converter/country/CountryConverter.java b/src/java/org/mxchange/jjobs/converter/country/CountryConverter.java
new file mode 100644
index 00000000..d76e38ce
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/converter/country/CountryConverter.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.converter.country;
+
+import java.text.MessageFormat;
+import java.util.List;
+import java.util.Objects;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+import javax.faces.convert.FacesConverter;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import org.mxchange.jcoreeelogger.beans.local.logger.Log;
+import org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal;
+import org.mxchange.jcountry.data.AddressbookCountrySingletonBeanRemote;
+import org.mxchange.jcountry.data.Country;
+
+/**
+ * Converter for country instance
+ * <p>
+ * @author Roland Haeder
+ */
+@FacesConverter (value = "country")
+public class CountryConverter implements Converter {
+
+	/**
+	 * Country bean
+	 */
+	private AddressbookCountrySingletonBeanRemote countryController;
+
+	/**
+	 * Logger instance
+	 */
+	@Log
+	private LoggerBeanLocal loggerBeanLocal;
+
+	@Override
+	public Object getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) {
+		// Trace message
+		this.loggerBeanLocal.logTrace(MessageFormat.format("getAsObject: contect={0},component={1},submittedValue={2},this.countryController={3} - CALLED!", context, component, submittedValue, this.countryController)); //NOI18N
+
+		// Get full list
+		List<Country> countryList = this.countryController.allCountries();
+
+		// Is the value null or empty?
+		if ((null == submittedValue) || (submittedValue.trim().isEmpty())) {
+			// Return null
+			return null;
+		}
+
+		// Init value
+		Country country = null;
+
+		// Try this better
+		try {
+			// Convert it to long
+			Long countryId = Long.parseLong(submittedValue);
+
+			// Category id should not be below 1
+			assert (countryId > 0) : "countryId is smaller than one: " + countryId; //NOI18N
+
+			// Debug message
+			this.loggerBeanLocal.logDebug(MessageFormat.format("getAsObject: countryId={0}", countryId)); //NOI18N
+
+			// Try to find it
+			for (final Country cntry : countryList) {
+				// Is the id the same? (null-safe)
+				if (Objects.equals(cntry.getCountryId(), countryId)) {
+					// Found it
+					country = cntry;
+					break;
+				}
+			}
+		} catch (final NumberFormatException ex) {
+			// Log exception (maybe to much?)
+			this.loggerBeanLocal.logException(ex);
+		}
+
+		// Trace message
+		this.loggerBeanLocal.logTrace(MessageFormat.format("getAsObject: country={0} - EXIT!", country)); //NOI18N
+
+		// Return it
+		return country;
+	}
+
+	@Override
+	public String getAsString (final FacesContext context, final UIComponent component, final Object value) {
+		// Is the object null?
+		if ((null == value) || ((String.valueOf(value)).isEmpty())) {
+			// Is null
+			return ""; //NOI18N
+		} else if (!(value instanceof Country)) {
+			// Not same interface
+			throw new IllegalArgumentException(MessageFormat.format("value {0} does not implement Country.", value)); //NOI18N
+		}
+
+		// Return category id
+		return String.valueOf(((Country) value).getCountryId());
+	}
+
+	/**
+	 * Initialization of this converter
+	 */
+	public CountryConverter () {
+		// Try to get it
+		try {
+			// Get initial context
+			Context context = new InitialContext();
+
+			// Lookup logger
+			this.loggerBeanLocal = (LoggerBeanLocal) context.lookup("java:global/jcore-logger-ejb/logger!org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal"); //NOI18N
+
+			// ... and country controller
+			this.countryController = (AddressbookCountrySingletonBeanRemote) context.lookup("java:global/addressbook-ejb/country!org.mxchange.jcountry.data.AddressbookCountrySingletonBeanRemote"); //NOI18N
+		} catch (final NamingException ex) {
+			// Continue to throw it
+			throw new RuntimeException("context.lookup() failed.", ex); //NOI18N
+		}
+	}
+}
diff --git a/src/java/org/mxchange/jjobs/converter/smsprovider/SmsProviderConverter.java b/src/java/org/mxchange/jjobs/converter/smsprovider/SmsProviderConverter.java
new file mode 100644
index 00000000..5022e001
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/converter/smsprovider/SmsProviderConverter.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.converter.smsprovider;
+
+import java.text.MessageFormat;
+import java.util.List;
+import java.util.Objects;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+import javax.faces.convert.FacesConverter;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import org.mxchange.jcoreeelogger.beans.local.logger.Log;
+import org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal;
+import org.mxchange.jphone.phonenumbers.smsprovider.AddressbookSmsProviderSingletonBeanRemote;
+import org.mxchange.jphone.phonenumbers.smsprovider.SmsProvider;
+
+/**
+ * Converter for SMS provider instance
+ * <p>
+ * @author Roland Haeder
+ */
+@FacesConverter (value = "cellphoneCarrier")
+public class SmsProviderConverter implements Converter {
+
+	/**
+	 * Logger instance
+	 */
+	@Log
+	private LoggerBeanLocal loggerBeanLocal;
+
+	/**
+	 * SMS provider bean
+	 */
+	private AddressbookSmsProviderSingletonBeanRemote providerController;
+
+	@Override
+	public Object getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) {
+		// Trace message
+		this.loggerBeanLocal.logTrace(MessageFormat.format("getAsObject: contect={0},component={1},submittedValue={2} - CALLED!", context, component, submittedValue)); //NOI18N
+
+		// Get full list
+		List<SmsProvider> providerList = this.providerController.allSmsProvider();
+
+		// Is the value null or empty?
+		if ((null == submittedValue) || (submittedValue.trim().isEmpty())) {
+			// Return null
+			return null;
+		}
+
+		// Init value
+		SmsProvider provider = null;
+
+		// Try this better
+		try {
+			// Convert it to long
+			Long providerId = Long.parseLong(submittedValue);
+
+			// Category id should not be below 1
+			assert (providerId > 0) : "providerId is smaller than one: " + providerId; //NOI18N
+
+			// Debug message
+			this.loggerBeanLocal.logDebug(MessageFormat.format("getAsObject: providerId={0}", providerId)); //NOI18N
+
+			// Try to find it
+			for (final SmsProvider prov : providerList) {
+				// Is the id the same? (null-safe)
+				if (Objects.equals(prov.getProviderId(), providerId)) {
+					// Found it
+					provider = prov;
+					break;
+				}
+			}
+		} catch (final NumberFormatException ex) {
+			// Log exception (maybe to much?)
+			this.loggerBeanLocal.logException(ex);
+		}
+
+		// Trace message
+		this.loggerBeanLocal.logTrace(MessageFormat.format("getAsObject: provider={0} - EXIT!", provider)); //NOI18N
+
+		// Return it
+		return provider;
+	}
+
+	@Override
+	public String getAsString (final FacesContext context, final UIComponent component, final Object value) {
+		// Is the object null?
+		if ((null == value) || ((String.valueOf(value)).isEmpty())) {
+			// Is null
+			return ""; //NOI18N
+		} else if (!(value instanceof SmsProvider)) {
+			// Not same interface
+			throw new IllegalArgumentException(MessageFormat.format("value {0} does not implement SmsProvider.", value)); //NOI18N
+		}
+
+		// Return category id
+		return String.valueOf(((SmsProvider) value).getProviderId());
+	}
+
+	/**
+	 * Initialization of this converter
+	 */
+	public SmsProviderConverter () {
+		// Try to get it
+		try {
+			// Get initial context
+			Context context = new InitialContext();
+
+			// Lookup logger
+			this.loggerBeanLocal = (LoggerBeanLocal) context.lookup("java:global/jcore-logger-ejb/logger!org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal"); //NOI18N
+
+			/// and SMS provider controller
+			this.providerController = (AddressbookSmsProviderSingletonBeanRemote) context.lookup("java:global/addressbook-ejb/smsprovider!org.mxchange.jphone.phonenumbers.smsprovider.AddressbookSmsProviderSingletonBeanRemote"); //NOI18N
+		} catch (final NamingException ex) {
+			// Continue to throw it
+			throw new RuntimeException("context.lookup() failed.", ex); //NOI18N
+		}
+	}
+
+}
diff --git a/src/java/org/mxchange/jjobs/converter/user/UserConverter.java b/src/java/org/mxchange/jjobs/converter/user/UserConverter.java
new file mode 100644
index 00000000..546d9dcf
--- /dev/null
+++ b/src/java/org/mxchange/jjobs/converter/user/UserConverter.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jjobs.converter.user;
+
+import java.text.MessageFormat;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+import javax.faces.convert.ConverterException;
+import javax.faces.convert.FacesConverter;
+import javax.inject.Inject;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import org.mxchange.jjobs.beans.user.UserWebSessionController;
+import org.mxchange.jcoreeelogger.beans.local.logger.Log;
+import org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal;
+import org.mxchange.jusercore.exceptions.UserNotFoundException;
+import org.mxchange.jusercore.model.user.User;
+
+/**
+ * Converter for user id <-> valid user instance
+ * <p>
+ * @author Roland Haeder
+ */
+@FacesConverter (value = "UserConverter")
+public class UserConverter implements Converter {
+
+	/**
+	 * Logger instance
+	 */
+	@Log
+	private LoggerBeanLocal loggerBeanLocal;
+
+	/**
+	 * User bean
+	 */
+	@Inject
+	private UserWebSessionController userController;
+
+	@Override
+	public Object getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) {
+		// Trace message
+		this.loggerBeanLocal.logTrace(MessageFormat.format("getAsObject: contect={0},component={1},submittedValue={2} - CALLED!", context, component, submittedValue)); //NOI18N
+
+		// Is the value null or empty?
+		if ((null == submittedValue) || (submittedValue.trim().isEmpty())) {
+			// Return null
+			return null;
+		}
+
+		// Init instance
+		User user = null;
+
+		try {
+			// Try to parse the value as long
+			Long userId = Long.valueOf(submittedValue);
+
+			// Debug message
+			this.loggerBeanLocal.logDebug(MessageFormat.format("getAsObject: userId{0}", userId));
+
+			// Try to get user instance from it
+			user = this.userController.lookupUserById(userId);
+
+			// Debug message
+			this.loggerBeanLocal.logDebug(MessageFormat.format("getAsObject: user={0}", user));
+		} catch (final NumberFormatException ex) {
+			// Throw again
+			throw new ConverterException(ex);
+		} catch (final UserNotFoundException ex) {
+			// Debug message
+			this.loggerBeanLocal.logDebug(MessageFormat.format("getAsObject: Exception: {0} - Returning null ...", ex));
+
+			// Return null
+			return null;
+		}
+
+		// Trace message
+		this.loggerBeanLocal.logTrace(MessageFormat.format("getAsObject: user={0} - EXIT!", user));
+
+		// Return it
+		return user;
+	}
+
+	@Override
+	public String getAsString (final FacesContext context, final UIComponent component, final Object value) {
+		// Is the object null?
+		if ((null == value) || ((String.valueOf(value)).isEmpty())) {
+			// Is null
+			return ""; //NOI18N
+		} else if (!(value instanceof User)) {
+			// Not same interface
+			throw new IllegalArgumentException(MessageFormat.format("value {0} does not implement User.", value)); //NOI18N
+		}
+
+		// Return category id
+		return String.valueOf(((User) value).getUserId());
+	}
+
+	/**
+	 * Initialization of this converter
+	 */
+	public UserConverter () {
+		// Try to get it
+		try {
+			// Get initial context
+			Context context = new InitialContext();
+
+			// Lookup logger
+			this.loggerBeanLocal = (LoggerBeanLocal) context.lookup("java:global/jcore-logger-ejb/logger!org.mxchange.jcoreeelogger.beans.local.logger.LoggerBeanLocal"); //NOI18N
+
+			// ... and user controller
+			this.userController = (UserWebSessionController) context.lookup("java:global/juser-ejb/user!org.mxchange.jusercore.model.user.UserSessionBeanRemote"); //NOI18N
+		} catch (final NamingException ex) {
+			// Continue to throw it
+			throw new RuntimeException("context.lookup() failed.", ex); //NOI18N
+		}
+	}
+}
diff --git a/web/WEB-INF/faces-config.xml b/web/WEB-INF/faces-config.xml
index 969fbf47..19d9cd43 100644
--- a/web/WEB-INF/faces-config.xml
+++ b/web/WEB-INF/faces-config.xml
@@ -19,7 +19,7 @@
 	</validator>
 	<validator>
 		<validator-id>AddressbookNameValidator</validator-id>
-		<validator-class>org.mxchange.addressbook.validator.names.AddressbookNameValidator</validator-class>
+		<validator-class>org.mxchange.jjobs.validator.names.AddressbookNameValidator</validator-class>
 	</validator>
 	<validator>
 		<validator-id>PhoneNumberValidator</validator-id>
@@ -27,11 +27,11 @@
 	</validator>
 	<validator>
 		<validator-id>AddressbookIdValidator</validator-id>
-		<validator-class>org.mxchange.addressbook.validator.addressbook.AddressbookIdValidator</validator-class>
+		<validator-class>org.mxchange.jjobs.validator.addressbook.AddressbookIdValidator</validator-class>
 	</validator>
 	<validator>
 		<validator-id>UserProfileVisibilityValidator</validator-id>
-		<validator-class>org.mxchange.addressbook.validator.booleans.UserProfileVisibilityValidator</validator-class>
+		<validator-class>org.mxchange.jjobs.validator.booleans.UserProfileVisibilityValidator</validator-class>
 	</validator>
 	<validator>
 		<validator-id>UserIdValidator</validator-id>