Index: /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUConstants.java
===================================================================
--- /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUConstants.java	(revision 6815)
+++ /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUConstants.java	(revision 6816)
@@ -155,5 +155,5 @@
     public static final String SRU_RECORD_TOO_LARGE_TO_SEND =
             SRU_DIAGNOSTIC_URI_PREFIX + 70;
-    public static final String SRU_UNSUPPORTED_RECORD_PACKING =
+    public static final String SRU_UNSUPPORTED_XML_ESCAPING_VALUE =
             SRU_DIAGNOSTIC_URI_PREFIX + 71;
     public static final String SRU_XPATH_RETRIEVAL_UNSUPPORTED =
Index: /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUDiagnostic.java
===================================================================
--- /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUDiagnostic.java	(revision 6815)
+++ /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUDiagnostic.java	(revision 6816)
@@ -257,5 +257,5 @@
         } else if (uri.equals(SRUConstants.SRU_RECORD_TOO_LARGE_TO_SEND)) {
             return "Record too large to send";
-        } else if (uri.equals(SRUConstants.SRU_UNSUPPORTED_RECORD_PACKING)) {
+        } else if (uri.equals(SRUConstants.SRU_UNSUPPORTED_XML_ESCAPING_VALUE)) {
             return "Unsupported record packing";
         } else if (uri.equals(SRUConstants.SRU_XPATH_RETRIEVAL_UNSUPPORTED)) {
Index: /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRURecordPacking.java
===================================================================
--- /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRURecordPacking.java	(revision 6815)
+++ /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRURecordPacking.java	(revision 6816)
@@ -18,15 +18,17 @@
 
 /**
- * SRU Record packing
+ * SRU 2.0 record packing.
  */
 public enum SRURecordPacking {
     /**
-     * XML record packing
+     * The client requests that the server should supply records strictly
+     * according to the requested schema.
      */
-    XML,
+    PACKED,
 
     /**
-     * String record packing
+     * The server is free to allow the location of application data to vary
+     * within the record.
      */
-    STRING
+    UNPACKED
 } // enum SRURecordPacking
Index: /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRURecordXmlEscaping.java
===================================================================
--- /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRURecordXmlEscaping.java	(revision 6816)
+++ /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRURecordXmlEscaping.java	(revision 6816)
@@ -0,0 +1,32 @@
+/**
+ * This software is copyright (c) 2011-2013 by
+ *  - Institut fuer Deutsche Sprache (http://www.ids-mannheim.de)
+ * This is free software. You can redistribute it
+ * and/or modify it under the terms described in
+ * the GNU General Public License v3 of which you
+ * should have received a copy. Otherwise you can download
+ * it from
+ *
+ *   http://www.gnu.org/licenses/gpl-3.0.txt
+ *
+ * @copyright Institut fuer Deutsche Sprache (http://www.ids-mannheim.de)
+ *
+ * @license http://www.gnu.org/licenses/gpl-3.0.txt
+ *  GNU General Public License v3
+ */
+package eu.clarin.sru.server;
+
+/**
+ * SRU Record XML escaping.
+ */
+public enum SRURecordXmlEscaping {
+    /**
+     * XML record packing
+     */
+    XML,
+
+    /**
+     * String record packing
+     */
+    STRING
+} // enum SRURecordXmlEscaping
Index: /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRURenderBy.java
===================================================================
--- /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRURenderBy.java	(revision 6816)
+++ /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRURenderBy.java	(revision 6816)
@@ -0,0 +1,36 @@
+/**
+ * This software is copyright (c) 2011-2013 by
+ *  - Institut fuer Deutsche Sprache (http://www.ids-mannheim.de)
+ * This is free software. You can redistribute it
+ * and/or modify it under the terms described in
+ * the GNU General Public License v3 of which you
+ * should have received a copy. Otherwise you can download
+ * it from
+ *
+ *   http://www.gnu.org/licenses/gpl-3.0.txt
+ *
+ * @copyright Institut fuer Deutsche Sprache (http://www.ids-mannheim.de)
+ *
+ * @license http://www.gnu.org/licenses/gpl-3.0.txt
+ *  GNU General Public License v3
+ */
+package eu.clarin.sru.server;
+
+/**
+ * SRU Record XML escaping.
+ */
+public enum SRURenderBy {
+    /**
+     * The client requests that the server simply return this URL in the
+     * response, in the href attribute of the xml-stylesheet processing
+     * instruction before the response xml
+     */
+    CLIENT,
+
+    /**
+     * The client requests that the server format the response according to the
+     * specified stylesheet, assuming the default SRU response schema as input
+     * to the stylesheet.
+     */
+    SERVER
+} // enum SRURenderBy
Index: /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRURequest.java
===================================================================
--- /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRURequest.java	(revision 6815)
+++ /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRURequest.java	(revision 6816)
@@ -81,6 +81,17 @@
 
     /**
-     * Get the <em>recordPacking</em> parameter of this request. Only available
-     * for <em>explain</em> and <em>searchRetrieve</em> requests.
+     * Get the <em>recordXmlEscpaing</em> (SRU 2.0) or <em>recordPacking</em>
+     * (SRU 1.1 and SRU 1.2) parameter of this request. Only available for
+     * <em>explain</em> and <em>searchRetrieve</em> requests.
+     *
+     * @return the record XML escaping method
+     * @see SRURecordXmlEscaping
+     */
+    public SRURecordXmlEscaping getRecordXmlEscaping();
+
+
+    /**
+     * Get the <em>recordPacking</em> (SRU 2.0) parameter of this request. Only
+     * available for <em>searchRetrieve</em> requests.
      *
      * @return the record packing method
@@ -88,5 +99,4 @@
      */
     public SRURecordPacking getRecordPacking();
-
 
     /**
@@ -118,16 +128,4 @@
      */
     public int getMaximumRecords();
-
-
-    /**
-     * Get the <em>recordSchema</em> parameter of this request. Only available
-     * for <em>searchRetrieve</em> requests.
-     *
-     * @return the record schema name or <code>null</code> if no value was
-     *         supplied for this request
-     * @deprecated use {@link #getRecordSchemaIdentifier()}
-     */
-    @Deprecated
-    public String getRecordSchemaName();
 
 
@@ -212,4 +210,35 @@
      */
     public String getStylesheet();
+
+
+    /**
+     * Get the <em>renderBy</em> parameter of this request.
+     *
+     * @return the renderBy parameter or <code>null</code> if no value was
+     *         supplied for this request
+     */
+    public SRURenderBy getRenderBy();
+
+
+    /**
+     * (SRU 2.0) The request parameter <em>responseType</em>, paired with the
+     * Internet media type specified for the response (via either the httpAccept
+     * parameter or http accept header) determines the schema for the response.
+     *
+     * @return the value of the responeType request parameter or
+     *         <code>null</code> if no value was supplied for this request
+     */
+    public String getResponeType();
+
+
+    /**
+     * (SRU 2.0) The request parameter <em>httpAccept</em> may be supplied to
+     * indicate the preferred format of the response. The value is an Internet
+     * media type.
+     *
+     * @return the value of the httpAccept request parameter or
+     *         <code>null</code> if no value was supplied for
+     */
+    public String getHttpAccept();
 
 
Index: /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRURequestImpl.java
===================================================================
--- /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRURequestImpl.java	(revision 6815)
+++ /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRURequestImpl.java	(revision 6816)
@@ -35,31 +35,45 @@
     private static final Logger logger =
             LoggerFactory.getLogger(SRURequest.class);
-    private static final String PARAM_OPERATION         = "operation";
-    private static final String PARAM_VERSION           = "version";
-    private static final String PARAM_RECORD_PACKING    = "recordPacking";
-    private static final String PARAM_STYLESHEET        = "stylesheet";
-    private static final String PARAM_QUERY             = "query";
-    private static final String PARAM_START_RECORD      = "startRecord";
-    private static final String PARAM_MAXIMUM_RECORDS   = "maximumRecords";
-    private static final String PARAM_RECORD_SCHEMA     = "recordSchema";
-    private static final String PARAM_RECORD_X_PATH     = "recordXPath";
-    private static final String PARAM_RESULT_SET_TTL    = "resultSetTTL";
-    private static final String PARAM_SORT_KEYS         = "sortKeys";
-    private static final String PARAM_SCAN_CLAUSE       = "scanClause";
-    private static final String PARAM_RESPONSE_POSITION = "responsePosition";
-    private static final String PARAM_MAXIMUM_TERMS     = "maximumTerms";
-    private static final String OP_EXPLAIN              = "explain";
-    private static final String OP_SCAN                 = "scan";
-    private static final String OP_SEARCH_RETRIEVE      = "searchRetrieve";
-    private static final String VERSION_1_1             = "1.1";
-    private static final String VERSION_1_2             = "1.2";
-    private static final String RECORD_PACKING_XML      = "xml";
-    private static final String RECORD_PACKING_STRING   = "string";
-    private static final String PARAM_EXTENSION_PREFIX  = "x-";
-    private static final String X_UNLIMITED_RESULTSET   = "x-unlimited-resultset";
-    private static final String X_UNLIMITED_TERMLIST    = "x-unlimited-termlist";
-    private static final String X_INDENT_RESPONSE       = "x-indent-response";
-    private static final int DEFAULT_START_RECORD       = 1;
-    private static final int DEFAULT_RESPONSE_POSITION  = 1;
+    /* general / explain related parameter names */
+    private static final String PARAM_OPERATION            = "operation";
+    private static final String PARAM_VERSION              = "version";
+    private static final String PARAM_STYLESHEET           = "stylesheet";
+    private static final String PARAM_RENDER_BY            = "renderedBy";
+    private static final String PARAM_HTTP_ACCEPT          = "httpAccept";
+    private static final String PARAM_RESPONSE_TYPE        = "responseType";
+    /* searchRetrieve related parameter names */
+    private static final String PARAM_QUERY                = "query";
+    private static final String PARAM_QUERY_TYPE           = "queryType";
+    private static final String PARAM_START_RECORD         = "startRecord";
+    private static final String PARAM_MAXIMUM_RECORDS      = "maximumRecords";
+    private static final String PARAM_RECORD_XML_ESCAPING  = "recordXMLEscaping";
+    private static final String PARAM_RECORD_PACKING       = "recordPacking";
+    private static final String PARAM_RECORD_SCHEMA        = "recordSchema";
+    private static final String PARAM_RECORD_X_PATH        = "recordXPath";
+    private static final String PARAM_RESULT_SET_TTL       = "resultSetTTL";
+    private static final String PARAM_SORT_KEYS            = "sortKeys";
+    /* scan related parameter names */
+    private static final String PARAM_SCAN_CLAUSE          = "scanClause";
+    private static final String PARAM_RESPONSE_POSITION    = "responsePosition";
+    private static final String PARAM_MAXIMUM_TERMS        = "maximumTerms";
+    /* operations */
+    private static final String OP_EXPLAIN                 = "explain";
+    private static final String OP_SCAN                    = "scan";
+    private static final String OP_SEARCH_RETRIEVE         = "searchRetrieve";
+    private static final String VERSION_1_1                = "1.1";
+    private static final String VERSION_1_2                = "1.2";
+    /* various parameter values */
+    private static final String RECORD_XML_ESCAPING_XML    = "xml";
+    private static final String RECORD_XML_ESCPAING_STRING = "string";
+    private static final String RECORD_PACKING_PACKED      = "packed";
+    private static final String RECORD_PACKING_UNPACKED    = "unpacked";
+    private static final String RENDER_BY_CLIENT           = "client";
+    private static final String RENDER_BY_SERVER           = "server";
+    private static final String PARAM_EXTENSION_PREFIX     = "x-";
+    private static final String X_UNLIMITED_RESULTSET      = "x-unlimited-resultset";
+    private static final String X_UNLIMITED_TERMLIST       = "x-unlimited-termlist";
+    private static final String X_INDENT_RESPONSE          = "x-indent-response";
+    private static final int DEFAULT_START_RECORD          = 1;
+    private static final int DEFAULT_RESPONSE_POSITION     = 1;
     private final SRUServerConfig config;
     private final HttpServletRequest request;
@@ -67,10 +81,15 @@
     private SRUOperation operation;
     private SRUVersion version;
+    private SRURecordXmlEscaping recordXmlEscaping;
     private SRURecordPacking recordPacking;
     private CQLNode query;
+    private String queryType;
     private int startRecord = DEFAULT_START_RECORD;
     private int maximumRecords = -1;
     private String recordSchemaIdentifier;
     private String stylesheet;
+    private SRURenderBy renderBy;
+    private String responseType;
+    private String httpAccept;
     private String recordXPath;
     private int resultSetTTL = -1;
@@ -81,8 +100,14 @@
 
     private static enum Parameter {
-        RECORD_PACKING,
+        STYLESHEET,
+        RENDER_BY,
+        HTTP_ACCEPT,
+        RESPONSE_TYPE,
         QUERY,
+        QUERY_TYPE,
         START_RECORD,
         MAXIMUM_RECORDS,
+        RECORD_XML_ESCAPING,
+        RECORD_PACKING,
         RECORD_SCHEMA,
         RECORD_XPATH,
@@ -92,5 +117,4 @@
         RESPONSE_POSITION,
         MAXIMUM_TERMS,
-        STYLESHEET
     }
 
@@ -113,14 +137,42 @@
         }
 
-        public String getName() {
+        public String getName(SRUVersion version) {
             switch (parameter) {
-            case RECORD_PACKING:
-                return PARAM_RECORD_PACKING;
+            case STYLESHEET:
+                return PARAM_STYLESHEET;
+            case RENDER_BY:
+                return PARAM_RENDER_BY;
+            case HTTP_ACCEPT:
+                return PARAM_HTTP_ACCEPT;
+            case RESPONSE_TYPE:
+                return PARAM_RESPONSE_TYPE;
             case QUERY:
                 return PARAM_QUERY;
+            case QUERY_TYPE:
+                return PARAM_QUERY_TYPE;
             case START_RECORD:
                 return PARAM_START_RECORD;
             case MAXIMUM_RECORDS:
                 return PARAM_MAXIMUM_RECORDS;
+            case RECORD_XML_ESCAPING:
+                /*
+                 * 'recordPacking' was renamed to 'recordXMLEscaping' in SRU
+                 * 2.0. For library API treat 'recordPacking' parameter as
+                 * 'recordPacking' for SRU 1.1 and SRU 1.2.
+                 */
+                if (version == SRUVersion.VERSION_2_0) {
+                    return PARAM_RECORD_XML_ESCAPING;
+                } else {
+                    return PARAM_RECORD_PACKING;
+                }
+            case RECORD_PACKING:
+                /*
+                 * FIXME: make this better
+                 */
+                if (version == SRUVersion.VERSION_2_0) {
+                    return PARAM_RECORD_PACKING;
+                } else {
+                    throw new InternalError("should not happen");
+                }
             case RECORD_SCHEMA:
                 return PARAM_RECORD_SCHEMA;
@@ -137,6 +189,4 @@
             case MAXIMUM_TERMS:
                 return PARAM_MAXIMUM_TERMS;
-            case STYLESHEET:
-                return PARAM_STYLESHEET;
             default:
                 throw new InternalError();
@@ -154,40 +204,51 @@
     } // class ParameterInfo
 
-    private static final ParameterInfo[] PARAMS_EXPLAIN = {
+    private static final ParameterInfo[] PARAMETER_SET_EXPLAIN = {
+            new ParameterInfo(Parameter.STYLESHEET, false,
+                    SRUVersion.VERSION_1_1, SRUVersion.VERSION_1_2),
+            new ParameterInfo(Parameter.RECORD_XML_ESCAPING, false,
+                    SRUVersion.VERSION_1_1, SRUVersion.VERSION_1_2)
+    };
+    private static final ParameterInfo[] PARAMETER_SET_SCAN = {
+            new ParameterInfo(Parameter.STYLESHEET, false,
+                    SRUVersion.VERSION_1_1, SRUVersion.VERSION_2_0),
+            new ParameterInfo(Parameter.HTTP_ACCEPT, false,
+                    SRUVersion.VERSION_2_0, SRUVersion.VERSION_2_0),
+            new ParameterInfo(Parameter.SCAN_CLAUSE, true,
+                    SRUVersion.VERSION_1_1, SRUVersion.VERSION_2_0),
+            new ParameterInfo(Parameter.RESPONSE_POSITION, false,
+                    SRUVersion.VERSION_1_1, SRUVersion.VERSION_2_0),
+            new ParameterInfo(Parameter.MAXIMUM_TERMS, false,
+                    SRUVersion.VERSION_1_1, SRUVersion.VERSION_2_0)
+    };
+    private static final ParameterInfo[] PARAMETER_SET_SEARCH_RETRIEVE = {
+        new ParameterInfo(Parameter.STYLESHEET, false,
+                    SRUVersion.VERSION_1_1, SRUVersion.VERSION_1_2),
+        new ParameterInfo(Parameter.HTTP_ACCEPT, false,
+                SRUVersion.VERSION_2_0, SRUVersion.VERSION_2_0),
+        new ParameterInfo(Parameter.RENDER_BY, false,
+                SRUVersion.VERSION_2_0, SRUVersion.VERSION_2_0),
+        new ParameterInfo(Parameter.RESPONSE_TYPE, false,
+                SRUVersion.VERSION_2_0, SRUVersion.VERSION_2_0),
+        new ParameterInfo(Parameter.QUERY, true,
+                SRUVersion.VERSION_1_1, SRUVersion.VERSION_2_0),
+        new ParameterInfo(Parameter.QUERY_TYPE, true,
+                SRUVersion.VERSION_2_0, SRUVersion.VERSION_2_0),
+        new ParameterInfo(Parameter.START_RECORD, false,
+                SRUVersion.VERSION_1_1, SRUVersion.VERSION_2_0),
+        new ParameterInfo(Parameter.MAXIMUM_RECORDS, false,
+                SRUVersion.VERSION_1_1, SRUVersion.VERSION_2_0),
+        new ParameterInfo(Parameter.RECORD_XML_ESCAPING, false,
+                SRUVersion.VERSION_1_1, SRUVersion.VERSION_2_0),
         new ParameterInfo(Parameter.RECORD_PACKING, false,
-                SRUVersion.VERSION_1_1, SRUVersion.VERSION_1_2),
-        new ParameterInfo(Parameter.STYLESHEET, false,
-                SRUVersion.VERSION_1_1, SRUVersion.VERSION_1_2)
-    };
-    private static final ParameterInfo[] PARAMS_SCAN = {
-        new ParameterInfo(Parameter.SCAN_CLAUSE, true,
-                SRUVersion.VERSION_1_1, SRUVersion.VERSION_1_2),
-        new ParameterInfo(Parameter.RESPONSE_POSITION, false,
-                SRUVersion.VERSION_1_1, SRUVersion.VERSION_1_2),
-        new ParameterInfo(Parameter.MAXIMUM_TERMS, false,
-                SRUVersion.VERSION_1_1, SRUVersion.VERSION_1_2),
-        new ParameterInfo(Parameter.STYLESHEET, false,
-                SRUVersion.VERSION_1_1, SRUVersion.VERSION_1_2)
-
-    };
-    private static final ParameterInfo[] PARAMS_SEARCH_RETRIEVE = {
-        new ParameterInfo(Parameter.QUERY, true,
-                SRUVersion.VERSION_1_1, SRUVersion.VERSION_1_2),
-        new ParameterInfo(Parameter.START_RECORD, false,
-                SRUVersion.VERSION_1_1, SRUVersion.VERSION_1_2),
-        new ParameterInfo(Parameter.MAXIMUM_RECORDS, false,
-                SRUVersion.VERSION_1_1, SRUVersion.VERSION_1_2),
-        new ParameterInfo(Parameter.RECORD_PACKING, false,
-                SRUVersion.VERSION_1_1, SRUVersion.VERSION_1_2),
+                SRUVersion.VERSION_2_0, SRUVersion.VERSION_2_0),
         new ParameterInfo(Parameter.RECORD_SCHEMA, false,
-                SRUVersion.VERSION_1_1, SRUVersion.VERSION_1_2),
+                SRUVersion.VERSION_1_1, SRUVersion.VERSION_2_0),
+        new ParameterInfo(Parameter.RESULT_SET_TTL, false,
+                SRUVersion.VERSION_1_1, SRUVersion.VERSION_2_0),
         new ParameterInfo(Parameter.RECORD_XPATH, false,
-                SRUVersion.VERSION_1_1, SRUVersion.VERSION_1_1),
-        new ParameterInfo(Parameter.RESULT_SET_TTL, false,
                 SRUVersion.VERSION_1_1, SRUVersion.VERSION_1_2),
         new ParameterInfo(Parameter.SORT_KEYS, false,
-                SRUVersion.VERSION_1_1, SRUVersion.VERSION_1_1),
-        new ParameterInfo(Parameter.STYLESHEET, false,
-                SRUVersion.VERSION_1_1, SRUVersion.VERSION_1_2)
+                SRUVersion.VERSION_1_1, SRUVersion.VERSION_2_0),
     };
 
@@ -340,14 +401,14 @@
         if (diagnostics == null) {
             // check mandatory/optional parameters for operation
-            ParameterInfo[] parameters;
+            ParameterInfo[] parameter_set;
             switch (operation) {
             case EXPLAIN:
-                parameters = PARAMS_EXPLAIN;
+                parameter_set = PARAMETER_SET_EXPLAIN;
                 break;
             case SCAN:
-                parameters = PARAMS_SCAN;
+                parameter_set = PARAMETER_SET_SCAN;
                 break;
             case SEARCH_RETRIEVE:
-                parameters = PARAMS_SEARCH_RETRIEVE;
+                parameter_set = PARAMETER_SET_SEARCH_RETRIEVE;
                 break;
             default:
@@ -366,9 +427,10 @@
 
             // check parameters ...
-            for (ParameterInfo parameter : parameters) {
-                String value = getParameter(parameter.getName(), true, true);
+            for (ParameterInfo parameter : parameter_set) {
+                final String name = parameter.getName(version);
+                final String value = getParameter(name, true, true);
                 if (value != null) {
                     // remove supported parameter from list
-                    parameterNames.remove(parameter.getName());
+                    parameterNames.remove(name);
 
                     /*
@@ -378,8 +440,8 @@
                     if (!parameter.isForVersion(version)) {
                         addDiagnostic(SRUConstants.SRU_UNSUPPORTED_PARAMETER,
-                                parameter.getName(),
+                                name,
                                 "Version " + version.getVersionString() +
                                         " does not support parameter \"" +
-                                        parameter.getName() + "\".");
+                                        name + "\".");
                         continue;
                     }
@@ -387,12 +449,24 @@
                     // validate and parse parameters ...
                     switch (parameter.getParameter()) {
-                    case RECORD_PACKING:
-                        if (value.endsWith(RECORD_PACKING_XML)) {
-                            recordPacking = SRURecordPacking.XML;
-                        } else if (value.equals(RECORD_PACKING_STRING)) {
-                            recordPacking = SRURecordPacking.STRING;
+                    case RECORD_XML_ESCAPING:
+                        if (value.equals(RECORD_XML_ESCAPING_XML)) {
+                            recordXmlEscaping = SRURecordXmlEscaping.XML;
+                        } else if (value.equals(RECORD_XML_ESCPAING_STRING)) {
+                            recordXmlEscaping = SRURecordXmlEscaping.STRING;
                         } else {
                             addDiagnostic(
-                                    SRUConstants.SRU_UNSUPPORTED_RECORD_PACKING,
+                                    SRUConstants.SRU_UNSUPPORTED_XML_ESCAPING_VALUE,
+                                    null, "Record XML escaping \"" + value +
+                                            "\" is not supported.");
+                        }
+                        break;
+                    case RECORD_PACKING:
+                        if (value.equals(RECORD_PACKING_PACKED)) {
+                            recordPacking = SRURecordPacking.PACKED;
+                        } else if (value.equals(RECORD_PACKING_UNPACKED)) {
+                            recordPacking = SRURecordPacking.UNPACKED;
+                        } else {
+                            addDiagnostic(
+                                    SRUConstants.SRU_UNSUPPORTED_PARAMETER_VALUE,
                                     null, "Record packing \"" + value +
                                             "\" is not supported.");
@@ -400,13 +474,14 @@
                         break;
                     case QUERY:
-                        query = parseCQLParameter(parameter.getName(), value);
+                        query = parseCQLParameter(name, value);
+                        break;
+                    case QUERY_TYPE:
+                        queryType = parseQueryTypeParameter(name, value);
                         break;
                     case START_RECORD:
-                        startRecord = parseNumberedParameter(
-                                parameter.getName(), value, 1);
+                        startRecord = parseNumberedParameter(name, value, 1);
                         break;
                     case MAXIMUM_RECORDS:
-                        maximumRecords = parseNumberedParameter(
-                                parameter.getName(), value, 0);
+                        maximumRecords = parseNumberedParameter(name, value, 0);
                         break;
                     case RECORD_SCHEMA:
@@ -436,6 +511,5 @@
                         break;
                     case RESULT_SET_TTL:
-                        resultSetTTL = parseNumberedParameter(
-                                parameter.getName(), value, 0);
+                        resultSetTTL = parseNumberedParameter(name, value, 0);
                         break;
                     case SORT_KEYS:
@@ -443,17 +517,40 @@
                         break;
                     case SCAN_CLAUSE:
-                        scanClause = parseCQLParameter(
-                                parameter.getName(), value);
+                        scanClause = parseCQLParameter(name, value);
                         break;
                     case RESPONSE_POSITION:
                         responsePosition = parseNumberedParameter(
-                                parameter.getName(), value, 0);
+                                name, value, 0);
                         break;
                     case MAXIMUM_TERMS:
-                        maximumTerms = parseNumberedParameter(
-                                parameter.getName(), value, 0);
+                        maximumTerms = parseNumberedParameter(name, value, 0);
                         break;
                     case STYLESHEET:
                         stylesheet = value;
+                        break;
+                    case RENDER_BY:
+                        if (value.equals(RENDER_BY_CLIENT)) {
+                            renderBy = SRURenderBy.CLIENT;
+                        } else if (value.equals(RENDER_BY_SERVER)) {
+                            renderBy = SRURenderBy.SERVER;
+                        } else {
+                            addDiagnostic(
+                                    SRUConstants.SRU_UNSUPPORTED_PARAMETER_VALUE,
+                                    null,
+                                    "Value \"" + value + "\" for parameter '" +
+                                            name + "' is not supported.");
+                        }
+                        break;
+                    case RESPONSE_TYPE:
+                        /*
+                         * FIXME: check parameter validity?!
+                         */
+                        responseType = value;
+                        break;
+                    case HTTP_ACCEPT:
+                        /*
+                         * FIXME: check parameter validity?!
+                         */
+                        httpAccept = value;
                         break;
                     } // switch
@@ -462,6 +559,5 @@
                         addDiagnostic(
                                 SRUConstants.SRU_MANDATORY_PARAMETER_NOT_SUPPLIED,
-                                parameter.getName(), "Mandatory parameter \"" +
-                                        parameter.getName() +
+                                name, "Mandatory parameter \"" + name +
                                         "\" was not supplied.");
                     }
@@ -503,6 +599,6 @@
 
 
-    SRURecordPacking getRawRecordPacking() {
-        return recordPacking;
+    SRURecordXmlEscaping getRawRecordPacking() {
+        return recordXmlEscaping;
     }
 
@@ -585,4 +681,12 @@
 
     @Override
+    public SRURecordXmlEscaping getRecordXmlEscaping() {
+        return (recordXmlEscaping != null)
+                ? recordXmlEscaping
+                : config.getDefaultRecordXmlEscaping();
+    }
+
+
+    @Override
     public SRURecordPacking getRecordPacking() {
         return (recordPacking != null)
@@ -623,11 +727,4 @@
 
     @Override
-    @Deprecated
-    public String getRecordSchemaName() {
-        return getRawRecordSchemaIdentifier();
-    }
-
-
-    @Override
     public String getRecordSchemaIdentifier() {
         return recordSchemaIdentifier;
@@ -686,4 +783,26 @@
     public String getStylesheet() {
         return stylesheet;
+    }
+
+
+    @Override
+    public SRURenderBy getRenderBy() {
+        return renderBy;
+    }
+
+
+    @Override
+    public String getResponeType() {
+        return responseType;
+    }
+
+
+    @Override
+    public String getHttpAccept() {
+        if (httpAccept != null) {
+            return httpAccept;
+        } else {
+            return request.getHeader("ACCEPT");
+        }
     }
 
@@ -808,4 +927,21 @@
             return config.getDefaultVersion();
         }
+    }
+
+
+    private String parseQueryTypeParameter(String param, String value) {
+        if (value != null) {
+            for (int i = 0; i < value.length(); i++) {
+                final char ch = value.charAt(i);
+                if (!((ch >= 'a' && ch <= 'z') ||
+                        (ch >= 'A' && ch <= 'Z') ||
+                        (ch >= '0' && ch <= '9') ||
+                        ((i > 0) && ((ch == '-') || ch == '_')))) {
+                    addDiagnostic(SRUConstants.SRU_UNSUPPORTED_PARAMETER_VALUE,
+                            param, "Value contains illegal characters.");
+                }
+            }
+        }
+        return value;
     }
 
Index: /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUResultCountPrecision.java
===================================================================
--- /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUResultCountPrecision.java	(revision 6816)
+++ /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUResultCountPrecision.java	(revision 6816)
@@ -0,0 +1,52 @@
+/**
+ * This software is copyright (c) 2011-2013 by
+ *  - Institut fuer Deutsche Sprache (http://www.ids-mannheim.de)
+ * This is free software. You can redistribute it
+ * and/or modify it under the terms described in
+ * the GNU General Public License v3 of which you
+ * should have received a copy. Otherwise you can download
+ * it from
+ *
+ *   http://www.gnu.org/licenses/gpl-3.0.txt
+ *
+ * @copyright Institut fuer Deutsche Sprache (http://www.ids-mannheim.de)
+ *
+ * @license http://www.gnu.org/licenses/gpl-3.0.txt
+ *  GNU General Public License v3
+ */
+package eu.clarin.sru.server;
+
+/**
+ * (SRU 2.0) Indicate the accuracy of the result count reported by total
+ * number of records that matched the query.
+ */
+public enum SRUResultCountPrecision {
+    /**
+     * The server guarantees that the reported number of records is accurate.
+     */
+    EXACT,
+    /**
+     * The server has no idea what the result count is, and does not want to
+     * venture an estimate.
+     */
+    UNKNOWN,
+    /**
+     * The server does not know the result set count, but offers an estimate.
+     */
+    ESTIMATE,
+    /**
+     * The value supplied is an estimate of the maximum possible count that the
+     * result set will attain.
+     */
+    MAXIMUM,
+    /**
+     * The server does not know the result count but guarantees that it is at
+     * least this large.
+     */
+    MINIMUM,
+    /**
+     * The value supplied is an estimate of the count at the time the response
+     * was sent, however the result set may continue to grow.
+     */
+    CURRENT
+} // enum SRUResultCountPrecision
Index: /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUSearchResultSet.java
===================================================================
--- /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUSearchResultSet.java	(revision 6815)
+++ /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUSearchResultSet.java	(revision 6816)
@@ -90,12 +90,28 @@
 
     /**
-     * The idle time for this result. The default implementation returns
-     * <code>-1</code>.
-     *
-     * @return the result set idle time or <code>-1</code> if not applicable for
+     * The result set time to live. In SRU 2.0 it will be serialized as
+     * <code>&lt;resultSetTTL&gt;</code> element; in SRU 1.2 as
+     * <code>&lt;resultSetIdleTime&gt;</code> element.The default implementation
+     * returns <code>-1</code>.
+     *
+     * @return the result set time to live or <code>-1</code> if not applicable for
      *         this result
      */
-    public int getResultSetIdleTime() {
+    public int getResultSetTTL() {
         return -1;
+    }
+
+
+    /**
+     * (SRU 2.0) Indicate the accuracy of the result count reported by total
+     * number of records that matched the query. Default implementation returns
+     * <code>null</code>.
+     *
+     * @see SRUResultCountPrecision
+     * @return the result count precision or <code>null</code> if not applicable
+     *         for this result
+     */
+    public SRUResultCountPrecision getResultCountPrecision() {
+        return null;
     }
 
Index: /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUServer.java
===================================================================
--- /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUServer.java	(revision 6815)
+++ /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUServer.java	(revision 6816)
@@ -123,5 +123,5 @@
                     SRUXMLStreamWriter out =
                         createXMLStreamWriter(response.getOutputStream(),
-                                SRURecordPacking.XML, false,
+                                SRURecordXmlEscaping.XML, false,
                                 req.getIndentResponse());
                     final SRUNamespaces ns = getNamespaces(req.getVersion());
@@ -164,5 +164,5 @@
                     SRUXMLStreamWriter out =
                             createXMLStreamWriter(response.getOutputStream(),
-                                    SRURecordPacking.XML, false,
+                                    SRURecordXmlEscaping.XML, false,
                                     req.getIndentResponse());
                     final SRUNamespaces ns = getNamespaces(req.getVersion());
@@ -201,5 +201,5 @@
             SRUXMLStreamWriter out =
                     createXMLStreamWriter(response.getOutputStream(),
-                                          request.getRecordPacking(),
+                                          request.getRecordXmlEscaping(),
                                           true,
                                           request.getIndentResponse());
@@ -258,5 +258,5 @@
             SRUXMLStreamWriter out =
                     createXMLStreamWriter(response.getOutputStream(),
-                                          request.getRecordPacking(),
+                                          request.getRecordXmlEscaping(),
                                           true,
                                           request.getIndentResponse());
@@ -394,5 +394,5 @@
             SRUXMLStreamWriter out =
                     createXMLStreamWriter(response.getOutputStream(),
-                                          request.getRecordPacking(),
+                                          request.getRecordXmlEscaping(),
                                           true,
                                           request.getIndentResponse());
@@ -413,9 +413,10 @@
             }
 
-            // resultSetIdleTime
-            if (result.getResultSetIdleTime() > 0) {
+            // resultSetIdleTime (SRU 1.1 and SRU 1.2)
+            if (!request.isVersion(SRUVersion.VERSION_2_0) &&
+                    (result.getResultSetTTL() > 0)) {
                 out.writeStartElement(ns.getResponseNS(), "resultSetIdleTime");
                 out.writeCharacters(Integer.toString(result
-                        .getResultSetIdleTime()));
+                        .getResultSetTTL()));
                 out.writeEndElement(); // "resultSetIdleTime" element
             }
@@ -465,5 +466,5 @@
 
                         // recordPacking
-                        writeRecordPacking(out, ns, request.getRecordPacking());
+                        writeRecordPacking(out, ns, request.getRecordXmlEscaping());
 
                         /*
@@ -482,7 +483,8 @@
 
                         /*
-                         * recordIdentifier is version 1.2 only
+                         * recordIdentifier is version 1.2+ only
                          */
-                        if (request.isVersion(SRUVersion.VERSION_1_2)) {
+                        if (request.isVersion(SRUVersion.VERSION_1_2,
+                                SRUVersion.VERSION_2_0)) {
                             final String identifier =
                                     result.getRecordIdentifier();
@@ -543,4 +545,48 @@
             }
 
+            // SRU 2.0 stuff ...
+            if (request.isVersion(SRUVersion.VERSION_2_0)) {
+                // resultSetTTL
+                if (result.getResultSetTTL() > 0) {
+                    out.writeStartElement(ns.getResponseNS(), "resultSetTTL");
+                    out.writeCharacters(Integer.toString(result
+                            .getResultSetTTL()));
+                    out.writeEndElement(); // "resultSetTTL" element
+                }
+
+                // resultCountPrecision (SRU 2.0)
+                final SRUResultCountPrecision precision =
+                        result.getResultCountPrecision();
+                if (precision != null) {
+                    out.writeStartElement(ns.getResponseNS(), "resultCountPrecision");
+                    switch (precision) {
+                    case EXACT:
+                        out.writeCharacters("info:srw/vocabulary/resultCountPrecision/1/exact");
+                        break;
+                    case UNKNOWN:
+                        out.writeCharacters("info:srw/vocabulary/resultCountPrecision/1/unknown");
+                        break;
+                    case ESTIMATE:
+                        out.writeCharacters("info:srw/vocabulary/resultCountPrecision/1/estimate");
+                        break;
+                    case MAXIMUM:
+                        out.writeCharacters("info:srw/vocabulary/resultCountPrecision/1/maximum");
+                        break;
+                    case MINIMUM:
+                        out.writeCharacters("info:srw/vocabulary/resultCountPrecision/1/minimum");
+                        break;
+                    case CURRENT:
+                        out.writeCharacters("info:srw/vocabulary/resultCountPrecision/1/current");
+                        break;
+                    } // switch
+                    out.writeEndElement(); // "resultCountPrecision" element
+                }
+
+                // facetedResults
+                // NOT YET SUPPORTED
+
+                // searchResultAnalysis
+                // NOT YET SUPPORTED
+            }
             endResponse(out);
         } finally {
@@ -666,5 +712,5 @@
 
         // recordPacking
-        writeRecordPacking(out, ns, request.getRecordPacking());
+        writeRecordPacking(out, ns, request.getRecordXmlEscaping());
 
         out.writeStartElement(ns.getResponseNS(), "recordData");
@@ -1025,4 +1071,16 @@
         }
 
+        // echoedSearchRetrieveRequest/renderedBy
+        // FIXME: NOT YET IMPLEMENTED
+
+        // echoedSearchRetrieveRequest/extraRequestParameter
+        // FIXME: NOT YET IMPLEMENTED
+
+        // echoedSearchRetrieveRequest/httpAccept
+        // FIXME: NOT YET IMPLEMENTED
+
+        // echoedSearchRetrieveRequest/responseType
+        // FIXME: NOT YET IMPLEMENTED
+
         // echoedSearchRetrieveRequest/baseUrl (SRU 1.2 only)
         if (request.isVersion(SRUVersion.VERSION_1_2)) {
@@ -1053,5 +1111,5 @@
 
     private void writeRecordPacking(SRUXMLStreamWriter out, SRUNamespaces ns,
-            SRURecordPacking recordPacking) throws XMLStreamException {
+            SRURecordXmlEscaping recordPacking) throws XMLStreamException {
         out.writeStartElement(ns.getResponseNS(), "recordPacking");
         switch (recordPacking) {
@@ -1096,5 +1154,5 @@
 
     private SRUXMLStreamWriter createXMLStreamWriter(OutputStream out,
-            SRURecordPacking recordPacking, boolean skipFlush, int indent)
+            SRURecordXmlEscaping recordPacking, boolean skipFlush, int indent)
             throws SRUException {
         try {
Index: /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUServerConfig.java
===================================================================
--- /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUServerConfig.java	(revision 6815)
+++ /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUServerConfig.java	(revision 6816)
@@ -717,6 +717,11 @@
 
 
+    public SRURecordXmlEscaping getDefaultRecordXmlEscaping() {
+        return SRURecordXmlEscaping.XML;
+    }
+
+
     public SRURecordPacking getDefaultRecordPacking() {
-        return SRURecordPacking.XML;
+        return SRURecordPacking.PACKED;
     }
 
Index: /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUXMLStreamWriter.java
===================================================================
--- /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUXMLStreamWriter.java	(revision 6815)
+++ /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUXMLStreamWriter.java	(revision 6816)
@@ -45,5 +45,5 @@
     }
     private static final SAXParserFactory factory;
-    private final SRURecordPacking packing;
+    private final SRURecordXmlEscaping recordEscaping;
     private final Writer writer;
     private final XMLStreamWriter xmlwriter;
@@ -55,13 +55,14 @@
 
 
-    SRUXMLStreamWriter(OutputStream stream, XMLOutputFactory factory,
-            SRURecordPacking recordPacking, int indent) throws IOException,
-            XMLStreamException {
-        this.packing = recordPacking;
+    SRUXMLStreamWriter(OutputStream stream,
+            XMLOutputFactory factory,
+            SRURecordXmlEscaping recordXmlEscaping,
+            int indent) throws IOException, XMLStreamException {
+        this.recordEscaping = recordXmlEscaping;
         this.writer = new OutputStreamWriter(stream,
                 SRUServer.RESPONSE_ENCODING) {
             @Override
             public void write(int c) throws IOException {
-                if (writingRecord && (packing == SRURecordPacking.STRING)) {
+                if (writingRecord && (recordEscaping == SRURecordXmlEscaping.STRING)) {
                     /*
                      * NOTE: need to write single characters here, because
@@ -98,5 +99,5 @@
             @Override
             public void write(char[] c, int off, int len) throws IOException {
-                if (writingRecord && (packing == SRURecordPacking.STRING)) {
+                if (writingRecord && (recordEscaping == SRURecordXmlEscaping.STRING)) {
                     for (int i = off; i < len; i++) {
                         this.write(c[i]);
@@ -109,5 +110,5 @@
             @Override
             public void write(String s, int off, int len) throws IOException {
-                if (writingRecord && (packing == SRURecordPacking.STRING)) {
+                if (writingRecord && (recordEscaping == SRURecordXmlEscaping.STRING)) {
                     for (int i = off; i < len; i++) {
                         this.write(s.charAt(i));
@@ -480,5 +481,5 @@
 
     private void onStartElement() throws XMLStreamException {
-        if (!(writingRecord && (packing == SRURecordPacking.STRING))) {
+        if (!(writingRecord && (recordEscaping == SRURecordXmlEscaping.STRING))) {
             stateStack.push(IndentingState.SEEN_ELEMENT);
             state = IndentingState.SEEN_NOTHING;
@@ -493,5 +494,5 @@
 
     private void onEndElement() throws XMLStreamException {
-        if (!(writingRecord && (packing == SRURecordPacking.STRING))) {
+        if (!(writingRecord && (recordEscaping == SRURecordXmlEscaping.STRING))) {
             depth--;
             if (state == IndentingState.SEEN_ELEMENT) {
@@ -505,5 +506,5 @@
 
     private void onEmptyElement() throws XMLStreamException {
-        if (!(writingRecord && (packing == SRURecordPacking.STRING))) {
+        if (!(writingRecord && (recordEscaping == SRURecordXmlEscaping.STRING))) {
             state = IndentingState.SEEN_ELEMENT;
             if (depth > 0) {
