Index: src/test/java/info/magnolia/module/templatingkit/util/website.level1.xml
===================================================================
--- src/test/java/info/magnolia/module/templatingkit/util/website.level1.xml	(revision 0)
+++ src/test/java/info/magnolia/module/templatingkit/util/website.level1.xml	(revision 0)
@@ -0,0 +1,268 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sv:node sv:name="level1" xmlns:sv="http://www.jcp.org/jcr/sv/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <sv:property sv:name="jcr:primaryType" sv:type="Name">
+    <sv:value>mgnl:content</sv:value>
+  </sv:property>
+  <sv:property sv:name="jcr:mixinTypes" sv:type="Name">
+    <sv:value>mix:lockable</sv:value>
+  </sv:property>
+  <sv:property sv:name="jcr:uuid" sv:type="String">
+    <sv:value>b39ca0a1-052f-42f6-b5eb-13e2e9c6f842</sv:value>
+  </sv:property>
+  <sv:node sv:name="MetaData">
+    <sv:property sv:name="jcr:primaryType" sv:type="Name">
+      <sv:value>mgnl:metaData</sv:value>
+    </sv:property>
+    <sv:property sv:name="mgnl:authorid" sv:type="String">
+      <sv:value>superuser</sv:value>
+    </sv:property>
+    <sv:property sv:name="mgnl:creationdate" sv:type="Date">
+      <sv:value>2010-10-19T15:41:24.281+02:00</sv:value>
+    </sv:property>
+    <sv:property sv:name="mgnl:lastmodified" sv:type="Date">
+      <sv:value>2010-10-19T15:42:03.698+02:00</sv:value>
+    </sv:property>
+    <sv:property sv:name="mgnl:template" sv:type="String">
+      <sv:value>folder</sv:value>
+    </sv:property>
+  </sv:node>
+  <sv:node sv:name="level2">
+    <sv:property sv:name="jcr:primaryType" sv:type="Name">
+      <sv:value>mgnl:content</sv:value>
+    </sv:property>
+    <sv:property sv:name="jcr:mixinTypes" sv:type="Name">
+      <sv:value>mix:lockable</sv:value>
+    </sv:property>
+    <sv:property sv:name="jcr:uuid" sv:type="String">
+      <sv:value>2b8eee21-84d5-4c49-b0e3-5072f71a18c9</sv:value>
+    </sv:property>
+    <sv:node sv:name="MetaData">
+      <sv:property sv:name="jcr:primaryType" sv:type="Name">
+        <sv:value>mgnl:metaData</sv:value>
+      </sv:property>
+      <sv:property sv:name="mgnl:authorid" sv:type="String">
+        <sv:value>superuser</sv:value>
+      </sv:property>
+      <sv:property sv:name="mgnl:creationdate" sv:type="Date">
+        <sv:value>2010-10-19T15:41:34.941+02:00</sv:value>
+      </sv:property>
+      <sv:property sv:name="mgnl:lastmodified" sv:type="Date">
+        <sv:value>2010-10-19T15:42:09.217+02:00</sv:value>
+      </sv:property>
+      <sv:property sv:name="mgnl:template" sv:type="String">
+        <sv:value>folder</sv:value>
+      </sv:property>
+    </sv:node>
+    <sv:node sv:name="homepage">
+      <sv:property sv:name="jcr:primaryType" sv:type="Name">
+        <sv:value>mgnl:content</sv:value>
+      </sv:property>
+      <sv:property sv:name="jcr:mixinTypes" sv:type="Name">
+        <sv:value>mix:lockable</sv:value>
+      </sv:property>
+      <sv:property sv:name="jcr:uuid" sv:type="String">
+        <sv:value>da54dab3-999a-4133-b89a-aea3112031c6</sv:value>
+      </sv:property>
+      <sv:node sv:name="MetaData">
+        <sv:property sv:name="jcr:primaryType" sv:type="Name">
+          <sv:value>mgnl:metaData</sv:value>
+        </sv:property>
+        <sv:property sv:name="mgnl:authorid" sv:type="String">
+          <sv:value>superuser</sv:value>
+        </sv:property>
+        <sv:property sv:name="mgnl:creationdate" sv:type="Date">
+          <sv:value>2010-10-19T15:42:12.365+02:00</sv:value>
+        </sv:property>
+        <sv:property sv:name="mgnl:lastmodified" sv:type="Date">
+          <sv:value>2010-10-19T15:42:23.693+02:00</sv:value>
+        </sv:property>
+        <sv:property sv:name="mgnl:template" sv:type="String">
+          <sv:value>home</sv:value>
+        </sv:property>
+      </sv:node>
+      <sv:node sv:name="untitled">
+        <sv:property sv:name="jcr:primaryType" sv:type="Name">
+          <sv:value>mgnl:content</sv:value>
+        </sv:property>
+        <sv:property sv:name="jcr:mixinTypes" sv:type="Name">
+          <sv:value>mix:lockable</sv:value>
+        </sv:property>
+        <sv:property sv:name="jcr:uuid" sv:type="String">
+          <sv:value>63973bf8-9fa5-4c4f-bee4-5d4767a3eac8</sv:value>
+        </sv:property>
+        <sv:node sv:name="MetaData">
+          <sv:property sv:name="jcr:primaryType" sv:type="Name">
+            <sv:value>mgnl:metaData</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:authorid" sv:type="String">
+            <sv:value>superuser</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:creationdate" sv:type="Date">
+            <sv:value>2010-10-19T19:06:12.803+02:00</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:lastmodified" sv:type="Date">
+            <sv:value>2010-10-19T19:06:50.172+02:00</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:template" sv:type="String">
+            <sv:value>teaserPage1</sv:value>
+          </sv:property>
+        </sv:node>
+      </sv:node>
+      <sv:node sv:name="untitled0">
+        <sv:property sv:name="jcr:primaryType" sv:type="Name">
+          <sv:value>mgnl:content</sv:value>
+        </sv:property>
+        <sv:property sv:name="jcr:mixinTypes" sv:type="Name">
+          <sv:value>mix:lockable</sv:value>
+        </sv:property>
+        <sv:property sv:name="jcr:uuid" sv:type="String">
+          <sv:value>0be25d3e-783d-48b1-8e06-786de704bec1</sv:value>
+        </sv:property>
+        <sv:node sv:name="MetaData">
+          <sv:property sv:name="jcr:primaryType" sv:type="Name">
+            <sv:value>mgnl:metaData</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:activated" sv:type="Boolean">
+            <sv:value>false</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:authorid" sv:type="String">
+            <sv:value>superuser</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:creationdate" sv:type="Date">
+            <sv:value>2010-10-19T19:06:12.803+02:00</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:lastmodified" sv:type="Date">
+            <sv:value>2010-10-19T19:06:54.851+02:00</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:template" sv:type="String">
+            <sv:value>teaserPage1</sv:value>
+          </sv:property>
+        </sv:node>
+      </sv:node>
+      <sv:node sv:name="untitled1">
+        <sv:property sv:name="jcr:primaryType" sv:type="Name">
+          <sv:value>mgnl:content</sv:value>
+        </sv:property>
+        <sv:property sv:name="jcr:mixinTypes" sv:type="Name">
+          <sv:value>mix:lockable</sv:value>
+        </sv:property>
+        <sv:property sv:name="jcr:uuid" sv:type="String">
+          <sv:value>bdcfe93f-578a-4434-a20d-26b26f75b898</sv:value>
+        </sv:property>
+        <sv:node sv:name="MetaData">
+          <sv:property sv:name="jcr:primaryType" sv:type="Name">
+            <sv:value>mgnl:metaData</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:activated" sv:type="Boolean">
+            <sv:value>false</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:authorid" sv:type="String">
+            <sv:value>superuser</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:creationdate" sv:type="Date">
+            <sv:value>2010-10-19T19:06:12.803+02:00</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:lastmodified" sv:type="Date">
+            <sv:value>2010-10-19T19:07:00.088+02:00</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:template" sv:type="String">
+            <sv:value>teaserPage1</sv:value>
+          </sv:property>
+        </sv:node>
+      </sv:node>
+      <sv:node sv:name="untitled2">
+        <sv:property sv:name="jcr:primaryType" sv:type="Name">
+          <sv:value>mgnl:content</sv:value>
+        </sv:property>
+        <sv:property sv:name="jcr:mixinTypes" sv:type="Name">
+          <sv:value>mix:lockable</sv:value>
+        </sv:property>
+        <sv:property sv:name="jcr:uuid" sv:type="String">
+          <sv:value>6a8ce189-2b0f-43e7-aab9-209e107b7bf8</sv:value>
+        </sv:property>
+        <sv:node sv:name="MetaData">
+          <sv:property sv:name="jcr:primaryType" sv:type="Name">
+            <sv:value>mgnl:metaData</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:activated" sv:type="Boolean">
+            <sv:value>false</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:authorid" sv:type="String">
+            <sv:value>superuser</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:creationdate" sv:type="Date">
+            <sv:value>2010-10-19T19:06:12.803+02:00</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:lastmodified" sv:type="Date">
+            <sv:value>2010-10-19T19:07:31.707+02:00</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:template" sv:type="String">
+            <sv:value>teaserPage2</sv:value>
+          </sv:property>
+        </sv:node>
+      </sv:node>
+      <sv:node sv:name="untitled3">
+        <sv:property sv:name="jcr:primaryType" sv:type="Name">
+          <sv:value>mgnl:content</sv:value>
+        </sv:property>
+        <sv:property sv:name="jcr:mixinTypes" sv:type="Name">
+          <sv:value>mix:lockable</sv:value>
+        </sv:property>
+        <sv:property sv:name="jcr:uuid" sv:type="String">
+          <sv:value>e681592f-4c69-4cd6-bbf8-8fbf9d1b6118</sv:value>
+        </sv:property>
+        <sv:node sv:name="MetaData">
+          <sv:property sv:name="jcr:primaryType" sv:type="Name">
+            <sv:value>mgnl:metaData</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:activated" sv:type="Boolean">
+            <sv:value>false</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:authorid" sv:type="String">
+            <sv:value>superuser</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:creationdate" sv:type="Date">
+            <sv:value>2010-10-19T19:06:12.803+02:00</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:lastmodified" sv:type="Date">
+            <sv:value>2010-10-19T19:07:40.007+02:00</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:template" sv:type="String">
+            <sv:value>teaserPage1</sv:value>
+          </sv:property>
+        </sv:node>
+      </sv:node>
+      <sv:node sv:name="untitled4">
+        <sv:property sv:name="jcr:primaryType" sv:type="Name">
+          <sv:value>mgnl:content</sv:value>
+        </sv:property>
+        <sv:property sv:name="jcr:mixinTypes" sv:type="Name">
+          <sv:value>mix:lockable</sv:value>
+        </sv:property>
+        <sv:property sv:name="jcr:uuid" sv:type="String">
+          <sv:value>48a7b4d1-a596-48d2-95f1-74b24c6e62cb</sv:value>
+        </sv:property>
+        <sv:node sv:name="MetaData">
+          <sv:property sv:name="jcr:primaryType" sv:type="Name">
+            <sv:value>mgnl:metaData</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:activated" sv:type="Boolean">
+            <sv:value>false</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:authorid" sv:type="String">
+            <sv:value>superuser</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:creationdate" sv:type="Date">
+            <sv:value>2010-10-19T19:06:12.803+02:00</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:lastmodified" sv:type="Date">
+            <sv:value>2010-10-19T19:07:50.628+02:00</sv:value>
+          </sv:property>
+          <sv:property sv:name="mgnl:template" sv:type="String">
+            <sv:value>teaserPage1</sv:value>
+          </sv:property>
+        </sv:node>
+      </sv:node>
+    </sv:node>
+  </sv:node>
+</sv:node>
Index: src/test/java/info/magnolia/module/templatingkit/util/SureFireModuleManager.java
===================================================================
--- src/test/java/info/magnolia/module/templatingkit/util/SureFireModuleManager.java	(revision 0)
+++ src/test/java/info/magnolia/module/templatingkit/util/SureFireModuleManager.java	(revision 0)
@@ -0,0 +1,146 @@
+/**
+ * This file Copyright (c) 2003-2010 Magnolia International
+ * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
+ *
+ *
+ * This file is dual-licensed under both the Magnolia
+ * Network Agreement and the GNU General Public License.
+ * You may elect to use one or the other of these licenses.
+ *
+ * This file is distributed in the hope that it will be
+ * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
+ * Redistribution, except as permitted by whichever of the GPL
+ * or MNA you select, is prohibited.
+ *
+ * 1. For the GPL license (GPL), you can redistribute and/or
+ * modify this file under the terms of the GNU General
+ * Public License, Version 3, as published by the Free Software
+ * Foundation.  You should have received a copy of the GNU
+ * General Public License, Version 3 along with this program;
+ * if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * 2. For the Magnolia Network Agreement (MNA), this file
+ * and the accompanying materials are made available under the
+ * terms of the MNA which accompanies this distribution, and
+ * is available at http://www.magnolia-cms.com/mna.html
+ *
+ * Any modifications to this file must keep this entire header
+ * intact.
+ *
+ */
+
+package info.magnolia.module.templatingkit.util;
+
+import info.magnolia.module.InstallContextImpl;
+import info.magnolia.module.ModuleManagementException;
+import info.magnolia.module.ModuleManagerImpl;
+import info.magnolia.module.model.DependencyDefinition;
+import info.magnolia.module.model.ModuleDefinition;
+import info.magnolia.module.model.reader.BetwixtModuleDefinitionReader;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+
+/**
+ * Use this ModuleManager implementation for unit tests that require loading of module definitions,
+ * starting from a given root module and traversing its dependencies.
+ * <p>
+ * This is necessary because the classloader used by maven surefire plugin does not allow us to
+ * iterate jars and their contained resources to find all module definition files that exist in the
+ * classpath. Instead we traverse the dependency hierarchy, so being able to look for exact
+ * resource names.
+ *
+ * @author jfrantzius
+ *
+ */
+public class SureFireModuleManager extends ModuleManagerImpl {
+
+    private static final Logger log = Logger.getLogger(SureFireModuleManager.class);
+
+    private static class TraversingModuleReader extends BetwixtModuleDefinitionReader {
+
+        private final String rootModuleName;
+
+        TraversingModuleReader(String rootModuleName) {
+            this.rootModuleName = rootModuleName;
+        }
+
+        @Override
+        public Map<String, ModuleDefinition> readAll() throws ModuleManagementException {
+            ModuleDefinition moduleDef = readUsingContextClassloader(rootModuleName);
+            Map<String, ModuleDefinition> result = new HashMap<String, ModuleDefinition>();
+            addDependenciesRecursively(moduleDef, result);
+            return result;
+        }
+
+        private void addDependenciesRecursively(ModuleDefinition rootModuleDef, Map<String, ModuleDefinition> defs) throws ModuleManagementException {
+            Collection<DependencyDefinition> dependencies = rootModuleDef.getDependencies();
+            for (DependencyDefinition dependencyDefinition : dependencies) {
+                if (!defs.containsKey(dependencyDefinition.getName())) {
+                    ModuleDefinition dependency = readUsingContextClassloader(dependencyDefinition.getName());
+                    if (dependency != null) {
+                        defs.put(dependencyDefinition.getName(), dependency);
+                        addDependenciesRecursively(dependency, defs);
+                    }
+                    else {
+                        log
+                            .warn("Cannot read module definition for dependency "
+                                + dependencyDefinition.getName()
+                                + " of module "
+                                + rootModuleDef
+                                + ". Do the dependencies in the module's pom.xml differ from its declared dependencies in the magnolia module definition?");
+                    }
+                }
+            }
+        }
+
+        public ModuleDefinition readUsingContextClassloader(String moduleName) throws ModuleManagementException {
+            // during surefire run, BetwixtModuleDefinitionReader's
+            // getClass().getResourcesAsStream() doesn't
+            // see the required resources, so must redefine it here and use
+            // Thread.getContextClassLoader(), which seems to see all required resources
+            final String pathPrefix = "META-INF/magnolia/";
+            InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(pathPrefix + moduleName + ".xml");
+            if (resourceAsStream == null) {
+                // try lowercase
+                resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(pathPrefix + moduleName.toLowerCase() + ".xml");
+            }
+            if (resourceAsStream != null) {
+                final InputStreamReader reader = new InputStreamReader(resourceAsStream);
+                try {
+                    return read(reader);
+                }
+                finally {
+                    try {
+                        reader.close();
+                    }
+                    catch (IOException e) {
+                        log.error("Can't close input for " + moduleName, e);
+                    }
+                }
+            }
+            else {
+                return null;
+            }
+        }
+
+    }
+
+
+
+    public SureFireModuleManager(String rootModuleName) {
+        // read module definitions from classpath, starting with the given module, traversing its
+        // dependencies
+        super(new InstallContextImpl(), new TraversingModuleReader(rootModuleName));
+    }
+}
\ No newline at end of file
Index: src/test/java/info/magnolia/module/templatingkit/util/STKUtilQueryTest.java
===================================================================
--- src/test/java/info/magnolia/module/templatingkit/util/STKUtilQueryTest.java	(revision 0)
+++ src/test/java/info/magnolia/module/templatingkit/util/STKUtilQueryTest.java	(revision 0)
@@ -0,0 +1,113 @@
+/**
+ * This file Copyright (c) 2003-2010 Magnolia International
+ * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
+ *
+ *
+ * This file is dual-licensed under both the Magnolia
+ * Network Agreement and the GNU General Public License.
+ * You may elect to use one or the other of these licenses.
+ *
+ * This file is distributed in the hope that it will be
+ * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
+ * Redistribution, except as permitted by whichever of the GPL
+ * or MNA you select, is prohibited.
+ *
+ * 1. For the GPL license (GPL), you can redistribute and/or
+ * modify this file under the terms of the GNU General
+ * Public License, Version 3, as published by the Free Software
+ * Foundation.  You should have received a copy of the GNU
+ * General Public License, Version 3 along with this program;
+ * if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * 2. For the Magnolia Network Agreement (MNA), this file
+ * and the accompanying materials are made available under the
+ * terms of the MNA which accompanies this distribution, and
+ * is available at http://www.magnolia-cms.com/mna.html
+ *
+ * Any modifications to this file must keep this entire header
+ * intact.
+ *
+ */
+
+package info.magnolia.module.templatingkit.util;
+
+import info.magnolia.cms.beans.config.PropertiesInitializer;
+import info.magnolia.cms.core.Content;
+import info.magnolia.cms.core.HierarchyManager;
+import info.magnolia.context.MgnlContext;
+import info.magnolia.importexport.DataTransporter;
+import info.magnolia.module.ModuleManager;
+import info.magnolia.objectfactory.Components;
+import info.magnolia.test.ComponentsTestUtil;
+import info.magnolia.test.RepositoryTestCase;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jcr.ImportUUIDBehavior;
+import javax.jcr.RepositoryException;
+
+
+
+/**
+ * Tests for filtering, sorting and shrinking by query in STKUtil.
+ * @author jfrantzius
+ *
+ */
+public class STKUtilQueryTest extends RepositoryTestCase {
+
+    protected void initDefaultImplementations() throws IOException {
+        PropertiesInitializer.getInstance().loadBeanProperties();
+        // provide our own ModuleManager implementation that is able to read the required module
+        // definitions e.g. from surefire classpath
+        ComponentsTestUtil.setInstance(ModuleManager.class, new SureFireModuleManager("standard-templating-kit"));
+        assertTrue(Components.getSingleton(ModuleManager.class) instanceof SureFireModuleManager);
+        PropertiesInitializer.getInstance().loadAllModuleProperties();
+    }
+
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        InputStream xmlStream = this.getClass().getClassLoader().getResourceAsStream("info/magnolia/module/templatingkit/util/website.level1.xml");
+        DataTransporter.importXmlStream(
+            xmlStream,
+            "website",
+            "/",
+            "name matters only when importing a file that needs XSL transformation",
+            false,
+            ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW,
+            true,
+            true);
+    }
+
+    /**
+     *
+     * @throws RepositoryException
+     */
+    public void testQueryOptions() throws RepositoryException {
+        HierarchyManager hm = MgnlContext.getHierarchyManager("website");
+        Content level1Node = hm.getContent("/level1");
+        // query those with lastModified smaller than the untitled2 node, should yield untitled,
+        // untitled0 and untitled1,
+        // ordered by mastModified descending
+        String andClause = "mgnl:lastmodified < TIMESTAMP '2010-10-19T19:07:31.707+02:00'";
+        List<Content> firstThreeOrderedDesc = STKUtil.getContentListByTemplateName(
+            level1Node,
+            "teaserPage1",
+            Integer.MAX_VALUE,
+            andClause,
+            "mgnl:lastmodified desc");
+        assertEquals(3, firstThreeOrderedDesc.size());
+        Iterator<Content> iterator = firstThreeOrderedDesc.iterator();
+        assertEquals("untitled1", iterator.next().getName());
+        assertEquals("untitled0", iterator.next().getName());
+        assertEquals("untitled", iterator.next().getName());
+    }
+
+}
Index: src/main/java/info/magnolia/module/templatingkit/util/STKUtil.java
===================================================================
--- src/main/java/info/magnolia/module/templatingkit/util/STKUtil.java	(revision 38286)
+++ src/main/java/info/magnolia/module/templatingkit/util/STKUtil.java	(working copy)
@@ -409,12 +409,32 @@
     }
 
     public static List<Content> getContentListByTemplateName(Content searchRoot, String templateName) throws RepositoryException{
+    	return getContentListByTemplateName(searchRoot, templateName, Integer.MAX_VALUE, null, null);
+    }
+
+    /**
+     * Find content objects with a given template below a given search root.
+     * @param searchRoot
+     * @param templateName
+     * @param maxResultSize setting this can drastically improve query performance, if you are interested only in a fixed number of leading result objects
+     * @param andClause an additional "AND" clause in SQL syntax, excluding the "AND" itself, e.g. "date IS NOT NULL"
+     * @param orderByClause an "ORDER BY" clause in SQL syntax, excluding the "ORDER BY" itself, e.g. "date desc" or "date asc"
+     * @return
+     * @throws RepositoryException
+     */
+    public static List<Content> getContentListByTemplateName(Content searchRoot, String templateName, int maxResultSize, String andClause, String orderByClause) throws RepositoryException{
         HierarchyManager hm = searchRoot.getHierarchyManager();
         String path  = searchRoot.getHandle();
         String repository = hm.getName();
 
-        String sql = "select * from nt:base where jcr:path like '" + path +"/%' and mgnl:template = '"+templateName+"'";
-        List<Content> itemsList = (List<Content>) QueryUtil.query(repository, sql, Query.SQL , ItemType.CONTENT.getSystemName());
+        StringBuffer sql = new StringBuffer("select * from nt:base where jcr:path like '" + path +"/%' and mgnl:template = '"+templateName+"'");
+        if (andClause != null) {
+            sql.append(" AND " + andClause);
+        }
+        if (orderByClause != null) {
+            sql.append(" ORDER BY " + orderByClause);
+        }
+        List<Content> itemsList = (List<Content>) QueryUtil.query(repository, sql.toString(), Query.SQL , ItemType.CONTENT.getSystemName(), maxResultSize);
         // wrap all
         for (int i = 0; i < itemsList.size(); i++) {
             itemsList.set(i, new I18nContentWrapper(itemsList.get(i)));
@@ -431,6 +451,10 @@
     }
 
     public static List<Content> getContentListByTemplateCategorySubCategory(Content siteRoot, String category, String subCategory) throws RepositoryException {
+    	return getContentListByTemplateCategorySubCategory(siteRoot, subCategory, subCategory, Integer.MAX_VALUE, null, null);
+    }
+
+    public static List<Content> getContentListByTemplateCategorySubCategory(Content siteRoot, String category, String subCategory, int maxResultSize, String andClause, String orderBy) throws RepositoryException {
 
         final List<Content> templates = new ArrayList<Content>();
 
@@ -441,7 +465,7 @@
                 final STKTemplate stkTemplate = (STKTemplate)template;
                 if(StringUtils.equals(stkTemplate.getCategory(), category) //TODO: the second condition fails
                         && (StringUtils.isEmpty(subCategory) || StringUtils.equals(stkTemplate.getSubcategory(), subCategory) )) {
-                    templates.addAll(getContentListByTemplateName(siteRoot, template.getName()));
+                    templates.addAll(getContentListByTemplateName(siteRoot, template.getName(), maxResultSize, andClause, orderBy));
                 }
             }
         }
