public Collection<User> findUsers(Set<String> fields, String query)
      throws UnsupportedOperationException {
    if (fields.isEmpty()) {
      return Collections.emptyList();
    }
    if (!getSearchFields().containsAll(fields)) {
      throw new IllegalArgumentException("Search fields " + fields + " are not valid.");
    }
    if (query == null || "".equals(query)) {
      return Collections.emptyList();
    }
    // SQL LIKE queries don't map directly into a keyword/wildcard search like we want.
    // Therefore, we do a best approximiation by replacing '*' with '%' and then
    // surrounding the whole query with two '%'. This will return more data than desired,
    // but is better than returning less data than desired.
    query = "%" + query.replace('*', '%') + "%";
    if (query.endsWith("%%")) {
      query = query.substring(0, query.length() - 1);
    }

    List<String> usernames = new ArrayList<String>(50);
    Connection con = null;
    Statement stmt = null;
    ResultSet rs = null;
    try {
      con = DbConnectionManager.getConnection();
      stmt = con.createStatement();
      StringBuilder sql = new StringBuilder();
      sql.append("SELECT username FROM jiveUser WHERE");
      boolean first = true;
      if (fields.contains("Username")) {
        sql.append(" username LIKE '").append(StringUtils.escapeForSQL(query)).append("'");
        first = false;
      }
      if (fields.contains("Name")) {
        if (!first) {
          sql.append(" AND");
        }
        sql.append(" name LIKE '").append(StringUtils.escapeForSQL(query)).append("'");
        first = false;
      }
      if (fields.contains("Email")) {
        if (!first) {
          sql.append(" AND");
        }
        sql.append(" email LIKE '").append(StringUtils.escapeForSQL(query)).append("'");
      }
      rs = stmt.executeQuery(sql.toString());
      while (rs.next()) {
        usernames.add(rs.getString(1));
      }
    } catch (SQLException e) {
      Log.error(e);
    } finally {
      DbConnectionManager.closeConnection(rs, stmt, con);
    }
    return new UserCollection(usernames.toArray(new String[usernames.size()]));
  }
  private synchronized void doConfigClearspace() throws UnauthorizedException {

    Log.debug("Starting Clearspace configuration.");

    List<String> bindInterfaces = getServerInterfaces();
    if (bindInterfaces.size() == 0) {
      // We aren't up and running enough to tell Clearspace what interfaces to bind to.
      Log.debug("No bind interfaces found to config Clearspace");
      throw new IllegalStateException("There are no binding interfaces.");
    }

    try {

      XMPPServerInfo serverInfo = XMPPServer.getInstance().getServerInfo();

      String path = IM_URL_PREFIX + "configureComponent/";

      // Creates the XML with the data
      Document groupDoc = DocumentHelper.createDocument();
      Element rootE = groupDoc.addElement("configureComponent");
      Element domainE = rootE.addElement("domain");
      domainE.setText(serverInfo.getXMPPDomain());
      for (String bindInterface : bindInterfaces) {
        Element hostsE = rootE.addElement("hosts");
        hostsE.setText(bindInterface);
      }
      Element portE = rootE.addElement("port");
      portE.setText(String.valueOf(ExternalComponentManager.getServicePort()));

      Log.debug(
          "Trying to configure Clearspace with: Domain: "
              + serverInfo.getXMPPDomain()
              + ", hosts: "
              + bindInterfaces.toString()
              + ", port: "
              + port);

      executeRequest(POST, path, rootE.asXML());

      // Done, Clearspace was configured correctly, clear the task
      Log.debug("Clearspace was configured, stopping the task.");
      TaskEngine.getInstance().cancelScheduledTask(configClearspaceTask);
      configClearspaceTask = null;

    } catch (UnauthorizedException ue) {
      throw ue;
    } catch (Exception e) {
      // It is not supported exception, wrap it into an UnsupportedOperationException
      throw new UnsupportedOperationException("Unexpected error", e);
    }
  }
 public Collection<User> getUsers(int startIndex, int numResults) {
   List<String> usernames = new ArrayList<String>(numResults);
   Connection con = null;
   PreparedStatement pstmt = null;
   ResultSet rs = null;
   try {
     con = DbConnectionManager.getConnection();
     pstmt = DbConnectionManager.createScrollablePreparedStatement(con, ALL_USERS);
     rs = pstmt.executeQuery();
     DbConnectionManager.setFetchSize(rs, startIndex + numResults);
     DbConnectionManager.scrollResultSet(rs, startIndex);
     int count = 0;
     while (rs.next() && count < numResults) {
       usernames.add(rs.getString(1));
       count++;
     }
   } catch (SQLException e) {
     Log.error(e);
   } finally {
     DbConnectionManager.closeConnection(rs, pstmt, con);
   }
   return new UserCollection(usernames.toArray(new String[usernames.size()]));
 }