anchor.diff:  				
   		// look for a headers collection - this was added by looping the grid header row columns 
   		JSONArray headers = jsonData.optJSONArray("headers");
  +				
  +		// we'll build and then write each row
  +		StringBuilder sb = new StringBuilder();
  +		
  +		// string builder bytes which we'll get from the string builder in UTF-8 and then write to the output stream for each line
  +		byte[] sbytes = null;
   		
   		// if we got any headers 
   		if (headers != null) {
  +
   			// this is the dynamic header list, so loop it
   			for (int i = 0; i < headers.length(); i++) {
   				// print the escaped header
   				String header = escapeValue(headers.optString(i));
  -				out.write(header.replaceAll("[^ -~]", ""));
  +				sb.append(header.replaceAll("[^ -~]", ""));
   				
   				// print the comma if not the last value
  -				if (i < headers.length() - 1) out.write(",");
  +				if (i < headers.length() - 1) sb.append(",");
   			}
   			// print the line break
  -			out.write("\r\n");
  -		}
  +			sb.append("\r\n");
  +			
  +			// get any string builder bytes for the header as UTF-8
  +			sbytes = sb.toString().getBytes("UTF-8");
  +			
  +			// write them to the output stream
  +			o.write(sbytes, 0, sbytes.length);
  +			
  +		}		
   
   		// now loop the rows
   		for (int i = 0; i < rows.length(); i++) {
  +			
  +			// empty the string builder
  +			sb.setLength(0);
  +			
   			// get this row
   			JSONArray row = rows.getJSONArray(i);
   			// loop the cells in the row
   			for (int j = 0; j < row.length(); j++) {
   				// print the escaped col value
  -				out.write(escapeValue(row.optString(j)));
  +				sb.append(escapeValue(row.optString(j)));
   				// print the comma if not the last value
  -				if (j < row.length() - 1) out.write(",");
  +				if (j < row.length() - 1) sb.append(",");
   			}				
   			// print the line break
  -			out.write("\r\n");
  -		}		
  +			sb.append("\r\n");
  +			
  +			// get the string builder bytes for this row as UTF-8
  +			sbytes = sb.toString().getBytes("UTF-8");
  +			
  +			// write them to the output stream
  +			o.write(sbytes, 0, sbytes.length);
  +			
  +		}
   	}
   
  +	// flush and close the output stream
  +	o.flush();
  +	o.close();
  +
   %>
positive.code: 	// Expect that the data from the front-end is encoded as UTF-8
  	request.setCharacterEncoding("UTF-8");
  
  	// get any file name provided to us
  	String fileName = request.getParameter("downloadFileName");
  
  
negative.code: 	
  	// if not data yet look for backwards compatible location
  	if (data == null) data = request.getParameter("data");
  
  	// if we got some data
  	if (data != null) {
  				
  		// turn the data into a proper json object 
  		JSONObject jsonData = new JSONObject(data);
  		
  		// get its rows 2d-array
  