code: protected Query createQuery(String typeName, List<AttributeDescriptor> schema, Criterion criterion,
  			int maxFeatures, int startIndex, List<String> attributeNames, String crs) throws IOException {
  		CriterionToFilterConverter converter = criterionToFilterFactory.createConverter();
  		Filter filter = converter.convert(criterion, schema);
  		Query query = null;
  		if (attributeNames == null) {
  			query = new Query(typeName, filter, maxFeatures > 0 ? maxFeatures : Integer.MAX_VALUE, Query.ALL_NAMES,
  					null);
  		} else {
  			query = new Query(typeName, filter, maxFeatures > 0 ? maxFeatures : Integer.MAX_VALUE,
  					attributeNames.toArray(new String[attributeNames.size()]), null);
  		}
  		if (startIndex > 0) {
  			query.setStartIndex(startIndex);
  		}
  		if (null != crs) {
  			try {
  				// always use the urn version as otherwise servers disagree on axis order
  				if (crs.equalsIgnoreCase("EPSG:4326")) {
  					crs = "urn:x-ogc:def:crs:EPSG:4326";
  				}
  				query.setCoordinateSystem(CRS.decode(crs));
  			} catch (NoSuchAuthorityCodeException e) { // assume non-fatal
  				log.warn("Problem getting CRS for id " + crs + ": " + e.getMessage());
  			} catch (FactoryException e) {
  				// assume non-fatal
  				log.warn("Problem getting CRS for id " + crs + ": " + e.getMessage());
  			}
  		}
  		return query;
  	}
docs: Query a geotools source for features using the criterion as a filter.
  
  @param source
  @param criterion
  @param attributeNames
  @param crs
  @return
  @throws IOException
  @throws GeomajasException