docs: @SuppressWarnings("unchecked")
  	public CommandResponse execute(String commandName, CommandRequest request, String userToken, String locale) {
  		String id = Long.toString(++commandCount); // NOTE indicative, this is not (fully) thread safe or cluster aware
  		log.info(id + MSG_START + commandName + " for user token " + userToken + " in locale " + locale);
  		if (log.isTraceEnabled()) {
  			log.trace(id + MSG_START + commandName + " request " + request);
  		}
  		long begin = System.currentTimeMillis();
  		CommandResponse response;
  
  		String previousToken = securityContext.getToken();
  		// for null token we always need to *try* as otherwise login would never be possible
  		boolean tokenIdentical = null != userToken && userToken.equals(previousToken);
  		try {
  			if (!tokenIdentical) {
  				// need to change security context
  				if (!securityManager.createSecurityContext(userToken)) {
  					// not authorized
  					response = new CommandResponse();
  					response.setId(id);
  					response.getErrors().add(
  							new GeomajasSecurityException(ExceptionCode.CREDENTIALS_MISSING_OR_INVALID, userToken));
  					serializeExceptions(response, "", locale, id);
  
  					response.setExecutionTime(System.currentTimeMillis() - begin);
  					return response;
  				}
  			}
  
  			// check access rights for the command
  			if (securityContext.isCommandAuthorized(commandName)) {
  
  				Command command = null;
  				try {
  					command = applicationContext.getBean(commandName, Command.class);
  				} catch (BeansException be) {
  					log.debug(id + MSG_START + commandName + ", could not create command bean", be);
  				}
  				if (null != command) {
  					response = command.getEmptyCommandResponse();
  					response.setId(id);
  					try {
  						command.execute(request, response);
  					} catch (Throwable throwable) { //NOPMD
  						log.debug(id + MSG_START + commandName + ", error executing command", throwable);
  						response.getErrors().add(throwable);
  						serializeExceptions(response, commandName, locale, id);
  					}
  				} else {
  					response = new CommandResponse();
  					response.setId(id);
  					response.getErrors().add(new GeomajasException(ExceptionCode.COMMAND_NOT_FOUND, commandName));
  					serializeExceptions(response, commandName, locale, id);
  				}
  
  			} else {
  				// not authorized
  				response = new CommandResponse();
  				response.setId(id);
  				response.getErrors().add(
  						new GeomajasSecurityException(ExceptionCode.COMMAND_ACCESS_DENIED, commandName, securityContext
  								.getUserId()));
  				serializeExceptions(response, commandName, locale, id);
  			}
  
  			long executionTime = System.currentTimeMillis() - begin;
  			response.setExecutionTime(executionTime);
  			if (log.isDebugEnabled()) {
  				log.debug(id + MSG_START + commandName + " done in " + executionTime + "ms");
  			}
  			if (log.isTraceEnabled()) {
  				log.trace(id + MSG_START + commandName + " response " + response);
  			}
  			return response;
  		} finally {
  			if (!tokenIdentical) {
  				// clear security context
  				securityManager.clearSecurityContext();
  			}
  		}
  	}