Index: /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUServer.java
===================================================================
--- /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUServer.java	(revision 2697)
+++ /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUServer.java	(revision 2698)
@@ -17,4 +17,5 @@
 package eu.clarin.sru.server;
 
+import java.io.FilterOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
@@ -65,5 +66,4 @@
     static final String RESPONSE_ENCODING = "utf-8";
     private static final String RESPONSE_CONTENT_TYPE = "application/xml";
-    private static final int RESPONSE_BUFFER_SIZE = 64 * 1024;
     private static final Logger logger =
             LoggerFactory.getLogger(SRUServer.class);
@@ -116,6 +116,5 @@
             response.setStatus(HttpServletResponse.SC_OK);
             // make sure we can reset the stream later in case of error ...
-            response.setBufferSize(RESPONSE_BUFFER_SIZE);
-
+            response.setBufferSize(config.getResponseBufferSize());
             try {
                 if (req.checkParameters()) {
@@ -135,5 +134,6 @@
                     SRUXMLStreamWriter out =
                         createXMLStreamWriter(response.getOutputStream(),
-                                SRURecordPacking.XML, req.getIndentResponse());
+                                SRURecordPacking.XML, false,
+                                req.getIndentResponse());
                     writeFatalError(out, req, req.getDiagnostics());
                 }
@@ -150,4 +150,22 @@
         } catch (SRUException e) {
             if (!response.isCommitted()) {
+                if (logger.isInfoEnabled()) {
+                    final String message = e.getDiagnostic().getMessage();
+                    if (message != null) {
+                        logger.info("Sending fatal diagnostic '{}{}' with " +
+                                "message '{}'",
+                                new Object[] {
+                                        SRUConstants.SRU_DIAGNOSTIC_URI_PREFIX,
+                                        e.getDiagnostic().getCode(),
+                                        message
+                                });
+                    } else {
+                        logger.info("Sending fatal diagnostic '{}{}'",
+                                SRUConstants.SRU_DIAGNOSTIC_URI_PREFIX,
+                                e.getDiagnostic().getCode());
+                    }
+                    logger.debug("Fatal diagnostic was caused by " +
+                            "this exception", e);
+                }
                 response.resetBuffer();
                 try {
@@ -160,5 +178,5 @@
                     SRUXMLStreamWriter out =
                             createXMLStreamWriter(response.getOutputStream(),
-                                    SRURecordPacking.XML,
+                                    SRURecordPacking.XML, false,
                                     req.getIndentResponse());
                     writeFatalError(out, req, diagnostics);
@@ -168,6 +186,13 @@
                 }
             } else {
+                /*
+                 * The servlet already flushed the output buffer, so cannot
+                 * degrade gracefully anymore and, unfortunately, will produce
+                 * ill-formed XML output.
+                 * Increase the response buffer size, if you want to avoid
+                 * this (at the cost of memory).
+                 */
                 logger.error("A fatal error occurred, but the response was "
-                        + "already committed", e);
+                        + "already committed. Unable to recover gracefully.", e);
             }
         }
@@ -188,4 +213,5 @@
                     createXMLStreamWriter(response.getOutputStream(),
                                           request.getRecordPacking(),
+                                          true,
                                           request.getIndentResponse());
 
@@ -238,4 +264,5 @@
                     createXMLStreamWriter(response.getOutputStream(),
                                           request.getRecordPacking(),
+                                          true,
                                           request.getIndentResponse());
 
@@ -364,4 +391,5 @@
                     createXMLStreamWriter(response.getOutputStream(),
                                           request.getRecordPacking(),
+                                          true,
                                           request.getIndentResponse());
 
@@ -1044,8 +1072,33 @@
 
     private SRUXMLStreamWriter createXMLStreamWriter(OutputStream out,
-            SRURecordPacking recordPacking, int indent) throws SRUException {
+            SRURecordPacking recordPacking, boolean skipFlush, int indent)
+            throws SRUException {
         try {
-            return new SRUXMLStreamWriter(out, writerFactory, recordPacking,
-                    indent);
+            if (skipFlush) {
+                /*
+                 * Add a FilterOutputStream to delay flush() as long as
+                 * possible. Doing so, enabled us to send an appropriate SRU
+                 * diagnostic in case an error occurs during the serialization
+                 * of the response.
+                 * Of course, if an error occurs when the Servlet response
+                 * buffer already had been flushed, because it was to large,
+                 * we cannot fail gracefully and we will produce ill-formed
+                 * XML output.
+                 */
+                out = new FilterOutputStream(out) {
+                    @Override
+                    public void flush() throws IOException {
+                    }
+
+
+                    @Override
+                    public void close() throws IOException {
+                        super.flush();
+                        super.close();
+                    }
+                };
+            }
+            return new SRUXMLStreamWriter(out, writerFactory,
+                    recordPacking, indent);
         } catch (Exception e) {
             throw new SRUException(SRUConstants.SRU_GENERAL_SYSTEM_ERROR,
Index: /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUServerConfig.java
===================================================================
--- /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUServerConfig.java	(revision 2697)
+++ /SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUServerConfig.java	(revision 2698)
@@ -224,4 +224,14 @@
             "eu.clarin.sru.server.allowOverrideIndentResponse";
     /**
+     * Parameter constant for configuring the size of response buffer size. The
+     * servlet will buffer up to this amount of data before sending a response
+     * to the client. The value if the response buffer in bytes.
+     * <p>
+     * Valid values: any positive integer (default 65536)
+     * </p>
+     */
+    public static final String SRU_RESPONSE_BUFFER_SIZE =
+            "eu.clarin.sru.server.responseBufferSize";
+    /**
      * @deprecated use {@link #SRU_TRANSPORT}
      */
@@ -283,8 +293,9 @@
     private static final String LEGACY_SRU_ALLOW_OVERRIDE_INDENT_RESPONSE =
             "sru.allowOverrideIndentResponse";
-    private static final int DEFAULT_NUMBER_OF_RECORDS = 100;
-    private static final int DEFAULT_MAXIMUM_RECORDS   = 250;
-    private static final int DEFAULT_NUMBER_OF_TERMS   = 250;
-    private static final int DEFAULT_MAXIMUM_TERMS     = 500;
+    private static final int DEFAULT_NUMBER_OF_RECORDS    = 100;
+    private static final int DEFAULT_MAXIMUM_RECORDS      = 250;
+    private static final int DEFAULT_NUMBER_OF_TERMS      = 250;
+    private static final int DEFAULT_MAXIMUM_TERMS        = 500;
+    private static final int DEFAULT_RESPONSE_BUFFER_SIZE = 64 * 1024;
     private static final String CONFIG_FILE_NAMESPACE_URI =
             "http://www.clarin.eu/sru-server/1.0/";
@@ -626,4 +637,5 @@
     private final boolean echoRequests;
     private final int indentResponse;
+    private final int responseBufferSize;
     private final boolean allowOverrideMaximumRecords;
     private final boolean allowOverrideMaximumTerms;
@@ -638,5 +650,6 @@
             String database, int numberOfRecords, int maximumRecords,
             int numberOfTerms, int maximumTerms, boolean echoRequests,
-            int indentResponse, boolean allowOverrideMaximumRecords,
+            int indentResponse, int responseBufferSize,
+            boolean allowOverrideMaximumRecords,
             boolean allowOverrideMaximumTerms,
             boolean allowOverrideIndentResponse, DatabaseInfo databaseinfo,
@@ -652,4 +665,5 @@
         this.echoRequests                = echoRequests;
         this.indentResponse              = indentResponse;
+        this.responseBufferSize          = responseBufferSize;
         this.allowOverrideMaximumRecords = allowOverrideMaximumRecords;
         this.allowOverrideMaximumTerms   = allowOverrideMaximumTerms;
@@ -751,4 +765,9 @@
     public boolean allowOverrideIndentResponse() {
         return allowOverrideIndentResponse;
+    }
+
+
+    public int getResponseBufferSize() {
+        return responseBufferSize;
     }
 
@@ -988,10 +1007,14 @@
                     SRU_ALLOW_OVERRIDE_INDENT_RESPONSE, false, false);
 
+            int responseBufferSize = parseNumber(params,
+                    SRU_RESPONSE_BUFFER_SIZE, false,
+                    DEFAULT_RESPONSE_BUFFER_SIZE, 0, -1);
+
             return new SRUServerConfig(transport, host, port, database,
                     numberOfRecords, maximumRecords, numberOfTerms,
                     maximumTerms, echoRequests, indentResponse,
-                    allowOverrideMaximumRecords, allowOverrideMaximumTerms,
-                    allowOverrideIndentResponse, databaseInfo, indexInfo,
-                    schemaInfo);
+                    responseBufferSize, allowOverrideMaximumRecords,
+                    allowOverrideMaximumTerms, allowOverrideIndentResponse,
+                    databaseInfo, indexInfo, schemaInfo);
         } catch (IOException e) {
             throw new SRUConfigException("error reading configuration file", e);
