Index: perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/admin/groups/ListGroupsPanel.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/admin/groups/ListGroupsPanel.java	(revision 40081)
+++ perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/admin/groups/ListGroupsPanel.java	(revision )
@@ -113,7 +113,7 @@
 
         this.groupDataProvider = groupDataProvider;
         TextField<String> search = new TextField<String>("search-query",
-                                                         new PropertyModel<String>(this.groupDataProvider, "query"));
+                                                         new PropertyModel<String>(this.groupDataProvider, "searchTerm"));
         search.add(StringValidator.minimumLength(1));
         search.setRequired(false);
         search.add(new DefaultFocusBehavior());
Index: perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/admin/SearchableDataProvider.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/admin/SearchableDataProvider.java	(revision 40081)
+++ perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/admin/SearchableDataProvider.java	(revision )
@@ -30,7 +30,6 @@
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.builder.EqualsBuilder;
 import org.apache.commons.lang.builder.HashCodeBuilder;
-import org.apache.wicket.Session;
 import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
 import org.hippoecm.frontend.model.JcrNodeModel;
 import org.hippoecm.frontend.model.event.IObservable;
@@ -81,10 +80,13 @@
             {" or ", " OR "}
     };
 
-    private final String queryAll;
+    private final String searchAllSqlStatement;
+
+    private final String searchTermSqlStatementTemplate;
+
     private final String observePath;
     private final String[] observeNodeTypes;
-    private String query;
+    private String searchTerm;
     private List<T> list = new ArrayList<T>();
     private volatile boolean dirty = true;
     private IObservationContext<JcrNodeModel> context;
@@ -93,12 +95,14 @@
     /**
      * Creates a searchable provider.
      *
-     * @param queryAll         the JCR SQL query to search for all beans
+     * @param searchAllSqlStatement             the JCR SQL searchTerm to search for all beans
+     * @param searchTermSqlStatementTemplate    the JCR SQL template to search with a specific search term
      * @param observePath      the JCR path to observe for changes
      * @param observeNodeTypes the node types to observe for changes
      */
-    public SearchableDataProvider(String queryAll, String observePath, String... observeNodeTypes) {
-        this.queryAll = queryAll;
+    public SearchableDataProvider(String searchAllSqlStatement, String searchTermSqlStatementTemplate, String observePath, String... observeNodeTypes) {
+        this.searchAllSqlStatement = searchAllSqlStatement;
+        this.searchTermSqlStatementTemplate = searchTermSqlStatementTemplate;
         this.observePath = observePath;
         this.observeNodeTypes = observeNodeTypes;
     }
@@ -113,7 +117,7 @@
     protected abstract T createBean(Node node) throws RepositoryException;
 
     public Iterator<T> iterator(int first, int count) {
-        populateList(query);
+        populateList(searchTerm);
         List<T> result = new ArrayList<T>();
         for (int i = first; i < (count + first); i++) {
             result.add(list.get(i));
@@ -122,7 +126,7 @@
     }
 
     public int size() {
-        populateList(query);
+        populateList(searchTerm);
         return list.size();
     }
 
@@ -133,20 +137,20 @@
     /**
      * Populate list, refresh when a new session id is found or when dirty
      *
-     * @param query the query used for free text search to limit the list
+     * @param searchTerm the searchTerm used for free text search to limit the list
      */
-    private void populateList(String query) {
+    private void populateList(final String searchTerm) {
         // synchronize on the runtime class, as there can be multiple implementations of this abstract class
         if (!dirty) {
             return;
         }
         list.clear();
 
-        StringBuilder sqlQuery = new StringBuilder(queryAll);
-        if (StringUtils.isNotEmpty(query)) {
-            sqlQuery.append(" and CONTAINS(., '");
-            sqlQuery.append(query);
-            sqlQuery.append("')");
+        final StringBuilder sqlQuery;
+        if (StringUtils.isNotEmpty(searchTerm)) {
+            sqlQuery = new StringBuilder(searchTermSqlStatementTemplate.replace("{}", searchTerm));
+        } else {
+            sqlQuery = new StringBuilder(searchAllSqlStatement);
         }
         log.debug("Executing query: {}", sqlQuery);
         try {
@@ -172,30 +176,30 @@
     }
 
     /**
-     * Set the search query. Only beans that match the query will be included. A '*' in the query acts as a wildcard.
-     * When the query is null or empty, all beans will be included.
+     * Set the search searchTerm. Only beans that match the searchTerm will be included. A '*' in the searchTerm acts as a wildcard.
+     * When the searchTerm is null or empty, all beans will be included.
      * <p/>
-     * N.B. this method is needed to let Wicket use setQuery/getQuery in a PropertyModel instead of reflection.
+     * N.B. this method is needed to let Wicket use setSearchTerm/getSearchTerm in a PropertyModel instead of reflection.
      *
-     * @param newQuery the query to search for users with
+     * @param searchTerm the searchTerm to search for users with
      */
     @SuppressWarnings("unused")
-    public void setQuery(final String newQuery) {
-        this.query = escapeJcrContainsQuery(newQuery);
+    public void setSearchTerm(final String searchTerm) {
+        this.searchTerm = escapeJcrContainsQuery(searchTerm);
         dirty = true;
     }
 
     /**
-     * Returns the query used by this provider to limit the provided beans. The query can be null or empty, in which
+     * Returns the searchTerm used by this provider to limit the provided beans. The searchTerm can be null or empty, in which
      * case there are no limitations and all beans will be included.
      * <p/>
-     * N.B. this method is needed to let Wicket use setQuery/getQuery in a PropertyModel instead of reflection.
+     * N.B. this method is needed to let Wicket use setSearchTerm/getSearchTerm in a PropertyModel instead of reflection.
      *
-     * @return the search query to use
+     * @return the search searchTerm to use
      */
     @SuppressWarnings("unused")
-    public String getQuery() {
-        return this.query;
+    public String getSearchTerm() {
+        return this.searchTerm;
     }
 
     /**
@@ -335,20 +339,20 @@
         SearchableDataProvider other = (SearchableDataProvider) object;
 
         return new EqualsBuilder()
-                .append(queryAll, other.queryAll)
+                .append(searchAllSqlStatement, other.searchAllSqlStatement)
                 .append(observePath, other.observePath)
                 .append(observeNodeTypes, other.observeNodeTypes)
-                .append(query, other.query)
+                .append(searchTerm, other.searchTerm)
                 .isEquals();
     }
 
     @Override
     public int hashCode() {
         return new HashCodeBuilder(57, 433)
-                .append(queryAll)
+                .append(searchAllSqlStatement)
                 .append(observePath)
                 .append(observeNodeTypes)
-                .append(query)
+                .append(searchTerm)
                 .toHashCode();
     }
 
Index: perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/admin/users/UserDataProvider.java
===================================================================
--- perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/admin/users/UserDataProvider.java	(revision 40081)
+++ perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/admin/users/UserDataProvider.java	(revision 40081)
@@ -1,76 +0,0 @@
-/*
- *  Copyright 2008-2013 Hippo B.V. (http://www.onehippo.com)
- * 
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- * 
- *       http://www.apache.org/licenses/LICENSE-2.0
- * 
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.hippoecm.frontend.plugins.cms.admin.users;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.apache.commons.collections.comparators.NullComparator;
-import org.apache.wicket.model.IModel;
-import org.hippoecm.frontend.plugins.cms.admin.SearchableDataProvider;
-import org.hippoecm.repository.api.HippoNodeType;
-
-
-public class UserDataProvider extends SearchableDataProvider<User> {
-
-    private static final long serialVersionUID = 1L;
-    private static final String QUERY_USER_LIST = "SELECT * FROM " + HippoNodeType.NT_USER
-            + " where (hipposys:system <> 'true' or hipposys:system IS NULL)";
-
-    public UserDataProvider() {
-        super(QUERY_USER_LIST, "/hippo:configuration/hippo:users", HippoNodeType.NT_USER, HippoNodeType.NT_USERFOLDER);
-        setSort("username", true);
-    }
-
-    @Override
-    public IModel<User> model(final User user) {
-        return new DetachableUser(user);
-    }
-
-    @Override
-    protected User createBean(final Node node) throws RepositoryException {
-        return new User(node);
-    }
-
-    @Override
-    public Iterator<User> iterator(int first, int count) {
-        List<User> userList = new ArrayList<User>(getList());
-
-        final Comparator<String> nullSafeComparator = new NullComparator(false);
-
-        Collections.sort(userList, new Comparator<User>() {
-            public int compare(User user1, User user2) {
-                int direction = getSort().isAscending() ? 1 : -1;
-
-                if ("frontend:firstname".equals(getSort().getProperty())) {
-                    return direction * (nullSafeComparator.compare(user1.getFirstName(), user2.getFirstName()));
-                } else if ("frontend:lastname".equals(getSort().getProperty())) {
-                    return direction * (nullSafeComparator.compare(user1.getLastName(), user2.getLastName()));
-                } else {
-                    return direction * (nullSafeComparator.compare(user1.getUsername(), user2.getUsername()));
-                }
-            }
-        });
-
-        return userList.subList(first, Math.min(first + count, userList.size())).iterator();
-    }
-}
Index: perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/admin/groups/GroupDataProvider.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/admin/groups/GroupDataProvider.java	(revision 40081)
+++ perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/admin/groups/GroupDataProvider.java	(revision )
@@ -31,11 +31,21 @@
 public class GroupDataProvider extends SearchableDataProvider<Group> {
 
     private static final long serialVersionUID = 1L;
-    private static final String QUERY_GROUP_LIST = "SELECT * FROM " + HippoNodeType.NT_GROUP
-            + " where (hipposys:system <> 'true' or hipposys:system IS NULL)";
 
+    private static final String QUERY_ALL_GROUP_LIST = "SELECT * " +
+                " FROM " + HippoNodeType.NT_GROUP +
+                " WHERE (hipposys:system <> 'true' OR hipposys:system IS NULL)";
+
+    private static final String QUERY_GROUP_LIST_TEMPLATE = "SELECT * " +
+                    " FROM " + HippoNodeType.NT_GROUP +
+                    " WHERE (hipposys:system <> 'true' OR hipposys:system IS NULL) OR " +
+                          " (  jcr:contains(hipposys:description, '{}') OR " +
+                              "jcr:contains(hipposys:members, '{}') OR " +
+                              "jcr:contains(hipposys:groups, '{}') " +
+                            ") ";
+
     public GroupDataProvider() {
-        super(QUERY_GROUP_LIST, "/hippo:configuration/hippo:groups", HippoNodeType.NT_GROUP, HippoNodeType.NT_GROUPFOLDER);
+        super(QUERY_ALL_GROUP_LIST, QUERY_GROUP_LIST_TEMPLATE, "/hippo:configuration/hippo:groups", HippoNodeType.NT_GROUP, HippoNodeType.NT_GROUPFOLDER);
         setSort("groupname", true);
     }
 
Index: perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/admin/users/ListUsersPanel.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/admin/users/ListUsersPanel.java	(revision 40081)
+++ perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/admin/users/ListUsersPanel.java	(revision )
@@ -168,7 +168,7 @@
         add(form);
 
         final TextField<String> search = new TextField<String>("search-query",
-                                                               new PropertyModel<String>(userDataProvider, "query"));
+                                                               new PropertyModel<String>(userDataProvider, "searchTerm"));
         search.add(StringValidator.minimumLength(1));
         search.setRequired(false);
         search.add(new DefaultFocusBehavior());
