@Override
	public void run() {
		try {
			out = new PrintWriter(socket.getOutputStream());
			in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		} catch (IOException e) {
			logger.error("Failed to bind input or output stream to user client");
		}

		// communicate
		String inputLine, outputLine;
		InetAddress inetAddress = socket.getInetAddress();
		int port = socket.getPort();
		protocol = new CommunicationProtocol(inetAddress, port, userManagement, analyticsServerRef, billingServerRef, registry);

		try {
			// read line and pass it to the CommunicationProtocoll
			while ((inputLine = in.readLine()) != null) {
				logger.debug("Receiving client command: "+inputLine);
				outputLine = protocol.processInput(inputLine);
				out.println(outputLine);
				logger.debug("Sending client response: "+outputLine);
				out.flush();
			}
		} catch (IOException e) {
			// empty
		}
		if (!protocol.getUser().getName().equals("")) {
			userManagement.getUserByName(protocol.getUser().getName()).setOnline(false);
		}

		try {
			Timestamp logoutTimestamp = new Timestamp(System.currentTimeMillis());
			long timestamp = logoutTimestamp.getTime();
			mClientHandler.processEvent(new UserEvent(UserEvent.USER_DISCONNECTED, timestamp, protocol.getUser().getName()));
		} catch (RemoteException e) {
			logger.error("Failed to connect to the Analytics Server");
		} catch (WrongEventTypeException e) {
			// wont happen
		}
	}