@Override
  public CmisService getService(CallContext context) {
    // authenticate the user
    // if the authentication fails, authenticate() throws a
    // CmisPermissionDeniedException
    userManager.authenticate(context);

    // get service object for this thread
    CallContextAwareCmisService service = threadLocalService.get();
    if (service == null) {
      // there is no service object for this thread -> create one
      FileShareCmisService fileShareService = new FileShareCmisService(repositoryManager);

      service = (CallContextAwareCmisService) wrapperManager.wrap(fileShareService);

      threadLocalService.set(service);
    }

    // hand over the call context to the service object
    service.setCallContext(context);

    return service;
  }
  /** Reads the configuration and sets up the repositories, logins, and type definitions. */
  private void readConfiguration(Map<String, String> parameters) {
    List<String> keys = new ArrayList<String>(parameters.keySet());
    Collections.sort(keys);

    for (String key : keys) {
      if (key.startsWith(PREFIX_LOGIN)) {
        // get logins
        String usernameAndPassword = replaceSystemProperties(parameters.get(key));
        if (usernameAndPassword == null) {
          continue;
        }

        String username = usernameAndPassword;
        String password = "";

        int x = usernameAndPassword.indexOf(':');
        if (x > -1) {
          username = usernameAndPassword.substring(0, x);
          password = usernameAndPassword.substring(x + 1);
        }

        LOG.info("Adding login '{}'.", username);

        userManager.addLogin(username, password);
      } else if (key.startsWith(PREFIX_TYPE)) {
        // load type definition
        String typeFile = replaceSystemProperties(parameters.get(key).trim());
        if (typeFile.length() == 0) {
          continue;
        }

        LOG.info("Loading type definition: {}", typeFile);

        if (typeFile.charAt(0) == '/') {
          try {
            typeManager.loadTypeDefinitionFromResource(typeFile);
            continue;
          } catch (IllegalArgumentException e) {
            // resource not found -> try it as a regular file
          } catch (Exception e) {
            LOG.warn(
                "Could not load type defintion from resource '{}': {}",
                typeFile,
                e.getMessage(),
                e);
            continue;
          }
        }

        try {
          typeManager.loadTypeDefinitionFromFile(typeFile);
        } catch (Exception e) {
          LOG.warn("Could not load type defintion from file '{}': {}", typeFile, e.getMessage(), e);
        }
      } else if (key.startsWith(PREFIX_REPOSITORY)) {
        // configure repositories
        String repositoryId = key.substring(PREFIX_REPOSITORY.length()).trim();
        int x = repositoryId.lastIndexOf('.');
        if (x > 0) {
          repositoryId = repositoryId.substring(0, x);
        }

        if (repositoryId.length() == 0) {
          throw new IllegalArgumentException("No repository id!");
        }

        if (key.endsWith(SUFFIX_READWRITE)) {
          // read-write users
          FileShareRepository fsr = repositoryManager.getRepository(repositoryId);
          for (String user : split(parameters.get(key))) {
            fsr.setUserReadWrite(replaceSystemProperties(user));
          }
        } else if (key.endsWith(SUFFIX_READONLY)) {
          // read-only users
          FileShareRepository fsr = repositoryManager.getRepository(repositoryId);
          for (String user : split(parameters.get(key))) {
            fsr.setUserReadOnly(replaceSystemProperties(user));
          }
        } else {
          // new repository
          String root = replaceSystemProperties(parameters.get(key));

          LOG.info("Adding repository '{}': {}", repositoryId, root);

          FileShareRepository fsr = new FileShareRepository(repositoryId, root, typeManager);
          repositoryManager.addRepository(fsr);
        }
      }
    }
  }