@Override
  public synchronized void start() throws Exception {
    checkState(!started, "Already started");

    log.info("Starting");

    // FIXME: Sort out overlap in responsibility between lifecycle here and RealmManagerImpl
    // FIXME: Wonder if a provider to handle configuration of RealmSecurityManager here is better?

    // prepare security manager
    if (realmSecurityManager instanceof Initializable) {
      ((Initializable) realmSecurityManager).init();
    }

    // prepare shiro cache
    EhCacheManager shiroCacheManager = new EhCacheManager();
    shiroCacheManager.setCacheManager(cacheManager);
    realmSecurityManager.setCacheManager(shiroCacheManager);

    // TODO: Sort out better means to invoke lifecycle here, realm-manager is only here for
    // start/stop now
    realmManager.start();

    started = true;
  }
  /**
   * We need to order the UserManagers the same way as the Realms are ordered. We need to be able to
   * find a user based on the ID.
   *
   * <p>This my never go away, but the current reason why we need it is:
   * https://issues.apache.org/jira/browse/KI-77 There is no (clean) way to resolve a realms roles
   * into permissions. take a look at the issue and VOTE!
   *
   * @return the list of UserManagers in the order (as close as possible) to the list of realms.
   */
  private List<UserManager> orderUserManagers() {
    List<UserManager> orderedLocators = new ArrayList<>();

    List<UserManager> unOrderdLocators = new ArrayList<>(getUserManagers());

    Map<String, UserManager> realmToUserManagerMap = new HashMap<>();

    for (UserManager userManager : getUserManagers()) {
      if (userManager.getAuthenticationRealmName() != null) {
        realmToUserManagerMap.put(userManager.getAuthenticationRealmName(), userManager);
      }
    }

    // get the sorted order of realms from the realm locator
    Collection<Realm> realms = realmSecurityManager.getRealms();

    for (Realm realm : realms) {
      // now user the realm.name to find the UserManager
      if (realmToUserManagerMap.containsKey(realm.getName())) {
        UserManager userManager = realmToUserManagerMap.get(realm.getName());
        // remove from unorderd and add to orderd
        unOrderdLocators.remove(userManager);
        orderedLocators.add(userManager);
      }
    }

    // now add all the un-ordered ones to the ordered ones, this way they will be at the end of the
    // ordered list
    orderedLocators.addAll(unOrderdLocators);

    return orderedLocators;
  }
  @Override
  public synchronized void stop() throws Exception {
    // FIXME: We never guard started=true ?!

    log.info("Stopping");

    realmManager.stop();

    realmSecurityManager.destroy();

    // TODO: Unset security manager?

    // FIXME: We never set started=false ?!
  }
  @Override
  public void changePassword(String userId, String oldPassword, String newPassword)
      throws UserNotFoundException, InvalidCredentialsException {
    // first authenticate the user
    try {
      UsernamePasswordToken authenticationToken = new UsernamePasswordToken(userId, oldPassword);
      if (realmSecurityManager.authenticate(authenticationToken) == null) {
        throw new InvalidCredentialsException();
      }
    } catch (AuthenticationException e) {
      log.debug("User failed to change password reason: " + e.getMessage(), e);
      throw new InvalidCredentialsException();
    }

    // if that was good just change the password
    changePassword(userId, newPassword);
  }
 @Override
 public void checkPermission(PrincipalCollection principal, String permission)
     throws AuthorizationException {
   realmSecurityManager.checkPermission(principal, permission);
 }
 @Override
 public boolean[] isPermitted(PrincipalCollection principal, List<String> permissions) {
   return realmSecurityManager.isPermitted(
       principal, permissions.toArray(new String[permissions.size()]));
 }
 @Override
 public boolean isPermitted(PrincipalCollection principal, String permission) {
   return realmSecurityManager.isPermitted(principal, permission);
 }
 @Override
 public AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {
   return realmSecurityManager.authenticate(token);
 }