You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by jo...@apache.org on 2020/09/17 22:09:06 UTC

[nifi] 11/15: NIFI-7800: Fix line endings for changed files

This is an automated email from the ASF dual-hosted git repository.

joewitt pushed a commit to branch support/nifi-1.12.x
in repository https://gitbox.apache.org/repos/asf/nifi.git

commit 57d7ca19313d379281b77d2b06ca404beef609ec
Author: Matthew Burgess <ma...@apache.org>
AuthorDate: Mon Sep 14 11:46:14 2020 -0400

    NIFI-7800: Fix line endings for changed files
    
    Signed-off-by: Pierre Villard <pi...@gmail.com>
    
    This closes #4527.
---
 .../java/org/apache/nifi/xml/WriteXMLResult.java   | 1304 ++++-----
 .../org/apache/nifi/xml/TestWriteXMLResult.java    | 2860 ++++++++++----------
 2 files changed, 2082 insertions(+), 2082 deletions(-)

diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-record-serialization-services-bundle/nifi-record-serialization-services/src/main/java/org/apache/nifi/xml/WriteXMLResult.java b/nifi-nar-bundles/nifi-standard-services/nifi-record-serialization-services-bundle/nifi-record-serialization-services/src/main/java/org/apache/nifi/xml/WriteXMLResult.java
index 6f5abc8..dc40e75 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-record-serialization-services-bundle/nifi-record-serialization-services/src/main/java/org/apache/nifi/xml/WriteXMLResult.java
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-record-serialization-services-bundle/nifi-record-serialization-services/src/main/java/org/apache/nifi/xml/WriteXMLResult.java
@@ -1,652 +1,652 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.nifi.xml;
-
-import javanet.staxutils.IndentingXMLStreamWriter;
-import org.apache.nifi.record.NullSuppression;
-import org.apache.nifi.schema.access.SchemaAccessWriter;
-import org.apache.nifi.serialization.AbstractRecordSetWriter;
-import org.apache.nifi.serialization.RecordSetWriter;
-import org.apache.nifi.serialization.WriteResult;
-import org.apache.nifi.serialization.record.DataType;
-import org.apache.nifi.serialization.record.RawRecordWriter;
-import org.apache.nifi.serialization.record.Record;
-import org.apache.nifi.serialization.record.RecordField;
-import org.apache.nifi.serialization.record.RecordFieldType;
-import org.apache.nifi.serialization.record.RecordSchema;
-import org.apache.nifi.serialization.record.type.ArrayDataType;
-import org.apache.nifi.serialization.record.type.ChoiceDataType;
-import org.apache.nifi.serialization.record.type.MapDataType;
-import org.apache.nifi.serialization.record.type.RecordDataType;
-import org.apache.nifi.serialization.record.util.DataTypeUtils;
-
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.text.DateFormat;
-import java.util.ArrayDeque;
-import java.util.Deque;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.Supplier;
-import java.util.regex.Pattern;
-
-import static org.apache.nifi.xml.XMLRecordSetWriter.RECORD_TAG_NAME;
-import static org.apache.nifi.xml.XMLRecordSetWriter.ROOT_TAG_NAME;
-
-
-public class WriteXMLResult extends AbstractRecordSetWriter implements RecordSetWriter, RawRecordWriter {
-    private static final Pattern TAG_NAME_CHARS_TO_STRIP = Pattern.compile("[/<>!&'\"]");
-
-    private final RecordSchema recordSchema;
-    private final SchemaAccessWriter schemaAccess;
-    private final XMLStreamWriter writer;
-    private final NullSuppression nullSuppression;
-    private final boolean omitDeclaration;
-    private final ArrayWrapping arrayWrapping;
-    private final String arrayTagName;
-    private final String recordTagName;
-    private final String rootTagName;
-    private final boolean allowWritingMultipleRecords;
-    private boolean hasWrittenRecord;
-
-    private final Supplier<DateFormat> LAZY_DATE_FORMAT;
-    private final Supplier<DateFormat> LAZY_TIME_FORMAT;
-    private final Supplier<DateFormat> LAZY_TIMESTAMP_FORMAT;
-
-    public WriteXMLResult(final RecordSchema recordSchema, final SchemaAccessWriter schemaAccess, final OutputStream out, final boolean prettyPrint, final boolean omitDeclaration,
-                          final NullSuppression nullSuppression, final ArrayWrapping arrayWrapping, final String arrayTagName, final String rootTagName, final String recordTagName,
-                          final String charSet, final String dateFormat, final String timeFormat, final String timestampFormat) throws IOException {
-
-        super(out);
-
-        this.recordSchema = recordSchema;
-        this.schemaAccess = schemaAccess;
-        this.nullSuppression = nullSuppression;
-
-        this.omitDeclaration = omitDeclaration;
-
-        this.arrayWrapping = arrayWrapping;
-        this.arrayTagName = arrayTagName;
-
-        this.rootTagName = rootTagName;
-
-        if (recordTagName != null) {
-            this.recordTagName = recordTagName;
-        } else {
-            Optional<String> recordTagNameOptional = recordSchema.getSchemaName().isPresent()? recordSchema.getSchemaName() : recordSchema.getIdentifier().getName();
-            if (recordTagNameOptional.isPresent()) {
-                this.recordTagName = recordTagNameOptional.get();
-            } else {
-                final String message = "The property '" + RECORD_TAG_NAME.getDisplayName() +
-                    "' has not been set and the writer does not find a record name in the schema.";
-                throw new IOException(message);
-            }
-        }
-
-        this.allowWritingMultipleRecords = !(this.rootTagName == null);
-        hasWrittenRecord = false;
-
-        final DateFormat df = dateFormat == null ? null : DataTypeUtils.getDateFormat(dateFormat);
-        final DateFormat tf = timeFormat == null ? null : DataTypeUtils.getDateFormat(timeFormat);
-        final DateFormat tsf = timestampFormat == null ? null : DataTypeUtils.getDateFormat(timestampFormat);
-
-        LAZY_DATE_FORMAT = () -> df;
-        LAZY_TIME_FORMAT = () -> tf;
-        LAZY_TIMESTAMP_FORMAT = () -> tsf;
-
-        try {
-            XMLOutputFactory factory = XMLOutputFactory.newInstance();
-
-            if (prettyPrint) {
-                writer = new IndentingXMLStreamWriter(factory.createXMLStreamWriter(out, charSet));
-            } else {
-                writer = factory.createXMLStreamWriter(out, charSet);
-            }
-
-        } catch (XMLStreamException e) {
-            throw new IOException(e.getMessage());
-        }
-    }
-
-    @Override
-    protected void onBeginRecordSet() throws IOException {
-
-        final OutputStream out = getOutputStream();
-        schemaAccess.writeHeader(recordSchema, out);
-
-        try {
-            if (!omitDeclaration) {
-                writer.writeStartDocument();
-            }
-
-            if (allowWritingMultipleRecords) {
-                writer.writeStartElement(rootTagName);
-            }
-
-        } catch (XMLStreamException e) {
-            throw new IOException(e.getMessage());
-        }
-    }
-
-    @Override
-    protected Map<String, String> onFinishRecordSet() throws IOException {
-
-        try {
-            if (allowWritingMultipleRecords) {
-                writer.writeEndElement();
-            }
-
-            writer.writeEndDocument();
-        } catch (XMLStreamException e) {
-            throw new IOException(e.getMessage());
-        }
-        return schemaAccess.getAttributes(recordSchema);
-    }
-
-    @Override
-    public void close() throws IOException {
-
-        try {
-            writer.close();
-
-        } catch (XMLStreamException e) {
-            throw new IOException(e.getMessage());
-        }
-
-        super.close();
-    }
-
-    @Override
-    public void flush() throws IOException {
-
-        try {
-            writer.flush();
-
-        } catch (XMLStreamException e) {
-            throw new IOException(e.getMessage());
-        }
-    }
-
-    private void checkWritingMultipleRecords() throws IOException {
-        if (!allowWritingMultipleRecords && hasWrittenRecord) {
-            final String message = "The writer attempts to write multiple record although property \'" + ROOT_TAG_NAME.getDisplayName() +
-                "\' has not been set. If the XMLRecordSetWriter is supposed to write multiple records into one FlowFile, this property is required to be configured.";
-            throw new IOException(message);
-        }
-    }
-
-    @Override
-    protected Map<String, String> writeRecord(Record record) throws IOException {
-
-        if (!isActiveRecordSet()) {
-            schemaAccess.writeHeader(recordSchema, getOutputStream());
-        }
-
-        checkWritingMultipleRecords();
-
-        Deque<String> tagsToOpen = new ArrayDeque<>();
-
-        try {
-            tagsToOpen.addLast(recordTagName);
-
-            boolean closingTagRequired = iterateThroughRecordUsingSchema(tagsToOpen, record, recordSchema);
-            if (closingTagRequired) {
-                writer.writeEndElement();
-                hasWrittenRecord = true;
-            }
-
-        } catch (XMLStreamException e) {
-            throw new IOException(e.getMessage());
-        }
-        return schemaAccess.getAttributes(recordSchema);
-    }
-
-    private boolean iterateThroughRecordUsingSchema(Deque<String> tagsToOpen, Record record, RecordSchema schema) throws XMLStreamException {
-
-        boolean loopHasWritten = false;
-        for (RecordField field : schema.getFields()) {
-
-            String fieldName = field.getFieldName();
-            DataType dataType = field.getDataType();
-            Object value = record.getValue(field);
-
-            final DataType chosenDataType = dataType.getFieldType() == RecordFieldType.CHOICE ? DataTypeUtils.chooseDataType(value, (ChoiceDataType) dataType) : dataType;
-            final Object coercedValue = DataTypeUtils.convertType(value, chosenDataType, LAZY_DATE_FORMAT, LAZY_TIME_FORMAT, LAZY_TIMESTAMP_FORMAT, fieldName);
-
-            if (coercedValue != null) {
-                boolean hasWritten = writeFieldForType(tagsToOpen, coercedValue, chosenDataType, fieldName);
-                if (hasWritten) {
-                    loopHasWritten = true;
-                }
-
-            } else {
-                if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING) && recordHasField(field, record)) {
-                    writeAllTags(tagsToOpen, fieldName);
-                    writer.writeEndElement();
-                    loopHasWritten = true;
-                }
-            }
-        }
-
-        return loopHasWritten;
-    }
-
-    private boolean writeFieldForType(Deque<String> tagsToOpen, Object coercedValue, DataType dataType, String fieldName) throws XMLStreamException {
-        switch (dataType.getFieldType()) {
-            case BOOLEAN:
-            case BYTE:
-            case CHAR:
-            case DECIMAL:
-            case DOUBLE:
-            case FLOAT:
-            case INT:
-            case LONG:
-            case SHORT:
-            case STRING: {
-                writeAllTags(tagsToOpen, fieldName);
-                writer.writeCharacters(coercedValue.toString());
-                writer.writeEndElement();
-                return true;
-            }
-            case DATE: {
-                writeAllTags(tagsToOpen, fieldName);
-                final String stringValue = DataTypeUtils.toString(coercedValue, LAZY_DATE_FORMAT);
-                writer.writeCharacters(stringValue);
-                writer.writeEndElement();
-                return true;
-            }
-            case TIME: {
-                writeAllTags(tagsToOpen, fieldName);
-                final String stringValue = DataTypeUtils.toString(coercedValue, LAZY_TIME_FORMAT);
-                writer.writeCharacters(stringValue);
-                writer.writeEndElement();
-                return true;
-            }
-            case TIMESTAMP: {
-                writeAllTags(tagsToOpen, fieldName);
-                final String stringValue = DataTypeUtils.toString(coercedValue, LAZY_TIMESTAMP_FORMAT);
-                writer.writeCharacters(stringValue);
-                writer.writeEndElement();
-                return true;
-            }
-            case RECORD: {
-                final Record record = (Record) coercedValue;
-                final RecordDataType recordDataType = (RecordDataType) dataType;
-                final RecordSchema childSchema = recordDataType.getChildSchema();
-                tagsToOpen.addLast(fieldName);
-
-                boolean hasWritten = iterateThroughRecordUsingSchema(tagsToOpen, record, childSchema);
-
-                if (hasWritten) {
-                    writer.writeEndElement();
-                    return true;
-                } else {
-
-                    if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
-                        writeAllTags(tagsToOpen);
-                        writer.writeEndElement();
-                        return true;
-                    } else {
-                        tagsToOpen.removeLast();
-                        return false;
-                    }
-                }
-            }
-            case ARRAY: {
-                final Object[] arrayValues;
-                if (coercedValue instanceof Object[]) {
-                    arrayValues = (Object[]) coercedValue;
-                } else {
-                    arrayValues = new Object[]{coercedValue.toString()};
-                }
-
-                final ArrayDataType arrayDataType = (ArrayDataType) dataType;
-                final DataType elementType = arrayDataType.getElementType();
-
-                final String elementName;
-                final String wrapperName;
-                if (arrayWrapping.equals(ArrayWrapping.USE_PROPERTY_FOR_ELEMENTS)) {
-                    elementName = arrayTagName;
-                    wrapperName = fieldName;
-                } else if (arrayWrapping.equals(ArrayWrapping.USE_PROPERTY_AS_WRAPPER)) {
-                    elementName = fieldName;
-                    wrapperName = arrayTagName;
-                } else {
-                    elementName = fieldName;
-                    wrapperName = null;
-                }
-
-                if (wrapperName!= null) {
-                    tagsToOpen.addLast(wrapperName);
-                }
-
-                boolean loopHasWritten = false;
-                for (Object element : arrayValues) {
-
-                    final DataType chosenDataType = elementType.getFieldType() == RecordFieldType.CHOICE ? DataTypeUtils.chooseDataType(element, (ChoiceDataType) elementType) : elementType;
-                    final Object coercedElement = DataTypeUtils.convertType(element, chosenDataType, LAZY_DATE_FORMAT, LAZY_TIME_FORMAT, LAZY_TIMESTAMP_FORMAT, elementName);
-
-                    if (coercedElement != null) {
-                        boolean hasWritten = writeFieldForType(tagsToOpen, coercedElement, elementType, elementName);
-
-                        if (hasWritten) {
-                            loopHasWritten = true;
-                        }
-
-                    } else {
-                        if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
-                            writeAllTags(tagsToOpen, fieldName);
-                            writer.writeEndElement();
-                            loopHasWritten = true;
-                        }
-                    }
-                }
-
-                if (wrapperName!= null) {
-                    if (loopHasWritten) {
-                        writer.writeEndElement();
-                        return true;
-                    } else {
-                        if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
-                            writeAllTags(tagsToOpen);
-                            writer.writeEndElement();
-                            return true;
-                        } else {
-                            tagsToOpen.removeLast();
-                            return false;
-                        }
-                    }
-                } else {
-                    return loopHasWritten;
-                }
-            }
-            case MAP: {
-                final MapDataType mapDataType = (MapDataType) dataType;
-                final DataType valueDataType = mapDataType.getValueType();
-                final Map<String,?> map = (Map<String,?>) coercedValue;
-
-                tagsToOpen.addLast(fieldName);
-                boolean loopHasWritten = false;
-
-                for (Map.Entry<String,?> entry : map.entrySet()) {
-
-                    final String key = entry.getKey();
-
-                    final DataType chosenDataType = valueDataType.getFieldType() == RecordFieldType.CHOICE ? DataTypeUtils.chooseDataType(entry.getValue(),
-                            (ChoiceDataType) valueDataType) : valueDataType;
-                    final Object coercedElement = DataTypeUtils.convertType(entry.getValue(), chosenDataType, LAZY_DATE_FORMAT, LAZY_TIME_FORMAT, LAZY_TIMESTAMP_FORMAT, key);
-
-                    if (coercedElement != null) {
-                        boolean hasWritten = writeFieldForType(tagsToOpen, entry.getValue(), valueDataType, key);
-
-                        if (hasWritten) {
-                            loopHasWritten = true;
-                        }
-                    } else {
-                        if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
-                            writeAllTags(tagsToOpen, key);
-                            writer.writeEndElement();
-                            loopHasWritten = true;
-                        }
-                    }
-                }
-
-                if (loopHasWritten) {
-                    writer.writeEndElement();
-                    return true;
-                } else {
-                    if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
-                        writeAllTags(tagsToOpen);
-                        writer.writeEndElement();
-                        return true;
-                    } else {
-                        tagsToOpen.removeLast();
-                        return false;
-                    }
-                }
-            }
-            case CHOICE:
-            default: {
-                return writeUnknownField(tagsToOpen, coercedValue, fieldName);
-            }
-        }
-    }
-
-    private void writeAllTags(Deque<String> tagsToOpen, String fieldName) throws XMLStreamException {
-        tagsToOpen.addLast(fieldName);
-        writeAllTags(tagsToOpen);
-    }
-
-    private String escapeTagName(final String tagName) {
-        return TAG_NAME_CHARS_TO_STRIP.matcher(tagName).replaceAll("");
-    }
-
-    private void writeAllTags(Deque<String> tagsToOpen) throws XMLStreamException {
-        for (String tagName : tagsToOpen) {
-            writer.writeStartElement(escapeTagName(tagName));
-        }
-        tagsToOpen.clear();
-    }
-
-    @Override
-    public WriteResult writeRawRecord(Record record) throws IOException {
-
-        if (!isActiveRecordSet()) {
-            schemaAccess.writeHeader(recordSchema, getOutputStream());
-        }
-
-        checkWritingMultipleRecords();
-
-        Deque<String> tagsToOpen = new ArrayDeque<>();
-
-        try {
-            tagsToOpen.addLast(recordTagName);
-
-            boolean closingTagRequired = iterateThroughRecordWithoutSchema(tagsToOpen, record);
-            if (closingTagRequired) {
-                writer.writeEndElement();
-                hasWrittenRecord = true;
-            }
-
-        } catch (XMLStreamException e) {
-            throw new IOException(e.getMessage());
-        }
-
-        final Map<String, String> attributes = schemaAccess.getAttributes(recordSchema);
-        return WriteResult.of(incrementRecordCount(), attributes);
-    }
-
-    private boolean iterateThroughRecordWithoutSchema(Deque<String> tagsToOpen, Record record) throws XMLStreamException {
-
-        boolean loopHasWritten = false;
-
-        for (String fieldName : record.getRawFieldNames()) {
-            Object value = record.getValue(fieldName);
-
-            if (value != null) {
-                boolean hasWritten = writeUnknownField(tagsToOpen, value, fieldName);
-
-                if (hasWritten) {
-                    loopHasWritten = true;
-                }
-            } else {
-                if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
-                    writeAllTags(tagsToOpen, fieldName);
-                    writer.writeEndElement();
-                    loopHasWritten = true;
-                }
-            }
-        }
-
-        return loopHasWritten;
-    }
-
-    private boolean writeUnknownField(Deque<String> tagsToOpen, Object value, String fieldName) throws XMLStreamException {
-
-        if (value instanceof Record) {
-            Record valueAsRecord = (Record) value;
-            tagsToOpen.addLast(fieldName);
-
-            boolean hasWritten = iterateThroughRecordWithoutSchema(tagsToOpen, valueAsRecord);
-
-            if (hasWritten) {
-                writer.writeEndElement();
-                return true;
-            } else {
-                if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
-                    writeAllTags(tagsToOpen);
-                    writer.writeEndElement();
-                    return true;
-                } else {
-                    tagsToOpen.removeLast();
-                    return false;
-                }
-            }
-        }
-
-        if (value instanceof Object[]) {
-            Object[] valueAsArray = (Object[]) value;
-
-            final String elementName;
-            final String wrapperName;
-            if (arrayWrapping.equals(ArrayWrapping.USE_PROPERTY_FOR_ELEMENTS)) {
-                elementName = arrayTagName;
-                wrapperName = fieldName;
-            } else if (arrayWrapping.equals(ArrayWrapping.USE_PROPERTY_AS_WRAPPER)) {
-                elementName = fieldName;
-                wrapperName = arrayTagName;
-            } else {
-                elementName = fieldName;
-                wrapperName = null;
-            }
-
-            if (wrapperName!= null) {
-                tagsToOpen.addLast(wrapperName);
-            }
-
-            boolean loopHasWritten = false;
-
-            for (Object element : valueAsArray) {
-                if (element != null) {
-                    boolean hasWritten = writeUnknownField(tagsToOpen, element, elementName);
-
-                    if (hasWritten) {
-                        loopHasWritten = true;
-                    }
-
-                } else {
-                    if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
-                        writeAllTags(tagsToOpen, fieldName);
-                        writer.writeEndElement();
-                        loopHasWritten = true;
-                    }
-                }
-            }
-
-            if (wrapperName!= null) {
-                if (loopHasWritten) {
-                    writer.writeEndElement();
-                    return true;
-                } else {
-                    if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
-                        writeAllTags(tagsToOpen);
-                        writer.writeEndElement();
-                        return true;
-                    } else {
-                        tagsToOpen.removeLast();
-                        return false;
-                    }
-                }
-            } else {
-                return loopHasWritten;
-            }
-        }
-
-        if (value instanceof Map) {
-            Map<String, ?> valueAsMap = (Map<String, ?>) value;
-
-            tagsToOpen.addLast(fieldName);
-            boolean loopHasWritten = false;
-
-            for (Map.Entry<String,?> entry : valueAsMap.entrySet()) {
-
-                final String key = entry.getKey();
-                final Object entryValue = entry.getValue();
-
-                if (entryValue != null) {
-                    boolean hasWritten = writeUnknownField(tagsToOpen, entry.getValue(), key);
-
-                    if (hasWritten) {
-                        loopHasWritten = true;
-                    }
-                } else {
-                    if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
-                        writeAllTags(tagsToOpen, key);
-                        writer.writeEndElement();
-                        loopHasWritten = true;
-                    }
-                }
-
-            }
-
-            if (loopHasWritten) {
-                writer.writeEndElement();
-                return true;
-            } else {
-                if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
-                    writeAllTags(tagsToOpen);
-                    writer.writeEndElement();
-                    return true;
-                } else {
-                    tagsToOpen.removeLast();
-                    return false;
-                }
-            }
-        }
-
-        writeAllTags(tagsToOpen, fieldName);
-        writer.writeCharacters(value.toString());
-        writer.writeEndElement();
-        return true;
-    }
-
-
-    @Override
-    public String getMimeType() {
-        return "application/xml";
-    }
-
-    private boolean recordHasField(RecordField field, Record record) {
-        Set<String> recordFieldNames = record.getRawFieldNames();
-        if (recordFieldNames.contains(field.getFieldName())) {
-            return true;
-        }
-
-        for (String alias : field.getAliases()) {
-            if (recordFieldNames.contains(alias)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.xml;
+
+import javanet.staxutils.IndentingXMLStreamWriter;
+import org.apache.nifi.record.NullSuppression;
+import org.apache.nifi.schema.access.SchemaAccessWriter;
+import org.apache.nifi.serialization.AbstractRecordSetWriter;
+import org.apache.nifi.serialization.RecordSetWriter;
+import org.apache.nifi.serialization.WriteResult;
+import org.apache.nifi.serialization.record.DataType;
+import org.apache.nifi.serialization.record.RawRecordWriter;
+import org.apache.nifi.serialization.record.Record;
+import org.apache.nifi.serialization.record.RecordField;
+import org.apache.nifi.serialization.record.RecordFieldType;
+import org.apache.nifi.serialization.record.RecordSchema;
+import org.apache.nifi.serialization.record.type.ArrayDataType;
+import org.apache.nifi.serialization.record.type.ChoiceDataType;
+import org.apache.nifi.serialization.record.type.MapDataType;
+import org.apache.nifi.serialization.record.type.RecordDataType;
+import org.apache.nifi.serialization.record.util.DataTypeUtils;
+
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.DateFormat;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Supplier;
+import java.util.regex.Pattern;
+
+import static org.apache.nifi.xml.XMLRecordSetWriter.RECORD_TAG_NAME;
+import static org.apache.nifi.xml.XMLRecordSetWriter.ROOT_TAG_NAME;
+
+
+public class WriteXMLResult extends AbstractRecordSetWriter implements RecordSetWriter, RawRecordWriter {
+    private static final Pattern TAG_NAME_CHARS_TO_STRIP = Pattern.compile("[/<>!&'\"]");
+
+    private final RecordSchema recordSchema;
+    private final SchemaAccessWriter schemaAccess;
+    private final XMLStreamWriter writer;
+    private final NullSuppression nullSuppression;
+    private final boolean omitDeclaration;
+    private final ArrayWrapping arrayWrapping;
+    private final String arrayTagName;
+    private final String recordTagName;
+    private final String rootTagName;
+    private final boolean allowWritingMultipleRecords;
+    private boolean hasWrittenRecord;
+
+    private final Supplier<DateFormat> LAZY_DATE_FORMAT;
+    private final Supplier<DateFormat> LAZY_TIME_FORMAT;
+    private final Supplier<DateFormat> LAZY_TIMESTAMP_FORMAT;
+
+    public WriteXMLResult(final RecordSchema recordSchema, final SchemaAccessWriter schemaAccess, final OutputStream out, final boolean prettyPrint, final boolean omitDeclaration,
+                          final NullSuppression nullSuppression, final ArrayWrapping arrayWrapping, final String arrayTagName, final String rootTagName, final String recordTagName,
+                          final String charSet, final String dateFormat, final String timeFormat, final String timestampFormat) throws IOException {
+
+        super(out);
+
+        this.recordSchema = recordSchema;
+        this.schemaAccess = schemaAccess;
+        this.nullSuppression = nullSuppression;
+
+        this.omitDeclaration = omitDeclaration;
+
+        this.arrayWrapping = arrayWrapping;
+        this.arrayTagName = arrayTagName;
+
+        this.rootTagName = rootTagName;
+
+        if (recordTagName != null) {
+            this.recordTagName = recordTagName;
+        } else {
+            Optional<String> recordTagNameOptional = recordSchema.getSchemaName().isPresent()? recordSchema.getSchemaName() : recordSchema.getIdentifier().getName();
+            if (recordTagNameOptional.isPresent()) {
+                this.recordTagName = recordTagNameOptional.get();
+            } else {
+                final String message = "The property '" + RECORD_TAG_NAME.getDisplayName() +
+                    "' has not been set and the writer does not find a record name in the schema.";
+                throw new IOException(message);
+            }
+        }
+
+        this.allowWritingMultipleRecords = !(this.rootTagName == null);
+        hasWrittenRecord = false;
+
+        final DateFormat df = dateFormat == null ? null : DataTypeUtils.getDateFormat(dateFormat);
+        final DateFormat tf = timeFormat == null ? null : DataTypeUtils.getDateFormat(timeFormat);
+        final DateFormat tsf = timestampFormat == null ? null : DataTypeUtils.getDateFormat(timestampFormat);
+
+        LAZY_DATE_FORMAT = () -> df;
+        LAZY_TIME_FORMAT = () -> tf;
+        LAZY_TIMESTAMP_FORMAT = () -> tsf;
+
+        try {
+            XMLOutputFactory factory = XMLOutputFactory.newInstance();
+
+            if (prettyPrint) {
+                writer = new IndentingXMLStreamWriter(factory.createXMLStreamWriter(out, charSet));
+            } else {
+                writer = factory.createXMLStreamWriter(out, charSet);
+            }
+
+        } catch (XMLStreamException e) {
+            throw new IOException(e.getMessage());
+        }
+    }
+
+    @Override
+    protected void onBeginRecordSet() throws IOException {
+
+        final OutputStream out = getOutputStream();
+        schemaAccess.writeHeader(recordSchema, out);
+
+        try {
+            if (!omitDeclaration) {
+                writer.writeStartDocument();
+            }
+
+            if (allowWritingMultipleRecords) {
+                writer.writeStartElement(rootTagName);
+            }
+
+        } catch (XMLStreamException e) {
+            throw new IOException(e.getMessage());
+        }
+    }
+
+    @Override
+    protected Map<String, String> onFinishRecordSet() throws IOException {
+
+        try {
+            if (allowWritingMultipleRecords) {
+                writer.writeEndElement();
+            }
+
+            writer.writeEndDocument();
+        } catch (XMLStreamException e) {
+            throw new IOException(e.getMessage());
+        }
+        return schemaAccess.getAttributes(recordSchema);
+    }
+
+    @Override
+    public void close() throws IOException {
+
+        try {
+            writer.close();
+
+        } catch (XMLStreamException e) {
+            throw new IOException(e.getMessage());
+        }
+
+        super.close();
+    }
+
+    @Override
+    public void flush() throws IOException {
+
+        try {
+            writer.flush();
+
+        } catch (XMLStreamException e) {
+            throw new IOException(e.getMessage());
+        }
+    }
+
+    private void checkWritingMultipleRecords() throws IOException {
+        if (!allowWritingMultipleRecords && hasWrittenRecord) {
+            final String message = "The writer attempts to write multiple record although property \'" + ROOT_TAG_NAME.getDisplayName() +
+                "\' has not been set. If the XMLRecordSetWriter is supposed to write multiple records into one FlowFile, this property is required to be configured.";
+            throw new IOException(message);
+        }
+    }
+
+    @Override
+    protected Map<String, String> writeRecord(Record record) throws IOException {
+
+        if (!isActiveRecordSet()) {
+            schemaAccess.writeHeader(recordSchema, getOutputStream());
+        }
+
+        checkWritingMultipleRecords();
+
+        Deque<String> tagsToOpen = new ArrayDeque<>();
+
+        try {
+            tagsToOpen.addLast(recordTagName);
+
+            boolean closingTagRequired = iterateThroughRecordUsingSchema(tagsToOpen, record, recordSchema);
+            if (closingTagRequired) {
+                writer.writeEndElement();
+                hasWrittenRecord = true;
+            }
+
+        } catch (XMLStreamException e) {
+            throw new IOException(e.getMessage());
+        }
+        return schemaAccess.getAttributes(recordSchema);
+    }
+
+    private boolean iterateThroughRecordUsingSchema(Deque<String> tagsToOpen, Record record, RecordSchema schema) throws XMLStreamException {
+
+        boolean loopHasWritten = false;
+        for (RecordField field : schema.getFields()) {
+
+            String fieldName = field.getFieldName();
+            DataType dataType = field.getDataType();
+            Object value = record.getValue(field);
+
+            final DataType chosenDataType = dataType.getFieldType() == RecordFieldType.CHOICE ? DataTypeUtils.chooseDataType(value, (ChoiceDataType) dataType) : dataType;
+            final Object coercedValue = DataTypeUtils.convertType(value, chosenDataType, LAZY_DATE_FORMAT, LAZY_TIME_FORMAT, LAZY_TIMESTAMP_FORMAT, fieldName);
+
+            if (coercedValue != null) {
+                boolean hasWritten = writeFieldForType(tagsToOpen, coercedValue, chosenDataType, fieldName);
+                if (hasWritten) {
+                    loopHasWritten = true;
+                }
+
+            } else {
+                if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING) && recordHasField(field, record)) {
+                    writeAllTags(tagsToOpen, fieldName);
+                    writer.writeEndElement();
+                    loopHasWritten = true;
+                }
+            }
+        }
+
+        return loopHasWritten;
+    }
+
+    private boolean writeFieldForType(Deque<String> tagsToOpen, Object coercedValue, DataType dataType, String fieldName) throws XMLStreamException {
+        switch (dataType.getFieldType()) {
+            case BOOLEAN:
+            case BYTE:
+            case CHAR:
+            case DECIMAL:
+            case DOUBLE:
+            case FLOAT:
+            case INT:
+            case LONG:
+            case SHORT:
+            case STRING: {
+                writeAllTags(tagsToOpen, fieldName);
+                writer.writeCharacters(coercedValue.toString());
+                writer.writeEndElement();
+                return true;
+            }
+            case DATE: {
+                writeAllTags(tagsToOpen, fieldName);
+                final String stringValue = DataTypeUtils.toString(coercedValue, LAZY_DATE_FORMAT);
+                writer.writeCharacters(stringValue);
+                writer.writeEndElement();
+                return true;
+            }
+            case TIME: {
+                writeAllTags(tagsToOpen, fieldName);
+                final String stringValue = DataTypeUtils.toString(coercedValue, LAZY_TIME_FORMAT);
+                writer.writeCharacters(stringValue);
+                writer.writeEndElement();
+                return true;
+            }
+            case TIMESTAMP: {
+                writeAllTags(tagsToOpen, fieldName);
+                final String stringValue = DataTypeUtils.toString(coercedValue, LAZY_TIMESTAMP_FORMAT);
+                writer.writeCharacters(stringValue);
+                writer.writeEndElement();
+                return true;
+            }
+            case RECORD: {
+                final Record record = (Record) coercedValue;
+                final RecordDataType recordDataType = (RecordDataType) dataType;
+                final RecordSchema childSchema = recordDataType.getChildSchema();
+                tagsToOpen.addLast(fieldName);
+
+                boolean hasWritten = iterateThroughRecordUsingSchema(tagsToOpen, record, childSchema);
+
+                if (hasWritten) {
+                    writer.writeEndElement();
+                    return true;
+                } else {
+
+                    if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
+                        writeAllTags(tagsToOpen);
+                        writer.writeEndElement();
+                        return true;
+                    } else {
+                        tagsToOpen.removeLast();
+                        return false;
+                    }
+                }
+            }
+            case ARRAY: {
+                final Object[] arrayValues;
+                if (coercedValue instanceof Object[]) {
+                    arrayValues = (Object[]) coercedValue;
+                } else {
+                    arrayValues = new Object[]{coercedValue.toString()};
+                }
+
+                final ArrayDataType arrayDataType = (ArrayDataType) dataType;
+                final DataType elementType = arrayDataType.getElementType();
+
+                final String elementName;
+                final String wrapperName;
+                if (arrayWrapping.equals(ArrayWrapping.USE_PROPERTY_FOR_ELEMENTS)) {
+                    elementName = arrayTagName;
+                    wrapperName = fieldName;
+                } else if (arrayWrapping.equals(ArrayWrapping.USE_PROPERTY_AS_WRAPPER)) {
+                    elementName = fieldName;
+                    wrapperName = arrayTagName;
+                } else {
+                    elementName = fieldName;
+                    wrapperName = null;
+                }
+
+                if (wrapperName!= null) {
+                    tagsToOpen.addLast(wrapperName);
+                }
+
+                boolean loopHasWritten = false;
+                for (Object element : arrayValues) {
+
+                    final DataType chosenDataType = elementType.getFieldType() == RecordFieldType.CHOICE ? DataTypeUtils.chooseDataType(element, (ChoiceDataType) elementType) : elementType;
+                    final Object coercedElement = DataTypeUtils.convertType(element, chosenDataType, LAZY_DATE_FORMAT, LAZY_TIME_FORMAT, LAZY_TIMESTAMP_FORMAT, elementName);
+
+                    if (coercedElement != null) {
+                        boolean hasWritten = writeFieldForType(tagsToOpen, coercedElement, elementType, elementName);
+
+                        if (hasWritten) {
+                            loopHasWritten = true;
+                        }
+
+                    } else {
+                        if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
+                            writeAllTags(tagsToOpen, fieldName);
+                            writer.writeEndElement();
+                            loopHasWritten = true;
+                        }
+                    }
+                }
+
+                if (wrapperName!= null) {
+                    if (loopHasWritten) {
+                        writer.writeEndElement();
+                        return true;
+                    } else {
+                        if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
+                            writeAllTags(tagsToOpen);
+                            writer.writeEndElement();
+                            return true;
+                        } else {
+                            tagsToOpen.removeLast();
+                            return false;
+                        }
+                    }
+                } else {
+                    return loopHasWritten;
+                }
+            }
+            case MAP: {
+                final MapDataType mapDataType = (MapDataType) dataType;
+                final DataType valueDataType = mapDataType.getValueType();
+                final Map<String,?> map = (Map<String,?>) coercedValue;
+
+                tagsToOpen.addLast(fieldName);
+                boolean loopHasWritten = false;
+
+                for (Map.Entry<String,?> entry : map.entrySet()) {
+
+                    final String key = entry.getKey();
+
+                    final DataType chosenDataType = valueDataType.getFieldType() == RecordFieldType.CHOICE ? DataTypeUtils.chooseDataType(entry.getValue(),
+                            (ChoiceDataType) valueDataType) : valueDataType;
+                    final Object coercedElement = DataTypeUtils.convertType(entry.getValue(), chosenDataType, LAZY_DATE_FORMAT, LAZY_TIME_FORMAT, LAZY_TIMESTAMP_FORMAT, key);
+
+                    if (coercedElement != null) {
+                        boolean hasWritten = writeFieldForType(tagsToOpen, entry.getValue(), valueDataType, key);
+
+                        if (hasWritten) {
+                            loopHasWritten = true;
+                        }
+                    } else {
+                        if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
+                            writeAllTags(tagsToOpen, key);
+                            writer.writeEndElement();
+                            loopHasWritten = true;
+                        }
+                    }
+                }
+
+                if (loopHasWritten) {
+                    writer.writeEndElement();
+                    return true;
+                } else {
+                    if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
+                        writeAllTags(tagsToOpen);
+                        writer.writeEndElement();
+                        return true;
+                    } else {
+                        tagsToOpen.removeLast();
+                        return false;
+                    }
+                }
+            }
+            case CHOICE:
+            default: {
+                return writeUnknownField(tagsToOpen, coercedValue, fieldName);
+            }
+        }
+    }
+
+    private void writeAllTags(Deque<String> tagsToOpen, String fieldName) throws XMLStreamException {
+        tagsToOpen.addLast(fieldName);
+        writeAllTags(tagsToOpen);
+    }
+
+    private String escapeTagName(final String tagName) {
+        return TAG_NAME_CHARS_TO_STRIP.matcher(tagName).replaceAll("");
+    }
+
+    private void writeAllTags(Deque<String> tagsToOpen) throws XMLStreamException {
+        for (String tagName : tagsToOpen) {
+            writer.writeStartElement(escapeTagName(tagName));
+        }
+        tagsToOpen.clear();
+    }
+
+    @Override
+    public WriteResult writeRawRecord(Record record) throws IOException {
+
+        if (!isActiveRecordSet()) {
+            schemaAccess.writeHeader(recordSchema, getOutputStream());
+        }
+
+        checkWritingMultipleRecords();
+
+        Deque<String> tagsToOpen = new ArrayDeque<>();
+
+        try {
+            tagsToOpen.addLast(recordTagName);
+
+            boolean closingTagRequired = iterateThroughRecordWithoutSchema(tagsToOpen, record);
+            if (closingTagRequired) {
+                writer.writeEndElement();
+                hasWrittenRecord = true;
+            }
+
+        } catch (XMLStreamException e) {
+            throw new IOException(e.getMessage());
+        }
+
+        final Map<String, String> attributes = schemaAccess.getAttributes(recordSchema);
+        return WriteResult.of(incrementRecordCount(), attributes);
+    }
+
+    private boolean iterateThroughRecordWithoutSchema(Deque<String> tagsToOpen, Record record) throws XMLStreamException {
+
+        boolean loopHasWritten = false;
+
+        for (String fieldName : record.getRawFieldNames()) {
+            Object value = record.getValue(fieldName);
+
+            if (value != null) {
+                boolean hasWritten = writeUnknownField(tagsToOpen, value, fieldName);
+
+                if (hasWritten) {
+                    loopHasWritten = true;
+                }
+            } else {
+                if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
+                    writeAllTags(tagsToOpen, fieldName);
+                    writer.writeEndElement();
+                    loopHasWritten = true;
+                }
+            }
+        }
+
+        return loopHasWritten;
+    }
+
+    private boolean writeUnknownField(Deque<String> tagsToOpen, Object value, String fieldName) throws XMLStreamException {
+
+        if (value instanceof Record) {
+            Record valueAsRecord = (Record) value;
+            tagsToOpen.addLast(fieldName);
+
+            boolean hasWritten = iterateThroughRecordWithoutSchema(tagsToOpen, valueAsRecord);
+
+            if (hasWritten) {
+                writer.writeEndElement();
+                return true;
+            } else {
+                if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
+                    writeAllTags(tagsToOpen);
+                    writer.writeEndElement();
+                    return true;
+                } else {
+                    tagsToOpen.removeLast();
+                    return false;
+                }
+            }
+        }
+
+        if (value instanceof Object[]) {
+            Object[] valueAsArray = (Object[]) value;
+
+            final String elementName;
+            final String wrapperName;
+            if (arrayWrapping.equals(ArrayWrapping.USE_PROPERTY_FOR_ELEMENTS)) {
+                elementName = arrayTagName;
+                wrapperName = fieldName;
+            } else if (arrayWrapping.equals(ArrayWrapping.USE_PROPERTY_AS_WRAPPER)) {
+                elementName = fieldName;
+                wrapperName = arrayTagName;
+            } else {
+                elementName = fieldName;
+                wrapperName = null;
+            }
+
+            if (wrapperName!= null) {
+                tagsToOpen.addLast(wrapperName);
+            }
+
+            boolean loopHasWritten = false;
+
+            for (Object element : valueAsArray) {
+                if (element != null) {
+                    boolean hasWritten = writeUnknownField(tagsToOpen, element, elementName);
+
+                    if (hasWritten) {
+                        loopHasWritten = true;
+                    }
+
+                } else {
+                    if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
+                        writeAllTags(tagsToOpen, fieldName);
+                        writer.writeEndElement();
+                        loopHasWritten = true;
+                    }
+                }
+            }
+
+            if (wrapperName!= null) {
+                if (loopHasWritten) {
+                    writer.writeEndElement();
+                    return true;
+                } else {
+                    if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
+                        writeAllTags(tagsToOpen);
+                        writer.writeEndElement();
+                        return true;
+                    } else {
+                        tagsToOpen.removeLast();
+                        return false;
+                    }
+                }
+            } else {
+                return loopHasWritten;
+            }
+        }
+
+        if (value instanceof Map) {
+            Map<String, ?> valueAsMap = (Map<String, ?>) value;
+
+            tagsToOpen.addLast(fieldName);
+            boolean loopHasWritten = false;
+
+            for (Map.Entry<String,?> entry : valueAsMap.entrySet()) {
+
+                final String key = entry.getKey();
+                final Object entryValue = entry.getValue();
+
+                if (entryValue != null) {
+                    boolean hasWritten = writeUnknownField(tagsToOpen, entry.getValue(), key);
+
+                    if (hasWritten) {
+                        loopHasWritten = true;
+                    }
+                } else {
+                    if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
+                        writeAllTags(tagsToOpen, key);
+                        writer.writeEndElement();
+                        loopHasWritten = true;
+                    }
+                }
+
+            }
+
+            if (loopHasWritten) {
+                writer.writeEndElement();
+                return true;
+            } else {
+                if (nullSuppression.equals(NullSuppression.NEVER_SUPPRESS) || nullSuppression.equals(NullSuppression.SUPPRESS_MISSING)) {
+                    writeAllTags(tagsToOpen);
+                    writer.writeEndElement();
+                    return true;
+                } else {
+                    tagsToOpen.removeLast();
+                    return false;
+                }
+            }
+        }
+
+        writeAllTags(tagsToOpen, fieldName);
+        writer.writeCharacters(value.toString());
+        writer.writeEndElement();
+        return true;
+    }
+
+
+    @Override
+    public String getMimeType() {
+        return "application/xml";
+    }
+
+    private boolean recordHasField(RecordField field, Record record) {
+        Set<String> recordFieldNames = record.getRawFieldNames();
+        if (recordFieldNames.contains(field.getFieldName())) {
+            return true;
+        }
+
+        for (String alias : field.getAliases()) {
+            if (recordFieldNames.contains(alias)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+}
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-record-serialization-services-bundle/nifi-record-serialization-services/src/test/java/org/apache/nifi/xml/TestWriteXMLResult.java b/nifi-nar-bundles/nifi-standard-services/nifi-record-serialization-services-bundle/nifi-record-serialization-services/src/test/java/org/apache/nifi/xml/TestWriteXMLResult.java
index 13148d8..a278167 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-record-serialization-services-bundle/nifi-record-serialization-services/src/test/java/org/apache/nifi/xml/TestWriteXMLResult.java
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-record-serialization-services-bundle/nifi-record-serialization-services/src/test/java/org/apache/nifi/xml/TestWriteXMLResult.java
@@ -1,1430 +1,1430 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.nifi.xml;
-
-import org.apache.nifi.schema.access.SchemaNameAsAttribute;
-import org.apache.nifi.serialization.SimpleRecordSchema;
-import org.apache.nifi.serialization.record.DataType;
-import org.apache.nifi.serialization.record.MapRecord;
-import org.apache.nifi.serialization.record.Record;
-import org.apache.nifi.serialization.record.RecordField;
-import org.apache.nifi.serialization.record.RecordFieldType;
-import org.apache.nifi.serialization.record.RecordSchema;
-import org.apache.nifi.serialization.record.RecordSet;
-import org.junit.Assert;
-import org.junit.Test;
-import org.xmlunit.diff.DefaultNodeMatcher;
-import org.xmlunit.diff.ElementSelectors;
-import org.xmlunit.matchers.CompareMatcher;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.math.BigInteger;
-import java.sql.Date;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TimeZone;
-
-import static org.apache.nifi.record.NullSuppression.ALWAYS_SUPPRESS;
-import static org.apache.nifi.record.NullSuppression.NEVER_SUPPRESS;
-import static org.apache.nifi.record.NullSuppression.SUPPRESS_MISSING;
-import static org.apache.nifi.xml.ArrayWrapping.NO_WRAPPING;
-import static org.apache.nifi.xml.ArrayWrapping.USE_PROPERTY_AS_WRAPPER;
-import static org.apache.nifi.xml.ArrayWrapping.USE_PROPERTY_FOR_ELEMENTS;
-import static org.apache.nifi.xml.TestWriteXMLResultUtils.DATE_FORMAT;
-import static org.apache.nifi.xml.TestWriteXMLResultUtils.SCHEMA_IDENTIFIER_RECORD;
-import static org.apache.nifi.xml.TestWriteXMLResultUtils.TIMESTAMP_FORMAT;
-import static org.apache.nifi.xml.TestWriteXMLResultUtils.TIME_FORMAT;
-import static org.apache.nifi.xml.TestWriteXMLResultUtils.getEmptyNestedRecordDefinedSchema;
-import static org.apache.nifi.xml.TestWriteXMLResultUtils.getEmptyNestedRecordEmptyNestedSchema;
-import static org.apache.nifi.xml.TestWriteXMLResultUtils.getEmptyRecordsWithEmptySchema;
-import static org.apache.nifi.xml.TestWriteXMLResultUtils.getNestedRecords;
-import static org.apache.nifi.xml.TestWriteXMLResultUtils.getNestedRecordsWithNullValues;
-import static org.apache.nifi.xml.TestWriteXMLResultUtils.getNestedRecordsWithOnlyNullValues;
-import static org.apache.nifi.xml.TestWriteXMLResultUtils.getRecordWithSimpleArray;
-import static org.apache.nifi.xml.TestWriteXMLResultUtils.getRecordWithSimpleMap;
-import static org.apache.nifi.xml.TestWriteXMLResultUtils.getSimpleRecords;
-import static org.apache.nifi.xml.TestWriteXMLResultUtils.getSimpleRecordsWithChoice;
-import static org.apache.nifi.xml.TestWriteXMLResultUtils.getSimpleRecordsWithNullValues;
-import static org.apache.nifi.xml.TestWriteXMLResultUtils.getSimpleRecordsWithoutIdentifierInSchema;
-import static org.apache.nifi.xml.TestWriteXMLResultUtils.getSingleRecord;
-import static org.junit.Assert.assertThat;
-
-public class TestWriteXMLResult {
-
-    @Test
-    public void testRecordNameIsNullSchemaIdentifierMissing() {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getSimpleRecordsWithoutIdentifierInSchema();
-
-        final String expectedMessage = "The property 'Name of Record Tag' has not been set and the writer does not find a record name in the schema.";
-        final StringBuilder actualMessage = new StringBuilder();
-
-        try {
-            new WriteXMLResult(recordSet.getSchema(), new SchemaNameAsAttribute(),
-                    out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "root", null, "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        } catch (IOException e) {
-            actualMessage.append(e.getMessage());
-        }
-        Assert.assertEquals(expectedMessage, actualMessage.toString());
-
-    }
-
-    @Test
-    public void testRecordNameIsNullSchemaIdentifierExists() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getSimpleRecords();
-        WriteXMLResult writer = new WriteXMLResult(recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", null, "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isIdenticalTo(out.toString()).ignoreWhitespace());
-
-    }
-
-    @Test
-    public void testRootNameIsNull() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getSimpleRecords();
-        WriteXMLResult writer = new WriteXMLResult(recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, null, "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        final String expectedMessage = "The writer attempts to write multiple record although property \'Name of Root Tag\' " +
-                "has not been set. If the XMLRecordSetWriter is supposed to write multiple records into one FlowFile, this property is required to be configured.";
-        final StringBuilder actualMessage = new StringBuilder();
-
-        try {
-            writer.write(recordSet);
-
-        } catch (IOException e) {
-            actualMessage.append(e.getMessage());
-        }
-        Assert.assertEquals(expectedMessage, actualMessage.toString());
-    }
-
-    @Test
-    public void testSingleRecord() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getSingleRecord();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, null, "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>";
-
-        assertThat(xmlResult, CompareMatcher.isIdenticalTo(out.toString()).ignoreWhitespace());
-    }
-
-    @Test
-    public void testDataTypes() throws IOException, ParseException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        final List<RecordField> fields = new ArrayList<>();
-
-        for (final RecordFieldType fieldType : RecordFieldType.values()) {
-
-            if (fieldType == RecordFieldType.CHOICE) {
-                final List<DataType> possibleTypes = new ArrayList<>();
-                possibleTypes.add(RecordFieldType.INT.getDataType());
-                possibleTypes.add(RecordFieldType.LONG.getDataType());
-
-                fields.add(new RecordField(fieldType.name().toLowerCase(), fieldType.getChoiceDataType(possibleTypes)));
-
-            } else if (fieldType == RecordFieldType.MAP) {
-                fields.add(new RecordField(fieldType.name().toLowerCase(), fieldType.getMapDataType(RecordFieldType.INT.getDataType())));
-
-            } else {
-                fields.add(new RecordField(fieldType.name().toLowerCase(), fieldType.getDataType()));
-            }
-        }
-        final RecordSchema schema = new SimpleRecordSchema(fields, SCHEMA_IDENTIFIER_RECORD);
-
-        final DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
-        df.setTimeZone(TimeZone.getTimeZone("gmt"));
-        final long time = df.parse("2017/01/01 17:00:00.000").getTime();
-
-        final Map<String, Object> map = new LinkedHashMap<>();
-        map.put("height", 48);
-        map.put("width", 96);
-
-        final Map<String, Object> valueMap = new LinkedHashMap<>();
-        valueMap.put("string", "string");
-        valueMap.put("boolean", true);
-        valueMap.put("byte", (byte) 1);
-        valueMap.put("char", 'c');
-        valueMap.put("short", (short) 8);
-        valueMap.put("int", 9);
-        valueMap.put("bigint", BigInteger.valueOf(8L));
-        valueMap.put("long", 8L);
-        valueMap.put("float", 8.0F);
-        valueMap.put("double", 8.0D);
-        valueMap.put("decimal", 8.1D);
-        valueMap.put("date", new Date(time));
-        valueMap.put("time", new Time(time));
-        valueMap.put("timestamp", new Timestamp(time));
-        valueMap.put("record", null);
-        valueMap.put("array", null);
-        valueMap.put("choice", 48L);
-        valueMap.put("map", map);
-
-        final Record record = new MapRecord(schema, valueMap);
-        final RecordSet rs = RecordSet.of(schema, record);
-
-        WriteXMLResult writer = new WriteXMLResult( rs.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "RECORD", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(rs);
-        writer.flush();
-
-        String xmlResult = "<ROOT><RECORD><string>string</string><boolean>true</boolean><byte>1</byte><char>c</char><short>8</short>" +
-                "<int>9</int><bigint>8</bigint><long>8</long><float>8.0</float><double>8.0</double><decimal>8.1</decimal>" +
-                "<date>2017-01-01</date><time>17:00:00</time><timestamp>2017-01-01 17:00:00</timestamp><record /><choice>48</choice><array />" +
-                "<map><height>48</height><width>96</width></map></RECORD></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testSimpleRecord() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getSimpleRecords();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isIdenticalTo(out.toString()).ignoreWhitespace());
-    }
-
-    @Test
-    public void testSimpleRecordWithNullValuesAlwaysSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getSimpleRecordsWithNullValues();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isIdenticalTo(out.toString()).ignoreWhitespace());
-    }
-
-    @Test
-    public void testSimpleRecordWithNullValuesNeverSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getSimpleRecordsWithNullValues();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><NAME></NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME></NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isIdenticalTo(out.toString()).ignoreWhitespace());
-    }
-
-    @Test
-    public void testSimpleRecordWithNullValuesSuppressMissings() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getSimpleRecordsWithNullValues();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, SUPPRESS_MISSING, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><NAME></NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isIdenticalTo(out.toString()).ignoreWhitespace());
-    }
-
-    @Test
-    public void testSimpleRecordWithXMLDeclaration() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getSimpleRecords();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, false, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<?xml version=\"1.0\" ?><ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        Assert.assertEquals(xmlResult, out.toString().trim());
-    }
-
-    @Test
-    public void testSimpleRecordWithOutXMLDeclaration() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getSimpleRecords();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, false, true, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        Assert.assertEquals(xmlResult, out.toString().trim());
-    }
-
-    @Test
-    public void testEmptyRecordWithEmptySchema() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getEmptyRecordsWithEmptySchema();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isIdenticalTo(out.toString()).ignoreWhitespace());
-    }
-
-    @Test
-    public void testNestedRecord() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getNestedRecords();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY>" +
-                "<ADDRESS><STREET>292 West Street</STREET><CITY>Jersey City</CITY></ADDRESS></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY><ADDRESS>" +
-                "<STREET>123 6th St.</STREET><CITY>Seattle</CITY></ADDRESS></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testNestedRecordWithNullValuesAlwaysSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getNestedRecordsWithNullValues();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><ADDRESS><CITY>Jersey City</CITY></ADDRESS><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><ADDRESS><CITY>Seattle</CITY></ADDRESS><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testNestedRecordWithNullValuesNeverSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getNestedRecordsWithNullValues();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY>" +
-                "<ADDRESS><STREET></STREET><CITY>Jersey City</CITY></ADDRESS></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY><ADDRESS>" +
-                "<STREET></STREET><CITY>Seattle</CITY></ADDRESS></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testNestedRecordWithNullValuesSuppressMissings() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getNestedRecordsWithNullValues();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, SUPPRESS_MISSING, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY>" +
-                "<ADDRESS><STREET></STREET><CITY>Jersey City</CITY></ADDRESS></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY><ADDRESS>" +
-                "<CITY>Seattle</CITY></ADDRESS></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testNestedRecordWithOnlyNullValuesAlwaysSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getNestedRecordsWithOnlyNullValues();
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testNestedRecordWithOnlyNullValuesNeverSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getNestedRecordsWithOnlyNullValues();
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><ADDRESS><STREET></STREET><CITY></CITY></ADDRESS>" +
-                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><ADDRESS><STREET></STREET><CITY></CITY></ADDRESS>" +
-                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testEmptyNestedRecordEmptySchemaNeverSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getEmptyNestedRecordEmptyNestedSchema();
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><ADDRESS></ADDRESS><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><ADDRESS></ADDRESS><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testEmptyNestedRecordEmptySchemaAlwaysSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getEmptyNestedRecordEmptyNestedSchema();
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testNestedEmptyRecordDefinedSchemaSuppressMissing() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getEmptyNestedRecordDefinedSchema();
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, SUPPRESS_MISSING, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><ADDRESS></ADDRESS><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><ADDRESS></ADDRESS><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testSimpleArray() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.WITHOUT_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><CHILDREN>Tom</CHILDREN><CHILDREN>Anna</CHILDREN><CHILDREN>Ben</CHILDREN>" +
-                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><CHILDREN>Tom</CHILDREN><CHILDREN>Anna</CHILDREN><CHILDREN>Ben</CHILDREN>" +
-                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testSimpleArrayWithNullValuesAlwaysSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.HAS_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><CHILDREN>Tom</CHILDREN><CHILDREN>Ben</CHILDREN>" +
-                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><CHILDREN>Tom</CHILDREN><CHILDREN>Ben</CHILDREN>" +
-                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testSimpleArrayWithNullValuesNeverSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.HAS_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><CHILDREN>Tom</CHILDREN><CHILDREN></CHILDREN><CHILDREN>Ben</CHILDREN>" +
-                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><CHILDREN>Tom</CHILDREN><CHILDREN></CHILDREN><CHILDREN>Ben</CHILDREN>" +
-                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testSimpleArrayWithOnlyNullValuesAlwaysSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.ONLY_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testSimpleArrayWithOnlyNullValuesAlwaysSuppressWrapping() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.ONLY_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, USE_PROPERTY_AS_WRAPPER, "ARRAY", "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testEmptyArray() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.EMPTY);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testEmptyArrayNeverSupressPropAsWrapper() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.EMPTY);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, NEVER_SUPPRESS, USE_PROPERTY_AS_WRAPPER, "ARRAY", "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><ARRAY></ARRAY><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><ARRAY></ARRAY><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testSimpleArrayPropAsWrapper() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.WITHOUT_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, USE_PROPERTY_AS_WRAPPER, "ARRAY", "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><ARRAY><CHILDREN>Tom</CHILDREN><CHILDREN>Anna</CHILDREN><CHILDREN>Ben</CHILDREN></ARRAY>" +
-                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><ARRAY><CHILDREN>Tom</CHILDREN><CHILDREN>Anna</CHILDREN><CHILDREN>Ben</CHILDREN></ARRAY>" +
-                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testSimpleArrayPropForElem() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.WITHOUT_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, USE_PROPERTY_FOR_ELEMENTS, "ELEM", "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><CHILDREN><ELEM>Tom</ELEM><ELEM>Anna</ELEM><ELEM>Ben</ELEM></CHILDREN>" +
-                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><CHILDREN><ELEM>Tom</ELEM><ELEM>Anna</ELEM><ELEM>Ben</ELEM></CHILDREN>" +
-                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testSimpleMapAlwaysSuppressWithoutNull() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.WITHOUT_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3><CHILD2>Anna</CHILD2></CHILDREN>" +
-                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3><CHILD2>Anna</CHILD2></CHILDREN>" +
-                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testSimpleMapAlwaysSuppressHasNull() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.HAS_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3></CHILDREN>" +
-                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3></CHILDREN>" +
-                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testSimpleMapAlwaysSuppressOnlyNull() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.ONLY_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testSimpleMapAlwaysSuppressEmpty() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.EMPTY);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        System.out.println(out.toString());
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testSimpleMapNeverSuppressHasNull() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.HAS_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3><CHILD2></CHILD2></CHILDREN>" +
-                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3><CHILD2></CHILD2></CHILDREN>" +
-                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testSimpleMapNeverSuppressEmpty() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.EMPTY);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><CHILDREN></CHILDREN><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><CHILDREN></CHILDREN><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testChoice() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getSimpleRecordsWithChoice();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-
-    /*
-    *
-    *
-    * Test writeRawRecord
-    *
-    *
-     */
-
-
-    @Test
-    public void testWriteWithoutSchemaSimpleRecord() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getSimpleRecords();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaSimpleRecordWithNullValuesAlwaysSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getSimpleRecordsWithNullValues();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaSimpleRecordWithNullValuesNeverSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getSimpleRecordsWithNullValues();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><NAME></NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaSimpleRecordWithNullValuesSuppressMissings() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getSimpleRecordsWithNullValues();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, SUPPRESS_MISSING, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><NAME></NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaNestedRecord() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getNestedRecords();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY>" +
-                "<ADDRESS><STREET>292 West Street</STREET><CITY>Jersey City</CITY></ADDRESS></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY><ADDRESS>" +
-                "<STREET>123 6th St.</STREET><CITY>Seattle</CITY></ADDRESS></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaNestedRecordWithNullValuesAlwaysSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getNestedRecordsWithNullValues();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY>" +
-                "<ADDRESS><CITY>Jersey City</CITY></ADDRESS></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY><ADDRESS>" +
-                "<CITY>Seattle</CITY></ADDRESS></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaNestedRecordWithNullValuesNeverSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-        RecordSet recordSet = getNestedRecordsWithNullValues();
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY>" +
-                "<ADDRESS><STREET></STREET><CITY>Jersey City</CITY></ADDRESS></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY><ADDRESS>" +
-                "<CITY>Seattle</CITY></ADDRESS></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaNestedRecordWithOnlyNullValuesAlwaysSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getNestedRecordsWithOnlyNullValues();
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaNestedRecordWithOnlyNullValuesNeverSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getNestedRecordsWithOnlyNullValues();
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><ADDRESS><STREET></STREET><CITY></CITY></ADDRESS>" +
-                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><ADDRESS></ADDRESS>" +
-                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaSimpleArray() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.WITHOUT_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><CHILDREN>Tom</CHILDREN><CHILDREN>Anna</CHILDREN><CHILDREN>Ben</CHILDREN>" +
-                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><CHILDREN>Tom</CHILDREN><CHILDREN>Anna</CHILDREN><CHILDREN>Ben</CHILDREN>" +
-                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaSimpleArrayWithNullValuesAlwaysSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.HAS_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><CHILDREN>Tom</CHILDREN><CHILDREN>Ben</CHILDREN>" +
-                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><CHILDREN>Tom</CHILDREN><CHILDREN>Ben</CHILDREN>" +
-                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaSimpleArrayWithNullValuesNeverSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.HAS_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><CHILDREN>Tom</CHILDREN><CHILDREN></CHILDREN><CHILDREN>Ben</CHILDREN>" +
-                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><CHILDREN>Tom</CHILDREN><CHILDREN></CHILDREN><CHILDREN>Ben</CHILDREN>" +
-                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaSimpleArrayWithOnlyNullValuesAlwaysSuppress() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.ONLY_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaSimpleArrayWithOnlyNullValuesAlwaysSuppressWrapping() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.ONLY_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, USE_PROPERTY_AS_WRAPPER, "ARRAY", "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaEmptyArray() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.EMPTY);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaEmptyArrayNeverSupressPropAsWrapper() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.EMPTY);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, NEVER_SUPPRESS, USE_PROPERTY_AS_WRAPPER, "ARRAY", "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><ARRAY></ARRAY><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><ARRAY></ARRAY><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaSimpleArrayPropAsWrapper() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.WITHOUT_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, USE_PROPERTY_AS_WRAPPER, "ARRAY", "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><ARRAY><CHILDREN>Tom</CHILDREN><CHILDREN>Anna</CHILDREN><CHILDREN>Ben</CHILDREN></ARRAY>" +
-                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><ARRAY><CHILDREN>Tom</CHILDREN><CHILDREN>Anna</CHILDREN><CHILDREN>Ben</CHILDREN></ARRAY>" +
-                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaSimpleArrayPropForElem() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.WITHOUT_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, USE_PROPERTY_FOR_ELEMENTS, "ELEM", "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><CHILDREN><ELEM>Tom</ELEM><ELEM>Anna</ELEM><ELEM>Ben</ELEM></CHILDREN>" +
-                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><CHILDREN><ELEM>Tom</ELEM><ELEM>Anna</ELEM><ELEM>Ben</ELEM></CHILDREN>" +
-                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaSimpleMapAlwaysSuppressWithoutNull() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.WITHOUT_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3><CHILD2>Anna</CHILD2></CHILDREN>" +
-                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3><CHILD2>Anna</CHILD2></CHILDREN>" +
-                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaSimpleMapAlwaysSuppressHasNull() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.HAS_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.write(recordSet);
-        writer.flush();
-
-        String xmlResult = "<ROOT><PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3></CHILDREN>" +
-                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3></CHILDREN>" +
-                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaSimpleMapAlwaysSuppressOnlyNull() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.ONLY_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaSimpleMapAlwaysSuppressEmpty() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.EMPTY);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaSimpleMapNeverSuppressHasNull() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.HAS_NULL);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3><CHILD2></CHILD2></CHILDREN>" +
-                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3><CHILD2></CHILD2></CHILDREN>" +
-                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-
-    @Test
-    public void testWriteWithoutSchemaSimpleMapNeverSuppressEmpty() throws IOException {
-        OutputStream out = new ByteArrayOutputStream();
-
-        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.EMPTY);
-
-        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
-                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
-
-        writer.onBeginRecordSet();
-
-        Record record;
-        while ((record = recordSet.next()) != null) {
-            writer.writeRawRecord(record);
-        }
-
-        writer.onFinishRecordSet();
-        writer.flush();
-        writer.close();
-
-        String xmlResult = "<ROOT><PERSON><CHILDREN></CHILDREN><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
-                "<PERSON><CHILDREN></CHILDREN><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
-
-        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.xml;
+
+import org.apache.nifi.schema.access.SchemaNameAsAttribute;
+import org.apache.nifi.serialization.SimpleRecordSchema;
+import org.apache.nifi.serialization.record.DataType;
+import org.apache.nifi.serialization.record.MapRecord;
+import org.apache.nifi.serialization.record.Record;
+import org.apache.nifi.serialization.record.RecordField;
+import org.apache.nifi.serialization.record.RecordFieldType;
+import org.apache.nifi.serialization.record.RecordSchema;
+import org.apache.nifi.serialization.record.RecordSet;
+import org.junit.Assert;
+import org.junit.Test;
+import org.xmlunit.diff.DefaultNodeMatcher;
+import org.xmlunit.diff.ElementSelectors;
+import org.xmlunit.matchers.CompareMatcher;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.sql.Date;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+
+import static org.apache.nifi.record.NullSuppression.ALWAYS_SUPPRESS;
+import static org.apache.nifi.record.NullSuppression.NEVER_SUPPRESS;
+import static org.apache.nifi.record.NullSuppression.SUPPRESS_MISSING;
+import static org.apache.nifi.xml.ArrayWrapping.NO_WRAPPING;
+import static org.apache.nifi.xml.ArrayWrapping.USE_PROPERTY_AS_WRAPPER;
+import static org.apache.nifi.xml.ArrayWrapping.USE_PROPERTY_FOR_ELEMENTS;
+import static org.apache.nifi.xml.TestWriteXMLResultUtils.DATE_FORMAT;
+import static org.apache.nifi.xml.TestWriteXMLResultUtils.SCHEMA_IDENTIFIER_RECORD;
+import static org.apache.nifi.xml.TestWriteXMLResultUtils.TIMESTAMP_FORMAT;
+import static org.apache.nifi.xml.TestWriteXMLResultUtils.TIME_FORMAT;
+import static org.apache.nifi.xml.TestWriteXMLResultUtils.getEmptyNestedRecordDefinedSchema;
+import static org.apache.nifi.xml.TestWriteXMLResultUtils.getEmptyNestedRecordEmptyNestedSchema;
+import static org.apache.nifi.xml.TestWriteXMLResultUtils.getEmptyRecordsWithEmptySchema;
+import static org.apache.nifi.xml.TestWriteXMLResultUtils.getNestedRecords;
+import static org.apache.nifi.xml.TestWriteXMLResultUtils.getNestedRecordsWithNullValues;
+import static org.apache.nifi.xml.TestWriteXMLResultUtils.getNestedRecordsWithOnlyNullValues;
+import static org.apache.nifi.xml.TestWriteXMLResultUtils.getRecordWithSimpleArray;
+import static org.apache.nifi.xml.TestWriteXMLResultUtils.getRecordWithSimpleMap;
+import static org.apache.nifi.xml.TestWriteXMLResultUtils.getSimpleRecords;
+import static org.apache.nifi.xml.TestWriteXMLResultUtils.getSimpleRecordsWithChoice;
+import static org.apache.nifi.xml.TestWriteXMLResultUtils.getSimpleRecordsWithNullValues;
+import static org.apache.nifi.xml.TestWriteXMLResultUtils.getSimpleRecordsWithoutIdentifierInSchema;
+import static org.apache.nifi.xml.TestWriteXMLResultUtils.getSingleRecord;
+import static org.junit.Assert.assertThat;
+
+public class TestWriteXMLResult {
+
+    @Test
+    public void testRecordNameIsNullSchemaIdentifierMissing() {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getSimpleRecordsWithoutIdentifierInSchema();
+
+        final String expectedMessage = "The property 'Name of Record Tag' has not been set and the writer does not find a record name in the schema.";
+        final StringBuilder actualMessage = new StringBuilder();
+
+        try {
+            new WriteXMLResult(recordSet.getSchema(), new SchemaNameAsAttribute(),
+                    out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "root", null, "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        } catch (IOException e) {
+            actualMessage.append(e.getMessage());
+        }
+        Assert.assertEquals(expectedMessage, actualMessage.toString());
+
+    }
+
+    @Test
+    public void testRecordNameIsNullSchemaIdentifierExists() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getSimpleRecords();
+        WriteXMLResult writer = new WriteXMLResult(recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", null, "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isIdenticalTo(out.toString()).ignoreWhitespace());
+
+    }
+
+    @Test
+    public void testRootNameIsNull() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getSimpleRecords();
+        WriteXMLResult writer = new WriteXMLResult(recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, null, "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        final String expectedMessage = "The writer attempts to write multiple record although property \'Name of Root Tag\' " +
+                "has not been set. If the XMLRecordSetWriter is supposed to write multiple records into one FlowFile, this property is required to be configured.";
+        final StringBuilder actualMessage = new StringBuilder();
+
+        try {
+            writer.write(recordSet);
+
+        } catch (IOException e) {
+            actualMessage.append(e.getMessage());
+        }
+        Assert.assertEquals(expectedMessage, actualMessage.toString());
+    }
+
+    @Test
+    public void testSingleRecord() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getSingleRecord();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, null, "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>";
+
+        assertThat(xmlResult, CompareMatcher.isIdenticalTo(out.toString()).ignoreWhitespace());
+    }
+
+    @Test
+    public void testDataTypes() throws IOException, ParseException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        final List<RecordField> fields = new ArrayList<>();
+
+        for (final RecordFieldType fieldType : RecordFieldType.values()) {
+
+            if (fieldType == RecordFieldType.CHOICE) {
+                final List<DataType> possibleTypes = new ArrayList<>();
+                possibleTypes.add(RecordFieldType.INT.getDataType());
+                possibleTypes.add(RecordFieldType.LONG.getDataType());
+
+                fields.add(new RecordField(fieldType.name().toLowerCase(), fieldType.getChoiceDataType(possibleTypes)));
+
+            } else if (fieldType == RecordFieldType.MAP) {
+                fields.add(new RecordField(fieldType.name().toLowerCase(), fieldType.getMapDataType(RecordFieldType.INT.getDataType())));
+
+            } else {
+                fields.add(new RecordField(fieldType.name().toLowerCase(), fieldType.getDataType()));
+            }
+        }
+        final RecordSchema schema = new SimpleRecordSchema(fields, SCHEMA_IDENTIFIER_RECORD);
+
+        final DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
+        df.setTimeZone(TimeZone.getTimeZone("gmt"));
+        final long time = df.parse("2017/01/01 17:00:00.000").getTime();
+
+        final Map<String, Object> map = new LinkedHashMap<>();
+        map.put("height", 48);
+        map.put("width", 96);
+
+        final Map<String, Object> valueMap = new LinkedHashMap<>();
+        valueMap.put("string", "string");
+        valueMap.put("boolean", true);
+        valueMap.put("byte", (byte) 1);
+        valueMap.put("char", 'c');
+        valueMap.put("short", (short) 8);
+        valueMap.put("int", 9);
+        valueMap.put("bigint", BigInteger.valueOf(8L));
+        valueMap.put("long", 8L);
+        valueMap.put("float", 8.0F);
+        valueMap.put("double", 8.0D);
+        valueMap.put("decimal", 8.1D);
+        valueMap.put("date", new Date(time));
+        valueMap.put("time", new Time(time));
+        valueMap.put("timestamp", new Timestamp(time));
+        valueMap.put("record", null);
+        valueMap.put("array", null);
+        valueMap.put("choice", 48L);
+        valueMap.put("map", map);
+
+        final Record record = new MapRecord(schema, valueMap);
+        final RecordSet rs = RecordSet.of(schema, record);
+
+        WriteXMLResult writer = new WriteXMLResult( rs.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "RECORD", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(rs);
+        writer.flush();
+
+        String xmlResult = "<ROOT><RECORD><string>string</string><boolean>true</boolean><byte>1</byte><char>c</char><short>8</short>" +
+                "<int>9</int><bigint>8</bigint><long>8</long><float>8.0</float><double>8.0</double><decimal>8.1</decimal>" +
+                "<date>2017-01-01</date><time>17:00:00</time><timestamp>2017-01-01 17:00:00</timestamp><record /><choice>48</choice><array />" +
+                "<map><height>48</height><width>96</width></map></RECORD></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testSimpleRecord() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getSimpleRecords();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isIdenticalTo(out.toString()).ignoreWhitespace());
+    }
+
+    @Test
+    public void testSimpleRecordWithNullValuesAlwaysSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getSimpleRecordsWithNullValues();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isIdenticalTo(out.toString()).ignoreWhitespace());
+    }
+
+    @Test
+    public void testSimpleRecordWithNullValuesNeverSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getSimpleRecordsWithNullValues();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><NAME></NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME></NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isIdenticalTo(out.toString()).ignoreWhitespace());
+    }
+
+    @Test
+    public void testSimpleRecordWithNullValuesSuppressMissings() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getSimpleRecordsWithNullValues();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, SUPPRESS_MISSING, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><NAME></NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isIdenticalTo(out.toString()).ignoreWhitespace());
+    }
+
+    @Test
+    public void testSimpleRecordWithXMLDeclaration() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getSimpleRecords();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, false, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<?xml version=\"1.0\" ?><ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        Assert.assertEquals(xmlResult, out.toString().trim());
+    }
+
+    @Test
+    public void testSimpleRecordWithOutXMLDeclaration() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getSimpleRecords();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, false, true, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        Assert.assertEquals(xmlResult, out.toString().trim());
+    }
+
+    @Test
+    public void testEmptyRecordWithEmptySchema() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getEmptyRecordsWithEmptySchema();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isIdenticalTo(out.toString()).ignoreWhitespace());
+    }
+
+    @Test
+    public void testNestedRecord() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getNestedRecords();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY>" +
+                "<ADDRESS><STREET>292 West Street</STREET><CITY>Jersey City</CITY></ADDRESS></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY><ADDRESS>" +
+                "<STREET>123 6th St.</STREET><CITY>Seattle</CITY></ADDRESS></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testNestedRecordWithNullValuesAlwaysSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getNestedRecordsWithNullValues();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><ADDRESS><CITY>Jersey City</CITY></ADDRESS><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><ADDRESS><CITY>Seattle</CITY></ADDRESS><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testNestedRecordWithNullValuesNeverSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getNestedRecordsWithNullValues();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY>" +
+                "<ADDRESS><STREET></STREET><CITY>Jersey City</CITY></ADDRESS></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY><ADDRESS>" +
+                "<STREET></STREET><CITY>Seattle</CITY></ADDRESS></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testNestedRecordWithNullValuesSuppressMissings() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getNestedRecordsWithNullValues();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, SUPPRESS_MISSING, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY>" +
+                "<ADDRESS><STREET></STREET><CITY>Jersey City</CITY></ADDRESS></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY><ADDRESS>" +
+                "<CITY>Seattle</CITY></ADDRESS></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testNestedRecordWithOnlyNullValuesAlwaysSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getNestedRecordsWithOnlyNullValues();
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testNestedRecordWithOnlyNullValuesNeverSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getNestedRecordsWithOnlyNullValues();
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><ADDRESS><STREET></STREET><CITY></CITY></ADDRESS>" +
+                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><ADDRESS><STREET></STREET><CITY></CITY></ADDRESS>" +
+                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testEmptyNestedRecordEmptySchemaNeverSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getEmptyNestedRecordEmptyNestedSchema();
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><ADDRESS></ADDRESS><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><ADDRESS></ADDRESS><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testEmptyNestedRecordEmptySchemaAlwaysSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getEmptyNestedRecordEmptyNestedSchema();
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testNestedEmptyRecordDefinedSchemaSuppressMissing() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getEmptyNestedRecordDefinedSchema();
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, SUPPRESS_MISSING, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><ADDRESS></ADDRESS><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><ADDRESS></ADDRESS><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testSimpleArray() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.WITHOUT_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><CHILDREN>Tom</CHILDREN><CHILDREN>Anna</CHILDREN><CHILDREN>Ben</CHILDREN>" +
+                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><CHILDREN>Tom</CHILDREN><CHILDREN>Anna</CHILDREN><CHILDREN>Ben</CHILDREN>" +
+                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testSimpleArrayWithNullValuesAlwaysSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.HAS_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><CHILDREN>Tom</CHILDREN><CHILDREN>Ben</CHILDREN>" +
+                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><CHILDREN>Tom</CHILDREN><CHILDREN>Ben</CHILDREN>" +
+                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testSimpleArrayWithNullValuesNeverSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.HAS_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><CHILDREN>Tom</CHILDREN><CHILDREN></CHILDREN><CHILDREN>Ben</CHILDREN>" +
+                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><CHILDREN>Tom</CHILDREN><CHILDREN></CHILDREN><CHILDREN>Ben</CHILDREN>" +
+                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testSimpleArrayWithOnlyNullValuesAlwaysSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.ONLY_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testSimpleArrayWithOnlyNullValuesAlwaysSuppressWrapping() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.ONLY_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, USE_PROPERTY_AS_WRAPPER, "ARRAY", "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testEmptyArray() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.EMPTY);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testEmptyArrayNeverSupressPropAsWrapper() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.EMPTY);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, NEVER_SUPPRESS, USE_PROPERTY_AS_WRAPPER, "ARRAY", "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><ARRAY></ARRAY><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><ARRAY></ARRAY><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testSimpleArrayPropAsWrapper() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.WITHOUT_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, USE_PROPERTY_AS_WRAPPER, "ARRAY", "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><ARRAY><CHILDREN>Tom</CHILDREN><CHILDREN>Anna</CHILDREN><CHILDREN>Ben</CHILDREN></ARRAY>" +
+                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><ARRAY><CHILDREN>Tom</CHILDREN><CHILDREN>Anna</CHILDREN><CHILDREN>Ben</CHILDREN></ARRAY>" +
+                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testSimpleArrayPropForElem() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.WITHOUT_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, USE_PROPERTY_FOR_ELEMENTS, "ELEM", "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><CHILDREN><ELEM>Tom</ELEM><ELEM>Anna</ELEM><ELEM>Ben</ELEM></CHILDREN>" +
+                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><CHILDREN><ELEM>Tom</ELEM><ELEM>Anna</ELEM><ELEM>Ben</ELEM></CHILDREN>" +
+                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testSimpleMapAlwaysSuppressWithoutNull() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.WITHOUT_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3><CHILD2>Anna</CHILD2></CHILDREN>" +
+                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3><CHILD2>Anna</CHILD2></CHILDREN>" +
+                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testSimpleMapAlwaysSuppressHasNull() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.HAS_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3></CHILDREN>" +
+                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3></CHILDREN>" +
+                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testSimpleMapAlwaysSuppressOnlyNull() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.ONLY_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testSimpleMapAlwaysSuppressEmpty() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.EMPTY);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        System.out.println(out.toString());
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testSimpleMapNeverSuppressHasNull() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.HAS_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3><CHILD2></CHILD2></CHILDREN>" +
+                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3><CHILD2></CHILD2></CHILDREN>" +
+                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testSimpleMapNeverSuppressEmpty() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.EMPTY);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><CHILDREN></CHILDREN><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><CHILDREN></CHILDREN><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testChoice() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getSimpleRecordsWithChoice();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+
+    /*
+    *
+    *
+    * Test writeRawRecord
+    *
+    *
+     */
+
+
+    @Test
+    public void testWriteWithoutSchemaSimpleRecord() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getSimpleRecords();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaSimpleRecordWithNullValuesAlwaysSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getSimpleRecordsWithNullValues();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaSimpleRecordWithNullValuesNeverSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getSimpleRecordsWithNullValues();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><NAME></NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaSimpleRecordWithNullValuesSuppressMissings() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getSimpleRecordsWithNullValues();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, SUPPRESS_MISSING, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><NAME></NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaNestedRecord() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getNestedRecords();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY>" +
+                "<ADDRESS><STREET>292 West Street</STREET><CITY>Jersey City</CITY></ADDRESS></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY><ADDRESS>" +
+                "<STREET>123 6th St.</STREET><CITY>Seattle</CITY></ADDRESS></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaNestedRecordWithNullValuesAlwaysSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getNestedRecordsWithNullValues();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY>" +
+                "<ADDRESS><CITY>Jersey City</CITY></ADDRESS></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY><ADDRESS>" +
+                "<CITY>Seattle</CITY></ADDRESS></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaNestedRecordWithNullValuesNeverSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+        RecordSet recordSet = getNestedRecordsWithNullValues();
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY>" +
+                "<ADDRESS><STREET></STREET><CITY>Jersey City</CITY></ADDRESS></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY><ADDRESS>" +
+                "<CITY>Seattle</CITY></ADDRESS></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaNestedRecordWithOnlyNullValuesAlwaysSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getNestedRecordsWithOnlyNullValues();
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaNestedRecordWithOnlyNullValuesNeverSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getNestedRecordsWithOnlyNullValues();
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><ADDRESS><STREET></STREET><CITY></CITY></ADDRESS>" +
+                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><ADDRESS></ADDRESS>" +
+                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaSimpleArray() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.WITHOUT_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><CHILDREN>Tom</CHILDREN><CHILDREN>Anna</CHILDREN><CHILDREN>Ben</CHILDREN>" +
+                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><CHILDREN>Tom</CHILDREN><CHILDREN>Anna</CHILDREN><CHILDREN>Ben</CHILDREN>" +
+                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaSimpleArrayWithNullValuesAlwaysSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.HAS_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><CHILDREN>Tom</CHILDREN><CHILDREN>Ben</CHILDREN>" +
+                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><CHILDREN>Tom</CHILDREN><CHILDREN>Ben</CHILDREN>" +
+                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaSimpleArrayWithNullValuesNeverSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.HAS_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><CHILDREN>Tom</CHILDREN><CHILDREN></CHILDREN><CHILDREN>Ben</CHILDREN>" +
+                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><CHILDREN>Tom</CHILDREN><CHILDREN></CHILDREN><CHILDREN>Ben</CHILDREN>" +
+                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaSimpleArrayWithOnlyNullValuesAlwaysSuppress() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.ONLY_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaSimpleArrayWithOnlyNullValuesAlwaysSuppressWrapping() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.ONLY_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, USE_PROPERTY_AS_WRAPPER, "ARRAY", "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaEmptyArray() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.EMPTY);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaEmptyArrayNeverSupressPropAsWrapper() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.EMPTY);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, NEVER_SUPPRESS, USE_PROPERTY_AS_WRAPPER, "ARRAY", "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><ARRAY></ARRAY><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><ARRAY></ARRAY><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaSimpleArrayPropAsWrapper() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.WITHOUT_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, USE_PROPERTY_AS_WRAPPER, "ARRAY", "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><ARRAY><CHILDREN>Tom</CHILDREN><CHILDREN>Anna</CHILDREN><CHILDREN>Ben</CHILDREN></ARRAY>" +
+                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><ARRAY><CHILDREN>Tom</CHILDREN><CHILDREN>Anna</CHILDREN><CHILDREN>Ben</CHILDREN></ARRAY>" +
+                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaSimpleArrayPropForElem() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleArray(TestWriteXMLResultUtils.NullValues.WITHOUT_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, USE_PROPERTY_FOR_ELEMENTS, "ELEM", "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><CHILDREN><ELEM>Tom</ELEM><ELEM>Anna</ELEM><ELEM>Ben</ELEM></CHILDREN>" +
+                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><CHILDREN><ELEM>Tom</ELEM><ELEM>Anna</ELEM><ELEM>Ben</ELEM></CHILDREN>" +
+                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaSimpleMapAlwaysSuppressWithoutNull() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.WITHOUT_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3><CHILD2>Anna</CHILD2></CHILDREN>" +
+                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3><CHILD2>Anna</CHILD2></CHILDREN>" +
+                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaSimpleMapAlwaysSuppressHasNull() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.HAS_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.write(recordSet);
+        writer.flush();
+
+        String xmlResult = "<ROOT><PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3></CHILDREN>" +
+                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3></CHILDREN>" +
+                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaSimpleMapAlwaysSuppressOnlyNull() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.ONLY_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaSimpleMapAlwaysSuppressEmpty() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.EMPTY);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, ALWAYS_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaSimpleMapNeverSuppressHasNull() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.HAS_NULL);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3><CHILD2></CHILD2></CHILDREN>" +
+                "<NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><CHILDREN><CHILD1>Tom</CHILD1><CHILD3>Ben</CHILD3><CHILD2></CHILD2></CHILDREN>" +
+                "<NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+
+    @Test
+    public void testWriteWithoutSchemaSimpleMapNeverSuppressEmpty() throws IOException {
+        OutputStream out = new ByteArrayOutputStream();
+
+        RecordSet recordSet = getRecordWithSimpleMap(TestWriteXMLResultUtils.NullValues.EMPTY);
+
+        WriteXMLResult writer = new WriteXMLResult( recordSet.getSchema(), new SchemaNameAsAttribute(),
+                out, true, false, NEVER_SUPPRESS, NO_WRAPPING, null, "ROOT", "PERSON", "UTF-8", DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT);
+
+        writer.onBeginRecordSet();
+
+        Record record;
+        while ((record = recordSet.next()) != null) {
+            writer.writeRawRecord(record);
+        }
+
+        writer.onFinishRecordSet();
+        writer.flush();
+        writer.close();
+
+        String xmlResult = "<ROOT><PERSON><CHILDREN></CHILDREN><NAME>Cleve Butler</NAME><AGE>42</AGE><COUNTRY>USA</COUNTRY></PERSON>" +
+                "<PERSON><CHILDREN></CHILDREN><NAME>Ainslie Fletcher</NAME><AGE>33</AGE><COUNTRY>UK</COUNTRY></PERSON></ROOT>";
+
+        assertThat(xmlResult, CompareMatcher.isSimilarTo(out.toString()).ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
+    }
+}